zeiss-microscopy / libCZI

Open Source Cross-Platform C++ library to read CZI image files
GNU General Public License v3.0
71 stars 19 forks source link

Uncompressed subblocks workaround #48

Closed Leo311 closed 3 years ago

Leo311 commented 4 years ago

I have sample *.czi files which ZEN 3.0 (blue edition) was able to render, but CZIcmd failed on (with commands ExtractSubBlock, ChannelComposite, etc.), stopping and printing decompression error messages.

Upon reading hexdumps of these .czi files (pointed to by lots of added debugging messages), I found that in the sample .czi files that were failing there were specific SubBlocks which the SubBlock Metadata labeled as JpxXr compressed, but the corresponding binary SubBlock Data did not have the correct JpxXr magic header bytes 0x49 0x49 0xbc 0x01. These SubBlocks -- labeled as JpxXr, but without correct magic header -- were exactly where CZIcmd failed, stopped, and printed a decompression error.

Further examination of these failing SubBlocks found that the binary SubBlock Data size was exactly that of uncompressed pixel data.

WIth the change I made in CreateBitmapFromSubBlock_JpgXr(), I was able to use CZIcmd to render images for these previously failing *.czi files. The rendered images agreed with ZEN rendering.

Since the CZIcmd code was correctly checking for the JpxXr label and JpxXr magic header (as verified by reading .czi hexdumps) and finding a conflict, I concluded: -- the CZIcmd code was actually "correct" in failing with a decompression error, -- but that ZEN was compensating for the label<>magic header conflict, -- so ... there were legacy CZI file creators which had a bug and created bad .czi files; but ZEN was explicitly compensating for this bug, while CZIcmd was not.

The change I have made in CreateBitmapFromSubBlock_JpgXr() is an error compensation that works for all the otherwise failing *.czi files that I have: -- it checks for the label<>magic header conflict (which would otherwise fail with a decompression error), -- and checks that the binary SubBlock Data datasize corresponds with uncompressed pixel data, -- and if both happen, reverts to CreateBitmapFromSubBlock_Uncompressed() to process the SubBlock.


Other changes in this pull request:

zeissmicroscopy commented 3 years ago

changes from this PR have been incorporated