History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/imageio/ImageReadParam.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/imageio/ImageReadParam.java+508−0
@@ -0,0 +1,508 @@
1+/*
2+ * Copyright (c) 1999, 2003, 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</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+ * <code>IIOParam.setSourceSubsampling</code>}. 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 = (int[])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 (int[])(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+}