001: /*
002: * $RCSfile: J2KImageWriteParam.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.2 $
042: * $Date: 2006/09/20 23:23:30 $
043: * $State: Exp $
044: */
045: package com.sun.media.imageio.plugins.jpeg2000;
046:
047: import java.awt.Rectangle;
048: import java.awt.image.Raster;
049: import java.awt.image.RenderedImage;
050: import java.util.Collections;
051: import java.util.Locale;
052: import java.util.Iterator;
053: import javax.imageio.ImageWriteParam;
054:
055: /**
056: * A subclass of <code>ImageWriteParam</code> for writing images in
057: * the JPEG 2000 format.
058: *
059: * <p>JPEG 2000 plugin supports to losslessly or lossy compress gray-scale,
060: * RGB, and RGBA images with byte, unsigned short or short data type. It also
061: * supports losslessly compress bilevel, and 8-bit color indexed images. The
062: * result data is in the of JP2 format -- JPEG 2000 Part 1 or baseline format.
063: *
064: * <p>The parameters for encoding JPEG 2000 are listed in the following table:
065: *
066: * <p><table border=1>
067: * <caption><b>JPEG 2000 Plugin Decoding Parameters</b></caption>
068: * <tr><th>Parameter Name</th> <th>Description</th></tr>
069: * <tr>
070: * <td>numDecompositionLevels</td>
071: * <td> The number of decomposition levels to generate. This value must
072: * be in the range
073: * <code>0 ≤ numDecompositionLevels ≤ 32
074: * </code>. The default value is <code>5</code>. Note that the number
075: * of resolution levels is
076: * <code>numDecompositionLevels + 1</code>.
077: * The number of decomposition levels is constant across
078: * all components and all tiles.
079: * </td>
080: * </tr>
081: * <tr>
082: * <td>encodingRate</td>
083: * <td> The bitrate in bits-per-pixel for encoding. Should be set when
084: * lossy compression scheme is used. With the default value
085: * <code>Double.MAX_VALUE</code>, a lossless compression will be done.
086: * </td>
087: * </tr>
088: * <tr>
089: * <td>lossless</td>
090: * <td> Indicates using the lossless scheme or not. It is equivalent to
091: * use reversible quantization and 5x3 integer wavelet filters. The
092: * default is <code>true</code>.
093: * </td>
094: * </tr>
095: * <tr>
096: * <td>componentTransformation</td>
097: * <td> Specifies to utilize the component transformation on some tiles.
098: * If the wavelet transform is reversible (w5x3 filter), the Reversible
099: * Component Transformation (RCT) is applied. If not reversible
100: * (w9x7 filter), the Irreversible Component Transformation (ICT) is used.
101: * </td>
102: * </tr>
103: * <tr>
104: * <td>filters</td>
105: * <td> Specifies which wavelet filters to use for the specified
106: * tile-components. JPEG 2000 part I only supports w5x3 and w9x7 filters.
107: * </td>
108: * </tr>
109: * <tr>
110: * <td>codeBlockSize</td>
111: * <td> Specifies the maximum code-block size to use for tile-component.
112: * The maximum width and height is 1024, however the block size
113: * (i.e. width x height) must not exceed 4096. The minimum width and
114: * height is 4. The default values are (64, 64).
115: * </td>
116: * </tr>
117: * <tr>
118: * <td>progressionType</td>
119: * <td> Specifies which type of progression should be used when generating
120: * the codestream.
121: * <p> The format is ont of the progression types defined below:
122: *
123: * <p> res : Resolution-Layer-Component-Position
124: * <p> layer: Layer-Resolution-Component-Position
125: * <p> res-pos: Resolution-Position-Component-Layer
126: * <p> pos-comp: Position-Component-Resolution-Layer
127: * <p> comp-pos: Component-Position-Resolution-Layer
128: * </td>
129: * </tr>
130: * <tr>
131: * <td>SOP</td>
132: * <td>Specifies whether start of packet (SOP) markers should be used.
133: * true enables, false disables it. The default value is false.
134: * </td>
135: * </tr>
136: * <tr>
137: * <td>EPH</td>
138: * <td>Specifies whether end of packet header (EPH) markers should be used.
139: * true enables, false disables it. The default value is false.
140: * </td>
141: * </tr>
142: * <tr>
143: * <td>writeCodeStreamOnly</td>
144: * <td>Specifies whether write only the jpeg2000 code stream, i.e, no any
145: * box is written. The default value is false.
146: * </td>
147: * </tr>
148: * </table>
149: */
150: public class J2KImageWriteParam extends ImageWriteParam {
151: /** The filter for lossy compression. */
152: public static final String FILTER_97 = "w9x7";
153:
154: /** The filter for lossless compression. */
155: public static final String FILTER_53 = "w5x3";
156:
157: /**
158: * The number of decomposition levels.
159: */
160: private int numDecompositionLevels = 5;
161:
162: /**
163: * The bitrate in bits-per-pixel for encoding. Should be set when lossy
164: * compression scheme is used. The default is
165: * <code>Double.MAX_VALUE</code>.
166: */
167: private double encodingRate = Double.MAX_VALUE;
168:
169: /**
170: * Indicates using the lossless scheme or not. It is equivalent to
171: * use reversible quantization and 5x3 integer wavelet filters.
172: */
173: private boolean lossless = true;
174:
175: /** Specifies to utilize the component transformation with some tiles.
176: * If the wavelet transform is reversible (w5x3 filter), the
177: * Reversible Component Transformation (RCT) is applied. If not reversible
178: * (w9x7 filter), the Irreversible Component Transformation (ICT)
179: * is used.
180: */
181: private boolean componentTransformation = true;
182:
183: /** Specifies which filters to use for the specified tile-components.
184: * JPEG 2000 part I only supports w5x3 and w9x7 filters.
185: */
186: private String filter = FILTER_53;
187:
188: /** Specifies the maximum code-block size to use for tile-component.
189: * The maximum width and height is 1024, however the image area
190: * (i.e. width x height) must not exceed 4096. The minimum
191: * width and height is 4. Default: 64 64.
192: */
193: private int[] codeBlockSize = new int[] { 64, 64 };
194:
195: /** See above.
196: */
197: private String progressionType = "layer";
198:
199: /** Specifies whether end of packet header (EPH) markers should be used.
200: * true enables, false disables it. Default: false.
201: */
202: private boolean EPH = false;
203:
204: /** Specifies whether start of packet (SOP) markers should be used.
205: * true enables, false disables it. Default: false.
206: */
207: private boolean SOP = false;
208:
209: /** Specifies whether write only the jpeg2000 code stream, i.e, no any
210: * box is written. The default value is false.
211: */
212: private boolean writeCodeStreamOnly = false;
213:
214: /**
215: * Constructor which sets the <code>Locale</code>.
216: *
217: * @param locale a <code>Locale</code> to be used to localize
218: * compression type names and quality descriptions, or
219: * <code>null</code>.
220: */
221: public J2KImageWriteParam(Locale locale) {
222: super (locale);
223: setDefaults();
224: }
225:
226: /**
227: * Constructs a <code>J2KImageWriteParam</code> object with default
228: * values for all parameters.
229: */
230: public J2KImageWriteParam() {
231: super ();
232: setDefaults();
233: }
234:
235: /** Set source */
236: private void setDefaults() {
237: // override the params in the super class
238: canOffsetTiles = true;
239: canWriteTiles = true;
240: canOffsetTiles = true;
241: compressionTypes = new String[] { "JPEG2000" };
242: canWriteCompressed = true;
243: tilingMode = MODE_EXPLICIT;
244: }
245:
246: /**
247: * Sets <code>numDecompositionLevels</code>.
248: *
249: * @param numDecompositionLevels the number of decomposition levels.
250: * @throws IllegalArgumentException if <code>numDecompositionLevels</code>
251: * is negative or greater than 32.
252: * @see #getNumDecompositionLevels
253: */
254: public void setNumDecompositionLevels(int numDecompositionLevels) {
255: if (numDecompositionLevels < 0 || numDecompositionLevels > 32) {
256: throw new IllegalArgumentException(
257: "numDecompositionLevels < 0 || numDecompositionLevels > 32");
258: }
259: this .numDecompositionLevels = numDecompositionLevels;
260: }
261:
262: /**
263: * Gets <code>numDecompositionLevels</code>.
264: *
265: * @return the number of decomposition levels.
266: * @see #setNumDecompositionLevels
267: */
268: public int getNumDecompositionLevels() {
269: return numDecompositionLevels;
270: }
271:
272: /**
273: * Sets <code>encodingRate</code>.
274: *
275: * @param rate the encoding rate in bits-per-pixel.
276: * @see #getEncodingRate()
277: */
278: public void setEncodingRate(double rate) {
279: this .encodingRate = rate;
280: if (encodingRate != Double.MAX_VALUE) {
281: lossless = false;
282: filter = FILTER_97;
283: } else {
284: lossless = true;
285: filter = FILTER_53;
286: }
287: }
288:
289: /**
290: * Gets <code>encodingRate</code>.
291: *
292: * @return the encoding rate in bits-per-pixel.
293: * @see #setEncodingRate(double)
294: */
295: public double getEncodingRate() {
296: return encodingRate;
297: }
298:
299: /**
300: * Sets <code>lossless</code>.
301: *
302: * @param lossless whether the compression scheme is lossless.
303: * @see #getLossless()
304: */
305: public void setLossless(boolean lossless) {
306: this .lossless = lossless;
307: }
308:
309: /**
310: * Gets <code>lossless</code>.
311: *
312: * @return whether the compression scheme is lossless.
313: * @see #setLossless(boolean)
314: */
315: public boolean getLossless() {
316: return lossless;
317: }
318:
319: /**
320: * Sets <code>filter</code>.
321: *
322: * @param value which wavelet filters to use for the specified
323: * tile-components.
324: * @see #getFilter()
325: */
326: public void setFilter(String value) {
327: filter = value;
328: }
329:
330: /**
331: * Gets <code>filters</code>.
332: *
333: * @return which wavelet filters to use for the specified
334: * tile-components.
335: * @see #setFilter(String)
336: */
337: public String getFilter() {
338: return filter;
339: }
340:
341: /**
342: * Sets <code>componentTransformation</code>.
343: *
344: * @param value whether to utilize the component transformation.
345: * @see #getComponentTransformation()
346: */
347: public void setComponentTransformation(boolean value) {
348: componentTransformation = value;
349: }
350:
351: /**
352: * Gets <code>componentTransformation</code>.
353: *
354: * @return whether to utilize the component transformation.
355: * @see #setComponentTransformation(boolean)
356: */
357: public boolean getComponentTransformation() {
358: return componentTransformation;
359: }
360:
361: /**
362: * Sets <code>codeBlockSize</code>.
363: *
364: * @param value the maximum code-block size to use per tile-component.
365: * @see #getCodeBlockSize()
366: */
367: public void setCodeBlockSize(int[] value) {
368: codeBlockSize = value;
369: }
370:
371: /**
372: * Gets <code>codeBlockSize</code>.
373: *
374: * @return the maximum code-block size to use per tile-component.
375: * @see #setCodeBlockSize(int[])
376: */
377: public int[] getCodeBlockSize() {
378: return codeBlockSize;
379: }
380:
381: /**
382: * Sets <code>SOP</code>.
383: *
384: * @param value whether start of packet (SOP) markers should be used.
385: * @see #getSOP()
386: */
387: public void setSOP(boolean value) {
388: SOP = value;
389: }
390:
391: /**
392: * Gets <code>SOP</code>.
393: *
394: * @return whether start of packet (SOP) markers should be used.
395: * @see #setSOP(boolean)
396: */
397: public boolean getSOP() {
398: return SOP;
399: }
400:
401: /**
402: * Sets <code>EPH</code>.
403: *
404: * @param value whether end of packet header (EPH) markers should be used.
405: * @see #getEPH()
406: */
407: public void setEPH(boolean value) {
408: EPH = value;
409: }
410:
411: /**
412: * Gets <code>EPH</code>.
413: *
414: * @return whether end of packet header (EPH) markers should be used.
415: * @see #setEPH(boolean)
416: */
417: public boolean getEPH() {
418: return EPH;
419: }
420:
421: /**
422: * Sets <code>progressionType</code>.
423: *
424: * @param value which type of progression should be used when generating
425: * the codestream.
426: * @see #getProgressionType()
427: */
428: public void setProgressionType(String value) {
429: progressionType = value;
430: }
431:
432: /**
433: * Gets <code>progressionType</code>.
434: *
435: * @return which type of progression should be used when generating
436: * the codestream.
437: * @see #setProgressionType(String)
438: */
439: public String getProgressionType() {
440: return progressionType;
441: }
442:
443: /** Sets <code>writeCodeStreamOnly</code>.
444: *
445: * @param value Whether the jpeg2000 code stream only or the jp2 format
446: * will be written into the output.
447: * @see #getWriteCodeStreamOnly()
448: */
449: public void setWriteCodeStreamOnly(boolean value) {
450: writeCodeStreamOnly = value;
451: }
452:
453: /** Gets <code>writeCodeStreamOnly</code>.
454: *
455: * @return whether the jpeg2000 code stream only or the jp2 format
456: * will be written into the output.
457: * @see #setWriteCodeStreamOnly(boolean)
458: */
459: public boolean getWriteCodeStreamOnly() {
460: return writeCodeStreamOnly;
461: }
462: }
|