< prev index next >

src/java.desktop/share/native/libjavajpeg/imageioJPEG.c

Print this page


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