From 941fcd45200cdf9dc1a6fcfe088d5089edae94e0 Mon Sep 17 00:00:00 2001
From: theazgra <theazgra@gmail.com>
Date: Tue, 12 Mar 2019 11:32:25 +0100
Subject: [PATCH] Mapping of signed types to unsigned.

---
 czi-format/czi-parser/custom_types.h          |   2 +-
 czi-format/czi-parser/czi_file.cpp            |  29 +++++++-
 czi-format/czi-parser/main.cpp                |   2 +-
 czi-format/czi-parser/utilities/type_mapper.h |  69 ++++++++++++++++++
 .../czi-parser/utilities/vector_utilities.h   |  50 +++++++++++++
 .../DS_ZISRAW-FileFormat.pdf                  | Bin
 .../XmlSchemas/CommonTypes.xsd                |   0
 .../XmlSchemas/Dimensions.xsd                 |   0
 .../XmlSchemas/DisplaySetting.xsd             |   0
 .../XmlSchemas/ImageAnalysisSetting.xsd       |   0
 .../XmlSchemas/ImageMetadata.xsd              |   0
 .../XmlSchemas/Information.xsd                |   0
 .../XmlSchemas/Instrument.xsd                 |   0
 .../XmlSchemas/Layers.xsd                     |   0
 .../XmlSchemas/PhysiologySetting.xsd          |   0
 .../XmlSchemas/Scaling.xsd                    |   0
 .../XmlSchemas/Timeline.xsd                   |   0
 .../XmlSchemas/Views.xsd                      |   0
 18 files changed, 146 insertions(+), 6 deletions(-)
 create mode 100644 czi-format/czi-parser/utilities/type_mapper.h
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/DS_ZISRAW-FileFormat.pdf (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/CommonTypes.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Dimensions.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/DisplaySetting.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/ImageAnalysisSetting.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/ImageMetadata.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Information.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Instrument.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Layers.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/PhysiologySetting.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Scaling.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Timeline.xsd (100%)
 rename czi-format/{czi-doc-zen-2.3 => docs_czi}/XmlSchemas/Views.xsd (100%)

diff --git a/czi-format/czi-parser/custom_types.h b/czi-format/czi-parser/custom_types.h
index 22a8910..d758eb2 100644
--- a/czi-format/czi-parser/custom_types.h
+++ b/czi-format/czi-parser/custom_types.h
@@ -24,7 +24,7 @@ typedef unsigned long ulong;
 constexpr uint UINT_MAX = std::numeric_limits<uint>::max();
 constexpr ulong ULONG_MAX = std::numeric_limits<ulong>::max();
 constexpr short SHORT_MAX = std::numeric_limits<short>::max();
-constexpr short USHORT_MAX = std::numeric_limits<ushort>::max();
+constexpr ushort USHORT_MAX = std::numeric_limits<ushort>::max();
 
 #define TagType std::string, std::string
 typedef std::pair<TagType> Tag;
diff --git a/czi-format/czi-parser/czi_file.cpp b/czi-format/czi-parser/czi_file.cpp
index 0e274fb..be6ff86 100644
--- a/czi-format/czi-parser/czi_file.cpp
+++ b/czi-format/czi-parser/czi_file.cpp
@@ -522,9 +522,14 @@ void CziFile::frames_difference() const
 
     auto framesByChannels = get_subblocks_grouped_by_channels();
 
+    std::pair<uint, uint> canBeMappedCounts = std::make_pair(0, 0);
+
     for (const std::pair<uint, std::vector<uint>> &channelGroup : framesByChannels)
     {
         printf("Starting channel %u\n", channelGroup.first);
+
+        //#pragma omp parallel for
+
         for (size_t i = 1; i < channelGroup.second.size(); i++)
         {
             // This assertion will fail if pixel type isn't Gray16
@@ -541,17 +546,33 @@ void CziFile::frames_difference() const
 
             std::vector<int> differenceArray = vecUtil::diff_vectors<ushort, int>(prevFrameValues, currentFrameValues);
 
+            int min = vecUtil::find_min(differenceArray);
+            int max = vecUtil::find_max(differenceArray);
+            long maxMappedValue = (min < 0) ? (abs(min) + max) : (max);
+            bool canBeMappedToUShort = maxMappedValue < USHORT_MAX;
+
+#pragma omp critical
+            {
+                if (canBeMappedToUShort)
+                    canBeMappedCounts.first++;
+                else
+                    canBeMappedCounts.second++;
+            }
+
             ByteArray intBytes = int_array_to_bytes(differenceArray);
 
             auto frameCompResult = test_compression_method(currentFrameData, CompressionMethod_BZIP2, 6);
             auto diffCompResult = test_compression_method(intBytes, CompressionMethod_BZIP2, 6);
 
-            float diffSizeDif = ((float)diffCompResult.compressedSize / (float)frameCompResult.compressedSize) * 100.0f;
+            float diffSizeDif = ((float)diffCompResult.compressedSize / (float)frameCompResult.compressedSize);
 
-            printf("Frame [%u | %u]: Size %7lu Compression ratio: %7f\n",
-                   channelGroup.second[i - 1], channelGroup.second[i], frameCompResult.compressedSize, frameCompResult.compressionRatio);
+            printf("========================\nFrame [%u vs %u]\n\tCR frame: %10.5f\n\tCR  diff: %10.5f\n\tSizeDiff: %10.5f\n\tMin: %10i\n\tMax: %10i\n\tMax mapped value: %10li\n\tCan be mapped to ushort: %s\n",
+                   channelGroup.second[i - 1], channelGroup.second[i], frameCompResult.compressionRatio, diffCompResult.compressionRatio, diffSizeDif,
+                   min, max, maxMappedValue, canBeMappedToUShort ? "YES" : "NO");
 
-            printf(" Diff:           Size %7lu Compression ratio: %7f\n Size: %f\n\n", diffCompResult.compressedSize, diffCompResult.compressionRatio, diffSizeDif);
+            //printf("Max value: %7i Min value: %7i #of values: %7li\n", max, min, rangeSize);
         }
     }
+
+    printf("%u can be mapped to short difference value.\n%u can not be mapped.\n", canBeMappedCounts.first, canBeMappedCounts.second);
 }
