jdk/src/share/native/sun/awt/image/jpeg/imageioJPEG.c
changeset 2383 c6a2226cc4de
parent 2 90ce3da70b43
child 3009 de653b2cab31
equal deleted inserted replaced
2382:1e4cc5a20bd1 2383:c6a2226cc4de
   394     }
   394     }
   395 
   395 
   396     data->jpegObj = cinfo;
   396     data->jpegObj = cinfo;
   397     cinfo->client_data = data;
   397     cinfo->client_data = data;
   398 
   398 
   399 #ifdef DEBUG
   399 #ifdef DEBUG_IIO_JPEG
   400     printf("new structures: data is %p, cinfo is %p\n", data, cinfo);
   400     printf("new structures: data is %p, cinfo is %p\n", data, cinfo);
   401 #endif
   401 #endif
   402 
   402 
   403     data->imageIOobj = (*env)->NewWeakGlobalRef(env, obj);
   403     data->imageIOobj = (*env)->NewWeakGlobalRef(env, obj);
   404     if (data->imageIOobj == NULL) {
   404     if (data->imageIOobj == NULL) {
   671     int i, j;
   671     int i, j;
   672     j_compress_ptr comp;
   672     j_compress_ptr comp;
   673     j_decompress_ptr decomp;
   673     j_decompress_ptr decomp;
   674 
   674 
   675     qlen = (*env)->GetArrayLength(env, qtables);
   675     qlen = (*env)->GetArrayLength(env, qtables);
   676 #ifdef DEBUG
   676 #ifdef DEBUG_IIO_JPEG
   677     printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
   677     printf("in setQTables, qlen = %d, write is %d\n", qlen, write);
   678 #endif
   678 #endif
   679     for (i = 0; i < qlen; i++) {
   679     for (i = 0; i < qlen; i++) {
   680         table = (*env)->GetObjectArrayElement(env, qtables, i);
   680         table = (*env)->GetObjectArrayElement(env, qtables, i);
   681         qdata = (*env)->GetObjectField(env, table, JPEGQTable_tableID);
   681         qdata = (*env)->GetObjectField(env, table, JPEGQTable_tableID);
   874     /* This is where input suspends */
   874     /* This is where input suspends */
   875     if (sb->suspendable) {
   875     if (sb->suspendable) {
   876         return FALSE;
   876         return FALSE;
   877     }
   877     }
   878 
   878 
   879 #ifdef DEBUG
   879 #ifdef DEBUG_IIO_JPEG
   880     printf("Filling input buffer, remaining skip is %ld, ",
   880     printf("Filling input buffer, remaining skip is %ld, ",
   881            sb->remaining_skip);
   881            sb->remaining_skip);
   882     printf("Buffer length is %d\n", sb->bufferLength);
   882     printf("Buffer length is %d\n", sb->bufferLength);
   883 #endif
   883 #endif
   884 
   884 
   904     if ((*env)->ExceptionOccurred(env)
   904     if ((*env)->ExceptionOccurred(env)
   905         || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
   905         || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
   906             cinfo->err->error_exit((j_common_ptr) cinfo);
   906             cinfo->err->error_exit((j_common_ptr) cinfo);
   907     }
   907     }
   908 
   908 
   909 #ifdef DEBUG
   909 #ifdef DEBUG_IIO_JPEG
   910       printf("Buffer filled. ret = %d\n", ret);
   910       printf("Buffer filled. ret = %d\n", ret);
   911 #endif
   911 #endif
   912     /*
   912     /*
   913      * If we have reached the end of the stream, then the EOI marker
   913      * If we have reached the end of the stream, then the EOI marker
   914      * is missing.  We accept such streams but generate a warning.
   914      * is missing.  We accept such streams but generate a warning.
   915      * The image is likely to be corrupted, though everything through
   915      * The image is likely to be corrupted, though everything through
   916      * the end of the last complete MCU should be usable.
   916      * the end of the last complete MCU should be usable.
   917      */
   917      */
   918     if (ret <= 0) {
   918     if (ret <= 0) {
   919         jobject reader = data->imageIOobj;
   919         jobject reader = data->imageIOobj;
   920 #ifdef DEBUG
   920 #ifdef DEBUG_IIO_JPEG
   921       printf("YO! Early EOI! ret = %d\n", ret);
   921       printf("YO! Early EOI! ret = %d\n", ret);
   922 #endif
   922 #endif
   923         RELEASE_ARRAYS(env, data, src->next_input_byte);
   923         RELEASE_ARRAYS(env, data, src->next_input_byte);
   924         (*env)->CallVoidMethod(env, reader,
   924         (*env)->CallVoidMethod(env, reader,
   925                                JPEGImageReader_warningOccurredID,
   925                                JPEGImageReader_warningOccurredID,
  1214 jbyteArray
  1214 jbyteArray
  1215 read_icc_profile (JNIEnv *env, j_decompress_ptr cinfo)
  1215 read_icc_profile (JNIEnv *env, j_decompress_ptr cinfo)
  1216 {
  1216 {
  1217     jpeg_saved_marker_ptr marker;
  1217     jpeg_saved_marker_ptr marker;
  1218     int num_markers = 0;
  1218     int num_markers = 0;
       
  1219     int num_found_markers = 0;
  1219     int seq_no;
  1220     int seq_no;
  1220     JOCTET *icc_data;
  1221     JOCTET *icc_data;
       
  1222     JOCTET *dst_ptr;
  1221     unsigned int total_length;
  1223     unsigned int total_length;
  1222 #define MAX_SEQ_NO  255         // sufficient since marker numbers are bytes
  1224 #define MAX_SEQ_NO  255         // sufficient since marker numbers are bytes
  1223     char marker_present[MAX_SEQ_NO+1];    // 1 if marker found
  1225     jpeg_saved_marker_ptr icc_markers[MAX_SEQ_NO + 1];
  1224     unsigned int data_length[MAX_SEQ_NO+1]; // size of profile data in marker
  1226     int first;         // index of the first marker in the icc_markers array
  1225     unsigned int data_offset[MAX_SEQ_NO+1]; // offset for data in marker
  1227     int last;          // index of the last marker in the icc_markers array
  1226     jbyteArray data = NULL;
  1228     jbyteArray data = NULL;
  1227 
  1229 
  1228     /* This first pass over the saved markers discovers whether there are
  1230     /* This first pass over the saved markers discovers whether there are
  1229      * any ICC markers and verifies the consistency of the marker numbering.
  1231      * any ICC markers and verifies the consistency of the marker numbering.
  1230      */
  1232      */
  1231 
  1233 
  1232     for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
  1234     for (seq_no = 0; seq_no <= MAX_SEQ_NO; seq_no++)
  1233         marker_present[seq_no] = 0;
  1235         icc_markers[seq_no] = NULL;
       
  1236 
  1234 
  1237 
  1235     for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
  1238     for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
  1236         if (marker_is_icc(marker)) {
  1239         if (marker_is_icc(marker)) {
  1237             if (num_markers == 0)
  1240             if (num_markers == 0)
  1238                 num_markers = GETJOCTET(marker->data[13]);
  1241                 num_markers = GETJOCTET(marker->data[13]);
  1240                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1243                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1241                      "Invalid icc profile: inconsistent num_markers fields");
  1244                      "Invalid icc profile: inconsistent num_markers fields");
  1242                 return NULL;
  1245                 return NULL;
  1243             }
  1246             }
  1244             seq_no = GETJOCTET(marker->data[12]);
  1247             seq_no = GETJOCTET(marker->data[12]);
  1245             if (seq_no <= 0 || seq_no > num_markers) {
  1248 
       
  1249             /* Some third-party tools produce images with profile chunk
       
  1250              * numeration started from zero. It is inconsistent with ICC
       
  1251              * spec, but seems to be recognized by majority of image
       
  1252              * processing tools, so we should be more tolerant to this
       
  1253              * departure from the spec.
       
  1254              */
       
  1255             if (seq_no < 0 || seq_no > num_markers) {
  1246                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1256                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1247                      "Invalid icc profile: bad sequence number");
  1257                      "Invalid icc profile: bad sequence number");
  1248                 return NULL;
  1258                 return NULL;
  1249             }
  1259             }
  1250             if (marker_present[seq_no]) {
  1260             if (icc_markers[seq_no] != NULL) {
  1251                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1261                 JNU_ThrowByName(env, "javax/imageio/IIOException",
  1252                      "Invalid icc profile: duplicate sequence numbers");
  1262                      "Invalid icc profile: duplicate sequence numbers");
  1253                 return NULL;
  1263                 return NULL;
  1254             }
  1264             }
  1255             marker_present[seq_no] = 1;
  1265             icc_markers[seq_no] = marker;
  1256             data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
  1266             num_found_markers ++;
  1257         }
  1267         }
  1258     }
  1268     }
  1259 
  1269 
  1260     if (num_markers == 0)
  1270     if (num_markers == 0)
  1261         return NULL;  // There is no profile
  1271         return NULL;  // There is no profile
  1262 
  1272 
  1263     /* Check for missing markers, count total space needed,
  1273     if (num_markers != num_found_markers) {
  1264      * compute offset of each marker's part of the data.
  1274         JNU_ThrowByName(env, "javax/imageio/IIOException",
       
  1275                         "Invalid icc profile: invalid number of icc markers");
       
  1276         return NULL;
       
  1277     }
       
  1278 
       
  1279     first = icc_markers[0] ? 0 : 1;
       
  1280     last = num_found_markers + first;
       
  1281 
       
  1282     /* Check for missing markers, count total space needed.
  1265      */
  1283      */
  1266 
       
  1267     total_length = 0;
  1284     total_length = 0;
  1268     for (seq_no = 1; seq_no <= num_markers; seq_no++) {
  1285     for (seq_no = first; seq_no < last; seq_no++) {
  1269         if (marker_present[seq_no] == 0) {
  1286         unsigned int length;
       
  1287         if (icc_markers[seq_no] == NULL) {
  1270             JNU_ThrowByName(env, "javax/imageio/IIOException",
  1288             JNU_ThrowByName(env, "javax/imageio/IIOException",
  1271                  "Invalid icc profile: missing sequence number");
  1289                  "Invalid icc profile: missing sequence number");
  1272             return NULL;
  1290             return NULL;
  1273         }
  1291         }
  1274         data_offset[seq_no] = total_length;
  1292         /* check the data length correctness */
  1275         total_length += data_length[seq_no];
  1293         length = icc_markers[seq_no]->data_length;
       
  1294         if (ICC_OVERHEAD_LEN > length || length > MAX_BYTES_IN_MARKER) {
       
  1295             JNU_ThrowByName(env, "javax/imageio/IIOException",
       
  1296                  "Invalid icc profile: invalid data length");
       
  1297             return NULL;
       
  1298         }
       
  1299         total_length += (length - ICC_OVERHEAD_LEN);
  1276     }
  1300     }
  1277 
  1301 
  1278     if (total_length <= 0) {
  1302     if (total_length <= 0) {
  1279         JNU_ThrowByName(env, "javax/imageio/IIOException",
  1303         JNU_ThrowByName(env, "javax/imageio/IIOException",
  1280               "Invalid icc profile: found only empty markers");
  1304               "Invalid icc profile: found only empty markers");
  1299                         "Unable to pin icc profile data array");
  1323                         "Unable to pin icc profile data array");
  1300         return NULL;
  1324         return NULL;
  1301     }
  1325     }
  1302 
  1326 
  1303     /* and fill it in */
  1327     /* and fill it in */
  1304     for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
  1328     dst_ptr = icc_data;
  1305         if (marker_is_icc(marker)) {
  1329     for (seq_no = first; seq_no < last; seq_no++) {
  1306             JOCTET FAR *src_ptr;
  1330         JOCTET FAR *src_ptr = icc_markers[seq_no]->data + ICC_OVERHEAD_LEN;
  1307             JOCTET *dst_ptr;
  1331         unsigned int length =
  1308             unsigned int length;
  1332             icc_markers[seq_no]->data_length - ICC_OVERHEAD_LEN;
  1309             seq_no = GETJOCTET(marker->data[12]);
  1333 
  1310             dst_ptr = icc_data + data_offset[seq_no];
  1334         memcpy(dst_ptr, src_ptr, length);
  1311             src_ptr = marker->data + ICC_OVERHEAD_LEN;
  1335         dst_ptr += length;
  1312             length = data_length[seq_no];
       
  1313             while (length--) {
       
  1314                 *dst_ptr++ = *src_ptr++;
       
  1315             }
       
  1316         }
       
  1317     }
  1336     }
  1318 
  1337 
  1319     /* finally, unpin the array */
  1338     /* finally, unpin the array */
  1320     (*env)->ReleasePrimitiveArrayCritical(env,
  1339     (*env)->ReleasePrimitiveArrayCritical(env,
  1321                                           data,
  1340                                           data,
  1528     jboolean retval = JNI_FALSE;
  1547     jboolean retval = JNI_FALSE;
  1529     imageIODataPtr data = (imageIODataPtr) ptr;
  1548     imageIODataPtr data = (imageIODataPtr) ptr;
  1530     j_decompress_ptr cinfo;
  1549     j_decompress_ptr cinfo;
  1531     struct jpeg_source_mgr *src;
  1550     struct jpeg_source_mgr *src;
  1532     sun_jpeg_error_ptr jerr;
  1551     sun_jpeg_error_ptr jerr;
       
  1552     jbyteArray profileData = NULL;
  1533 
  1553 
  1534     if (data == NULL) {
  1554     if (data == NULL) {
  1535         JNU_ThrowByName(env,
  1555         JNU_ThrowByName(env,
  1536                         "java/lang/IllegalStateException",
  1556                         "java/lang/IllegalStateException",
  1537                         "Attempting to use reader after dispose()");
  1557                         "Attempting to use reader after dispose()");
  1555             JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
  1575             JNU_ThrowByName(env, "javax/imageio/IIOException", buffer);
  1556         }
  1576         }
  1557         return retval;
  1577         return retval;
  1558     }
  1578     }
  1559 
  1579 
  1560 #ifdef DEBUG
  1580 #ifdef DEBUG_IIO_JPEG
  1561     printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo);
  1581     printf("In readImageHeader, data is %p cinfo is %p\n", data, cinfo);
  1562     printf("clearFirst is %d\n", clearFirst);
  1582     printf("clearFirst is %d\n", clearFirst);
  1563 #endif
  1583 #endif
  1564 
  1584 
  1565     if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
  1585     if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
  1582     ret = jpeg_read_header(cinfo, FALSE);
  1602     ret = jpeg_read_header(cinfo, FALSE);
  1583 
  1603 
  1584     if (ret == JPEG_HEADER_TABLES_ONLY) {
  1604     if (ret == JPEG_HEADER_TABLES_ONLY) {
  1585         retval = JNI_TRUE;
  1605         retval = JNI_TRUE;
  1586         imageio_term_source(cinfo);  // Pushback remaining buffer contents
  1606         imageio_term_source(cinfo);  // Pushback remaining buffer contents
  1587 #ifdef DEBUG
  1607 #ifdef DEBUG_IIO_JPEG
  1588         printf("just read tables-only image; q table 0 at %p\n",
  1608         printf("just read tables-only image; q table 0 at %p\n",
  1589                cinfo->quant_tbl_ptrs[0]);
  1609                cinfo->quant_tbl_ptrs[0]);
  1590 #endif
  1610 #endif
  1591         RELEASE_ARRAYS(env, data, src->next_input_byte);
  1611         RELEASE_ARRAYS(env, data, src->next_input_byte);
  1592     } else {
  1612     } else {
  1689                 cinfo->jpeg_color_space = JCS_YCCK;
  1709                 cinfo->jpeg_color_space = JCS_YCCK;
  1690                 /* Leave the output space as CMYK */
  1710                 /* Leave the output space as CMYK */
  1691             }
  1711             }
  1692         }
  1712         }
  1693         RELEASE_ARRAYS(env, data, src->next_input_byte);
  1713         RELEASE_ARRAYS(env, data, src->next_input_byte);
       
  1714 
       
  1715         /* read icc profile data */
       
  1716         profileData = read_icc_profile(env, cinfo);
       
  1717 
       
  1718         if ((*env)->ExceptionCheck(env)) {
       
  1719             return retval;
       
  1720         }
       
  1721 
  1694         (*env)->CallVoidMethod(env, this,
  1722         (*env)->CallVoidMethod(env, this,
  1695                                JPEGImageReader_setImageDataID,
  1723                                JPEGImageReader_setImageDataID,
  1696                                cinfo->image_width,
  1724                                cinfo->image_width,
  1697                                cinfo->image_height,
  1725                                cinfo->image_height,
  1698                                cinfo->jpeg_color_space,
  1726                                cinfo->jpeg_color_space,
  1699                                cinfo->out_color_space,
  1727                                cinfo->out_color_space,
  1700                                cinfo->num_components,
  1728                                cinfo->num_components,
  1701                                read_icc_profile(env, cinfo));
  1729                                profileData);
  1702         if (reset) {
  1730         if (reset) {
  1703             jpeg_abort_decompress(cinfo);
  1731             jpeg_abort_decompress(cinfo);
  1704         }
  1732         }
  1705     }
  1733     }
  1706 
  1734 
  1825         }
  1853         }
  1826     }
  1854     }
  1827 
  1855 
  1828     (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT);
  1856     (*env)->ReleaseIntArrayElements(env, srcBands, body, JNI_ABORT);
  1829 
  1857 
  1830 #ifdef DEBUG
  1858 #ifdef DEBUG_IIO_JPEG
  1831     printf("---- in reader.read ----\n");
  1859     printf("---- in reader.read ----\n");
  1832     printf("numBands is %d\n", numBands);
  1860     printf("numBands is %d\n", numBands);
  1833     printf("bands array: ");
  1861     printf("bands array: ");
  1834     for (i = 0; i < numBands; i++) {
  1862     for (i = 0; i < numBands; i++) {
  1835         printf("%d ", bands[i]);
  1863         printf("%d ", bands[i]);
  2485 
  2513 
  2486     jpeg_suppress_tables(cinfo, TRUE);  // Suppress writing of any current
  2514     jpeg_suppress_tables(cinfo, TRUE);  // Suppress writing of any current
  2487 
  2515 
  2488     data->streamBuf.suspendable = FALSE;
  2516     data->streamBuf.suspendable = FALSE;
  2489     if (qtables != NULL) {
  2517     if (qtables != NULL) {
  2490 #ifdef DEBUG
  2518 #ifdef DEBUG_IIO_JPEG
  2491         printf("in writeTables: qtables not NULL\n");
  2519         printf("in writeTables: qtables not NULL\n");
  2492 #endif
  2520 #endif
  2493         setQTables(env, (j_common_ptr) cinfo, qtables, TRUE);
  2521         setQTables(env, (j_common_ptr) cinfo, qtables, TRUE);
  2494     }
  2522     }
  2495 
  2523 
  2761         }
  2789         }
  2762     }
  2790     }
  2763 
  2791 
  2764     cinfo->restart_interval = restartInterval;
  2792     cinfo->restart_interval = restartInterval;
  2765 
  2793 
  2766 #ifdef DEBUG
  2794 #ifdef DEBUG_IIO_JPEG
  2767     printf("writer setup complete, starting compressor\n");
  2795     printf("writer setup complete, starting compressor\n");
  2768 #endif
  2796 #endif
  2769 
  2797 
  2770     // start the compressor; tables must already be set
  2798     // start the compressor; tables must already be set
  2771     jpeg_start_compress(cinfo, FALSE); // Leaves sent_table alone
  2799     jpeg_start_compress(cinfo, FALSE); // Leaves sent_table alone
  2810         pixelStride = numBands*stepX;
  2838         pixelStride = numBands*stepX;
  2811         for (; in < pixelLimit; in += pixelStride) {
  2839         for (; in < pixelLimit; in += pixelStride) {
  2812             for (i = 0; i < numBands; i++) {
  2840             for (i = 0; i < numBands; i++) {
  2813                 if (scale !=NULL && scale[i] != NULL) {
  2841                 if (scale !=NULL && scale[i] != NULL) {
  2814                     *out++ = scale[i][*(in+i)];
  2842                     *out++ = scale[i][*(in+i)];
  2815 #ifdef DEBUG
  2843 #ifdef DEBUG_IIO_JPEG
  2816                     if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  2844                     if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  2817                         printf("in %d -> out %d, ", *(in+i), *(out-i-1));
  2845                         printf("in %d -> out %d, ", *(in+i), *(out-i-1));
  2818                     }
  2846                     }
  2819 #endif
  2847 #endif
  2820 
  2848 
  2821 #ifdef DEBUG
  2849 #ifdef DEBUG_IIO_JPEG
  2822                     if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  2850                     if (in == data->pixelBuf.buf.bp){ // Just the first pixel
  2823                         printf("\n");
  2851                         printf("\n");
  2824                     }
  2852                     }
  2825 #endif
  2853 #endif
  2826                 } else {
  2854                 } else {