< prev index next >

modules/javafx.graphics/src/main/native-iio/jpegloader.c

Print this page

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 }
< prev index next >