jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
changeset 8355 6b58fe58e767
parent 7668 d4a77089c587
child 8358 39c22ace748d
equal deleted inserted replaced
8354:3189b5e18f80 8355:6b58fe58e767
   107 
   107 
   108 typedef struct streamBufferStruct {
   108 typedef struct streamBufferStruct {
   109     jobject stream;            // ImageInputStream or ImageOutputStream
   109     jobject stream;            // ImageInputStream or ImageOutputStream
   110     jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
   110     jbyteArray hstreamBuffer;  // Handle to a Java buffer for the stream
   111     JOCTET *buf;               // Pinned buffer pointer */
   111     JOCTET *buf;               // Pinned buffer pointer */
   112     int bufferOffset;          // holds offset between unpin and the next pin
   112     size_t bufferOffset;          // holds offset between unpin and the next pin
   113     int bufferLength;          // Allocated, nut just used
   113     size_t bufferLength;          // Allocated, nut just used
   114     int suspendable;           // Set to true to suspend input
   114     int suspendable;           // Set to true to suspend input
   115     long remaining_skip;       // Used only on input
   115     long remaining_skip;       // Used only on input
   116 } streamBuffer, *streamBufferPtr;
   116 } streamBuffer, *streamBufferPtr;
   117 
   117 
   118 /*
   118 /*
   127 
   127 
   128 /*
   128 /*
   129  * Used to signal that no data need be restored from an unpin to a pin.
   129  * Used to signal that no data need be restored from an unpin to a pin.
   130  * I.e. the buffer is empty.
   130  * I.e. the buffer is empty.
   131  */
   131  */
   132 #define NO_DATA -1
   132 #define NO_DATA ((size_t)-1)
   133 
   133 
   134 // Forward reference
   134 // Forward reference
   135 static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb);
   135 static void resetStreamBuffer(JNIEnv *env, streamBufferPtr sb);
   136 
   136 
   137 /*
   137 /*
   387  * on success, NULL on failure.
   387  * on success, NULL on failure.
   388  */
   388  */
   389 static imageIODataPtr initImageioData (JNIEnv *env,
   389 static imageIODataPtr initImageioData (JNIEnv *env,
   390                                        j_common_ptr cinfo,
   390                                        j_common_ptr cinfo,
   391                                        jobject obj) {
   391                                        jobject obj) {
   392     int i, j;
       
   393 
   392 
   394     imageIODataPtr data = (imageIODataPtr) malloc (sizeof(imageIOData));
   393     imageIODataPtr data = (imageIODataPtr) malloc (sizeof(imageIOData));
   395     if (data == NULL) {
   394     if (data == NULL) {
   396         return NULL;
   395         return NULL;
   397     }
   396     }
   980     struct jpeg_source_mgr *src = cinfo->src;
   979     struct jpeg_source_mgr *src = cinfo->src;
   981     imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
   980     imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
   982     streamBufferPtr sb = &data->streamBuf;
   981     streamBufferPtr sb = &data->streamBuf;
   983     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
   982     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
   984     jint ret;
   983     jint ret;
   985     int offset, buflen;
   984     size_t offset, buflen;
   986 
   985 
   987     /*
   986     /*
   988      * The original (jpegdecoder.c) had code here that called
   987      * The original (jpegdecoder.c) had code here that called
   989      * InputStream.available and just returned if the number of bytes
   988      * InputStream.available and just returned if the number of bytes
   990      * available was less than any remaining skip.  Presumably this was
   989      * available was less than any remaining skip.  Presumably this was
  1518                          "java/lang/OutOfMemoryError",
  1517                          "java/lang/OutOfMemoryError",
  1519                          "Initializing Reader");
  1518                          "Initializing Reader");
  1520         imageio_dispose((j_common_ptr)cinfo);
  1519         imageio_dispose((j_common_ptr)cinfo);
  1521         return 0;
  1520         return 0;
  1522     }
  1521     }
  1523     return (jlong) ret;
  1522     return ptr_to_jlong(ret);
  1524 }
  1523 }
  1525 
  1524 
  1526 /*
  1525 /*
  1527  * When we set a source from Java, we set up the stream in the streamBuf
  1526  * When we set a source from Java, we set up the stream in the streamBuf
  1528  * object.  If there was an old one, it is released first.
  1527  * object.  If there was an old one, it is released first.
  1533     (JNIEnv *env,
  1532     (JNIEnv *env,
  1534      jobject this,
  1533      jobject this,
  1535      jlong ptr,
  1534      jlong ptr,
  1536      jobject source) {
  1535      jobject source) {
  1537 
  1536 
  1538     imageIODataPtr data = (imageIODataPtr) ptr;
  1537     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  1539     j_common_ptr cinfo;
  1538     j_common_ptr cinfo;
  1540 
  1539 
  1541     if (data == NULL) {
  1540     if (data == NULL) {
  1542         JNU_ThrowByName(env,
  1541         JNU_ThrowByName(env,
  1543                         "java/lang/IllegalStateException",
  1542                         "java/lang/IllegalStateException",
  1572 
  1571 
  1573     int ret;
  1572     int ret;
  1574     int h_samp0, h_samp1, h_samp2;
  1573     int h_samp0, h_samp1, h_samp2;
  1575     int v_samp0, v_samp1, v_samp2;
  1574     int v_samp0, v_samp1, v_samp2;
  1576     jboolean retval = JNI_FALSE;
  1575     jboolean retval = JNI_FALSE;
  1577     imageIODataPtr data = (imageIODataPtr) ptr;
  1576     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  1578     j_decompress_ptr cinfo;
  1577     j_decompress_ptr cinfo;
  1579     struct jpeg_source_mgr *src;
  1578     struct jpeg_source_mgr *src;
  1580     sun_jpeg_error_ptr jerr;
  1579     sun_jpeg_error_ptr jerr;
  1581     jbyteArray profileData = NULL;
  1580     jbyteArray profileData = NULL;
  1582 
  1581 
  1770     (JNIEnv *env,
  1769     (JNIEnv *env,
  1771      jobject this,
  1770      jobject this,
  1772      jlong ptr,
  1771      jlong ptr,
  1773      jint code) {
  1772      jint code) {
  1774 
  1773 
  1775     imageIODataPtr data = (imageIODataPtr) ptr;
  1774     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  1776     j_decompress_ptr cinfo;
  1775     j_decompress_ptr cinfo;
  1777 
  1776 
  1778     if (data == NULL) {
  1777     if (data == NULL) {
  1779         JNU_ThrowByName(env,
  1778         JNU_ThrowByName(env,
  1780                         "java/lang/IllegalStateException",
  1779                         "java/lang/IllegalStateException",
  1812 
  1811 
  1813 
  1812 
  1814     struct jpeg_source_mgr *src;
  1813     struct jpeg_source_mgr *src;
  1815     JSAMPROW scanLinePtr = NULL;
  1814     JSAMPROW scanLinePtr = NULL;
  1816     jint bands[MAX_BANDS];
  1815     jint bands[MAX_BANDS];
  1817     int i, j;
  1816     int i;
  1818     jint *body;
  1817     jint *body;
  1819     int scanlineLimit;
  1818     int scanlineLimit;
  1820     int pixelStride;
  1819     int pixelStride;
  1821     unsigned char *in, *out, *pixelLimit;
  1820     unsigned char *in, *out, *pixelLimit;
  1822     int targetLine;
  1821     int targetLine;
  1823     int skipLines, linesLeft;
  1822     int skipLines, linesLeft;
  1824     pixelBufferPtr pb;
  1823     pixelBufferPtr pb;
  1825     sun_jpeg_error_ptr jerr;
  1824     sun_jpeg_error_ptr jerr;
  1826     boolean done;
  1825     boolean done;
  1827     jint *bandSize;
       
  1828     int maxBandValue, halfMaxBandValue;
       
  1829     boolean mustScale = FALSE;
  1826     boolean mustScale = FALSE;
  1830     boolean progressive = FALSE;
  1827     boolean progressive = FALSE;
  1831     boolean orderedBands = TRUE;
  1828     boolean orderedBands = TRUE;
  1832     imageIODataPtr data = (imageIODataPtr) ptr;
  1829     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  1833     j_decompress_ptr cinfo;
  1830     j_decompress_ptr cinfo;
  1834     unsigned int numBytes;
  1831     size_t numBytes;
  1835 
  1832 
  1836     /* verify the inputs */
  1833     /* verify the inputs */
  1837 
  1834 
  1838     if (data == NULL) {
  1835     if (data == NULL) {
  1839         JNU_ThrowByName(env,
  1836         JNU_ThrowByName(env,
  1861         JNU_ThrowByName(env, "javax/imageio/IIOException",
  1858         JNU_ThrowByName(env, "javax/imageio/IIOException",
  1862                         "Invalid argument to native readImage");
  1859                         "Invalid argument to native readImage");
  1863         return JNI_FALSE;
  1860         return JNI_FALSE;
  1864     }
  1861     }
  1865 
  1862 
  1866     if (stepX > cinfo->image_width) {
  1863     if (stepX > (jint)cinfo->image_width) {
  1867         stepX = cinfo->image_width;
  1864         stepX = cinfo->image_width;
  1868     }
  1865     }
  1869     if (stepY > cinfo->image_height) {
  1866     if (stepY > (jint)cinfo->image_height) {
  1870         stepY = cinfo->image_height;
  1867         stepY = cinfo->image_height;
  1871     }
  1868     }
  1872 
  1869 
  1873     /*
  1870     /*
  1874      * First get the source bands array and copy it to our local array
  1871      * First get the source bands array and copy it to our local array
  2117 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead
  2114 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abortRead
  2118     (JNIEnv *env,
  2115     (JNIEnv *env,
  2119      jobject this,
  2116      jobject this,
  2120      jlong ptr) {
  2117      jlong ptr) {
  2121 
  2118 
  2122     imageIODataPtr data = (imageIODataPtr) ptr;
  2119     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2123 
  2120 
  2124     if (data == NULL) {
  2121     if (data == NULL) {
  2125         JNU_ThrowByName(env,
  2122         JNU_ThrowByName(env,
  2126                         "java/lang/IllegalStateException",
  2123                         "java/lang/IllegalStateException",
  2127                         "Attempting to use reader after dispose()");
  2124                         "Attempting to use reader after dispose()");
  2135 JNIEXPORT void JNICALL
  2132 JNIEXPORT void JNICALL
  2136 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetLibraryState
  2133 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetLibraryState
  2137     (JNIEnv *env,
  2134     (JNIEnv *env,
  2138      jobject this,
  2135      jobject this,
  2139      jlong ptr) {
  2136      jlong ptr) {
  2140     imageIODataPtr data = (imageIODataPtr) ptr;
  2137     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2141     j_decompress_ptr cinfo;
  2138     j_decompress_ptr cinfo;
  2142 
  2139 
  2143     if (data == NULL) {
  2140     if (data == NULL) {
  2144         JNU_ThrowByName(env,
  2141         JNU_ThrowByName(env,
  2145                         "java/lang/IllegalStateException",
  2142                         "java/lang/IllegalStateException",
  2157 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetReader
  2154 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_resetReader
  2158     (JNIEnv *env,
  2155     (JNIEnv *env,
  2159      jobject this,
  2156      jobject this,
  2160      jlong ptr) {
  2157      jlong ptr) {
  2161 
  2158 
  2162     imageIODataPtr data = (imageIODataPtr) ptr;
  2159     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2163     j_decompress_ptr cinfo;
  2160     j_decompress_ptr cinfo;
  2164     sun_jpeg_error_ptr jerr;
  2161     sun_jpeg_error_ptr jerr;
  2165 
  2162 
  2166     if (data == NULL) {
  2163     if (data == NULL) {
  2167         JNU_ThrowByName(env,
  2164         JNU_ThrowByName(env,
  2230 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader
  2227 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_disposeReader
  2231     (JNIEnv *env,
  2228     (JNIEnv *env,
  2232      jclass reader,
  2229      jclass reader,
  2233      jlong ptr) {
  2230      jlong ptr) {
  2234 
  2231 
  2235     imageIODataPtr data = (imageIODataPtr) ptr;
  2232     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2236     j_common_ptr info = destroyImageioData(env, data);
  2233     j_common_ptr info = destroyImageioData(env, data);
  2237 
  2234 
  2238     imageio_dispose(info);
  2235     imageio_dispose(info);
  2239 }
  2236 }
  2240 
  2237 
  2315     imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
  2312     imageIODataPtr data = (imageIODataPtr) cinfo->client_data;
  2316     streamBufferPtr sb = &data->streamBuf;
  2313     streamBufferPtr sb = &data->streamBuf;
  2317     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
  2314     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
  2318 
  2315 
  2319     /* find out how much needs to be written */
  2316     /* find out how much needs to be written */
  2320     jint datacount = sb->bufferLength - dest->free_in_buffer;
  2317     /* this conversion from size_t to jint is safe, because the lenght of the buffer is limited by jint */
  2321 
  2318     jint datacount = (jint)(sb->bufferLength - dest->free_in_buffer);
  2322     if (datacount != 0) {
  2319     if (datacount != 0) {
  2323         RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  2320         RELEASE_ARRAYS(env, data, (const JOCTET *)(dest->next_output_byte));
  2324 
  2321 
  2325         (*env)->CallVoidMethod(env,
  2322         (*env)->CallVoidMethod(env,
  2326                                sb->stream,
  2323                                sb->stream,
  2483                          "java/lang/OutOfMemoryError",
  2480                          "java/lang/OutOfMemoryError",
  2484                          "Initializing Writer");
  2481                          "Initializing Writer");
  2485         imageio_dispose((j_common_ptr)cinfo);
  2482         imageio_dispose((j_common_ptr)cinfo);
  2486         return 0;
  2483         return 0;
  2487     }
  2484     }
  2488     return (jlong) ret;
  2485     return ptr_to_jlong(ret);
  2489 }
  2486 }
  2490 
  2487 
  2491 JNIEXPORT void JNICALL
  2488 JNIEXPORT void JNICALL
  2492 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
  2489 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
  2493     (JNIEnv *env,
  2490     (JNIEnv *env,
  2494      jobject this,
  2491      jobject this,
  2495      jlong ptr,
  2492      jlong ptr,
  2496      jobject destination) {
  2493      jobject destination) {
  2497 
  2494 
  2498     imageIODataPtr data = (imageIODataPtr) ptr;
  2495     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2499     j_compress_ptr cinfo;
  2496     j_compress_ptr cinfo;
  2500 
  2497 
  2501     if (data == NULL) {
  2498     if (data == NULL) {
  2502         JNU_ThrowByName(env,
  2499         JNU_ThrowByName(env,
  2503                         "java/lang/IllegalStateException",
  2500                         "java/lang/IllegalStateException",
  2524      jobjectArray DCHuffmanTables,
  2521      jobjectArray DCHuffmanTables,
  2525      jobjectArray ACHuffmanTables) {
  2522      jobjectArray ACHuffmanTables) {
  2526 
  2523 
  2527     struct jpeg_destination_mgr *dest;
  2524     struct jpeg_destination_mgr *dest;
  2528     sun_jpeg_error_ptr jerr;
  2525     sun_jpeg_error_ptr jerr;
  2529     imageIODataPtr data = (imageIODataPtr) ptr;
  2526     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2530     j_compress_ptr cinfo;
  2527     j_compress_ptr cinfo;
  2531 
  2528 
  2532     if (data == NULL) {
  2529     if (data == NULL) {
  2533         JNU_ThrowByName(env,
  2530         JNU_ThrowByName(env,
  2534                         "java/lang/IllegalStateException",
  2531                         "java/lang/IllegalStateException",
  2623     jsize qlen, hlen;
  2620     jsize qlen, hlen;
  2624     int *scanptr;
  2621     int *scanptr;
  2625     jint *scanData;
  2622     jint *scanData;
  2626     jint *bandSize;
  2623     jint *bandSize;
  2627     int maxBandValue, halfMaxBandValue;
  2624     int maxBandValue, halfMaxBandValue;
  2628     imageIODataPtr data = (imageIODataPtr) ptr;
  2625     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2629     j_compress_ptr cinfo;
  2626     j_compress_ptr cinfo;
  2630     UINT8** scale = NULL;
  2627     UINT8** scale = NULL;
       
  2628 
  2631 
  2629 
  2632     /* verify the inputs */
  2630     /* verify the inputs */
  2633 
  2631 
  2634     if (data == NULL) {
  2632     if (data == NULL) {
  2635         JNU_ThrowByName(env,
  2633         JNU_ThrowByName(env,
  2738             char buffer[JMSG_LENGTH_MAX];
  2736             char buffer[JMSG_LENGTH_MAX];
  2739             (*cinfo->err->format_message) ((j_common_ptr) cinfo,
  2737             (*cinfo->err->format_message) ((j_common_ptr) cinfo,
  2740                                           buffer);
  2738                                           buffer);
  2741             JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
  2739             JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
  2742         }
  2740         }
       
  2741 
       
  2742         if (scale != NULL) {
       
  2743             for (i = 0; i < numBands; i++) {
       
  2744                 if (scale[i] != NULL) {
       
  2745                     free(scale[i]);
       
  2746                 }
       
  2747             }
       
  2748             free(scale);
       
  2749         }
       
  2750 
  2743         free(scanLinePtr);
  2751         free(scanLinePtr);
  2744         return data->abortFlag;
  2752         return data->abortFlag;
  2745     }
  2753     }
  2746 
  2754 
  2747     // set up parameters
  2755     // set up parameters
  2951 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_abortWrite
  2959 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_abortWrite
  2952     (JNIEnv *env,
  2960     (JNIEnv *env,
  2953      jobject this,
  2961      jobject this,
  2954      jlong ptr) {
  2962      jlong ptr) {
  2955 
  2963 
  2956     imageIODataPtr data = (imageIODataPtr) ptr;
  2964     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2957 
  2965 
  2958     if (data == NULL) {
  2966     if (data == NULL) {
  2959         JNU_ThrowByName(env,
  2967         JNU_ThrowByName(env,
  2960                         "java/lang/IllegalStateException",
  2968                         "java/lang/IllegalStateException",
  2961                         "Attempting to use writer after dispose()");
  2969                         "Attempting to use writer after dispose()");
  2968 JNIEXPORT void JNICALL
  2976 JNIEXPORT void JNICALL
  2969 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_resetWriter
  2977 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_resetWriter
  2970     (JNIEnv *env,
  2978     (JNIEnv *env,
  2971      jobject this,
  2979      jobject this,
  2972      jlong ptr) {
  2980      jlong ptr) {
  2973     imageIODataPtr data = (imageIODataPtr) ptr;
  2981     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  2974     j_compress_ptr cinfo;
  2982     j_compress_ptr cinfo;
  2975 
  2983 
  2976     if (data == NULL) {
  2984     if (data == NULL) {
  2977         JNU_ThrowByName(env,
  2985         JNU_ThrowByName(env,
  2978                         "java/lang/IllegalStateException",
  2986                         "java/lang/IllegalStateException",
  3000 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_disposeWriter
  3008 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_disposeWriter
  3001     (JNIEnv *env,
  3009     (JNIEnv *env,
  3002      jclass writer,
  3010      jclass writer,
  3003      jlong ptr) {
  3011      jlong ptr) {
  3004 
  3012 
  3005     imageIODataPtr data = (imageIODataPtr) ptr;
  3013     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
  3006     j_common_ptr info = destroyImageioData(env, data);
  3014     j_common_ptr info = destroyImageioData(env, data);
  3007 
  3015 
  3008     imageio_dispose(info);
  3016     imageio_dispose(info);
  3009 }
  3017 }