2014.11.14 12:40 "[Tiff] Reading compressed Metamorph with libtiff 4.0.3", by Christophe Messaouik

Hello all,

I apologize in advance for the long winded text.

I've been working on this issue for a few days now and I think I found the source of the problem but I'm looking for confirmation from more knowledgeable people before moving on.

I'm trying to read compressed Metamorph stk files using the libtiff and it seems to me that it's currently not possible.

My current background:

I'm new to all this: libtiff, the TIFF format and the Metamorph format. :)

My knowledge on the Metamorph format:

The Metamorph format is not following the standard TIFF format: all planes contained in an stk file will be stored in the first and only IFD.

Fortunately the Metamorph format documentation (ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc ) explains how to read stk files. Quoting the important part:


The following TIFF tags require special handling in STK files:

Tag = 270 (10E.H)
Type = ASCII

Used to store the plane annotations. There is one NULL-terminated string for each plane in the stack.


The strips for all the planes of the stack are stored contiguously at this location. The following pseudocode fragment shows how to find the offset of a specified plane planeNum.

     LONG planeOffset = planeNum *

           (stripOffsets[stripsPerImage - 1] +
           stripByteCounts[stripsPerImage - 1] - stripOffsets[0]);

Note that the planeOffset must be added to the stripOffset[0] to find the image data for the specific plane in the file.



The Metamorph format documentation suggests that you need to add the size of the first plane to each strip offsets to find the strip offsets of the second plane.

This is all fine and dandy but it doesn't make sense when you are dealing with compressed data as each strip has a different byte count. So there must be a different way to read all those planes.

I've stumbled upon the bio formats library which is able to read those compressed STK files just fine. By debugging through it I realised it was able to read a huge array of strip offsets from the file. In fact, the array contained all the strip offsets of all the planes in the file! That would suggest that Metamorph stores more information than the documentation wants us to believe.

Back to libtiff. I debugged through it and found that libtiff also reads all the strip offsets of all the planes of the file. Unfortunately, I didn't find a way to access all those offsets. Why? Because libtiff tries to be memory efficient (I guess) by only keeping the strip offsets of the first plane. :(

Let's enter into details:

TIFFFetchStripThing() in tif_dirread.c is responsible for reading strips related arrays (from what I understand) and is where my problem seems to be coming from.

It calls TIFFReadDirEntryLong8Array(tif,dir,&data) which reads all the strip offsets of the file. "data" returned contains those valuable offsets that I would like to put my hands on.

Then it compares "dir->tdir_count" (the number of strips offsets read) and "nstrips" (the number of strips contained in a plane) and finds out that it has read too many offsets so it will make sure to ignore the offsets it doesn't care about with the following lines of code: _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));



From where I stand, with my limited knowledge of libtiff, I don't see any way to access the strip offsets that libtiff decides to ignore. They are discarded directly after being read so I'm a bit stuck.

Did I miss something in the API? Is there a way to prevent libtiff from discarding them? Or is there a function in the API I missed that I can ask to read all the offsets? (TIFFGetField() didn't seem to do the job by the way)

If there is no way to handle this case currently using libtiff, would it ma