diff --git a/README.md b/README.md
index 12312df8fe3ae32729bd40282fb95bfcc47fa6e9..0597290818f40345530195a300f9259d1f59569a 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 # Data compression project
 
 ### TODO *deadline* 25.2.2019
-- [ ] Tweak Z-Order reordering
+- [x] Tweak Z-Order reordering
   - Values, which are stored in more than one byte, must stay together.
   - Pixels, which contains more `channels`, can be separeted in final z order. (Try both separeted and not-separated)
     - Right now, when we `reorder` bytes we move *whole* pixel (*all channels*), but when pixel's channels will be separated we will move just one channel.
diff --git a/czi-format/czi-parser/custom_types.h b/czi-format/czi-parser/custom_types.h
index d29883dc64bc399aea582e99b1173dabc4714e52..20fb6b06489bcd68416b291165d2a539927ee31f 100644
--- a/czi-format/czi-parser/custom_types.h
+++ b/czi-format/czi-parser/custom_types.h
@@ -10,6 +10,7 @@
 #include <memory>
 #include <vector>
 #include "always_on_assert.h"
+#include <limits>
 
 constexpr bool NOT_IMPLEMENTED_YET = false;
 #define MUST_BE_IMPLEMENTED always_assert(false);
@@ -20,6 +21,9 @@ typedef unsigned short ushort;
 typedef unsigned int uint;
 typedef unsigned long ulong;
 
+constexpr uint UINT_MAX = std::numeric_limits<uint>::max();
+constexpr ulong ULONG_MAX = std::numeric_limits<ulong>::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 d031a6c0091170df2ee3a01e01cefc8a77856bd3..b28831e970dac2ace6e31d5324b4b9adbcfff9ef 100644
--- a/czi-format/czi-parser/czi_file.cpp
+++ b/czi-format/czi-parser/czi_file.cpp
@@ -345,10 +345,19 @@ std::vector<byte> CziFile::get_image_data(const uint subblockId, const bool ZCur
 
     if (ZCurveOrdered)
     {
-        auto zIndices = generate_ordered_z_order_indices(entry.width, entry.height);
-        always_assert(zIndices.size() == (ulong)(entry.width * entry.height));
+        always_assert((uint)entry.width <= UINT_MAX && (uint)entry.height <= UINT_MAX);
+        uint componentCount = get_count_of_components_of_pixel(entry.pixelType);
+        uint componentSize = get_component_size_of_pixel(entry.pixelType);
+
+        auto zIndices = generate_ordered_z_order_indices(entry.width, entry.height, componentCount);
+        always_assert(zIndices.size() == (ulong)(componentCount * entry.width * entry.height));
+
+        std::vector<byte> zOrderedBytes = reoder_bytes_to_z_order(imageBytes, zIndices, componentSize);
+
+        auto back = reoder_bytes_from_z_order(zOrderedBytes, zIndices, componentSize);
+        bool eq = vecUtil::vector_eq(imageBytes, back);
+        always_assert(eq);
 
-        std::vector<byte> zOrderedBytes = reoder_bytes_to_z_order(imageBytes, zIndices, bytesPerPixel);
         return zOrderedBytes;
     }
     else
diff --git a/czi-format/czi-parser/image/pixel_structures.h b/czi-format/czi-parser/image/pixel_structures.h
index 453249ec05e9e1a0514622cf0c92aa66ac12b299..505a5bb07cc5d28bbf439f4c0f164b9b06df692d 100644
--- a/czi-format/czi-parser/image/pixel_structures.h
+++ b/czi-format/czi-parser/image/pixel_structures.h
@@ -636,4 +636,66 @@ int get_bytes_per_pixel_type(const PixelType &pt)
         break;
     }
     return -1;
+}
+
+// Get number of bytes, by which ByteArray can be reordered in Z-Order.
+uint get_component_size_of_pixel(const PixelType &pt)
+{
+    switch (pt)
+    {
+    case PixelType_Gray8:
+        return 1;
+    case PixelType_Gray16:
+        return 2;
+    case PixelType_Gray32Float:
+        return 4;
+    case PixelType_Bgr24:
+        return 1; // Channels will be separated.
+    case PixelType_Bgr48:
+        return 2; // Channels will be separated.
+    case PixelType_Bgr96Float:
+        return 4; // Channels will be separated.
+    case PixelType_Bgra32:
+        return 1; // Channels will be separated.
+    case PixelType_Gray64ComplexFloat:
+        return 4; // Channels will be separated.
+    case PixelType_Bgr192ComplexFloat:
+        return 4; // Channels will be separated.
+    case PixelType_Gray32:
+        return 4;
+    case PixelType_Gray64:
+        return 8;
+    default:
+        INVALID_CASE;
+        break;
+    }
+    return -1;
+}
+
+// Get number of separable components in specific `PixelType`.
+uint get_count_of_components_of_pixel(const PixelType &pt)
+{
+    switch (pt)
+    {
+    case PixelType_Gray8:
+    case PixelType_Gray16:
+    case PixelType_Gray32Float:
+    case PixelType_Gray32:
+    case PixelType_Gray64:
+        return 1;
+    case PixelType_Gray64ComplexFloat:
+        return 2;
+    case PixelType_Bgr24:
+    case PixelType_Bgr48:
+    case PixelType_Bgr96Float:
+        return 3;
+    case PixelType_Bgra32:
+        return 4;
+    case PixelType_Bgr192ComplexFloat:
+        return 6;
+    default:
+        INVALID_CASE;
+        break;
+    }
+    return -1;
 }
