mirror of
https://git.freebsd.org/ports.git
synced 2025-05-18 01:53:13 -04:00
- Import more complete JPEG class support and turn on ICEDTEA option by default. [1] - Remove obsolete WEB option. Note the functionality is now moved to a new port java/icedtea-web, which depends on ICEDTEA option of this port. Obtained from: IcedTea project [1]
2667 lines
99 KiB
Diff
2667 lines
99 KiB
Diff
--- jdk/src/share/classes/com/sun/image/codec/jpeg/ImageFormatException.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/ImageFormatException.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,51 @@
|
|
+/* ImageFormatException.java
|
|
+ * Copyright (C) 2007 Matthew Flaschen
|
|
+ * Copyright (C) 2011 Red Hat, Inc.
|
|
+ *
|
|
+ * This file is part of IcedTea
|
|
+ *
|
|
+ * IcedTea is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * IcedTea is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ * 02110-1301 USA.
|
|
+ *
|
|
+ * Linking this library statically or dynamically with other modules is
|
|
+ * making a combined work based on this library. Thus, the terms and
|
|
+ * conditions of the GNU General Public License cover the whole
|
|
+ * combination.
|
|
+ *
|
|
+ * As a special exception, the copyright holders of this library give you
|
|
+ * permission to link this library with independent modules to produce an
|
|
+ * executable, regardless of the license terms of these independent
|
|
+ * modules, and to copy and distribute the resulting executable under
|
|
+ * terms of your choice, provided that you also meet, for each linked
|
|
+ * independent module, the terms and conditions of the license of that
|
|
+ * module. An independent module is a module which is not derived from
|
|
+ * or based on this library. If you modify this library, you may extend
|
|
+ * this exception to your version of the library, but you are not
|
|
+ * obligated to do so. If you do not wish to do so, delete this
|
|
+ * exception statement from your version.
|
|
+ */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+public class ImageFormatException extends RuntimeException {
|
|
+
|
|
+ public ImageFormatException() {
|
|
+ super();
|
|
+ }
|
|
+
|
|
+ public ImageFormatException(String s) {
|
|
+ super(s);
|
|
+ }
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGCodec.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGCodec.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,193 @@
|
|
+/* JPEGCodec.java --
|
|
+ * Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+ * Copyright (C) 2007 Matthew Flaschen
|
|
+ *
|
|
+ * This file is part of GNU Classpath.
|
|
+ *
|
|
+ * GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ * 02110-1301 USA.
|
|
+ *
|
|
+ * Linking this library statically or dynamically with other modules is
|
|
+ * making a combined work based on this library. Thus, the terms and
|
|
+ * conditions of the GNU General Public License cover the whole
|
|
+ * combination.
|
|
+ *
|
|
+ * As a special exception, the copyright holders of this library give you
|
|
+ * permission to link this library with independent modules to produce an
|
|
+ * executable, regardless of the license terms of these independent
|
|
+ * modules, and to copy and distribute the resulting executable under
|
|
+ * terms of your choice, provided that you also meet, for each linked
|
|
+ * independent module, the terms and conditions of the license of that
|
|
+ * module. An independent module is a module which is not derived from
|
|
+ * or based on this library. If you modify this library, you may extend
|
|
+ * this exception to your version of the library, but you are not
|
|
+ * obligated to do so. If you do not wish to do so, delete this
|
|
+ * exception statement from your version.
|
|
+ */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.io.OutputStream;
|
|
+import java.awt.color.ColorSpace;
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.ColorModel;
|
|
+import java.awt.image.Raster;
|
|
+
|
|
+import sun.awt.image.codec.JPEGImageDecoderImpl;
|
|
+import sun.awt.image.codec.JPEGImageEncoderImpl;
|
|
+import sun.awt.image.codec.JPEGParam;
|
|
+
|
|
+/**
|
|
+ * This class is a factory for implementations of the JPEG Image
|
|
+ * Decoder/Encoder.
|
|
+ */
|
|
+public class JPEGCodec {
|
|
+
|
|
+ private JPEGCodec() {}
|
|
+
|
|
+ /**
|
|
+ * This creates an instance of a JPEGImageDecoder that can be used to decode
|
|
+ * JPEG Data streams.
|
|
+ *
|
|
+ * @param src
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGImageDecoder createJPEGDecoder(InputStream src) {
|
|
+ return new JPEGImageDecoderImpl(src);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This creates an instance of a JPEGImageDecoder that can be used to decode
|
|
+ * JPEG Data streams.
|
|
+ *
|
|
+ * @param src
|
|
+ * @param jdp
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGImageDecoder createJPEGDecoder(InputStream src,
|
|
+ JPEGDecodeParam jdp) {
|
|
+ return new JPEGImageDecoderImpl(src, jdp);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This creates an instance of a JPEGImageEncoder that can be used to encode
|
|
+ * image data as JPEG Data streams.
|
|
+ *
|
|
+ * @param os
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGImageEncoder createJPEGEncoder(OutputStream os) {
|
|
+ return new JPEGImageEncoderImpl(os);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This creates an instance of a JPEGImageEncoder that can be used to encode
|
|
+ * image data as JPEG Data streams.
|
|
+ *
|
|
+ * @param dest
|
|
+ * @param jep
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGImageEncoder createJPEGEncoder(OutputStream dest,
|
|
+ JPEGEncodeParam jep) {
|
|
+ return new JPEGImageEncoderImpl(dest, jep);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects.
|
|
+ *
|
|
+ * @param bi
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGEncodeParam getDefaultJPEGEncodeParam(BufferedImage bi) {
|
|
+ return getDefaultJPEGEncodeParam(bi.getRaster(),
|
|
+ getDefaultColorID(bi.getColorModel()));
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects.
|
|
+ *
|
|
+ * @param numBands
|
|
+ * @param colorID
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGEncodeParam getDefaultJPEGEncodeParam(int numBands,
|
|
+ int colorID) {
|
|
+ return new JPEGParam(colorID, numBands);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating a JPEGEncodeParam from a
|
|
+ * JPEGDecodeParam.
|
|
+ *
|
|
+ * @param jdp
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGEncodeParam getDefaultJPEGEncodeParam(JPEGDecodeParam jdp) {
|
|
+ return new JPEGParam(jdp);
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects.
|
|
+ *
|
|
+ * @param ras
|
|
+ * @param colorID
|
|
+ * @return
|
|
+ */
|
|
+ public static JPEGEncodeParam getDefaultJPEGEncodeParam(Raster ras,
|
|
+ int colorID) {
|
|
+ return getDefaultJPEGEncodeParam(ras.getNumBands(), colorID);
|
|
+ }
|
|
+
|
|
+ private static int getDefaultColorID(ColorModel cm) {
|
|
+ ColorSpace cs = cm.getColorSpace();
|
|
+ int type = cs.getType();
|
|
+ int id = -1;
|
|
+ switch (type) {
|
|
+ case ColorSpace.TYPE_GRAY:
|
|
+ id = JPEGEncodeParam.COLOR_ID_GRAY;
|
|
+ break;
|
|
+
|
|
+ case ColorSpace.TYPE_RGB:
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_RGBA
|
|
+ : JPEGEncodeParam.COLOR_ID_RGB;
|
|
+
|
|
+ case ColorSpace.TYPE_YCbCr:
|
|
+ try {
|
|
+ if (cs == ColorSpace.getInstance(ColorSpace.CS_PYCC)) {
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_PYCCA
|
|
+ : JPEGEncodeParam.COLOR_ID_PYCC;
|
|
+ }
|
|
+ } catch (IllegalArgumentException e) {
|
|
+ /* We know it isn't PYCC type, nothing to handle */
|
|
+ }
|
|
+ if (id == -1) {
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_YCbCrA
|
|
+ : JPEGEncodeParam.COLOR_ID_YCbCr;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case ColorSpace.TYPE_CMYK:
|
|
+ id = JPEGEncodeParam.COLOR_ID_CMYK;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ id = JPEGEncodeParam.COLOR_ID_UNKNOWN;
|
|
+ }
|
|
+
|
|
+ return id;
|
|
+ }
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGDecodeParam.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGDecodeParam.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,390 @@
|
|
+/* JPEGImageDecoder.java --
|
|
+ * Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+ * Copyright (C) 2007 Matthew Flaschen
|
|
+ *
|
|
+ * This file is part of GNU Classpath.
|
|
+ *
|
|
+ * GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ * 02110-1301 USA.
|
|
+ *
|
|
+ * Linking this library statically or dynamically with other modules is
|
|
+ * making a combined work based on this library. Thus, the terms and
|
|
+ * conditions of the GNU General Public License cover the whole
|
|
+ * combination.
|
|
+ *
|
|
+ * As a special exception, the copyright holders of this library give you
|
|
+ * permission to link this library with independent modules to produce an
|
|
+ * executable, regardless of the license terms of these independent
|
|
+ * modules, and to copy and distribute the resulting executable under
|
|
+ * terms of your choice, provided that you also meet, for each linked
|
|
+ * independent module, the terms and conditions of the license of that
|
|
+ * module. An independent module is a module which is not derived from
|
|
+ * or based on this library. If you modify this library, you may extend
|
|
+ * this exception to your version of the library, but you are not
|
|
+ * obligated to do so. If you do not wish to do so, delete this
|
|
+ * exception statement from your version.
|
|
+ */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+/**
|
|
+ * <p>
|
|
+ * JPEGDecodeParam encapsulates tables and options necessary to control decoding
|
|
+ * JPEG data streams. Parameters are either set explicitly by the application
|
|
+ * for encoding, or read from the JPEG header for decoding. In the case of
|
|
+ * decoding abbreviated data streams the application may need to set some/all of
|
|
+ * the values it's self.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * When working with BufferedImages (@see JPEGImageDecoder.decodeBufferedImage),
|
|
+ * the codec will attempt to generate an appropriate ColorModel for the JPEG
|
|
+ * COLOR_ID. This is not always possible (example mappings are listed below) .
|
|
+ * In cases where unsupported conversions are required, or unknown encoded
|
|
+ * COLOR_ID's are in use, the user must request the data as a Raster and perform
|
|
+ * the transformations themselves. When decoding into a raster (@see
|
|
+ * JPEGImageDecoder.decodeRaster) no ColorSpace adjustments are made. Note: The
|
|
+ * color ids described herein are simply enumerated values that influence data
|
|
+ * processing by the JPEG codec. JPEG compression is by definition color blind.
|
|
+ * These values are used as hints when decompressing JPEG data. Of particular
|
|
+ * interest is the default conversion from YCbCr to sRGB when decoding buffered
|
|
+ * Images.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * Note: because JPEG is mostly color-blind color fidelity can not be
|
|
+ * guaranteed. This will hopefully be rectified in the near future by the wide
|
|
+ * spread inclusion of ICC-profiles in the JPEG data stream (as a special
|
|
+ * marker). The following is an example of the conversions that take place. This
|
|
+ * is only a guide to the types of conversions that are allowed. This list is
|
|
+ * likely to change in the future so it is strongly recommended that you check
|
|
+ * for thrown ImageFormatExceptions and check the actual ColorModel associated
|
|
+ * with the BufferedImage returned rather than make assumptions.
|
|
+ * </p>
|
|
+ * DECODING:
|
|
+ *
|
|
+ * <pre>
|
|
+ * JPEG (Encoded) Color ID BufferedImage ColorSpace
|
|
+ * ======================= ========================
|
|
+ * COLOR_ID_UNKNOWN ** Invalid **
|
|
+ * COLOR_ID_GRAY CS_GRAY
|
|
+ * COLOR_ID_RGB CS_sRGB
|
|
+ * COLOR_ID_YCbCr CS_sRGB
|
|
+ * COLOR_ID_CMYK ** Invalid **
|
|
+ * COLOR_ID_PYCC CS_PYCC
|
|
+ * COLOR_ID_RGBA CS_sRGB (w/ alpha)
|
|
+ * COLOR_ID_YCbCrA CS_sRGB (w/ alpha)
|
|
+ * COLOR_ID_RGBA_INVERTED ** Invalid **
|
|
+ * COLOR_ID_YCbCrA_INVERTED ** Invalid **
|
|
+ * COLOR_ID_PYCCA CS_PYCC (w/ alpha)
|
|
+ * COLOR_ID_YCCK ** Invalid **
|
|
+ * </pre>
|
|
+ * <p>
|
|
+ * If the user needs better control over conversion, the user must request the
|
|
+ * data as a Raster and handle the conversion of the image data themselves. When
|
|
+ * decoding JFIF files the encoded COLOR_ID will always be one of:
|
|
+ * COLOR_ID_UNKNOWN, COLOR_ID_GRAY, COLOR_ID_RGB, COLOR_ID_YCbCr, COLOR_ID_CMYK,
|
|
+ * or COLOR_ID_YCCK
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * Note that the classes in the com.sun.image.codec.jpeg package are not part of
|
|
+ * the core Java APIs. They are a part of Sun's JDK and JRE distributions.
|
|
+ * Although other licensees may choose to distribute these classes, developers
|
|
+ * cannot depend on their availability in non-Sun implementations. We expect
|
|
+ * that equivalent functionality will eventually be available in a core API or
|
|
+ * standard extension.
|
|
+ * </p>
|
|
+ */
|
|
+public interface JPEGDecodeParam extends Cloneable {
|
|
+
|
|
+ /** APP0 marker - JFIF info */
|
|
+ public static final int APP0_MARKER = 0xE0;
|
|
+ /** APP1 marker */
|
|
+ public static final int APP1_MARKER = 0xE1;
|
|
+ /** APP2 marker */
|
|
+ public static final int APP2_MARKER = 0xE2;
|
|
+ /** APP3 marker */
|
|
+ public static final int APP3_MARKER = 0xE3;
|
|
+ /** APP4 marker */
|
|
+ public static final int APP4_MARKER = 0xE4;
|
|
+ /** APP5 marker */
|
|
+ public static final int APP5_MARKER = 0xE5;
|
|
+ /** APP6 marker */
|
|
+ public static final int APP6_MARKER = 0xE6;
|
|
+ /** APP7 marker */
|
|
+ public static final int APP7_MARKER = 0xE7;
|
|
+ /** APP8 marker */
|
|
+ public static final int APP8_MARKER = 0xE8;
|
|
+ /** APP9 marker */
|
|
+ public static final int APP9_MARKER = 0xE9;
|
|
+ /** APPA marker */
|
|
+ public static final int APPA_MARKER = 0xEA;
|
|
+ /** APPB marker */
|
|
+ public static final int APPB_MARKER = 0xEB;
|
|
+ /** APPC marker */
|
|
+ public static final int APPC_MARKER = 0xEC;
|
|
+ /** APPD marker */
|
|
+ public static final int APPD_MARKER = 0xED;
|
|
+ /** APPE marker - Adobe info */
|
|
+ public static final int APPE_MARKER = 0xEE;
|
|
+ /** APPF marker */
|
|
+ public static final int APPF_MARKER = 0xEF;
|
|
+ /** Adobe marker indicates presence/need for Adobe marker. */
|
|
+ public static final int COMMENT_MARKER = 0XFE;
|
|
+
|
|
+ /* Color ID values */
|
|
+ public static final int COLOR_ID_UNKNOWN = 0;
|
|
+ public static final int COLOR_ID_GRAY = 1;
|
|
+ public static final int COLOR_ID_RGB = 2;
|
|
+ public static final int COLOR_ID_YCbCr = 3;
|
|
+ public static final int COLOR_ID_CMYK = 4;
|
|
+ public static final int COLOR_ID_PYCC = 5;
|
|
+ public static final int COLOR_ID_RGBA = 6;
|
|
+ public static final int COLOR_ID_YCbCrA = 7;
|
|
+ public static final int COLOR_ID_RGBA_INVERTED = 8;
|
|
+ public static final int COLOR_ID_YCbCrA_INVERTED = 9;
|
|
+ public static final int COLOR_ID_PYCCA = 10;
|
|
+ public static final int COLOR_ID_YCCK = 11;
|
|
+ public static final int NUM_COLOR_ID = 12;
|
|
+
|
|
+ /** Number of allowed Huffman and Quantization Tables */
|
|
+ public static final int NUM_TABLES = 4;
|
|
+
|
|
+ /** The X and Y units simply indicate the aspect ratio of the pixels. */
|
|
+ public static final int DENSITY_UNIT_ASPECT_RATIO = 0;
|
|
+ /** Pixel density is in pixels per inch. */
|
|
+ public static final int DENSITY_UNIT_DOTS_INCH = 1;
|
|
+ /** Pixel density is in pixels per centimeter. */
|
|
+ public static final int DENSITY_UNIT_DOTS_CM = 2;
|
|
+ /** The max known value for DENSITY_UNIT */
|
|
+ public static final int NUM_DENSITY_UNIT = 3;
|
|
+
|
|
+ public Object clone();
|
|
+
|
|
+ /**
|
|
+ * Get the image width.
|
|
+ *
|
|
+ * @return int the width of the image data in pixels.
|
|
+ */
|
|
+ public int getWidth();
|
|
+
|
|
+ /**
|
|
+ * Get the image height.
|
|
+ *
|
|
+ * @return The height of the image data in pixels.
|
|
+ */
|
|
+ public int getHeight();
|
|
+
|
|
+ /**
|
|
+ * Return the Horizontal subsampling factor for requested Component. The
|
|
+ * Subsample factor is the number of input pixels that contribute to each
|
|
+ * output pixel. This is distinct from the way the JPEG to each output
|
|
+ * pixel. This is distinct from the way the JPEG standard defines this
|
|
+ * quantity, because fractional subsampling factors are not allowed.
|
|
+ *
|
|
+ * @param component
|
|
+ * The component of the encoded image to return the subsampling
|
|
+ * factor for.
|
|
+ * @return The subsample factor.
|
|
+ */
|
|
+ public int getHorizontalSubsampling(int component);
|
|
+
|
|
+ /**
|
|
+ * Return the Vertical subsampling factor for requested Component. The
|
|
+ * Subsample factor is the number of input pixels that contribute to each
|
|
+ * output pixel. This is distinct from the way the JPEG to each output
|
|
+ * pixel. This is distinct from the way the JPEG standard defines this
|
|
+ * quantity, because fractional subsampling factors are not allowed.
|
|
+ *
|
|
+ * @param component
|
|
+ * The component of the encoded image to return the subsampling
|
|
+ * factor for.
|
|
+ * @return The subsample factor.
|
|
+ */
|
|
+ public int getVerticalSubsampling(int component);
|
|
+
|
|
+ /**
|
|
+ * Returns the coefficient quantization tables or NULL if not defined.
|
|
+ * tableNum must range in value from 0 - 3.
|
|
+ *
|
|
+ * @param tableNum
|
|
+ * the index of the table to be returned.
|
|
+ * @return Quantization table stored at index tableNum.
|
|
+ */
|
|
+ public JPEGQTable getQTable(int tableNum);
|
|
+
|
|
+ /**
|
|
+ * Returns the Quantization table for the requested component.
|
|
+ *
|
|
+ * @param component
|
|
+ * the image component of interest.
|
|
+ * @return Quantization table associated with component
|
|
+ */
|
|
+ public JPEGQTable getQTableForComponent(int component);
|
|
+
|
|
+ /**
|
|
+ * Returns the DC Huffman coding table requested or null if not defined
|
|
+ *
|
|
+ * @param tableNum
|
|
+ * the index of the table to be returned.
|
|
+ * @return Huffman table stored at index tableNum.
|
|
+ */
|
|
+ public JPEGHuffmanTable getDCHuffmanTable(int tableNum);
|
|
+
|
|
+ /**
|
|
+ * Returns the DC Huffman coding table for the requested component.
|
|
+ *
|
|
+ * @param component
|
|
+ * the image component of interest.
|
|
+ * @return Huffman table associated with component
|
|
+ */
|
|
+ public JPEGHuffmanTable getDCHuffmanTableForComponent(int component);
|
|
+
|
|
+ /**
|
|
+ * Returns the AC Huffman coding table requested or null if not defined
|
|
+ *
|
|
+ * @param tableNum
|
|
+ * the index of the table to be returned.
|
|
+ * @return Huffman table stored at index tableNum.
|
|
+ */
|
|
+ public JPEGHuffmanTable getACHuffmanTable(int tableNum);
|
|
+
|
|
+ /**
|
|
+ * Returns the AC Huffman coding table for the requested component.
|
|
+ *
|
|
+ * @param component
|
|
+ * the image component of interest.
|
|
+ * @return Huffman table associated with component
|
|
+ */
|
|
+ public JPEGHuffmanTable getACHuffmanTableForComponent(int component);
|
|
+
|
|
+ /**
|
|
+ * Get the number of the DC Huffman table that will be used for a particular
|
|
+ * component.
|
|
+ *
|
|
+ * @param component
|
|
+ * The Component of interest.
|
|
+ * @return The table number of the DC Huffman table for component.
|
|
+ */
|
|
+ public int getDCHuffmanComponentMapping(int component);
|
|
+
|
|
+ /**
|
|
+ * Get the number of the AC Huffman table that will be used for a particular
|
|
+ * component.
|
|
+ *
|
|
+ * @param component
|
|
+ * The Component of interest.
|
|
+ * @return The table number of the AC Huffman table for component.
|
|
+ */
|
|
+ public int getACHuffmanComponentMapping(int component);
|
|
+
|
|
+ /**
|
|
+ * Get the number of the quantization table that will be used for a
|
|
+ * particular component.
|
|
+ *
|
|
+ * @param component
|
|
+ * The Component of interest.
|
|
+ * @return The table number of the Quantization table for component.
|
|
+ */
|
|
+ public int getQTableComponentMapping(int component);
|
|
+
|
|
+ /**
|
|
+ * Returns true if the image information in the ParamBlock is currently
|
|
+ * valid. This indicates if image data was read from the stream for decoding
|
|
+ * and weather image data should be written when encoding.
|
|
+ */
|
|
+ public boolean isImageInfoValid();
|
|
+
|
|
+ /**
|
|
+ * Returns true if the tables in the ParamBlock are currently valid. This
|
|
+ * indicates that tables were read from the stream for decoding. When
|
|
+ * encoding this indicates whether tables should be written to the stream.
|
|
+ */
|
|
+ public boolean isTableInfoValid();
|
|
+
|
|
+ /**
|
|
+ * Returns true if at least one instance of the marker is present in the
|
|
+ * Parameter object. For encoding returns true if there is at least one
|
|
+ * instance of the marker to be written.
|
|
+ *
|
|
+ * @param marker
|
|
+ * The marker of interest.
|
|
+ */
|
|
+ public boolean getMarker(int marker);
|
|
+
|
|
+ /**
|
|
+ * Returns a 'byte[][]' associated with the requested marker in the
|
|
+ * parameter object. Each entry in the 'byte[][]' is the data associated
|
|
+ * with one instance of the marker (each marker can theoretically appear any
|
|
+ * number of times in a stream).
|
|
+ *
|
|
+ * @param marker
|
|
+ * The marker of interest.
|
|
+ * @return The 'byte[][]' for this marker or null if none available.
|
|
+ */
|
|
+ public byte[][] getMarkerData(int marker);
|
|
+
|
|
+ /**
|
|
+ * Returns the JPEG Encoded color id. This is generally speaking only used
|
|
+ * if you are decoding into Rasters. Note that when decoding into a Raster
|
|
+ * no color conversion is performed.
|
|
+ *
|
|
+ * @return The value of the JPEG encoded data's color id.
|
|
+ */
|
|
+ public int getEncodedColorID();
|
|
+
|
|
+ /**
|
|
+ * Returns the number of components for the current encoding COLOR_ID.
|
|
+ *
|
|
+ * @return the number of Components
|
|
+ */
|
|
+ public int getNumComponents();
|
|
+
|
|
+ /**
|
|
+ * Get the MCUs per restart marker.
|
|
+ *
|
|
+ * @return The number of MCUs between restart markers.
|
|
+ */
|
|
+ public int getRestartInterval();
|
|
+
|
|
+ /**
|
|
+ * Get the code for pixel size units This value is copied from the APP0
|
|
+ * marker. It isn't used by the JPEG codec. If the APP0 marker wasn't
|
|
+ * present then you can not rely on this value.
|
|
+ *
|
|
+ * @return Value indicating the density unit one of the DENSITY_UNIT_*
|
|
+ * constants.
|
|
+ */
|
|
+ public int getDensityUnit();
|
|
+
|
|
+ /**
|
|
+ * Get the horizontal pixel density This value is copied from the APP0
|
|
+ * marker. It isn't used by the JPEG code. If the APP0 marker wasn't present
|
|
+ * then you can not rely on this value.
|
|
+ *
|
|
+ * @return The horizontal pixel density, in units described by
|
|
+ * @see #getDensityUnit()
|
|
+ */
|
|
+ public int getXDensity();
|
|
+
|
|
+ /**
|
|
+ * Get the vertical pixel density This value is copied into the APP0 marker.
|
|
+ * It isn't used by the JPEG code. If the APP0 marker wasn't present then
|
|
+ * you can not rely on this value.
|
|
+ *
|
|
+ * @return The vertical pixel density, in units described by
|
|
+ * @see #getDensityUnit()
|
|
+ */
|
|
+ public int getYDensity();
|
|
+
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGEncodeParam.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGEncodeParam.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,307 @@
|
|
+/* JPEGEncodeParam.java --
|
|
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of GNU Classpath.
|
|
+
|
|
+ GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2, or (at your option)
|
|
+ any later version.
|
|
+
|
|
+ GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ 02110-1301 USA.
|
|
+
|
|
+ Linking this library statically or dynamically with other modules is
|
|
+ making a combined work based on this library. Thus, the terms and
|
|
+ conditions of the GNU General Public License cover the whole
|
|
+ combination.
|
|
+
|
|
+ As a special exception, the copyright holders of this library give you
|
|
+ permission to link this library with independent modules to produce an
|
|
+ executable, regardless of the license terms of these independent
|
|
+ modules, and to copy and distribute the resulting executable under
|
|
+ terms of your choice, provided that you also meet, for each linked
|
|
+ independent module, the terms and conditions of the license of that
|
|
+ module. An independent module is a module which is not derived from
|
|
+ or based on this library. If you modify this library, you may extend
|
|
+ this exception to your version of the library, but you are not
|
|
+ obligated to do so. If you do not wish to do so, delete this
|
|
+ exception statement from your version. */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+/**
|
|
+ * <p>
|
|
+ * JPEGEncodeParam encapsulates tables and options necessary to control encoding
|
|
+ * of JPEG data streams. Parameters are either set explicitly by the application
|
|
+ * for encoding, or read from another JPEG header.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * When working with BufferedImages, the codec will attempt to match the encoded
|
|
+ * JPEG COLOR_ID with the ColorModel in the BufferedImage. This is not always
|
|
+ * possible (the default mappings are listed below). In cases where unsupported
|
|
+ * conversions are required (or odd image colorspaces are in use) the user must
|
|
+ * either convert the image data to a known ColorSpace or encode the data from a
|
|
+ * raster. When encoding rasters no colorspace adjustments are made, so the user
|
|
+ * must do any conversions required to get to the encoded COLOR_ID. The COLOR_ID
|
|
+ * for the encoded images is used to control the JPEG codec's inital values for
|
|
+ * Huffman and Quantization Tables as well as subsampling factors. It is also
|
|
+ * used to determine what color conversion should be performed to obtain the
|
|
+ * best encoding.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * Note: The color ids described herein are simply enumerated values that
|
|
+ * influence data processing by the JPEG codec. JPEG compression is, by
|
|
+ * definition, color blind. These values are used as hints when compressing JPEG
|
|
+ * data. Through these values the JPEG codec can perform some default rotation
|
|
+ * of data into spaces that will aid in getting better compression ratios.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * Example behavior is described below. Since these mappings are likely to
|
|
+ * change in the future it is strongly recommended that you make use of the @see
|
|
+ * JPEGImageEncoder.getDefaultParamBlock calls and check the encodedColorID for
|
|
+ * your particular BufferedImage. In extreme cases is may be necessary for the
|
|
+ * user to convert the image to the desired colorspace, and encode it from a
|
|
+ * Raster. In this case the API programmer must specify the colorID of the data
|
|
+ * in the Raster and no color conversion will take place.
|
|
+ * </p>
|
|
+ *
|
|
+ * ENCODING:
|
|
+ *
|
|
+ * <pre>
|
|
+ * BufferedImage Type/Instance JPEG (Encoded) Color ID
|
|
+ * =========================== =======================
|
|
+ * TYPE_GRAY COLOR_ID_GRAYSCALE
|
|
+ * TYPE_RGB COLOR_ID_YCbCr
|
|
+ * TYPE_YCbCr COLOR_ID_YCbCr
|
|
+ * TYPE_YCbCr/CS_PYCC COLOR_ID_PYCC
|
|
+ * TYPE_CMYK COLOR_ID_CMYK
|
|
+ * TYPE_RGB (w/ alpha) COLOR_ID_YCbCrA
|
|
+ * TYPE_YCbCr (w/ alpha) COLOR_ID_YCbCrA
|
|
+ * TYPE_YCbCr/CS_PYCC (w/ alpha) COLOR_ID_PYCCA
|
|
+ * ** Any Other ** COLOR_ID_UNKNOWN
|
|
+ * </pre>
|
|
+ * <p>
|
|
+ * When the user wants more control than the BufferedImage conversions provide,
|
|
+ * the user must encode the data from a Raster. In this case the data undergoes
|
|
+ * no color conversion at all. It is the user's responsibility to perform the
|
|
+ * desired conversions. If you intend to write a JFIF image (by including the
|
|
+ * APP0_MARKER) the encoded COLOR_ID must be one of: COLOR_ID_UNKNOWN,
|
|
+ * COLOR_ID_GRAYSCALE, COLOR_ID_YCbCr, or COLOR_ID_CMYK. In all other instances
|
|
+ * an ImageformatException will be thrown.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * IMPORTANT: an Alpha RGB BufferedImage will not map to a valid JFIF stream,
|
|
+ * you must strip off the alpha prior to encoding if you want a JFIF file. If
|
|
+ * the APP0 marker is set and you do not strip off the Alpha, an
|
|
+ * ImageFormatException will be thrown.
|
|
+ * </p>
|
|
+ * <p>
|
|
+ * Note that the classes in the com.sun.image.codec.jpeg package are not part of
|
|
+ * the core Java APIs. They are a part of Sun's JDK and JRE distributions.
|
|
+ * Although other licensees may choose to distribute these classes, developers
|
|
+ * cannot depend on their availability in non-Sun implementations. We expect
|
|
+ * that equivalent functionality will eventually be available in a core API or
|
|
+ * standard extension.
|
|
+ * </p>
|
|
+ */
|
|
+public interface JPEGEncodeParam extends JPEGDecodeParam {
|
|
+
|
|
+ /**
|
|
+ * Set the horizontal subsample factor for the given component. Note that
|
|
+ * the subsample factor is the number of input pixels that contribute to
|
|
+ * each output pixel (usually 2 for YCC).
|
|
+ *
|
|
+ * @param component
|
|
+ * The component being specified.
|
|
+ * @param subsample
|
|
+ * The subsampling factor being specified.
|
|
+ */
|
|
+ public void setHorizontalSubsampling(int component, int subsample);
|
|
+
|
|
+ /**
|
|
+ * Set the vertical subsample factor for the given component. Note that the
|
|
+ * subsample factor is the number of input pixels that contribute to each
|
|
+ * output pixel (usually 2 for YCC).
|
|
+ *
|
|
+ * @param component
|
|
+ * The component being specified.
|
|
+ * @param subsample
|
|
+ * The subsampling factor being specified.
|
|
+ */
|
|
+ public void setVerticalSubsampling(int component, int subsample);
|
|
+
|
|
+ /**
|
|
+ * Sets the coefficient quantization tables at index passed. tableNum must
|
|
+ * range in value from 0 - 3.
|
|
+ *
|
|
+ * @param qtable
|
|
+ * that will be used.
|
|
+ * @param tableNum
|
|
+ * the index of the table to be set.
|
|
+ */
|
|
+ public void setQTable(int tableNum, JPEGQTable qTable);
|
|
+
|
|
+ /**
|
|
+ * Sets the DC Huffman coding table at index to the table provided.
|
|
+ *
|
|
+ * @param huffTable
|
|
+ * JPEGHuffmanTable that will be assigned to index tableNum.
|
|
+ * @param tableNum
|
|
+ * - the index of the table to be set.
|
|
+ * @exception IllegalArgumentException
|
|
+ * - thrown if the tableNum is out of range. Index must range
|
|
+ * in value from 0 - 3.
|
|
+ */
|
|
+ public void setDCHuffmanTable(int tableNum, JPEGHuffmanTable huffTable);
|
|
+
|
|
+ /**
|
|
+ * Sets the AC Huffman coding table at index to the table provided.
|
|
+ *
|
|
+ * @param huffTable
|
|
+ * JPEGHuffmanTable that will be assigned to index tableNum.
|
|
+ * @param tableNum
|
|
+ * - the index of the table to be set.
|
|
+ * @exception IllegalArgumentException
|
|
+ * - thrown if the tableNum is out of range. Index must range
|
|
+ * in value from 0 - 3.
|
|
+ */
|
|
+ public void setACHuffmanTable(int tableNum, JPEGHuffmanTable huffTable);
|
|
+
|
|
+ /**
|
|
+ * Sets the mapping between a component and it's DC Huffman Table.
|
|
+ *
|
|
+ * @param component
|
|
+ * The component to set the mapping for
|
|
+ * @param table
|
|
+ * The DC Huffman table to use for component
|
|
+ */
|
|
+ public void setDCHuffmanComponentMapping(int component, int table);
|
|
+
|
|
+ /**
|
|
+ * Sets the mapping between a component and it's AC Huffman Table.
|
|
+ *
|
|
+ * @param component
|
|
+ * The component to set the mapping for
|
|
+ * @param table
|
|
+ * The AC Huffman table to use for component
|
|
+ */
|
|
+ public void setACHuffmanComponentMapping(int component, int table);
|
|
+
|
|
+ /**
|
|
+ * Sets the mapping between a component and it's Quantization Table.
|
|
+ *
|
|
+ * @param component
|
|
+ * The component to set the mapping for
|
|
+ * @param table
|
|
+ * The Quantization Table to use for component
|
|
+ */
|
|
+ public void setQTableComponentMapping(int component, int table);
|
|
+
|
|
+ /**
|
|
+ * Set the flag indicating the validity of the table information in the
|
|
+ * ParamBlock. This is used to indicate if tables should be included when
|
|
+ * encoding.
|
|
+ */
|
|
+ public void setImageInfoValid(boolean flag);
|
|
+
|
|
+ /**
|
|
+ * Set the flag indicating the validity of the image information in the
|
|
+ * ParamBlock. This is used to indicates if image data should be written
|
|
+ * when encoding.
|
|
+ */
|
|
+ public void setTableInfoValid(boolean flag);
|
|
+
|
|
+ /**
|
|
+ * Sets the marker data to be written to the output data stream. This
|
|
+ * removes any existing marker data in the JPEParm object. This can be used
|
|
+ * to remove the default APP0 marker by calling it with data set to null.
|
|
+ *
|
|
+ * @param marker
|
|
+ * The marker to set the data for.
|
|
+ * @param data
|
|
+ * the new set of data to be written.
|
|
+ */
|
|
+ public void setMarkerData(int marker, byte[][] data);
|
|
+
|
|
+ /**
|
|
+ * Appends 'data' to the array of byte[] associated with marker. This will
|
|
+ * result in additional instance of the marker being written (one for each
|
|
+ * byte[] in the array.).
|
|
+ *
|
|
+ * @param marker
|
|
+ * The marker to add and instance of.
|
|
+ * @param data
|
|
+ * the data to be written.
|
|
+ */
|
|
+ public void addMarkerData(int marker, byte[] data);
|
|
+
|
|
+ /**
|
|
+ * Set the MCUs per restart, or 0 for no restart markers.
|
|
+ *
|
|
+ * @param restartInterval
|
|
+ * number MCUs per restart marker.
|
|
+ */
|
|
+ public void setRestartInterval(int restartInterval);
|
|
+
|
|
+ /**
|
|
+ * Set the pixel size units This value is copied into the APP0 marker (if
|
|
+ * that marker is written). This value isn't used by the JPEG code.
|
|
+ *
|
|
+ * @param unit
|
|
+ * One of the DENSITY_UNIT_* values.
|
|
+ */
|
|
+ public void setDensityUnit(int unit);
|
|
+
|
|
+ /**
|
|
+ * Set the horizontal pixel density. This value is written into the APP0
|
|
+ * marker. It isn't used by the JPEG code.
|
|
+ *
|
|
+ * @param density
|
|
+ * the horizontal pixel density, in units described by @see
|
|
+ * JPEGParam.getDensityUnit.
|
|
+ */
|
|
+ public void setXDensity(int density);
|
|
+
|
|
+ /**
|
|
+ * Set the vertical pixel density. This value is copied into the JFIF APP0
|
|
+ * marker. It isn't used by the JPEG code.
|
|
+ *
|
|
+ * @param density
|
|
+ * The vertical pixel density, in units described by @see
|
|
+ * JPEGParam.getDensityUnit.
|
|
+ */
|
|
+ public void setYDensity(int density);
|
|
+
|
|
+ /**
|
|
+ * This creates new Quantization tables that replace the currently installed
|
|
+ * Quantization tables. It also updates the Component QTable mapping to the
|
|
+ * default for the current encoded COLOR_ID.
|
|
+ *
|
|
+ * The Created Quantization table varies from very high compression, very
|
|
+ * low quality, (0.0) to low compression, very high quality (1.0) based on
|
|
+ * the quality parameter.
|
|
+ *
|
|
+ * At a quality level of 1.0 the table will be all 1's which will lead to no
|
|
+ * loss of data due to quantization (however chrominance subsampling, if
|
|
+ * used, and roundoff error in the DCT will still degrade the image some
|
|
+ * what).
|
|
+ *
|
|
+ * This is a linear manipulation of the standard chrominance Q-Table.
|
|
+ *
|
|
+ * Some guidelines: 0.75 high quality 0.5 medium quality 0.25 low quality
|
|
+ *
|
|
+ * @param quality
|
|
+ * 0.0-1.0 setting of desired quality level.
|
|
+ * @param forceBaseline
|
|
+ * force baseline quantization table
|
|
+ */
|
|
+ public void setQuality(float quality, boolean forceBaseline);
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGHuffmanTable.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGHuffmanTable.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,129 @@
|
|
+/* JPEGHuffmanTable.java -- Huffman table implementation for JPEG.
|
|
+Copyright (C) 2011 Red Hat
|
|
+
|
|
+This program is free software; you can redistribute it and/or modify
|
|
+it under the terms of the GNU General Public License as published by
|
|
+the Free Software Foundation; either version 2 of the License, or
|
|
+(at your option) any later version.
|
|
+
|
|
+This program is distributed in the hope that it will be useful, but
|
|
+WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+General Public License for more details.
|
|
+
|
|
+You should have received a copy of the GNU General Public License
|
|
+along with this program; if not, write to the Free Software
|
|
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+/**
|
|
+ * A class to encapsulate a JPEG Huffman table.
|
|
+ */
|
|
+public class JPEGHuffmanTable {
|
|
+
|
|
+ /**
|
|
+ * The standard DC luminance Huffman table.
|
|
+ */
|
|
+ public static final JPEGHuffmanTable StdDCLuminance;
|
|
+
|
|
+ /**
|
|
+ * The standard DC chrominance Huffman table.
|
|
+ */
|
|
+ public static final JPEGHuffmanTable StdDCChrominance;
|
|
+
|
|
+ /**
|
|
+ * The standard AC luminance Huffman table.
|
|
+ */
|
|
+ public static final JPEGHuffmanTable StdACLuminance;
|
|
+
|
|
+ /**
|
|
+ * The standard AC chrominance Huffman table.
|
|
+ */
|
|
+ public static final JPEGHuffmanTable StdACChrominance;
|
|
+
|
|
+ private short[] lengths;
|
|
+
|
|
+ private short[] symbols;
|
|
+
|
|
+ static {
|
|
+ javax.imageio.plugins.jpeg.JPEGHuffmanTable temp;
|
|
+
|
|
+ temp = javax.imageio.plugins.jpeg.JPEGHuffmanTable.StdDCLuminance;
|
|
+ StdDCLuminance = new JPEGHuffmanTable(temp.getLengths(),
|
|
+ temp.getValues());
|
|
+
|
|
+ temp = javax.imageio.plugins.jpeg.JPEGHuffmanTable.StdDCChrominance;
|
|
+ StdDCChrominance = new JPEGHuffmanTable(temp.getLengths(),
|
|
+ temp.getValues());
|
|
+
|
|
+ temp = javax.imageio.plugins.jpeg.JPEGHuffmanTable.StdACLuminance;
|
|
+ StdACLuminance = new JPEGHuffmanTable(temp.getLengths(),
|
|
+ temp.getValues());
|
|
+
|
|
+ temp = javax.imageio.plugins.jpeg.JPEGHuffmanTable.StdACChrominance;
|
|
+ StdACChrominance = new JPEGHuffmanTable(temp.getLengths(),
|
|
+ temp.getValues());
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Creates a Huffman table and initializes it. The input arrays are copied.
|
|
+ * The arrays must describe a possible Huffman table. For example, 3 codes
|
|
+ * cannot be expressed with a single bit.
|
|
+ *
|
|
+ * @param lengths
|
|
+ * an array of {@code short}s where <code>lengths[k]</code> is
|
|
+ * equal to the number of values with corresponding codes of
|
|
+ * length <code>k + 1</code> bits.
|
|
+ * @param values
|
|
+ * an array of shorts containing the values in order of
|
|
+ * increasing code length.
|
|
+ * @throws IllegalArgumentException
|
|
+ * if <code>lengths</code> or <code>values</code> are null, the
|
|
+ * length of <code>lengths</code> is greater than 16, the length
|
|
+ * of <code>values</code> is greater than 256, if any value in
|
|
+ * <code>lengths</code> or <code>values</code> is less than
|
|
+ * zero, or if the arrays do not describe a valid Huffman table.
|
|
+ */
|
|
+ public JPEGHuffmanTable(short lengths[], short symbols[]) {
|
|
+ if (lengths == null)
|
|
+ throw new IllegalArgumentException("lengths array can not be null.");
|
|
+ if (symbols == null)
|
|
+ throw new IllegalArgumentException("symbols array can not be null.");
|
|
+ if (lengths.length > 17)
|
|
+ throw new IllegalArgumentException("lengths array can not be longer than 17.");
|
|
+ if (symbols.length > 256)
|
|
+ throw new IllegalArgumentException("symbols array can not be longer than 256.");
|
|
+ for (int a = 0; a < lengths.length; ++a)
|
|
+ if (lengths[a] < 0)
|
|
+ throw new IllegalArgumentException("length " + a + " is smaller than zero.");
|
|
+ for (int a = 0; a < symbols.length; ++a)
|
|
+ if (symbols[a] < 0)
|
|
+ throw new IllegalArgumentException("symbol " + a + " is smaller than zero.");
|
|
+ this.lengths = lengths;
|
|
+ this.symbols = symbols;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return an array containing the number of symbols for each length in
|
|
+ * the Huffman table.
|
|
+ *
|
|
+ * @return A short array where length[a] is equal to the number of symbols
|
|
+ * in the Huffman table of length a. The first element (length[0])
|
|
+ * is unused.
|
|
+ */
|
|
+ public short[] getLengths() {
|
|
+ return lengths;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Return an array containing the Huffman symbols arranged by increasing
|
|
+ * length. To make use of this array you must refer to the lengths array.
|
|
+ *
|
|
+ * @return A short array of Huffman symbols
|
|
+ */
|
|
+ public short[] getSymbols() {
|
|
+ return symbols;
|
|
+ }
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGImageDecoder.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGImageDecoder.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,102 @@
|
|
+/* JPEGImageDecoder.java --
|
|
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+ Copyright (C) 2007 Matthew Flaschen
|
|
+
|
|
+ This file is part of GNU Classpath.
|
|
+
|
|
+ GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2, or (at your option)
|
|
+ any later version.
|
|
+
|
|
+ GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ 02110-1301 USA.
|
|
+
|
|
+ Linking this library statically or dynamically with other modules is
|
|
+ making a combined work based on this library. Thus, the terms and
|
|
+ conditions of the GNU General Public License cover the whole
|
|
+ combination.
|
|
+
|
|
+ As a special exception, the copyright holders of this library give you
|
|
+ permission to link this library with independent modules to produce an
|
|
+ executable, regardless of the license terms of these independent
|
|
+ modules, and to copy and distribute the resulting executable under
|
|
+ terms of your choice, provided that you also meet, for each linked
|
|
+ independent module, the terms and conditions of the license of that
|
|
+ module. An independent module is a module which is not derived from
|
|
+ or based on this library. If you modify this library, you may extend
|
|
+ this exception to your version of the library, but you are not
|
|
+ obligated to do so. If you do not wish to do so, delete this
|
|
+ exception statement from your version. */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.Raster;
|
|
+
|
|
+import java.io.InputStream;
|
|
+import java.io.IOException;
|
|
+
|
|
+public interface JPEGImageDecoder {
|
|
+
|
|
+ /**
|
|
+ * Decodes the current JPEG data stream. The result of decoding this
|
|
+ * InputStream is a BufferedImage the ColorModel associated with this
|
|
+ * BufferedImage is determined based on the encoded COLOR_ID of the
|
|
+ * JPEGDecodeParam object. For a tables only stream this will return null.
|
|
+ *
|
|
+ * @return BufferedImage containing the image data.
|
|
+ * @throws ImageFormatException
|
|
+ * If irregularities in the JPEG stream or an unknown condition
|
|
+ * is encountered.
|
|
+ * @throws IOException
|
|
+ */
|
|
+ public BufferedImage decodeAsBufferedImage() throws IOException,
|
|
+ ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Decode the JPEG stream that was passed as part of construction. The JPEG
|
|
+ * decompression will be performed according to the current settings of the
|
|
+ * JPEGDecodeParam object. For a tables only stream this will return null.
|
|
+ *
|
|
+ * @return Raster containg the image data. Colorspace and other pertinent
|
|
+ * information can be obtained from the JPEGDecodeParam object.
|
|
+ * @throws ImageFormatException
|
|
+ * If irregularities in the JPEG stream or an unknown condition
|
|
+ * is encountered.
|
|
+ * @throws IOException
|
|
+ */
|
|
+ public Raster decodeAsRaster() throws IOException, ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Get the input stream that decoding will occur from.
|
|
+ *
|
|
+ * @return The stream that the decoder is currently associated with.
|
|
+ */
|
|
+ public InputStream getInputStream();
|
|
+
|
|
+ /**
|
|
+ * Returns the JPEGDecodeParam object that resulted from the most recent
|
|
+ * decoding event.
|
|
+ *
|
|
+ * @return
|
|
+ */
|
|
+ public JPEGDecodeParam getJPEGDecodeParam();
|
|
+
|
|
+ /**
|
|
+ * Sets the JPEGDecodeParam object used to determine the features of the
|
|
+ * decompression performed on the JPEG encoded data. This is usually only
|
|
+ * needed for decoding abbreviated JPEG data streams.
|
|
+ *
|
|
+ * @param jdp
|
|
+ * JPEGDecodeParam object
|
|
+ */
|
|
+ public void setJPEGDecodeParam(JPEGDecodeParam jdp);
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGImageEncoder.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGImageEncoder.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,208 @@
|
|
+/* JPEGImageEncoder.java --
|
|
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+
|
|
+ This file is part of GNU Classpath.
|
|
+
|
|
+ GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2, or (at your option)
|
|
+ any later version.
|
|
+
|
|
+ GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ 02110-1301 USA.
|
|
+
|
|
+ Linking this library statically or dynamically with other modules is
|
|
+ making a combined work based on this library. Thus, the terms and
|
|
+ conditions of the GNU General Public License cover the whole
|
|
+ combination.
|
|
+
|
|
+ As a special exception, the copyright holders of this library give you
|
|
+ permission to link this library with independent modules to produce an
|
|
+ executable, regardless of the license terms of these independent
|
|
+ modules, and to copy and distribute the resulting executable under
|
|
+ terms of your choice, provided that you also meet, for each linked
|
|
+ independent module, the terms and conditions of the license of that
|
|
+ module. An independent module is a module which is not derived from
|
|
+ or based on this library. If you modify this library, you may extend
|
|
+ this exception to your version of the library, but you are not
|
|
+ obligated to do so. If you do not wish to do so, delete this
|
|
+ exception statement from your version. */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+import java.io.OutputStream;
|
|
+import java.io.IOException;
|
|
+
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.ColorModel;
|
|
+import java.awt.image.Raster;
|
|
+
|
|
+public interface JPEGImageEncoder {
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects. The
|
|
+ * returned object will do a credible job of encoding the given
|
|
+ * BufferedImage.
|
|
+ *
|
|
+ * @param bi
|
|
+ * @return
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(BufferedImage bi)
|
|
+ throws ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects. It is the
|
|
+ * users responsibility to match the colorID with the given number of bands,
|
|
+ * which should match the data being encoded. Failure to do so may lead to
|
|
+ * poor compression and/or poor image quality. If you don't understand much
|
|
+ * about JPEG it is strongly recommended that you stick to the BufferedImage
|
|
+ * interface.
|
|
+ *
|
|
+ * @param numBands
|
|
+ * the number of bands that will be encoded (max of four).
|
|
+ * @param colorID
|
|
+ * the COLOR_ID for the encoded data. This is used to set
|
|
+ * reasonable defaults in the parameter object. This must match
|
|
+ * the number of bands given.
|
|
+ * @return
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(int numBands, int colorID)
|
|
+ throws ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating a JPEGEncodeParam from a
|
|
+ * JPEGDecodeParam. This will return a new JPEGEncodeParam object that is
|
|
+ * initialized from the JPEGDecodeParam object. All major pieces of
|
|
+ * information will be initialized from the DecodeParam (Markers, Tables,
|
|
+ * mappings).
|
|
+ *
|
|
+ * @param d
|
|
+ * The JPEGDecodeParam object to copy.
|
|
+ * @return
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(JPEGDecodeParam d)
|
|
+ throws ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * This is a factory method for creating JPEGEncodeParam objects. It is the
|
|
+ * users responsiblity to match the colorID with the data contained in the
|
|
+ * Raster. Failure to do so may lead to either poor compression or poor
|
|
+ * image quality. If you don't understand much about JPEG it is strongly
|
|
+ * reccomended that you stick to the BufferedImage interfaces.
|
|
+ *
|
|
+ * @param ras
|
|
+ * @param colorID
|
|
+ * @return
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(Raster ras, int colorID)
|
|
+ throws ImageFormatException;
|
|
+
|
|
+ public JPEGEncodeParam getJPEGEncodeParam() throws ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Set the JPEGEncodeParam object that is to be used for future encoding
|
|
+ * operations. 'p' is copied so changes will not be tracked, unless you call
|
|
+ * this method again.
|
|
+ *
|
|
+ * @param p
|
|
+ * The JPEGEncodeParam object to use for future encodings.
|
|
+ */
|
|
+ public void setJPEGEncodeParam(JPEGEncodeParam p);
|
|
+
|
|
+ /**
|
|
+ * Return the stream the Encoder is current associated with.
|
|
+ *
|
|
+ * @return
|
|
+ */
|
|
+ public OutputStream getOutputStream();
|
|
+
|
|
+ /**
|
|
+ * Encode a BufferedImage as a JPEG data stream. Note, some color
|
|
+ * conversions may takes place. The jep's encoded COLOR_ID should match the
|
|
+ * value returned by getDefaultColorID when given the BufferedImage's
|
|
+ * ColorModel. This call also sets the current JPEGEncodeParam object. The
|
|
+ * given JPEGEncodeParam object will be used for this and future encodings.
|
|
+ * If p is null then a new JPEGEncodeParam object will be created by calling
|
|
+ * getDefaultJPEGEncodeParam with bi.
|
|
+ *
|
|
+ * @param bi
|
|
+ * The BufferedImage to encode.
|
|
+ * @param p
|
|
+ * The JPEGEncodeParam object used to control the encoding.
|
|
+ * @throws IOException
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public void encode(BufferedImage bi, JPEGEncodeParam p) throws IOException,
|
|
+ ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Encode a Raster as a JPEG data stream. Note that no color conversion
|
|
+ * takes place. It is required that you match the Raster to the encoded
|
|
+ * COLOR_ID contained in the current JPEGEncodeParam object. If no
|
|
+ * JPEGEncodeParam object has been provided yet a new JPEGEncodeParam object
|
|
+ * will be created by calling getDefaultJPEGEncodeParam with ras and
|
|
+ * COLOR_ID_UNKNOWN.
|
|
+ *
|
|
+ * @param ras
|
|
+ * The Raster to encode.
|
|
+ * @throws IOException
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public void encode(Raster ras) throws IOException, ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Encode a BufferedImage as a JPEG data stream. Note, some color
|
|
+ * conversions may takes place. The current JPEGEncodeParam's encoded
|
|
+ * COLOR_ID should match the value returned by getDefaultColorID when given
|
|
+ * the BufferedImage's ColorModel. If no JPEGEncodeParam object has been
|
|
+ * provided yet a default one will be created by calling
|
|
+ * getDefaultJPEGEncodeParam with bi.
|
|
+ *
|
|
+ * @param bi
|
|
+ * The BufferedImage to encode.
|
|
+ * @throws IOException
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public void encode(BufferedImage bi) throws IOException,
|
|
+ ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Encode a Raster as a JPEG data stream. Note that no color conversion
|
|
+ * takes place. It is required that you match the Raster to the encoded
|
|
+ * COLOR_ID contained in the JPEGEncodeParam object. If p is null a new
|
|
+ * JPEGEncodeParam object will be created by calling
|
|
+ * getDefaultJPEGEncodeParam with ras and COLOR_ID_UNKNOWN.
|
|
+ *
|
|
+ * @param ras
|
|
+ * The Raster to encode.
|
|
+ * @param p
|
|
+ * The JPEGEncodeParam object used to control the encoding.
|
|
+ * @throws IOException
|
|
+ * @throws ImageFormatException
|
|
+ */
|
|
+ public void encode(Raster ras, JPEGEncodeParam p) throws IOException,
|
|
+ ImageFormatException;
|
|
+
|
|
+ /**
|
|
+ * Returns the 'default' encoded COLOR_ID for a given ColorModel. This
|
|
+ * method is not needed in the simple case of encoding Buffered Images (the
|
|
+ * library will figure things out for you). It can be useful for encoding
|
|
+ * Rasters. To determine what needs to be done to the image prior to
|
|
+ * encoding.
|
|
+ *
|
|
+ * @param cm
|
|
+ * The ColorModel to map to an jpeg encoded COLOR_ID.
|
|
+ * @return
|
|
+ */
|
|
+ public int getDefaultColorId(ColorModel cm);
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGQTable.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/JPEGQTable.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,118 @@
|
|
+/* JPEGQTable.java --
|
|
+ Copyright (C) 2011 Red Hat
|
|
+ Copyright (C) 2007 Free Software Foundation, Inc.
|
|
+ Copyright (C) 2007 Matthew Flaschen
|
|
+
|
|
+ This file is part of GNU Classpath.
|
|
+
|
|
+ GNU Classpath is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2, or (at your option)
|
|
+ any later version.
|
|
+
|
|
+ GNU Classpath is distributed in the hope that it will be useful, but
|
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ 02110-1301 USA.
|
|
+
|
|
+ Linking this library statically or dynamically with other modules is
|
|
+ making a combined work based on this library. Thus, the terms and
|
|
+ conditions of the GNU General Public License cover the whole
|
|
+ combination.
|
|
+
|
|
+ As a special exception, the copyright holders of this library give you
|
|
+ permission to link this library with independent modules to produce an
|
|
+ executable, regardless of the license terms of these independent
|
|
+ modules, and to copy and distribute the resulting executable under
|
|
+ terms of your choice, provided that you also meet, for each linked
|
|
+ independent module, the terms and conditions of the license of that
|
|
+ module. An independent module is a module which is not derived from
|
|
+ or based on this library. If you modify this library, you may extend
|
|
+ this exception to your version of the library, but you are not
|
|
+ obligated to do so. If you do not wish to do so, delete this
|
|
+ exception statement from your version. */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+import java.util.Arrays;
|
|
+
|
|
+/**
|
|
+ * Class to encapsulate the JPEG quantization tables.
|
|
+ *
|
|
+ * Note: The tables K1Luminance, K1Div2Luminance, K2Chrominance,
|
|
+ * K2Div2Chrominance is an instance of the superclass.
|
|
+ *
|
|
+ * @author Andrew Su (asu@redhat.com)
|
|
+ *
|
|
+ */
|
|
+public class JPEGQTable {
|
|
+
|
|
+ /**
|
|
+ * Luminance quantization table (in zig-zag order).
|
|
+ */
|
|
+ public static final JPEGQTable StdLuminance;
|
|
+
|
|
+ /**
|
|
+ * Chromninance quantization table (in zig-zag order).
|
|
+ */
|
|
+ public static final JPEGQTable StdChrominance;
|
|
+
|
|
+ static {
|
|
+ /* table for luminance values in zig-zag order */
|
|
+ int[] table1 = { 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16,
|
|
+ 19, 24, 40, 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61,
|
|
+ 60, 57, 51, 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80,
|
|
+ 109, 81, 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100,
|
|
+ 120, 92, 101, 103, 99 };
|
|
+
|
|
+ StdLuminance = new JPEGQTable(table1);
|
|
+
|
|
+ /* table for chrominance values in zig-zag order */
|
|
+ int[] table2 = { 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56,
|
|
+ 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
|
|
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
|
|
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
|
|
+ 99, 99, 99 };
|
|
+ StdChrominance = new JPEGQTable(table2);
|
|
+ }
|
|
+
|
|
+ private int[] table;
|
|
+
|
|
+ /**
|
|
+ * Constructs an quantization table from the array that was passed. The
|
|
+ * coefficients must be in zig-zag order. The array must be of length 64.
|
|
+ * The table will be copied.
|
|
+ *
|
|
+ * @param table
|
|
+ * the quantization table, as an int array.
|
|
+ * @throws IllegalArgumentException
|
|
+ * if table is null or table.length is not equal to 64.
|
|
+ */
|
|
+ public JPEGQTable(int[] table) {
|
|
+ /* Table must be 8x8 thus 64 entries */
|
|
+ if (table == null || table.length != 64) {
|
|
+ throw new IllegalArgumentException("Not a valid table.");
|
|
+ }
|
|
+ this.table = Arrays.copyOf(table, table.length);
|
|
+ }
|
|
+
|
|
+ public int[] getTable() {
|
|
+ return Arrays.copyOf(table, table.length);
|
|
+ }
|
|
+
|
|
+ public JPEGQTable getScaledInstance(float scaleFactor, boolean forceBaseline) {
|
|
+ int limit = (forceBaseline) ? 255 : 32767;
|
|
+ int[] newTable = new int[table.length];
|
|
+ for (int i = 0; i < table.length; i++) {
|
|
+ int newValue = Math.round(table[i] * scaleFactor);
|
|
+ newTable[i] = (newValue < 1) ? 1 : (newValue > limit) ? limit : newValue;
|
|
+ }
|
|
+ return new JPEGQTable(newTable);
|
|
+ }
|
|
+
|
|
+}
|
|
--- jdk/src/share/classes/com/sun/image/codec/jpeg/TruncatedFileException.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/com/sun/image/codec/jpeg/TruncatedFileException.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,92 @@
|
|
+/* TruncatedFileException.java
|
|
+ Copyright (C) 2007 Matthew Flaschen
|
|
+ Copyright (C) 2011 Red Hat, Inc.
|
|
+
|
|
+ This file is part of IcedTea
|
|
+
|
|
+ IcedTea is free software; you can redistribute it and/or modify
|
|
+ it under the terms of the GNU General Public License as published by
|
|
+ the Free Software Foundation; either version 2, or (at your option)
|
|
+ any later version.
|
|
+
|
|
+ IcedTea is distributed in the hope that it will be useful, but
|
|
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU General Public License
|
|
+ along with GNU Classpath; see the file COPYING. If not, write to the
|
|
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
+ 02110-1301 USA.
|
|
+
|
|
+ Linking this library statically or dynamically with other modules is
|
|
+ making a combined work based on this library. Thus, the terms and
|
|
+ conditions of the GNU General Public License cover the whole
|
|
+ combination.
|
|
+
|
|
+ As a special exception, the copyright holders of this library give you
|
|
+ permission to link this library with independent modules to produce an
|
|
+ executable, regardless of the license terms of these independent
|
|
+ modules, and to copy and distribute the resulting executable under
|
|
+ terms of your choice, provided that you also meet, for each linked
|
|
+ independent module, the terms and conditions of the license of that
|
|
+ module. An independent module is a module which is not derived from
|
|
+ or based on this library. If you modify this library, you may extend
|
|
+ this exception to your version of the library, but you are not
|
|
+ obligated to do so. If you do not wish to do so, delete this
|
|
+ exception statement from your version. */
|
|
+
|
|
+package com.sun.image.codec.jpeg;
|
|
+
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.Raster;
|
|
+
|
|
+public class TruncatedFileException extends RuntimeException {
|
|
+
|
|
+ private final BufferedImage bufferedImage;
|
|
+
|
|
+ private final Raster raster;
|
|
+
|
|
+ /**
|
|
+ * Creates a new exception with the specified {@link BufferedImage}
|
|
+ * containing the partially read image data.
|
|
+ *
|
|
+ * @param bufferedImage the partially decoded image (may be null).
|
|
+ */
|
|
+ public TruncatedFileException(BufferedImage bufferedImage) {
|
|
+ this.bufferedImage = bufferedImage;
|
|
+ this.raster = null;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Creates a new exception with the specified {@link Raster}
|
|
+ * containing the partially read image data.
|
|
+ *
|
|
+ * @param raster the partially decoded image (may be null).
|
|
+ */
|
|
+ public TruncatedFileException(Raster raster) {
|
|
+ this.raster = raster;
|
|
+ this.bufferedImage = null;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns the partially read data as a {@link BufferedImage}
|
|
+ * if available, or {@code null} if not.
|
|
+ *
|
|
+ * @return the partially read data.
|
|
+ */
|
|
+ public BufferedImage getBufferedImage() {
|
|
+ return bufferedImage;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Returns the partially read data as a {@link Raster}
|
|
+ * if available, or {@code null} if not.
|
|
+ *
|
|
+ * @return the partially read data.
|
|
+ */
|
|
+ public Raster getRaster() {
|
|
+ return raster;
|
|
+ }
|
|
+
|
|
+}
|
|
--- jdk/src/share/classes/sun/awt/image/codec/JPEGImageDecoderImpl.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/sun/awt/image/codec/JPEGImageDecoderImpl.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,108 @@
|
|
+/* JPEGImageDecoderImpl.java -- JPEG decoder implementation
|
|
+Copyright (C) 2011 Red Hat
|
|
+
|
|
+This program is free software; you can redistribute it and/or modify
|
|
+it under the terms of the GNU General Public License as published by
|
|
+the Free Software Foundation; either version 2 of the License, or
|
|
+(at your option) any later version.
|
|
+
|
|
+This program is distributed in the hope that it will be useful, but
|
|
+WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+General Public License for more details.
|
|
+
|
|
+You should have received a copy of the GNU General Public License
|
|
+along with this program; if not, write to the Free Software
|
|
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+package sun.awt.image.codec;
|
|
+
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.Raster;
|
|
+import java.io.IOException;
|
|
+import java.io.InputStream;
|
|
+import java.util.Iterator;
|
|
+
|
|
+import javax.imageio.ImageIO;
|
|
+import javax.imageio.ImageReader;
|
|
+import javax.imageio.plugins.jpeg.JPEGHuffmanTable;
|
|
+import javax.imageio.plugins.jpeg.JPEGImageReadParam;
|
|
+import javax.imageio.plugins.jpeg.JPEGQTable;
|
|
+import javax.imageio.stream.MemoryCacheImageInputStream;
|
|
+
|
|
+import com.sun.image.codec.jpeg.ImageFormatException;
|
|
+import com.sun.image.codec.jpeg.JPEGDecodeParam;
|
|
+import com.sun.image.codec.jpeg.JPEGImageDecoder;
|
|
+import com.sun.imageio.plugins.jpeg.JPEGImageReader;
|
|
+
|
|
+/**
|
|
+ * This class provides the implementation for a JPEG decoder.
|
|
+ */
|
|
+public class JPEGImageDecoderImpl implements JPEGImageDecoder {
|
|
+ private static final String JPGMime = "image/jpeg";
|
|
+
|
|
+ private JPEGImageReader JPGReader;
|
|
+ private InputStream in;
|
|
+ private JPEGDecodeParam param;
|
|
+
|
|
+ public JPEGImageDecoderImpl(InputStream in) {
|
|
+ this(in, null);
|
|
+ }
|
|
+
|
|
+ public JPEGImageDecoderImpl(InputStream in, JPEGDecodeParam param) {
|
|
+ this.in = in;
|
|
+ setJPEGDecodeParam(param);
|
|
+
|
|
+ Iterator<ImageReader> JPGReaderIter = ImageIO
|
|
+ .getImageReadersByMIMEType(JPGMime);
|
|
+ if (JPGReaderIter.hasNext()) {
|
|
+ JPGReader = (JPEGImageReader) JPGReaderIter.next();
|
|
+ }
|
|
+
|
|
+ JPGReader.setInput(new MemoryCacheImageInputStream(in));
|
|
+ }
|
|
+
|
|
+ public BufferedImage decodeAsBufferedImage() throws IOException,
|
|
+ ImageFormatException {
|
|
+ JPEGImageReadParam irp = null;
|
|
+
|
|
+ if (param != null) {
|
|
+ // We should do more than this, but it's a start.
|
|
+ JPEGQTable[] qTables = new JPEGQTable[4];
|
|
+ JPEGHuffmanTable[] DCHuffmanTables = new JPEGHuffmanTable[4];
|
|
+ JPEGHuffmanTable[] ACHuffmanTables = new JPEGHuffmanTable[4];
|
|
+
|
|
+ for (int i = 0; i < 4; i++) {
|
|
+ qTables[i] = new JPEGQTable(param.getQTable(i).getTable());
|
|
+ com.sun.image.codec.jpeg.JPEGHuffmanTable dcHuffman = param.getDCHuffmanTable(i);
|
|
+ com.sun.image.codec.jpeg.JPEGHuffmanTable acHuffman = param.getACHuffmanTable(i);
|
|
+ DCHuffmanTables[i] = new JPEGHuffmanTable(dcHuffman.getLengths(),
|
|
+ dcHuffman.getSymbols());
|
|
+ ACHuffmanTables[i] = new JPEGHuffmanTable(acHuffman.getLengths(),
|
|
+ dcHuffman.getSymbols());
|
|
+ }
|
|
+
|
|
+ irp = new JPEGImageReadParam();
|
|
+ irp.setDecodeTables(qTables, DCHuffmanTables, ACHuffmanTables);
|
|
+ }
|
|
+
|
|
+ return JPGReader.read(0, irp);
|
|
+ }
|
|
+
|
|
+ public Raster decodeAsRaster() throws IOException, ImageFormatException {
|
|
+ return JPGReader.readRaster(0, null);
|
|
+ }
|
|
+
|
|
+ public InputStream getInputStream() {
|
|
+ return in;
|
|
+ }
|
|
+
|
|
+ public JPEGDecodeParam getJPEGDecodeParam() {
|
|
+ if (param == null) return null;
|
|
+ return (JPEGDecodeParam) param.clone();
|
|
+ }
|
|
+
|
|
+ public void setJPEGDecodeParam(JPEGDecodeParam jdp) {
|
|
+ param = jdp;
|
|
+ }
|
|
+}
|
|
--- jdk/src/share/classes/sun/awt/image/codec/JPEGImageEncoderImpl.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/sun/awt/image/codec/JPEGImageEncoderImpl.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,183 @@
|
|
+/* JPEGImageEncoder.java -- JPEG encoder implementation
|
|
+Copyright (C) 2011 Red Hat
|
|
+
|
|
+This program is free software; you can redistribute it and/or modify
|
|
+it under the terms of the GNU General Public License as published by
|
|
+the Free Software Foundation; either version 2 of the License, or
|
|
+(at your option) any later version.
|
|
+
|
|
+This program is distributed in the hope that it will be useful, but
|
|
+WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+General Public License for more details.
|
|
+
|
|
+You should have received a copy of the GNU General Public License
|
|
+along with this program; if not, write to the Free Software
|
|
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+package sun.awt.image.codec;
|
|
+
|
|
+import java.awt.color.ColorSpace;
|
|
+import java.awt.image.BufferedImage;
|
|
+import java.awt.image.ColorModel;
|
|
+import java.awt.image.Raster;
|
|
+import java.io.IOException;
|
|
+import java.io.OutputStream;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Iterator;
|
|
+
|
|
+import javax.imageio.IIOImage;
|
|
+import javax.imageio.ImageIO;
|
|
+import javax.imageio.ImageWriteParam;
|
|
+import javax.imageio.ImageWriter;
|
|
+import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
|
|
+import javax.imageio.stream.MemoryCacheImageOutputStream;
|
|
+
|
|
+import com.sun.image.codec.jpeg.ImageFormatException;
|
|
+import com.sun.image.codec.jpeg.JPEGCodec;
|
|
+import com.sun.image.codec.jpeg.JPEGDecodeParam;
|
|
+import com.sun.image.codec.jpeg.JPEGEncodeParam;
|
|
+import com.sun.image.codec.jpeg.JPEGImageEncoder;
|
|
+import com.sun.imageio.plugins.jpeg.JPEG;
|
|
+
|
|
+/**
|
|
+ * This class provides the implementation for encoding JPEG images.
|
|
+ *
|
|
+ */
|
|
+public class JPEGImageEncoderImpl implements JPEGImageEncoder {
|
|
+ private static final String JPGMime = "image/jpeg";
|
|
+
|
|
+ private ImageWriter JPGWriter;
|
|
+ private JPEGEncodeParam param;
|
|
+ private OutputStream out;
|
|
+
|
|
+ public JPEGImageEncoderImpl(OutputStream os) {
|
|
+ this(os, null);
|
|
+ }
|
|
+
|
|
+ public JPEGImageEncoderImpl(OutputStream out, JPEGEncodeParam newParam) {
|
|
+ this.out = out;
|
|
+ setJPEGEncodeParam(newParam);
|
|
+
|
|
+ Iterator<ImageWriter> JPGWriterIter = ImageIO
|
|
+ .getImageWritersByMIMEType(JPGMime);
|
|
+ if (JPGWriterIter.hasNext()) {
|
|
+ JPGWriter = JPGWriterIter.next();
|
|
+ }
|
|
+
|
|
+ JPGWriter.setOutput(new MemoryCacheImageOutputStream(out));
|
|
+ }
|
|
+
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(BufferedImage bi)
|
|
+ throws ImageFormatException {
|
|
+ return JPEGCodec.getDefaultJPEGEncodeParam(bi);
|
|
+ }
|
|
+
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(int numBands, int colorID)
|
|
+ throws ImageFormatException {
|
|
+ return JPEGCodec.getDefaultJPEGEncodeParam(numBands, colorID);
|
|
+ }
|
|
+
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(JPEGDecodeParam d)
|
|
+ throws ImageFormatException {
|
|
+ return JPEGCodec.getDefaultJPEGEncodeParam(d);
|
|
+ }
|
|
+
|
|
+ public JPEGEncodeParam getDefaultJPEGEncodeParam(Raster ras, int colorID)
|
|
+ throws ImageFormatException {
|
|
+ return JPEGCodec.getDefaultJPEGEncodeParam(ras, colorID);
|
|
+ }
|
|
+
|
|
+ public JPEGEncodeParam getJPEGEncodeParam() throws ImageFormatException {
|
|
+ if (param == null)
|
|
+ return null;
|
|
+ return (JPEGEncodeParam) param.clone();
|
|
+ }
|
|
+
|
|
+ public void setJPEGEncodeParam(JPEGEncodeParam p) {
|
|
+ param = p;
|
|
+ }
|
|
+
|
|
+ public OutputStream getOutputStream() {
|
|
+ return out;
|
|
+ }
|
|
+
|
|
+ private void encode(IIOImage img) throws IOException, ImageFormatException {
|
|
+ if (JPGWriter == null)
|
|
+ throw new ImageFormatException(
|
|
+ "JPEG writer code not implemented in ImageIO");
|
|
+
|
|
+ JPEGImageWriteParam jiwp = new JPEGImageWriteParam(null);
|
|
+ ;
|
|
+ jiwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
|
+ if (param != null && param instanceof JPEGParam) {
|
|
+ JPEGParam jp = (JPEGParam) param;
|
|
+ jiwp.setCompressionQuality(jp.getQuality());
|
|
+ } else {
|
|
+ jiwp.setCompressionQuality(JPEG.DEFAULT_QUALITY);
|
|
+ }
|
|
+
|
|
+ JPGWriter.write(null, img, jiwp);
|
|
+ }
|
|
+
|
|
+ public void encode(BufferedImage bi, JPEGEncodeParam writeParam)
|
|
+ throws IOException, ImageFormatException {
|
|
+ setJPEGEncodeParam(writeParam);
|
|
+ encode(new IIOImage(bi, new ArrayList<BufferedImage>(), null));
|
|
+ }
|
|
+
|
|
+ public void encode(Raster rs, JPEGEncodeParam writeParam)
|
|
+ throws IOException, ImageFormatException {
|
|
+ setJPEGEncodeParam(writeParam);
|
|
+ encode(new IIOImage(rs, new ArrayList<BufferedImage>(), null));
|
|
+ }
|
|
+
|
|
+ public void encode(BufferedImage bi) throws IOException,
|
|
+ ImageFormatException {
|
|
+ encode(bi, null);
|
|
+ }
|
|
+
|
|
+ public void encode(Raster rs) throws IOException, ImageFormatException {
|
|
+ encode(rs, null);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getDefaultColorId(ColorModel cm) {
|
|
+ ColorSpace cs = cm.getColorSpace();
|
|
+ int type = cs.getType();
|
|
+ int id = -1;
|
|
+ switch (type) {
|
|
+ case ColorSpace.TYPE_GRAY:
|
|
+ id = JPEGEncodeParam.COLOR_ID_GRAY;
|
|
+ break;
|
|
+
|
|
+ case ColorSpace.TYPE_RGB:
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_RGBA
|
|
+ : JPEGEncodeParam.COLOR_ID_RGB;
|
|
+
|
|
+ case ColorSpace.TYPE_YCbCr:
|
|
+ try {
|
|
+ if (cs == ColorSpace.getInstance(ColorSpace.CS_PYCC)) {
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_PYCCA
|
|
+ : JPEGEncodeParam.COLOR_ID_PYCC;
|
|
+ }
|
|
+ } catch (IllegalArgumentException e) {
|
|
+ /* We know it isn't PYCC type, nothing to handle */
|
|
+ }
|
|
+ if (id == -1) {
|
|
+ id = cm.hasAlpha() ? JPEGEncodeParam.COLOR_ID_YCbCrA
|
|
+ : JPEGEncodeParam.COLOR_ID_YCbCr;
|
|
+ }
|
|
+ break;
|
|
+
|
|
+ case ColorSpace.TYPE_CMYK:
|
|
+ id = JPEGEncodeParam.COLOR_ID_CMYK;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ id = JPEGEncodeParam.COLOR_ID_UNKNOWN;
|
|
+ }
|
|
+
|
|
+ return id;
|
|
+ }
|
|
+}
|
|
--- jdk/src/share/classes/sun/awt/image/codec/JPEGParam.java 1969-12-31 19:00:00.000000000 -0500
|
|
+++ jdk/src/share/classes/sun/awt/image/codec/JPEGParam.java 2011-07-07 09:19:34.000000000 -0400
|
|
@@ -0,0 +1,750 @@
|
|
+/* JPEGParam.java -- keeps track of encode and decode parameters for JPEG.
|
|
+ * Copyright (C) 2011 Red Hat
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful, but
|
|
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ * General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+package sun.awt.image.codec;
|
|
+
|
|
+import java.util.Arrays;
|
|
+
|
|
+import com.sun.image.codec.jpeg.JPEGDecodeParam;
|
|
+import com.sun.image.codec.jpeg.JPEGEncodeParam;
|
|
+import com.sun.image.codec.jpeg.JPEGHuffmanTable;
|
|
+import com.sun.image.codec.jpeg.JPEGQTable;
|
|
+import com.sun.imageio.plugins.jpeg.JPEG;
|
|
+
|
|
+/**
|
|
+ * This class encapsulates the information about encoding and decoding the JPEG
|
|
+ * image.
|
|
+ *
|
|
+ * @author Andrew Su (asu@redhat.com)
|
|
+ *
|
|
+ */
|
|
+public class JPEGParam implements JPEGEncodeParam {
|
|
+ /*
|
|
+ * NOTE: bands mean the same thing as components, trying to keep it
|
|
+ * Consistent with the documentation
|
|
+ *
|
|
+ * NOTE: subsampling is not done implementing.
|
|
+ */
|
|
+
|
|
+ private float quality = JPEG.DEFAULT_QUALITY;
|
|
+ private int colorID = -1;
|
|
+ private int width;
|
|
+ private int height;
|
|
+ private int numBands;
|
|
+ private boolean imageInfoValid = false;
|
|
+ private boolean tableInfoValid = false;
|
|
+ private JPEGQTable[] qTable = new JPEGQTable[NUM_TABLES];
|
|
+ private JPEGHuffmanTable[] acHuffmanTable = new JPEGHuffmanTable[NUM_TABLES];
|
|
+ private JPEGHuffmanTable[] dcHuffmanTable = new JPEGHuffmanTable[NUM_TABLES];
|
|
+
|
|
+ private int restartInterval = 0;
|
|
+ private int[] horizontalSubsampleComponents;
|
|
+ private int[] verticalSubsampleComponents;
|
|
+
|
|
+ /* [marker between 0xE0 to 0xEF minus 0xE0 to get index][data] */
|
|
+ private byte[][][] markers = new byte[16][][];
|
|
+ private byte[][] commentMarker = null;
|
|
+
|
|
+ /* number of components each color id has (color id from JPEGDecodeParam) */
|
|
+ private static int[] components = { 0, 1, 3, 3, 4, 3, 4, 4, 4, 4, 4, 4, };
|
|
+ private int[] qTableComponentMapping;
|
|
+ private int[] acHuffmanComponentMapping;
|
|
+ private int[] dcHuffmanComponentMapping;
|
|
+
|
|
+ /*
|
|
+ * Breakdown for marker bytes
|
|
+ * 5 for name.
|
|
+ * 2 for version.
|
|
+ * 1 for density type.
|
|
+ * 2 for x density.
|
|
+ * 2 for y density.
|
|
+ * 2 for thumbnail.
|
|
+ */
|
|
+ private byte APP0_MARKER_NUM_BYTES = 14;
|
|
+
|
|
+ public JPEGParam(JPEGEncodeParam param) {
|
|
+ this((JPEGDecodeParam) param);
|
|
+ }
|
|
+
|
|
+ public JPEGParam(JPEGDecodeParam param) {
|
|
+ this(param.getEncodedColorID(), param.getNumComponents());
|
|
+
|
|
+ setTableInfoValid(param.isTableInfoValid());
|
|
+ setImageInfoValid(param.isImageInfoValid());
|
|
+ setRestartInterval(param.getRestartInterval());
|
|
+
|
|
+ // Copy the Q tables and Huffman tables.
|
|
+ for (int i = 0; i < NUM_TABLES; i++) {
|
|
+ qTable[i] = param.getQTable(i);
|
|
+ acHuffmanTable[i] = param.getACHuffmanTable(i);
|
|
+ dcHuffmanTable[i] = param.getDCHuffmanTable(i);
|
|
+ }
|
|
+
|
|
+ // Next we want to copy the component mappings.
|
|
+ for (int i = 0; i < getNumComponents(); i++) {
|
|
+ setQTableComponentMapping(i, param.getQTableComponentMapping(i));
|
|
+ setACHuffmanComponentMapping(i,
|
|
+ param.getACHuffmanComponentMapping(i));
|
|
+ setDCHuffmanComponentMapping(i,
|
|
+ param.getDCHuffmanComponentMapping(i));
|
|
+ }
|
|
+
|
|
+ // Copy all the marker data.
|
|
+ for (int i = APP0_MARKER; i < APPF_MARKER; i++) {
|
|
+ byte[][] markerData = param.getMarkerData(i);
|
|
+ byte[][] copyMarkerData = null;
|
|
+ if (markerData != null) {
|
|
+ copyMarkerData = new byte[markerData.length][];
|
|
+ for (int j = 0; j < markerData.length; j++) {
|
|
+ copyMarkerData[j] = Arrays.copyOf(markerData[j],
|
|
+ markerData[j].length);
|
|
+ }
|
|
+ }
|
|
+ setMarkerData(i, copyMarkerData);
|
|
+ }
|
|
+
|
|
+ byte[][] commentData = param.getMarkerData(COMMENT_MARKER);
|
|
+ byte[][] copyCommentData = null;
|
|
+ if (commentData != null) {
|
|
+ copyCommentData = new byte[commentData.length][];
|
|
+ for (int i = 0; i < commentData.length; i++) {
|
|
+ copyCommentData[i] = Arrays.copyOf(commentData[i],
|
|
+ commentData[i].length);
|
|
+ }
|
|
+ setMarkerData(COMMENT_MARKER, copyCommentData);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public JPEGParam(int colorID) {
|
|
+ this(colorID, components[colorID]);
|
|
+ }
|
|
+
|
|
+ public JPEGParam(int colorID, int numBands) {
|
|
+ // We were given an invalid color id, or the number of bands given to us
|
|
+ // did not match requirements.
|
|
+ if (colorID < 0
|
|
+ || colorID >= JPEGDecodeParam.NUM_COLOR_ID
|
|
+ || (colorID != COLOR_ID_UNKNOWN && numBands != components[colorID])) {
|
|
+ throw new IllegalArgumentException();
|
|
+ }
|
|
+ this.colorID = colorID;
|
|
+ this.numBands = numBands;
|
|
+
|
|
+ initialize();
|
|
+ }
|
|
+
|
|
+ private void initialize() {
|
|
+
|
|
+ qTable[0] = JPEGQTable.StdLuminance;
|
|
+ qTable[1] = JPEGQTable.StdChrominance;
|
|
+
|
|
+ acHuffmanTable[0] = JPEGHuffmanTable.StdACLuminance;
|
|
+ acHuffmanTable[1] = JPEGHuffmanTable.StdACChrominance;
|
|
+
|
|
+ dcHuffmanTable[0] = JPEGHuffmanTable.StdDCLuminance;
|
|
+ dcHuffmanTable[1] = JPEGHuffmanTable.StdDCChrominance;
|
|
+
|
|
+ qTableComponentMapping = new int[getNumComponents()];
|
|
+ acHuffmanComponentMapping = new int[getNumComponents()];
|
|
+ dcHuffmanComponentMapping = new int[getNumComponents()];
|
|
+
|
|
+ horizontalSubsampleComponents = new int[getNumComponents()];
|
|
+ verticalSubsampleComponents = new int[getNumComponents()];
|
|
+
|
|
+ /*
|
|
+ * we can just set these to true since they are using default values
|
|
+ * right now
|
|
+ */
|
|
+ setTableInfoValid(true);
|
|
+ setImageInfoValid(true);
|
|
+
|
|
+ setMarkerData(APP0_MARKER,
|
|
+ arrayAdd(getMarkerData(APP0_MARKER), createAPP0MarkerData()));
|
|
+
|
|
+ }
|
|
+
|
|
+ private byte[] createAPP0MarkerData() {
|
|
+ byte[] data = null;
|
|
+ // Create JFIF APP0 Marker if compatible.
|
|
+ // By compatible, it must be one of the following cases.
|
|
+ // Reference:
|
|
+ // http://www.jpeg.org/public/jfif.pdf
|
|
+ // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JFIF.html
|
|
+ switch (colorID) {
|
|
+ case COLOR_ID_UNKNOWN:
|
|
+ case COLOR_ID_GRAY:
|
|
+ case COLOR_ID_RGB:
|
|
+ case COLOR_ID_YCbCr:
|
|
+ case COLOR_ID_CMYK:
|
|
+ data = new byte[APP0_MARKER_NUM_BYTES];
|
|
+
|
|
+ // Null terminated JFIF string. [5 bytes]
|
|
+ data[0] = 'J';
|
|
+ data[1] = 'F';
|
|
+ data[2] = 'I';
|
|
+ data[3] = 'F';
|
|
+ data[4] = 0x0;
|
|
+
|
|
+ // Version number [2 bytes]
|
|
+ data[5] = 1;
|
|
+ data[6] = 2;
|
|
+
|
|
+ // Density unit [1 byte]
|
|
+ data[7] = DENSITY_UNIT_ASPECT_RATIO;
|
|
+
|
|
+ // X density [2 bytes]
|
|
+ data[8] = 0;
|
|
+ data[9] = 1;
|
|
+
|
|
+ // Y density [2 bytes]
|
|
+ data[10] = 0;
|
|
+ data[11] = 1;
|
|
+
|
|
+ // Thumbnail [2 bytes]
|
|
+ data[12] = 0;
|
|
+ data[13] = 0;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return data;
|
|
+ }
|
|
+
|
|
+ public void setQuality(float quality, boolean forceBaseline) {
|
|
+ if (quality < 0.0) {
|
|
+ quality = 0.00f;
|
|
+ } else if (quality > 1.0) {
|
|
+ quality = 1.0f;
|
|
+ }
|
|
+
|
|
+ this.quality = quality; // preserve original.
|
|
+
|
|
+ /*
|
|
+ * Since quality value of 1 is the lowest compression, we want our
|
|
+ * QTable to contain as much 1s as possible. Since scaling is by a
|
|
+ * factor, we want to invert the selection such that highest quality is
|
|
+ * 0 and lowest is 1.
|
|
+ */
|
|
+ quality = 1 - quality;
|
|
+
|
|
+ // We will scale our QTables to match the quality value given to us.
|
|
+ for (int i = 0; i < NUM_TABLES; i++) {
|
|
+ if (qTable[i] != null) {
|
|
+ qTable[i] = qTable[i].getScaledInstance(quality, forceBaseline);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public Object clone() {
|
|
+ JPEGParam c = new JPEGParam(this);
|
|
+ return c;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getWidth() {
|
|
+ return width;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getHeight() {
|
|
+ return height;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getHorizontalSubsampling(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ return horizontalSubsampleComponents[component];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getVerticalSubsampling(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ return verticalSubsampleComponents[component];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGQTable getQTable(int tableNum) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+ return qTable[tableNum];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGQTable getQTableForComponent(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ return qTable[qTableComponentMapping[component]];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGHuffmanTable getDCHuffmanTable(int tableNum) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+ return dcHuffmanTable[tableNum];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGHuffmanTable getDCHuffmanTableForComponent(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ return dcHuffmanTable[dcHuffmanComponentMapping[component]];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGHuffmanTable getACHuffmanTable(int tableNum) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+ return acHuffmanTable[tableNum];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public JPEGHuffmanTable getACHuffmanTableForComponent(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ return acHuffmanTable[acHuffmanComponentMapping[component]];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getDCHuffmanComponentMapping(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+ return dcHuffmanComponentMapping[component];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getACHuffmanComponentMapping(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+ return acHuffmanComponentMapping[component];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getQTableComponentMapping(int component) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+ return qTableComponentMapping[component];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isImageInfoValid() {
|
|
+ return imageInfoValid;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isTableInfoValid() {
|
|
+ return tableInfoValid;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean getMarker(int marker) {
|
|
+ byte[][] data = null;
|
|
+ switch (marker) {
|
|
+ case APP0_MARKER:
|
|
+ case APP1_MARKER:
|
|
+ case APP2_MARKER:
|
|
+ case APP3_MARKER:
|
|
+ case APP4_MARKER:
|
|
+ case APP5_MARKER:
|
|
+ case APP6_MARKER:
|
|
+ case APP7_MARKER:
|
|
+ case APP8_MARKER:
|
|
+ case APP9_MARKER:
|
|
+ case APPA_MARKER:
|
|
+ case APPB_MARKER:
|
|
+ case APPC_MARKER:
|
|
+ case APPD_MARKER:
|
|
+ case APPE_MARKER:
|
|
+ case APPF_MARKER:
|
|
+ data = markers[marker - APP0_MARKER];
|
|
+ break;
|
|
+ case COMMENT_MARKER:
|
|
+ data = commentMarker;
|
|
+ break;
|
|
+ default:
|
|
+ throw new IllegalArgumentException("Marker provided is invalid");
|
|
+ }
|
|
+
|
|
+ return data != null && data.length > 0;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public byte[][] getMarkerData(int marker) {
|
|
+ byte[][] data = null;
|
|
+
|
|
+ switch (marker) {
|
|
+ case APP0_MARKER:
|
|
+ case APP1_MARKER:
|
|
+ case APP2_MARKER:
|
|
+ case APP3_MARKER:
|
|
+ case APP4_MARKER:
|
|
+ case APP5_MARKER:
|
|
+ case APP6_MARKER:
|
|
+ case APP7_MARKER:
|
|
+ case APP8_MARKER:
|
|
+ case APP9_MARKER:
|
|
+ case APPA_MARKER:
|
|
+ case APPB_MARKER:
|
|
+ case APPC_MARKER:
|
|
+ case APPD_MARKER:
|
|
+ case APPE_MARKER:
|
|
+ case APPF_MARKER:
|
|
+ data = markers[marker - APP0_MARKER];
|
|
+ break;
|
|
+ case COMMENT_MARKER:
|
|
+ // TODO: Add stuff for comment marker
|
|
+ break;
|
|
+ default:
|
|
+ throw new IllegalArgumentException("Marker provided is invalid");
|
|
+ }
|
|
+ return data;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getEncodedColorID() {
|
|
+ return colorID;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getNumComponents() {
|
|
+ return numBands;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getRestartInterval() {
|
|
+ return restartInterval;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getDensityUnit() {
|
|
+ if (!getMarker(APP0_MARKER))
|
|
+ throw new IllegalArgumentException("APP0 Marker not found.");
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+
|
|
+ if (data == null)
|
|
+ throw new IllegalArgumentException("No valid APP0 Marker found");
|
|
+
|
|
+ return data[7];
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getXDensity() {
|
|
+ if (!getMarker(APP0_MARKER))
|
|
+ throw new IllegalArgumentException("APP0 Marker not found.");
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+
|
|
+ if (data == null)
|
|
+ throw new IllegalArgumentException("No valid APP0 Marker found");
|
|
+
|
|
+ // data[8] is the upper portion of the density value
|
|
+ // data[9] is the lower portion of the density value
|
|
+ int upper = data[8] << 8; // Shift it so we can merge with lower value.
|
|
+ int lower = data[9] & 0xFF; // Keep it in bounds 0 - 256
|
|
+ return upper | lower; // Merge
|
|
+
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getYDensity() {
|
|
+ if (!getMarker(APP0_MARKER))
|
|
+ throw new IllegalArgumentException("APP0 Marker not found.");
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+
|
|
+ if (data == null)
|
|
+ throw new IllegalArgumentException("No valid APP0 Marker found");
|
|
+
|
|
+ // data[10] is the upper portion of the density value
|
|
+ // data[11] is the lower portion of the density value
|
|
+ int upper = data[10] << 8; // Shift it so we can merge with lower value.
|
|
+ int lower = data[11] & 0xFF;// Keep it in bounds 0 - 256
|
|
+ return upper | lower; // merge
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setHorizontalSubsampling(int component, int subsample) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ horizontalSubsampleComponents[component] = subsample;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setVerticalSubsampling(int component, int subsample) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component");
|
|
+ }
|
|
+
|
|
+ verticalSubsampleComponents[component] = subsample;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setQTable(int tableNum, JPEGQTable qTable) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+
|
|
+ this.qTable[tableNum] = qTable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setDCHuffmanTable(int tableNum, JPEGHuffmanTable huffTable) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+
|
|
+ dcHuffmanTable[tableNum] = huffTable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setACHuffmanTable(int tableNum, JPEGHuffmanTable huffTable) {
|
|
+ if (tableNum < 0 || tableNum > NUM_TABLES)
|
|
+ throw new IllegalArgumentException("tableNum must be [0-"
|
|
+ + (NUM_TABLES - 1) + "]");
|
|
+ acHuffmanTable[tableNum] = huffTable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setACHuffmanComponentMapping(int component, int table) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component specified.");
|
|
+ } else if (table < 0 || table > NUM_TABLES) {
|
|
+ throw new IllegalArgumentException("Invalid table specified");
|
|
+ }
|
|
+
|
|
+ acHuffmanComponentMapping[component] = table;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setDCHuffmanComponentMapping(int component, int table) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component specified.");
|
|
+ } else if (table < 0 || table > NUM_TABLES) {
|
|
+ throw new IllegalArgumentException("Invalid table specified");
|
|
+ }
|
|
+
|
|
+ dcHuffmanComponentMapping[component] = table;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setQTableComponentMapping(int component, int table) {
|
|
+ if (component < 0 || component > getNumComponents()) {
|
|
+ throw new IllegalArgumentException("Invalid component specified.");
|
|
+ } else if (table < 0 || table > NUM_TABLES) {
|
|
+ throw new IllegalArgumentException("Invalid table specified");
|
|
+ }
|
|
+
|
|
+ qTableComponentMapping[component] = table;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setImageInfoValid(boolean flag) {
|
|
+ imageInfoValid = flag;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setTableInfoValid(boolean flag) {
|
|
+ tableInfoValid = flag;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setMarkerData(int marker, byte[][] data) {
|
|
+ if (data == null) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ switch (marker) {
|
|
+ case APP0_MARKER:
|
|
+ case APP1_MARKER:
|
|
+ case APP2_MARKER:
|
|
+ case APP3_MARKER:
|
|
+ case APP4_MARKER:
|
|
+ case APP5_MARKER:
|
|
+ case APP6_MARKER:
|
|
+ case APP7_MARKER:
|
|
+ case APP8_MARKER:
|
|
+ case APP9_MARKER:
|
|
+ case APPA_MARKER:
|
|
+ case APPB_MARKER:
|
|
+ case APPC_MARKER:
|
|
+ case APPD_MARKER:
|
|
+ case APPE_MARKER:
|
|
+ case APPF_MARKER:
|
|
+ markers[marker - APP0_MARKER] = data;
|
|
+ break;
|
|
+ case COMMENT_MARKER:
|
|
+ commentMarker = data;
|
|
+ break;
|
|
+ default:
|
|
+ throw new IllegalArgumentException("Marker provided is invalid");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void addMarkerData(int marker, byte[] data) {
|
|
+ if (data == null) {
|
|
+ return;
|
|
+ }
|
|
+ switch (marker) {
|
|
+ case APP0_MARKER:
|
|
+ case APP1_MARKER:
|
|
+ case APP2_MARKER:
|
|
+ case APP3_MARKER:
|
|
+ case APP4_MARKER:
|
|
+ case APP5_MARKER:
|
|
+ case APP6_MARKER:
|
|
+ case APP7_MARKER:
|
|
+ case APP8_MARKER:
|
|
+ case APP9_MARKER:
|
|
+ case APPA_MARKER:
|
|
+ case APPB_MARKER:
|
|
+ case APPC_MARKER:
|
|
+ case APPD_MARKER:
|
|
+ case APPE_MARKER:
|
|
+ case APPF_MARKER:
|
|
+ markers[marker - APP0_MARKER] = arrayAdd(markers[marker
|
|
+ - APP0_MARKER], data);
|
|
+ break;
|
|
+ case COMMENT_MARKER:
|
|
+ commentMarker = arrayAdd(commentMarker, data);
|
|
+ break;
|
|
+ default:
|
|
+ throw new IllegalArgumentException("Marker provided is invalid");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setRestartInterval(int restartInterval) {
|
|
+ this.restartInterval = restartInterval;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setDensityUnit(int unit) {
|
|
+ if (unit < 0 || unit > NUM_DENSITY_UNIT) {
|
|
+ throw new IllegalArgumentException("Invalid density unit.");
|
|
+ }
|
|
+
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+ if (data == null) { // We will create one now.
|
|
+ data = createAPP0MarkerData();
|
|
+ // markers[0] = array of APP0_MARKER
|
|
+ markers[0] = arrayAdd(markers[0], data);
|
|
+ }
|
|
+
|
|
+ data[7] = (byte) unit;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setXDensity(int density) {
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+ if (data == null) { // We will create one now.
|
|
+ data = createAPP0MarkerData();
|
|
+ // markers[0] = array of APP0_MARKER
|
|
+ markers[0] = arrayAdd(markers[0], data);
|
|
+ }
|
|
+
|
|
+ byte upper = (byte) (density >>> 8 & 0xFF); // unsigned shift to keep it
|
|
+ // positive
|
|
+ byte lower = (byte) (density & 0xFF);
|
|
+ data[8] = upper;
|
|
+ data[9] = lower;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setYDensity(int density) {
|
|
+ byte[] data = getValidAPP0Marker();
|
|
+ if (data == null) { // We will create one now.
|
|
+ data = createAPP0MarkerData();
|
|
+ // markers[0] = array of APP0_MARKER
|
|
+ markers[0] = arrayAdd(markers[0], data);
|
|
+ }
|
|
+
|
|
+ byte upper = (byte) (density >>> 8 & 0xFF); // unsigned shift to keep it
|
|
+ // positive
|
|
+ byte lower = (byte) (density & 0xFF);
|
|
+ data[10] = upper;
|
|
+ data[11] = lower;
|
|
+ }
|
|
+
|
|
+ public void setWidth(int width) {
|
|
+ this.width = width;
|
|
+ }
|
|
+
|
|
+ public void setHeight(int height) {
|
|
+ this.height = height;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * get the quality value.
|
|
+ *
|
|
+ * @return currently set quality value.
|
|
+ */
|
|
+ public float getQuality() {
|
|
+ return quality;
|
|
+ }
|
|
+
|
|
+ /**
|
|
+ * Appends new data to original array
|
|
+ *
|
|
+ * @param origArr
|
|
+ * @param newArr
|
|
+ * @return
|
|
+ */
|
|
+ private byte[][] arrayAdd(byte[][] origArr, byte[] newArr) {
|
|
+ byte[][] newData;
|
|
+ if (origArr != null) {
|
|
+ newData = Arrays.copyOf(origArr, origArr.length + 1);
|
|
+ newData[origArr.length] = Arrays.copyOf(newArr, newArr.length);
|
|
+ } else {
|
|
+ newData = new byte[1][];
|
|
+ newData[0] = Arrays.copyOf(newArr, newArr.length);
|
|
+ }
|
|
+
|
|
+ return newData;
|
|
+ }
|
|
+
|
|
+ private byte[] getValidAPP0Marker() {
|
|
+ byte[][] app0Markers = getMarkerData(APP0_MARKER);
|
|
+ for (int i = 0; i < app0Markers.length; i++) {
|
|
+ byte[] data = app0Markers[i];
|
|
+ if (data[0] == 'J' && data[1] == 'F' && data[2] == 'I'
|
|
+ && data[3] == 'F' && data[4] == 0x0) {
|
|
+ if (data[5] <= 1) { // version is 1 or below.
|
|
+ // We have a valid JFIF header.
|
|
+ return data;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return null;
|
|
+ }
|
|
+}
|