Skip to content
Snippets Groups Projects
Commit a9b478bb authored by theazgra's avatar theazgra
Browse files

Fixed Z-order.

parent 4824ea88
No related branches found
No related tags found
No related merge requests found
# Data compression project # Data compression project
### TODO *deadline* 25.2.2019 ### 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. - 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) - 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. - 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.
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "always_on_assert.h" #include "always_on_assert.h"
#include <limits>
constexpr bool NOT_IMPLEMENTED_YET = false; constexpr bool NOT_IMPLEMENTED_YET = false;
#define MUST_BE_IMPLEMENTED always_assert(false); #define MUST_BE_IMPLEMENTED always_assert(false);
...@@ -20,6 +21,9 @@ typedef unsigned short ushort; ...@@ -20,6 +21,9 @@ typedef unsigned short ushort;
typedef unsigned int uint; typedef unsigned int uint;
typedef unsigned long ulong; 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 #define TagType std::string, std::string
typedef std::pair<TagType> Tag; typedef std::pair<TagType> Tag;
......
...@@ -345,10 +345,19 @@ std::vector<byte> CziFile::get_image_data(const uint subblockId, const bool ZCur ...@@ -345,10 +345,19 @@ std::vector<byte> CziFile::get_image_data(const uint subblockId, const bool ZCur
if (ZCurveOrdered) if (ZCurveOrdered)
{ {
auto zIndices = generate_ordered_z_order_indices(entry.width, entry.height); always_assert((uint)entry.width <= UINT_MAX && (uint)entry.height <= UINT_MAX);
always_assert(zIndices.size() == (ulong)(entry.width * entry.height)); 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; return zOrderedBytes;
} }
else else
......
...@@ -636,4 +636,66 @@ int get_bytes_per_pixel_type(const PixelType &pt) ...@@ -636,4 +636,66 @@ int get_bytes_per_pixel_type(const PixelType &pt)
break; break;
} }
return -1; 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
...@@ -67,54 +67,62 @@ struct PointWithIndex ...@@ -67,54 +67,62 @@ struct PointWithIndex
bool operator>=(const PointWithIndex &other) const { return (z >= other.z); } 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; std::vector<PointWithIndex> result;
result.resize(width * height); result.resize((colCount * componentCount) * rowCount);
// This doesnt count with bytes per pixel
size_t index = 0; 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++; index++;
} }
} }
always_assert(((ulong)(colCount * componentCount) * (ulong)rowCount) == result.size());
std::sort(result.begin(), result.end()); std::sort(result.begin(), result.end());
return result; 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; std::vector<byte> zOrderedBytes;
zOrderedBytes.resize(bytes.size());
size_t it = 0;
size_t from, pos;
for (const PointWithIndex &index : zIndices) for (const PointWithIndex &index : zIndices)
{ {
auto fromIt = bytes.begin() + index.bufferPosition; from = (index.bufferPosition * componentSize);
auto toIt = fromIt + chunkSize; //zOrderedBytes.insert(zOrderedBytes.end(), fromIt, toIt);
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; 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; std::vector<byte> bytes;
bytes.resize(zOrderedBytes.size()); bytes.resize(zOrderedBytes.size());
ulong iteration = 0; size_t it = 0;
size_t insertAt, copyFrom; size_t insertAt, copyFrom;
for (const PointWithIndex &index : zIndices) for (const PointWithIndex &index : zIndices)
{ {
insertAt = index.bufferPosition; insertAt = index.bufferPosition * componentSize;
copyFrom = iteration * chunkSize; copyFrom = it * componentSize;
vecUtil::vector_insert_at(bytes, zOrderedBytes, insertAt, copyFrom, chunkSize); vecUtil::vector_insert_at(bytes, zOrderedBytes, insertAt, copyFrom, componentSize);
++iteration; ++it;
} }
always_assert(bytes.size() == zOrderedBytes.size()); always_assert(bytes.size() == zOrderedBytes.size());
......
...@@ -8,7 +8,7 @@ int main(int argc, char **argv) ...@@ -8,7 +8,7 @@ int main(int argc, char **argv)
args::Group cziFileGroup(argParser, "CZI file input - necessary.", args::Group::Validators::All); args::Group cziFileGroup(argParser, "CZI file input - necessary.", args::Group::Validators::All);
args::Group mainMethodGroup(argParser, "Methods:", args::Group::Validators::AtMostOne); args::Group mainMethodGroup(argParser, "Methods:", args::Group::Validators::AtMostOne);
args::Group optionsGroup(argParser, "Program options:", args::Group::Validators::DontCare); 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. // Main option, has to be set. Czi file.
args::ValueFlag<std::string> cziFile(cziFileGroup, "czi file", "CZI file to load.", {'i', "input"}); args::ValueFlag<std::string> cziFile(cziFileGroup, "czi file", "CZI file to load.", {'i', "input"});
...@@ -64,6 +64,14 @@ int main(int argc, char **argv) ...@@ -64,6 +64,14 @@ int main(int argc, char **argv)
parsedFile.test_compression(cm, verboseOption.Matched()); 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"; 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") if (cziFile == "-v" || cziFile == "--version")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment