1 /*
2 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1026 if (sb->remaining_skip) {
1027 src->skip_input_data(cinfo, 0);
1028 }
1029
1030 /* Save the data currently in the buffer */
1031 offset = src->bytes_in_buffer;
1032 if (src->next_input_byte > sb->buf) {
1033 memcpy(sb->buf, src->next_input_byte, offset);
1034 }
1035
1036
1037 RELEASE_ARRAYS(env, data, src->next_input_byte);
1038
1039 GET_IO_REF(input);
1040
1041 buflen = sb->bufferLength - offset;
1042 if (buflen <= 0) {
1043 if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
1044 cinfo->err->error_exit((j_common_ptr) cinfo);
1045 }
1046 return;
1047 }
1048
1049 ret = (*env)->CallIntMethod(env, input,
1050 JPEGImageReader_readInputDataID,
1051 sb->hstreamBuffer,
1052 offset, buflen);
1053 if ((ret > 0) && ((unsigned int)ret > buflen)) ret = (int)buflen;
1054 if ((*env)->ExceptionOccurred(env)
1055 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
1056 cinfo->err->error_exit((j_common_ptr) cinfo);
1057 }
1058 /*
1059 * If we have reached the end of the stream, then the EOI marker
1060 * is missing. We accept such streams but generate a warning.
1061 * The image is likely to be corrupted, though everything through
1062 * the end of the last complete MCU should be usable.
1063 */
1064 if (ret <= 0) {
1065 jobject reader = data->imageIOobj;
1781 /* Leave the output space as CMYK */
1782 }
1783 }
1784 RELEASE_ARRAYS(env, data, src->next_input_byte);
1785
1786 /* read icc profile data */
1787 profileData = read_icc_profile(env, cinfo);
1788
1789 if ((*env)->ExceptionCheck(env)) {
1790 return retval;
1791 }
1792
1793 (*env)->CallVoidMethod(env, this,
1794 JPEGImageReader_setImageDataID,
1795 cinfo->image_width,
1796 cinfo->image_height,
1797 cinfo->jpeg_color_space,
1798 cinfo->out_color_space,
1799 cinfo->num_components,
1800 profileData);
1801 if (reset) {
1802 jpeg_abort_decompress(cinfo);
1803 }
1804 }
1805
1806 return retval;
1807 }
1808
1809
1810 JNIEXPORT void JNICALL
1811 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setOutColorSpace
1812 (JNIEnv *env,
1813 jobject this,
1814 jlong ptr,
1815 jint code) {
1816
1817 imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
1818 j_decompress_ptr cinfo;
1819
1820 if (data == NULL) {
1821 JNU_ThrowByName(env,
1822 "java/lang/IllegalStateException",
1823 "Attempting to use reader after dispose()");
1993 DCHuffmanTables,
1994 ACHuffmanTables,
1995 TRUE);
1996 }
1997
1998 progressive = jpeg_has_multiple_scans(cinfo);
1999 if (progressive) {
2000 cinfo->buffered_image = TRUE;
2001 cinfo->input_scan_number = minProgressivePass+1; // Java count from 0
2002 #define MAX_JAVA_INT 2147483647 // XXX Is this defined in JNI somewhere?
2003 if (maxProgressivePass < MAX_JAVA_INT) {
2004 maxProgressivePass++; // For testing
2005 }
2006 }
2007
2008 data->streamBuf.suspendable = FALSE;
2009
2010 jpeg_start_decompress(cinfo);
2011
2012 if (numBands != cinfo->output_components) {
2013 JNU_ThrowByName(env, "javax/imageio/IIOException",
2014 "Invalid argument to native readImage");
2015 return data->abortFlag;
2016 }
2017
2018 if (cinfo->output_components <= 0 ||
2019 cinfo->image_width > (0xffffffffu / (unsigned int)cinfo->output_components))
2020 {
2021 JNU_ThrowByName(env, "javax/imageio/IIOException",
2022 "Invalid number of output components");
2023 return data->abortFlag;
2024 }
2025
2026 // Allocate a 1-scanline buffer
2027 scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->output_components);
2028 if (scanLinePtr == NULL) {
2029 RELEASE_ARRAYS(env, data, src->next_input_byte);
2030 JNU_ThrowByName( env,
2031 "java/lang/OutOfMemoryError",
2032 "Reading JPEG Stream");
2033 return data->abortFlag;
2034 }
2035
2036 // loop over progressive passes
2037 done = FALSE;
2038 while (!done) {
2039 if (progressive) {
2040 // initialize the next pass. Note that this skips up to
2041 // the first interesting pass.
2042 jpeg_start_output(cinfo, cinfo->input_scan_number);
2043 if (wantUpdates) {
2044 (*env)->CallVoidMethod(env, this,
2045 JPEGImageReader_passStartedID,
2046 cinfo->input_scan_number-1);
2047 }
2048 } else if (wantUpdates) {
2049 (*env)->CallVoidMethod(env, this,
2050 JPEGImageReader_passStartedID,
2051 0);
2052
2053 }
2054
2055 // Skip until the first interesting line
2056 while ((data->abortFlag == JNI_FALSE)
2057 && ((jint)cinfo->output_scanline < sourceYStart)) {
2058 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2059 }
2060
2061 scanlineLimit = sourceYStart+sourceHeight;
2062 pixelLimit = scanLinePtr
2063 +(sourceXStart+sourceWidth)*cinfo->output_components;
2064
2065 pixelStride = stepX*cinfo->output_components;
2066 targetLine = 0;
2067
2068 while ((data->abortFlag == JNI_FALSE)
2069 && ((jint)cinfo->output_scanline < scanlineLimit)) {
2070
2071 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2072
2120 linesLeft = scanlineLimit - cinfo->output_scanline;
2121 // Take the minimum
2122 if (skipLines > linesLeft) {
2123 skipLines = linesLeft;
2124 }
2125 for(i = 0; i < skipLines; i++) {
2126 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2127 }
2128 }
2129 if (progressive) {
2130 jpeg_finish_output(cinfo); // Increments pass counter
2131 // Call Java to notify pass complete
2132 if (jpeg_input_complete(cinfo)
2133 || (cinfo->input_scan_number > maxProgressivePass)) {
2134 done = TRUE;
2135 }
2136 } else {
2137 done = TRUE;
2138 }
2139 if (wantUpdates) {
2140 (*env)->CallVoidMethod(env, this,
2141 JPEGImageReader_passCompleteID);
2142 }
2143
2144 }
2145 /*
2146 * We are done, but we might not have read all the lines, or all
2147 * the passes, so use jpeg_abort instead of jpeg_finish_decompress.
2148 */
2149 if (cinfo->output_scanline == cinfo->output_height) {
2150 // if ((cinfo->output_scanline == cinfo->output_height) &&
2151 //(jpeg_input_complete(cinfo))) { // We read the whole file
2152 jpeg_finish_decompress(cinfo);
2153 } else {
2154 jpeg_abort_decompress(cinfo);
2155 }
2156
2157 free(scanLinePtr);
2158
2159 RELEASE_ARRAYS(env, data, src->next_input_byte);
2160
2161 return data->abortFlag;
3082 * this will cause a problem is if an image-only stream is written
3083 * with this object without initializing the correct tables first,
3084 * which should not be possible.
3085 */
3086
3087 cinfo->dest->next_output_byte = NULL;
3088 cinfo->dest->free_in_buffer = 0;
3089 }
3090
3091 JNIEXPORT void JNICALL
3092 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_disposeWriter
3093 (JNIEnv *env,
3094 jclass writer,
3095 jlong ptr) {
3096
3097 imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
3098 j_common_ptr info = destroyImageioData(env, data);
3099
3100 imageio_dispose(info);
3101 }
|
1 /*
2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1026 if (sb->remaining_skip) {
1027 src->skip_input_data(cinfo, 0);
1028 }
1029
1030 /* Save the data currently in the buffer */
1031 offset = src->bytes_in_buffer;
1032 if (src->next_input_byte > sb->buf) {
1033 memcpy(sb->buf, src->next_input_byte, offset);
1034 }
1035
1036
1037 RELEASE_ARRAYS(env, data, src->next_input_byte);
1038
1039 GET_IO_REF(input);
1040
1041 buflen = sb->bufferLength - offset;
1042 if (buflen <= 0) {
1043 if (!GET_ARRAYS(env, data, &(src->next_input_byte))) {
1044 cinfo->err->error_exit((j_common_ptr) cinfo);
1045 }
1046 RELEASE_ARRAYS(env, data, src->next_input_byte);
1047 return;
1048 }
1049
1050 ret = (*env)->CallIntMethod(env, input,
1051 JPEGImageReader_readInputDataID,
1052 sb->hstreamBuffer,
1053 offset, buflen);
1054 if ((ret > 0) && ((unsigned int)ret > buflen)) ret = (int)buflen;
1055 if ((*env)->ExceptionOccurred(env)
1056 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
1057 cinfo->err->error_exit((j_common_ptr) cinfo);
1058 }
1059 /*
1060 * If we have reached the end of the stream, then the EOI marker
1061 * is missing. We accept such streams but generate a warning.
1062 * The image is likely to be corrupted, though everything through
1063 * the end of the last complete MCU should be usable.
1064 */
1065 if (ret <= 0) {
1066 jobject reader = data->imageIOobj;
1782 /* Leave the output space as CMYK */
1783 }
1784 }
1785 RELEASE_ARRAYS(env, data, src->next_input_byte);
1786
1787 /* read icc profile data */
1788 profileData = read_icc_profile(env, cinfo);
1789
1790 if ((*env)->ExceptionCheck(env)) {
1791 return retval;
1792 }
1793
1794 (*env)->CallVoidMethod(env, this,
1795 JPEGImageReader_setImageDataID,
1796 cinfo->image_width,
1797 cinfo->image_height,
1798 cinfo->jpeg_color_space,
1799 cinfo->out_color_space,
1800 cinfo->num_components,
1801 profileData);
1802 if ((*env)->ExceptionOccurred(env)
1803 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
1804 cinfo->err->error_exit((j_common_ptr) cinfo);
1805 }
1806 if (reset) {
1807 jpeg_abort_decompress(cinfo);
1808 }
1809 RELEASE_ARRAYS(env, data, src->next_input_byte);
1810 }
1811
1812 return retval;
1813 }
1814
1815
1816 JNIEXPORT void JNICALL
1817 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setOutColorSpace
1818 (JNIEnv *env,
1819 jobject this,
1820 jlong ptr,
1821 jint code) {
1822
1823 imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
1824 j_decompress_ptr cinfo;
1825
1826 if (data == NULL) {
1827 JNU_ThrowByName(env,
1828 "java/lang/IllegalStateException",
1829 "Attempting to use reader after dispose()");
1999 DCHuffmanTables,
2000 ACHuffmanTables,
2001 TRUE);
2002 }
2003
2004 progressive = jpeg_has_multiple_scans(cinfo);
2005 if (progressive) {
2006 cinfo->buffered_image = TRUE;
2007 cinfo->input_scan_number = minProgressivePass+1; // Java count from 0
2008 #define MAX_JAVA_INT 2147483647 // XXX Is this defined in JNI somewhere?
2009 if (maxProgressivePass < MAX_JAVA_INT) {
2010 maxProgressivePass++; // For testing
2011 }
2012 }
2013
2014 data->streamBuf.suspendable = FALSE;
2015
2016 jpeg_start_decompress(cinfo);
2017
2018 if (numBands != cinfo->output_components) {
2019 RELEASE_ARRAYS(env, data, src->next_input_byte);
2020 JNU_ThrowByName(env, "javax/imageio/IIOException",
2021 "Invalid argument to native readImage");
2022 return data->abortFlag;
2023 }
2024
2025 if (cinfo->output_components <= 0 ||
2026 cinfo->image_width > (0xffffffffu / (unsigned int)cinfo->output_components))
2027 {
2028 RELEASE_ARRAYS(env, data, src->next_input_byte);
2029 JNU_ThrowByName(env, "javax/imageio/IIOException",
2030 "Invalid number of output components");
2031 return data->abortFlag;
2032 }
2033
2034 // Allocate a 1-scanline buffer
2035 scanLinePtr = (JSAMPROW)malloc(cinfo->image_width*cinfo->output_components);
2036 if (scanLinePtr == NULL) {
2037 RELEASE_ARRAYS(env, data, src->next_input_byte);
2038 JNU_ThrowByName( env,
2039 "java/lang/OutOfMemoryError",
2040 "Reading JPEG Stream");
2041 return data->abortFlag;
2042 }
2043
2044 // loop over progressive passes
2045 done = FALSE;
2046 while (!done) {
2047 if (progressive) {
2048 // initialize the next pass. Note that this skips up to
2049 // the first interesting pass.
2050 jpeg_start_output(cinfo, cinfo->input_scan_number);
2051 if (wantUpdates) {
2052 RELEASE_ARRAYS(env, data, src->next_input_byte);
2053 (*env)->CallVoidMethod(env, this,
2054 JPEGImageReader_passStartedID,
2055 cinfo->input_scan_number-1);
2056 if ((*env)->ExceptionOccurred(env)
2057 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
2058 cinfo->err->error_exit((j_common_ptr) cinfo);
2059 }
2060 }
2061 } else if (wantUpdates) {
2062 RELEASE_ARRAYS(env, data, src->next_input_byte);
2063 (*env)->CallVoidMethod(env, this,
2064 JPEGImageReader_passStartedID,
2065 0);
2066 if ((*env)->ExceptionOccurred(env)
2067 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
2068 cinfo->err->error_exit((j_common_ptr) cinfo);
2069 }
2070 }
2071
2072 // Skip until the first interesting line
2073 while ((data->abortFlag == JNI_FALSE)
2074 && ((jint)cinfo->output_scanline < sourceYStart)) {
2075 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2076 }
2077
2078 scanlineLimit = sourceYStart+sourceHeight;
2079 pixelLimit = scanLinePtr
2080 +(sourceXStart+sourceWidth)*cinfo->output_components;
2081
2082 pixelStride = stepX*cinfo->output_components;
2083 targetLine = 0;
2084
2085 while ((data->abortFlag == JNI_FALSE)
2086 && ((jint)cinfo->output_scanline < scanlineLimit)) {
2087
2088 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2089
2137 linesLeft = scanlineLimit - cinfo->output_scanline;
2138 // Take the minimum
2139 if (skipLines > linesLeft) {
2140 skipLines = linesLeft;
2141 }
2142 for(i = 0; i < skipLines; i++) {
2143 jpeg_read_scanlines(cinfo, &scanLinePtr, 1);
2144 }
2145 }
2146 if (progressive) {
2147 jpeg_finish_output(cinfo); // Increments pass counter
2148 // Call Java to notify pass complete
2149 if (jpeg_input_complete(cinfo)
2150 || (cinfo->input_scan_number > maxProgressivePass)) {
2151 done = TRUE;
2152 }
2153 } else {
2154 done = TRUE;
2155 }
2156 if (wantUpdates) {
2157 RELEASE_ARRAYS(env, data, src->next_input_byte);
2158 (*env)->CallVoidMethod(env, this,
2159 JPEGImageReader_passCompleteID);
2160 if ((*env)->ExceptionOccurred(env)
2161 || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
2162 cinfo->err->error_exit((j_common_ptr) cinfo);
2163 }
2164 }
2165
2166 }
2167 /*
2168 * We are done, but we might not have read all the lines, or all
2169 * the passes, so use jpeg_abort instead of jpeg_finish_decompress.
2170 */
2171 if (cinfo->output_scanline == cinfo->output_height) {
2172 // if ((cinfo->output_scanline == cinfo->output_height) &&
2173 //(jpeg_input_complete(cinfo))) { // We read the whole file
2174 jpeg_finish_decompress(cinfo);
2175 } else {
2176 jpeg_abort_decompress(cinfo);
2177 }
2178
2179 free(scanLinePtr);
2180
2181 RELEASE_ARRAYS(env, data, src->next_input_byte);
2182
2183 return data->abortFlag;
3104 * this will cause a problem is if an image-only stream is written
3105 * with this object without initializing the correct tables first,
3106 * which should not be possible.
3107 */
3108
3109 cinfo->dest->next_output_byte = NULL;
3110 cinfo->dest->free_in_buffer = 0;
3111 }
3112
3113 JNIEXPORT void JNICALL
3114 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_disposeWriter
3115 (JNIEnv *env,
3116 jclass writer,
3117 jlong ptr) {
3118
3119 imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
3120 j_common_ptr info = destroyImageioData(env, data);
3121
3122 imageio_dispose(info);
3123 }
3124
|