< prev index next >

modules/graphics/src/main/java/com/sun/javafx/iio/jpeg/JPEGImageLoader.java

Print this page
rev 8890 : RT-40778


  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
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.iio.jpeg;
  27 
  28 import com.sun.javafx.iio.ImageFrame;
  29 import com.sun.javafx.iio.ImageMetadata;
  30 import com.sun.javafx.iio.ImageStorage.ImageType;
  31 import com.sun.glass.utils.NativeLibLoader;
  32 import com.sun.javafx.iio.common.ImageLoaderImpl;
  33 import com.sun.javafx.iio.common.ImageTools;
  34 import com.sun.javafx.iio.common.PushbroomScaler;
  35 import com.sun.javafx.iio.common.ScalerFactory;
  36 import java.io.IOException;
  37 import java.io.InputStream;
  38 import java.nio.ByteBuffer;
  39 import java.security.AccessController;
  40 import java.security.PrivilegedAction;
  41 
  42 public class JPEGImageLoader extends ImageLoaderImpl {
  43 
  44     // IJG Color codes.
  45     public static final int JCS_UNKNOWN = 0;       // error/unspecified
  46     public static final int JCS_GRAYSCALE = 1;     // monochrome
  47     public static final int JCS_RGB = 2;           // red/green/blue
  48     public static final int JCS_YCbCr = 3;         // Y/Cb/Cr (also known as YUV)
  49     public static final int JCS_CMYK = 4;          // C/M/Y/K
  50     public static final int JCS_YCC = 5;           // PhotoYCC
  51     public static final int JCS_RGBA = 6;          // RGB-Alpha
  52     public static final int JCS_YCbCrA = 7;        // Y/Cb/Cr/Alpha
  53     // 8 and 9 were old "Legacy" codes which the old code never identified
  54     // on reading anyway.  Support for writing them is being dropped, too.
  55     public static final int JCS_YCCA = 10;         // PhotoYCC-Alpha


 206     }
 207 
 208     protected void finalize() {
 209         dispose();
 210     }
 211 
 212     public ImageFrame load(int imageIndex, int width, int height, boolean preserveAspectRatio, boolean smooth) throws IOException {
 213         if (imageIndex != 0) {
 214             return null;
 215         }
 216 
 217         accessLock.lock();
 218 
 219         // Determine output image dimensions.
 220         int[] widthHeight = ImageTools.computeDimensions(inWidth, inHeight, width, height, preserveAspectRatio);
 221         width = widthHeight[0];
 222         height = widthHeight[1];
 223 
 224         ImageMetadata md = new ImageMetadata(null, true,
 225                 null, null, null, null, null,
 226                 inWidth, inHeight, null, null, null);
 227 
 228         updateImageMetadata(md);
 229 
 230         ByteBuffer buffer = null;
 231 
 232         int outNumComponents;
 233         try {
 234             outNumComponents = startDecompression(structPointer,
 235                     outColorSpaceCode, width, height);
 236 
 237             // Uncomment next line for direct ByteBuffer.
 238             //buffer = decompressDirect(structPointer, listeners != null && !listeners.isEmpty());
 239             // Comment out next three lines to suppress indirect ByteBuffers.
 240             byte[] array = new byte[outWidth*outHeight*outNumComponents];
 241             buffer = ByteBuffer.wrap(array);
 242             decompressIndirect(structPointer, listeners != null && !listeners.isEmpty(), buffer.array());
 243         } catch (IOException e) {
 244             throw e;
 245         } finally {
 246             accessLock.unlock();
 247             dispose();
 248         }
 249 
 250         if (buffer == null) {
 251             throw new IOException("Error decompressing JPEG stream!");
 252         }
 253 
 254         ImageFrame frame = null;
 255 
 256         // Check whether the decompressed image has been scaled to the correct
 257         // dimensions. If not, downscalte it here. Note outData, outHeight, and
 258         // outWidth refer to the image as returned by the decompressor. This
 259         // image might have been downscaled from the original source by a factor
 260         // of N/8 where 1 <= N <=8.
 261         if (outWidth != width || outHeight != height) {
 262             // Get the decompressed data array. Note that the code really should
 263             // be moidified to use direct buffers if and only if this post-
 264             // decompression scaling will NOT occur.
 265             byte[] outData;
 266             if (buffer.hasArray()) {
 267                 outData = buffer.array();
 268             } else {
 269                 outData = new byte[buffer.capacity()];
 270                 buffer.get(outData);
 271             }
 272 
 273             PushbroomScaler scaler = ScalerFactory.createScaler(outWidth, outHeight,
 274                     outNumComponents, width, height, smooth);
 275             int stride = outWidth * outNumComponents;
 276             int off = 0;
 277             for (int y = 0; y < outHeight; y++) {
 278                 if (scaler.putSourceScanline(outData, off)) {
 279                     break;
 280                 }
 281                 off += stride;
 282             }
 283             buffer = scaler.getDestination();
 284             frame = new ImageFrame(outImageType, buffer,
 285                     width, height, width * outNumComponents, null, md);
 286         }
 287         else {
 288             frame = new ImageFrame(outImageType, buffer,
 289                                    outWidth, outHeight, outWidth * outNumComponents, null, md);
 290         }
 291 
 292         return frame;

 293     }
 294 
 295     private static class Lock {
 296         private boolean locked;
 297 
 298         public Lock() {
 299             locked = false;
 300         }
 301 
 302         public synchronized boolean isLocked() {
 303             return locked;
 304         }
 305 
 306         public synchronized void lock() {
 307             if (locked) {
 308                 throw new IllegalStateException("Recursive loading is not allowed.");
 309             }
 310             locked = true;
 311         }
 312 


  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
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.iio.jpeg;
  27 
  28 import com.sun.javafx.iio.ImageFrame;
  29 import com.sun.javafx.iio.ImageMetadata;
  30 import com.sun.javafx.iio.ImageStorage.ImageType;
  31 import com.sun.glass.utils.NativeLibLoader;
  32 import com.sun.javafx.iio.common.ImageLoaderImpl;
  33 import com.sun.javafx.iio.common.ImageTools;


  34 import java.io.IOException;
  35 import java.io.InputStream;
  36 import java.nio.ByteBuffer;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 
  40 public class JPEGImageLoader extends ImageLoaderImpl {
  41 
  42     // IJG Color codes.
  43     public static final int JCS_UNKNOWN = 0;       // error/unspecified
  44     public static final int JCS_GRAYSCALE = 1;     // monochrome
  45     public static final int JCS_RGB = 2;           // red/green/blue
  46     public static final int JCS_YCbCr = 3;         // Y/Cb/Cr (also known as YUV)
  47     public static final int JCS_CMYK = 4;          // C/M/Y/K
  48     public static final int JCS_YCC = 5;           // PhotoYCC
  49     public static final int JCS_RGBA = 6;          // RGB-Alpha
  50     public static final int JCS_YCbCrA = 7;        // Y/Cb/Cr/Alpha
  51     // 8 and 9 were old "Legacy" codes which the old code never identified
  52     // on reading anyway.  Support for writing them is being dropped, too.
  53     public static final int JCS_YCCA = 10;         // PhotoYCC-Alpha


 204     }
 205 
 206     protected void finalize() {
 207         dispose();
 208     }
 209 
 210     public ImageFrame load(int imageIndex, int width, int height, boolean preserveAspectRatio, boolean smooth) throws IOException {
 211         if (imageIndex != 0) {
 212             return null;
 213         }
 214 
 215         accessLock.lock();
 216 
 217         // Determine output image dimensions.
 218         int[] widthHeight = ImageTools.computeDimensions(inWidth, inHeight, width, height, preserveAspectRatio);
 219         width = widthHeight[0];
 220         height = widthHeight[1];
 221 
 222         ImageMetadata md = new ImageMetadata(null, true,
 223                 null, null, null, null, null,
 224                 width, height, null, null, null);
 225 
 226         updateImageMetadata(md);
 227 
 228         ByteBuffer buffer = null;
 229 
 230         int outNumComponents;
 231         try {
 232             outNumComponents = startDecompression(structPointer,
 233                     outColorSpaceCode, width, height);
 234 
 235             // Uncomment next line for direct ByteBuffer.
 236             //buffer = decompressDirect(structPointer, listeners != null && !listeners.isEmpty());
 237             // Comment out next three lines to suppress indirect ByteBuffers.
 238             byte[] array = new byte[outWidth*outHeight*outNumComponents];
 239             buffer = ByteBuffer.wrap(array);
 240             decompressIndirect(structPointer, listeners != null && !listeners.isEmpty(), buffer.array());
 241         } catch (IOException e) {
 242             throw e;
 243         } finally {
 244             accessLock.unlock();
 245             dispose();
 246         }
 247 
 248         if (buffer == null) {
 249             throw new IOException("Error decompressing JPEG stream!");
 250         }
 251 


 252         // Check whether the decompressed image has been scaled to the correct
 253         // dimensions. If not, downscale it here. Note outData, outHeight, and
 254         // outWidth refer to the image as returned by the decompressor. This
 255         // image might have been downscaled from the original source by a factor
 256         // of N/8 where 1 <= N <=8.
 257         if (outWidth != width || outHeight != height) {
 258             buffer = ImageTools.scaleImage(buffer,
 259                     outWidth, outHeight, outNumComponents, width, height, smooth);


























 260         }
 261 
 262         return new ImageFrame(outImageType, buffer,
 263                 width, height, width * outNumComponents, null, md);
 264     }
 265 
 266     private static class Lock {
 267         private boolean locked;
 268 
 269         public Lock() {
 270             locked = false;
 271         }
 272 
 273         public synchronized boolean isLocked() {
 274             return locked;
 275         }
 276 
 277         public synchronized void lock() {
 278             if (locked) {
 279                 throw new IllegalStateException("Recursive loading is not allowed.");
 280             }
 281             locked = true;
 282         }
 283 
< prev index next >