FOP-3055: Use a event for a draw image error

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1898074 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java b/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
index e9499f8..fbcd164 100644
--- a/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
+++ b/fop-core/src/main/java/org/apache/fop/render/intermediate/AbstractIFPainter.java
@@ -51,6 +51,7 @@
 import org.apache.fop.fonts.FontTriplet;
 import org.apache.fop.fonts.MultiByteFont;
 import org.apache.fop.fonts.truetype.SVGGlyphData;
+import org.apache.fop.pdf.PDFConformanceException;
 import org.apache.fop.render.ImageHandler;
 import org.apache.fop.render.ImageHandlerRegistry;
 import org.apache.fop.render.ImageHandlerUtil;
@@ -171,10 +172,12 @@
 
         try {
             drawImage(img, rect, context);
-        } catch (IOException ioe) {
+        } catch (PDFConformanceException e) {
+            throw e;
+        } catch (Exception e) {
             ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
                     getUserAgent().getEventBroadcaster());
-            eventProducer.imageWritingError(this, ioe);
+            eventProducer.imageWritingError(this, e);
         }
     }
 
diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java b/fop-core/src/main/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java
index 3988fdf..56a9eba 100644
--- a/fop-core/src/main/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java
+++ b/fop-core/src/main/java/org/apache/fop/render/ps/PSGraphics2DAdapter.java
@@ -106,25 +106,27 @@
         // scale to viewbox
         transform.translate(fx, fy);
         gen.getCurrentState().concatMatrix(transform);
-        if (paintAsBitmap) {
-            //Fallback solution: Paint to a BufferedImage
-            int resolution = Math.round(context.getUserAgent().getTargetResolution());
-            RendererContextWrapper ctx = RendererContext.wrapRendererContext(context);
-            BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false);
+        try {
+            if (paintAsBitmap) {
+                //Fallback solution: Paint to a BufferedImage
+                int resolution = Math.round(context.getUserAgent().getTargetResolution());
+                RendererContextWrapper ctx = RendererContext.wrapRendererContext(context);
+                BufferedImage bi = paintToBufferedImage(painter, ctx, resolution, false, false);
 
-            float scale = PDFFactory.DEFAULT_PDF_RESOLUTION
-                            / context.getUserAgent().getTargetResolution();
-            graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null);
-        } else {
-            if (painter instanceof GeneralGraphics2DImagePainter) {
-                PSFontUtils.addFallbackFonts(fontInfo, (GeneralGraphics2DImagePainter) painter);
+                float scale = PDFFactory.DEFAULT_PDF_RESOLUTION
+                        / context.getUserAgent().getTargetResolution();
+                graphics.drawImage(bi, new AffineTransform(scale, 0, 0, scale, 0, 0), null);
+            } else {
+                if (painter instanceof GeneralGraphics2DImagePainter) {
+                    PSFontUtils.addFallbackFonts(fontInfo, (GeneralGraphics2DImagePainter) painter);
+                }
+                Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
+                painter.paint(graphics, area);
             }
-            Rectangle2D area = new Rectangle2D.Double(0.0, 0.0, imw, imh);
-            painter.paint(graphics, area);
+        } finally {
+            gen.restoreGraphicsState();
+            gen.commentln("%FOPEndGraphics2D");
         }
-
-        gen.restoreGraphicsState();
-        gen.commentln("%FOPEndGraphics2D");
     }
 
 }
diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/PSImageHandlerGraphics2D.java b/fop-core/src/main/java/org/apache/fop/render/ps/PSImageHandlerGraphics2D.java
index f128ecc..aefbb41 100644
--- a/fop-core/src/main/java/org/apache/fop/render/ps/PSImageHandlerGraphics2D.java
+++ b/fop-core/src/main/java/org/apache/fop/render/ps/PSImageHandlerGraphics2D.java
@@ -98,9 +98,12 @@
         if (painter instanceof GeneralGraphics2DImagePainter) {
             PSFontUtils.addFallbackFonts(psContext.getFontInfo(), (GeneralGraphics2DImagePainter) painter);
         }
-        painter.paint(graphics, area);
-        gen.restoreGraphicsState();
-        gen.commentln("%FOPEndGraphics2D");
+        try {
+            painter.paint(graphics, area);
+        } finally {
+            gen.restoreGraphicsState();
+            gen.commentln("%FOPEndGraphics2D");
+        }
     }
 
     /** {@inheritDoc} */
