src/share/native/sun/awt/image/jpeg/imageioJPEG.c

Print this page

        

*** 105,115 ****
   */
  
  /******************** StreamBuffer definition ************************/
  
  typedef struct streamBufferStruct {
!     jobject stream;            // ImageInputStream or ImageOutputStream
      jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
      JOCTET *buf;               // Pinned buffer pointer */
      int bufferOffset;          // holds offset between unpin and the next pin
      int bufferLength;          // Allocated, nut just used
      int suspendable;           // Set to true to suspend input
--- 105,115 ----
   */
  
  /******************** StreamBuffer definition ************************/
  
  typedef struct streamBufferStruct {
!     jweak ioRef;               // weak reference to a provider of I/O routines
      jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
      JOCTET *buf;               // Pinned buffer pointer */
      int bufferOffset;          // holds offset between unpin and the next pin
      int bufferLength;          // Allocated, nut just used
      int suspendable;           // Set to true to suspend input

*** 124,133 ****
--- 124,142 ----
   * seems too big and 1K seems too small.  If 4K was good enough for the
   * IJG folks, it's good enough for me.
   */
  #define STREAMBUF_SIZE 4096
  
+ #define GET_IO_REF(io_name)                                            \
+     do {                                                               \
+         if ((*env)->IsSameObject(env, sb->ioRef, NULL) ||              \
+             ((io_name) = (*env)->NewLocalRef(env, sb->ioRef)) == NULL) \
+         {                                                              \
+             cinfo->err->error_exit((j_common_ptr) cinfo);              \
+         }                                                              \
+     } while (0)                                                        \
+ 
  /*
   * Used to signal that no data need be restored from an unpin to a pin.
   * I.e. the buffer is empty.
   */
  #define NO_DATA -1

*** 158,168 ****
                           "Initializing Reader");
          return NOT_OK;
      }
  
  
!     sb->stream = NULL;
  
      sb->buf = NULL;
  
      resetStreamBuffer(env, sb);
  
--- 167,177 ----
                           "Initializing Reader");
          return NOT_OK;
      }
  
  
!     sb->ioRef = NULL;
  
      sb->buf = NULL;
  
      resetStreamBuffer(env, sb);
  

*** 190,202 ****
   * The global reference to the stream is released, but the reference
   * to the buffer is retained.  The buffer is unpinned if it was pinned.
   * All other state is reset.
   */
  static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
!     if (sb->stream != NULL) {
!         (*env)->DeleteGlobalRef(env, sb->stream);
!         sb->stream = NULL;
      }
      unpinStreamBuffer(env, sb, NULL);
      sb->bufferOffset = NO_DATA;
      sb->suspendable = FALSE;
      sb->remaining_skip = 0;
