1604
1605 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1606 (*env)->CallVoidMethod(env, this,
1607 JPEGImageLoader_setOutputAttributesID,
1608 cinfo->output_width,
1609 cinfo->output_height);
1610
1611 return cinfo->output_components;
1612 }
1613
1614 #define SAFE_TO_MULT(a, b) (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
1615
1616 JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressIndirect
1617 (JNIEnv *env, jobject this, jlong ptr, jboolean report_progress, jbyteArray barray) {
1618 imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1619 j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1620 struct jpeg_source_mgr *src = cinfo->src;
1621 sun_jpeg_error_ptr jerr;
1622 int bytes_per_row = cinfo->output_width * cinfo->output_components;
1623 int offset = 0;
1624
1625 JSAMPROW scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof (JSAMPLE));
1626 if (scanline_ptr == NULL) {
1627 ThrowByName(env,
1628 "java/lang/OutOfMemoryError",
1629 "Reading JPEG Stream");
1630 return JNI_FALSE;
1631 }
1632
1633 if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
1634 !SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
1635 ((*env)->GetArrayLength(env, barray) <
1636 (bytes_per_row * cinfo->output_height)))
1637 {
1638 free(scanline_ptr);
1639 ThrowByName(env,
1640 "java/lang/OutOfMemoryError",
1641 "Reading JPEG Stream");
1642 return JNI_FALSE;
1643 }
1644
1645 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1646 free(scanline_ptr);
1647 ThrowByName(env,
1648 "java/io/IOException",
1649 "Array pin failed");
1650 return JNI_FALSE;
1651 }
1652
1653 /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1654 jerr = (sun_jpeg_error_ptr) cinfo->err;
1655
1656 if (setjmp(jerr->setjmp_buffer)) {
1657 /* If we get here, the JPEG code has signaled an error
1658 while reading. */
1659 free(scanline_ptr);
1660 if (!(*env)->ExceptionOccurred(env)) {
1661 char buffer[JMSG_LENGTH_MAX];
1662 (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1663 buffer);
1664 ThrowByName(env, "java/io/IOException", buffer);
1665 }
1666 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1667 return JNI_FALSE;
1668 }
1669
1670 while (cinfo->output_scanline < cinfo->output_height) {
1671 int num_scanlines;
1672 if (report_progress == JNI_TRUE) {
1673 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1674 (*env)->CallVoidMethod(env, this,
1675 JPEGImageLoader_updateImageProgressID,
1676 cinfo->output_scanline);
1677 if ((*env)->ExceptionCheck(env)) {
1678 free(scanline_ptr);
1679 return JNI_FALSE;
1680 }
1681 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1682 free(scanline_ptr);
1683 ThrowByName(env,
1684 "java/io/IOException",
1685 "Array pin failed");
1686 return JNI_FALSE;
1687 }
1688 }
1689
1690 num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
1691 if (num_scanlines == 1) {
1692 jboolean iscopy = FALSE;
1693 jbyte *body = (*env)->GetPrimitiveArrayCritical(env, barray, &iscopy);
1694 if (body == NULL) {
1695 fprintf(stderr, "decompressIndirect: GetPrimitiveArrayCritical returns NULL: out of memory\n");
1696 free(scanline_ptr);
1697 return JNI_FALSE;
1698 }
1699 memcpy(body+offset,scanline_ptr, bytes_per_row);
1700 (*env)->ReleasePrimitiveArrayCritical(env, barray, body, JNI_ABORT);
1701 offset += bytes_per_row;
1702 }
1703 }
1704
1705 if (report_progress == JNI_TRUE) {
1706 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1707 (*env)->CallVoidMethod(env, this,
1708 JPEGImageLoader_updateImageProgressID,
1709 cinfo->output_height);
1710 if ((*env)->ExceptionCheck(env)) {
1711 free(scanline_ptr);
1712 return JNI_FALSE;
1713 }
1714 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1715 free(scanline_ptr);
1716 ThrowByName(env,
1717 "java/io/IOException",
1718 "Array pin failed");
1719 return JNI_FALSE;
1720 }
1721 }
1722
1723 jpeg_finish_decompress(cinfo);
1724 free(scanline_ptr);
1725
1726 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1727 return JNI_TRUE;
1728 }
|
1604
1605 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1606 (*env)->CallVoidMethod(env, this,
1607 JPEGImageLoader_setOutputAttributesID,
1608 cinfo->output_width,
1609 cinfo->output_height);
1610
1611 return cinfo->output_components;
1612 }
1613
1614 #define SAFE_TO_MULT(a, b) (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
1615
1616 JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressIndirect
1617 (JNIEnv *env, jobject this, jlong ptr, jboolean report_progress, jbyteArray barray) {
1618 imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1619 j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1620 struct jpeg_source_mgr *src = cinfo->src;
1621 sun_jpeg_error_ptr jerr;
1622 int bytes_per_row = cinfo->output_width * cinfo->output_components;
1623 int offset = 0;
1624 JSAMPROW scanline_ptr = NULL;
1625
1626 if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
1627 !SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
1628 ((*env)->GetArrayLength(env, barray) <
1629 (bytes_per_row * cinfo->output_height)))
1630 {
1631 ThrowByName(env,
1632 "java/lang/OutOfMemoryError",
1633 "Reading JPEG Stream");
1634 return JNI_FALSE;
1635 }
1636
1637 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1638 ThrowByName(env,
1639 "java/io/IOException",
1640 "Array pin failed");
1641 return JNI_FALSE;
1642 }
1643
1644 /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1645 jerr = (sun_jpeg_error_ptr) cinfo->err;
1646
1647 if (setjmp(jerr->setjmp_buffer)) {
1648 /* If we get here, the JPEG code has signaled an error
1649 while reading. */
1650 if (!(*env)->ExceptionOccurred(env)) {
1651 char buffer[JMSG_LENGTH_MAX];
1652 (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1653 buffer);
1654 ThrowByName(env, "java/io/IOException", buffer);
1655 }
1656 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1657 return JNI_FALSE;
1658 }
1659
1660 scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof(JSAMPLE));
1661 if (scanline_ptr == NULL) {
1662 ThrowByName(env,
1663 "java/lang/OutOfMemoryError",
1664 "Reading JPEG Stream");
1665 return JNI_FALSE;
1666 }
1667
1668 while (cinfo->output_scanline < cinfo->output_height) {
1669 int num_scanlines;
1670 if (report_progress == JNI_TRUE) {
1671 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1672 (*env)->CallVoidMethod(env, this,
1673 JPEGImageLoader_updateImageProgressID,
1674 cinfo->output_scanline);
1675 if ((*env)->ExceptionCheck(env)) {
1676 free(scanline_ptr);
1677 return JNI_FALSE;
1678 }
1679 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1680 free(scanline_ptr);
1681 ThrowByName(env,
1682 "java/io/IOException",
1683 "Array pin failed");
1684 return JNI_FALSE;
1685 }
1686 }
1687
1688 num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
1689 if (num_scanlines == 1) {
1690 jboolean iscopy = FALSE;
1691 jbyte *body = (*env)->GetPrimitiveArrayCritical(env, barray, &iscopy);
1692 if (body == NULL) {
1693 fprintf(stderr, "decompressIndirect: GetPrimitiveArrayCritical returns NULL: out of memory\n");
1694 free(scanline_ptr);
1695 return JNI_FALSE;
1696 }
1697 memcpy(body+offset,scanline_ptr, bytes_per_row);
1698 (*env)->ReleasePrimitiveArrayCritical(env, barray, body, JNI_ABORT);
1699 offset += bytes_per_row;
1700 }
1701 }
1702 free(scanline_ptr);
1703
1704 if (report_progress == JNI_TRUE) {
1705 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1706 (*env)->CallVoidMethod(env, this,
1707 JPEGImageLoader_updateImageProgressID,
1708 cinfo->output_height);
1709 if ((*env)->ExceptionCheck(env)) {
1710 return JNI_FALSE;
1711 }
1712 if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1713 ThrowByName(env,
1714 "java/io/IOException",
1715 "Array pin failed");
1716 return JNI_FALSE;
1717 }
1718 }
1719
1720 jpeg_finish_decompress(cinfo);
1721
1722 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1723 return JNI_TRUE;
1724 }
|