<html><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><META name="Author" content="Novell GroupWise WebAccess"></head><body style='font-family: Helvetica, Arial, sans-serif; font-size: 13px; '>Hello,<br><br>I have developed a small Java-tool which converts a JPEG-image, stored in a NDPI-file, to an OME-TIFF. It also works for images with an edge length larger than 65536 pixels. Therefore, I read the image using tiles. With large JPEG-files the automatically calculated tile size can reach 3968x3968 pixels (or maybe even more). I use the writer-methods provided by Bio-Formats to save the image as a tiled OME-TIFF. The problem: When using the provided LZW-compression, a NegativeArraySizeException exception is thrown by the LZWCodec-class when the tile size reaches a certain level.  I think the reason for this exception is an integer-overflow in the LZWCodec-class, when calculating the size of the output buffer in the following line (at the beginning of the compress-method):<br><br>byte[] output = new byte[(input.length * 141) / 100 + 3];<br><br>Thrown exception:<br>Exception in thread "main" java.lang.NegativeArraySizeException<br>    at loci.formats.codec.LZWCodec.compress(LZWCodec.java:117)<br>    at loci.formats.tiff.TiffCompression.compress(TiffCompression.java:328)<br>    at loci.formats.tiff.TiffSaver.writeImage(TiffSaver.java:371)<br>    at loci.formats.tiff.TiffSaver.writeImage(TiffSaver.java:265)<br>    at loci.formats.out.TiffWriter.saveBytes(TiffWriter.java:191)<br>    at loci.formats.out.OMETiffWriter.saveBytes(OMETiffWriter.java:197)<br>    at LZWTest.main(LZWTest.java:63)<br><br>I am using the latest trunk build of Bio-Formats.<br><br>Below, I added an example-code (LZWTest.java) to reproduce this exception.<br>Example settings:<br>Tile size: 2250 x 2250 pixels, 3 components, 8bit per component (= works)<br>Tile size: 2300 x 2300 pixels, 3 components, 8bit per component (= NegativeArraySizeException)<br><br>Thanks in advance for having a look at it!<br><br>Regards,<br>Matthias<br><br><br>------------------------------------------------<br>LZWTest.java<br>------------------------------------------------<br>import loci.common.services.ServiceFactory;<br>import loci.formats.FormatTools;<br>import loci.formats.MetadataTools;<br>import loci.formats.meta.IMetadata;<br>import loci.formats.out.OMETiffWriter;<br>import loci.formats.out.TiffWriter;<br>import loci.formats.services.OMEXMLService;<br>import loci.formats.tiff.IFD;<br>import loci.formats.tiff.TiffCompression;<br><br>public class LZWTest {<br>  <br>  static final int PIXEL_TYPE = FormatTools.UINT8;<br>  static final int COMPONENTS = 3;<br>  static final int w = 2300;<br>  static final int h = 2300;<br>  <br>  public static void main(String[] args) throws Exception {<br>    if (args.length < 1) {<br>      System.out.println("Please specify an output file name.");<br>      System.exit(1);<br>    }<br>    String id = args[0];<br><br>    // create blank image<br>    System.out.println("Creating random image...");<br>    byte[] img = new byte[w * h * COMPONENTS * FormatTools.getBytesPerPixel(PIXEL_TYPE)];<br>    System.out.println("Image Size in Bytes: " + img.length);<br>    <br>    /*<br>     * Wrong calculated size of output buffer because of integer overflow<br>     * Taken from LZWCodec.java - compress-method<br>     */<br>    System.out.println("Wrong LZW Buffer Size: " + (img.length * 141) / 100 + 3);<br>    <br>    // This would be the right size for the output buffer<br>    System.out.println("Right LZW Buffer Size: " + img.length * 1.41 + 3);<br>    <br>    // fill image with random data<br>    for (int i=0; i<img.length; i++) img[i] = (byte) (256 * Math.random());<br><br>    // create metadata object with minimum required metadata fields<br>    System.out.println("Populating metadata...");<br>    ServiceFactory factory = new ServiceFactory();<br>    OMEXMLService service = factory.getInstance(OMEXMLService.class);<br>    IMetadata meta = service.createOMEXMLMetadata();    <br>    MetadataTools.populateMetadata(meta, 0, null, false, "XYZCT", FormatTools.getPixelTypeString(PIXEL_TYPE), w, h, 1, COMPONENTS, 1, COMPONENTS);<br>   <br>    // Set up the writer for OME-TIFF<br>    TiffWriter writer = new OMETiffWriter();<br>    writer.setMetadataRetrieve(meta);<br>    writer.setInterleaved(Boolean.TRUE);<br>    writer.setBigTiff(false);<br>    writer.setId(id);<br><br>    // Set up IFD for creating a tiled OME-TIFF<br>    IFD ifd = new IFD();<br>    ifd.put(IFD.TILE_WIDTH, w);<br>    ifd.put(IFD.TILE_LENGTH, h);<br>    ifd.put(IFD.COMPRESSION, TiffCompression.LZW.getCode());<br>    <br>    // Save tile<br>    writer.saveBytes(0, img, ifd, 0, 0, w, h);<br>    <br>    writer.close();<br>  }<br><br>}<br></body></html>