001: /*
002: * $RCSfile: PNGDecodeParam.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:55:31 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.codec;
013:
014: /**
015: * An instance of <code>ImageDecodeParam</code> for decoding images in
016: * the PNG format.
017: *
018: * <code>PNGDecodeParam</code> allows several aspects of the decoding
019: * process for PNG images to be controlled. By default, decoding produces
020: * output images with the following properties:
021: *
022: * <p> Images with a bit depth of 8 or less use a
023: * <code>DataBufferByte</code> to hold the pixel data. 16-bit images
024: * use a <code>DataBufferUShort</code>.
025: *
026: * <p> Palette color images and non-transparent grayscale images with
027: * bit depths of 1, 2, or 4 will have a
028: * <code>MultiPixelPackedSampleModel</code> and an
029: * <code>IndexColorModel</code>. For palette color images, the
030: * <code>ColorModel</code> palette contains the red, green, blue, and
031: * optionally alpha palette information. For grayscale images, the
032: * palette is used to expand the pixel data to cover the range 0-255.
033: * The pixels are stored packed 8, 4, or 2 to the byte.
034: *
035: * <p> All other images are stored using a
036: * <code>PixelInterleavedSampleModel</code> with each sample of a pixel
037: * occupying its own <code>byte</code> or <code>short</code> within
038: * the <code>DataBuffer</code>. A <code>ComponentColorModel</code> is
039: * used which simply extracts the red, green, blue, gray, and/or alpha
040: * information from separate <code>DataBuffer</code> entries.
041: *
042: * <p> Five aspects of this process may be altered by means of methods
043: * in this class.
044: *
045: * <p> <code>setSuppressAlpha()</code> prevents an alpha channel
046: * from appearing in the output.
047: *
048: * <p> <code>setExpandPalette()</code> turns palette-color images into
049: * 3-or 4-channel full-color images.
050: *
051: * <p> <code>setOutput8BitGray()</code> causes 1, 2, or 4 bit
052: * grayscale images to be output in 8-bit form, using a
053: * <code>ComponentSampleModel</code> and
054: * <code>ComponentColorModel</code>.
055: *
056: * <p> <code>setDecodingExponent()</code> causes the output image to be
057: * gamma-corrected using a supplied output gamma value.
058: *
059: * <p> <code>setExpandGrayAlpha()</code> causes 2-channel gray/alpha
060: * (GA) images to be output as full-color (GGGA) images, which may
061: * simplify further processing and display.
062: *
063: * <p><b> This class is not a committed part of the JAI API. It may
064: * be removed or changed in future releases of JAI.</b>
065: */
066: public class PNGDecodeParam implements ImageDecodeParam {
067:
068: /**
069: * Constructs a default instance of <code>PNGDecodeParam</code>.
070: */
071: public PNGDecodeParam() {
072: }
073:
074: private boolean suppressAlpha = false;
075:
076: /**
077: * Returns <code>true</code> if alpha (transparency) will
078: * be prevented from appearing in the output.
079: */
080: public boolean getSuppressAlpha() {
081: return suppressAlpha;
082: }
083:
084: /**
085: * If set, no alpha (transparency) channel will appear in the
086: * output image.
087: *
088: * <p> The default is to allow transparency to appear in the
089: * output image.
090: */
091: public void setSuppressAlpha(boolean suppressAlpha) {
092: this .suppressAlpha = suppressAlpha;
093: }
094:
095: private boolean expandPalette = false;
096:
097: /**
098: * Returns true if palette-color images will be expanded to
099: * produce full-color output.
100: */
101: public boolean getExpandPalette() {
102: return expandPalette;
103: }
104:
105: /**
106: * If set, palette color images (PNG color type 3) will
107: * be decoded into full-color (RGB) output images. The output
108: * image may have 3 or 4 channels, depending on the presence of
109: * transparency information.
110: *
111: * <p> The default is to output palette images using a single
112: * channel. The palette information is used to construct the
113: * output image's <code>ColorModel</code>.
114: */
115: public void setExpandPalette(boolean expandPalette) {
116: this .expandPalette = expandPalette;
117: }
118:
119: private boolean output8BitGray = false;
120:
121: /**
122: * Returns the current value of the 8-bit gray output parameter.
123: */
124: public boolean getOutput8BitGray() {
125: return output8BitGray;
126: }
127:
128: /**
129: * If set, grayscale images with a bit depth less than 8
130: * (1, 2, or 4) will be output in 8 bit form. The output values
131: * will occupy the full 8-bit range. For example, gray values
132: * 0, 1, 2, and 3 of a 2-bit image will be output as
133: * 0, 85, 170, and 255.
134: *
135: * <p> The decoding of non-grayscale images and grayscale images
136: * with a bit depth of 8 or 16 are unaffected by this setting.
137: *
138: * <p> The default is not to perform expansion. Grayscale images
139: * with a depth of 1, 2, or 4 bits will be represented using
140: * a <code>MultiPixelPackedSampleModel</code> and an
141: * <code>IndexColorModel</code>.
142: */
143: public void setOutput8BitGray(boolean output8BitGray) {
144: this .output8BitGray = output8BitGray;
145: }
146:
147: private boolean performGammaCorrection = false;
148:
149: /**
150: * Returns <code>true</code> if gamma correction is to be performed
151: * on the image data. The default is <code>false</code>.
152: *
153: * <p> If gamma correction is to be performed, the
154: * <code>getUserExponent()</code> and
155: * <code>getDisplayExponent()</code> methods are used in addition to
156: * the gamma value stored within the file (or the default value of
157: * 1/2.2 used if no value is found) to produce a single exponent
158: * using the formula:
159: * <pre>
160: * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
161: * </pre>
162: */
163: public boolean getPerformGammaCorrection() {
164: return performGammaCorrection;
165: }
166:
167: /**
168: * Turns gamma corection of the image data on or off.
169: */
170: public void setPerformGammaCorrection(boolean performGammaCorrection) {
171: this .performGammaCorrection = performGammaCorrection;
172: }
173:
174: private float userExponent = 1.0F;
175:
176: /**
177: * Returns the current value of the user exponent parameter.
178: * By default, the user exponent is equal to 1.0F.
179: */
180: public float getUserExponent() {
181: return userExponent;
182: }
183:
184: /**
185: * Sets the user exponent to a given value. The exponent
186: * must be positive. If not, an
187: * <code>IllegalArgumentException</code> will be thrown.
188: *
189: * <p> The output image pixels will be placed through a transformation
190: * of the form:
191: *
192: * <pre>
193: * sample = integer_sample / (2^bitdepth - 1.0)
194: * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
195: * output = sample ^ decoding_exponent
196: * </pre>
197: *
198: * where <code>gamma_from_file</code> is the gamma of the file
199: * data, as determined by the <code>gAMA</code>, </code>sRGB</code>,
200: * and/or <code>iCCP</code> chunks, and <code>display_exponent</code>
201: * is the exponent of the intrinsic transfer curve of the display,
202: * generally 2.2.
203: *
204: * <p> Input files which do not specify any gamma are assumed to
205: * have a gamma of <code>1/2.2</code>; such images may be displayed
206: * on a CRT with an exponent of 2.2 using the default user
207: * exponent of 1.0.
208: *
209: * <p> The user exponent may be used in order to change the
210: * effective gamma of a file. If a file has a stored gamma of
211: * X, but the decoder believes that the true file gamma is Y,
212: * setting a user exponent of Y/X will produce the same result
213: * as changing the file gamma.
214: *
215: * <p> This parameter affects the decoding of all image types.
216: *
217: * @throws IllegalArgumentException if <code>userExponent</code> is
218: * negative.
219: */
220: public void setUserExponent(float userExponent) {
221: if (userExponent <= 0.0F) {
222: throw new IllegalArgumentException(JaiI18N
223: .getString("PNGDecodeParam0"));
224: }
225: this .userExponent = userExponent;
226: }
227:
228: private float displayExponent = 2.2F;
229:
230: /**
231: * Returns the current value of the display exponent parameter.
232: * By default, the display exponent is equal to 2.2F.
233: */
234: public float getDisplayExponent() {
235: return displayExponent;
236: }
237:
238: /**
239: * Sets the display exponent to a given value. The exponent
240: * must be positive. If not, an
241: * <code>IllegalArgumentException</code> will be thrown.
242: *
243: * <p> The output image pixels will be placed through a transformation
244: * of the form:
245: *
246: * <pre>
247: * sample = integer_sample / (2^bitdepth - 1.0)
248: * decoding_exponent = user_exponent/(gamma_from_file * display_exponent)
249: * output = sample ^ decoding_exponent
250: * </pre>
251: *
252: * where <code>gamma_from_file</code> is the gamma of the file
253: * data, as determined by the <code>gAMA</code>, </code>sRGB</code>,
254: * and/or <code>iCCP</code> chunks, and <code>user_exponent</code>
255: * is an additional user-supplied parameter.
256: *
257: * <p> Input files which do not specify any gamma are assumed to
258: * have a gamma of <code>1/2.2</code>; such images should be
259: * decoding using the default display exponent of 2.2.
260: *
261: * <p> If an image is to be processed further before being displayed,
262: * it may be preferable to set the display exponent to 1.0 in order
263: * to produce a linear output image.
264: *
265: * <p> This parameter affects the decoding of all image types.
266: *
267: * @throws IllegalArgumentException if <code>userExponent</code> is
268: * negative.
269: */
270: public void setDisplayExponent(float displayExponent) {
271: if (displayExponent <= 0.0F) {
272: throw new IllegalArgumentException(JaiI18N
273: .getString("PNGDecodeParam1"));
274: }
275: this .displayExponent = displayExponent;
276: }
277:
278: private boolean expandGrayAlpha = false;
279:
280: /**
281: * Returns the current setting of the gray/alpha expansion.
282: */
283: public boolean getExpandGrayAlpha() {
284: return expandGrayAlpha;
285: }
286:
287: /**
288: * If set, images containing one channel of gray and one channel of
289: * alpha (GA) will be output in a 4-channel format (GGGA). This
290: * produces output that may be simpler to process and display.
291: *
292: * <p> This setting affects both images of color type 4 (explicit
293: * alpha) and images of color type 0 (grayscale) that contain
294: * transparency information.
295: *
296: * <p> By default, no expansion is performed.
297: */
298: public void setExpandGrayAlpha(boolean expandGrayAlpha) {
299: this .expandGrayAlpha = expandGrayAlpha;
300: }
301:
302: private boolean generateEncodeParam = false;
303:
304: private PNGEncodeParam encodeParam = null;
305:
306: /**
307: * Returns <code>true</code> if an instance of
308: * <code>PNGEncodeParam</code> will be available after an image
309: * has been decoded via the <code>getEncodeParam</code> method.
310: */
311: public boolean getGenerateEncodeParam() {
312: return generateEncodeParam;
313: }
314:
315: /**
316: * If set, an instance of <code>PNGEncodeParam</code> will be
317: * available after an image has been decoded via the
318: * <code>getEncodeParam</code> method that encapsulates information
319: * about the contents of the PNG file. If not set, this information
320: * will not be recorded and <code>getEncodeParam()</code> will
321: * return <code>null</code>.
322: */
323: public void setGenerateEncodeParam(boolean generateEncodeParam) {
324: this .generateEncodeParam = generateEncodeParam;
325: }
326:
327: /**
328: * If <code>getGenerateEncodeParam()</code> is <code>true</code>,
329: * this method may be called after decoding has completed, and
330: * will return an instance of <code>PNGEncodeParam</code> containing
331: * information about the contents of the PNG file just decoded.
332: */
333: public PNGEncodeParam getEncodeParam() {
334: return encodeParam;
335: }
336:
337: /**
338: * Sets the current encoder param instance. This method is
339: * intended to be called by the PNG decoder and will overwrite the
340: * current instance returned by <code>getEncodeParam</code>.
341: */
342: public void setEncodeParam(PNGEncodeParam encodeParam) {
343: this.encodeParam = encodeParam;
344: }
345: }
|