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 */ 045package com.github.jaiimageio.jpeg2000; 046 047import java.util.Locale; 048 049import javax.imageio.ImageWriteParam; 050 051/** 052 * A subclass of <code>ImageWriteParam</code> for writing images in 053 * the JPEG 2000 format. 054 * 055 * <p>JPEG 2000 plugin supports to losslessly or lossy compress gray-scale, 056 * RGB, and RGBA images with byte, unsigned short or short data type. It also 057 * supports losslessly compress bilevel, and 8-bit color indexed images. The 058 * result data is in the of JP2 format -- JPEG 2000 Part 1 or baseline format. 059 * 060 * <p>The parameters for encoding JPEG 2000 are listed in the following table: 061 * 062 * <p><table border=1> 063 * <caption><b>JPEG 2000 Plugin Decoding Parameters</b></caption> 064 * <tr><th>Parameter Name</th> <th>Description</th></tr> 065 * <tr> 066 * <td>numDecompositionLevels</td> 067 * <td> The number of decomposition levels to generate. This value must 068 * be in the range 069 * <code>0 ≤ numDecompositionLevels ≤ 32 070 * </code>. The default value is <code>5</code>. Note that the number 071 * of resolution levels is 072 * <code>numDecompositionLevels + 1</code>. 073 * The number of decomposition levels is constant across 074 * all components and all tiles. 075 * </td> 076 * </tr> 077 * <tr> 078 * <td>encodingRate</td> 079 * <td> The bitrate in bits-per-pixel for encoding. Should be set when 080 * lossy compression scheme is used. With the default value 081 * <code>Double.MAX_VALUE</code>, a lossless compression will be done. 082 * </td> 083 * </tr> 084 * <tr> 085 * <td>lossless</td> 086 * <td> Indicates using the lossless scheme or not. It is equivalent to 087 * use reversible quantization and 5x3 integer wavelet filters. The 088 * default is <code>true</code>. 089 * </td> 090 * </tr> 091 * <tr> 092 * <td>componentTransformation</td> 093 * <td> Specifies to utilize the component transformation on some tiles. 094 * If the wavelet transform is reversible (w5x3 filter), the Reversible 095 * Component Transformation (RCT) is applied. If not reversible 096 * (w9x7 filter), the Irreversible Component Transformation (ICT) is used. 097 * </td> 098 * </tr> 099 * <tr> 100 * <td>filters</td> 101 * <td> Specifies which wavelet filters to use for the specified 102 * tile-components. JPEG 2000 part I only supports w5x3 and w9x7 filters. 103 * </td> 104 * </tr> 105 * <tr> 106 * <td>codeBlockSize</td> 107 * <td> Specifies the maximum code-block size to use for tile-component. 108 * The maximum width and height is 1024, however the block size 109 * (i.e. width x height) must not exceed 4096. The minimum width and 110 * height is 4. The default values are (64, 64). 111 * </td> 112 * </tr> 113 * <tr> 114 * <td>progressionType</td> 115 * <td> Specifies which type of progression should be used when generating 116 * the codestream. 117 * <p> The format is one of the progression types defined below: 118 * 119 * <p> res : Resolution-Layer-Component-Position 120 * <p> layer: Layer-Resolution-Component-Position 121 * <p> res-pos: Resolution-Position-Component-Layer 122 * <p> pos-comp: Position-Component-Resolution-Layer 123 * <p> comp-pos: Component-Position-Resolution-Layer 124 * </td> 125 * </tr> 126 * <tr> 127 * <td>SOP</td> 128 * <td>Specifies whether start of packet (SOP) markers should be used. 129 * true enables, false disables it. The default value is false. 130 * </td> 131 * </tr> 132 * <tr> 133 * <td>EPH</td> 134 * <td>Specifies whether end of packet header (EPH) markers should be used. 135 * true enables, false disables it. The default value is false. 136 * </td> 137 * </tr> 138 * <tr> 139 * <td>writeCodeStreamOnly</td> 140 * <td>Specifies whether write only the jpeg2000 code stream, i.e, no any 141 * box is written. The default value is false. 142 * </td> 143 * </tr> 144 * </table> 145 */ 146public class J2KImageWriteParam extends ImageWriteParam { 147 /** The filter for lossy compression. */ 148 public static final String FILTER_97 = "w9x7"; 149 150 /** The filter for lossless compression. */ 151 public static final String FILTER_53 = "w5x3"; 152 153 /** 154 * The number of decomposition levels. 155 */ 156 private int numDecompositionLevels = 5; 157 158 /** 159 * The bitrate in bits-per-pixel for encoding. Should be set when lossy 160 * compression scheme is used. The default is 161 * <code>Double.MAX_VALUE</code>. 162 */ 163 private double encodingRate = Double.MAX_VALUE; 164 165 /** 166 * Indicates using the lossless scheme or not. It is equivalent to 167 * use reversible quantization and 5x3 integer wavelet filters. 168 */ 169 private boolean lossless = true; 170 171 /** Specifies to utilize the component transformation with some tiles. 172 * If the wavelet transform is reversible (w5x3 filter), the 173 * Reversible Component Transformation (RCT) is applied. If not reversible 174 * (w9x7 filter), the Irreversible Component Transformation (ICT) 175 * is used. 176 */ 177 private boolean componentTransformation = true; 178 179 /** Specifies which filters to use for the specified tile-components. 180 * JPEG 2000 part I only supports w5x3 and w9x7 filters. 181 */ 182 private String filter = FILTER_53; 183 184 /** Specifies the maximum code-block size to use for tile-component. 185 * The maximum width and height is 1024, however the image area 186 * (i.e. width x height) must not exceed 4096. The minimum 187 * width and height is 4. Default: 64 64. 188 */ 189 private int[] codeBlockSize = new int[]{64, 64}; 190 191 /** See above. 192 */ 193 private String progressionType = "layer"; 194 195 /** Specifies whether end of packet header (EPH) markers should be used. 196 * true enables, false disables it. Default: false. 197 */ 198 private boolean EPH = false; 199 200 /** Specifies whether start of packet (SOP) markers should be used. 201 * true enables, false disables it. Default: false. 202 */ 203 private boolean SOP = false; 204 205 /** Specifies whether write only the jpeg2000 code stream, i.e, no any 206 * box is written. The default value is false. 207 */ 208 private boolean writeCodeStreamOnly = false; 209 210 /** 211 * Constructor which sets the <code>Locale</code>. 212 * 213 * @param locale a <code>Locale</code> to be used to localize 214 * compression type names and quality descriptions, or 215 * <code>null</code>. 216 */ 217 public J2KImageWriteParam(Locale locale) { 218 super(locale); 219 setDefaults(); 220 } 221 222 /** 223 * Constructs a <code>J2KImageWriteParam</code> object with default 224 * values for all parameters. 225 */ 226 public J2KImageWriteParam() { 227 super(); 228 setDefaults(); 229 } 230 231 /** Set source */ 232 private void setDefaults() { 233 // override the params in the super class 234 canOffsetTiles = true; 235 canWriteTiles = true; 236 canOffsetTiles = true; 237 compressionTypes = new String[] {"JPEG2000"}; 238 canWriteCompressed = true; 239 canWriteProgressive= true; 240 tilingMode = MODE_EXPLICIT; 241 } 242 243 /** 244 * Sets <code>numDecompositionLevels</code>. 245 * 246 * @param numDecompositionLevels the number of decomposition levels. 247 * @throws IllegalArgumentException if <code>numDecompositionLevels</code> 248 * is negative or greater than 32. 249 * @see #getNumDecompositionLevels 250 */ 251 public void setNumDecompositionLevels(int numDecompositionLevels) { 252 if(numDecompositionLevels < 0 || numDecompositionLevels > 32) { 253 throw new IllegalArgumentException 254 ("numDecompositionLevels < 0 || numDecompositionLevels > 32"); 255 } 256 this.numDecompositionLevels = numDecompositionLevels; 257 } 258 259 /** 260 * Gets <code>numDecompositionLevels</code>. 261 * 262 * @return the number of decomposition levels. 263 * @see #setNumDecompositionLevels 264 */ 265 public int getNumDecompositionLevels() { 266 return numDecompositionLevels; 267 } 268 269 /** 270 * Sets <code>encodingRate</code>. 271 * 272 * @param rate the encoding rate in bits-per-pixel. 273 * @see #getEncodingRate() 274 */ 275 public void setEncodingRate(double rate) { 276 this.encodingRate = rate; 277 if (encodingRate != Double.MAX_VALUE) { 278 lossless = false; 279 filter = FILTER_97; 280 } else { 281 lossless = true; 282 filter = FILTER_53; 283 } 284 } 285 286 /** 287 * Gets <code>encodingRate</code>. 288 * 289 * @return the encoding rate in bits-per-pixel. 290 * @see #setEncodingRate(double) 291 */ 292 public double getEncodingRate() { 293 return encodingRate; 294 } 295 296 /** 297 * Sets <code>lossless</code>. 298 * 299 * @param lossless whether the compression scheme is lossless. 300 * @see #getLossless() 301 */ 302 public void setLossless(boolean lossless) { 303 this.lossless = lossless; 304 } 305 306 /** 307 * Gets <code>lossless</code>. 308 * 309 * @return whether the compression scheme is lossless. 310 * @see #setLossless(boolean) 311 */ 312 public boolean getLossless() { 313 return lossless; 314 } 315 316 /** 317 * Sets <code>filter</code>. 318 * 319 * @param value which wavelet filters to use for the specified 320 * tile-components. 321 * @see #getFilter() 322 */ 323 public void setFilter(String value) { 324 filter = value; 325 } 326 327 /** 328 * Gets <code>filters</code>. 329 * 330 * @return which wavelet filters to use for the specified 331 * tile-components. 332 * @see #setFilter(String) 333 */ 334 public String getFilter() { 335 return filter; 336 } 337 338 /** 339 * Sets <code>componentTransformation</code>. 340 * 341 * @param value whether to utilize the component transformation. 342 * @see #getComponentTransformation() 343 */ 344 public void setComponentTransformation(boolean value) { 345 componentTransformation = value; 346 } 347 348 /** 349 * Gets <code>componentTransformation</code>. 350 * 351 * @return whether to utilize the component transformation. 352 * @see #setComponentTransformation(boolean) 353 */ 354 public boolean getComponentTransformation() { 355 return componentTransformation; 356 } 357 358 /** 359 * Sets <code>codeBlockSize</code>. 360 * 361 * @param value the maximum code-block size to use per tile-component. 362 * @see #getCodeBlockSize() 363 */ 364 public void setCodeBlockSize(int[] value) { 365 codeBlockSize = value; 366 } 367 368 /** 369 * Gets <code>codeBlockSize</code>. 370 * 371 * @return the maximum code-block size to use per tile-component. 372 * @see #setCodeBlockSize(int[]) 373 */ 374 public int[] getCodeBlockSize() { 375 return codeBlockSize; 376 } 377 378 /** 379 * Sets <code>SOP</code>. 380 * 381 * @param value whether start of packet (SOP) markers should be used. 382 * @see #getSOP() 383 */ 384 public void setSOP(boolean value) { 385 SOP = value; 386 } 387 388 /** 389 * Gets <code>SOP</code>. 390 * 391 * @return whether start of packet (SOP) markers should be used. 392 * @see #setSOP(boolean) 393 */ 394 public boolean getSOP() { 395 return SOP; 396 } 397 398 /** 399 * Sets <code>EPH</code>. 400 * 401 * @param value whether end of packet header (EPH) markers should be used. 402 * @see #getEPH() 403 */ 404 public void setEPH(boolean value) { 405 EPH = value; 406 } 407 408 /** 409 * Gets <code>EPH</code>. 410 * 411 * @return whether end of packet header (EPH) markers should be used. 412 * @see #setEPH(boolean) 413 */ 414 public boolean getEPH() { 415 return EPH; 416 } 417 418 /** 419 * Sets <code>progressionType</code>. 420 * 421 * @param value which type of progression should be used when generating 422 * the codestream. 423 * @see #getProgressionType() 424 */ 425 public void setProgressionType(String value) { 426 progressionType = value; 427 } 428 429 /** 430 * Gets <code>progressionType</code>. 431 * 432 * @return which type of progression should be used when generating 433 * the codestream. 434 * @see #setProgressionType(String) 435 */ 436 public String getProgressionType() { 437 return progressionType; 438 } 439 440 /** Sets <code>writeCodeStreamOnly</code>. 441 * 442 * @param value Whether the jpeg2000 code stream only or the jp2 format 443 * will be written into the output. 444 * @see #getWriteCodeStreamOnly() 445 */ 446 public void setWriteCodeStreamOnly(boolean value) { 447 writeCodeStreamOnly = value; 448 } 449 450 /** Gets <code>writeCodeStreamOnly</code>. 451 * 452 * @return whether the jpeg2000 code stream only or the jp2 format 453 * will be written into the output. 454 * @see #setWriteCodeStreamOnly(boolean) 455 */ 456 public boolean getWriteCodeStreamOnly() { 457 return writeCodeStreamOnly; 458 } 459}