< prev index next >

modules/javafx.graphics/src/main/native-iio/jpegloader.c

Print this page
@@ -1,7 +1,7 @@
  /*
-  * Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
+  * Copyright (c) 2009, 2019, 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.  Oracle designates this

@@ -684,10 +684,15 @@
  static void imageio_abort(JNIEnv *env, jobject this,
          imageIODataPtr data) {
      data->abortFlag = JNI_TRUE;
  }
  
+ static void disposeIIO(JNIEnv *env, imageIODataPtr data) {
+     j_common_ptr info = destroyImageioData(env, data);
+     imageio_dispose(info);
+ }
+ 
  /*************** end of shared utility code ****************/
  
  /********************** Loader Support **************************/
  
  /********************** Source Management ***********************/

@@ -1273,13 +1278,11 @@
  }
  
  JNIEXPORT void JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_disposeNative
  (JNIEnv *env, jclass cls, jlong ptr) {
      imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
-     j_common_ptr info = destroyImageioData(env, data);
- 
-     imageio_dispose(info);
+     disposeIIO(env, data);
  }
  
  #define JPEG_APP1  (JPEG_APP0 + 1)  /* EXIF APP1 marker code  */
  
  /*

@@ -1336,10 +1339,12 @@
      if (setjmp(jerr_mgr->setjmp_buffer)) {
          /* If we get here, the JPEG code has signaled an error. */
          char buffer[JMSG_LENGTH_MAX];
          (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                  buffer);
+         free(cinfo->err);
+         free(cinfo);
          ThrowByName(env, "java/io/IOException", buffer);
          return 0;
      }
  
      /* Perform library initialization */

@@ -1353,10 +1358,11 @@
       * Now set up our source.
       */
      cinfo->src =
              (struct jpeg_source_mgr *) malloc(sizeof (struct jpeg_source_mgr));
      if (cinfo->src == NULL) {
+         imageio_dispose((j_common_ptr) cinfo);
          ThrowByName(env,
                  "java/lang/OutOfMemoryError",
                  "Initializing Reader");
          return 0;
      }

@@ -1369,43 +1375,49 @@
      cinfo->src->term_source = imageio_term_source;
  
      /* set up the association to persist for future calls */
      data = initImageioData(env, (j_common_ptr) cinfo, this);
      if (data == NULL) {
+         imageio_dispose((j_common_ptr) cinfo);
          ThrowByName(env,
                  "java/lang/OutOfMemoryError",
                  "Initializing Reader");
          return 0;
      }
  
      imageio_set_stream(env, (j_common_ptr) cinfo, data, stream);
  
-     if ((*env)->ExceptionCheck(env)) return 0;
+     if ((*env)->ExceptionCheck(env)) {
+         disposeIIO(env, data);
+         return 0;
+     }
  
      imageio_init_source((j_decompress_ptr) cinfo);
  
      src = cinfo->src;
      jerr = (sun_jpeg_error_ptr) cinfo->err;
  
      /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
      if (setjmp(jerr->setjmp_buffer)) {
          /* If we get here, the JPEG code has signaled an error
             while reading the header. */
-         RELEASE_ARRAYS(env, data, src->next_input_byte);
+         disposeIIO(env, data);
          if (!(*env)->ExceptionOccurred(env)) {
              char buffer[JMSG_LENGTH_MAX];
              (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                      buffer);
              ThrowByName(env, "java/io/IOException", buffer);
          }
+ 
          return 0;
      }
  
      if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
          ThrowByName(env,
                  "java/io/IOException",
                  "Array pin failed");
+         disposeIIO(env, data);
          return 0;
      }
  
      jret = jpeg_read_header(cinfo, FALSE);
  

@@ -1498,10 +1510,11 @@
  
          /* read icc profile data */
          profileData = read_icc_profile(env, cinfo);
  
          if ((*env)->ExceptionCheck(env)) {
+             disposeIIO(env, data);
              return 0;
          }
  
          (*env)->CallVoidMethod(env, this,
                  JPEGImageLoader_setInputAttributesID,

@@ -1510,10 +1523,11 @@
                  cinfo->jpeg_color_space,
                  cinfo->out_color_space,
                  cinfo->num_components,
                  profileData);
          if ((*env)->ExceptionCheck(env)) {
+             disposeIIO(env, data);
              return 0;
          }
      }
  
      return ptr_to_jlong(data);

