< prev index next >

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

Print this page




1321         free(cinfo);
1322         ThrowByName(env,
1323                 "java/lang/OutOfMemoryError",
1324                 "Initializing Reader");
1325         return 0;
1326     }
1327 
1328     /* We set up the normal JPEG error routines, then override error_exit. */
1329     cinfo->err = jpeg_std_error(&(jerr_mgr->pub));
1330     jerr_mgr->pub.error_exit = sun_jpeg_error_exit;
1331     /* We need to setup our own print routines */
1332     jerr_mgr->pub.output_message = sun_jpeg_output_message;
1333     /* Now we can setjmp before every call to the library */
1334 
1335     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1336     if (setjmp(jerr_mgr->setjmp_buffer)) {
1337         /* If we get here, the JPEG code has signaled an error. */
1338         char buffer[JMSG_LENGTH_MAX];
1339         (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1340                 buffer);


1341         ThrowByName(env, "java/io/IOException", buffer);
1342         return 0;
1343     }
1344 
1345     /* Perform library initialization */
1346     jpeg_create_decompress(cinfo);
1347 
1348     // Set up to keep any APP2 markers, as these might contain ICC profile
1349     // data
1350     jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
1351 
1352     /*
1353      * Now set up our source.
1354      */
1355     cinfo->src =
1356             (struct jpeg_source_mgr *) malloc(sizeof (struct jpeg_source_mgr));
1357     if (cinfo->src == NULL) {


1358         ThrowByName(env,
1359                 "java/lang/OutOfMemoryError",
1360                 "Initializing Reader");
1361         return 0;
1362     }
1363     cinfo->src->bytes_in_buffer = 0;
1364     cinfo->src->next_input_byte = NULL;
1365     cinfo->src->init_source = imageio_init_source;
1366     cinfo->src->fill_input_buffer = imageio_fill_input_buffer;
1367     cinfo->src->skip_input_data = imageio_skip_input_data;
1368     cinfo->src->resync_to_restart = jpeg_resync_to_restart; // use default
1369     cinfo->src->term_source = imageio_term_source;
1370 
1371     /* set up the association to persist for future calls */
1372     data = initImageioData(env, (j_common_ptr) cinfo, this);
1373     if (data == NULL) {



1374         ThrowByName(env,
1375                 "java/lang/OutOfMemoryError",
1376                 "Initializing Reader");
1377         return 0;
1378     }
1379 
1380     imageio_set_stream(env, (j_common_ptr) cinfo, data, stream);
1381 
1382     if ((*env)->ExceptionCheck(env)) return 0;





