1

I need to read a very large image file (56000 px X 49000 px). I need to read it in small rectangular chunks, so I am trying to follow this example: Read region from very large image file in Java

However, I get this error: java.lang.IllegalArgumentException: width*height > Integer.MAX_VALUE!

My code snippet is below (taken more or less exactly from the link above):

ImageInputStream stream = null;
    try {
        stream = ImageIO.createImageInputStream(new File(this.inFile)); // File or input stream
    } catch (Exception ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }
    Iterator<ImageReader> readers = ImageIO.getImageReaders(stream);

    ImageReader r = readers.next();
    System.out.println("Using reader: " + r);
    r.setInput(stream);
    try {
        System.out.println("Height = " + r.getHeight(0));
        System.out.println("Width = " + r.getWidth(0));
    } catch (IOException ex) {
        Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
    }

ImageReadParam param = r.getDefaultReadParam();
Rectangle sourceRegion = new Rectangle(0, 0, 200, 200);
param.setSourceRegion(sourceRegion); // Set region

        BufferedImage image = null;
        try {
            image = r.read(0, param); // Will read only the region specified
            System.out.println("Read file " + this.inFile);
            System.out.println("Width = " + image.getWidth());
            System.out.println("Height = " + image.getHeight());
        } catch (Exception ex) {
            Logger.getLogger(CreateTrainingSetFromImage.class.getName()).log(Level.SEVERE, null, ex);
        }

My understanding is that specifying the Rectangle sourceRegion for param would make the ImageReader read only that small chunk of the image, so I don't understand what's causing the error. Any help would be much appreciated. If it helps, I am using the TwelveMonkeys ImageIO plugins.

Here is the output:

Using reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@5437dd04
Height = 49429
Width = 56281
Apr 23, 2017 11:57:17 AM createtrainingsetfromimage.CreateTrainingSetFromImage    test
SEVERE: null
java.lang.IllegalArgumentException: width*height > Integer.MAX_VALUE!
at javax.imageio.ImageReader.getDestination(ImageReader.java:2840)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(JPEGImageReader.java:1066)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:1034)
at com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader.read(JPEGImageReader.java:382)
at createtrainingsetfromimage.CreateTrainingSetFromImage.test(CreateTrainingSetFromImage.java:102)
at createtrainingsetfromimage.CreateTrainingSetFromImage.createTrainingSet(CreateTrainingSetFromImage.java:168)
at createtrainingsetfromimage.CreateTrainingSetFromImage.main(CreateTrainingSetFromImage.java:46)
Community
  • 1
  • 1
Samarth
  • 133
  • 1
  • 6
  • where does the exception occur? – Albert Apr 23 '17 at 06:13
  • I am not sure what is the source of the error , but it suggest that you need to use double. – c0der Apr 23 '17 at 06:16
  • Provide a stacktrace, please, and indicate on which line the error is occuring. I'm going to guess `ImageIO.createImageInputStream` does a calculation with the width and height which exceeds the max integer size. – Christopher Schneider Apr 23 '17 at 06:20
  • The error occurs at image = r.read(0, param); I've edited the post to include the output. – Samarth Apr 23 '17 at 16:00
  • @Samarth Are you able to post a link to such a huge image, for test purposes? – Harald K Apr 24 '17 at 08:41
  • @haraldK Here is a link to the jpeg I am using for test purposes: http://www.filedropper.com/floydclass – Samarth Apr 24 '17 at 13:45
  • @haraldK Hmm... I just tried it again (in both Firefox and Chrome) and was able to download it. Let me try to find another file hosting service to share it. – Samarth Apr 24 '17 at 17:56
  • @Samarth Never mind, probably just an issue with the work network. Works fine now from a different location. – Harald K Apr 24 '17 at 19:49

1 Answers1

0

There's a known bug/limitation in the getDestination method of the ImageReader base class (the super class of the JPEGImageReader and all other ImageIO reader implementations), that calculates the width * height of the input image, rather than the region you are actually trying to read... This prevents you from reading even small parts of such images.

The code looks like this, and the width and height parameters are the dimensions of the input:

if ((long) width * height > Integer.MAX_VALUE) {
    throw new IllegalArgumentException("width*height > Integer.MAX_VALUE!");
}

In most of my (the TwelveMonkeys ImageIO library's) ImageReaders I work around this limitation by using a different implementation of the getDestination method. But for the JPEGImageReader I delegate the actual decoding to the com.sun....JPEGImageReader, which uses the original method, and causes this exception.

It might be possible to work around the problem by using the readRaster method instead of read (as it does not use the getDestination method), but it requires extra work, and I haven't had the possibility to test this yet.

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • I am using a jpeg for testing (I posted the link in response to your comments above). I actually need to use it with tiff files. When I tried the same code with a tiff, I got the following error: `Exception in thread "main" java.util.NoSuchElementException` at the line `ImageReader r = readers.next();`. Prior to that I check to make sure that the TwelveMonkeys `TIFFImageReader` is registered as a tiff reader, so that is not the problem. Does this indicate my tiff image is non-compliant somehow? – Samarth Apr 24 '17 at 13:46
  • If you are 100% sure the `TIFFImageReader` is registered, then that indicates that your file isn't a TIFF file (the logic for detecting is quite simple, inspecting only the first 4 bytes). Perhaps it's a BigTIFF? – Harald K Apr 24 '17 at 13:53
  • I think it may have been generated from arcGIS, so it might be a geotiff. – Samarth Apr 24 '17 at 17:53
  • Here's a link to the tiff file if you want to try it: http://www.filedropper.com/floydclass_1 – Samarth Apr 25 '17 at 00:01
  • @Samarth As I thought, the file is a [BigTIFF](http://stackoverflow.com/q/43376951/1428606). The TwelveMonkeys `TIFFImageReader` does not support BigTIFF currently. It might in the future, though. :-) – Harald K Apr 25 '17 at 07:28
  • Thanks for your help with this. I wouldn't have figured it out on my own. – Samarth Apr 25 '17 at 17:01
  • @Samarth FYI: I'm planning to add [support for BigTIFF](https://github.com/haraldk/TwelveMonkeys/issues/342) in the next version of the library. – Harald K Apr 27 '17 at 10:12