Newer
Older
return ((header.filePart == 0) && (header.fileGuid == header.masterFileGuid));
void CziFile::print_segment_header(const SegmentHeader &segmentHeader) const
{
printf("---------SegmentHeader---------\n");
printf("%-25s %15s\n", "SID", segmentHeader.sId.c_str());
printf("%-25s %15li\n", "AllocatedSize", segmentHeader.allocatedSize);
printf("%-25s %15li\n", "UsedSize", segmentHeader.usedSize);
printf("-------------------------------\n");
}
const char *CziFile::pixel_type_str(const PixelType px) const
always_assert("Bad pixel type." && false);
return nullptr;
const char *CziFile::pyramid_type_str(const PyramidType pt) const
return "MultiSubBlock";
break;
default:
{
always_assert("Bad pyramid type." && false);
return nullptr;
const char *CziFile::compression_type_str(const CompressionType ct) const
return "System";
break;
default:
{
always_assert("Bad compression type." && false);
return nullptr;
const char *CziFile::dimension_type_str(const Dimension &d) const
return "X (width)";
return "Y (height)";
return "C (channels)";
return "Z (Z-slices)";
return "T (timestamps)";
return "R (rotation)";
return "S (scene)";
return "I (illumination)";
return "B (block index)";
return "M (mosaic)";
return "H (phase)";
return "V (views)";
break;
default:
{
always_assert("Bad dimension type." && false);
return nullptr;
const char *CziFile::dimension_char(const Dimension &d) const
default:
{
always_assert("Bad dimension type." && false);
break;
}
}
std::string CziFile::dimension_stack_str(const std::vector<DimensionEntryDV1> &dims, bool includeSize) const
{
std::string result;
for (const DimensionEntryDV1 &entry : dims)
{
result.append(dimension_char(entry.dimension));
// + std::string(includeSize ? () : ""));
if (includeSize)
result.append("(" + std::to_string(entry.size) + ")-");
}
if (includeSize)
{
result = result.substr(0, result.length() - 1);
printf("==========SubBlock directory==========\n");
print_segment_header(subBlockDirectory.header);
printf("%-25s %15i\n", "EntryCount", subBlockDirectory.entryCount);
for (size_t entry = 0; entry < subBlockDirectory.entryCount; entry++)
{
printf("SubBlockId: %i\tPixelType: %s\tCompression: %s\tDimensionStack: %s\tPyramidType: %s\n",
(int)entry,
pixel_type_str(subBlockDirectory.entries[entry].pixelType),
compression_type_str(subBlockDirectory.entries[entry].compression),
dimension_stack_str(subBlockDirectory.entries[entry].dimensions, true).c_str(),
pyramid_type_str(subBlockDirectory.entries[entry].pyramidType));
}
printf("======================================\n");
std::string byte_array_str(const std::vector<byte> &bytes)
{
std::string result = "";
for (size_t i = 0; i < bytes.size(); i++)
{
result.append(std::to_string(bytes[i]));
if (i % 4 == 0 && i != bytes.size() - 1)
result.append("-");
}
return result;
}
{
printf("Loaded CZI FILE: %s\n", fileName.c_str());
printf("==========Summary report==========\n");
print_segment_header(header.header);
printf("%-25s %13i.%i\n", "FileVersion", header.fileVersion.major, header.fileVersion.minor);
printf("%-25s %15i\n", "FilePart", header.filePart);
printf("%-25s %30s\n", "MasterGUID", byte_array_str(header.masterFileGuid).c_str());
printf("%-25s %30s\n", "FileGUID", byte_array_str(header.masterFileGuid).c_str());
//TODO: Replace with GUID print.
printf("%-25s %15i\n", "GUIDs are matching", vecUtil::vector_eq(header.masterFileGuid, header.fileGuid));
printf("%-25s %15i\n", "UpdatePending", header.updatePending);
printf("%-25s %15li\n", "SubblockDirPosition", header.subBlockDirectoryPosition);
printf("%-25s %15li\n", "MetadataPosition", header.metadataPosition);
printf("%-25s %15li\n", "AttachmentDirPosition", header.attachmentDirectoryPosition);
printf("%-25s %15i\n", "SubBlockCount", subBlockDirectory.entryCount);
printf("%-25s %15i\n", "AttachmentCount", attachmentDirectory.entryCount);
{
std::map<PixelType, int> pixelTypeMap;
std::map<CompressionType, int> compressionMap;
std::map<std::string, int> dimensionMap;
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
for (size_t sbId = 0; sbId < subBlockDirectory.entryCount; sbId++)
{
const DirectoryEntryDV entry = subBlockDirectory.entries[sbId];
if (pixelTypeMap.count(entry.pixelType))
pixelTypeMap[entry.pixelType]++;
else
pixelTypeMap.emplace(std::make_pair(entry.pixelType, 1));
if (compressionMap.count(entry.compression))
compressionMap[entry.compression]++;
else
compressionMap.emplace(std::make_pair(entry.compression, 1));
std::string dimStackStr = dimension_stack_str(entry.dimensions, false);
if (dimensionMap.count(dimStackStr))
dimensionMap[dimStackStr]++;
else
dimensionMap.emplace(std::make_pair(dimStackStr, 1));
}
printf("Pixel type distribution:\n");
for (auto &&ptPair : pixelTypeMap)
{
printf("\t%s %ix\n", pixel_type_str(ptPair.first), ptPair.second);
}
printf("Compression type distribution:\n");
for (auto &&ctPair : compressionMap)
{
printf("\t%s %ix\n", compression_type_str(ctPair.first), ctPair.second);
}
printf("Dimension stack distribution:\n");
for (auto &&dimPair : dimensionMap)
{
printf("\t%s %ix\n", dimPair.first.c_str(), dimPair.second);
}
}
//printf("%-25s %15i\n", "DimensionCount", subBlockDirectory.entries[0].dimensionCount);
//printf("%-25s %15s\n", "PixelType", pixel_type_str(subBlockDirectory.entries[0].pixelType));
}
printf("==================================\n");
ImageMatrix CziFile::get_image(const uint subblockId) const
{
// // subblockId is in bounds.
// always_assert((uint)subblockId < subBlockDirectory.entries.size());
// // Image is not empty.
// always_assert(entry.width > 0 && entry.height > 0);
// // Read image bytes.
// std::vector<byte> imageBytes;
// {
// BinaryFileStream cziStream(fileName);
// imageBytes = cziStream.move_and_consume_bytes(entry.subBlock.dataLocation, entry.subBlock.dataSize);
// }
auto imageBytes = get_image_data(subblockId, false);
auto entry = subBlockDirectory.entries[subblockId];
ImageMatrix image = ImageMatrix((uint)entry.width, (uint)entry.height, entry.pixelType, imageBytes);
return image;
}
std::vector<byte> CziFile::get_image_data(const uint subblockId, const bool ZCurveOrdered) const
always_assert((uint)subblockId < subBlockDirectory.entries.size());
auto entry = subBlockDirectory.entries[subblockId];
always_assert(entry.width > 0 && entry.height > 0);
// Read image bytes.
std::vector<byte> imageBytes;
{
BinaryFileStream cziStream(fileName);
imageBytes = cziStream.move_and_consume_bytes(entry.subBlock.dataLocation, entry.subBlock.dataSize);
}
// Check if read data are correct and not corrupted.
int bytesPerPixel = get_bytes_per_pixel_type(entry.pixelType);
ulong expectedSize = entry.width * entry.height * bytesPerPixel;
always_assert(expectedSize == imageBytes.size());
if (ZCurveOrdered)
{
auto zIndices = generate_ordered_z_order_indices(entry.width, entry.height);
always_assert(zIndices.size() == (ulong)(entry.width * entry.height));
std::vector<byte> zOrderedBytes = reoder_bytes_to_z_order(imageBytes, zIndices, bytesPerPixel);
return zOrderedBytes;
}
else
{
return imageBytes;
}
void CziFile::differences_between_next(const std::string baseName) const
{
if (subBlockDirectory.entries.size() <= 1)
{
printf("There aren't 2 different images in this CZI file.\n");
return;
}
std::string fName;
ImageMatrix ref = get_image(0);
for (size_t i = 1; i < subBlockDirectory.entries.size(); i++)
{
fName = baseName + "diff_" + std::to_string(i - 1) + "_" + std::to_string(i) + ".ppm";
ImageMatrix next = get_image(i);
ImageMatrix diff_ref_next = ref.create_difference_matrix(next);
diff_ref_next.save_as_ppm(fName.c_str());
void CziFile::extract_images(const std::string &baseName) const
{
std::string fName;
for (size_t i = 0; i < subBlockDirectory.entries.size(); i++)
{
auto subblock = get_image(i);
fName = baseName + "subblock_" + std::to_string(i) + ".ppm";
subblock.save_as_ppm(fName.c_str());
}
}
void CziFile::dump_image_data(const std::string &baseName) const
{
BinaryFileStream cziStream(fileName);
int imageIndex = 0;
for (const DirectoryEntryDV &entry : subBlockDirectory.entries)
{
always_assert(entry.width > 0 && entry.height > 0);
std::string binaryFileName = baseName + std::to_string(imageIndex++) + ".bin";
auto imageBytes = cziStream.move_and_consume_bytes(entry.subBlock.dataLocation, entry.subBlock.dataSize);
write_bytes_to_file(imageBytes, binaryFileName.c_str());
printf("Wrote %s\n", binaryFileName.c_str());
}
}
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
void CziFile::test_rle_encode() const
{
float dataSize, dataZSize, rleDataSize, rleDataZSize, ratio, ratioZ;
float overall = 0;
float overallZ = 0;
for (size_t i = 0; i < subBlockDirectory.entries.size(); i++)
{
auto data = get_image_data(i, false);
auto dataZ = get_image_data(i, true);
auto rle_data = rle_encode(data);
auto rle_dataZ = rle_encode(dataZ);
dataSize = (float)data.size();
dataZSize = (float)dataZ.size();
rleDataSize = (float)rle_data.size();
rleDataZSize = (float)rle_dataZ.size();
ratio = compression_ratio(dataSize, rleDataSize);
ratioZ = compression_ratio(dataZSize, rleDataZSize);
overall += ratio;
overallZ += ratioZ;
printf("Subblock %-3i Compression ratios: Normal: %8f Z-Ordered: %8f\n", (int)i, ratio, ratioZ);
}
float dataCount = (float)subBlockDirectory.entries.size();
overall /= dataCount;
overallZ /= dataCount;
printf("Overall Normal %8f Z-Ordered: %8f\n", overall, overallZ);
}