--- 199,211 ----
   * The global reference to the stream is released, but the reference
   * to the buffer is retained.  The buffer is unpinned if it was pinned.
   * All other state is reset.
   */
  static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb) {
!     if (sb->ioRef != NULL) {
!         (*env)->DeleteWeakGlobalRef(env, sb->ioRef);
!         sb->ioRef = NULL;
      }
      unpinStreamBuffer(env, sb, NULL);
      sb->bufferOffset = NO_DATA;
      sb->suspendable = FALSE;
      sb->remaining_skip = 0;

*** 580,604 ****
  /*************** Shared utility code ***********************/
  
  static void imageio_set_stream(JNIEnv *env,
                                 j_common_ptr cinfo,
                                 imageIODataPtr data,
!                                jobject stream){
      streamBufferPtr sb;
      sun_jpeg_error_ptr jerr;
  
      sb = &data->streamBuf;
  
      resetStreamBuffer(env, sb);  // Removes any old stream
  
!     /* Now we need a new global reference for the stream */
!     if (stream != NULL) { // Fix for 4411955
!         sb->stream = (*env)->NewGlobalRef(env, stream);
!         if (sb->stream == NULL) {
              JNU_ThrowByName(env,
                              "java/lang/OutOfMemoryError",
!                             "Setting Stream");
              return;
          }
      }
  
      /* And finally reset state */
--- 589,613 ----
  /*************** Shared utility code ***********************/
  
  static void imageio_set_stream(JNIEnv *env,
                                 j_common_ptr cinfo,
                                 imageIODataPtr data,
!                                jobject io) {
      streamBufferPtr sb;
      sun_jpeg_error_ptr jerr;
  
      sb = &data->streamBuf;
  
      resetStreamBuffer(env, sb);  // Removes any old stream
  
!     /* Now we need a new weak global reference for the I/O provider */
!     if (io != NULL) { // Fix for 4411955
!         sb->ioRef = (*env)->NewWeakGlobalRef(env, io);
!         if (sb->ioRef == NULL) {
              JNU_ThrowByName(env,
                              "java/lang/OutOfMemoryError",
!                             "Setting I/O provider");
              return;
          }
      }
  
      /* And finally reset state */

*** 904,913 ****
--- 913,923 ----
      struct jpeg_source_mgr *src = cinfo->src;
      imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
      streamBufferPtr sb = &data->streamBuf;
      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
      int ret;
+     jobject input = NULL;
  
      /* This is where input suspends */
      if (sb->suspendable) {
          return FALSE;
      }

*** 929,941 ****
  
      /*
       * Now fill a complete buffer, or as much of one as the stream
       * will give us if we are near the end.
       */
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      ret = (*env)->CallIntMethod(env,
!                                 sb->stream,
                                  JPEGImageReader_readInputDataID,
                                  sb->hstreamBuffer, 0,
                                  sb->bufferLength);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
--- 939,953 ----
  
      /*
       * Now fill a complete buffer, or as much of one as the stream
       * will give us if we are near the end.
       */
+     GET_IO_REF(input);
+ 
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      ret = (*env)->CallIntMethod(env,
!                                 input,
                                  JPEGImageReader_readInputDataID,
                                  sb->hstreamBuffer, 0,
                                  sb->bufferLength);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {

*** 991,1000 ****
--- 1003,1013 ----
      imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
      streamBufferPtr sb = &data->streamBuf;
      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
      jint ret;
      int offset, buflen;
+     jobject input = NULL;
  
      /*
       * The original (jpegdecoder.c) had code here that called
       * InputStream.available and just returned if the number of bytes
       * available was less than any remaining skip.  Presumably this was

*** 1012,1031 ****
      /* Save the data currently in the buffer */
      offset = src->bytes_in_buffer;
      if (src->next_input_byte > sb->buf) {
          memcpy(sb->buf, src->next_input_byte, offset);
      }
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      buflen = sb->bufferLength - offset;
      if (buflen <= 0) {
          if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
              cinfo->err->error_exit((j_common_ptr) cinfo);
          }
          return;
      }
  
!     ret = (*env)->CallIntMethod(env, sb->stream,
                                  JPEGImageReader_readInputDataID,
                                  sb->hstreamBuffer,
                                  offset, buflen);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
--- 1025,1047 ----
      /* Save the data currently in the buffer */
      offset = src->bytes_in_buffer;
      if (src->next_input_byte > sb->buf) {
          memcpy(sb->buf, src->next_input_byte, offset);
      }
+     
+     GET_IO_REF(input);
+ 
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      buflen = sb->bufferLength - offset;
      if (buflen <= 0) {
          if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
              cinfo->err->error_exit((j_common_ptr) cinfo);
          }
          return;
      }
  
!     ret = (*env)->CallIntMethod(env, input,
                                  JPEGImageReader_readInputDataID,
                                  sb->hstreamBuffer,
                                  offset, buflen);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {

*** 1084,1093 ****
--- 1100,1110 ----
      imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
      streamBufferPtr sb = &data->streamBuf;
      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
      jlong ret;
      jobject reader;
+     jobject input = NULL;
  
      if (num_bytes < 0) {
          return;
      }
      num_bytes += sb->remaining_skip;

*** 1113,1125 ****
      if (sb->suspendable) {
          sb->remaining_skip = num_bytes;
          return;
      }
  
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      ret = (*env)->CallLongMethod(env,
!                                  sb->stream,
                                   JPEGImageReader_skipInputBytesID,
                                   (jlong) num_bytes);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
              cinfo->err->error_exit((j_common_ptr) cinfo);
--- 1130,1144 ----
      if (sb->suspendable) {
          sb->remaining_skip = num_bytes;
          return;
      }
      
+     GET_IO_REF(input);
+ 
      RELEASE_ARRAYS(env, data, src->next_input_byte);
      ret = (*env)->CallLongMethod(env,
!                                  input,
                                   JPEGImageReader_skipInputBytesID,
                                   (jlong) num_bytes);
      if ((*env)->ExceptionOccurred(env)
          || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
              cinfo->err->error_exit((j_common_ptr) cinfo);

*** 2291,2305 ****
  {
      struct jpeg_destination_mgr *dest = cinfo->dest;
      imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
      streamBufferPtr sb = &data->streamBuf;
      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
  
      RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  
      (*env)->CallVoidMethod(env,
!                            sb->stream,
                             JPEGImageWriter_writeOutputDataID,
                             sb->hstreamBuffer,
                             0,
                             sb->bufferLength);
      if ((*env)->ExceptionOccurred(env)
--- 2310,2327 ----
  {
      struct jpeg_destination_mgr *dest = cinfo->dest;
      imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
      streamBufferPtr sb = &data->streamBuf;
      JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+     jobject output = NULL;
+ 
+     GET_IO_REF(output);
  
      RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  
      (*env)->CallVoidMethod(env,
!                            output,
                             JPEGImageWriter_writeOutputDataID,
                             sb->hstreamBuffer,
                             0,
                             sb->bufferLength);
      if ((*env)->ExceptionOccurred(env)

*** 2329,2342 ****
  
      /* find out how much needs to be written */
      jint datacount = sb->bufferLength - dest->free_in_buffer;
  
      if (datacount != 0) {
          RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  
          (*env)->CallVoidMethod(env,
!                                sb->stream,
                                 JPEGImageWriter_writeOutputDataID,
                                 sb->hstreamBuffer,
                                 0,
                                 datacount);
  
--- 2351,2368 ----
  
      /* find out how much needs to be written */
      jint datacount = sb->bufferLength - dest->free_in_buffer;
  
      if (datacount != 0) {
+         jobject output = NULL;
+         
+         GET_IO_REF(output);
+         
          RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  
          (*env)->CallVoidMethod(env,
!                                output,
                                 JPEGImageWriter_writeOutputDataID,
                                 sb->hstreamBuffer,
                                 0,
                                 datacount);