@@ -1604,12 +1618,12 @@
      imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
      j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
      struct jpeg_source_mgr *src = cinfo->src;
      sun_jpeg_error_ptr jerr;
      int bytes_per_row = cinfo->output_width * cinfo->output_components;
-     JSAMPROW scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof (JSAMPLE));
      int offset = 0;
+     JSAMPROW scanline_ptr = NULL;
  
      if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
          !SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
          ((*env)->GetArrayLength(env, barray) <
           (bytes_per_row * cinfo->output_height)))

@@ -1625,18 +1639,10 @@
                  "java/io/IOException",
                  "Array pin failed");
          return JNI_FALSE;
      }
  
-     if (scanline_ptr == NULL) {
-         ThrowByName(env,
-                 "java/lang/OutOfMemoryError",
-                 "Reading JPEG Stream");
-         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
-         return JNI_FALSE;
-     }
- 
      /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
      jerr = (sun_jpeg_error_ptr) cinfo->err;
  
      if (setjmp(jerr->setjmp_buffer)) {
          /* If we get here, the JPEG code has signaled an error

@@ -1645,62 +1651,74 @@
              char buffer[JMSG_LENGTH_MAX];
              (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
                      buffer);
              ThrowByName(env, "java/io/IOException", buffer);
          }
-         if (scanline_ptr != NULL) {
-             free(scanline_ptr);
-         }
          RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
          return JNI_FALSE;
      }
  
+     scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof(JSAMPLE));
+     if (scanline_ptr == NULL) {
+         ThrowByName(env,
+                 "java/lang/OutOfMemoryError",
+                 "Reading JPEG Stream");
+         return JNI_FALSE;
+     }
+ 
      while (cinfo->output_scanline < cinfo->output_height) {
          int num_scanlines;
          if (report_progress == JNI_TRUE) {
              RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
              (*env)->CallVoidMethod(env, this,
                      JPEGImageLoader_updateImageProgressID,
                      cinfo->output_scanline);
-             if ((*env)->ExceptionCheck(env)) return JNI_FALSE;
+             if ((*env)->ExceptionCheck(env)) {
+                 free(scanline_ptr);
+                 return JNI_FALSE;
+             }
              if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
-               ThrowByName(env,
+                 free(scanline_ptr);
+                 ThrowByName(env,
                            "java/io/IOException",
                            "Array pin failed");
-               return JNI_FALSE;
+                 return JNI_FALSE;
              }
          }
  
          num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
          if (num_scanlines == 1) {
              jboolean iscopy = FALSE;
              jbyte *body = (*env)->GetPrimitiveArrayCritical(env, barray, &iscopy);
              if (body == NULL) {
                  fprintf(stderr, "decompressIndirect: GetPrimitiveArrayCritical returns NULL: out of memory\n");
+                 free(scanline_ptr);
                  return JNI_FALSE;
              }
              memcpy(body+offset,scanline_ptr, bytes_per_row);
              (*env)->ReleasePrimitiveArrayCritical(env, barray, body, JNI_ABORT);
              offset += bytes_per_row;
          }
      }
+     free(scanline_ptr);
  
      if (report_progress == JNI_TRUE) {
          RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
          (*env)->CallVoidMethod(env, this,
                  JPEGImageLoader_updateImageProgressID,
                  cinfo->output_height);
-       if ((*env)->ExceptionCheck(env)) return JNI_FALSE;
-       if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
-           ThrowByName(env,
+         if ((*env)->ExceptionCheck(env)) {
+             return JNI_FALSE;
+         }
+         if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
+             ThrowByName(env,
                  "java/io/IOException",
                  "Array pin failed");
-           return JNI_FALSE;
-       }
+             return JNI_FALSE;
+         }
      }
  
      jpeg_finish_decompress(cinfo);
-     free(scanline_ptr);
  
      RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
      return JNI_TRUE;
  }
< prev index next >