diff --git a/czi-format/czi-parser/CMakeLists.txt b/czi-format/czi-parser/CMakeLists.txt
index f9ee73eb48f24dd75f0a3c59f91093d2de439827..f6fab4b2aa55f2abeb712e401f546771e6ea836a 100644
--- a/czi-format/czi-parser/CMakeLists.txt
+++ b/czi-format/czi-parser/CMakeLists.txt
@@ -22,4 +22,4 @@ target_link_libraries (czi-parser ${CMAKE_THREAD_LIBS_INIT})
 
 set(CPACK_PROJECT_NAME ${PROJECT_NAME})
 set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
-include(CPack)
+include(CPack)
\ No newline at end of file
diff --git a/czi-format/czi-parser/compression/rle.h b/czi-format/czi-parser/compression/rle.h
new file mode 100644
index 0000000000000000000000000000000000000000..eed9860af20fae4fef144a1cf49b9903fedd73a8
--- /dev/null
+++ b/czi-format/czi-parser/compression/rle.h
@@ -0,0 +1,110 @@
+#pragma once
+#include "../custom_types.h"
+#include "../utilities/vector_utilities.h"
+#include "../image/z_order.h"
+
+constexpr size_t MAX_LITERAL_COUNT = 255;
+constexpr size_t MAX_RUN_COUNT = 255;
+
+// Run-Length encode bytes and return compressed bytes.
+std::vector<byte> rle_encode(const std::vector<byte> &bytes)
+{
+    std::vector<byte> compressed;
+    byte literalBuffer[MAX_LITERAL_COUNT];
+    size_t literalCount = 0;
+    size_t runCount = 0;
+
+    size_t uncompresseddBufferSize = bytes.size();
+
+    for (size_t bufferIndex = 0; bufferIndex < uncompresseddBufferSize;)
+    {
+        byte symbol = bytes[bufferIndex];
+        runCount = 1;
+
+        // Encode run.
+        while ((runCount < MAX_RUN_COUNT) &&
+               (bytes[bufferIndex + runCount] == symbol) &&
+               (runCount < (uncompresseddBufferSize - bufferIndex)))
+        {
+            ++runCount;
+        }
+
+        if ((runCount > 1) ||
+            (literalCount == MAX_LITERAL_COUNT) ||
+            ((bufferIndex == (uncompresseddBufferSize - 1)) && literalCount > 0))
+        {
+            // Write literal buffer.
+            byte literalCountBYTE = (byte)literalCount;
+            always_assert(literalCountBYTE == literalCount);
+
+            compressed.push_back(literalCountBYTE);
+            for (size_t literalBufferIndex = 0; literalBufferIndex < literalCount; literalBufferIndex++)
+            {
+                compressed.push_back(literalBuffer[literalBufferIndex]);
+            }
+            literalCount = 0;
+
+            // Write run sequence.
+            byte runCountBYTE = (byte)runCount;
+            always_assert(runCountBYTE == runCount);
+            compressed.push_back(runCountBYTE);
+            compressed.push_back(symbol);
+
+            bufferIndex += runCount;
+        }
+        else
+        {
+            // Encode literal symbol.
+            literalBuffer[literalCount++] = symbol;
+            ++bufferIndex;
+        }
+    }
+
+    return compressed;
+}
+
+// Decode Run-Length encoded bytes.
+std::vector<byte> rle_decode(const std::vector<byte> &compressed)
+{
+    std::vector<byte> uncompressed;
+    uncompressed.reserve(compressed.size());
+
+    size_t compressedBufferSize = compressed.size();
+    size_t bufferIndex = 0;
+
+    byte literalCount, runCount, runSymbol;
+    while (bufferIndex < compressedBufferSize)
+    {
+        literalCount = compressed[bufferIndex++];
+        while (literalCount--)
+        {
+            uncompressed.push_back(compressed[bufferIndex++]);
+        }
+
+        runCount = compressed[bufferIndex++];
+        runSymbol = compressed[bufferIndex++];
+        while (runCount--)
+        {
+            uncompressed.push_back(runSymbol);
+        }
+    }
+
+    return uncompressed;
+}
+
+void rle_test()
+{
+    std::vector<byte> data = {10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+                              20, 30, 40, 45, 48, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50,
+                              50, 0, 0, 1, 2, 3, 8, 8, 8, 8, 9, 6, 5, 4};
+
+    // 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 40, 45, 48, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 1, 2, 3, 8, 8, 8, 8, 9, 6, 5, 4
+    // 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 20, 30, 40, 45, 48, 46, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 1, 2, 3, 8, 8, 8, 8, 9, 6, 5, 4
+
+    auto compressed = rle_encode(data);
+    auto uncompressed = rle_decode(compressed);
+
+    bool same = are_same_vectors(data, uncompressed);
+
+    always_assert(same);
+}
\ 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 95357ca34590cdb23fc90b00e19091d6875b3123..45d1fe21d56ecb1fc3bac14118e0f0d958903bae 100644
--- a/czi-format/czi-parser/image/z_order.h
+++ b/czi-format/czi-parser/image/z_order.h
@@ -45,15 +45,17 @@ struct PointWithIndex
 {
     uint x;
     uint y;
+    ulong bufferPosition;
     ulong z;
 
     PointWithIndex() {}
 
     // Create interleaved Z order index from X and Y coordinate.
-    PointWithIndex(uint _x, uint _y)
+    PointWithIndex(uint _x, uint _y, ulong _bufferPosition)
     {
         x = _x;
         y = _y;
+        bufferPosition = _bufferPosition;
         z = interleave(x, y);
     }
 
@@ -75,7 +77,8 @@ std::vector<PointWithIndex> generate_ordered_z_order_indices(const uint width, c
     {
         for (uint x = 0; x < width; x++)
         {
-            result[index++] = PointWithIndex(x, y);
+            result[index] = PointWithIndex(x, y, index);
+            index++;
         }
     }
 
diff --git a/czi-format/czi-parser/main.cpp b/czi-format/czi-parser/main.cpp
index 94f3b93c300b545c99e4e94d8544ae3ec05953e4..bf1f7cbe3c589fca4762a86e377454f97b6acbc2 100644
--- a/czi-format/czi-parser/main.cpp
+++ b/czi-format/czi-parser/main.cpp
@@ -1,8 +1,12 @@
 #include "czi_parser.h"
 #include "file_system.h"
+#include "compression/rle.h"
 
 int main(int argc, char **argv)
 {
+    rle_test();
+    return 0;
+
     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")
     {
diff --git a/czi-format/czi-parser/utilities/vector_utilities.h b/czi-format/czi-parser/utilities/vector_utilities.h
index 8706e11855562a2922589c60840a708d9f47e3a0..4ba0cfe0933ff71798506098caf803bdd1cd6126 100644
--- a/czi-format/czi-parser/utilities/vector_utilities.h
+++ b/czi-format/czi-parser/utilities/vector_utilities.h
@@ -1,3 +1,4 @@
+#pragma once
 #include <vector>
 
 template <typename T>