@@ -161,9 +164,12 @@
                     gen.writeln("  /Filter /SubFileDecode");
                     gen.writeln("  /DecodeParms << /EODCount 0 /EODString (%FOPEndOfData) >>");
                     gen.writeln(">> /ReusableStreamDecode filter");
-                    paintImageG2D(imageG2D, dimensionsMpt, gen, fontInfo);
-                    gen.writeln("%FOPEndOfData");
-                    gen.writeln("def");
+                    try {
+                        paintImageG2D(imageG2D, dimensionsMpt, gen, fontInfo);
+                    } finally {
+                        gen.writeln("%FOPEndOfData");
+                        gen.writeln("def");
+                    }
                 }
 
                 @Override
diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java b/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java
index ac3ad5b..7144aaf 100644
--- a/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java
+++ b/fop-core/src/main/java/org/apache/fop/render/ps/ResourceHandler.java
@@ -327,6 +327,10 @@
                     userAgent.getEventBroadcaster());
             eventProducer.imageError(resTracker, (info != null ? info.toString() : uri),
                     ie, null);
+        } catch (Exception e) {
+            ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
+                    userAgent.getEventBroadcaster());
+            eventProducer.imageWritingError(this, e);
         }
     }
 
diff --git a/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java
index 4215bdc..3add2a4 100644
--- a/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/render/afp/AFPPainterTestCase.java
@@ -46,7 +46,9 @@
 import static org.mockito.Mockito.when;
 
 import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
 import org.apache.xmlgraphics.image.loader.ImageFlavor;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.impl.DefaultImageContext;
 import org.apache.xmlgraphics.image.loader.impl.DefaultImageSessionContext;
@@ -62,7 +64,9 @@
 import org.apache.fop.afp.fonts.RasterFont;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FopFactory;
+import org.apache.fop.events.Event;
 import org.apache.fop.events.EventBroadcaster;
+import org.apache.fop.events.EventListener;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fo.expr.PropertyException;
 import org.apache.fop.fonts.Font;
@@ -383,4 +387,38 @@
                 + "END PAGE_GROUP PGP00001\n"
                 + "END DOCUMENT DOC00001\n");
     }
+
+    @Test
+    public void testEventOnImageParseException() throws Exception {
+        FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+        AFPDocumentHandler dh = new AFPDocumentHandler(new IFContext(ua));
+        dh.setResult(new StreamResult(new ByteArrayOutputStream()));
+        dh.startDocument();
+        dh.startPage(0, "", "", new Dimension());
+        MyAFPPainter afpPainter = new MyAFPPainter(dh);
+        ImageInfo info = new ImageInfo("test/resources/fop/image/logo.jpg", "image/jpeg") {
+            public Image getOriginalImage() {
+                throw new RuntimeException();
+            }
+        };
+        final Event[] event = new Event[1];
+        ua.getEventBroadcaster().addEventListener(new EventListener() {
+            public void processEvent(Event e) {
+                event[0] = e;
+            }
+        });
+        afpPainter.drawImageUsingImageHandler(info, new Rectangle());
+        Assert.assertEquals(event[0].getEventKey(), "imageWritingError");
+    }
+
+    static class MyAFPPainter extends AFPPainter {
+        MyAFPPainter(AFPDocumentHandler documentHandler) {
+            super(documentHandler);
+        }
+
+        protected void drawImageUsingImageHandler(ImageInfo info, Rectangle rect)
+                throws ImageException, IOException {
+            super.drawImageUsingImageHandler(info, rect);
+        }
+    }
 }
diff --git a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
index 387afef..f95e9f3 100644
--- a/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/render/pdf/PDFPainterTestCase.java
@@ -45,8 +45,14 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import org.apache.xmlgraphics.image.loader.Image;
+import org.apache.xmlgraphics.image.loader.ImageException;
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FopFactory;
+import org.apache.fop.events.Event;
+import org.apache.fop.events.EventListener;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fonts.FontInfo;
 import org.apache.fop.fonts.FontTriplet;
@@ -139,9 +145,9 @@
         assertEquals(pdfPainter.renderingContext.getHints().get("page-number"), 3);
     }
 
