You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/10/25 21:01:49 UTC
svn commit: r1402274 [11/31] - in
/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext:
./ awt/ awt/color/ awt/font/ awt/g2d/ awt/geom/ awt/image/ awt/image/codec/
awt/image/codec/jpeg/ awt/image/codec/p...
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,137 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.codec.jpeg;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.flex.forks.batik.ext.awt.image.GraphicsUtil;
+import org.apache.flex.forks.batik.ext.awt.image.renderable.DeferRable;
+import org.apache.flex.forks.batik.ext.awt.image.renderable.Filter;
+import org.apache.flex.forks.batik.ext.awt.image.renderable.RedRable;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.Any2sRGBRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.FormatRed;
+import org.apache.flex.forks.batik.ext.awt.image.rendered.CachableRed;
+import org.apache.flex.forks.batik.ext.awt.image.spi.ImageTagRegistry;
+import org.apache.flex.forks.batik.ext.awt.image.spi.MagicNumberRegistryEntry;
+import org.apache.flex.forks.batik.util.ParsedURL;
+
+import com.sun.image.codec.jpeg.JPEGCodec;
+import com.sun.image.codec.jpeg.JPEGImageDecoder;
+import com.sun.image.codec.jpeg.TruncatedFileException;
+
+/**
+ *
+ * @version $Id: JPEGRegistryEntry.java 501094 2007-01-29 16:35:37Z deweese $
+ */
+public class JPEGRegistryEntry
+ extends MagicNumberRegistryEntry {
+
+ static final byte [] sigJPEG = {(byte)0xFF, (byte)0xd8,
+ (byte)0xFF};
+ static final String [] exts = {"jpeg", "jpg" };
+ static final String [] mimeTypes = {"image/jpeg", "image/jpg" };
+ static final MagicNumber [] magicNumbers = {
+ new MagicNumber(0, sigJPEG)
+ };
+
+ public JPEGRegistryEntry() {
+ super("JPEG", exts, mimeTypes, magicNumbers);
+ }
+
+ /**
+ * Decode the Stream into a RenderableImage
+ *
+ * @param inIS The input stream that contains the image.
+ * @param origURL The original URL, if any, for documentation
+ * purposes only. This may be null.
+ * @param needRawData If true the image returned should not have
+ * any default color correction the file may
+ * specify applied.
+ */
+ public Filter handleStream(InputStream inIS,
+ ParsedURL origURL,
+ boolean needRawData) {
+ final DeferRable dr = new DeferRable();
+ final InputStream is = inIS;
+ final String errCode;
+ final Object [] errParam;
+ if (origURL != null) {
+ errCode = ERR_URL_FORMAT_UNREADABLE;
+ errParam = new Object[] {"JPEG", origURL};
+ } else {
+ errCode = ERR_STREAM_FORMAT_UNREADABLE;
+ errParam = new Object[] {"JPEG"};
+ }
+
+ Thread t = new Thread() {
+ public void run() {
+ Filter filt;
+ try{
+ JPEGImageDecoder decoder;
+ decoder = JPEGCodec.createJPEGDecoder(is);
+ BufferedImage image;
+ try {
+ image = decoder.decodeAsBufferedImage();
+ } catch (TruncatedFileException tfe) {
+ image = tfe.getBufferedImage();
+ // Should probably draw some indication
+ // that this is a partial image....
+ if (image == null)
+ throw new IOException
+ ("JPEG File was truncated");
+ }
+ dr.setBounds(new Rectangle2D.Double
+ (0, 0, image.getWidth(),
+ image.getHeight()));
+ CachableRed cr;
+ cr = GraphicsUtil.wrap(image);
+ cr = new Any2sRGBRed(cr);
+ cr = new FormatRed(cr, GraphicsUtil.sRGB_Unpre);
+ WritableRaster wr = (WritableRaster)cr.getData();
+ ColorModel cm = cr.getColorModel();
+ image = new BufferedImage
+ (cm, wr, cm.isAlphaPremultiplied(), null);
+ cr = GraphicsUtil.wrap(image);
+ filt = new RedRable(cr);
+ } catch (IOException ioe) {
+ // Something bad happened here...
+ filt = ImageTagRegistry.getBrokenLinkImage
+ (JPEGRegistryEntry.this, errCode, errParam);
+ } catch (ThreadDeath td) {
+ filt = ImageTagRegistry.getBrokenLinkImage
+ (JPEGRegistryEntry.this, errCode, errParam);
+ dr.setSource(filt);
+ throw td;
+ } catch (Throwable t) {
+ filt = ImageTagRegistry.getBrokenLinkImage
+ (JPEGRegistryEntry.this, errCode, errParam);
+ }
+
+ dr.setSource(filt);
+ }
+ };
+ t.start();
+ return dr;
+ }
+}
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/jpeg/JPEGRegistryEntry.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/package.html
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/package.html?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/package.html (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/package.html Thu Oct 25 19:01:43 2012
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+ <head>
+ <title>org.apache.batik.ext.awt.image.codec</title>
+ </head>
+
+ <body>
+Provides a set of classes to encode/decode images in various raster
+image file formats.
+ </body>
+</html>
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGDecodeParam.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGDecodeParam.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGDecodeParam.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGDecodeParam.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,354 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.codec.png;
+
+import org.apache.flex.forks.batik.ext.awt.image.codec.util.ImageDecodeParam;
+import org.apache.flex.forks.batik.ext.awt.image.codec.util.PropertyUtil;
+
+/**
+ * An instance of <code>ImageDecodeParam</code> for decoding images in
+ * the PNG format.
+ *
+ * <code>PNGDecodeParam</code> allows several aspects of the decoding
+ * process for PNG images to be controlled. By default, decoding produces
+ * output images with the following properties:
+ *
+ * <p> Images with a bit depth of 8 or less use a
+ * <code>DataBufferByte</code> to hold the pixel data. 16-bit images
+ * use a <code>DataBufferUShort</code>.
+ *
+ * <p> Palette color images and non-transparent grayscale images with
+ * bit depths of 1, 2, or 4 will have a
+ * <code>MultiPixelPackedSampleModel</code> and an
+ * <code>IndexColorModel</code>. For palette color images, the
+ * <code>ColorModel</code> palette contains the red, green, blue, and
+ * optionally alpha palette information. For grayscale images, the
+ * palette is used to expand the pixel data to cover the range 0-255.
+ * The pixels are stored packed 8, 4, or 2 to the byte.
+ *
+ * <p> All other images are stored using a
+ * <code>PixelInterleavedSampleModel</code> with each sample of a pixel
+ * occupying its own <code>byte</code> or <code>short</code> within
+ * the <code>DataBuffer</code>. A <code>ComponentColorModel</code> is
+ * used which simply extracts the red, green, blue, gray, and/or alpha
+ * information from separate <code>DataBuffer</code> entries.
+ *
+ * <p> Five aspects of this process may be altered by means of methods
+ * in this class.
+ *
+ * <p> <code>setSuppressAlpha()</code> prevents an alpha channel
+ * from appearing in the output.
+ *
+ * <p> <code>setExpandPalette()</code> turns palette-color images into
+ * 3-or 4-channel full-color images.
+ *
+ * <p> <code>setOutput8BitGray()</code> causes 1, 2, or 4 bit
+ * grayscale images to be output in 8-bit form, using a
+ * <code>ComponentSampleModel</code> and
+ * <code>ComponentColorModel</code>.
+ *
+ * <p> <code>setDecodingExponent()</code> causes the output image to be
+ * gamma-corrected using a supplied output gamma value.
+ *
+ * <p> <code>setExpandGrayAlpha()</code> causes 2-channel gray/alpha
+ * (GA) images to be output as full-color (GGGA) images, which may
+ * simplify further processing and display.
+ *
+ * <p><b> This class is not a committed part of the JAI API. It may
+ * be removed or changed in future releases of JAI.</b>
+ *
+ * @version $Id: PNGDecodeParam.java 498740 2007-01-22 18:35:57Z dvholten $
+ */
+public class PNGDecodeParam implements ImageDecodeParam {
+
+ /**
+ * Constructs a default instance of <code>PNGDecodeParam</code>.
+ */
+ public PNGDecodeParam() {}
+
+ private boolean suppressAlpha = false;
+
+ /**
+ * Returns <code>true</code> if alpha (transparency) will
+ * be prevented from appearing in the output.
+ */
+ public boolean getSuppressAlpha() {
+ return suppressAlpha;
+ }
+
+ /**
+ * If set, no alpha (transparency) channel will appear in the
+ * output image.
+ *
+ * <p> The default is to allow transparency to appear in the
+ * output image.
+ */
+ public void setSuppressAlpha(boolean suppressAlpha) {
+ this.suppressAlpha = suppressAlpha;
+ }
+
+ private boolean expandPalette = false;
+
+ /**
+ * Returns true if palette-color images will be expanded to
+ * produce full-color output.
+ */
+ public boolean getExpandPalette() {
+ return expandPalette;
+ }
+
+ /**
+ * If set, palette color images (PNG color type 3) will
+ * be decoded into full-color (RGB) output images. The output
+ * image may have 3 or 4 channels, depending on the presence of
+ * transparency information.
+ *
+ * <p> The default is to output palette images using a single
+ * channel. The palette information is used to construct the
+ * output image's <code>ColorModel</code>.
+ */
+ public void setExpandPalette(boolean expandPalette) {
+ this.expandPalette = expandPalette;
+ }
+
+ private boolean output8BitGray = false;
+
+ /**
+ * Returns the current value of the 8-bit gray output parameter.
+ */
+ public boolean getOutput8BitGray() {
+ return output8BitGray;
+ }
+
+ /**
+ * If set, grayscale images with a bit depth less than 8
+ * (1, 2, or 4) will be output in 8 bit form. The output values
+ * will occupy the full 8-bit range. For example, gray values
+ * 0, 1, 2, and 3 of a 2-bit image will be output as
+ * 0, 85, 170, and 255.
+ *
+ * <p> The decoding of non-grayscale images and grayscale images
+ * with a bit depth of 8 or 16 are unaffected by this setting.
+ *
+ * <p> The default is not to perform expansion. Grayscale images
+ * with a depth of 1, 2, or 4 bits will be represented using
+ * a <code>MultiPixelPackedSampleModel</code> and an
+ * <code>IndexColorModel</code>.
+ */
+ public void setOutput8BitGray(boolean output8BitGray) {
+ this.output8BitGray = output8BitGray;
+ }
+
+ private boolean performGammaCorrection = true;
+
+ /**
+ * Returns <code>true</code> if gamma correction is to be performed
+ * on the image data. The default is <code>true</code>.
+ *
+ * <p> If gamma correction is to be performed, the
+ * <code>getUserExponent()</code> and
+ * <code>getDisplayExponent()</code> methods are used in addition to
+ * the gamma value stored within the file (or the default value of
+ * 1/2.2 used if no value is found) to produce a single exponent
+ * using the formula:
+ * <pre>
+ * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
+ * </pre>
+ */
+ public boolean getPerformGammaCorrection() {
+ return performGammaCorrection;
+ }
+
+ /**
+ * Turns gamma corection of the image data on or off.
+ */
+ public void setPerformGammaCorrection(boolean performGammaCorrection) {
+ this.performGammaCorrection = performGammaCorrection;
+ }
+
+ private float userExponent = 1.0F;
+
+ /**
+ * Returns the current value of the user exponent parameter.
+ * By default, the user exponent is equal to 1.0F.
+ */
+ public float getUserExponent() {
+ return userExponent;
+ }
+
+ /**
+ * Sets the user exponent to a given value. The exponent
+ * must be positive. If not, an
+ * <code>IllegalArgumentException</code> will be thrown.
+ *
+ * <p> The output image pixels will be placed through a transformation
+ * of the form:
+ *
+ * <pre>
+ * sample = integer_sample / (2^bitdepth - 1.0)
+ * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
+ * output = sample ^ decoding_exponent
+ * </pre>
+ *
+ * where <code>gamma_from_file</code> is the gamma of the file
+ * data, as determined by the <code>gAMA</code>, </code>sRGB</code>,
+ * and/or <code>iCCP</code> chunks, and <code>display_exponent</code>
+ * is the exponent of the intrinsic transfer curve of the display,
+ * generally 2.2.
+ *
+ * <p> Input files which do not specify any gamma are assumed to
+ * have a gamma of <code>1/2.2</code>; such images may be displayed
+ * on a CRT with an exponent of 2.2 using the default user
+ * exponent of 1.0.
+ *
+ * <p> The user exponent may be used in order to change the
+ * effective gamma of a file. If a file has a stored gamma of
+ * X, but the decoder believes that the true file gamma is Y,
+ * setting a user exponent of Y/X will produce the same result
+ * as changing the file gamma.
+ *
+ * <p> This parameter affects the decoding of all image types.
+ *
+ * @throws IllegalArgumentException if <code>userExponent</code> is
+ * negative.
+ */
+ public void setUserExponent(float userExponent) {
+ if (userExponent <= 0.0F) {
+ throw new IllegalArgumentException(PropertyUtil.getString("PNGDecodeParam0"));
+ }
+ this.userExponent = userExponent;
+ }
+
+ private float displayExponent = 2.2F;
+
+ /**
+ * Returns the current value of the display exponent parameter.
+ * By default, the display exponent is equal to 2.2F.
+ */
+ public float getDisplayExponent() {
+ return displayExponent;
+ }
+
+ /**
+ * Sets the display exponent to a given value. The exponent
+ * must be positive. If not, an
+ * <code>IllegalArgumentException</code> will be thrown.
+ *
+ * <p> The output image pixels will be placed through a transformation
+ * of the form:
+ *
+ * <pre>
+ * sample = integer_sample / (2^bitdepth - 1.0)
+ * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
+ * output = sample ^ decoding_exponent
+ * </pre>
+ *
+ * where <code>gamma_from_file</code> is the gamma of the file
+ * data, as determined by the <code>gAMA</code>, </code>sRGB</code>,
+ * and/or <code>iCCP</code> chunks, and <code>user_exponent</code>
+ * is an additional user-supplied parameter.
+ *
+ * <p> Input files which do not specify any gamma are assumed to
+ * have a gamma of <code>1/2.2</code>; such images should be
+ * decoding using the default display exponent of 2.2.
+ *
+ * <p> If an image is to be processed further before being displayed,
+ * it may be preferable to set the display exponent to 1.0 in order
+ * to produce a linear output image.
+ *
+ * <p> This parameter affects the decoding of all image types.
+ *
+ * @throws IllegalArgumentException if <code>userExponent</code> is
+ * negative.
+ */
+ public void setDisplayExponent(float displayExponent) {
+ if (displayExponent <= 0.0F) {
+ throw new IllegalArgumentException(PropertyUtil.getString("PNGDecodeParam1"));
+ }
+ this.displayExponent = displayExponent;
+ }
+
+ private boolean expandGrayAlpha = false;
+
+ /**
+ * Returns the current setting of the gray/alpha expansion.
+ */
+ public boolean getExpandGrayAlpha() {
+ return expandGrayAlpha;
+ }
+
+ /**
+ * If set, images containing one channel of gray and one channel of
+ * alpha (GA) will be output in a 4-channel format (GGGA). This
+ * produces output that may be simpler to process and display.
+ *
+ * <p> This setting affects both images of color type 4 (explicit
+ * alpha) and images of color type 0 (grayscale) that contain
+ * transparency information.
+ *
+ * <p> By default, no expansion is performed.
+ */
+ public void setExpandGrayAlpha(boolean expandGrayAlpha) {
+ this.expandGrayAlpha = expandGrayAlpha;
+ }
+
+ private boolean generateEncodeParam = false;
+
+ private PNGEncodeParam encodeParam = null;
+
+ /**
+ * Returns <code>true</code> if an instance of
+ * <code>PNGEncodeParam</code> will be available after an image
+ * has been decoded via the <code>getEncodeParam</code> method.
+ */
+ public boolean getGenerateEncodeParam() {
+ return generateEncodeParam;
+ }
+
+ /**
+ * If set, an instance of <code>PNGEncodeParam</code> will be
+ * available after an image has been decoded via the
+ * <code>getEncodeParam</code> method that encapsulates information
+ * about the contents of the PNG file. If not set, this information
+ * will not be recorded and <code>getEncodeParam()</code> will
+ * return <code>null</code>.
+ */
+ public void setGenerateEncodeParam(boolean generateEncodeParam) {
+ this.generateEncodeParam = generateEncodeParam;
+ }
+
+ /**
+ * If <code>getGenerateEncodeParam()</code> is <code>true</code>,
+ * this method may be called after decoding has completed, and
+ * will return an instance of <code>PNGEncodeParam</code> containing
+ * information about the contents of the PNG file just decoded.
+ */
+ public PNGEncodeParam getEncodeParam() {
+ return encodeParam;
+ }
+
+ /**
+ * Sets the current encoder param instance. This method is
+ * intended to be called by the PNG decoder and will overwrite the
+ * current instance returned by <code>getEncodeParam</code>.
+ */
+ public void setEncodeParam(PNGEncodeParam encodeParam) {
+ this.encodeParam = encodeParam;
+ }
+}
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGDecodeParam.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGEncodeParam.java
URL: http://svn.apache.org/viewvc/incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGEncodeParam.java?rev=1402274&view=auto
==============================================================================
--- incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGEncodeParam.java (added)
+++ incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGEncodeParam.java Thu Oct 25 19:01:43 2012
@@ -0,0 +1,1505 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.flex.forks.batik.ext.awt.image.codec.png;
+
+import org.apache.flex.forks.batik.ext.awt.image.codec.util.ImageEncodeParam;
+import org.apache.flex.forks.batik.ext.awt.image.codec.util.PropertyUtil;
+
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.util.Date;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * An instance of <code>ImageEncodeParam</code> for encoding images in
+ * the PNG format.
+ *
+ * <p><b> This class is not a committed part of the JAI API. It may
+ * be removed or changed in future releases of JAI.</b>
+ *
+ * @version $Id: PNGEncodeParam.java 498740 2007-01-22 18:35:57Z dvholten $
+ */
+public abstract class PNGEncodeParam implements ImageEncodeParam {
+
+ /** Constant for use with the sRGB chunk. */
+ public static final int INTENT_PERCEPTUAL = 0;
+
+ /** Constant for use with the sRGB chunk. */
+ public static final int INTENT_RELATIVE = 1;
+
+ /** Constant for use with the sRGB chunk. */
+ public static final int INTENT_SATURATION = 2;
+
+ /** Constant for use with the sRGB chunk. */
+ public static final int INTENT_ABSOLUTE = 3;
+
+ /** Constant for use in filtering. */
+ public static final int PNG_FILTER_NONE = 0;
+
+ /** Constant for use in filtering. */
+ public static final int PNG_FILTER_SUB = 1;
+
+ /** Constant for use in filtering. */
+ public static final int PNG_FILTER_UP = 2;
+
+ /** Constant for use in filtering. */
+ public static final int PNG_FILTER_AVERAGE = 3;
+
+ /** Constant for use in filtering. */
+ public static final int PNG_FILTER_PAETH = 4;
+
+
+ /**
+ * Returns an instance of <code>PNGEncodeParam.Palette</code>,
+ * <code>PNGEncodeParam.Gray</code>, or
+ * <code>PNGEncodeParam.RGB</code> appropriate for encoding
+ * the given image.
+ *
+ * <p> If the image has an <code>IndexColorModel</code>, an
+ * instance of <code>PNGEncodeParam.Palette</code> is returned.
+ * Otherwise, if the image has 1 or 2 bands an instance of
+ * <code>PNGEncodeParam.Gray</code> is returned. In all other
+ * cases an instance of <code>PNGEncodeParam.RGB</code> is
+ * returned.
+ *
+ * <p> Note that this method does not provide any guarantee that
+ * the given image will be successfully encoded by the PNG
+ * encoder, as it only performs a very superficial analysis of
+ * the image structure.
+ */
+ public static PNGEncodeParam getDefaultEncodeParam(RenderedImage im) {
+ ColorModel colorModel = im.getColorModel();
+ if (colorModel instanceof IndexColorModel) {
+ return new PNGEncodeParam.Palette();
+ }
+
+ SampleModel sampleModel = im.getSampleModel();
+ int numBands = sampleModel.getNumBands();
+
+ if (numBands == 1 || numBands == 2) {
+ return new PNGEncodeParam.Gray();
+ } else {
+ return new PNGEncodeParam.RGB();
+ }
+ }
+
+ public static class Palette extends PNGEncodeParam {
+
+ /** Constructs an instance of <code>PNGEncodeParam.Palette</code>. */
+ public Palette() {}
+
+ // bKGD chunk
+
+ private boolean backgroundSet = false;
+
+ /**
+ * Suppresses the 'bKGD' chunk from being output.
+ */
+ public void unsetBackground() {
+ backgroundSet = false;
+ }
+
+ /**
+ * Returns true if a 'bKGD' chunk will be output.
+ */
+ public boolean isBackgroundSet() {
+ return backgroundSet;
+ }
+
+ /**
+ * Sets the desired bit depth for a palette image. The bit
+ * depth must be one of 1, 2, 4, or 8, or else an
+ * <code>IllegalArgumentException</code> will be thrown.
+ */
+ public void setBitDepth(int bitDepth) {
+ if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 &&
+ bitDepth != 8) {
+ throw new IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam2"));
+ }
+ this.bitDepth = bitDepth;
+ bitDepthSet = true;
+ }
+
+ // PLTE chunk
+
+ private int[] palette = null;
+ private boolean paletteSet = false;
+
+ /**
+ * Sets the RGB palette of the image to be encoded.
+ * The <code>rgb</code> parameter contains alternating
+ * R, G, B values for each color index used in the image.
+ * The number of elements must be a multiple of 3 between
+ * 3 and 3*256.
+ *
+ * <p> The 'PLTE' chunk will encode this information.
+ *
+ * @param rgb An array of <code>int</code>s.
+ */
+ public void setPalette(int[] rgb) {
+ if (rgb.length < 1*3 || rgb.length > 256*3) {
+ throw new
+ IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam0"));
+ }
+ if ((rgb.length % 3) != 0) {
+ throw new
+ IllegalArgumentException(PropertyUtil.getString("PNGEncodeParam1"));
+ }
+
+ palette = (int[])(rgb.clone());
+ paletteSet = true;
+ }
+
+ /**
+ * Returns the current RGB palette.
+ *
+ * <p> If the palette has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the palette is not set.
+ *
+ * @return An array of <code>int</code>s.
+ */
+ public int[] getPalette() {
+ if (!paletteSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam3"));
+ }
+ return (int[])(palette.clone());
+ }
+
+ /**
+ * Suppresses the 'PLTE' chunk from being output.
+ */
+ public void unsetPalette() {
+ palette = null;
+ paletteSet = false;
+ }
+
+ /**
+ * Returns true if a 'PLTE' chunk will be output.
+ */
+ public boolean isPaletteSet() {
+ return paletteSet;
+ }
+
+ // bKGD chunk
+
+ private int backgroundPaletteIndex;
+
+ /**
+ * Sets the palette index of the suggested background color.
+ *
+ * <p> The 'bKGD' chunk will encode this information.
+ */
+ public void setBackgroundPaletteIndex(int index) {
+ backgroundPaletteIndex = index;
+ backgroundSet = true;
+ }
+
+ /**
+ * Returns the palette index of the suggested background color.
+ *
+ * <p> If the background palette index has not previously been
+ * set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the palette index is not set.
+ */
+ public int getBackgroundPaletteIndex() {
+ if (!backgroundSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam4"));
+ }
+ return backgroundPaletteIndex;
+ }
+
+ // tRNS chunk
+
+ private int[] transparency;
+
+ /**
+ * Sets the alpha values associated with each palette entry.
+ * The <code>alpha</code> parameter should have as many entries
+ * as there are RGB triples in the palette.
+ *
+ * <p> The 'tRNS' chunk will encode this information.
+ */
+ public void setPaletteTransparency(byte[] alpha) {
+ transparency = new int[alpha.length];
+ for (int i = 0; i < alpha.length; i++) {
+ transparency[i] = alpha[i] & 0xff;
+ }
+ transparencySet = true;
+ }
+
+ /**
+ * Returns the alpha values associated with each palette entry.
+ *
+ * <p> If the palette transparency has not previously been
+ * set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the palette transparency is
+ * not set.
+ */
+ public byte[] getPaletteTransparency() {
+ if (!transparencySet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam5"));
+ }
+ byte[] alpha = new byte[transparency.length];
+ for (int i = 0; i < alpha.length; i++) {
+ alpha[i] = (byte)transparency[i];
+ }
+ return alpha;
+ }
+ }
+
+ public static class Gray extends PNGEncodeParam {
+
+ /** Constructs an instance of <code>PNGEncodeParam.Gray</code>. */
+ public Gray() {}
+
+ // bKGD chunk
+
+ private boolean backgroundSet = false;
+
+ /**
+ * Suppresses the 'bKGD' chunk from being output.
+ */
+ public void unsetBackground() {
+ backgroundSet = false;
+ }
+
+ /**
+ * Returns true if a 'bKGD' chunk will be output.
+ */
+ public boolean isBackgroundSet() {
+ return backgroundSet;
+ }
+
+ /**
+ * Sets the desired bit depth for a grayscale image. The bit
+ * depth must be one of 1, 2, 4, 8, or 16.
+ *
+ * <p> When encoding a source image of a greater bit depth,
+ * pixel values will be clamped to the smaller range after
+ * shifting by the value given by <code>getBitShift()</code>.
+ * When encoding a source image of a smaller bit depth, pixel
+ * values will be shifted and left-filled with zeroes.
+ */
+ public void setBitDepth(int bitDepth) {
+ if (bitDepth != 1 && bitDepth != 2 && bitDepth != 4 &&
+ bitDepth != 8 && bitDepth != 16) {
+ throw new IllegalArgumentException();
+ }
+ this.bitDepth = bitDepth;
+ bitDepthSet = true;
+ }
+
+ // bKGD chunk
+
+ private int backgroundPaletteGray;
+
+ /**
+ * Sets the suggested gray level of the background.
+ *
+ * <p> The 'bKGD' chunk will encode this information.
+ */
+ public void setBackgroundGray(int gray) {
+ backgroundPaletteGray = gray;
+ backgroundSet = true;
+ }
+
+ /**
+ * Returns the suggested gray level of the background.
+ *
+ * <p> If the background gray level has not previously been
+ * set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the background gray level
+ * is not set.
+ */
+ public int getBackgroundGray() {
+ if (!backgroundSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam6"));
+ }
+ return backgroundPaletteGray;
+ }
+
+ // tRNS chunk
+
+ private int[] transparency;
+
+ /**
+ * Sets the gray value to be used to denote transparency.
+ *
+ * <p> Setting this attribute will cause the alpha channel
+ * of the input image to be ignored.
+ *
+ * <p> The 'tRNS' chunk will encode this information.
+ */
+ public void setTransparentGray(int transparentGray) {
+ transparency = new int[1];
+ transparency[0] = transparentGray;
+ transparencySet = true;
+ }
+
+ /**
+ * Returns the gray value to be used to denote transparency.
+ *
+ * <p> If the transparent gray value has not previously been
+ * set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the transparent gray value
+ * is not set.
+ */
+ public int getTransparentGray() {
+ if (!transparencySet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam7"));
+ }
+ int gray = transparency[0];
+ return gray;
+ }
+
+ private int bitShift;
+ private boolean bitShiftSet = false;
+
+ /**
+ * Sets the desired bit shift for a grayscale image.
+ * Pixels in the source image will be shifted right by
+ * the given amount prior to being clamped to the maximum
+ * value given by the encoded image's bit depth.
+ */
+ public void setBitShift(int bitShift) {
+ if (bitShift < 0) {
+ throw new RuntimeException();
+ }
+ this.bitShift = bitShift;
+ bitShiftSet = true;
+ }
+
+ /**
+ * Returns the desired bit shift for a grayscale image.
+ *
+ * <p> If the bit shift has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the bit shift is not set.
+ */
+ public int getBitShift() {
+ if (!bitShiftSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam8"));
+ }
+ return bitShift;
+ }
+
+ /**
+ * Suppresses the setting of the bit shift of a grayscale image.
+ * Pixels in the source image will not be shifted prior to encoding.
+ */
+ public void unsetBitShift() {
+ bitShiftSet = false;
+ }
+
+ /**
+ * Returns true if the bit shift has been set.
+ */
+ public boolean isBitShiftSet() {
+ return bitShiftSet;
+ }
+
+ /**
+ * Returns true if the bit depth has been set.
+ */
+ public boolean isBitDepthSet() {
+ return bitDepthSet;
+ }
+ }
+
+ public static class RGB extends PNGEncodeParam {
+
+ /** Constructs an instance of <code>PNGEncodeParam.RGB</code>. */
+ public RGB() {}
+
+ // bKGD chunk
+
+ private boolean backgroundSet = false;
+
+ /**
+ * Suppresses the 'bKGD' chunk from being output.
+ */
+ public void unsetBackground() {
+ backgroundSet = false;
+ }
+
+ /**
+ * Returns true if a 'bKGD' chunk will be output.
+ */
+ public boolean isBackgroundSet() {
+ return backgroundSet;
+ }
+
+ /**
+ * Sets the desired bit depth for an RGB image. The bit
+ * depth must be 8 or 16.
+ */
+ public void setBitDepth(int bitDepth) {
+ if (bitDepth != 8 && bitDepth != 16) {
+ throw new RuntimeException();
+ }
+ this.bitDepth = bitDepth;
+ bitDepthSet = true;
+ }
+
+ // bKGD chunk
+
+ private int[] backgroundRGB;
+
+ /**
+ * Sets the RGB value of the suggested background color.
+ * The <code>rgb</code> parameter should have 3 entries.
+ *
+ * <p> The 'bKGD' chunk will encode this information.
+ */
+ public void setBackgroundRGB(int[] rgb) {
+ if (rgb.length != 3) {
+ throw new RuntimeException();
+ }
+ backgroundRGB = rgb;
+ backgroundSet = true;
+ }
+
+ /**
+ * Returns the RGB value of the suggested background color.
+ *
+ * <p> If the background color has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the background color is not set.
+ */
+ public int[] getBackgroundRGB() {
+ if (!backgroundSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam9"));
+ }
+ return backgroundRGB;
+ }
+
+ // tRNS chunk
+
+ private int[] transparency;
+
+ /**
+ * Sets the RGB value to be used to denote transparency.
+ *
+ * <p> Setting this attribute will cause the alpha channel
+ * of the input image to be ignored.
+ *
+ * <p> The 'tRNS' chunk will encode this information.
+ */
+ public void setTransparentRGB(int[] transparentRGB) {
+ transparency = (int[])(transparentRGB.clone());
+ transparencySet = true;
+ }
+
+ /**
+ * Returns the RGB value to be used to denote transparency.
+ *
+ * <p> If the transparent color has not previously been set,
+ * or has been unset, an <code>IllegalStateException</code>
+ * will be thrown.
+ *
+ * @throws IllegalStateException if the transparent color is not set.
+ */
+ public int[] getTransparentRGB() {
+ if (!transparencySet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam10"));
+ }
+ return (int[])(transparency.clone());
+ }
+ }
+
+ protected int bitDepth;
+ protected boolean bitDepthSet = false;
+
+ /**
+ * Sets the desired bit depth of an image.
+ */
+ public abstract void setBitDepth(int bitDepth);
+
+ /**
+ * Returns the desired bit depth for a grayscale image.
+ *
+ * <p> If the bit depth has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the bit depth is not set.
+ */
+ public int getBitDepth() {
+ if (!bitDepthSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam11"));
+ }
+ return bitDepth;
+ }
+
+ /**
+ * Suppresses the setting of the bit depth of a grayscale image.
+ * The depth of the encoded image will be inferred from the source
+ * image bit depth, rounded up to the next power of 2 between 1
+ * and 16.
+ */
+ public void unsetBitDepth() {
+ bitDepthSet = false;
+ }
+
+ private boolean useInterlacing = false;
+
+ /**
+ * Turns Adam7 interlacing on or off.
+ */
+ public void setInterlacing(boolean useInterlacing) {
+ this.useInterlacing = useInterlacing;
+ }
+
+ /**
+ * Returns <code>true</code> if Adam7 interlacing will be used.
+ */
+ public boolean getInterlacing() {
+ return useInterlacing;
+ }
+
+ // bKGD chunk - delegate to subclasses
+
+ // In JAI 1.0, 'backgroundSet' was private. The JDK 1.2 compiler
+ // was lenient and incorrectly allowed this variable to be
+ // accessed from the subclasses. The JDK 1.3 compiler correctly
+ // flags this as a use of a non-static variable in a static
+ // context. Changing 'backgroundSet' to protected would have
+ // solved the problem, but would have introduced a visible API
+ // change. Thus we are forced to adopt the solution of placing a
+ // separate private variable in each subclass and providing
+ // separate implementations of 'unsetBackground' and
+ // 'isBackgroundSet' in each concrete subclass.
+
+ /**
+ * Suppresses the 'bKGD' chunk from being output.
+ * For API compatibility with JAI 1.0, the superclass
+ * defines this method to throw a <code>RuntimeException</code>;
+ * accordingly, subclasses must provide their own implementations.
+ */
+ public void unsetBackground() {
+ throw new RuntimeException(PropertyUtil.getString("PNGEncodeParam23"));
+ }
+
+ /**
+ * Returns true if a 'bKGD' chunk will be output.
+ * For API compatibility with JAI 1.0, the superclass
+ * defines this method to throw a <code>RuntimeException</code>;
+ * accordingly, subclasses must provide their own implementations.
+ */
+ public boolean isBackgroundSet() {
+ throw new RuntimeException(PropertyUtil.getString("PNGEncodeParam24"));
+ }
+
+ // cHRM chunk
+
+ private float[] chromaticity = null;
+ private boolean chromaticitySet = false;
+
+ /**
+ * Sets the white point and primary chromaticities in CIE (x, y)
+ * space.
+ *
+ * <p> The <code>chromaticity</code> parameter should be a
+ * <code>float</code> array of length 8 containing the white point
+ * X and Y, red X and Y, green X and Y, and blue X and Y values in
+ * order.
+ *
+ * <p> The 'cHRM' chunk will encode this information.
+ */
+ public void setChromaticity(float[] chromaticity) {
+ if (chromaticity.length != 8) {
+ throw new IllegalArgumentException();
+ }
+ this.chromaticity = (float[])(chromaticity.clone());
+ chromaticitySet = true;
+ }
+
+ /**
+ * A convenience method that calls the array version.
+ */
+ public void setChromaticity(float whitePointX, float whitePointY,
+ float redX, float redY,
+ float greenX, float greenY,
+ float blueX, float blueY) {
+ float[] chroma = new float[8];
+ chroma[0] = whitePointX;
+ chroma[1] = whitePointY;
+ chroma[2] = redX;
+ chroma[3] = redY;
+ chroma[4] = greenX;
+ chroma[5] = greenY;
+ chroma[6] = blueX;
+ chroma[7] = blueY;
+ setChromaticity(chroma);
+ }
+
+ /**
+ * Returns the white point and primary chromaticities in
+ * CIE (x, y) space.
+ *
+ * <p> See the documentation for the <code>setChromaticity</code>
+ * method for the format of the returned data.
+ *
+ * <p> If the chromaticity has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the chromaticity is not set.
+ */
+ public float[] getChromaticity() {
+ if (!chromaticitySet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam12"));
+ }
+ return (float[])(chromaticity.clone());
+ }
+
+ /**
+ * Suppresses the 'cHRM' chunk from being output.
+ */
+ public void unsetChromaticity() {
+ chromaticity = null;
+ chromaticitySet = false;
+ }
+
+ /**
+ * Returns true if a 'cHRM' chunk will be output.
+ */
+ public boolean isChromaticitySet() {
+ return chromaticitySet;
+ }
+
+ // gAMA chunk
+
+ private float gamma;
+ private boolean gammaSet = false;
+
+ /**
+ * Sets the file gamma value for the image.
+ *
+ * <p> The 'gAMA' chunk will encode this information.
+ */
+ public void setGamma(float gamma) {
+ this.gamma = gamma;
+ gammaSet = true;
+ }
+
+ /**
+ * Returns the file gamma value for the image.
+ *
+ * <p> If the file gamma has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the gamma is not set.
+ */
+ public float getGamma() {
+ if (!gammaSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam13"));
+ }
+ return gamma;
+ }
+
+ /**
+ * Suppresses the 'gAMA' chunk from being output.
+ */
+ public void unsetGamma() {
+ gammaSet = false;
+ }
+
+ /**
+ * Returns true if a 'gAMA' chunk will be output.
+ */
+ public boolean isGammaSet() {
+ return gammaSet;
+ }
+
+ // hIST chunk
+
+ private int[] paletteHistogram = null;
+ private boolean paletteHistogramSet = false;
+
+ /**
+ * Sets the palette histogram to be stored with this image.
+ * The histogram consists of an array of integers, one per
+ * palette entry.
+ *
+ * <p> The 'hIST' chunk will encode this information.
+ */
+ public void setPaletteHistogram(int[] paletteHistogram) {
+ this.paletteHistogram = (int[])(paletteHistogram.clone());
+ paletteHistogramSet = true;
+ }
+
+ /**
+ * Returns the palette histogram to be stored with this image.
+ *
+ * <p> If the histogram has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the histogram is not set.
+ */
+ public int[] getPaletteHistogram() {
+ if (!paletteHistogramSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam14"));
+ }
+ return paletteHistogram;
+ }
+
+ /**
+ * Suppresses the 'hIST' chunk from being output.
+ */
+ public void unsetPaletteHistogram() {
+ paletteHistogram = null;
+ paletteHistogramSet = false;
+ }
+
+ /**
+ * Returns true if a 'hIST' chunk will be output.
+ */
+ public boolean isPaletteHistogramSet() {
+ return paletteHistogramSet;
+ }
+
+ // iCCP chunk
+
+ private byte[] ICCProfileData = null;
+ private boolean ICCProfileDataSet = false;
+
+ /**
+ * Sets the ICC profile data to be stored with this image.
+ * The profile is represented in raw binary form.
+ *
+ * <p> The 'iCCP' chunk will encode this information.
+ */
+ public void setICCProfileData(byte[] ICCProfileData) {
+ this.ICCProfileData = (byte[])(ICCProfileData.clone());
+ ICCProfileDataSet = true;
+ }
+
+ /**
+ * Returns the ICC profile data to be stored with this image.
+ *
+ * <p> If the ICC profile has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the ICC profile is not set.
+ */
+ public byte[] getICCProfileData() {
+ if (!ICCProfileDataSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam15"));
+ }
+ return (byte[])(ICCProfileData.clone());
+ }
+
+ /**
+ * Suppresses the 'iCCP' chunk from being output.
+ */
+ public void unsetICCProfileData() {
+ ICCProfileData = null;
+ ICCProfileDataSet = false;
+ }
+
+ /**
+ * Returns true if a 'iCCP' chunk will be output.
+ */
+ public boolean isICCProfileDataSet() {
+ return ICCProfileDataSet;
+ }
+
+ // pHYS chunk
+
+ private int[] physicalDimension = null;
+ private boolean physicalDimensionSet = false;
+
+ /**
+ * Sets the physical dimension information to be stored with this
+ * image. The physicalDimension parameter should be a 3-entry
+ * array containing the number of pixels per unit in the X
+ * direction, the number of pixels per unit in the Y direction,
+ * and the unit specifier (0 = unknown, 1 = meters).
+ *
+ * <p> The 'pHYS' chunk will encode this information.
+ */
+ public void setPhysicalDimension(int[] physicalDimension) {
+ this.physicalDimension = (int[])(physicalDimension.clone());
+ physicalDimensionSet = true;
+ }
+
+ /**
+ * A convenience method that calls the array version.
+ */
+ public void setPhysicalDimension(int xPixelsPerUnit,
+ int yPixelsPerUnit,
+ int unitSpecifier) {
+ int[] pd = new int[3];
+ pd[0] = xPixelsPerUnit;
+ pd[1] = yPixelsPerUnit;
+ pd[2] = unitSpecifier;
+
+ setPhysicalDimension(pd);
+ }
+
+ /**
+ * Returns the physical dimension information to be stored
+ * with this image.
+ *
+ * <p> If the physical dimension information has not previously
+ * been set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the physical dimension information
+ * is not set.
+ */
+ public int[] getPhysicalDimension() {
+ if (!physicalDimensionSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam16"));
+ }
+ return (int[])(physicalDimension.clone());
+ }
+
+ /**
+ * Suppresses the 'pHYS' chunk from being output.
+ */
+ public void unsetPhysicalDimension() {
+ physicalDimension = null;
+ physicalDimensionSet = false;
+ }
+
+ /**
+ * Returns true if a 'pHYS' chunk will be output.
+ */
+ public boolean isPhysicalDimensionSet() {
+ return physicalDimensionSet;
+ }
+
+ // sPLT chunk
+
+ private PNGSuggestedPaletteEntry[] suggestedPalette = null;
+ private boolean suggestedPaletteSet = false;
+
+ /**
+ * Sets the suggested palette information to be stored with this
+ * image. The information is passed to this method as an array of
+ * <code>PNGSuggestedPaletteEntry</code> objects.
+ *
+ * <p> The 'sPLT' chunk will encode this information.
+ */
+ public void setSuggestedPalette(PNGSuggestedPaletteEntry[] palette) {
+ suggestedPalette = (PNGSuggestedPaletteEntry[])(palette.clone());
+ suggestedPaletteSet = true;
+ }
+
+ /**
+ * Returns the suggested palette information to be stored with this
+ * image.
+ *
+ * <p> If the suggested palette information has not previously
+ * been set, or has been unset, an
+ * <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the suggested palette
+ * information is not set.
+ */
+ public PNGSuggestedPaletteEntry[] getSuggestedPalette() {
+ if (!suggestedPaletteSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam17"));
+ }
+ return (PNGSuggestedPaletteEntry[])(suggestedPalette.clone());
+ }
+
+ /**
+ * Suppresses the 'sPLT' chunk from being output.
+ */
+ public void unsetSuggestedPalette() {
+ suggestedPalette = null;
+ suggestedPaletteSet = false;
+ }
+
+ /**
+ * Returns true if a 'sPLT' chunk will be output.
+ */
+ public boolean isSuggestedPaletteSet() {
+ return suggestedPaletteSet;
+ }
+
+ // sBIT chunk
+
+ private int[] significantBits = null;
+ private boolean significantBitsSet = false;
+
+ /**
+ * Sets the number of significant bits for each band of the image.
+ *
+ * <p> The number of entries in the <code>significantBits</code>
+ * array must be equal to the number of output bands in the image:
+ * 1 for a gray image, 2 for gray+alpha, 3 for index or truecolor,
+ * and 4 for truecolor+alpha.
+ *
+ * <p> The 'sBIT' chunk will encode this information.
+ */
+ public void setSignificantBits(int[] significantBits) {
+ this.significantBits = (int[])(significantBits.clone());
+ significantBitsSet = true;
+ }
+
+ /**
+ * Returns the number of significant bits for each band of the image.
+ *
+ * <p> If the significant bits values have not previously been
+ * set, or have been unset, an <code>IllegalStateException</code>
+ * will be thrown.
+ *
+ * @throws IllegalStateException if the significant bits values are
+ * not set.
+ */
+ public int[] getSignificantBits() {
+ if (!significantBitsSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam18"));
+ }
+ return (int[])significantBits.clone();
+ }
+
+ /**
+ * Suppresses the 'sBIT' chunk from being output.
+ */
+ public void unsetSignificantBits() {
+ significantBits = null;
+ significantBitsSet = false;
+ }
+
+ /**
+ * Returns true if an 'sBIT' chunk will be output.
+ */
+ public boolean isSignificantBitsSet() {
+ return significantBitsSet;
+ }
+
+ // sRGB chunk
+
+ private int SRGBIntent;
+ private boolean SRGBIntentSet = false;
+
+ /**
+ * Sets the sRGB rendering intent to be stored with this image.
+ * The legal values are 0 = Perceptual, 1 = Relative Colorimetric,
+ * 2 = Saturation, and 3 = Absolute Colorimetric. Refer to the
+ * PNG specification for information on these values.
+ *
+ * <p> The 'sRGB' chunk will encode this information.
+ */
+ public void setSRGBIntent(int SRGBIntent) {
+ this.SRGBIntent = SRGBIntent;
+ SRGBIntentSet = true;
+ }
+
+ /**
+ * Returns the sRGB rendering intent to be stored with this image.
+ *
+ * <p> If the sRGB intent has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the sRGB intent is not set.
+ */
+ public int getSRGBIntent() {
+ if (!SRGBIntentSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam19"));
+ }
+ return SRGBIntent;
+ }
+
+ /**
+ * Suppresses the 'sRGB' chunk from being output.
+ */
+ public void unsetSRGBIntent() {
+ SRGBIntentSet = false;
+ }
+
+ /**
+ * Returns true if an 'sRGB' chunk will be output.
+ */
+ public boolean isSRGBIntentSet() {
+ return SRGBIntentSet;
+ }
+
+ // tEXt chunk
+
+ private String[] text = null;
+ private boolean textSet = false;
+
+ /**
+ * Sets the textual data to be stored in uncompressed form with this
+ * image. The data is passed to this method as an array of
+ * <code>String</code>s.
+ *
+ * <p> The 'tEXt' chunk will encode this information.
+ */
+ public void setText(String[] text) {
+ this.text = text;
+ textSet = true;
+ }
+
+ /**
+ * Returns the text strings to be stored in uncompressed form with this
+ * image as an array of <code>String</code>s.
+ *
+ * <p> If the text strings have not previously been set, or have been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the text strings are not set.
+ */
+ public String[] getText() {
+ if (!textSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam20"));
+ }
+ return text;
+ }
+
+ /**
+ * Suppresses the 'tEXt' chunk from being output.
+ */
+ public void unsetText() {
+ text = null;
+ textSet = false;
+ }
+
+ /**
+ * Returns true if a 'tEXt' chunk will be output.
+ */
+ public boolean isTextSet() {
+ return textSet;
+ }
+
+ // tIME chunk
+
+ private Date modificationTime;
+ private boolean modificationTimeSet = false;
+
+ /**
+ * Sets the modification time, as a <code>Date</code>, to be
+ * stored with this image. The internal storage format will use
+ * UTC regardless of how the <code>modificationTime</code>
+ * parameter was created.
+ *
+ * <p> The 'tIME' chunk will encode this information.
+ */
+ public void setModificationTime(Date modificationTime) {
+ this.modificationTime = modificationTime;
+ modificationTimeSet = true;
+ }
+
+ /**
+ * Returns the modification time to be stored with this image.
+ *
+ * <p> If the bit depth has not previously been set, or has been
+ * unset, an <code>IllegalStateException</code> will be thrown.
+ *
+ * @throws IllegalStateException if the bit depth is not set.
+ */
+ public Date getModificationTime() {
+ if (!modificationTimeSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam21"));
+ }
+ return modificationTime;
+ }
+
+ /**
+ * Suppresses the 'tIME' chunk from being output.
+ */
+ public void unsetModificationTime() {
+ modificationTime = null;
+ modificationTimeSet = false;
+ }
+
+ /**
+ * Returns true if a 'tIME' chunk will be output.
+ */
+ public boolean isModificationTimeSet() {
+ return modificationTimeSet;
+ }
+
+ // tRNS chunk
+
+ boolean transparencySet = false;
+
+ /**
+ * Suppresses the 'tRNS' chunk from being output.
+ */
+ public void unsetTransparency() {
+ transparencySet = false;
+ }
+
+ /**
+ * Returns true if a 'tRNS' chunk will be output.
+ */
+ public boolean isTransparencySet() {
+ return transparencySet;
+ }
+
+ // zTXT chunk
+
+ private String[] zText = null;
+ private boolean zTextSet = false;
+
+ /**
+ * Sets the text strings to be stored in compressed form with this
+ * image. The data is passed to this method as an array of
+ * <code>String</code>s.
+ *
+ * <p> The 'zTXt' chunk will encode this information.
+ */
+ public void setCompressedText(String[] text) {
+ this.zText = text;
+ zTextSet = true;
+ }
+
+ /**
+ * Returns the text strings to be stored in compressed form with
+ * this image as an array of <code>String</code>s.
+ *
+ * <p> If the compressed text strings have not previously been
+ * set, or have been unset, an <code>IllegalStateException</code>
+ * will be thrown.
+ *
+ * @throws IllegalStateException if the compressed text strings are
+ * not set.
+ */
+ public String[] getCompressedText() {
+ if (!zTextSet) {
+ throw new IllegalStateException(PropertyUtil.getString("PNGEncodeParam22"));
+ }
+ return zText;
+ }
+
+ /**
+ * Suppresses the 'zTXt' chunk from being output.
+ */
+ public void unsetCompressedText() {
+ zText = null;
+ zTextSet = false;
+ }
+
+ /**
+ * Returns true if a 'zTXT' chunk will be output.
+ */
+ public boolean isCompressedTextSet() {
+ return zTextSet;
+ }
+
+ // Other chunk types
+
+ List chunkType = new ArrayList();
+ List chunkData = new ArrayList();
+
+ /**
+ * Adds a private chunk, in binary form, to the list of chunks to
+ * be stored with this image.
+ *
+ * @param type a 4-character String giving the chunk type name.
+ * @param data an array of <code>byte</code>s containing the
+ * chunk data.
+ */
+ public synchronized void addPrivateChunk(String type, byte[] data) {
+ chunkType.add(type);
+ chunkData.add(data.clone());
+ }
+
+ /**
+ * Returns the number of private chunks to be written to the
+ * output file.
+ */
+ public synchronized int getNumPrivateChunks() {
+ return chunkType.size();
+ }
+
+ /**
+ * Returns the type of the private chunk at a given index, as a
+ * 4-character <code>String</code>. The index must be smaller
+ * than the return value of <code>getNumPrivateChunks</code>.
+ */
+ public synchronized String getPrivateChunkType(int index) {
+ return (String)chunkType.get(index);
+ }
+
+ /**
+ * Returns the data associated of the private chunk at a given
+ * index, as an array of <code>byte</code>s. The index must be
+ * smaller than the return value of
+ * <code>getNumPrivateChunks</code>.
+ */
+ public synchronized byte[] getPrivateChunkData(int index) {
+ return (byte[])chunkData.get(index);
+ }
+
+ /**
+ * Remove all private chunks associated with this parameter instance
+ * whose 'safe-to-copy' bit is not set. This may be advisable when
+ * transcoding PNG images.
+ */
+ public synchronized void removeUnsafeToCopyPrivateChunks() {
+ List newChunkType = new ArrayList();
+ List newChunkData = new ArrayList();
+
+ int len = getNumPrivateChunks();
+ for (int i = 0; i < len; i++) {
+ String type = getPrivateChunkType(i);
+ char lastChar = type.charAt(3);
+ if (lastChar >= 'a' && lastChar <= 'z') {
+ newChunkType.add(type);
+ newChunkData.add(getPrivateChunkData(i));
+ }
+ }
+
+ chunkType = newChunkType;
+ chunkData = newChunkData;
+ }
+
+ /**
+ * Remove all private chunks associated with this parameter instance.
+ */
+ public synchronized void removeAllPrivateChunks() {
+ chunkType = new ArrayList();
+ chunkData = new ArrayList();
+ }
+
+ /**
+ * An abs() function for use by the Paeth predictor.
+ */
+ private static final int abs(int x) {
+ return (x < 0) ? -x : x;
+ }
+
+ /**
+ * The Paeth predictor routine used in PNG encoding. This routine
+ * is included as a convenience to subclasses that override the
+ * <code>filterRow</code> method.
+ */
+ public static final int paethPredictor(int a, int b, int c) {
+ int p = a + b - c;
+ int pa = abs(p - a);
+ int pb = abs(p - b);
+ int pc = abs(p - c);
+
+ if ((pa <= pb) && (pa <= pc)) {
+ return a;
+ } else if (pb <= pc) {
+ return b;
+ } else {
+ return c;
+ }
+ }
+
+ /**
+ * Performs filtering on a row of an image. This method may be
+ * overridden in order to provide a custom algorithm for choosing
+ * the filter type for a given row.
+ *
+ * <p> The method is supplied with the current and previous rows
+ * of the image. For the first row of the image, or of an
+ * interlacing pass, the previous row array will be filled with
+ * zeros as required by the PNG specification.
+ *
+ * <p> The method is also supplied with five scratch arrays.
+ * These arrays may be used within the method for any purpose.
+ * At method exit, the array at the index given by the return
+ * value of the method should contain the filtered data. The
+ * return value will also be used as the filter type.
+ *
+ * <p> The default implementation of the method performs a trial
+ * encoding with each of the filter types, and computes the sum of
+ * absolute values of the differences between the raw bytes of the
+ * current row and the predicted values. The index of the filter
+ * producing the smallest result is returned.
+ *
+ * <p> As an example, to perform only 'sub' filtering, this method
+ * could be implemented (non-optimally) as follows:
+ *
+ * <pre>
+ * for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
+ * int curr = currRow[i] & 0xff;
+ * int left = currRow[i - bytesPerPixel] & 0xff;
+ * scratchRow[PNG_FILTER_SUB][i] = (byte)(curr - left);
+ * }
+ * return PNG_FILTER_SUB;
+ * </pre>
+ *
+ * @param currRow The current row as an array of <code>byte</code>s
+ * of length at least <code>bytesPerRow + bytesPerPixel</code>.
+ * The pixel data starts at index <code>bytesPerPixel</code>;
+ * the initial <code>bytesPerPixel</code> bytes are zero.
+ * @param prevRow The current row as an array of <code>byte</code>s
+ * The pixel data starts at index <code>bytesPerPixel</code>;
+ * the initial <code>bytesPerPixel</code> bytes are zero.
+ * @param scratchRows An array of 5 <code>byte</code> arrays of
+ * length at least <code>bytesPerRow +
+ * bytesPerPixel</code>, useable to hold temporary results.
+ * The filtered row will be returned as one of the entries
+ * of this array. The returned filtered data should start
+ * at index <code>bytesPerPixel</code>; The initial
+ * <code>bytesPerPixel</code> bytes are not used.
+ * @param bytesPerRow The number of bytes in the image row.
+ * This value will always be greater than 0.
+ * @param bytesPerPixel The number of bytes representing a single
+ * pixel, rounded up to an integer. This is the 'bpp' parameter
+ * described in the PNG specification.
+ *
+ * @return The filter type to be used. The entry of
+ * <code>scratchRows[]</code> at this index holds the
+ * filtered data. */
+ public int filterRow(byte[] currRow,
+ byte[] prevRow,
+ byte[][] scratchRows,
+ int bytesPerRow,
+ int bytesPerPixel) {
+
+ int [] badness = {0, 0, 0, 0, 0};
+ int curr, left, up, upleft, diff;
+ int pa, pb, pc;
+ for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
+ curr = currRow[i] & 0xff;
+ left = currRow[i - bytesPerPixel] & 0xff;
+ up = prevRow[i] & 0xff;
+ upleft = prevRow[i - bytesPerPixel] & 0xff;
+
+ // no filter
+ badness[0] += curr;
+
+ // sub filter
+ diff = curr - left;
+ scratchRows[1][i] = (byte)diff;
+ badness [1] += (diff>0)?diff:-diff;
+
+ // up filter
+ diff = curr - up;
+ scratchRows[2][i] = (byte)diff;
+ badness [2] += (diff>=0)?diff:-diff;
+
+ // average filter
+ diff = curr - ((left+up)>>1);
+ scratchRows[3][i] = (byte)diff;
+ badness [3] += (diff>=0)?diff:-diff;
+
+ // paeth filter
+
+ // Original code much simplier but doesn't take full
+ // advantage of relationship between pa/b/c and
+ // information gleaned in abs operations.
+ /// pa = up -upleft;
+ /// pb = left-upleft;
+ /// pc = pa+pb;
+ /// pa = abs(pa);
+ /// pb = abs(pb);
+ /// pc = abs(pc);
+ /// if ((pa <= pb) && (pa <= pc))
+ /// diff = curr-left;
+ /// else if (pb <= pc)
+ /// diff = curr-up;
+ /// else
+ /// diff = curr-upleft;
+
+ pa = up -upleft;
+ pb = left-upleft;
+ if (pa<0) {
+ if (pb<0) {
+ // both pa & pb neg so pc is always greater than or
+ // equal to pa or pb;
+ if (pa >= pb) // since pa & pb neg check sense is reversed.
+ diff = curr-left;
+ else
+ diff = curr-up;
+ } else {
+ // pa neg pb pos so we must compute pc...
+ pc = pa+pb;
+ pa=-pa;
+ if (pa <= pb) // pc is positive and less than pb
+ if (pa <= pc)
+ diff = curr-left;
+ else
+ diff = curr-upleft;
+ else
+ // pc is negative and less than or equal to pa,
+ // but since pa is greater than pb this isn't an issue...
+ if (pb <= -pc)
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ }
+ } else {
+ if (pb<0) {
+ pb =-pb; // make it positive...
+ if (pa <= pb) {
+ // pc would be negative and less than or equal to pb
+ pc = pb-pa;
+ if (pa <= pc)
+ diff = curr-left;
+ else if (pb == pc)
+ // if pa is zero then pc==pb otherwise
+ // pc must be less than pb.
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ } else {
+ // pc would be positive and less than pa.
+ pc = pa-pb;
+ if (pb <= pc)
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ }
+ } else {
+ // both pos so pa+pb is always greater than pa/pb
+ if (pa <= pb)
+ diff = curr-left;
+ else
+ diff = curr-up;
+ }
+ }
+ scratchRows[4][i] = (byte)diff;
+ badness [4] += (diff>=0)?diff:-diff;
+ }
+ int filterType = 0;
+ int minBadness = badness[0];
+
+ for (int i = 1; i < 5; i++) {
+ if (badness[i] < minBadness) {
+ minBadness = badness[i];
+ filterType = i;
+ }
+ }
+
+ if (filterType == 0) {
+ System.arraycopy(currRow, bytesPerPixel,
+ scratchRows[0], bytesPerPixel,
+ bytesPerRow);
+ }
+
+ return filterType;
+ }
+}
Propchange: incubator/flex/sdk/branches/develop/modules/thirdparty/batik/sources/org/apache/flex/forks/batik/ext/awt/image/codec/png/PNGEncodeParam.java
------------------------------------------------------------------------------
svn:eol-style = native