\ No newline at end of file
diff --git a/czi-format/czi-parser/main.cpp b/czi-format/czi-parser/main.cpp
index 55655b2..8a71617 100644
--- a/czi-format/czi-parser/main.cpp
+++ b/czi-format/czi-parser/main.cpp
@@ -1,7 +1,7 @@
 #include "czi_parser.h"
 #include "compression/benchmark.h"
 #include "utilities/args.hxx"
-
+#include "utilities/type_mapper.h"
 int main(int argc, char **argv)
 {
     args::ArgumentParser argParser("CZI file tools", "Optional arguments are in `[]` necessary in `<>`.");
diff --git a/czi-format/czi-parser/utilities/type_mapper.h b/czi-format/czi-parser/utilities/type_mapper.h
new file mode 100644
index 0000000..a7f4087
--- /dev/null
+++ b/czi-format/czi-parser/utilities/type_mapper.h
@@ -0,0 +1,69 @@
+#pragma once
+#include "../custom_types.h"
+#include "vector_utilities.h"
+
+// Provide mapping utilites from signed types to big enaugh unsigned types.
+template <typename SourceType, typename TargetType>
+class TypeMapper
+{
+  private:
+  public:
+    // Map `SourceType` vector to `TargetType` vector. Saving mapping point as first element.
+    std::vector<TargetType> map(std::vector<SourceType> &data)
+    {
+        auto limits = vecUtil::find_min_max(data);
+        SourceType min = limits.first;
+        SourceType max = limits.second;
+
+        TargetType targetMaxValue = std::numeric_limits<TargetType>::max();
+        always_assert(max < targetMaxValue);
+        always_assert((abs(min) + max) < targetMaxValue);
+
+        TargetType mappingPoint = max;
+
+        std::vector<TargetType> result;
+        result.resize(data.size() + 1);
+
+        // Save mapping point as first value.
+        result[0] = mappingPoint;
+
+        for (size_t i = 0; i < data.size(); i++)
+        {
+            if (data[i] >= 0)
+            {
+                result[i + 1] = (TargetType)data[i];
+            }
+            else
+            {
+                result[i + 1] = mappingPoint + abs(data[i]);
+            }
+        }
+
+        return result;
+    }
+
+    // Map back `TargetType` vector to `SourceType` vector.
+    std::vector<SourceType> map_back(std::vector<TargetType> &data)
+    {
+        std::vector<SourceType> result;
+        result.resize(data.size() - 1);
+
+        // Retrieve mapping point.
+        TargetType mappingPoint = data[0];
+
+        for (size_t i = 1; i < data.size(); i++)
+        {
+            if (data[i] <= mappingPoint)
+            {
+                // Positive values
+                result[i - 1] = data[i];
+            }
+            else
+            {
+                // Negative values
+                result[i - 1] = -(data[i] - mappingPoint);
+            }
+        }
+        return result;
+    }
+};
\ No newline at end of file
diff --git a/czi-format/czi-parser/utilities/vector_utilities.h b/czi-format/czi-parser/utilities/vector_utilities.h
index 76482d5..7b08691 100644
--- a/czi-format/czi-parser/utilities/vector_utilities.h
+++ b/czi-format/czi-parser/utilities/vector_utilities.h
@@ -1,6 +1,7 @@
 #pragma once
 #include <vector>
 #include <algorithm>
+#include <limits>
 
 namespace vecUtil
 {
@@ -59,4 +60,53 @@ std::vector<DiffType> diff_vectors(const std::vector<T> &a, const std::vector<T>
     return result;
 }
 
+template <typename T>
+T find_max(const std::vector<T> &data)
+{
+    T max = std::numeric_limits<T>::min();
+    for (size_t i = 0; i < data.size(); i++)
+    {
+        if (data[i] > max)
+        {
+            max = data[i];
+        }
+    }
+    return max;
+}
+
+template <typename T>
+T find_min(const std::vector<T> &data)
+{
+    T min = std::numeric_limits<T>::max();
+    for (size_t i = 0; i < data.size(); i++)
+    {
+        if (data[i] < min)
+        {
+            min = data[i];
+        }
+    }
+    return min;
+}
+
+template <typename T>
+std::pair<T, T> find_min_max(const std::vector<T> &data)
+{
+    T min = std::numeric_limits<T>::max();
+    T max = std::numeric_limits<T>::min();
+
+    for (size_t i = 0; i < data.size(); i++)
+    {
+        if (data[i] < min)
+        {
+            min = data[i];
+        }
+
+        if (data[i] > max)
+        {
+            max = data[i];
+        }
+    }
+    return std::make_pair(min, max);
+}
+
 }; // namespace vecUtil
diff --git a/czi-format/czi-doc-zen-2.3/DS_ZISRAW-FileFormat.pdf b/czi-format/docs_czi/DS_ZISRAW-FileFormat.pdf
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/DS_ZISRAW-FileFormat.pdf
rename to czi-format/docs_czi/DS_ZISRAW-FileFormat.pdf
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/CommonTypes.xsd b/czi-format/docs_czi/XmlSchemas/CommonTypes.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/CommonTypes.xsd
rename to czi-format/docs_czi/XmlSchemas/CommonTypes.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Dimensions.xsd b/czi-format/docs_czi/XmlSchemas/Dimensions.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Dimensions.xsd
rename to czi-format/docs_czi/XmlSchemas/Dimensions.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/DisplaySetting.xsd b/czi-format/docs_czi/XmlSchemas/DisplaySetting.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/DisplaySetting.xsd
rename to czi-format/docs_czi/XmlSchemas/DisplaySetting.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/ImageAnalysisSetting.xsd b/czi-format/docs_czi/XmlSchemas/ImageAnalysisSetting.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/ImageAnalysisSetting.xsd
rename to czi-format/docs_czi/XmlSchemas/ImageAnalysisSetting.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/ImageMetadata.xsd b/czi-format/docs_czi/XmlSchemas/ImageMetadata.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/ImageMetadata.xsd
rename to czi-format/docs_czi/XmlSchemas/ImageMetadata.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Information.xsd b/czi-format/docs_czi/XmlSchemas/Information.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Information.xsd
rename to czi-format/docs_czi/XmlSchemas/Information.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Instrument.xsd b/czi-format/docs_czi/XmlSchemas/Instrument.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Instrument.xsd
rename to czi-format/docs_czi/XmlSchemas/Instrument.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Layers.xsd b/czi-format/docs_czi/XmlSchemas/Layers.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Layers.xsd
rename to czi-format/docs_czi/XmlSchemas/Layers.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/PhysiologySetting.xsd b/czi-format/docs_czi/XmlSchemas/PhysiologySetting.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/PhysiologySetting.xsd
rename to czi-format/docs_czi/XmlSchemas/PhysiologySetting.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Scaling.xsd b/czi-format/docs_czi/XmlSchemas/Scaling.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Scaling.xsd
rename to czi-format/docs_czi/XmlSchemas/Scaling.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Timeline.xsd b/czi-format/docs_czi/XmlSchemas/Timeline.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Timeline.xsd
rename to czi-format/docs_czi/XmlSchemas/Timeline.xsd
diff --git a/czi-format/czi-doc-zen-2.3/XmlSchemas/Views.xsd b/czi-format/docs_czi/XmlSchemas/Views.xsd
similarity index 100%
rename from czi-format/czi-doc-zen-2.3/XmlSchemas/Views.xsd
rename to czi-format/docs_czi/XmlSchemas/Views.xsd
-- 
GitLab