\ No newline at end of file
diff --git a/czi-format/czi-parser/image/z_order.h b/czi-format/czi-parser/image/z_order.h
index ecd4cb0d9583cb615a0612a41817bc9884dcf8e7..29546d1d7c694bbdefc1f3dcd1c1df7887c5ab17 100644
--- a/czi-format/czi-parser/image/z_order.h
+++ b/czi-format/czi-parser/image/z_order.h
@@ -67,54 +67,62 @@ struct PointWithIndex
     bool operator>=(const PointWithIndex &other) const { return (z >= other.z); }
 };
 
-std::vector<PointWithIndex> generate_ordered_z_order_indices(const uint width, const uint height)
+std::vector<PointWithIndex> generate_ordered_z_order_indices(const uint colCount, const uint rowCount, const uint componentCount)
 {
     std::vector<PointWithIndex> result;
-    result.resize(width * height);
+    result.resize((colCount * componentCount) * rowCount);
 
+    // This doesnt count with bytes per pixel
     size_t index = 0;
-    for (uint y = 0; y < height; y++)
+    for (uint row = 0; row < rowCount; row++)
     {
-        for (uint x = 0; x < width; x++)
+        for (uint col = 0; col < (colCount * componentCount); col++)
         {
-            result[index] = PointWithIndex(x, y, index);
+            result[index] = PointWithIndex(col, row, index);
             index++;
         }
     }
 
+    always_assert(((ulong)(colCount * componentCount) * (ulong)rowCount) == result.size());
     std::sort(result.begin(), result.end());
 
     return result;
 }
 
-std::vector<byte> reoder_bytes_to_z_order(const std::vector<byte> &bytes, const std::vector<PointWithIndex> &zIndices, const uint chunkSize)
+std::vector<byte> reoder_bytes_to_z_order(const std::vector<byte> &bytes, const std::vector<PointWithIndex> &zIndices,
+                                          const uint componentSize)
 {
     std::vector<byte> zOrderedBytes;
-
+    zOrderedBytes.resize(bytes.size());
+    size_t it = 0;
+    size_t from, pos;
     for (const PointWithIndex &index : zIndices)
     {
-        auto fromIt = bytes.begin() + index.bufferPosition;
-        auto toIt = fromIt + chunkSize;
-        zOrderedBytes.insert(zOrderedBytes.end(), fromIt, toIt);
+        from = (index.bufferPosition * componentSize);
+        //zOrderedBytes.insert(zOrderedBytes.end(), fromIt, toIt);
+        pos = it * componentSize;
+        vecUtil::vector_insert_at(zOrderedBytes, bytes, pos, from, componentSize);
+        it++;
     }
-    always_assert(zOrderedBytes.size() == bytes.size());
 
+    always_assert(zOrderedBytes.size() == bytes.size());
     return zOrderedBytes;
 }
 
-std::vector<byte> reoder_bytes_from_z_order(const std::vector<byte> &zOrderedBytes, const std::vector<PointWithIndex> &zIndices, const uint chunkSize)
+std::vector<byte> reoder_bytes_from_z_order(const std::vector<byte> &zOrderedBytes, const std::vector<PointWithIndex> &zIndices,
+                                            const uint componentSize)
 {
     std::vector<byte> bytes;
     bytes.resize(zOrderedBytes.size());
 
-    ulong iteration = 0;
+    size_t it = 0;
     size_t insertAt, copyFrom;
     for (const PointWithIndex &index : zIndices)
     {
-        insertAt = index.bufferPosition;
-        copyFrom = iteration * chunkSize;
-        vecUtil::vector_insert_at(bytes, zOrderedBytes, insertAt, copyFrom, chunkSize);
-        ++iteration;
+        insertAt = index.bufferPosition * componentSize;
+        copyFrom = it * componentSize;
+        vecUtil::vector_insert_at(bytes, zOrderedBytes, insertAt, copyFrom, componentSize);
+        ++it;
     }
     always_assert(bytes.size() == zOrderedBytes.size());
 
diff --git a/czi-format/czi-parser/main.cpp b/czi-format/czi-parser/main.cpp
index 024746f2a9a9f813910600dcb8466ffe5c72022d..2f67f8e9865c0d8dc3ca8bce44a8ba196ebe39bb 100644
--- a/czi-format/czi-parser/main.cpp
+++ b/czi-format/czi-parser/main.cpp
@@ -8,7 +8,7 @@ int main(int argc, char **argv)
     args::Group cziFileGroup(argParser, "CZI file input - necessary.", args::Group::Validators::All);
     args::Group mainMethodGroup(argParser, "Methods:", args::Group::Validators::AtMostOne);
     args::Group optionsGroup(argParser, "Program options:", args::Group::Validators::DontCare);
-    args::Group compressionGroup(argParser, "Avaible compressions", args::Group::Validators::Xor);
+    args::Group compressionGroup(argParser, "Avaible compressions", args::Group::Validators::AtMostOne);
 
     // Main option, has to be set. Czi file.
     args::ValueFlag<std::string> cziFile(cziFileGroup, "czi file", "CZI file to load.", {'i', "input"});
@@ -64,6 +64,14 @@ int main(int argc, char **argv)
         parsedFile.test_compression(cm, verboseOption.Matched());
     }
 
+    if (reportMethod)
+    {
+        if (verboseOption.Matched())
+            parsedFile.report_verbose();
+        else
+            parsedFile.report();
+    }
+
     /*
     std::string cziFile = (argc > 1) ? argv[1] : "/home/mor0146/gitlab/data_project/czi-format/data/CZT-Stack-Anno.czi"; //"/home/mor0146/gitlab/data_project/czi-format/data/m2/exampleSingleChannel.czi";
     if (cziFile == "-v" || cziFile == "--version")