8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener.
authorjdv
Thu, 29 Sep 2016 10:57:34 +0530
changeset 41403 be56daafbeaa
parent 41402 9ff91b2cd7a7
child 41404 584981a12276
8164931: Verify if writer.abort() works properly for all writers in IIOWriteProgressListener. Reviewed-by: prr, bpb, serb, psadhukhan
jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java
jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java
jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java
jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java
jdk/test/javax/imageio/WriteAbortTest.java
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java	Wed Sep 28 03:40:45 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java	Thu Sep 29 10:57:34 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,6 +156,10 @@
 
         clearAbortRequest();
         processImageStarted(0);
+        if (abortRequested()) {
+            processWriteAborted();
+            return;
+        }
         if (param == null)
             param = getDefaultWriteParam();
 
@@ -583,12 +587,8 @@
             stream.write(embedded_stream.toByteArray());
             embedded_stream = null;
 
-            if (abortRequested()) {
-                processWriteAborted();
-            } else {
-                processImageComplete();
-                stream.flushBefore(stream.getStreamPosition());
-            }
+            processImageComplete();
+            stream.flushBefore(stream.getStreamPosition());
 
             return;
         }
@@ -606,9 +606,6 @@
             destScanlineLength = destScanlineBytes / (DataBuffer.getDataTypeSize(dataType)>>3);
         }
         for (int i = 0; i < h; i++) {
-            if (abortRequested()) {
-                break;
-            }
 
             int row = minY + i;
 
@@ -724,6 +721,9 @@
             }
 
             processImageProgress(100.0f * (((float)i) / ((float)h)));
