001/* 002 * $RCSfile: J2KImageWriteParamJava.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.sun.media.imageioimpl.plugins.jpeg2000; 046 047import java.awt.Rectangle; 048import java.awt.image.Raster; 049import java.awt.image.RenderedImage; 050import java.util.Collections; 051import java.util.Locale; 052import java.util.Iterator; 053import javax.imageio.IIOImage; 054import javax.imageio.ImageWriteParam; 055import jj2000.j2k.*; 056import jj2000.j2k.roi.*; 057import jj2000.j2k.quantization.*; 058import jj2000.j2k.wavelet.analysis.AnWTFilterSpec; 059import jj2000.j2k.image.forwcomptransf.ForwCompTransfSpec; 060import jj2000.j2k.entropy.CBlkSizeSpec; 061import jj2000.j2k.entropy.PrecinctSizeSpec; 062import jj2000.j2k.entropy.ProgressionSpec; 063import jj2000.j2k.image.BlkImgDataSrc; 064import jj2000.j2k.entropy.encoder.LayersInfo; 065import com.sun.media.imageio.plugins.jpeg2000.J2KImageWriteParam; 066 067/** 068 * A subclass of <code>ImageWriteParam</code> for writing images in 069 * the JPEG 2000 format. 070 * 071 * <p>JPEG 2000 plugin supports to losslessly or lossy compress gray-scale, 072 * RGB, and RGBA images with byte, unsigned short or short data type. It also 073 * supports losslessly compress bilevel, and 8-bit indexed. The result data 074 * is in the format of JP2 (JPEG 2000 Part 1 or baseline format). 075 * 076 * <p>Many encoding parameters for JPEG 2000 can be tile-component specific. 077 * These parameters are marked as <code>Yes</code> in the column <code> 078 * TC_SPEC</code> in the following parameter table. 079 * They must be provided according to the pattern: 080 * [<tile-component idx>] <param> (repeated as many time as needed), 081 * where <tile-component idx> respect the following policy according to 082 * the degree of priority: 083 * <table> 084 * <tr><td>(1) t<idx> c<idx> : Tile-component specification.</td></tr> 085 * <tr><td>(2) t<idx> : Tile specification.</td></tr> 086 * <tr><td>(3) c<idx> : Component specification.</td></tr> 087 * <tr><td>(4) <void> : Default specification.</td></tr> 088 * </table> 089 * <p>Where the priorities of the specifications are: 090 * (1) > (2) > (3) > (4), (">" means "overrides") 091 * <idx>: "," separates indexes, "-" separates bounds of indexes list. 092 * (for example, 0,2-4 means indexes 0,2,3 and 4). 093 * 094 * <p>The parameters for encoding JPEG 2000 are listed in the following table: 095 * 096 * * <p><table border=1> 097 * <caption><b>JPEG 2000 Plugin Decoding Parameters</b></caption> 098 * <tr><th>Parameter Name</th> <th>Description</th><th>TC_SPEC</th></tr> 099 * <tr> 100 * <td>encodingRate</td> 101 * <td> The bitrate in bits-per-pixel for encoding. Should be set when 102 * lossy compression scheme is used. With the default value 103 * <code>Double.MAX_VALUE</code>, a lossless compression will be done. 104 * </td> 105 * <td>No</td> 106 * </tr> 107 * <tr> 108 * <td>lossless</td> 109 * <td> Indicates using the loseless scheme or not. It is equivalent to 110 * use reversible quantization and 5x3 integer wavelet filters. The 111 * default is <code>true</code>. 112 * </td> 113 * <td>No</td> 114 * </tr> 115 * <tr> 116 * <td>componentTransformation</td> 117 * <td> Specifies to utilize the component transformation on some tiles. 118 * If the wavelet transform is reversible (w5x3 filter), the Reversible 119 * Component Transformation (RCT) is applied. If not reversible 120 * (w9x7 filter), the Irreversible Component Transformation (ICT) is used. 121 * </td> 122 * <td>Yes, Tile_Specific</td> 123 * </tr> 124 * <tr> 125 * <td>filters</td> 126 * <td> Specifies which wavelet filters to use for the specified 127 * tile-components. JPEG 2000 part I only supports w5x3 and w9x7 filters. 128 * </td> 129 * <td>Yes</td> 130 * </tr> 131 * <tr> 132 * <td>decompositionLevel</td> 133 * <td> Specifies the wavelet decomposition levels to apply to 134 * the image. If it is 0, no wavelet transform is performed, in which 135 * case the original image data will be sent to the encoder and an example 136 * is the binary data. All components and all tiles have the same number 137 * of decomposition levels. The default value is 5. 138 * </td> 139 * <td>No</td> 140 * </tr> 141 * <tr> 142 * <td>guardBits</td> 143 * <td> The number of bits used for each tile-component in the quantizer 144 * to avoid overflow. It takes values in the range 0 through 7. The 145 * default value is 2. 146 * </td> 147 * <td>Yes</td> 148 * </tr> 149 * <tr> 150 * <td>quantizationStep</td> 151 * <td> This parameter specifies the base normalized quantization step 152 * size for the tiles/components. It is normalized to a dynamic range 153 * of 1 in the image domain. This parameter is ignored in reversible 154 * coding. The default value is 0.0078125. 155 * </td> 156 * <td>Yes</td> 157 * </tr> 158 * <tr> 159 * <td>quantizationType</td> 160 * <td> Specifies which quantization type to use for specified 161 * tiles/components. Not specified for lossless compression. By default, 162 * the quantization step size is "expounded". Supported quantization 163 * types specification are : "reversible" (no quantization), "derived" 164 * (derived quantization step size) and "expounded". 165 * </td> 166 * <td>Yes</td> 167 * </tr> 168 * <tr> 169 * <td>codeBlockSize</td> 170 * <td> Specifies the maximum code-block size to use for tile-component. 171 * The maximum width and height is 1024, however the block size 172 * (i.e. width x height) must not exceed 4096. The minimum width and 173 * height is 4. The default values are (64, 64). 174 * </td> 175 * <td>Yes</td> 176 * </tr> 177 * <tr> 178 * <td>progressionType</td> 179 * <td> Specifies which type of progression should be used when generating 180 * the codestream. 181 * <p> The format is [<tile index>] 182 * res|layer|res-pos|pos-comp|comp-pos [res_start comp_start layer_end 183 * res_end comp_end prog] [[res_start comp_start layer_end res_end 184 * comp_end prog]...] [[<tile-component idx]...]. 185 * <p>The value "res" generates a resolution progressive 186 * codestream with the number of layers specified by "layers" parameter. 187 * The value "layer" generates a layer progressive codestream with 188 * multiple layers. In any case, the rate-allocation algorithm optimizes 189 * for best quality in each layer. The quality measure is mean squared 190 * error (MSE) or a weighted version of it (WMSE). If no progression 191 * type is specified or imposed by other parameters, the default value 192 * is "layer". It is also possible to describe progression order 193 * changes. In this case, "res_start" is the index (from 0) of the 194 * first resolution level, "comp_start" is the index (from 0) of the 195 * first component, "layer_end" is the index (from 0) of the first layer 196 * not included, "res_end" is the index (from 0) of the first 197 * resolution level not included, "comp_end" is index (from 0) of 198 * the first component not included and "prog" is the progression type 199 * to be used for the rest of the tile/image. Several progression 200 * order changes can be specified, one after the other. 201 * </td> 202 * <td>Yes</td> 203 * </tr> 204 * <tr> 205 * <td>packPacketHeaderInTile</td> 206 * <td> Indicates that the packet headers are packed in the tiles' headers. 207 * The default is false. 208 * </td> 209 * <td>No</td> 210 * </tr> 211 * <tr> 212 * <td>packPacketHeaderInMain</td> 213 * <td> Indicates that the packet headers are packed in the main header. 214 * The default is false. 215 * </td> 216 * <td>No</td> 217 * </tr> 218 * <tr> 219 * <td>packetPerTilePart</td> 220 * <td> Specifies the maximum number of packets to be put into one tile-part. 221 * Zero means putting all packets in the first tile-part of each tile. 222 * </td> 223 * <td>No</td> 224 * </tr> 225 * <tr> 226 * <td>ROIs</td> 227 * <td> Specifies ROIs shape and location. The component index specifies 228 * which components contain the ROI. If this parameter is used, the 229 * codestream is layer progressive by default unless it is overridden by 230 * the <code>progressionType</code>. A rectanglar or circular ROI can be 231 * specified in the format: [<component idx>] R <left> 232 * <top> <width> <height> or [<component idx>] C 233 * <center x> <center y> <radius>. An arbitrary shape 234 * can be assigned by [<component idx>] A <PGM file> 235 * </td> 236 * <td>Yes, component-specified</td> 237 * </tr> 238 * <tr> 239 * <td>startLevelROI</td> 240 * <td> This parameter defines the lowest resolution levels to belong to 241 * the ROI. By doing this, it is possible to avoid getting 242 * information for the ROI at an early stage of transmission. 243 * startLevelROI = 0 means the lowest resolution level belongs to 244 * the ROI, 1 means the second lowest etc. The default values, -1, 245 * deactivates this parameter. 246 * </td> 247 * <td>No</td> 248 * </tr> 249 * <tr> 250 * <td>alignROI</td> 251 * <td> By specifying this parameter, the ROI mask will be limited to 252 * covering only entire code-blocks. The ROI coding can then be 253 * performed without any actual scaling of the coefficients but by 254 * instead scaling the distortion estimates. 255 * </td> 256 * <td>No</td> 257 * </tr> 258 * <tr> 259 * <td>bypass</td> 260 * <td> Uses the lazy coding mode with the entropy coder. This will bypass 261 * the MQ coder for some of the coding passes, where the distribution 262 * is often close to uniform. Since the MQ codeword will be terminated 263 * at least once per lazy pass, it is important to use an efficient 264 * termination algorithm, <code>methodForMQTermination</code>. 265 * true enables, and false disables it. The default value is false. 266 * </td> 267 * <td>Yes</td> 268 * </tr> 269 * <tr> 270 * <td>resetMQ</td> 271 * <td> If this is enabled the probability estimates of the MQ coder are 272 * reset after each arithmetically coded (i.e. non-lazy) coding pass. 273 * true enables, and false disables it. The default value is false. 274 * </td> 275 * <td>Yes</td> 276 * </tr> 277 * <tr> 278 * <td>terminateOnByte</td> 279 * <td> If this is enabled the codeword (raw or MQ) is terminated on a byte 280 * boundary after each coding pass. In this case it is important to use 281 * an efficient termination algorithm, "methodForMQTermination". 282 * true enables, and false disables it. The default value is false. 283 * </td> 284 * <td>Yes</td> 285 * </tr> 286 * <tr> 287 * <td>causalCXInfo</td> 288 * <td> Uses vertically stripe causal context formation. If this is 289 * enabled the context formation process in one stripe is independant of 290 * the next stripe (i.e. the one below it). true enables, and false 291 * disables it. The default value is false. 292 * </td> 293 * <td>Yes</td> 294 * </tr> 295 * <tr> 296 * <td>codeSegSymbol</td> 297 * <td> Inserts an error resilience segmentation symbol in the MQ codeword 298 * at the end of each bit-plane (cleanup pass). Decoders can use this 299 * information to detect and conceal errors. true enables, and false 300 * disables it. The default value is false. 301 * </td> 302 * <td>Yes</td> 303 * </tr> 304 * <tr> 305 * <td>methodForMQTermination</td> 306 * <td> Specifies the algorithm used to terminate the MQ codeword. The 307 * most efficient one is "near_opt", which delivers a codeword which 308 * in almost all cases is the shortest possible. The "easy" is a 309 * simpler algorithm that delivers a codeword length that is close 310 * to the previous one (in average 1 bit longer). The "predict" is 311 * almost the same as the "easy" but it leaves error resilient 312 * information on the spare least significant bits (in average 3.5 bits), 313 * which can be used by a decoder to detect errors. The "full" algorithm 314 * performs a full flush of the MQ coder and is highly inefficient. It 315 * is important to use a good termination policy since the MQ codeword 316 * can be terminated quite often, specially if the "bypass" or 317 * "terminateOnByte" parameters are enabled (in the normal case it would 318 * be terminated once per code-block, while "terminateOnByte" is specified 319 * it will be done almost 3 times per bit-plane in each code-block). 320 * The default value is "near_opt". 321 * </td> 322 * <td>Yes</td> 323 * </tr> 324 * <tr> 325 * <td>methodForMQLengthCalc</td> 326 * <td> Specifies the algorithm to use in calculating the necessary MQ 327 * length for each decoding pass. The best one is "near_opt", which 328 * performs a rather sophisticated calculation and provides the best 329 * results. The "lazy_good" and "lazy" are very simple algorithms 330 * that provide rather conservative results. "lazy_good" performs 331 * slightly better. Please use the default unless the experiments 332 * show the benefits of different length calculation algorithms. 333 * The default value is "near_opt". 334 * </td> 335 * <td>Yes</td> 336 * </tr> 337 * <tr> 338 * <td>precinctPartition</td> 339 * <td> Specifies precinct partition dimensions for tiles/components. They 340 * are stored from those applied to the highest resolution to those 341 * applied to the remaining resolutions in decreasing order. If less 342 * values than the number of decomposition levels are specified, then 343 * the last two values are used for the remaining resolutions. 344 * </td> 345 * <td>Yes</td> 346 * </tr> 347 * <tr> 348 * <td>layers</td> 349 * <td> Explicitly specifies the codestream layer formation parameters. 350 * The rate (double) parameter specifies the bitrate to which the first 351 * layer should be optimized. The layers (int) parameter, if present, 352 * specifies the number of extra layers that should be added for 353 * scalability. These extra layers are not optimized. Any extra rate 354 * and layers parameters add more layers, in the same way. An 355 * additional layer is always added at the end, which is optimized 356 * to the overall target bitrate of the bit stream. Any layers 357 * (optimized or not) whose target bitrate is higher that the overall 358 * target bitrate are silently ignored. The bitrates of the extra layers 359 * that are added through the layers parameter are approximately 360 * log-spaced between the other target bitrates. If several (rate, layers) 361 * constructs appear the rate parameters must appear in increasing order. 362 * The rate allocation algorithm ensures that all coded layers have a 363 * minimal reasonable size, if not these layers are silently ignored. 364 * Default: 0.015 +20 2.0 +10. 365 * </td> 366 * <td>No</td> 367 * </tr> 368 * <tr> 369 * <td>SOP</td> 370 * <td>Specifies whether start of packet (SOP) markers should be used. 371 * true enables, false disables it. The default value is false. 372 * </td> 373 * <td>Yes</td> 374 * </tr> 375 * <tr> 376 * <td>EPH</td> 377 * <td>Specifies whether end of packet header (EPH) markers should be used. 378 * true enables, false disables it. The default value is false. 379 * </td> 380 * <td>Yes</td> 381 * </tr> 382 * </table> 383 */ 384public class J2KImageWriteParamJava extends ImageWriteParam { 385 /** 386 * Indicates that the packet headers are packed in the tiles' headers. 387 */ 388 private boolean packPacketHeaderInTile = false; 389 390 /** 391 * Indicates that the packet headers are packed in the main header. 392 */ 393 private boolean packPacketHeaderInMain = false; 394 395 /** 396 * Specifies the maximum number of packets to be put into one tile-part. 397 * Zero means include all packets in first tile-part of each tile. 398 */ 399 private int packetPerTilePart = 0; 400 401 /** 402 * The bitrate in bits-per-pixel for encoding. Should be set when lossy 403 * compression scheme is used. The default is 404 * <code>Double.MAX_VALUE</code>. 405 */ 406 private double encodingRate = Double.MAX_VALUE; 407 408 /** 409 * Indicates using the loseless scheme or not. It is equivalent to 410 * use reversible quantization and 5x3 integer wavelet filters. 411 */ 412 private boolean lossless = true; 413 414 /** Specifies to utilize the component transformation with some tiles. 415 * If the wavelet transform is reversible (w5x3 filter), the 416 * Reversible Component Transformation (RCT) is applied. If not reversible 417 * (w9x7 filter), the Irreversible Component Transformation (ICT) 418 * is used. 419 */ 420 private ForwCompTransfSpec componentTransformation = null; 421 private boolean enableCT = true; 422 423 /** Specifies which filters to use for the specified tile-components. 424 * JPEG 2000 part I only supports w5x3 and w9x7 filters. 425 */ 426 private AnWTFilterSpec filters = null; 427 428 /** Specifies the number of wavelet decomposition levels to apply to 429 * the image. If it is 0, no wavelet transform is performed, in which 430 * case the original image data will be sent to the encoder and an 431 * example is the binary data. All components and all tiles have 432 * the same number of decomposition levels. Default: 5. 433 */ 434 private IntegerSpec decompositionLevel = null; // = 5; 435 436 /** The number of bits used for each tile-component in 437 * the quantizer to avoid overflow. It takes values in the range 0 438 * through 7. Default: 2. 439 */ 440 private GuardBitsSpec guardBits = null; 441 442 /** This parameter specifies the base normalized quantization step 443 * size for the tiles/components. It is normalized to a dynamic range 444 * of 1 in the image domain. This parameter is ignored in reversible 445 * coding. Default: 0.0078125. 446 */ 447 private QuantStepSizeSpec quantizationStep = null; 448 449 /** Specifies which quantization type to use for specified 450 * tiles/components. Not specified for lossless compression. By 451 * default , the quantization step size is "expounded". Supported 452 * quantization types specification are : "reversible" (no quantization), 453 * "derived" (derived quantization step size) and "expounded". 454 */ 455 private QuantTypeSpec quantizationType = null; 456 457 /** This parameter defines the lowest resolution levels to belong to 458 * the ROI. By doing this, it is possible to avoid only getting 459 * information for the ROI at an early stage of transmission. 460 * startLevelROI = 0 means the lowest resolution level belongs to 461 * the ROI, 1 means the second lowest etc. The default values, -1, 462 * deactivates this parameter. 463 */ 464 private int startLevelROI = -1; 465 466 /** By specifying this parameter, the ROI mask will be limited to 467 * covering only entire code-blocks. The ROI coding can then be 468 * performed without any actual scaling of the coefficients but 469 * by instead scaling the distortion estimates. 470 */ 471 private boolean alignROI = false; 472 473 /** Specifies ROIs shape and location. The component index specifies 474 * which components contain the ROI. If this parameter is used, the 475 * codestream is layer progressive by default unless it is 476 * overridden by the <code>progressionType</code>. 477 */ 478 private MaxShiftSpec ROIs = null; 479 480 /** Specifies the maximum code-block size to use for tile-component. 481 * The maximum width and height is 1024, however the image area 482 * (i.e. width x height) must not exceed 4096. The minimum 483 * width and height is 4. Default: 64 64. 484 */ 485 private CBlkSizeSpec codeBlockSize = null; 486 487 /** Uses the lazy coding mode with the entropy coder. This will bypass 488 * the MQ coder for some of the coding passes, where the distribution 489 * is often close to uniform. Since the MQ codeword will be terminated 490 * at least once per lazy pass, it is important to use an efficient 491 * termination algorithm, <code>methodForMQTermination</code>. 492 * true enables, and false disables it. Default: false. 493 */ 494 private StringSpec bypass = null; 495 496 /** If this is enabled the probability estimates of the MQ coder are 497 * reset after each arithmetically coded (i.e. non-lazy) coding pass. 498 * true enables, and false disables it. Default: false. 499 */ 500 private StringSpec resetMQ = null; 501 502 /** If this is enabled the codeword (raw or MQ) is terminated on a byte 503 * boundary after each coding pass. In this case it is important to 504 * use an efficient termination algorithm, the "methodForMQTermination". 505 * true enables, and false disables it. Default: false. 506 */ 507 private StringSpec terminateOnByte = null; 508 509 /** Uses vertically stripe causal context formation. If this is 510 * enabled the context formation process in one stripe is independant 511 * of the next stripe (i.e. the one below it). true enables, and 512 * false disables it. Default: false. 513 */ 514 private StringSpec causalCXInfo = null; 515 516 /** Inserts an error resilience segmentation symbol in the MQ codeword 517 * at the end of each bit-plane (cleanup pass). Decoders can use this 518 * information to detect and conceal errors. true enables, 519 * and false disables it. Default: false. 520 */ 521 private StringSpec codeSegSymbol = null; 522 523 /** Specifies the algorithm used to terminate the MQ codeword. The 524 * most efficient one is "near_opt", which delivers a codeword which 525 * in almost all cases is the shortest possible. The "easy" is a 526 * simpler algorithm that delivers a codeword length that is close 527 * to the previous one (in average 1 bit longer). The "predict" is 528 * almost the same as the "easy" but it leaves error resilient 529 * information on the spare least significant bits (in average 530 * 3.5 bits), which can be used by a decoder to detect errors. 531 * The "full" algorithm performs a full flush of the MQ coder and 532 * is highly inefficient. It is important to use a good termination 533 * policy since the MQ codeword can be terminated quite often, 534 * specially if the "bypass" or "terminateOnByte" parameters are 535 * enabled (in the normal case it would be terminated once per 536 * code-block, while "terminateOnByte" is specified it will be 537 * done almost 3 times per bit-plane in each code-block). 538 * Default: near_opt. 539 */ 540 private StringSpec methodForMQTermination = null; 541 542 /** Specifies the algorithm to use in calculating the necessary MQ 543 * length for each decoding pass. The best one is "near_opt", which 544 * performs a rather sophisticated calculation and provides the best 545 * results. The "lazy_good" and "lazy" are very simple algorithms 546 * that provide rather conservative results. "lazy_good" performs 547 * slightly better. Please use the default unless the experiments 548 * show the benefits of different length calculation algorithms. 549 * Default: near_opt. 550 */ 551 private StringSpec methodForMQLengthCalc = null; 552 553 /** Specifies precinct partition dimensions for tiles/components. They 554 * are stored from those applied to the highest resolution to those 555 * applied to the remaining resolutions in decreasing order. If less 556 * values than the number of decomposition levels are specified, then 557 * the last two values are used for the remaining resolutions. 558 */ 559 private PrecinctSizeSpec precinctPartition = null; 560 561 /** Specifies which type of progression should be used when generating 562 * the codestream. The value "res" generates a resolution progressive 563 * codestream with the number of layers specified by "layers" parameter. 564 * The value "layer" generates a layer progressive codestream with 565 * multiple layers. In any case, the rate-allocation algorithm optimizes 566 * for best quality in each layer. The quality measure is mean squared 567 * error (MSE) or a weighted version of it (WMSE). If no progression 568 * type is specified or imposed by other modules, the default value 569 * is "layer". It is also possible to describe progression order 570 * changes. In this case, "res_start" is the index (from 0) of the 571 * first resolution level, "comp_start" is the index (from 0) of the 572 * first component, "ly_end" is the index (from 0) of the first layer 573 * not included, "res_end" is the index (from 0) of the first 574 * resolution level not included, "comp_end" is index (from 0) of 575 * the first component not included and "prog" is the progression type 576 * to be used for the rest of the tile/image. Several progression 577 * order changes can be specified, one after the other. 578 */ 579 private ProgressionSpec progressionType = null; 580 581 /** 582 * The specified (tile-component) progression. Will be used to generate 583 * the progression type. 584 */ 585 private String progressionName = null; 586 587 /** Explicitly specifies the codestream layer formation parameters. 588 * The rate (double) parameter specifies the bitrate to which the first 589 * layer should be optimized. The layers (int) parameter, if present, 590 * specifies the number of extra layers that should be added for 591 * scalability. These extra layers are not optimized. Any extra rate 592 * and layers parameters add more layers, in the same way. An 593 * additional layer is always added at the end, which is optimized 594 * to the overall target bitrate of the bit stream. Any layers 595 * (optimized or not) whose target bitrate is higher that the 596 * overall target bitrate are silently ignored. The bitrates of 597 * the extra layers that are added through the layers parameter 598 * are approximately log-spaced between the other target bitrates. 599 * If several (rate, layers) constructs appear the rate parameters 600 * must appear in increasing order. The rate allocation algorithm 601 * ensures that all coded layers have a minimal reasonable size, 602 * if not these layers are silently ignored. Default: 0.015 +20 2.0 +10. 603 */ 604 private String layers = "0.015 +20 2.0 +10"; 605 606 /** Specifies whether end of packet header (EPH) markers should be used. 607 * true enables, false disables it. Default: false. 608 */ 609 private StringSpec EPH = null; 610 611 /** Specifies whether start of packet (SOP) markers should be used. 612 * true enables, false disables it. Default: false. 613 */ 614 private StringSpec SOP = null; 615 616 private int numTiles; 617 private int numComponents; 618 619 private RenderedImage imgsrc; 620 private Raster raster; 621 622 private int minX; 623 private int minY; 624 625 /** Constructor to set locales. */ 626 public J2KImageWriteParamJava(RenderedImage imgsrc, Locale locale) { 627 super(locale); 628 setDefaults(imgsrc); 629 } 630 631 /** Constructor to set locales. */ 632 public J2KImageWriteParamJava(IIOImage image, ImageWriteParam param) { 633 super(param.getLocale()); 634 if(image != null) { 635 if (image.hasRaster()) 636 setDefaults(image.getRaster()); 637 else 638 setDefaults(image.getRenderedImage()); 639 } 640 641 setSourceRegion(param.getSourceRegion()); 642 setSourceBands(param.getSourceBands()); 643 try { 644 setTiling(param.getTileWidth(), param.getTileHeight(), 645 param.getTileGridXOffset(), param.getTileGridYOffset()); 646 } catch (IllegalStateException e) { 647 // tileing is not set do nothing. 648 } 649 650 setDestinationOffset(param.getDestinationOffset()); 651 setSourceSubsampling(param.getSourceXSubsampling(), 652 param.getSourceYSubsampling(), 653 param.getSubsamplingXOffset(), 654 param.getSubsamplingYOffset()); 655 setDestinationType(param.getDestinationType()); 656 657 J2KImageWriteParam j2kParam; 658 if(param instanceof J2KImageWriteParam) { 659 j2kParam = (J2KImageWriteParam)param; 660 } else { 661 j2kParam = new J2KImageWriteParam(); 662 } 663 664 setDecompositionLevel(""+j2kParam.getNumDecompositionLevels()); 665 setEncodingRate(j2kParam.getEncodingRate()); 666 setLossless(j2kParam.getLossless()); 667 setFilters(j2kParam.getFilter()); 668 setEPH("" + j2kParam.getEPH()); 669 setSOP("" + j2kParam.getSOP()); 670 setProgressionName(j2kParam.getProgressionType()); 671 int[] size = j2kParam.getCodeBlockSize(); 672 setCodeBlockSize("" + size[0] +" " + size[1]); 673 enableCT = j2kParam.getComponentTransformation(); 674 setComponentTransformation("" + enableCT); 675 } 676 677 678 /** 679 * Constructs a <code>J2KImageWriteParamJava</code> object with default 680 * values for all parameters. 681 */ 682 public J2KImageWriteParamJava() { 683 super(); 684 setSuperProperties(); 685 } 686 687 /** 688 * Constructs a <code>J2KImageWriteParamJava</code> object with default 689 * values for all parameters. 690 */ 691 public J2KImageWriteParamJava(RenderedImage imgsrc) { 692 super(); 693 setDefaults(imgsrc); 694 } 695 696 /** 697 * Constructs a <code>J2KImageWriteParamJava</code> object with default 698 * values for all parameters. 699 */ 700 public J2KImageWriteParamJava(Raster raster) { 701 super(); 702 setDefaults(raster); 703 } 704 705 private void setSuperProperties() { 706 canOffsetTiles = true; 707 canWriteTiles = true; 708 canOffsetTiles = true; 709 canWriteProgressive = true; 710 tilingMode = MODE_EXPLICIT; 711 } 712 713 /** Set source */ 714 private void setDefaults(Raster raster) { 715 // override the params in the super class 716 setSuperProperties(); 717 718 if (raster != null) { 719 this.raster = raster; 720 tileGridXOffset = raster.getMinX(); 721 tileGridYOffset = raster.getMinY(); 722 tileWidth = raster.getWidth(); 723 tileHeight = raster.getHeight(); 724 tilingSet = true; 725 726 numTiles = 1; 727 numComponents = raster.getSampleModel().getNumBands(); 728 } 729 setDefaults(); 730 } 731 732 /** Set source */ 733 private void setDefaults(RenderedImage imgsrc) { 734 // override the params in the super class 735 setSuperProperties(); 736 737 tilingMode = MODE_EXPLICIT; 738 739 if (imgsrc != null) { 740 this.imgsrc = imgsrc; 741 tileGridXOffset = imgsrc.getTileGridXOffset(); 742 tileGridYOffset = imgsrc.getTileGridYOffset(); 743 tileWidth = imgsrc.getTileWidth(); 744 tileHeight = imgsrc.getTileHeight(); 745 tilingSet = true; 746 747 numTiles = imgsrc.getNumXTiles() * imgsrc.getNumYTiles(); 748 numComponents = imgsrc.getSampleModel().getNumBands(); 749 } 750 setDefaults(); 751 } 752 753 private void setDefaults() { 754 setROIs(null); 755 setQuantizationType(null); 756 setQuantizationStep(null); 757 setGuardBits(null); 758 setFilters(null); 759 setDecompositionLevel(null); 760 setComponentTransformation(null); 761 setMethodForMQLengthCalc(null); 762 setMethodForMQTermination(null); 763 setCodeSegSymbol(null); 764 setCausalCXInfo(null); 765 setTerminateOnByte(null); 766 setResetMQ(null); 767 setBypass(null); 768 setCodeBlockSize(null); 769 setPrecinctPartition(null); 770 setSOP(null); 771 setEPH(null); 772 } 773 774 /** Sets <code>encodingRate</code> */ 775 public void setEncodingRate(double rate) { 776 this.encodingRate = rate; 777 } 778 779 /** Gets <code>encodingRate</code> */ 780 public double getEncodingRate() { 781 return encodingRate; 782 } 783 784 /** Sets <code>lossless</code> */ 785 public void setLossless(boolean lossless) { 786 this.lossless = lossless; 787 } 788 789 /** Gets <code>encodingRate</code> */ 790 public boolean getLossless() { 791 return lossless; 792 } 793 /** Sets <code>packetPerTilePart</code> */ 794 public void setPacketPerTilePart(int packetPerTilePart) { 795 if (packetPerTilePart < 0) 796 throw new IllegalArgumentException(I18N.getString("J2KImageWriteParamJava0")); 797 798 this.packetPerTilePart = packetPerTilePart; 799 if (packetPerTilePart > 0) { 800 setSOP("true"); 801 setEPH("true"); 802 } 803 } 804 805 /** Gets <code>packetPerTilePart</code> */ 806 public int getPacketPerTilePart() { 807 return packetPerTilePart; 808 } 809 810 /** Sets <code>packPacketHeaderInTile</code> */ 811 public void setPackPacketHeaderInTile(boolean packPacketHeaderInTile) { 812 this.packPacketHeaderInTile = packPacketHeaderInTile; 813 if (packPacketHeaderInTile) { 814 setSOP("true"); 815 setEPH("true"); 816 } 817 } 818 819 /** Gets <code>packPacketHeaderInTile</code> */ 820 public boolean getPackPacketHeaderInTile() { 821 return packPacketHeaderInTile; 822 } 823 824 /** Sets <code>packPacketHeaderInMain</code> */ 825 public void setPackPacketHeaderInMain(boolean packPacketHeaderInMain) { 826 this.packPacketHeaderInMain = packPacketHeaderInMain; 827 if (packPacketHeaderInMain) { 828 setSOP("true"); 829 setEPH("true"); 830 } 831 } 832 833 /** Gets <code>packPacketHeaderInMain</code> */ 834 public boolean getPackPacketHeaderInMain() { 835 return packPacketHeaderInMain; 836 } 837 838 /** Sets <code>alignROI</code> */ 839 public void setAlignROI(boolean align) { 840 alignROI = align; 841 } 842 843 /** Gets <code>alignROI</code> */ 844 public boolean getAlignROI() { 845 return alignROI; 846 } 847 848 /** Sets <code>ROIs</code> */ 849 public void setROIs(String values) { 850 ROIs = new MaxShiftSpec(numTiles, numComponents, ModuleSpec.SPEC_TYPE_TILE_COMP, values); 851 } 852 853 /** Gets <code>ROIs</code> */ 854 public MaxShiftSpec getROIs() { 855 return ROIs; 856 } 857 858 /** Sets <code>quantizationType</code> */ 859 public void setQuantizationType(String values) { 860 quantizationType = new QuantTypeSpec(numTiles, numComponents, 861 ModuleSpec.SPEC_TYPE_TILE_COMP, this, values); 862 } 863 864 /** Gets <code>quantizationType</code> */ 865 public QuantTypeSpec getQuantizationType() { 866 return quantizationType; 867 } 868 869 /** Sets <code>quantizationStep</code> */ 870 public void setQuantizationStep(String values) { 871 quantizationStep = new QuantStepSizeSpec(numTiles, 872 numComponents, 873 ModuleSpec.SPEC_TYPE_TILE_COMP, 874 this, 875 values); 876 } 877 878 /** Gets <code>quantizationStep</code> */ 879 public QuantStepSizeSpec getQuantizationStep() { 880 return quantizationStep; 881 } 882 883 /** Sets <code>guardBits</code> */ 884 public void setGuardBits(String values) { 885 guardBits = new GuardBitsSpec(numTiles, 886 numComponents, 887 ModuleSpec.SPEC_TYPE_TILE_COMP, 888 this, 889 values); 890 } 891 892 /** Gets <code>guardBits</code> */ 893 public GuardBitsSpec getGuardBits() { 894 return guardBits; 895 } 896 897 /** Sets <code>filters</code> */ 898 // NOTE This also sets quantizationType and componentTransformation. 899 public void setFilters(String values) { 900 if (J2KImageWriteParam.FILTER_97.equals(values)) 901 setQuantizationType ("expounded"); 902 else 903 setQuantizationType("reversible"); 904 905 filters = new AnWTFilterSpec(numTiles, 906 numComponents, 907 ModuleSpec.SPEC_TYPE_TILE_COMP, 908 (QuantTypeSpec)quantizationType, 909 this, 910 values); 911 setComponentTransformation(""+enableCT); 912 } 913 914 /** Gets <code>filters</code> */ 915 public AnWTFilterSpec getFilters() { 916 return filters; 917 } 918 919 /** Sets <code>decompositionLevel</code> */ 920 public void setDecompositionLevel(String values) { 921 decompositionLevel = new IntegerSpec(numTiles, 922 numComponents, 923 ModuleSpec.SPEC_TYPE_TILE_COMP, 924 this, 925 values, 926 "5"); 927 928 // NOTE The precinctPartition depends upon decompositionLevel 929 // so it needs to be re-initialized. Note that the parameter of 930 // setPrecinctPartition() is not used in the current implementation. 931 setPrecinctPartition(null); 932 } 933 934 /** Gets <code>decompositionLevel</code> */ 935 public IntegerSpec getDecompositionLevel() { 936 return decompositionLevel; 937 } 938 939 /** Sets <code>componentTransformation</code> */ 940 // NOTE This requires filters having been set previously. 941 public void setComponentTransformation(String values) { 942 componentTransformation = 943 new ForwCompTransfSpec(numTiles, 944 numComponents, 945 ModuleSpec.SPEC_TYPE_TILE, 946 (AnWTFilterSpec)filters, 947 this, 948 values); 949 } 950 951 /** Gets <code>componentTransformation</code> */ 952 public ForwCompTransfSpec getComponentTransformation() { 953 return componentTransformation; 954 } 955 /** Sets <code>methodForMQLengthCalc</code> */ 956 public void setMethodForMQLengthCalc(String values) { 957 String[] strLcs = {"near_opt","lazy_good","lazy"}; 958 methodForMQLengthCalc = 959 new StringSpec(numTiles, 960 numComponents, 961 ModuleSpec.SPEC_TYPE_TILE_COMP, 962 "near_opt", 963 strLcs, 964 this, 965 values); 966 } 967 968 /** Gets <code>methodForMQLengthCalc</code> */ 969 public StringSpec getMethodForMQLengthCalc() { 970 return methodForMQLengthCalc; 971 } 972 973 /** Sets <code>methodForMQTermination</code> */ 974 public void setMethodForMQTermination(String values) { 975 String[] strTerm = {"near_opt","easy","predict","full"}; 976 methodForMQTermination = 977 new StringSpec(numTiles, 978 numComponents, 979 ModuleSpec.SPEC_TYPE_TILE_COMP, 980 "near_opt", 981 strTerm, 982 this, 983 values); 984 } 985 986 /** Gets <code>methodForMQTermination</code> */ 987 public StringSpec getMethodForMQTermination() { 988 return methodForMQTermination; 989 } 990 991 /** Sets <code>codeSegSymbol</code> */ 992 public void setCodeSegSymbol(String values) { 993 String[] strBoolean = {"true","false"}; 994 codeSegSymbol = 995 new StringSpec(numTiles, 996 numComponents, 997 ModuleSpec.SPEC_TYPE_TILE_COMP, 998 "false", 999 strBoolean, 1000 this, 1001 values); 1002 } 1003 1004 /** Gets <code>codeSegSymbol</code> */ 1005 public StringSpec getCodeSegSymbol() { 1006 return codeSegSymbol; 1007 } 1008 1009 /** Sets <code>causalCXInfo</code> */ 1010 public void setCausalCXInfo(String values) { 1011 String[] strBoolean = {"true","false"}; 1012 causalCXInfo = new StringSpec(numTiles, 1013 numComponents, 1014 ModuleSpec.SPEC_TYPE_TILE_COMP, 1015 "false", 1016 strBoolean, 1017 this, 1018 values); 1019 } 1020 1021 /** Gets <code>causalCXInfo</code> */ 1022 public StringSpec getCausalCXInfo() { 1023 return causalCXInfo; 1024 } 1025 1026 /** Sets <code>terminateOnByte</code> */ 1027 public void setTerminateOnByte(String values) { 1028 String[] strBoolean = {"true","false"}; 1029 terminateOnByte = new StringSpec(numTiles, 1030 numComponents, 1031 ModuleSpec.SPEC_TYPE_TILE_COMP, 1032 "false", 1033 strBoolean, 1034 this, 1035 values); 1036 } 1037 1038 /** Gets <code>terminateOnByte</code> */ 1039 public StringSpec getTerminateOnByte() { 1040 return terminateOnByte; 1041 } 1042 1043 /** Sets <code>resetMQ</code> */ 1044 public void setResetMQ(String values) { 1045 String[] strBoolean = {"true","false"}; 1046 resetMQ = new StringSpec(numTiles, 1047 numComponents, 1048 ModuleSpec.SPEC_TYPE_TILE_COMP, 1049 "false", 1050 strBoolean, 1051 this, 1052 values); 1053 } 1054 1055 /** Gets <code>resetMQ</code> */ 1056 public StringSpec getResetMQ() { 1057 return resetMQ; 1058 } 1059 1060 /** Sets <code>bypass</code> */ 1061 public void setBypass(String values) { 1062 String[] strBoolean = {"true","false"}; 1063 bypass = new StringSpec(numTiles, 1064 numComponents, 1065 ModuleSpec.SPEC_TYPE_TILE_COMP, 1066 "false", 1067 strBoolean, 1068 this, 1069 values); 1070 } 1071 1072 /** Gets <code>bypass</code> */ 1073 public StringSpec getBypass() { 1074 return bypass; 1075 } 1076 1077 /** Sets <code>codeBlockSize</code> */ 1078 public void setCodeBlockSize(String values) { 1079 codeBlockSize = new CBlkSizeSpec(numTiles, 1080 numComponents, 1081 ModuleSpec.SPEC_TYPE_TILE_COMP, 1082 this, 1083 values); 1084 } 1085 1086 /** Gets <code>codeBlockSize</code> */ 1087 public CBlkSizeSpec getCodeBlockSize() { 1088 return codeBlockSize; 1089 } 1090 1091 /** Sets <code>precinctPartition</code> */ 1092 public void setPrecinctPartition(String values) { 1093 String[] strBoolean = {"true","false"}; 1094 if (imgsrc != null) 1095 precinctPartition = 1096 new PrecinctSizeSpec(numTiles, 1097 numComponents, 1098 ModuleSpec.SPEC_TYPE_TILE_COMP, 1099 new RenderedImageSrc(imgsrc, this, null), 1100 decompositionLevel, 1101 this, 1102 values); 1103 else if (raster != null) 1104 precinctPartition = 1105 new PrecinctSizeSpec(numTiles, 1106 numComponents, 1107 ModuleSpec.SPEC_TYPE_TILE_COMP, 1108 new RenderedImageSrc(raster, this, null), 1109 decompositionLevel, 1110 this, 1111 values); 1112 } 1113 1114 /** Gets <code>precinctPartition</code> */ 1115 public PrecinctSizeSpec getPrecinctPartition() { 1116 return precinctPartition; 1117 } 1118 1119 /** Sets <code>SOP</code> */ 1120 public void setSOP(String values) { 1121 String[] strBoolean = {"true","false"}; 1122 SOP = new StringSpec(numTiles, 1123 numComponents, 1124 ModuleSpec.SPEC_TYPE_TILE_COMP, 1125 "false", 1126 strBoolean, 1127 this, 1128 values); 1129 } 1130 1131 /** Gets <code>SOP</code> */ 1132 public StringSpec getSOP() { 1133 return SOP; 1134 } 1135 1136 /** Sets <code>EPH</code> */ 1137 public void setEPH(String values) { 1138 String[] strBoolean = {"true","false"}; 1139 EPH = new StringSpec(numTiles, 1140 numComponents, 1141 ModuleSpec.SPEC_TYPE_TILE_COMP, 1142 "false", 1143 strBoolean, 1144 this, 1145 values); 1146 } 1147 1148 /** Gets <code>EPH</code> */ 1149 public StringSpec getEPH() { 1150 return EPH; 1151 } 1152 1153 /** Sets <code>progressionName</code> */ 1154 public void setProgressionName(String values) { 1155 progressionName = values; 1156 } 1157 1158 /** Gets <code>progressionType</code> */ 1159 public String getProgressionName() { 1160 return progressionName; 1161 } 1162 1163 /** Sets <code>progressionType</code> */ 1164 public void setProgressionType(LayersInfo lyrs, String values) { 1165 String[] strBoolean = {"true","false"}; 1166 progressionType = new ProgressionSpec(numTiles, 1167 numComponents, 1168 lyrs.getTotNumLayers(), 1169 decompositionLevel, 1170 ModuleSpec.SPEC_TYPE_TILE_COMP, 1171 this, 1172 values); 1173 } 1174 1175 /** Gets <code>progressionType</code> */ 1176 public ProgressionSpec getProgressionType() { 1177 return progressionType; 1178 } 1179 1180 /** Sets the <code>startLevelROI</code> */ 1181 public void setStartLevelROI(int value) { 1182 startLevelROI = value; 1183 } 1184 1185 /** Gets <code>startLevel</code> */ 1186 public int getStartLevelROI() { 1187 return startLevelROI; 1188 } 1189 1190 /** Sets the <code>layers</code> */ 1191 public void setLayers(String value) { 1192 layers = value; 1193 } 1194 1195 /** Gets <code>layers</code> */ 1196 public String getLayers() { 1197 return layers; 1198 } 1199 1200 /** Sets <code>minX</code> */ 1201 public void setMinX(int minX) { 1202 this.minX = minX; 1203 } 1204 1205 /** Gets <code>minX</code> */ 1206 public int getMinX() { 1207 return minX; 1208 } 1209 1210 /** Sets <code>minY</code> */ 1211 public void setMinY(int minY) { 1212 this.minY = minY; 1213 } 1214 1215 /** Gets <code>minY</code> */ 1216 public int getMinY() { 1217 return minY; 1218 } 1219 1220 /** Gets the number of tiles */ 1221 public int getNumTiles() { 1222 Rectangle sourceRegion = getSourceRegion(); 1223 if (sourceRegion == null) { 1224 if (imgsrc != null) 1225 sourceRegion = new Rectangle(imgsrc.getMinX(), 1226 imgsrc.getMinY(), 1227 imgsrc.getWidth(), 1228 imgsrc.getHeight()); 1229 else sourceRegion = raster.getBounds(); 1230 } else { 1231 if (imgsrc != null) 1232 sourceRegion = 1233 sourceRegion.intersection(new Rectangle(imgsrc.getMinX(), 1234 imgsrc.getMinY(), 1235 imgsrc.getWidth(), 1236 imgsrc.getHeight())); 1237 else sourceRegion = sourceRegion.intersection(raster.getBounds()); 1238 } 1239 1240 int scaleX = getSourceXSubsampling(); 1241 int scaleY = getSourceYSubsampling(); 1242 int xOffset = getSubsamplingXOffset(); 1243 int yOffset = getSubsamplingYOffset(); 1244 1245 int w = (sourceRegion.width - xOffset + scaleX - 1) / scaleX; 1246 int h = (sourceRegion.height - yOffset + scaleY - 1) / scaleY; 1247 1248 minX = (sourceRegion.x + xOffset) / scaleX; 1249 minY = (sourceRegion.y + yOffset) / scaleY; 1250 1251 numTiles = (int)((Math.floor((minX + w + tileWidth - 1.0) / tileWidth) - 1252 Math.floor((double)minX/tileWidth) ) * 1253 (Math.floor((minY + h + tileHeight - 1.0) / tileHeight) - 1254 Math.floor((double)minY/tileHeight) ) ); 1255 tileGridXOffset += (minX - tileGridXOffset) / tileWidth * tileWidth; 1256 tileGridYOffset += (minY - tileGridYOffset) / tileHeight * tileHeight; 1257 1258 return numTiles; 1259 } 1260 1261 /** Gets the number of components */ 1262 public int getNumComponents() { 1263 return numComponents; 1264 } 1265 1266 /** Override the method setSourceBands in the super class. This method 1267 * should be called before any tile-specific parameter setting method 1268 * to be called. 1269 */ 1270 public void setSourceBands(int[] bands) { 1271 super.setSourceBands(bands); 1272 if (bands != null) { 1273 numComponents = bands.length; 1274 setDefaults(); 1275 } 1276 } 1277 1278 /** Override the method setTiling in the super class. This method 1279 * should be called before any tile-specific parameter setting method 1280 * to be called. 1281 */ 1282 public void setTiling(int tw, int th, int xOff, int yOff) { 1283 super.setTiling(tw, th, xOff, yOff); 1284 getNumTiles(); 1285 setDefaults(); 1286 } 1287 1288 /** Override the method setSourceSubsampling in the super class. This 1289 * method should be called before any tile-specific parameter setting 1290 * method to be called. 1291 */ 1292 public void setSourceSubsampling(int sx, int sy, int xOff, int yOff) { 1293 super.setSourceSubsampling(sx, sy, xOff, yOff); 1294 getNumTiles(); 1295 setDefaults(); 1296 } 1297}