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