1 /*
2  * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
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 trueif 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 nullif 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 trueif 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 trueif 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 nullfor {@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 }
510