001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: TIFFEncodeParam.java 496556 2007-01-16 00:59:48Z cam $ */
019:
020: package org.apache.xmlgraphics.image.codec.tiff;
021:
022: import java.util.Iterator;
023: import java.util.zip.Deflater;
024:
025: import org.apache.xmlgraphics.image.codec.util.ImageEncodeParam;
026:
027: import com.sun.image.codec.jpeg.JPEGEncodeParam;
028:
029: /**
030: * An instance of <code>ImageEncodeParam</code> for encoding images in
031: * the TIFF format.
032: *
033: * <p> This class allows for the specification of encoding parameters. By
034: * default, the image is encoded without any compression, and is written
035: * out consisting of strips, not tiles. The particular compression scheme
036: * to be used can be specified by using the <code>setCompression()</code>
037: * method. The compression scheme specified will be honored only if it is
038: * compatible with the type of image being written out. For example,
039: * Group3 and Group4 compressions can only be used with Bilevel images.
040: * Writing of tiled TIFF images can be enabled by calling the
041: * <code>setWriteTiled()</code> method.
042: *
043: * <p><b> This class is not a committed part of the JAI API. It may
044: * be removed or changed in future releases of JAI.</b>
045: *
046: */
047: public class TIFFEncodeParam implements ImageEncodeParam {
048:
049: /** No compression. */
050: public static final int COMPRESSION_NONE = 1;
051:
052: /**
053: * Modified Huffman Compression (CCITT Group 3 1D facsimile compression).
054: * <p><b>Not currently supported.</b>
055: */
056: public static final int COMPRESSION_GROUP3_1D = 2;
057:
058: /**
059: * CCITT T.4 bilevel compression (CCITT Group 3 2D facsimile compression).
060: * <p><b>Not currently supported.</b>
061: */
062: public static final int COMPRESSION_GROUP3_2D = 3;
063:
064: /**
065: * CCITT T.6 bilevel compression (CCITT Group 4 facsimile compression).
066: * <p><b>Not currently supported.</b>
067: */
068: public static final int COMPRESSION_GROUP4 = 4;
069:
070: /**
071: * LZW compression.
072: * <p><b>Not supported.</b>
073: */
074: public static final int COMPRESSION_LZW = 5;
075:
076: /**
077: * Code for original JPEG-in-TIFF compression which has been
078: * depricated (for many good reasons) in favor of Tech Note 2
079: * JPEG compression (compression scheme 7).
080: * <p><b>Not supported.</b>
081: */
082: public static final int COMPRESSION_JPEG_BROKEN = 6;
083:
084: /**
085: * <a href="ftp://ftp.sgi.com/graphics/tiff/TTN2.draft.txt">
086: * JPEG-in-TIFF</a> compression.
087: */
088: public static final int COMPRESSION_JPEG_TTN2 = 7;
089:
090: /** Byte-oriented run-length encoding "PackBits" compression. */
091: public static final int COMPRESSION_PACKBITS = 32773;
092:
093: /**
094: * <a href="http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1951.txt">
095: * DEFLATE</a> lossless compression (also known as "Zip-in-TIFF").
096: */
097: public static final int COMPRESSION_DEFLATE = 32946;
098:
099: private int compression = COMPRESSION_NONE;
100:
101: private boolean writeTiled = false;
102: private int tileWidth;
103: private int tileHeight;
104:
105: private Iterator extraImages;
106:
107: private TIFFField[] extraFields;
108:
109: private boolean convertJPEGRGBToYCbCr = true;
110: private JPEGEncodeParam jpegEncodeParam = null;
111:
112: private int deflateLevel = Deflater.DEFAULT_COMPRESSION;
113:
114: /**
115: * Constructs a TIFFEncodeParam object with default values for
116: * all parameters.
117: */
118: public TIFFEncodeParam() {
119: }
120:
121: /**
122: * Returns the value of the compression parameter.
123: */
124: public int getCompression() {
125: return compression;
126: }
127:
128: /**
129: * Specifies the type of compression to be used. The compression type
130: * specified will be honored only if it is compatible with the image
131: * being written out. Currently only PackBits, JPEG, and DEFLATE
132: * compression schemes are supported.
133: *
134: * <p> If <code>compression</code> is set to any value but
135: * <code>COMPRESSION_NONE</code> and the <code>OutputStream</code>
136: * supplied to the <code>ImageEncoder</code> is not a
137: * <code>SeekableOutputStream</code>, then the encoder will use either
138: * a temporary file or a memory cache when compressing the data
139: * depending on whether the file system is accessible. Compression
140: * will therefore be more efficient if a <code>SeekableOutputStream</code>
141: * is supplied.
142: *
143: * @param compression The compression type.
144: */
145: public void setCompression(int compression) {
146:
147: switch (compression) {
148: case COMPRESSION_NONE:
149: case COMPRESSION_PACKBITS:
150: case COMPRESSION_JPEG_TTN2:
151: case COMPRESSION_DEFLATE:
152: // Do nothing.
153: break;
154: default:
155: throw new Error("TIFFEncodeParam0");
156: }
157:
158: this .compression = compression;
159: }
160:
161: /**
162: * Returns the value of the writeTiled parameter.
163: */
164: public boolean getWriteTiled() {
165: return writeTiled;
166: }
167:
168: /**
169: * If set, the data will be written out in tiled format, instead of
170: * in strips.
171: *
172: * @param writeTiled Specifies whether the image data should be
173: * wriiten out in tiled format.
174: */
175: public void setWriteTiled(boolean writeTiled) {
176: this .writeTiled = writeTiled;
177: }
178:
179: /**
180: * Sets the dimensions of the tiles to be written. If either
181: * value is non-positive, the encoder will use a default value.
182: *
183: * <p> If the data are being written as tiles, i.e.,
184: * <code>getWriteTiled()</code> returns <code>true</code>, then the
185: * default tile dimensions used by the encoder are those of the tiles
186: * of the image being encoded.
187: *
188: * <p> If the data are being written as strips, i.e.,
189: * <code>getWriteTiled()</code> returns <code>false</code>, the width
190: * of each strip is always the width of the image and the default
191: * number of rows per strip is 8.
192: *
193: * <p> If JPEG compession is being used, the dimensions of the strips or
194: * tiles may be modified to conform to the JPEG-in-TIFF specification.
195: *
196: * @param tileWidth The tile width; ignored if strips are used.
197: * @param tileHeight The tile height or number of rows per strip.
198: */
199: public void setTileSize(int tileWidth, int tileHeight) {
200: this .tileWidth = tileWidth;
201: this .tileHeight = tileHeight;
202: }
203:
204: /**
205: * Retrieves the tile width set via <code>setTileSize()</code>.
206: */
207: public int getTileWidth() {
208: return tileWidth;
209: }
210:
211: /**
212: * Retrieves the tile height set via <code>setTileSize()</code>.
213: */
214: public int getTileHeight() {
215: return tileHeight;
216: }
217:
218: /**
219: * Sets an <code>Iterator</code> of additional images to be written
220: * after the image passed as an argument to the <code>ImageEncoder</code>.
221: * The methods on the supplied <code>Iterator</code> must only be invoked
222: * by the <code>ImageEncoder</code> which will exhaust the available
223: * values unless an error occurs.
224: *
225: * <p> The value returned by an invocation of <code>next()</code> on the
226: * <code>Iterator</code> must return either a <code>RenderedImage</code>
227: * or an <code>Object[]</code> of length 2 wherein the element at index
228: * zero is a <code>RenderedImage</code> amd the other element is a
229: * <code>TIFFEncodeParam</code>. If no <code>TIFFEncodeParam</code> is
230: * supplied in this manner for an additional image, the parameters used
231: * to create the <code>ImageEncoder</code> will be used. The extra
232: * image <code>Iterator</code> set on any <code>TIFFEncodeParam</code>
233: * of an additional image will in all cases be ignored.
234: */
235: public synchronized void setExtraImages(Iterator extraImages) {
236: this .extraImages = extraImages;
237: }
238:
239: /**
240: * Returns the additional image <code>Iterator</code> specified via
241: * <code>setExtraImages()</code> or <code>null</code> if none was
242: * supplied or if a <code>null</code> value was supplied.
243: */
244: public synchronized Iterator getExtraImages() {
245: return extraImages;
246: }
247:
248: /**
249: * Sets the compression level for DEFLATE-compressed data which should
250: * either be <code>java.util.Deflater.DEFAULT_COMPRESSION</code> or a
251: * value in the range [1,9] where larger values indicate more compression.
252: * The default setting is <code>Deflater.DEFAULT_COMPRESSION</code>. This
253: * setting is ignored if the compression type is not DEFLATE.
254: */
255: public void setDeflateLevel(int deflateLevel) {
256: if (deflateLevel < 1 && deflateLevel > 9
257: && deflateLevel != Deflater.DEFAULT_COMPRESSION) {
258: throw new Error("TIFFEncodeParam1");
259: }
260:
261: this .deflateLevel = deflateLevel;
262: }
263:
264: /**
265: * Gets the compression level for DEFLATE compression.
266: */
267: public int getDeflateLevel() {
268: return deflateLevel;
269: }
270:
271: /**
272: * Sets flag indicating whether to convert RGB data to YCbCr when the
273: * compression type is JPEG. The default value is <code>true</code>.
274: * This flag is ignored if the compression type is not JPEG.
275: */
276: public void setJPEGCompressRGBToYCbCr(boolean convertJPEGRGBToYCbCr) {
277: this .convertJPEGRGBToYCbCr = convertJPEGRGBToYCbCr;
278: }
279:
280: /**
281: * Whether RGB data will be converted to YCbCr when using JPEG compression.
282: */
283: public boolean getJPEGCompressRGBToYCbCr() {
284: return convertJPEGRGBToYCbCr;
285: }
286:
287: /**
288: * Sets the JPEG compression parameters. These parameters are ignored
289: * if the compression type is not JPEG. The argument may be
290: * <code>null</code> to indicate that default compression parameters
291: * are to be used. For maximum conformance with the specification it
292: * is recommended in most cases that only the quality compression
293: * parameter be set.
294: *
295: * <p> The <code>writeTablesOnly</code> and <code>JFIFHeader</code>
296: * flags of the <code>JPEGEncodeParam</code> are ignored. The
297: * <code>writeImageOnly</code> flag is used to determine whether the
298: * JPEGTables field will be written to the TIFF stream: if
299: * <code>writeImageOnly</code> is <code>true</code>, then the JPEGTables
300: * field will be written and will contain a valid JPEG abbreviated
301: * table specification datastream. In this case the data in each data
302: * segment (strip or tile) will contain an abbreviated JPEG image
303: * datastream. If the <code>writeImageOnly</code> flag is
304: * <code>false</code>, then the JPEGTables field will not be written and
305: * each data segment will contain a complete JPEG interchange datastream.
306: */
307: public void setJPEGEncodeParam(JPEGEncodeParam jpegEncodeParam) {
308: if (jpegEncodeParam != null) {
309: jpegEncodeParam = (JPEGEncodeParam) jpegEncodeParam.clone();
310: jpegEncodeParam.setTableInfoValid(false);
311: jpegEncodeParam.setImageInfoValid(true);
312: }
313: this .jpegEncodeParam = jpegEncodeParam;
314: }
315:
316: /**
317: * Retrieves the JPEG compression parameters.
318: */
319: public JPEGEncodeParam getJPEGEncodeParam() {
320: return jpegEncodeParam;
321: }
322:
323: /**
324: * Sets an array of extra fields to be written to the TIFF Image File
325: * Directory (IFD). Fields with tags equal to the tag of any
326: * automatically generated fields are ignored. No error checking is
327: * performed with respect to the validity of the field contents or
328: * the appropriateness of the field for the image being encoded.
329: *
330: * @param extraFields An array of extra fields; the parameter is
331: * copied by reference.
332: */
333: public void setExtraFields(TIFFField[] extraFields) {
334: this .extraFields = extraFields;
335: }
336:
337: /**
338: * Returns the value set by <code>setExtraFields()</code>.
339: */
340: public TIFFField[] getExtraFields() {
341: return extraFields;
342: }
343: }
|