8169209: Improved image post-processing steps
authorprr
Fri, 18 Nov 2016 10:27:13 -0800
changeset 45973 3daf29464c02
parent 45769 2ed643787f98
child 45974 321669d70772
8169209: Improved image post-processing steps Reviewed-by: serb, vadim, mschoene
jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java
jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Mon Jun 26 18:48:25 2017 -0700
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Fri Nov 18 10:27:13 2016 -0800
@@ -392,6 +392,17 @@
         }
     }
 
+    private void skipPastImage(int imageIndex) {
+        cbLock.lock();
+        try {
+            gotoImage(imageIndex);
+            skipImage();
+        } catch (IOException | IndexOutOfBoundsException e) {
+        } finally {
+            cbLock.unlock();
+        }
+    }
+
     @SuppressWarnings("fallthrough")
     private int getNumImagesOnThread(boolean allowSearch)
       throws IOException {
@@ -1340,7 +1351,8 @@
          * just a 1-line intermediate data transfer buffer that will not
          * affect the acceleration of the resulting image.
          */
-        boolean aborted = readImage(structPointer,
+        boolean aborted = readImage(imageIndex,
+                                    structPointer,
                                     buffer.getData(),
                                     numRasterBands,
                                     srcBands,
@@ -1502,7 +1514,8 @@
     /**
      * Returns {@code true} if the read was aborted.
      */
-    private native boolean readImage(long structPointer,
+    private native boolean readImage(int imageIndex,
+                                     long structPointer,
                                      byte [] buffer,
                                      int numRasterBands,
                                      int [] srcBands,
--- a/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	Mon Jun 26 18:48:25 2017 -0700
+++ b/jdk/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c	Fri Nov 18 10:27:13 2016 -0800
@@ -72,6 +72,7 @@
 static jmethodID JPEGImageReader_pushBackID;
 static jmethodID JPEGImageReader_passStartedID;
 static jmethodID JPEGImageReader_passCompleteID;
+static jmethodID JPEGImageReader_skipPastImageID;
 static jmethodID JPEGImageWriter_writeOutputDataID;
 static jmethodID JPEGImageWriter_warningOccurredID;
 static jmethodID JPEGImageWriter_warningWithMessageID;
@@ -1472,6 +1473,10 @@
                                                      cls,
                                                      "pushBack",
                                                      "(I)V"));
+    CHECK_NULL(JPEGImageReader_skipPastImageID = (*env)->GetMethodID(env,
+                                                     cls,
+                                                     "skipPastImage",
+                                                     "(I)V"));
     CHECK_NULL(JPEGQTable_tableID = (*env)->GetFieldID(env,
                                             qTableClass,
                                             "qTable",
@@ -1853,6 +1858,7 @@
 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_readImage
     (JNIEnv *env,
      jobject this,
+     jint imageIndex,
      jlong ptr,
      jbyteArray buffer,
      jint numBands,
@@ -2181,12 +2187,23 @@
      * We are done, but we might not have read all the lines, or all
      * the passes, so use jpeg_abort instead of jpeg_finish_decompress.
      */
-    if (cinfo->output_scanline == cinfo->output_height) {
-        //    if ((cinfo->output_scanline == cinfo->output_height) &&
-        //(jpeg_input_complete(cinfo))) {  // We read the whole file
+    if ((cinfo->output_scanline != cinfo->output_height) ||
+        data->abortFlag == JNI_TRUE)
+     {
+        jpeg_abort_decompress(cinfo);
+     } else if ((!jpeg_input_complete(cinfo)) &&
+                (progressive &&
+                 (cinfo->input_scan_number > maxProgressivePass))) {
+        /* We haven't reached EOI, but we need to skip to there */
+        (*cinfo->src->term_source) (cinfo);
+        /* We can use jpeg_abort to release memory and reset global_state */
+        jpeg_abort((j_common_ptr) cinfo);
+        (*env)->CallVoidMethod(env,
+                               this,
+                               JPEGImageReader_skipPastImageID,
+                               imageIndex);
+    } else {
         jpeg_finish_decompress(cinfo);
-    } else {
-        jpeg_abort_decompress(cinfo);
     }
 
     free(scanLinePtr);