1383 
1384     imageio_init_source((j_decompress_ptr) cinfo);
1385 
1386     src = cinfo->src;
1387     jerr = (sun_jpeg_error_ptr) cinfo->err;
1388 
1389     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1390     if (setjmp(jerr->setjmp_buffer)) {
1391         /* If we get here, the JPEG code has signaled an error
1392            while reading the header. */
1393         RELEASE_ARRAYS(env, data, src->next_input_byte);
1394         if (!(*env)->ExceptionOccurred(env)) {
1395             char buffer[JMSG_LENGTH_MAX];
1396             (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1397                     buffer);
1398             ThrowByName(env, "java/io/IOException", buffer);
1399         }



1400         return 0;
1401     }
1402 
1403     if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {




1404         ThrowByName(env,
1405                 "java/io/IOException",
1406                 "Array pin failed");
1407         return 0;
1408     }
1409 
1410     jret = jpeg_read_header(cinfo, FALSE);
1411 
1412     if (jret == JPEG_HEADER_TABLES_ONLY) {
1413         imageio_term_source(cinfo); // Pushback remaining buffer contents
1414 #ifdef DEBUG_IIO_JPEG
1415         printf("just read tables-only image; q table 0 at %p\n",
1416                 cinfo->quant_tbl_ptrs[0]);
1417 #endif
1418         RELEASE_ARRAYS(env, data, src->next_input_byte);
1419     } else {
1420         /*
1421          * Now adjust the jpeg_color_space variable, which was set in
1422          * default_decompress_parms, to reflect our differences from IJG
1423          */


1483 
1484                 v_samp0 = cinfo->comp_info[0].v_samp_factor;
1485                 v_samp1 = cinfo->comp_info[1].v_samp_factor;
1486                 v_samp2 = cinfo->comp_info[2].v_samp_factor;
1487 
1488                 if ((h_samp1 > h_samp0) && (h_samp2 > h_samp0) ||
1489                         (v_samp1 > v_samp0) && (v_samp2 > v_samp0)) {
1490                     cinfo->jpeg_color_space = JCS_YCCK;
1491                     /* Leave the output space as CMYK */
1492                 }
1493 
1494                 /* There is no support for CMYK on jfx side, so request RGB output */
1495                 cinfo->out_color_space = JCS_RGB;
1496         }
1497         RELEASE_ARRAYS(env, data, src->next_input_byte);
1498 
1499         /* read icc profile data */
1500         profileData = read_icc_profile(env, cinfo);
1501 
1502         if ((*env)->ExceptionCheck(env)) {



1503             return 0;
1504         }
1505 
1506         (*env)->CallVoidMethod(env, this,
1507                 JPEGImageLoader_setInputAttributesID,
1508                 cinfo->image_width,
1509                 cinfo->image_height,
1510                 cinfo->jpeg_color_space,
1511                 cinfo->out_color_space,
1512                 cinfo->num_components,
1513                 profileData);
1514         if ((*env)->ExceptionCheck(env)) {



1515             return 0;
1516         }
1517     }
1518 
1519     return ptr_to_jlong(data);
1520 }
1521 
1522 JNIEXPORT jint JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_startDecompression
1523 (JNIEnv *env, jobject this, jlong ptr, jint outCS, jint dest_width, jint dest_height) {
1524     imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1525     j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1526     struct jpeg_source_mgr *src = cinfo->src;
1527     sun_jpeg_error_ptr jerr;
1528 
1529     jfloat x_scale;
1530     jfloat y_scale;
1531     jfloat max_scale;
1532 
1533     if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1534         ThrowByName(env,


1589     jpeg_start_decompress(cinfo);
1590 
1591     RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1592     (*env)->CallVoidMethod(env, this,
1593             JPEGImageLoader_setOutputAttributesID,
1594             cinfo->output_width,
1595             cinfo->output_height);
1596 
1597     return cinfo->output_components;
1598 }
1599 
1600 #define SAFE_TO_MULT(a, b) (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
1601 
1602 JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressIndirect
1603 (JNIEnv *env, jobject this, jlong ptr, jboolean report_progress, jbyteArray barray) {
1604     imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1605     j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1606     struct jpeg_source_mgr *src = cinfo->src;
1607     sun_jpeg_error_ptr jerr;
1608     int bytes_per_row = cinfo->output_width * cinfo->output_components;
1609     JSAMPROW scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof (JSAMPLE));
1610     int offset = 0;








1611 
1612     if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
1613         !SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
1614         ((*env)->GetArrayLength(env, barray) <
1615          (bytes_per_row * cinfo->output_height)))
1616      {

1617         ThrowByName(env,
1618                 "java/lang/OutOfMemoryError",
1619                 "Reading JPEG Stream");
1620         return JNI_FALSE;
1621     }
1622 
1623     if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {

1624         ThrowByName(env,
1625                 "java/io/IOException",
1626                 "Array pin failed");
1627         return JNI_FALSE;
1628     }
1629 
1630     if (scanline_ptr == NULL) {
1631         ThrowByName(env,
1632                 "java/lang/OutOfMemoryError",
1633                 "Reading JPEG Stream");
1634         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1635         return JNI_FALSE;
1636     }
1637 
1638     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1639     jerr = (sun_jpeg_error_ptr) cinfo->err;
1640 
1641     if (setjmp(jerr->setjmp_buffer)) {
1642         /* If we get here, the JPEG code has signaled an error
1643            while reading. */
1644         if (!(*env)->ExceptionOccurred(env)) {
1645             char buffer[JMSG_LENGTH_MAX];
1646             (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1647                     buffer);
1648             ThrowByName(env, "java/io/IOException", buffer);
1649         }
1650         if (scanline_ptr != NULL) {
1651             free(scanline_ptr);
1652         }
1653         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1654         return JNI_FALSE;
1655     }
1656 
1657     while (cinfo->output_scanline < cinfo->output_height) {
1658         int num_scanlines;
1659         if (report_progress == JNI_TRUE) {
1660             RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1661             (*env)->CallVoidMethod(env, this,
1662                     JPEGImageLoader_updateImageProgressID,
1663                     cinfo->output_scanline);
1664             if ((*env)->ExceptionCheck(env)) return JNI_FALSE;



1665             if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1666               ThrowByName(env,
1667                           "java/io/IOException",
1668                           "Array pin failed");

1669               return JNI_FALSE;
1670             }
1671         }
1672 
1673         num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
1674         if (num_scanlines == 1) {
1675             jboolean iscopy = FALSE;
1676             jbyte *body = (*env)->GetPrimitiveArrayCritical(env, barray, &iscopy);
1677             if (body == NULL) {
1678                 fprintf(stderr, "decompressIndirect: GetPrimitiveArrayCritical returns NULL: out of memory\n");


1679                 return JNI_FALSE;
1680             }
1681             memcpy(body+offset,scanline_ptr, bytes_per_row);
1682             (*env)->ReleasePrimitiveArrayCritical(env, barray, body, JNI_ABORT);
1683             offset += bytes_per_row;
1684         }
1685     }
1686 
1687     if (report_progress == JNI_TRUE) {
1688         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1689         (*env)->CallVoidMethod(env, this,
1690                 JPEGImageLoader_updateImageProgressID,
1691                 cinfo->output_height);
1692       if ((*env)->ExceptionCheck(env)) return JNI_FALSE;



1693       if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1694           ThrowByName(env,
1695                 "java/io/IOException",
1696                 "Array pin failed");

1697           return JNI_FALSE;
1698       }
1699     }
1700 
1701     jpeg_finish_decompress(cinfo);
1702     free(scanline_ptr);
1703 
1704     RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1705     return JNI_TRUE;
1706 }