-    class MyPDFPainter extends PDFPainter {
-        protected RenderingContext renderingContext;
-        public MyPDFPainter(PDFDocumentHandler documentHandler, PDFLogicalStructureHandler logicalStructureHandler) {
+    static class MyPDFPainter extends PDFPainter {
+        RenderingContext renderingContext;
+        MyPDFPainter(PDFDocumentHandler documentHandler, PDFLogicalStructureHandler logicalStructureHandler) {
             super(documentHandler, logicalStructureHandler);
         }
 
@@ -149,6 +155,10 @@
             renderingContext = super.createRenderingContext();
             return renderingContext;
         }
+
+        protected void drawImageUsingImageHandler(ImageInfo info, Rectangle rect) throws ImageException, IOException {
+            super.drawImageUsingImageHandler(info, rect);
+        }
     }
 
     @Test
@@ -394,4 +404,27 @@
         pdfPainter.generator.getStream().output(bos);
         return bos.toString();
     }
+
+    @Test
+    public void testEventOnImageParseException() throws Exception {
+        FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+        PDFDocumentHandler dh = new PDFDocumentHandler(new IFContext(ua));
+        dh.setResult(new StreamResult(new ByteArrayOutputStream()));
+        dh.startDocument();
+        dh.startPage(0, "", "", new Dimension());
+        MyPDFPainter pdfPainter = new MyPDFPainter(dh, null) {
+            protected void drawImage(Image image, Rectangle rect, RenderingContext context) {
+                throw new RuntimeException();
+            }
+        };
+        ImageInfo info = new ImageInfo("test/resources/fop/image/logo.jpg", "image/jpeg");
+        final Event[] event = new Event[1];
+        ua.getEventBroadcaster().addEventListener(new EventListener() {
+            public void processEvent(Event e) {
+                event[0] = e;
+            }
+        });
+        pdfPainter.drawImageUsingImageHandler(info, new Rectangle());
+        Assert.assertEquals(event[0].getEventKey(), "imageWritingError");
+    }
 }
diff --git a/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java b/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
index 61100bf..421f2ea 100644
--- a/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/render/ps/PSPainterTestCase.java
@@ -45,11 +45,15 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import org.apache.xmlgraphics.image.loader.ImageInfo;
+import org.apache.xmlgraphics.image.loader.ImageSize;
 import org.apache.xmlgraphics.ps.PSGenerator;
 import org.apache.xmlgraphics.ps.dsc.ResourceTracker;
 
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.apps.FopFactory;
+import org.apache.fop.events.Event;
+import org.apache.fop.events.EventListener;
 import org.apache.fop.fo.Constants;
 import org.apache.fop.fonts.EmbeddingMode;
 import org.apache.fop.fonts.Font;
@@ -280,4 +284,26 @@
         Assert.assertTrue(bos.toString().contains("[0.00012 0 0 0.00012 0 0] CT"));
         Assert.assertTrue(bos.toString().contains("1 0 0 RC"));
     }
+
+    @Test
+    public void testEventOnImageParseException() throws Exception {
+        FOUserAgent ua = FopFactory.newInstance(new File(".").toURI()).newFOUserAgent();
+        PSDocumentHandler dh = new PSDocumentHandler(new IFContext(ua));
+        dh.setResult(new StreamResult(new ByteArrayOutputStream()));
+        PSPainter psPainter = new PSPainter(dh);
+        dh.startDocument();
+        ImageInfo info = new ImageInfo("test/resources/fop/image/logo.jpg", "image/jpeg") {
+            public ImageSize getSize() {
+                throw new RuntimeException();
+            }
+        };
+        final Event[] event = new Event[1];
+        ua.getEventBroadcaster().addEventListener(new EventListener() {
+            public void processEvent(Event e) {
+                event[0] = e;
+            }
+        });
+        psPainter.drawImageUsingImageHandler(info, new Rectangle());
+        Assert.assertEquals(event[0].getEventKey(), "imageWritingError");
+    }
 }
diff --git a/fop/lib/xmlgraphics-commons-svn-trunk.jar b/fop/lib/xmlgraphics-commons-svn-trunk.jar
index 0bc32ba..d45509a 100644
--- a/fop/lib/xmlgraphics-commons-svn-trunk.jar
+++ b/fop/lib/xmlgraphics-commons-svn-trunk.jar
Binary files differ