<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>