[ome-users] Invalid values stored in TIFF-tag 'StripByteCounts' when writing striped OME-TIFF

Matthias Baldauf matthias.baldauf at umit.at
Fri Sep 7 16:31:12 BST 2012


Hello all,

I am using the Bio-Formats Java library (trunk build) to write an
OME-TIFF sequentially strip per strip.
It is basically the same approach I mentioned in a previous post
(http://lists.openmicroscopy.org.uk/pipermail/ome-users/2012-August/003178.html),
but now I am reading the JPEG in stripes and store them strip per strip
in an OME-TIFF. It works great for striped uncompressed OME-TIFFs.

However, when using LZW compression, it nearly ever results in an
OME-TIFF which cannot be opened.
To locate the error I analyzed the IFD of the TIFF and observed that the
tag 'StripByteCounts' doesn’t contain valid values.
In the case when there are just a few stripes in the OME-TIFF, the
values of 'StripByteCounts' are too large, even exceeding the number of
bytes when the strip would be uncompressed.
In the case when there are more stripes in the OME-TIFF, the values of
'StripByteCounts' are zero.
So I had a look at the IFD-class in the loci.formats.tiff package an
encountered the following lines in the getStripByteCounts() method:

    if (getCompression() == TiffCompression.LZW) {
      for (int i=0; i<byteCounts.length; i++) {
        counts[i] = byteCounts[i] * 2;
      }
    }

I removed the multiplication (* 2) and it seems to solve the error with
the wrong values of 'StripByteCounts'.
The OME-TIFFs can be opened now (even containing many stripes).
The multiplication increases the values of 'StripByteCounts' every time
a strip gets stored in the OME-TIFF.
This would explain the very large numbers and, when more strips are
added, the zeros because of an overflow.

Below, I added an example-code (TiffStripWriter.java) to reproduce this
error.
Example settings:
TIFF_WIDTH = 2000, TIFF_HEIGHT = 800, STRIP_WIDTH=2000, STRIP_HEIGHT =
80 (= values of 'StripByteCounts' are very large)
TIFF_WIDTH = 2000, TIFF_HEIGHT = 800, STRIP_WIDTH=2000, STRIP_HEIGHT = 8
(= values of 'StripByteCounts' are zero)


Thanks in advance for having a look at it!

Regards,
Matthias



------------------------------------------------
TiffStripWriter.java
------------------------------------------------
import loci.common.services.ServiceFactory;
import loci.formats.FormatTools;
import loci.formats.MetadataTools;
import loci.formats.meta.IMetadata;
import loci.formats.out.OMETiffWriter;
import loci.formats.out.TiffWriter;
import loci.formats.services.OMEXMLService;
import loci.formats.tiff.IFD;

public class TiffStripWriter {

    static final int PIXEL_TYPE = FormatTools.UINT8;
    static final int COMPONENTS = 3;
    static final int TIFF_WIDTH = 2000;
    static final int TIFF_HEIGHT = 800;
    static final int STRIP_WIDTH = 2000;
    static final int STRIP_HEIGHT = 80;

    public static void main(String[] args) throws Exception {
        if (args.length < 1) {
            System.out.println("Please specify an output file name.");
            System.exit(1);
        }
        String id = args[0];

        // create metadata object with minimum required metadata fields
        ServiceFactory factory = new ServiceFactory();
        OMEXMLService service =
factory.getInstance(OMEXMLService.class);
        IMetadata meta = service.createOMEXMLMetadata();
        MetadataTools.populateMetadata(meta, 0, null, false, "XYZCT",
FormatTools.getPixelTypeString(PIXEL_TYPE), TIFF_WIDTH, TIFF_HEIGHT, 1,
COMPONENTS, 1, COMPONENTS);

        // set up the writer for OME-TIFF
        TiffWriter writer = new OMETiffWriter();
        writer.setMetadataRetrieve(meta);
        writer.setInterleaved(Boolean.TRUE);
        writer.setBigTiff(false);
        writer.setId(id);
        writer.setCompression(TiffWriter.COMPRESSION_LZW);

        // set up IFD for creating a striped OME-TIFF
        IFD ifd = new IFD();
        ifd.put(IFD.ROWS_PER_STRIP, STRIP_HEIGHT);

        // create blank image
        byte[] img = new byte[STRIP_WIDTH * STRIP_HEIGHT * COMPONENTS *
FormatTools.getBytesPerPixel(PIXEL_TYPE)];

        // write OME
-TIFF
        for (int y = 0; y             for (int i = 0; i < img.length; i++)
                img[i] = (byte) (256 * Math.random());

            // write strip
            writer.saveBytes(0, img, ifd, 0, y * STRIP_HEIGHT,
STRIP_WIDTH, STRIP_HEIGHT);
        }

        writer.close();
    }

}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openmicroscopy.org.uk/pipermail/ome-users/attachments/20120907/09e82f3c/attachment.html>


More information about the ome-users mailing list