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); |
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]); |
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 { |