14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.imageio; 27 28 import java.awt.Dimension; 29 import java.awt.image.BufferedImage; 30 31 /** 32 * A class describing how a stream is to be decoded. Instances of 33 * this class or its subclasses are used to supply prescriptive 34 * "how-to" information to instances of <code>ImageReader</code>. 35 * 36 * <p> An image encoded as part of a file or stream may be thought of 37 * extending out in multiple dimensions: the spatial dimensions of 38 * width and height, a number of bands, and a number of progressive 39 * decoding passes. This class allows a contiguous (hyper)rectangular 40 * subarea of the image in all of these dimensions to be selected for 41 * decoding. Additionally, the spatial dimensions may be subsampled 42 * discontinuously. Finally, color and format conversions may be 43 * specified by controlling the <code>ColorModel</code> and 44 * <code>SampleModel</code> of the destination image, either by 45 * providing a <code>BufferedImage</code> or by using an 46 * <code>ImageTypeSpecifier</code>. 47 * 48 * <p> An <code>ImageReadParam</code> object is used to specify how an 49 * image, or a set of images, will be converted on input from 50 * a stream in the context of the Java Image I/O framework. A plug-in for a 51 * specific image format will return instances of 52 * <code>ImageReadParam</code> from the 53 * <code>getDefaultReadParam</code> method of its 54 * <code>ImageReader</code> implementation. 55 * 56 * <p> The state maintained by an instance of 57 * <code>ImageReadParam</code> is independent of any particular image 58 * being decoded. When actual decoding takes place, the values set in 59 * the read param are combined with the actual properties of the image 60 * being decoded from the stream and the destination 61 * <code>BufferedImage</code> that will receive the decoded pixel 62 * data. For example, the source region set using 63 * <code>setSourceRegion</code> will first be intersected with the 64 * actual valid source area. The result will be translated by the 65 * value returned by <code>getDestinationOffset</code>, and the 66 * resulting rectangle intersected with the actual valid destination 67 * area to yield the destination area that will be written. 68 * 69 * <p> The parameters specified by an <code>ImageReadParam</code> are 70 * applied to an image as follows. First, if a rendering size has 71 * been set by <code>setSourceRenderSize</code>, the entire decoded 72 * image is rendered at the size given by 73 * <code>getSourceRenderSize</code>. Otherwise, the image has its 74 * natural size given by <code>ImageReader.getWidth</code> and 75 * <code>ImageReader.getHeight</code>. 76 * 77 * <p> Next, the image is clipped against the source region 78 * specified by <code>getSourceXOffset</code>, <code>getSourceYOffset</code>, 79 * <code>getSourceWidth</code>, and <code>getSourceHeight</code>. 80 * 81 * <p> The resulting region is then subsampled according to the 82 * factors given in {@link IIOParam#setSourceSubsampling 83 * IIOParam.setSourceSubsampling}. The first pixel, 84 * the number of pixels per row, and the number of rows all depend 85 * on the subsampling settings. 86 * Call the minimum X and Y coordinates of the resulting rectangle 87 * (<code>minX</code>, <code>minY</code>), its width <code>w</code> 88 * and its height <code>h</code>. 89 * 90 * <p> This rectangle is offset by 91 * (<code>getDestinationOffset().x</code>, 92 * <code>getDestinationOffset().y</code>) and clipped against the 93 * destination bounds. If no destination image has been set, the 94 * destination is defined to have a width of 95 * <code>getDestinationOffset().x</code> + <code>w</code>, and a 96 * height of <code>getDestinationOffset().y</code> + <code>h</code> so 97 * that all pixels of the source region may be written to the 98 * destination. 99 * 100 * <p> Pixels that land, after subsampling, within the destination 101 * image, and that are written in one of the progressive passes 102 * specified by <code>getSourceMinProgressivePass</code> and 103 * <code>getSourceNumProgressivePasses</code> are passed along to the 104 * next step. 105 * 106 * <p> Finally, the source samples of each pixel are mapped into 107 * destination bands according to the algorithm described in the 108 * comment for <code>setDestinationBands</code>. 109 * 110 * <p> Plug-in writers may extend the functionality of 111 * <code>ImageReadParam</code> by providing a subclass that implements 112 * additional, plug-in specific interfaces. It is up to the plug-in 113 * to document what interfaces are available and how they are to be 114 * used. Readers will silently ignore any extended features of an 115 * <code>ImageReadParam</code> subclass of which they are not aware. 116 * Also, they may ignore any optional features that they normally 117 * disable when creating their own <code>ImageReadParam</code> 118 * instances via <code>getDefaultReadParam</code>. 119 * 120 * <p> Note that unless a query method exists for a capability, it must 121 * be supported by all <code>ImageReader</code> implementations 122 * (<i>e.g.</i> source render size is optional, but subsampling must be 123 * supported). 124 * 125 * 126 * @see ImageReader 127 * @see ImageWriter 128 * @see ImageWriteParam 129 */ 130 public class ImageReadParam extends IIOParam { 131 132 /** 133 * <code>true</code> if this <code>ImageReadParam</code> allows 134 * the source rendering dimensions to be set. By default, the 135 * value is <code>false</code>. Subclasses must set this value 136 * manually. 137 * 138 * <p> <code>ImageReader</code>s that do not support setting of 139 * the source render size should set this value to 140 * <code>false</code>. 141 */ 142 protected boolean canSetSourceRenderSize = false; 143 144 /** 145 * The desired rendering width and height of the source, if 146 * <code>canSetSourceRenderSize</code> is <code>true</code>, or 147 * <code>null</code>. 148 * 149 * <p> <code>ImageReader</code>s that do not support setting of 150 * the source render size may ignore this value. 151 */ 152 protected Dimension sourceRenderSize = null; 153 154 /** 155 * The current destination <code>BufferedImage</code>, or 156 * <code>null</code> if none has been set. By default, the value 157 * is <code>null</code>. 158 */ 159 protected BufferedImage destination = null; 160 161 /** 162 * The set of destination bands to be used, as an array of 163 * <code>int</code>s. By default, the value is <code>null</code>, 164 * indicating all destination bands should be written in order. 165 */ 166 protected int[] destinationBands = null; 167 168 /** 169 * The minimum index of a progressive pass to read from the 170 * source. By default, the value is set to 0, which indicates 171 * that passes starting with the first available pass should be 172 * decoded. 173 * 174 * <p> Subclasses should ensure that this value is 175 * non-negative. 176 */ 177 protected int minProgressivePass = 0; 178 179 /** 180 * The maximum number of progressive passes to read from the 181 * source. By default, the value is set to 182 * <code>Integer.MAX_VALUE</code>, which indicates that passes up 183 * to and including the last available pass should be decoded. 184 * 185 * <p> Subclasses should ensure that this value is positive. 186 * Additionally, if the value is not 187 * <code>Integer.MAX_VALUE</code>, then <code>minProgressivePass + 188 * numProgressivePasses - 1</code> should not exceed 189 * <code>Integer.MAX_VALUE</code>. 190 */ 191 protected int numProgressivePasses = Integer.MAX_VALUE; 192 193 /** 194 * Constructs an <code>ImageReadParam</code>. 195 */ 196 public ImageReadParam() {} 197 198 // Comment inherited 199 public void setDestinationType(ImageTypeSpecifier destinationType) { 200 super.setDestinationType(destinationType); 201 setDestination(null); 202 } 203 204 /** 205 * Supplies a <code>BufferedImage</code> to be used as the 206 * destination for decoded pixel data. The currently set image 207 * will be written to by the <code>read</code>, 208 * <code>readAll</code>, and <code>readRaster</code> methods, and 209 * a reference to it will be returned by those methods. 210 * 211 * <p> Pixel data from the aforementioned methods will be written 212 * starting at the offset specified by 213 * <code>getDestinationOffset</code>. 214 * 215 * <p> If <code>destination</code> is <code>null</code>, a 216 * newly-created <code>BufferedImage</code> will be returned by 217 * those methods. 218 * 219 * <p> At the time of reading, the image is checked to verify that 220 * its <code>ColorModel</code> and <code>SampleModel</code> 221 * correspond to one of the <code>ImageTypeSpecifier</code>s 222 * returned from the <code>ImageReader</code>'s 223 * <code>getImageTypes</code> method. If it does not, the reader 224 * will throw an <code>IIOException</code>. 225 * 226 * @param destination the BufferedImage to be written to, or 227 * <code>null</code>. 228 * 229 * @see #getDestination 230 */ 231 public void setDestination(BufferedImage destination) { 232 this.destination = destination; 233 } 234 235 /** 236 * Returns the <code>BufferedImage</code> currently set by the 237 * <code>setDestination</code> method, or <code>null</code> 238 * if none is set. 239 * 240 * @return the BufferedImage to be written to. 241 * 242 * @see #setDestination 243 */ 244 public BufferedImage getDestination() { 245 return destination; 246 } 247 248 /** 249 * Sets the indices of the destination bands where data 250 * will be placed. Duplicate indices are not allowed. 251 * 252 * <p> A <code>null</code> value indicates that all destination 253 * bands will be used. 254 * 255 * <p> Choosing a destination band subset will not affect the 256 * number of bands in the output image of a read if no destination 257 * image is specified; the created destination image will still 258 * have the same number of bands as if this method had never been 259 * called. If a different number of bands in the destination 260 * image is desired, an image must be supplied using the 261 * <code>ImageReadParam.setDestination</code> method. 262 * 263 * <p> At the time of reading or writing, an 264 * <code>IllegalArgumentException</code> will be thrown by the 265 * reader or writer if a value larger than the largest destination 266 * band index has been specified, or if the number of source bands 267 * and destination bands to be used differ. The 268 * <code>ImageReader.checkReadParamBandSettings</code> method may 269 * be used to automate this test. 270 * 271 * @param destinationBands an array of integer band indices to be 272 * used. 273 * 274 * @exception IllegalArgumentException if <code>destinationBands</code> 275 * contains a negative or duplicate value. 276 * 277 * @see #getDestinationBands 278 * @see #getSourceBands 279 * @see ImageReader#checkReadParamBandSettings 280 */ 281 public void setDestinationBands(int[] destinationBands) { 282 if (destinationBands == null) { 283 this.destinationBands = null; 284 } else { 285 int numBands = destinationBands.length; 286 for (int i = 0; i < numBands; i++) { 287 int band = destinationBands[i]; 288 if (band < 0) { 289 throw new IllegalArgumentException("Band value < 0!"); 290 } 291 for (int j = i + 1; j < numBands; j++) { 292 if (band == destinationBands[j]) { 293 throw new IllegalArgumentException("Duplicate band value!"); 294 } 295 } 296 } 297 this.destinationBands = destinationBands.clone(); 298 } 299 } 300 301 /** 302 * Returns the set of band indices where data will be placed. 303 * If no value has been set, <code>null</code> is returned to 304 * indicate that all destination bands will be used. 305 * 306 * @return the indices of the destination bands to be used, 307 * or <code>null</code>. 308 * 309 * @see #setDestinationBands 310 */ 311 public int[] getDestinationBands() { 312 if (destinationBands == null) { 313 return null; 314 } else { 315 return destinationBands.clone(); 316 } 317 } 318 319 /** 320 * Returns <code>true</code> if this reader allows the source 321 * image to be rendered at an arbitrary size as part of the 322 * decoding process, by means of the 323 * <code>setSourceRenderSize</code> method. If this method 324 * returns <code>false</code>, calls to 325 * <code>setSourceRenderSize</code> will throw an 326 * <code>UnsupportedOperationException</code>. 327 * 328 * @return <code>true</code> if setting source rendering size is 329 * supported. 330 * 331 * @see #setSourceRenderSize 332 */ 333 public boolean canSetSourceRenderSize() { 334 return canSetSourceRenderSize; 335 } 336 337 /** 338 * If the image is able to be rendered at an arbitrary size, sets 339 * the source width and height to the supplied values. Note that 340 * the values returned from the <code>getWidth</code> and 341 * <code>getHeight</code> methods on <code>ImageReader</code> are 342 * not affected by this method; they will continue to return the 343 * default size for the image. Similarly, if the image is also 344 * tiled the tile width and height are given in terms of the default 345 * size. 346 * 347 * <p> Typically, the width and height should be chosen such that 348 * the ratio of width to height closely approximates the aspect 349 * ratio of the image, as returned from 350 * <code>ImageReader.getAspectRatio</code>. 351 * 352 * <p> If this plug-in does not allow the rendering size to be 353 * set, an <code>UnsupportedOperationException</code> will be 354 * thrown. 355 * 356 * <p> To remove the render size setting, pass in a value of 357 * <code>null</code> for <code>size</code>. 358 * 359 * @param size a <code>Dimension</code> indicating the desired 360 * width and height. 361 * 362 * @exception IllegalArgumentException if either the width or the 363 * height is negative or 0. 364 * @exception UnsupportedOperationException if image resizing 365 * is not supported by this plug-in. 366 * 367 * @see #getSourceRenderSize 368 * @see ImageReader#getWidth 369 * @see ImageReader#getHeight 370 * @see ImageReader#getAspectRatio 371 */ 372 public void setSourceRenderSize(Dimension size) 373 throws UnsupportedOperationException { 374 if (!canSetSourceRenderSize()) { 375 throw new UnsupportedOperationException 376 ("Can't set source render size!"); 377 } 378 379 if (size == null) { 380 this.sourceRenderSize = null; 381 } else { 382 if (size.width <= 0 || size.height <= 0) { 383 throw new IllegalArgumentException("width or height <= 0!"); 384 } 385 this.sourceRenderSize = (Dimension)size.clone(); 386 } 387 } 388 389 /** 390 * Returns the width and height of the source image as it 391 * will be rendered during decoding, if they have been set via the 392 * <code>setSourceRenderSize</code> method. A 393 * <code>null</code>value indicates that no setting has been made. 394 * 395 * @return the rendered width and height of the source image 396 * as a <code>Dimension</code>. 397 * 398 * @see #setSourceRenderSize 399 */ 400 public Dimension getSourceRenderSize() { 401 return (sourceRenderSize == null) ? 402 null : (Dimension)sourceRenderSize.clone(); 403 } 404 405 /** 406 * Sets the range of progressive passes that will be decoded. 407 * Passes outside of this range will be ignored. 408 * 409 * <p> A progressive pass is a re-encoding of the entire image, 410 * generally at progressively higher effective resolutions, but 411 * requiring greater transmission bandwidth. The most common use 412 * of progressive encoding is found in the JPEG format, where 413 * successive passes include more detailed representations of the 414 * high-frequency image content. 415 * 416 * <p> The actual number of passes to be decoded is determined 417 * during decoding, based on the number of actual passes available 418 * in the stream. Thus if <code>minPass + numPasses - 1</code> is 419 * larger than the index of the last available passes, decoding 420 * will end with that pass. 421 * 422 * <p> A value of <code>numPasses</code> of 423 * <code>Integer.MAX_VALUE</code> indicates that all passes from 424 * <code>minPass</code> forward should be read. Otherwise, the 425 * index of the last pass (<i>i.e.</i>, <code>minPass + numPasses 426 * - 1</code>) must not exceed <code>Integer.MAX_VALUE</code>. 427 * 428 * <p> There is no <code>unsetSourceProgressivePasses</code> 429 * method; the same effect may be obtained by calling 430 * <code>setSourceProgressivePasses(0, Integer.MAX_VALUE)</code>. 431 * 432 * @param minPass the index of the first pass to be decoded. 433 * @param numPasses the maximum number of passes to be decoded. 434 * 435 * @exception IllegalArgumentException if <code>minPass</code> is 436 * negative, <code>numPasses</code> is negative or 0, or 437 * <code>numPasses</code> is smaller than 438 * <code>Integer.MAX_VALUE</code> but <code>minPass + 439 * numPasses - 1</code> is greater than 440 * <code>INTEGER.MAX_VALUE</code>. 441 * 442 * @see #getSourceMinProgressivePass 443 * @see #getSourceMaxProgressivePass 444 */ 445 public void setSourceProgressivePasses(int minPass, int numPasses) { 446 if (minPass < 0) { 447 throw new IllegalArgumentException("minPass < 0!"); 448 } 449 if (numPasses <= 0) { 450 throw new IllegalArgumentException("numPasses <= 0!"); 451 } 452 if ((numPasses != Integer.MAX_VALUE) && 453 (((minPass + numPasses - 1) & 0x80000000) != 0)) { 454 throw new IllegalArgumentException 455 ("minPass + numPasses - 1 > INTEGER.MAX_VALUE!"); 456 } 457 458 this.minProgressivePass = minPass; 459 this.numProgressivePasses = numPasses; 460 } 461 462 /** 463 * Returns the index of the first progressive pass that will be 464 * decoded. If no value has been set, 0 will be returned (which is 465 * the correct value). 466 * 467 * @return the index of the first pass that will be decoded. 468 * 469 * @see #setSourceProgressivePasses 470 * @see #getSourceNumProgressivePasses 471 */ 472 public int getSourceMinProgressivePass() { 473 return minProgressivePass; 474 } 475 476 /** 477 * If <code>getSourceNumProgressivePasses</code> is equal to 478 * <code>Integer.MAX_VALUE</code>, returns 479 * <code>Integer.MAX_VALUE</code>. Otherwise, returns 480 * <code>getSourceMinProgressivePass() + 481 * getSourceNumProgressivePasses() - 1</code>. 482 * 483 * @return the index of the last pass to be read, or 484 * <code>Integer.MAX_VALUE</code>. 485 */ 486 public int getSourceMaxProgressivePass() { 487 if (numProgressivePasses == Integer.MAX_VALUE) { 488 return Integer.MAX_VALUE; 489 } else { 490 return minProgressivePass + numProgressivePasses - 1; 491 } 492 } 493 494 /** 495 * Returns the number of the progressive passes that will be 496 * decoded. If no value has been set, 497 * <code>Integer.MAX_VALUE</code> will be returned (which is the 498 * correct value). 499 * 500 * @return the number of the passes that will be decoded. 501 * 502 * @see #setSourceProgressivePasses 503 * @see #getSourceMinProgressivePass 504 */ 505 public int getSourceNumProgressivePasses() { 506 return numProgressivePasses; 507 } 508 } | 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.imageio; 27 28 import java.awt.Dimension; 29 import java.awt.image.BufferedImage; 30 31 /** 32 * A class describing how a stream is to be decoded. Instances of 33 * this class or its subclasses are used to supply prescriptive 34 * "how-to" information to instances of {@code ImageReader}. 35 * 36 * <p> An image encoded as part of a file or stream may be thought of 37 * extending out in multiple dimensions: the spatial dimensions of 38 * width and height, a number of bands, and a number of progressive 39 * decoding passes. This class allows a contiguous (hyper)rectangular 40 * subarea of the image in all of these dimensions to be selected for 41 * decoding. Additionally, the spatial dimensions may be subsampled 42 * discontinuously. Finally, color and format conversions may be 43 * specified by controlling the {@code ColorModel} and 44 * {@code SampleModel} of the destination image, either by 45 * providing a {@code BufferedImage} or by using an 46 * {@code ImageTypeSpecifier}. 47 * 48 * <p> An {@code ImageReadParam} object is used to specify how an 49 * image, or a set of images, will be converted on input from 50 * a stream in the context of the Java Image I/O framework. A plug-in for a 51 * specific image format will return instances of 52 * {@code ImageReadParam} from the 53 * {@code getDefaultReadParam} method of its 54 * {@code ImageReader} implementation. 55 * 56 * <p> The state maintained by an instance of 57 * {@code ImageReadParam} is independent of any particular image 58 * being decoded. When actual decoding takes place, the values set in 59 * the read param are combined with the actual properties of the image 60 * being decoded from the stream and the destination 61 * {@code BufferedImage} that will receive the decoded pixel 62 * data. For example, the source region set using 63 * {@code setSourceRegion} will first be intersected with the 64 * actual valid source area. The result will be translated by the 65 * value returned by {@code getDestinationOffset}, and the 66 * resulting rectangle intersected with the actual valid destination 67 * area to yield the destination area that will be written. 68 * 69 * <p> The parameters specified by an {@code ImageReadParam} are 70 * applied to an image as follows. First, if a rendering size has 71 * been set by {@code setSourceRenderSize}, the entire decoded 72 * image is rendered at the size given by 73 * {@code getSourceRenderSize}. Otherwise, the image has its 74 * natural size given by {@code ImageReader.getWidth} and 75 * {@code ImageReader.getHeight}. 76 * 77 * <p> Next, the image is clipped against the source region 78 * specified by {@code getSourceXOffset}, {@code getSourceYOffset}, 79 * {@code getSourceWidth}, and {@code getSourceHeight}. 80 * 81 * <p> The resulting region is then subsampled according to the 82 * factors given in {@link IIOParam#setSourceSubsampling 83 * IIOParam.setSourceSubsampling}. The first pixel, 84 * the number of pixels per row, and the number of rows all depend 85 * on the subsampling settings. 86 * Call the minimum X and Y coordinates of the resulting rectangle 87 * ({@code minX}, {@code minY}), its width {@code w} 88 * and its height {@code h}. 89 * 90 * <p> This rectangle is offset by 91 * ({@code getDestinationOffset().x}, 92 * {@code getDestinationOffset().y}) and clipped against the 93 * destination bounds. If no destination image has been set, the 94 * destination is defined to have a width of 95 * {@code getDestinationOffset().x} + {@code w}, and a 96 * height of {@code getDestinationOffset().y} + {@code h} so 97 * that all pixels of the source region may be written to the 98 * destination. 99 * 100 * <p> Pixels that land, after subsampling, within the destination 101 * image, and that are written in one of the progressive passes 102 * specified by {@code getSourceMinProgressivePass} and 103 * {@code getSourceNumProgressivePasses} are passed along to the 104 * next step. 105 * 106 * <p> Finally, the source samples of each pixel are mapped into 107 * destination bands according to the algorithm described in the 108 * comment for {@code setDestinationBands}. 109 * 110 * <p> Plug-in writers may extend the functionality of 111 * {@code ImageReadParam} by providing a subclass that implements 112 * additional, plug-in specific interfaces. It is up to the plug-in 113 * to document what interfaces are available and how they are to be 114 * used. Readers will silently ignore any extended features of an 115 * {@code ImageReadParam} subclass of which they are not aware. 116 * Also, they may ignore any optional features that they normally 117 * disable when creating their own {@code ImageReadParam} 118 * instances via {@code getDefaultReadParam}. 119 * 120 * <p> Note that unless a query method exists for a capability, it must 121 * be supported by all {@code ImageReader} implementations 122 * (<i>e.g.</i> source render size is optional, but subsampling must be 123 * supported). 124 * 125 * 126 * @see ImageReader 127 * @see ImageWriter 128 * @see ImageWriteParam 129 */ 130 public class ImageReadParam extends IIOParam { 131 132 /** 133 * {@code true} if this {@code ImageReadParam} allows 134 * the source rendering dimensions to be set. By default, the 135 * value is {@code false}. Subclasses must set this value 136 * manually. 137 * 138 * <p> {@code ImageReader}s that do not support setting of 139 * the source render size should set this value to 140 * {@code false}. 141 */ 142 protected boolean canSetSourceRenderSize = false; 143 144 /** 145 * The desired rendering width and height of the source, if 146 * {@code canSetSourceRenderSize} is {@code true}, or 147 * {@code null}. 148 * 149 * <p> {@code ImageReader}s that do not support setting of 150 * the source render size may ignore this value. 151 */ 152 protected Dimension sourceRenderSize = null; 153 154 /** 155 * The current destination {@code BufferedImage}, or 156 * {@code null} if none has been set. By default, the value 157 * is {@code null}. 158 */ 159 protected BufferedImage destination = null; 160 161 /** 162 * The set of destination bands to be used, as an array of 163 * {@code int}s. By default, the value is {@code null}, 164 * indicating all destination bands should be written in order. 165 */ 166 protected int[] destinationBands = null; 167 168 /** 169 * The minimum index of a progressive pass to read from the 170 * source. By default, the value is set to 0, which indicates 171 * that passes starting with the first available pass should be 172 * decoded. 173 * 174 * <p> Subclasses should ensure that this value is 175 * non-negative. 176 */ 177 protected int minProgressivePass = 0; 178 179 /** 180 * The maximum number of progressive passes to read from the 181 * source. By default, the value is set to 182 * {@code Integer.MAX_VALUE}, which indicates that passes up 183 * to and including the last available pass should be decoded. 184 * 185 * <p> Subclasses should ensure that this value is positive. 186 * Additionally, if the value is not 187 * {@code Integer.MAX_VALUE}, then 188 * {@code minProgressivePass + numProgressivePasses - 1} 189 * should not exceed 190 * {@code Integer.MAX_VALUE}. 191 */ 192 protected int numProgressivePasses = Integer.MAX_VALUE; 193 194 /** 195 * Constructs an {@code ImageReadParam}. 196 */ 197 public ImageReadParam() {} 198 199 // Comment inherited 200 public void setDestinationType(ImageTypeSpecifier destinationType) { 201 super.setDestinationType(destinationType); 202 setDestination(null); 203 } 204 205 /** 206 * Supplies a {@code BufferedImage} to be used as the 207 * destination for decoded pixel data. The currently set image 208 * will be written to by the {@code read}, 209 * {@code readAll}, and {@code readRaster} methods, and 210 * a reference to it will be returned by those methods. 211 * 212 * <p> Pixel data from the aforementioned methods will be written 213 * starting at the offset specified by 214 * {@code getDestinationOffset}. 215 * 216 * <p> If {@code destination} is {@code null}, a 217 * newly-created {@code BufferedImage} will be returned by 218 * those methods. 219 * 220 * <p> At the time of reading, the image is checked to verify that 221 * its {@code ColorModel} and {@code SampleModel} 222 * correspond to one of the {@code ImageTypeSpecifier}s 223 * returned from the {@code ImageReader}'s 224 * {@code getImageTypes} method. If it does not, the reader 225 * will throw an {@code IIOException}. 226 * 227 * @param destination the BufferedImage to be written to, or 228 * {@code null}. 229 * 230 * @see #getDestination 231 */ 232 public void setDestination(BufferedImage destination) { 233 this.destination = destination; 234 } 235 236 /** 237 * Returns the {@code BufferedImage} currently set by the 238 * {@code setDestination} method, or {@code null} 239 * if none is set. 240 * 241 * @return the BufferedImage to be written to. 242 * 243 * @see #setDestination 244 */ 245 public BufferedImage getDestination() { 246 return destination; 247 } 248 249 /** 250 * Sets the indices of the destination bands where data 251 * will be placed. Duplicate indices are not allowed. 252 * 253 * <p> A {@code null} value indicates that all destination 254 * bands will be used. 255 * 256 * <p> Choosing a destination band subset will not affect the 257 * number of bands in the output image of a read if no destination 258 * image is specified; the created destination image will still 259 * have the same number of bands as if this method had never been 260 * called. If a different number of bands in the destination 261 * image is desired, an image must be supplied using the 262 * {@code ImageReadParam.setDestination} method. 263 * 264 * <p> At the time of reading or writing, an 265 * {@code IllegalArgumentException} will be thrown by the 266 * reader or writer if a value larger than the largest destination 267 * band index has been specified, or if the number of source bands 268 * and destination bands to be used differ. The 269 * {@code ImageReader.checkReadParamBandSettings} method may 270 * be used to automate this test. 271 * 272 * @param destinationBands an array of integer band indices to be 273 * used. 274 * 275 * @exception IllegalArgumentException if {@code destinationBands} 276 * contains a negative or duplicate value. 277 * 278 * @see #getDestinationBands 279 * @see #getSourceBands 280 * @see ImageReader#checkReadParamBandSettings 281 */ 282 public void setDestinationBands(int[] destinationBands) { 283 if (destinationBands == null) { 284 this.destinationBands = null; 285 } else { 286 int numBands = destinationBands.length; 287 for (int i = 0; i < numBands; i++) { 288 int band = destinationBands[i]; 289 if (band < 0) { 290 throw new IllegalArgumentException("Band value < 0!"); 291 } 292 for (int j = i + 1; j < numBands; j++) { 293 if (band == destinationBands[j]) { 294 throw new IllegalArgumentException("Duplicate band value!"); 295 } 296 } 297 } 298 this.destinationBands = destinationBands.clone(); 299 } 300 } 301 302 /** 303 * Returns the set of band indices where data will be placed. 304 * If no value has been set, {@code null} is returned to 305 * indicate that all destination bands will be used. 306 * 307 * @return the indices of the destination bands to be used, 308 * or {@code null}. 309 * 310 * @see #setDestinationBands 311 */ 312 public int[] getDestinationBands() { 313 if (destinationBands == null) { 314 return null; 315 } else { 316 return destinationBands.clone(); 317 } 318 } 319 320 /** 321 * Returns {@code true} if this reader allows the source 322 * image to be rendered at an arbitrary size as part of the 323 * decoding process, by means of the 324 * {@code setSourceRenderSize} method. If this method 325 * returns {@code false}, calls to 326 * {@code setSourceRenderSize} will throw an 327 * {@code UnsupportedOperationException}. 328 * 329 * @return {@code true} if setting source rendering size is 330 * supported. 331 * 332 * @see #setSourceRenderSize 333 */ 334 public boolean canSetSourceRenderSize() { 335 return canSetSourceRenderSize; 336 } 337 338 /** 339 * If the image is able to be rendered at an arbitrary size, sets 340 * the source width and height to the supplied values. Note that 341 * the values returned from the {@code getWidth} and 342 * {@code getHeight} methods on {@code ImageReader} are 343 * not affected by this method; they will continue to return the 344 * default size for the image. Similarly, if the image is also 345 * tiled the tile width and height are given in terms of the default 346 * size. 347 * 348 * <p> Typically, the width and height should be chosen such that 349 * the ratio of width to height closely approximates the aspect 350 * ratio of the image, as returned from 351 * {@code ImageReader.getAspectRatio}. 352 * 353 * <p> If this plug-in does not allow the rendering size to be 354 * set, an {@code UnsupportedOperationException} will be 355 * thrown. 356 * 357 * <p> To remove the render size setting, pass in a value of 358 * {@code null} for {@code size}. 359 * 360 * @param size a {@code Dimension} indicating the desired 361 * width and height. 362 * 363 * @exception IllegalArgumentException if either the width or the 364 * height is negative or 0. 365 * @exception UnsupportedOperationException if image resizing 366 * is not supported by this plug-in. 367 * 368 * @see #getSourceRenderSize 369 * @see ImageReader#getWidth 370 * @see ImageReader#getHeight 371 * @see ImageReader#getAspectRatio 372 */ 373 public void setSourceRenderSize(Dimension size) 374 throws UnsupportedOperationException { 375 if (!canSetSourceRenderSize()) { 376 throw new UnsupportedOperationException 377 ("Can't set source render size!"); 378 } 379 380 if (size == null) { 381 this.sourceRenderSize = null; 382 } else { 383 if (size.width <= 0 || size.height <= 0) { 384 throw new IllegalArgumentException("width or height <= 0!"); 385 } 386 this.sourceRenderSize = (Dimension)size.clone(); 387 } 388 } 389 390 /** 391 * Returns the width and height of the source image as it 392 * will be rendered during decoding, if they have been set via the 393 * {@code setSourceRenderSize} method. A 394 * {@code null} value indicates that no setting has been made. 395 * 396 * @return the rendered width and height of the source image 397 * as a {@code Dimension}. 398 * 399 * @see #setSourceRenderSize 400 */ 401 public Dimension getSourceRenderSize() { 402 return (sourceRenderSize == null) ? 403 null : (Dimension)sourceRenderSize.clone(); 404 } 405 406 /** 407 * Sets the range of progressive passes that will be decoded. 408 * Passes outside of this range will be ignored. 409 * 410 * <p> A progressive pass is a re-encoding of the entire image, 411 * generally at progressively higher effective resolutions, but 412 * requiring greater transmission bandwidth. The most common use 413 * of progressive encoding is found in the JPEG format, where 414 * successive passes include more detailed representations of the 415 * high-frequency image content. 416 * 417 * <p> The actual number of passes to be decoded is determined 418 * during decoding, based on the number of actual passes available 419 * in the stream. Thus if {@code minPass + numPasses - 1} is 420 * larger than the index of the last available passes, decoding 421 * will end with that pass. 422 * 423 * <p> A value of {@code numPasses} of 424 * {@code Integer.MAX_VALUE} indicates that all passes from 425 * {@code minPass} forward should be read. Otherwise, the 426 * index of the last pass (<i>i.e.</i>, {@code minPass + numPasses - 1}) 427 * must not exceed {@code Integer.MAX_VALUE}. 428 * 429 * <p> There is no {@code unsetSourceProgressivePasses} 430 * method; the same effect may be obtained by calling 431 * {@code setSourceProgressivePasses(0, Integer.MAX_VALUE)}. 432 * 433 * @param minPass the index of the first pass to be decoded. 434 * @param numPasses the maximum number of passes to be decoded. 435 * 436 * @exception IllegalArgumentException if {@code minPass} is 437 * negative, {@code numPasses} is negative or 0, or 438 * {@code numPasses} is smaller than 439 * {@code Integer.MAX_VALUE} but 440 * {@code minPass + numPasses - 1} is greater than 441 * {@code INTEGER.MAX_VALUE}. 442 * 443 * @see #getSourceMinProgressivePass 444 * @see #getSourceMaxProgressivePass 445 */ 446 public void setSourceProgressivePasses(int minPass, int numPasses) { 447 if (minPass < 0) { 448 throw new IllegalArgumentException("minPass < 0!"); 449 } 450 if (numPasses <= 0) { 451 throw new IllegalArgumentException("numPasses <= 0!"); 452 } 453 if ((numPasses != Integer.MAX_VALUE) && 454 (((minPass + numPasses - 1) & 0x80000000) != 0)) { 455 throw new IllegalArgumentException 456 ("minPass + numPasses - 1 > INTEGER.MAX_VALUE!"); 457 } 458 459 this.minProgressivePass = minPass; 460 this.numProgressivePasses = numPasses; 461 } 462 463 /** 464 * Returns the index of the first progressive pass that will be 465 * decoded. If no value has been set, 0 will be returned (which is 466 * the correct value). 467 * 468 * @return the index of the first pass that will be decoded. 469 * 470 * @see #setSourceProgressivePasses 471 * @see #getSourceNumProgressivePasses 472 */ 473 public int getSourceMinProgressivePass() { 474 return minProgressivePass; 475 } 476 477 /** 478 * If {@code getSourceNumProgressivePasses} is equal to 479 * {@code Integer.MAX_VALUE}, returns 480 * {@code Integer.MAX_VALUE}. Otherwise, returns 481 * {@code getSourceMinProgressivePass() + 482 * getSourceNumProgressivePasses() - 1}. 483 * 484 * @return the index of the last pass to be read, or 485 * {@code Integer.MAX_VALUE}. 486 */ 487 public int getSourceMaxProgressivePass() { 488 if (numProgressivePasses == Integer.MAX_VALUE) { 489 return Integer.MAX_VALUE; 490 } else { 491 return minProgressivePass + numProgressivePasses - 1; 492 } 493 } 494 495 /** 496 * Returns the number of the progressive passes that will be 497 * decoded. If no value has been set, 498 * {@code Integer.MAX_VALUE} will be returned (which is the 499 * correct value). 500 * 501 * @return the number of the passes that will be decoded. 502 * 503 * @see #setSourceProgressivePasses 504 * @see #getSourceMinProgressivePass 505 */ 506 public int getSourceNumProgressivePasses() { 507 return numProgressivePasses; 508 } 509 } |