1321         free(cinfo);
1322         ThrowByName(env,
1323                 "java/lang/OutOfMemoryError",
1324                 "Initializing Reader");
1325         return 0;
1326     }
1327 
1328     /* We set up the normal JPEG error routines, then override error_exit. */
1329     cinfo->err = jpeg_std_error(&(jerr_mgr->pub));
1330     jerr_mgr->pub.error_exit = sun_jpeg_error_exit;
1331     /* We need to setup our own print routines */
1332     jerr_mgr->pub.output_message = sun_jpeg_output_message;
1333     /* Now we can setjmp before every call to the library */
1334 
1335     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1336     if (setjmp(jerr_mgr->setjmp_buffer)) {
1337         /* If we get here, the JPEG code has signaled an error. */
1338         char buffer[JMSG_LENGTH_MAX];
1339         (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1340                 buffer);
1341         free(cinfo);
1342         free(jerr_mgr);
1343         ThrowByName(env, "java/io/IOException", buffer);
1344         return 0;
1345     }
1346 
1347     /* Perform library initialization */
1348     jpeg_create_decompress(cinfo);
1349 
1350     // Set up to keep any APP2 markers, as these might contain ICC profile
1351     // data
1352     jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
1353 
1354     /*
1355      * Now set up our source.
1356      */
1357     cinfo->src =
1358             (struct jpeg_source_mgr *) malloc(sizeof (struct jpeg_source_mgr));
1359     if (cinfo->src == NULL) {
1360         free(cinfo);
1361         free(jerr_mgr);
1362         ThrowByName(env,
1363                 "java/lang/OutOfMemoryError",
1364                 "Initializing Reader");
1365         return 0;
1366     }
1367     cinfo->src->bytes_in_buffer = 0;
1368     cinfo->src->next_input_byte = NULL;
1369     cinfo->src->init_source = imageio_init_source;
1370     cinfo->src->fill_input_buffer = imageio_fill_input_buffer;
1371     cinfo->src->skip_input_data = imageio_skip_input_data;
1372     cinfo->src->resync_to_restart = jpeg_resync_to_restart; // use default
1373     cinfo->src->term_source = imageio_term_source;
1374 
1375     /* set up the association to persist for future calls */
1376     data = initImageioData(env, (j_common_ptr) cinfo, this);
1377     if (data == NULL) {
1378         free(cinfo->src);
1379         free(cinfo);
1380         free(jerr_mgr);
1381         ThrowByName(env,
1382                 "java/lang/OutOfMemoryError",
1383                 "Initializing Reader");
1384         return 0;
1385     }
1386 
1387     imageio_set_stream(env, (j_common_ptr) cinfo, data, stream);
1388 
1389     if ((*env)->ExceptionCheck(env)) {
1390         free(cinfo->src);
1391         free(cinfo);
1392         free(jerr_mgr);
1393         return 0;
1394     }
1395 
1396     imageio_init_source((j_decompress_ptr) cinfo);
1397 
1398     src = cinfo->src;
1399     jerr = (sun_jpeg_error_ptr) cinfo->err;
1400 
1401     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1402     if (setjmp(jerr->setjmp_buffer)) {
1403         /* If we get here, the JPEG code has signaled an error
1404            while reading the header. */
1405         RELEASE_ARRAYS(env, data, src->next_input_byte);
1406         if (!(*env)->ExceptionOccurred(env)) {
1407             char buffer[JMSG_LENGTH_MAX];
1408             (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1409                     buffer);
1410             ThrowByName(env, "java/io/IOException", buffer);
1411         }
1412         free(cinfo->src);
1413         free(cinfo);
1414         free(jerr_mgr);
1415         return 0;
1416     }
1417 
1418     if (GET_ARRAYS(env, data, &src->next_input_byte) == NOT_OK) {
1419         RELEASE_ARRAYS(env, data, src->next_input_byte);
1420         free(cinfo->src);
1421         free(cinfo);
1422         free(jerr_mgr);
1423         ThrowByName(env,
1424                 "java/io/IOException",
1425                 "Array pin failed");
1426         return 0;
1427     }
1428 
1429     jret = jpeg_read_header(cinfo, FALSE);
1430 
1431     if (jret == JPEG_HEADER_TABLES_ONLY) {
1432         imageio_term_source(cinfo); // Pushback remaining buffer contents
1433 #ifdef DEBUG_IIO_JPEG
1434         printf("just read tables-only image; q table 0 at %p\n",
1435                 cinfo->quant_tbl_ptrs[0]);
1436 #endif
1437         RELEASE_ARRAYS(env, data, src->next_input_byte);
1438     } else {
1439         /*
1440          * Now adjust the jpeg_color_space variable, which was set in
1441          * default_decompress_parms, to reflect our differences from IJG
1442          */


1502 
1503                 v_samp0 = cinfo->comp_info[0].v_samp_factor;
1504                 v_samp1 = cinfo->comp_info[1].v_samp_factor;
1505                 v_samp2 = cinfo->comp_info[2].v_samp_factor;
1506 
1507                 if ((h_samp1 > h_samp0) && (h_samp2 > h_samp0) ||
1508                         (v_samp1 > v_samp0) && (v_samp2 > v_samp0)) {
1509                     cinfo->jpeg_color_space = JCS_YCCK;
1510                     /* Leave the output space as CMYK */
1511                 }
1512 
1513                 /* There is no support for CMYK on jfx side, so request RGB output */
1514                 cinfo->out_color_space = JCS_RGB;
1515         }
1516         RELEASE_ARRAYS(env, data, src->next_input_byte);
1517 
1518         /* read icc profile data */
1519         profileData = read_icc_profile(env, cinfo);
1520 
1521         if ((*env)->ExceptionCheck(env)) {
1522             free(cinfo->src);
1523             free(cinfo);
1524             free(jerr_mgr);
1525             return 0;
1526         }
1527 
1528         (*env)->CallVoidMethod(env, this,
1529                 JPEGImageLoader_setInputAttributesID,
1530                 cinfo->image_width,
1531                 cinfo->image_height,
1532                 cinfo->jpeg_color_space,
1533                 cinfo->out_color_space,
1534                 cinfo->num_components,
1535                 profileData);
1536         if ((*env)->ExceptionCheck(env)) {
1537             free(cinfo->src);
1538             free(cinfo);
1539             free(jerr_mgr);
1540             return 0;
1541         }
1542     }
1543 
1544     return ptr_to_jlong(data);
1545 }
1546 
1547 JNIEXPORT jint JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_startDecompression
1548 (JNIEnv *env, jobject this, jlong ptr, jint outCS, jint dest_width, jint dest_height) {
1549     imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1550     j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1551     struct jpeg_source_mgr *src = cinfo->src;
1552     sun_jpeg_error_ptr jerr;
1553 
1554     jfloat x_scale;
1555     jfloat y_scale;
1556     jfloat max_scale;
1557 
1558     if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1559         ThrowByName(env,


1614     jpeg_start_decompress(cinfo);
1615 
1616     RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1617     (*env)->CallVoidMethod(env, this,
1618             JPEGImageLoader_setOutputAttributesID,
1619             cinfo->output_width,
1620             cinfo->output_height);
1621 
1622     return cinfo->output_components;
1623 }
1624 
1625 #define SAFE_TO_MULT(a, b) (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
1626 
1627 JNIEXPORT jboolean JNICALL Java_com_sun_javafx_iio_jpeg_JPEGImageLoader_decompressIndirect
1628 (JNIEnv *env, jobject this, jlong ptr, jboolean report_progress, jbyteArray barray) {
1629     imageIODataPtr data = (imageIODataPtr) jlong_to_ptr(ptr);
1630     j_decompress_ptr cinfo = (j_decompress_ptr) data->jpegObj;
1631     struct jpeg_source_mgr *src = cinfo->src;
1632     sun_jpeg_error_ptr jerr;
1633     int bytes_per_row = cinfo->output_width * cinfo->output_components;

1634     int offset = 0;
1635     JSAMPROW scanline_ptr = (JSAMPROW) malloc(bytes_per_row * sizeof (JSAMPLE));
1636 
1637     if (scanline_ptr == NULL) {
1638         ThrowByName(env,
1639                 "java/lang/OutOfMemoryError",
1640                 "Reading JPEG Stream");
1641         return JNI_FALSE;
1642     }
1643 
1644     if (!SAFE_TO_MULT(cinfo->output_width, cinfo->output_components) ||
1645         !SAFE_TO_MULT(bytes_per_row, cinfo->output_height) ||
1646         ((*env)->GetArrayLength(env, barray) <
1647          (bytes_per_row * cinfo->output_height)))
1648      {
1649         free(scanline_ptr);
1650         ThrowByName(env,
1651                 "java/lang/OutOfMemoryError",
1652                 "Reading JPEG Stream");
1653         return JNI_FALSE;
1654     }
1655 
1656     if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1657         free(scanline_ptr);
1658         ThrowByName(env,
1659                 "java/io/IOException",
1660                 "Array pin failed");
1661         return JNI_FALSE;
1662     }
1663 








1664     /* Establish the setjmp return context for sun_jpeg_error_exit to use. */
1665     jerr = (sun_jpeg_error_ptr) cinfo->err;
1666 
1667     if (setjmp(jerr->setjmp_buffer)) {
1668         /* If we get here, the JPEG code has signaled an error
1669            while reading. */
1670         if (!(*env)->ExceptionOccurred(env)) {
1671             char buffer[JMSG_LENGTH_MAX];
1672             (*cinfo->err->format_message) ((struct jpeg_common_struct *) cinfo,
1673                     buffer);
1674             ThrowByName(env, "java/io/IOException", buffer);
1675         }

1676         free(scanline_ptr);

1677         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1678         return JNI_FALSE;
1679     }
1680 
1681     while (cinfo->output_scanline < cinfo->output_height) {
1682         int num_scanlines;
1683         if (report_progress == JNI_TRUE) {
1684             RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1685             (*env)->CallVoidMethod(env, this,
1686                     JPEGImageLoader_updateImageProgressID,
1687                     cinfo->output_scanline);
1688             if ((*env)->ExceptionCheck(env)) {
1689                 free(scanline_ptr);
1690                 return JNI_FALSE;
1691             }
1692             if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1693               ThrowByName(env,
1694                           "java/io/IOException",
1695                           "Array pin failed");
1696               free(scanline_ptr);
1697               return JNI_FALSE;
1698             }
1699         }
1700 
1701         num_scanlines = jpeg_read_scanlines(cinfo, &scanline_ptr, 1);
1702         if (num_scanlines == 1) {
1703             jboolean iscopy = FALSE;
1704             jbyte *body = (*env)->GetPrimitiveArrayCritical(env, barray, &iscopy);
1705             if (body == NULL) {
1706                 fprintf(stderr, "decompressIndirect: GetPrimitiveArrayCritical returns NULL: out of memory\n");
1707                 free(scanline_ptr);
1708                 RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1709                 return JNI_FALSE;
1710             }
1711             memcpy(body+offset,scanline_ptr, bytes_per_row);
1712             (*env)->ReleasePrimitiveArrayCritical(env, barray, body, JNI_ABORT);
1713             offset += bytes_per_row;
1714         }
1715     }
1716 
1717     if (report_progress == JNI_TRUE) {
1718         RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1719         (*env)->CallVoidMethod(env, this,
1720                 JPEGImageLoader_updateImageProgressID,
1721                 cinfo->output_height);
1722         if ((*env)->ExceptionCheck(env)) {
1723             free(scanline_ptr);
1724             return JNI_FALSE;
1725         }
1726         if (GET_ARRAYS(env, data, &cinfo->src->next_input_byte) == NOT_OK) {
1727             ThrowByName(env,
1728                 "java/io/IOException",
1729                 "Array pin failed");
1730             free(scanline_ptr);
1731             return JNI_FALSE;
1732         }
1733     }
1734 
1735     jpeg_finish_decompress(cinfo);
1736     free(scanline_ptr);
1737 
1738     RELEASE_ARRAYS(env, data, cinfo->src->next_input_byte);
1739     return JNI_TRUE;
1740 }
< prev index next >