+            if (abortRequested()) {
+                break;
+            }
         }
 
         if (compressionType == BI_RLE4 ||
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Wed Sep 28 03:40:45 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageWriter.java	Thu Sep 29 10:57:34 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -574,7 +574,6 @@
                        IIOMetadata sm,
                        IIOImage iioimage,
                        ImageWriteParam p) throws IOException {
-        clearAbortRequest();
 
         RenderedImage image = iioimage.getRenderedImage();
 
@@ -829,11 +828,11 @@
             image.getTile(0, 0) : image.getData();
         for (int y = dy; y < dh; y += ddy) {
             if (numRowsWritten % progressReportRowPeriod == 0) {
+                processImageProgress((numRowsWritten*100.0F)/dh);
                 if (abortRequested()) {
                     processWriteAborted();
                     return;
                 }
-                processImageProgress((numRowsWritten*100.0F)/dh);
             }
 
             raster.getSamples(sx, sy, sw, 1, 0, sbuf);
@@ -857,11 +856,11 @@
         lineStride *= ddy;
         for (int y = dy; y < dh; y += ddy) {
             if (numRowsWritten % progressReportRowPeriod == 0) {
+                processImageProgress((numRowsWritten*100.0F)/dh);
                 if (abortRequested()) {
                     processWriteAborted();
                     return;
                 }
-                processImageProgress((numRowsWritten*100.0F)/dh);
             }
 
             compressor.compress(data, offset, dw);
@@ -924,7 +923,12 @@
 
         int progressReportRowPeriod = Math.max(destHeight/20, 1);
 
+        clearAbortRequest();
         processImageStarted(imageIndex);
+        if (abortRequested()) {
+            processWriteAborted();
+            return;
+        }
 
         if (interlaceFlag) {
             if (DEBUG) System.out.println("Writing interlaced");
@@ -973,6 +977,9 @@
                 writeRowsOpt(data, offset, lineStride, compressor,
                              1, 2, destWidth, destHeight,
                              numRowsWritten, progressReportRowPeriod);
+                if (abortRequested()) {
+                    return;
+                }
             } else {
                 writeRows(image, compressor,
                           sourceXOffset, periodX,
@@ -1016,6 +1023,9 @@
                           sourceWidth,
                           1, 2, destWidth, destHeight,
                           numRowsWritten, progressReportRowPeriod);
+                if (abortRequested()) {
+                    return;
+                }
             }
         } else {
             if (DEBUG) System.out.println("Writing non-interlaced");
@@ -1031,6 +1041,9 @@
                 writeRowsOpt(data, offset, lineStride, compressor,
                              0, 1, destWidth, destHeight,
                              numRowsWritten, progressReportRowPeriod);
+                if (abortRequested()) {
+                    return;
+                }
             } else {
                 writeRows(image, compressor,
                           sourceXOffset, periodX,
@@ -1038,15 +1051,12 @@
                           sourceWidth,
                           0, 1, destWidth, destHeight,
                           numRowsWritten, progressReportRowPeriod);
+                if (abortRequested()) {
+                    return;
+                }
             }
         }
 
-        if (abortRequested()) {
-            return;
-        }
-
-        processImageProgress(100.0F);
-
         compressor.flush();
 
         stream.write(0x00);
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java	Wed Sep 28 03:40:45 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageWriter.java	Thu Sep 29 10:57:34 2016 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1234,43 +1234,46 @@
         clearAbortRequest();
 
         processImageStarted(0);
-
-        try {
-            write_magic();
-            write_IHDR();
+        if (abortRequested()) {
+            processWriteAborted();
+        } else {
+            try {
+                write_magic();
+                write_IHDR();
 
-            write_cHRM();
-            write_gAMA();
-            write_iCCP();
-            write_sBIT();
-            write_sRGB();
+                write_cHRM();
+                write_gAMA();
+                write_iCCP();
+                write_sBIT();
+                write_sRGB();
 
-            write_PLTE();
+                write_PLTE();
 
-            write_hIST();
-            write_tRNS();
-            write_bKGD();
+                write_hIST();
+                write_tRNS();
+                write_bKGD();
 
-            write_pHYs();
-            write_sPLT();
-            write_tIME();
-            write_tEXt();
-            write_iTXt();
-            write_zTXt();
+                write_pHYs();
+                write_sPLT();
+                write_tIME();
+                write_tEXt();
+                write_iTXt();
+                write_zTXt();
 
-            writeUnknownChunks();
+                writeUnknownChunks();
+
+                write_IDAT(im, deflaterLevel);
 
-            write_IDAT(im, deflaterLevel);
-
-            if (abortRequested()) {
-                processWriteAborted();
-            } else {
-                // Finish up and inform the listeners we are done
-                writeIEND();
-                processImageComplete();
+                if (abortRequested()) {
+                    processWriteAborted();
+                } else {
+                    // Finish up and inform the listeners we are done
+                    writeIEND();
+                    processImageComplete();
+                }
+            } catch (IOException e) {
+                throw new IIOException("I/O error writing PNG file!", e);
             }
-        } catch (IOException e) {
-            throw new IIOException("I/O error writing PNG file!", e);
         }
     }
 }
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java	Wed Sep 28 03:40:45 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFImageWriter.java	Thu Sep 29 10:57:34 2016 +0530
@@ -2437,6 +2437,10 @@
 
         clearAbortRequest();
         processImageStarted(0);
+        if (abortRequested()) {
+            processWriteAborted();
+            return;
+        }
 
         // Optionally write the header.
         if (writeHeader) {
@@ -2587,9 +2591,6 @@
                         nextSpace = pos + byteCount;
                     }
 
-                    pixelsDone += tileRect.width*tileRect.height;
-                    processImageProgress(100.0F*pixelsDone/totalPixels);
-
                     // Fill in the offset and byte count for the file
                     stream.mark();
                     stream.seek(stripOrTileOffsetsPosition);
@@ -2600,14 +2601,16 @@
                     stream.writeInt(byteCount);
                     stripOrTileByteCountsPosition += 4;
                     stream.reset();
+
+                    pixelsDone += tileRect.width*tileRect.height;
+                    processImageProgress(100.0F*pixelsDone/totalPixels);
+                    if (abortRequested()) {
+                        processWriteAborted();
+                        return;
+                    }
                 } catch (IOException e) {
                     throw new IIOException("I/O error writing TIFF file!", e);
                 }
