commit ddd2cb4aa2861aac19697b88f6c1e466bf46ca59
Author: David Sorber <david.sorber@gmail.com>
Date:   Sat Sep 8 19:45:57 2018 -0400

    Improve PCA post processing output message formatting.

diff --git a/software/photo_compress_archiver/PhotoCompressArchiver.cc b/software/photo_compress_archiver/PhotoCompressArchiver.cc
index bf8faf2..144cf1a 100644
--- a/software/photo_compress_archiver/PhotoCompressArchiver.cc
+++ b/software/photo_compress_archiver/PhotoCompressArchiver.cc
@@ -26,6 +26,54 @@
               << "ERROR: " << msg << std::endl;                               \
 }
 
+// Helper functions
+std::string _format_num_bytes(uint64_t num_bytes)
+{
+    const uint64_t tera = (1024 * 1024 * 1024L);
+    const uint64_t giga = (1024 * 1024 * 1024L);
+    const uint64_t mega = (1024 * 1024L);
+    const uint64_t kilo = 1024L;
+    
+    double fractional; 
+    std::ostringstream output;
+    
+    if (num_bytes >= tera)
+    {
+        // Tera
+        fractional = ((double)num_bytes) / tera;
+        output << std::fixed << std::setprecision(2) << fractional;
+        output << " TB";
+    }
+    else if (num_bytes >= giga)
+    {
+        // Giga
+        fractional = ((double)num_bytes) / giga;
+        output << std::fixed << std::setprecision(2) << fractional;
+        output << " GB";
+    }
+    else if (num_bytes >= mega)
+    {
+        // Mega
+        fractional = ((double)num_bytes) / mega;
+        output << std::fixed << std::setprecision(2) << fractional;
+        output << " MB";
+    }
+    else if (num_bytes >= kilo)
+    {
+        // Kilo
+        fractional = ((double)num_bytes) / kilo;
+        output << std::fixed << std::setprecision(2) << fractional;
+        output << " KB";
+    }
+    else
+    {
+        // Bytes
+        output << num_bytes << " b";
+    }
+    
+    return output.str();
+}
+
 PhotoCompressArchiver::PhotoCompressArchiver(
     const std::string& path, 
     uint32_t num_threads,
@@ -91,7 +139,8 @@ int PhotoCompressArchiver::execute()
     if (! m_decompress)
     {
         std::cout << "  Total uncompressed bytes: " 
-                  << m_total_uncompressed_size << "\n" << std::endl;
+                  << _format_num_bytes(m_total_uncompressed_size) << "\n" 
+                  << std::endl;
     }
     
     // Add terminator for each worker thread
@@ -137,14 +186,14 @@ int PhotoCompressArchiver::execute()
     if (! m_decompress)
     {
         std::cout << "\n  Total uncompressed bytes: " 
-                  << m_total_uncompressed_size << std::endl;
-        std::cout << "  Total compressed bytes: " << m_total_compressed_size 
-                  << std::endl;
+                  << _format_num_bytes(m_total_uncompressed_size) << std::endl;
+        std::cout << "  Total compressed bytes:   " 
+                  << _format_num_bytes(m_total_compressed_size) << std::endl;
         
         // Calculate and display ratio
         double ratio = (double)m_total_compressed_size / m_total_uncompressed_size;
-        std::cout << "  Compression ratio: " << std::fixed 
-                  << std::setprecision(4) << (ratio * 100) << "%" << std::endl;
+        std::cout << "  Compression ratio:        " << std::fixed 
+                  << std::setprecision(2) << (ratio * 100) << "%" << std::endl;
     }
     else
     {
@@ -152,7 +201,7 @@ int PhotoCompressArchiver::execute()
     }
     
     // Display execution duration
-    std::cout << "  Total time: " << duration << " s\n" << std::endl;
+    std::cout << "  Total time:               " << duration << " s\n" << std::endl;
     
     return 0;
 }
diff --git a/software/photo_compress_archiver/PhotoCompressArchiver.hh b/software/photo_compress_archiver/PhotoCompressArchiver.hh
index 8690c1a..941bb41 100644
--- a/software/photo_compress_archiver/PhotoCompressArchiver.hh
+++ b/software/photo_compress_archiver/PhotoCompressArchiver.hh
@@ -1,11 +1,11 @@
 #ifndef PHOTOCOMPRESSARCHIVER_H
 #define PHOTOCOMPRESSARCHIVER_H
 
-#include <atomic>
 #include <condition_variable>
 #include <cstdint>
 #include <deque>
 #include <mutex>
+#include <sstream>
 #include <string>
 #include <thread>
 #include <vector>
@@ -24,7 +24,7 @@ const std::string RED("\033[31m");
 const std::string YELLOW("\033[33m");
 const std::string PURPLE("\033[35m");
 
-const std::string version("v0.3.0");
+const std::string version("v0.3.1");
 
 const boost::regex JPEG_REGEX("^.+\\.(jpg)|(jpeg)$", boost::regex::icase);
 const boost::regex PJG_REGEX("^.+\\.pjg$", boost::regex::icase);
@@ -92,10 +92,10 @@ class PhotoCompressArchiver
         
         std::mutex m_output_mutex;          // output mutex
         
-        std::atomic<uint32_t> m_files_processed;        // number of input files processed
-        uint32_t m_num_input_files;                     // total number of input files found
-        std::atomic<uint64_t> m_total_uncompressed_size;// total uncompressed size of all images
-        std::atomic<uint64_t> m_total_compressed_size;  // total compressed size of all images
+        std::atomic<uint32_t> m_files_processed;    // number of input files processed
+        uint32_t m_num_input_files;                 // total number of input files found
+        uint64_t m_total_uncompressed_size;         // total uncompressed size of all images
+        uint64_t m_total_compressed_size;           // total compressed size of all images
         
         // input file list (either images or compressed images)
         ProtectedAndSynchronizedQueue<WorkUnit*> m_file_list;
