3

At the moment I'm trying to print some pdfs in java. The API used is Apache PDF Box in Version 2.0. After converting the images I write them to disk to save memory. In the next step I read them again and write the title in the head of the image. After that I write them again. To use them I read them again separately. When I read them for the last time I get the following exception every 200-300 images:

java.lang.IndexOutOfBoundsException: off < 0 || len < 0 || off+len > b.length || off+len < 0!
at javax.imageio.stream.MemoryCacheImageInputStream.read(MemoryCacheImageInputStream.java:100)
  at com.sun.imageio.plugins.common.SubImageInputStream.read(SubImageInputStream.java:61)
  at com.sun.imageio.plugins.common.InputStreamAdapter.read(InputStreamAdapter.java:47)
  at java.io.SequenceInputStream.read(SequenceInputStream.java:207)
  at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:238)
  at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
  at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
  at java.io.BufferedInputStream.read(BufferedInputStream.java:265)
  at java.io.FilterInputStream.read(FilterInputStream.java:83)
  at com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1104)
  at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1215)
  at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1330)
  at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1606)
  at javax.imageio.ImageIO.read(ImageIO.java:1448)
  at javax.imageio.ImageIO.read(ImageIO.java:1400)
  at my.code.Class.method()

I use the following code to convert the PDFs:

final HashMap<Integer, File> images = new HashMap<>();
PDDocument document = PDDocument.load(sourceFile);

PDFRenderer pdfRenderer = new PDFRenderer(document);
final ExecutorService service = Executors.newFixedThreadPool(4);
for (int page = 0; page < document.getNumberOfPages(); ++page)
{
    final int finalPageNumber = page;
    Runnable r = () -> {
        try
        {
            //Java could only print with 72 dpi so I'll use it
            BufferedImage image = pdfRenderer.renderImageWithDPI(finalPageNumber, 72);
            File imageFile = new File(sourceFile.getAbsolutePath() + "-" + (finalPageNumber + 1) + ".png");
            ImageIO.write(image, "png", imageFile);
            image.flush();
            images.put(finalPageNumber, imageFile);
        }
        catch (final IOException e)
        {
            e.printStackTrace();
        }
    };
    Thread t = new Thread(r, page + "");
    t.setName("" + page);
    service.submit(t);
}

And for reading is the following code used:

// example url: /tmp/example.pdf-17.png
Image i = ImageIO.read(url);

What about to solve this problem


edit

What I've forgotten to say I add a Title manually to the Image:

                BufferedImage bimage = new BufferedImage(   simple.getValue().getWidth(null),
                                                                        simple.getValue().getHeight(null) + 50,
                                                                        BufferedImage.TYPE_INT_ARGB);
                Graphics bGr = bimage.createGraphics();
                bGr.setColor(Color.WHITE);
                bGr.fillRect(0, 0, bimage.getWidth(), bimage.getHeight());
                bGr.setFont(new Font("Arial", Font.PLAIN, 15));
                bGr.setColor(Color.BLACK);
                bGr.drawImage(simple.getValue(), 0, 50, null);
                bGr.drawString(entry.getValue(), 20, 20);
                try
                {
                    ImageIO.write(bimage, "PNG", new File(simple.getKey().toURI()));
                }
                catch (IOException | URISyntaxException e)
                {                       
                    e.printStackTrace();
                }
                bGr.dispose();

And here are the links to the files (It could occur with every page):

Image which throws the exception

PDF file which is used (generated by Word2007)

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
finder2
  • 842
  • 1
  • 11
  • 30
  • 1
    Can you attach one of the files that causes this exception, or does it happen at random? – Harald K Apr 20 '16 at 15:31
  • @haraldK I think it happen randomly because I've tried it with several files from multiple sources but I will attach some example files. – finder2 Apr 21 '16 at 04:47
  • @RobertoDeLaParra is there a diffrence? the value isn't used at this position – finder2 Apr 21 '16 at 04:53
  • 1
    @finder2 in Java, writing `page++` is far more common than `++page` since the compiler can always generate good enough code. Writing `++page` comes from C++, where that operator can be defined on any type and can lead to inefficient code. Search for `pre-increment` to find lots of lengthy debates about this topic. – Roland Illig Apr 21 '16 at 06:03
  • 1
    @RolandIllig, RobertoDeLaParra: While it certainly looks unfamiliar in Java, and I'm sure you mean to be helpful, it really [doesn't make a difference](http://stackoverflow.com/questions/1918196/why-doesnt-changing-the-pre-to-the-post-increment-at-the-iteration-part-of-a-fo), and draws the attention away from the real problem the OP has. The exception is *not* related to pre- or postfix operators. – Harald K Apr 21 '16 at 08:11
  • @finder2 Did you experience the exception with the exact file you attached (the PNG)? Because I see nothing wrong with it, neither do I get an exception trying to read it using `ImageIO`. If so, the problem must be with the reading code only... Can you post all of it? Otherwise, please link an image where the exception happened (even if it's broken, that is point). – Harald K Apr 21 '16 at 08:14
  • @haraldK no it's realy randomly. I've discoverd that the problem is caused by the adding of the Title. Sometimes there are 5 exceptions and sometimes nothing occurs. – finder2 Apr 21 '16 at 08:32
  • When adding the title, are you overwriting an existing file? And perhaps reading this in a multithreaded environment? It's not really clear (to me at least) how all the code snippets you have posted fits together, so I'm unable to reproduce the exception. Try to isolate the problem and create a standalone program that exposes the exception, and you are much more likely to get help. – Harald K Apr 21 '16 at 08:43
  • 1
    PS: It would also help if you could run your code through a debugger, and put a breakpoint at `MemoryCacheImageInputStream` line 100, just to see exactly which one of the conditions are met. – Harald K Apr 21 '16 at 10:50
  • @haraldK I've debugged it. At line 100 there was everything fine when the exception was thrown. – finder2 Apr 22 '16 at 05:13
  • I don't understand... If everything is fine, you don't reach line 100 at all. But seems you solved your problem anyway. – Harald K Apr 22 '16 at 05:38
  • @haraldK I had debugged and if i went up in the stacktrace the values were fine. So I didn't understoot it – finder2 Apr 22 '16 at 11:23

1 Answers1

1

I have solved my Problem. I hadn't wait for the writing of the Image. Now I wait for the finish of the ExecutorService and everything works fine.

I think there was a problem to free resources, since I've seen that at MemoryCacheImageInputStream line 100 every thing was fine when the exception was thrown.

finder2
  • 842
  • 1
  • 11
  • 30