-
-                if (abortRequested()) {
-                    processWriteAborted();
-                    return;
-                }
             }
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/WriteAbortTest.java	Thu Sep 29 10:57:34 2016 +0530
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+ /*
+ * @test
+ * @bug     8164931
+ * @summary Test verifies that if we call ImageWriter.abort() in
+ *          IIOWriteProgressListener.imageStarted() or
+ *          IIOWriteProgressListener.imageProgress() are we
+ *          calling IIOWriteProgressListener.readAborted() for all readers.
+ * @run     main WriteAbortTest
+ */
+import java.awt.image.BufferedImage;
+import java.io.File;
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.nio.file.Files;
+import javax.imageio.ImageWriter;
+import javax.imageio.event.IIOWriteProgressListener;
+import javax.imageio.stream.ImageOutputStream;
+
+public class WriteAbortTest implements IIOWriteProgressListener {
+
+    ImageWriter writer = null;
+    ImageOutputStream ios = null;
+    BufferedImage bimg = null;
+    File file;
+    boolean startAbort = false;
+    boolean startAborted = false;
+    boolean progressAbort = false;
+    boolean progressAborted = false;
+    Color srccolor = Color.red;
+    int width = 100;
+    int heght = 100;
+
+    public WriteAbortTest(String format) throws Exception {
+        try {
+            System.out.println("Test for format " + format);
+            bimg = new BufferedImage(width, heght,
+                    BufferedImage.TYPE_INT_RGB);
+
+            Graphics2D g = bimg.createGraphics();
+            g.setColor(srccolor);
+            g.fillRect(0, 0, width, heght);
+            g.dispose();
+
+            file = File.createTempFile("src_", "." + format, new File("."));
+            ImageInputStream ios = ImageIO.createImageOutputStream(file);
+
+            ImageWriter writer =
+                    ImageIO.getImageWritersByFormatName(format).next();
+
+            writer.setOutput(ios);
+            writer.addIIOWriteProgressListener(this);
+
+            // Abort writing in IIOWriteProgressListener.imageStarted().
+            startAbort = true;
+            writer.write(bimg);
+            startAbort = false;
+
+            // Abort writing in IIOWriteProgressListener.imageProgress().
+            progressAbort = true;
+            writer.write(bimg);
+            progressAbort = false;
+
+            ios.close();
+            /*
+             * All abort requests from imageStarted,imageProgress
+             * from IIOWriteProgressListener should be reached
+             * otherwise throw RuntimeException.
+             */
+            if (!(startAborted
+                    && progressAborted)) {
+                throw new RuntimeException("All IIOWriteProgressListener abort"
+                        + " requests are not processed for format "
+                        + format);
+            }
+        } finally {
+            Files.delete(file.toPath());
+        }
+    }
+
+    /*
+     * Abstract methods that we need to implement from
+     * IIOWriteProgressListener, and relevant for this test case.
+     */
+    @Override
+    public void imageStarted(ImageWriter source, int imageIndex) {
+        System.out.println("imageStarted called");
+        if (startAbort) {
+            source.abort();
+        }
+    }
+
+    @Override
+    public void imageProgress(ImageWriter source, float percentageDone) {
+        System.out.println("imageProgress called");
+        if (progressAbort) {
+            source.abort();
+        }
+    }
+
+    @Override
+    public void writeAborted(ImageWriter source) {
+        System.out.println("writeAborted called");
+        // Verify IIOWriteProgressListener.imageStarted() abort request.
+        if (startAbort) {
+            System.out.println("imageStarted aborted ");
+            startAborted = true;
+        }
+
+        // Verify IIOWriteProgressListener.imageProgress() abort request.
+        if (progressAbort) {
+            System.out.println("imageProgress aborted ");
+            progressAborted = true;
+        }
+    }
+
+    public static void main(String args[]) throws Exception {
+        final String[] formats = {"bmp", "png", "gif", "jpg", "tif"};
+        for (String format : formats) {
+            new WriteAbortTest(format);
+        }
+    }
+
+    /*
+     * Remaining abstract methods that we need to implement from
+     * IIOWriteProgressListener, but not relevant for this test case.
+     */
+    @Override
+    public void imageComplete(ImageWriter source) {
+    }
+
+    @Override
+    public void thumbnailStarted(ImageWriter source, int imageIndex,
+                                 int thumbnailIndex) {
+    }
+
+    @Override
+    public void thumbnailProgress(ImageWriter source, float percentageDone) {
+    }
+
+    @Override
+    public void thumbnailComplete(ImageWriter source) {
+    }
+}
+