Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/imageio/ImageWriteParam.java
38829 views
1
/*
2
* Copyright (c) 2000, 2013, 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.util.Locale;
30
31
/**
32
* A class describing how a stream is to be encoded. Instances of
33
* this class or its subclasses are used to supply prescriptive
34
* "how-to" information to instances of <code>ImageWriter</code>.
35
*
36
* <p> A plug-in for a specific image format may define a subclass of
37
* this class, and return objects of that class from the
38
* <code>getDefaultWriteParam</code> method of its
39
* <code>ImageWriter</code> implementation. For example, the built-in
40
* JPEG writer plug-in will return instances of
41
* <code>javax.imageio.plugins.jpeg.JPEGImageWriteParam</code>.
42
*
43
* <p> The region of the image to be written is determined by first
44
* intersecting the actual bounds of the image with the rectangle
45
* specified by <code>IIOParam.setSourceRegion</code>, if any. If the
46
* resulting rectangle has a width or height of zero, the writer will
47
* throw an <code>IIOException</code>. If the intersection is
48
* non-empty, writing will commence with the first subsampled pixel
49
* and include additional pixels within the intersected bounds
50
* according to the horizontal and vertical subsampling factors
51
* specified by {@link IIOParam#setSourceSubsampling
52
* IIOParam.setSourceSubsampling}.
53
*
54
* <p> Individual features such as tiling, progressive encoding, and
55
* compression may be set in one of four modes.
56
* <code>MODE_DISABLED</code> disables the features;
57
* <code>MODE_DEFAULT</code> enables the feature with
58
* writer-controlled parameter values; <code>MODE_EXPLICIT</code>
59
* enables the feature and allows the use of a <code>set</code> method
60
* to provide additional parameters; and
61
* <code>MODE_COPY_FROM_METADATA</code> copies relevant parameter
62
* values from the stream and image metadata objects passed to the
63
* writer. The default for all features is
64
* <code>MODE_COPY_FROM_METADATA</code>. Non-standard features
65
* supplied in subclasses are encouraged, but not required to use a
66
* similar scheme.
67
*
68
* <p> Plug-in writers may extend the functionality of
69
* <code>ImageWriteParam</code> by providing a subclass that implements
70
* additional, plug-in specific interfaces. It is up to the plug-in
71
* to document what interfaces are available and how they are to be
72
* used. Writers will silently ignore any extended features of an
73
* <code>ImageWriteParam</code> subclass of which they are not aware.
74
* Also, they may ignore any optional features that they normally
75
* disable when creating their own <code>ImageWriteParam</code>
76
* instances via <code>getDefaultWriteParam</code>.
77
*
78
* <p> Note that unless a query method exists for a capability, it must
79
* be supported by all <code>ImageWriter</code> implementations
80
* (<i>e.g.</i> progressive encoding is optional, but subsampling must be
81
* supported).
82
*
83
*
84
* @see ImageReadParam
85
*/
86
public class ImageWriteParam extends IIOParam {
87
88
/**
89
* A constant value that may be passed into methods such as
90
* <code>setTilingMode</code>, <code>setProgressiveMode</code>,
91
* and <code>setCompressionMode</code> to disable a feature for
92
* future writes. That is, when this mode is set the stream will
93
* <b>not</b> be tiled, progressive, or compressed, and the
94
* relevant accessor methods will throw an
95
* <code>IllegalStateException</code>.
96
*
97
* @see #MODE_EXPLICIT
98
* @see #MODE_COPY_FROM_METADATA
99
* @see #MODE_DEFAULT
100
* @see #setProgressiveMode
101
* @see #getProgressiveMode
102
* @see #setTilingMode
103
* @see #getTilingMode
104
* @see #setCompressionMode
105
* @see #getCompressionMode
106
*/
107
public static final int MODE_DISABLED = 0;
108
109
/**
110
* A constant value that may be passed into methods such as
111
* <code>setTilingMode</code>,
112
* <code>setProgressiveMode</code>, and
113
* <code>setCompressionMode</code> to enable that feature for
114
* future writes. That is, when this mode is enabled the stream
115
* will be tiled, progressive, or compressed according to a
116
* sensible default chosen internally by the writer in a plug-in
117
* dependent way, and the relevant accessor methods will
118
* throw an <code>IllegalStateException</code>.
119
*
120
* @see #MODE_DISABLED
121
* @see #MODE_EXPLICIT
122
* @see #MODE_COPY_FROM_METADATA
123
* @see #setProgressiveMode
124
* @see #getProgressiveMode
125
* @see #setTilingMode
126
* @see #getTilingMode
127
* @see #setCompressionMode
128
* @see #getCompressionMode
129
*/
130
public static final int MODE_DEFAULT = 1;
131
132
/**
133
* A constant value that may be passed into methods such as
134
* <code>setTilingMode</code> or <code>setCompressionMode</code>
135
* to enable a feature for future writes. That is, when this mode
136
* is set the stream will be tiled or compressed according to
137
* additional information supplied to the corresponding
138
* <code>set</code> methods in this class and retrievable from the
139
* corresponding <code>get</code> methods. Note that this mode is
140
* not supported for progressive output.
141
*
142
* @see #MODE_DISABLED
143
* @see #MODE_COPY_FROM_METADATA
144
* @see #MODE_DEFAULT
145
* @see #setProgressiveMode
146
* @see #getProgressiveMode
147
* @see #setTilingMode
148
* @see #getTilingMode
149
* @see #setCompressionMode
150
* @see #getCompressionMode
151
*/
152
public static final int MODE_EXPLICIT = 2;
153
154
/**
155
* A constant value that may be passed into methods such as
156
* <code>setTilingMode</code>, <code>setProgressiveMode</code>, or
157
* <code>setCompressionMode</code> to enable that feature for
158
* future writes. That is, when this mode is enabled the stream
159
* will be tiled, progressive, or compressed based on the contents
160
* of stream and/or image metadata passed into the write
161
* operation, and any relevant accessor methods will throw an
162
* <code>IllegalStateException</code>.
163
*
164
* <p> This is the default mode for all features, so that a read
165
* including metadata followed by a write including metadata will
166
* preserve as much information as possible.
167
*
168
* @see #MODE_DISABLED
169
* @see #MODE_EXPLICIT
170
* @see #MODE_DEFAULT
171
* @see #setProgressiveMode
172
* @see #getProgressiveMode
173
* @see #setTilingMode
174
* @see #getTilingMode
175
* @see #setCompressionMode
176
* @see #getCompressionMode
177
*/
178
public static final int MODE_COPY_FROM_METADATA = 3;
179
180
// If more modes are added, this should be updated.
181
private static final int MAX_MODE = MODE_COPY_FROM_METADATA;
182
183
/**
184
* A <code>boolean</code> that is <code>true</code> if this
185
* <code>ImageWriteParam</code> allows tile width and tile height
186
* parameters to be set. By default, the value is
187
* <code>false</code>. Subclasses must set the value manually.
188
*
189
* <p> Subclasses that do not support writing tiles should ensure
190
* that this value is set to <code>false</code>.
191
*/
192
protected boolean canWriteTiles = false;
193
194
/**
195
* The mode controlling tiling settings, which Must be
196
* set to one of the four <code>MODE_*</code> values. The default
197
* is <code>MODE_COPY_FROM_METADATA</code>.
198
*
199
* <p> Subclasses that do not writing tiles may ignore this value.
200
*
201
* @see #MODE_DISABLED
202
* @see #MODE_EXPLICIT
203
* @see #MODE_COPY_FROM_METADATA
204
* @see #MODE_DEFAULT
205
* @see #setTilingMode
206
* @see #getTilingMode
207
*/
208
protected int tilingMode = MODE_COPY_FROM_METADATA;
209
210
/**
211
* An array of preferred tile size range pairs. The default value
212
* is <code>null</code>, which indicates that there are no
213
* preferred sizes. If the value is non-<code>null</code>, it
214
* must have an even length of at least two.
215
*
216
* <p> Subclasses that do not support writing tiles may ignore
217
* this value.
218
*
219
* @see #getPreferredTileSizes
220
*/
221
protected Dimension[] preferredTileSizes = null;
222
223
/**
224
* A <code>boolean</code> that is <code>true</code> if tiling
225
* parameters have been specified.
226
*
227
* <p> Subclasses that do not support writing tiles may ignore
228
* this value.
229
*/
230
protected boolean tilingSet = false;
231
232
/**
233
* The width of each tile if tiling has been set, or 0 otherwise.
234
*
235
* <p> Subclasses that do not support tiling may ignore this
236
* value.
237
*/
238
protected int tileWidth = 0;
239
240
/**
241
* The height of each tile if tiling has been set, or 0 otherwise.
242
* The initial value is <code>0</code>.
243
*
244
* <p> Subclasses that do not support tiling may ignore this
245
* value.
246
*/
247
protected int tileHeight = 0;
248
249
/**
250
* A <code>boolean</code> that is <code>true</code> if this
251
* <code>ImageWriteParam</code> allows tiling grid offset
252
* parameters to be set. By default, the value is
253
* <code>false</code>. Subclasses must set the value manually.
254
*
255
* <p> Subclasses that do not support writing tiles, or that
256
* support writing but not offsetting tiles must ensure that this
257
* value is set to <code>false</code>.
258
*/
259
protected boolean canOffsetTiles = false;
260
261
/**
262
* The amount by which the tile grid origin should be offset
263
* horizontally from the image origin if tiling has been set,
264
* or 0 otherwise. The initial value is <code>0</code>.
265
*
266
* <p> Subclasses that do not support offsetting tiles may ignore
267
* this value.
268
*/
269
protected int tileGridXOffset = 0;
270
271
/**
272
* The amount by which the tile grid origin should be offset
273
* vertically from the image origin if tiling has been set,
274
* or 0 otherwise. The initial value is <code>0</code>.
275
*
276
* <p> Subclasses that do not support offsetting tiles may ignore
277
* this value.
278
*/
279
protected int tileGridYOffset = 0;
280
281
/**
282
* A <code>boolean</code> that is <code>true</code> if this
283
* <code>ImageWriteParam</code> allows images to be written as a
284
* progressive sequence of increasing quality passes. By default,
285
* the value is <code>false</code>. Subclasses must set the value
286
* manually.
287
*
288
* <p> Subclasses that do not support progressive encoding must
289
* ensure that this value is set to <code>false</code>.
290
*/
291
protected boolean canWriteProgressive = false;
292
293
/**
294
* The mode controlling progressive encoding, which must be set to
295
* one of the four <code>MODE_*</code> values, except
296
* <code>MODE_EXPLICIT</code>. The default is
297
* <code>MODE_COPY_FROM_METADATA</code>.
298
*
299
* <p> Subclasses that do not support progressive encoding may
300
* ignore this value.
301
*
302
* @see #MODE_DISABLED
303
* @see #MODE_EXPLICIT
304
* @see #MODE_COPY_FROM_METADATA
305
* @see #MODE_DEFAULT
306
* @see #setProgressiveMode
307
* @see #getProgressiveMode
308
*/
309
protected int progressiveMode = MODE_COPY_FROM_METADATA;
310
311
/**
312
* A <code>boolean</code> that is <code>true</code> if this writer
313
* can write images using compression. By default, the value is
314
* <code>false</code>. Subclasses must set the value manually.
315
*
316
* <p> Subclasses that do not support compression must ensure that
317
* this value is set to <code>false</code>.
318
*/
319
protected boolean canWriteCompressed = false;
320
321
/**
322
* The mode controlling compression settings, which must be set to
323
* one of the four <code>MODE_*</code> values. The default is
324
* <code>MODE_COPY_FROM_METADATA</code>.
325
*
326
* <p> Subclasses that do not support compression may ignore this
327
* value.
328
*
329
* @see #MODE_DISABLED
330
* @see #MODE_EXPLICIT
331
* @see #MODE_COPY_FROM_METADATA
332
* @see #MODE_DEFAULT
333
* @see #setCompressionMode
334
* @see #getCompressionMode
335
*/
336
protected int compressionMode = MODE_COPY_FROM_METADATA;
337
338
/**
339
* An array of <code>String</code>s containing the names of the
340
* available compression types. Subclasses must set the value
341
* manually.
342
*
343
* <p> Subclasses that do not support compression may ignore this
344
* value.
345
*/
346
protected String[] compressionTypes = null;
347
348
/**
349
* A <code>String</code> containing the name of the current
350
* compression type, or <code>null</code> if none is set.
351
*
352
* <p> Subclasses that do not support compression may ignore this
353
* value.
354
*/
355
protected String compressionType = null;
356
357
/**
358
* A <code>float</code> containing the current compression quality
359
* setting. The initial value is <code>1.0F</code>.
360
*
361
* <p> Subclasses that do not support compression may ignore this
362
* value.
363
*/
364
protected float compressionQuality = 1.0F;
365
366
/**
367
* A <code>Locale</code> to be used to localize compression type
368
* names and quality descriptions, or <code>null</code> to use a
369
* default <code>Locale</code>. Subclasses must set the value
370
* manually.
371
*/
372
protected Locale locale = null;
373
374
/**
375
* Constructs an empty <code>ImageWriteParam</code>. It is up to
376
* the subclass to set up the instance variables properly.
377
*/
378
protected ImageWriteParam() {}
379
380
/**
381
* Constructs an <code>ImageWriteParam</code> set to use a
382
* given <code>Locale</code>.
383
*
384
* @param locale a <code>Locale</code> to be used to localize
385
* compression type names and quality descriptions, or
386
* <code>null</code>.
387
*/
388
public ImageWriteParam(Locale locale) {
389
this.locale = locale;
390
}
391
392
// Return a deep copy of the array
393
private static Dimension[] clonePreferredTileSizes(Dimension[] sizes) {
394
if (sizes == null) {
395
return null;
396
}
397
Dimension[] temp = new Dimension[sizes.length];
398
for (int i = 0; i < sizes.length; i++) {
399
temp[i] = new Dimension(sizes[i]);
400
}
401
return temp;
402
}
403
404
/**
405
* Returns the currently set <code>Locale</code>, or
406
* <code>null</code> if only a default <code>Locale</code> is
407
* supported.
408
*
409
* @return the current <code>Locale</code>, or <code>null</code>.
410
*/
411
public Locale getLocale() {
412
return locale;
413
}
414
415
/**
416
* Returns <code>true</code> if the writer can perform tiling
417
* while writing. If this method returns <code>false</code>, then
418
* <code>setTiling</code> will throw an
419
* <code>UnsupportedOperationException</code>.
420
*
421
* @return <code>true</code> if the writer supports tiling.
422
*
423
* @see #canOffsetTiles()
424
* @see #setTiling(int, int, int, int)
425
*/
426
public boolean canWriteTiles() {
427
return canWriteTiles;
428
}
429
430
/**
431
* Returns <code>true</code> if the writer can perform tiling with
432
* non-zero grid offsets while writing. If this method returns
433
* <code>false</code>, then <code>setTiling</code> will throw an
434
* <code>UnsupportedOperationException</code> if the grid offset
435
* arguments are not both zero. If <code>canWriteTiles</code>
436
* returns <code>false</code>, this method will return
437
* <code>false</code> as well.
438
*
439
* @return <code>true</code> if the writer supports non-zero tile
440
* offsets.
441
*
442
* @see #canWriteTiles()
443
* @see #setTiling(int, int, int, int)
444
*/
445
public boolean canOffsetTiles() {
446
return canOffsetTiles;
447
}
448
449
/**
450
* Determines whether the image will be tiled in the output
451
* stream and, if it will, how the tiling parameters will be
452
* determined. The modes are interpreted as follows:
453
*
454
* <ul>
455
*
456
* <li><code>MODE_DISABLED</code> - The image will not be tiled.
457
* <code>setTiling</code> will throw an
458
* <code>IllegalStateException</code>.
459
*
460
* <li><code>MODE_DEFAULT</code> - The image will be tiled using
461
* default parameters. <code>setTiling</code> will throw an
462
* <code>IllegalStateException</code>.
463
*
464
* <li><code>MODE_EXPLICIT</code> - The image will be tiled
465
* according to parameters given in the {@link #setTiling setTiling}
466
* method. Any previously set tiling parameters are discarded.
467
*
468
* <li><code>MODE_COPY_FROM_METADATA</code> - The image will
469
* conform to the metadata object passed in to a write.
470
* <code>setTiling</code> will throw an
471
* <code>IllegalStateException</code>.
472
*
473
* </ul>
474
*
475
* @param mode The mode to use for tiling.
476
*
477
* @exception UnsupportedOperationException if
478
* <code>canWriteTiles</code> returns <code>false</code>.
479
* @exception IllegalArgumentException if <code>mode</code> is not
480
* one of the modes listed above.
481
*
482
* @see #setTiling
483
* @see #getTilingMode
484
*/
485
public void setTilingMode(int mode) {
486
if (canWriteTiles() == false) {
487
throw new UnsupportedOperationException("Tiling not supported!");
488
}
489
if (mode < MODE_DISABLED || mode > MAX_MODE) {
490
throw new IllegalArgumentException("Illegal value for mode!");
491
}
492
this.tilingMode = mode;
493
if (mode == MODE_EXPLICIT) {
494
unsetTiling();
495
}
496
}
497
498
/**
499
* Returns the current tiling mode, if tiling is supported.
500
* Otherwise throws an <code>UnsupportedOperationException</code>.
501
*
502
* @return the current tiling mode.
503
*
504
* @exception UnsupportedOperationException if
505
* <code>canWriteTiles</code> returns <code>false</code>.
506
*
507
* @see #setTilingMode
508
*/
509
public int getTilingMode() {
510
if (!canWriteTiles()) {
511
throw new UnsupportedOperationException("Tiling not supported");
512
}
513
return tilingMode;
514
}
515
516
/**
517
* Returns an array of <code>Dimension</code>s indicating the
518
* legal size ranges for tiles as they will be encoded in the
519
* output file or stream. The returned array is a copy.
520
*
521
* <p> The information is returned as a set of pairs; the first
522
* element of a pair contains an (inclusive) minimum width and
523
* height, and the second element contains an (inclusive) maximum
524
* width and height. Together, each pair defines a valid range of
525
* sizes. To specify a fixed size, use the same width and height
526
* for both elements. To specify an arbitrary range, a value of
527
* <code>null</code> is used in place of an actual array of
528
* <code>Dimension</code>s.
529
*
530
* <p> If no array is specified on the constructor, but tiling is
531
* allowed, then this method returns <code>null</code>.
532
*
533
* @exception UnsupportedOperationException if the plug-in does
534
* not support tiling.
535
*
536
* @return an array of <code>Dimension</code>s with an even length
537
* of at least two, or <code>null</code>.
538
*/
539
public Dimension[] getPreferredTileSizes() {
540
if (!canWriteTiles()) {
541
throw new UnsupportedOperationException("Tiling not supported");
542
}
543
return clonePreferredTileSizes(preferredTileSizes);
544
}
545
546
/**
547
* Specifies that the image should be tiled in the output stream.
548
* The <code>tileWidth</code> and <code>tileHeight</code>
549
* parameters specify the width and height of the tiles in the
550
* file. If the tile width or height is greater than the width or
551
* height of the image, the image is not tiled in that dimension.
552
*
553
* <p> If <code>canOffsetTiles</code> returns <code>false</code>,
554
* then the <code>tileGridXOffset</code> and
555
* <code>tileGridYOffset</code> parameters must be zero.
556
*
557
* @param tileWidth the width of each tile.
558
* @param tileHeight the height of each tile.
559
* @param tileGridXOffset the horizontal offset of the tile grid.
560
* @param tileGridYOffset the vertical offset of the tile grid.
561
*
562
* @exception UnsupportedOperationException if the plug-in does not
563
* support tiling.
564
* @exception IllegalStateException if the tiling mode is not
565
* <code>MODE_EXPLICIT</code>.
566
* @exception UnsupportedOperationException if the plug-in does not
567
* support grid offsets, and the grid offsets are not both zero.
568
* @exception IllegalArgumentException if the tile size is not
569
* within one of the allowable ranges returned by
570
* <code>getPreferredTileSizes</code>.
571
* @exception IllegalArgumentException if <code>tileWidth</code>
572
* or <code>tileHeight</code> is less than or equal to 0.
573
*
574
* @see #canWriteTiles
575
* @see #canOffsetTiles
576
* @see #getTileWidth()
577
* @see #getTileHeight()
578
* @see #getTileGridXOffset()
579
* @see #getTileGridYOffset()
580
*/
581
public void setTiling(int tileWidth,
582
int tileHeight,
583
int tileGridXOffset,
584
int tileGridYOffset) {
585
if (!canWriteTiles()) {
586
throw new UnsupportedOperationException("Tiling not supported!");
587
}
588
if (getTilingMode() != MODE_EXPLICIT) {
589
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
590
}
591
if (tileWidth <= 0 || tileHeight <= 0) {
592
throw new IllegalArgumentException
593
("tile dimensions are non-positive!");
594
}
595
boolean tilesOffset = (tileGridXOffset != 0) || (tileGridYOffset != 0);
596
if (!canOffsetTiles() && tilesOffset) {
597
throw new UnsupportedOperationException("Can't offset tiles!");
598
}
599
if (preferredTileSizes != null) {
600
boolean ok = true;
601
for (int i = 0; i < preferredTileSizes.length; i += 2) {
602
Dimension min = preferredTileSizes[i];
603
Dimension max = preferredTileSizes[i+1];
604
if ((tileWidth < min.width) ||
605
(tileWidth > max.width) ||
606
(tileHeight < min.height) ||
607
(tileHeight > max.height)) {
608
ok = false;
609
break;
610
}
611
}
612
if (!ok) {
613
throw new IllegalArgumentException("Illegal tile size!");
614
}
615
}
616
617
this.tilingSet = true;
618
this.tileWidth = tileWidth;
619
this.tileHeight = tileHeight;
620
this.tileGridXOffset = tileGridXOffset;
621
this.tileGridYOffset = tileGridYOffset;
622
}
623
624
/**
625
* Removes any previous tile grid parameters specified by calls to
626
* <code>setTiling</code>.
627
*
628
* <p> The default implementation sets the instance variables
629
* <code>tileWidth</code>, <code>tileHeight</code>,
630
* <code>tileGridXOffset</code>, and
631
* <code>tileGridYOffset</code> to <code>0</code>.
632
*
633
* @exception UnsupportedOperationException if the plug-in does not
634
* support tiling.
635
* @exception IllegalStateException if the tiling mode is not
636
* <code>MODE_EXPLICIT</code>.
637
*
638
* @see #setTiling(int, int, int, int)
639
*/
640
public void unsetTiling() {
641
if (!canWriteTiles()) {
642
throw new UnsupportedOperationException("Tiling not supported!");
643
}
644
if (getTilingMode() != MODE_EXPLICIT) {
645
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
646
}
647
this.tilingSet = false;
648
this.tileWidth = 0;
649
this.tileHeight = 0;
650
this.tileGridXOffset = 0;
651
this.tileGridYOffset = 0;
652
}
653
654
/**
655
* Returns the width of each tile in an image as it will be
656
* written to the output stream. If tiling parameters have not
657
* been set, an <code>IllegalStateException</code> is thrown.
658
*
659
* @return the tile width to be used for encoding.
660
*
661
* @exception UnsupportedOperationException if the plug-in does not
662
* support tiling.
663
* @exception IllegalStateException if the tiling mode is not
664
* <code>MODE_EXPLICIT</code>.
665
* @exception IllegalStateException if the tiling parameters have
666
* not been set.
667
*
668
* @see #setTiling(int, int, int, int)
669
* @see #getTileHeight()
670
*/
671
public int getTileWidth() {
672
if (!canWriteTiles()) {
673
throw new UnsupportedOperationException("Tiling not supported!");
674
}
675
if (getTilingMode() != MODE_EXPLICIT) {
676
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
677
}
678
if (!tilingSet) {
679
throw new IllegalStateException("Tiling parameters not set!");
680
}
681
return tileWidth;
682
}
683
684
/**
685
* Returns the height of each tile in an image as it will be written to
686
* the output stream. If tiling parameters have not
687
* been set, an <code>IllegalStateException</code> is thrown.
688
*
689
* @return the tile height to be used for encoding.
690
*
691
* @exception UnsupportedOperationException if the plug-in does not
692
* support tiling.
693
* @exception IllegalStateException if the tiling mode is not
694
* <code>MODE_EXPLICIT</code>.
695
* @exception IllegalStateException if the tiling parameters have
696
* not been set.
697
*
698
* @see #setTiling(int, int, int, int)
699
* @see #getTileWidth()
700
*/
701
public int getTileHeight() {
702
if (!canWriteTiles()) {
703
throw new UnsupportedOperationException("Tiling not supported!");
704
}
705
if (getTilingMode() != MODE_EXPLICIT) {
706
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
707
}
708
if (!tilingSet) {
709
throw new IllegalStateException("Tiling parameters not set!");
710
}
711
return tileHeight;
712
}
713
714
/**
715
* Returns the horizontal tile grid offset of an image as it will
716
* be written to the output stream. If tiling parameters have not
717
* been set, an <code>IllegalStateException</code> is thrown.
718
*
719
* @return the tile grid X offset to be used for encoding.
720
*
721
* @exception UnsupportedOperationException if the plug-in does not
722
* support tiling.
723
* @exception IllegalStateException if the tiling mode is not
724
* <code>MODE_EXPLICIT</code>.
725
* @exception IllegalStateException if the tiling parameters have
726
* not been set.
727
*
728
* @see #setTiling(int, int, int, int)
729
* @see #getTileGridYOffset()
730
*/
731
public int getTileGridXOffset() {
732
if (!canWriteTiles()) {
733
throw new UnsupportedOperationException("Tiling not supported!");
734
}
735
if (getTilingMode() != MODE_EXPLICIT) {
736
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
737
}
738
if (!tilingSet) {
739
throw new IllegalStateException("Tiling parameters not set!");
740
}
741
return tileGridXOffset;
742
}
743
744
/**
745
* Returns the vertical tile grid offset of an image as it will
746
* be written to the output stream. If tiling parameters have not
747
* been set, an <code>IllegalStateException</code> is thrown.
748
*
749
* @return the tile grid Y offset to be used for encoding.
750
*
751
* @exception UnsupportedOperationException if the plug-in does not
752
* support tiling.
753
* @exception IllegalStateException if the tiling mode is not
754
* <code>MODE_EXPLICIT</code>.
755
* @exception IllegalStateException if the tiling parameters have
756
* not been set.
757
*
758
* @see #setTiling(int, int, int, int)
759
* @see #getTileGridXOffset()
760
*/
761
public int getTileGridYOffset() {
762
if (!canWriteTiles()) {
763
throw new UnsupportedOperationException("Tiling not supported!");
764
}
765
if (getTilingMode() != MODE_EXPLICIT) {
766
throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
767
}
768
if (!tilingSet) {
769
throw new IllegalStateException("Tiling parameters not set!");
770
}
771
return tileGridYOffset;
772
}
773
774
/**
775
* Returns <code>true</code> if the writer can write out images
776
* as a series of passes of progressively increasing quality.
777
*
778
* @return <code>true</code> if the writer supports progressive
779
* encoding.
780
*
781
* @see #setProgressiveMode
782
* @see #getProgressiveMode
783
*/
784
public boolean canWriteProgressive() {
785
return canWriteProgressive;
786
}
787
788
/**
789
* Specifies that the writer is to write the image out in a
790
* progressive mode such that the stream will contain a series of
791
* scans of increasing quality. If progressive encoding is not
792
* supported, an <code>UnsupportedOperationException</code> will
793
* be thrown.
794
*
795
* <p> The mode argument determines how
796
* the progression parameters are chosen, and must be either
797
* <code>MODE_DISABLED</code>,
798
* <code>MODE_COPY_FROM_METADATA</code>, or
799
* <code>MODE_DEFAULT</code>. Otherwise an
800
* <code>IllegalArgumentException</code> is thrown.
801
*
802
* <p> The modes are interpreted as follows:
803
*
804
* <ul>
805
* <li><code>MODE_DISABLED</code> - No progression. Use this to
806
* turn off progression.
807
*
808
* <li><code>MODE_COPY_FROM_METADATA</code> - The output image
809
* will use whatever progression parameters are found in the
810
* metadata objects passed into the writer.
811
*
812
* <li><code>MODE_DEFAULT</code> - The image will be written
813
* progressively, with parameters chosen by the writer.
814
* </ul>
815
*
816
* <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
817
*
818
* @param mode The mode for setting progression in the output
819
* stream.
820
*
821
* @exception UnsupportedOperationException if the writer does not
822
* support progressive encoding.
823
* @exception IllegalArgumentException if <code>mode</code> is not
824
* one of the modes listed above.
825
*
826
* @see #getProgressiveMode
827
*/
828
public void setProgressiveMode(int mode) {
829
if (!canWriteProgressive()) {
830
throw new UnsupportedOperationException(
831
"Progressive output not supported");
832
}
833
if (mode < MODE_DISABLED || mode > MAX_MODE) {
834
throw new IllegalArgumentException("Illegal value for mode!");
835
}
836
if (mode == MODE_EXPLICIT) {
837
throw new IllegalArgumentException(
838
"MODE_EXPLICIT not supported for progressive output");
839
}
840
this.progressiveMode = mode;
841
}
842
843
/**
844
* Returns the current mode for writing the stream in a
845
* progressive manner.
846
*
847
* @return the current mode for progressive encoding.
848
*
849
* @exception UnsupportedOperationException if the writer does not
850
* support progressive encoding.
851
*
852
* @see #setProgressiveMode
853
*/
854
public int getProgressiveMode() {
855
if (!canWriteProgressive()) {
856
throw new UnsupportedOperationException
857
("Progressive output not supported");
858
}
859
return progressiveMode;
860
}
861
862
/**
863
* Returns <code>true</code> if this writer supports compression.
864
*
865
* @return <code>true</code> if the writer supports compression.
866
*/
867
public boolean canWriteCompressed() {
868
return canWriteCompressed;
869
}
870
871
/**
872
* Specifies whether compression is to be performed, and if so how
873
* compression parameters are to be determined. The <code>mode</code>
874
* argument must be one of the four modes, interpreted as follows:
875
*
876
* <ul>
877
* <li><code>MODE_DISABLED</code> - If the mode is set to
878
* <code>MODE_DISABLED</code>, methods that query or modify the
879
* compression type or parameters will throw an
880
* <code>IllegalStateException</code> (if compression is
881
* normally supported by the plug-in). Some writers, such as JPEG,
882
* do not normally offer uncompressed output. In this case, attempting
883
* to set the mode to <code>MODE_DISABLED</code> will throw an
884
* <code>UnsupportedOperationException</code> and the mode will not be
885
* changed.
886
*
887
* <li><code>MODE_EXPLICIT</code> - Compress using the
888
* compression type and quality settings specified in this
889
* <code>ImageWriteParam</code>. Any previously set compression
890
* parameters are discarded.
891
*
892
* <li><code>MODE_COPY_FROM_METADATA</code> - Use whatever
893
* compression parameters are specified in metadata objects
894
* passed in to the writer.
895
*
896
* <li><code>MODE_DEFAULT</code> - Use default compression
897
* parameters.
898
* </ul>
899
*
900
* <p> The default is <code>MODE_COPY_FROM_METADATA</code>.
901
*
902
* @param mode The mode for setting compression in the output
903
* stream.
904
*
905
* @exception UnsupportedOperationException if the writer does not
906
* support compression, or does not support the requested mode.
907
* @exception IllegalArgumentException if <code>mode</code> is not
908
* one of the modes listed above.
909
*
910
* @see #getCompressionMode
911
*/
912
public void setCompressionMode(int mode) {
913
if (!canWriteCompressed()) {
914
throw new UnsupportedOperationException(
915
"Compression not supported.");
916
}
917
if (mode < MODE_DISABLED || mode > MAX_MODE) {
918
throw new IllegalArgumentException("Illegal value for mode!");
919
}
920
this.compressionMode = mode;
921
if (mode == MODE_EXPLICIT) {
922
unsetCompression();
923
}
924
}
925
926
/**
927
* Returns the current compression mode, if compression is
928
* supported.
929
*
930
* @return the current compression mode.
931
*
932
* @exception UnsupportedOperationException if the writer does not
933
* support compression.
934
*
935
* @see #setCompressionMode
936
*/
937
public int getCompressionMode() {
938
if (!canWriteCompressed()) {
939
throw new UnsupportedOperationException(
940
"Compression not supported.");
941
}
942
return compressionMode;
943
}
944
945
/**
946
* Returns a list of available compression types, as an array or
947
* <code>String</code>s, or <code>null</code> if a compression
948
* type may not be chosen using these interfaces. The array
949
* returned is a copy.
950
*
951
* <p> If the writer only offers a single, mandatory form of
952
* compression, it is not necessary to provide any named
953
* compression types. Named compression types should only be
954
* used where the user is able to make a meaningful choice
955
* between different schemes.
956
*
957
* <p> The default implementation checks if compression is
958
* supported and throws an
959
* <code>UnsupportedOperationException</code> if not. Otherwise,
960
* it returns a clone of the <code>compressionTypes</code>
961
* instance variable if it is non-<code>null</code>, or else
962
* returns <code>null</code>.
963
*
964
* @return an array of <code>String</code>s containing the
965
* (non-localized) names of available compression types, or
966
* <code>null</code>.
967
*
968
* @exception UnsupportedOperationException if the writer does not
969
* support compression.
970
*/
971
public String[] getCompressionTypes() {
972
if (!canWriteCompressed()) {
973
throw new UnsupportedOperationException(
974
"Compression not supported");
975
}
976
if (compressionTypes == null) {
977
return null;
978
}
979
return (String[])compressionTypes.clone();
980
}
981
982
/**
983
* Sets the compression type to one of the values indicated by
984
* <code>getCompressionTypes</code>. If a value of
985
* <code>null</code> is passed in, any previous setting is
986
* removed.
987
*
988
* <p> The default implementation checks whether compression is
989
* supported and the compression mode is
990
* <code>MODE_EXPLICIT</code>. If so, it calls
991
* <code>getCompressionTypes</code> and checks if
992
* <code>compressionType</code> is one of the legal values. If it
993
* is, the <code>compressionType</code> instance variable is set.
994
* If <code>compressionType</code> is <code>null</code>, the
995
* instance variable is set without performing any checking.
996
*
997
* @param compressionType one of the <code>String</code>s returned
998
* by <code>getCompressionTypes</code>, or <code>null</code> to
999
* remove any previous setting.
1000
*
1001
* @exception UnsupportedOperationException if the writer does not
1002
* support compression.
1003
* @exception IllegalStateException if the compression mode is not
1004
* <code>MODE_EXPLICIT</code>.
1005
* @exception UnsupportedOperationException if there are no
1006
* settable compression types.
1007
* @exception IllegalArgumentException if
1008
* <code>compressionType</code> is non-<code>null</code> but is not
1009
* one of the values returned by <code>getCompressionTypes</code>.
1010
*
1011
* @see #getCompressionTypes
1012
* @see #getCompressionType
1013
* @see #unsetCompression
1014
*/
1015
public void setCompressionType(String compressionType) {
1016
if (!canWriteCompressed()) {
1017
throw new UnsupportedOperationException(
1018
"Compression not supported");
1019
}
1020
if (getCompressionMode() != MODE_EXPLICIT) {
1021
throw new IllegalStateException
1022
("Compression mode not MODE_EXPLICIT!");
1023
}
1024
String[] legalTypes = getCompressionTypes();
1025
if (legalTypes == null) {
1026
throw new UnsupportedOperationException(
1027
"No settable compression types");
1028
}
1029
if (compressionType != null) {
1030
boolean found = false;
1031
if (legalTypes != null) {
1032
for (int i = 0; i < legalTypes.length; i++) {
1033
if (compressionType.equals(legalTypes[i])) {
1034
found = true;
1035
break;
1036
}
1037
}
1038
}
1039
if (!found) {
1040
throw new IllegalArgumentException("Unknown compression type!");
1041
}
1042
}
1043
this.compressionType = compressionType;
1044
}
1045
1046
/**
1047
* Returns the currently set compression type, or
1048
* <code>null</code> if none has been set. The type is returned
1049
* as a <code>String</code> from among those returned by
1050
* <code>getCompressionTypes</code>.
1051
* If no compression type has been set, <code>null</code> is
1052
* returned.
1053
*
1054
* <p> The default implementation checks whether compression is
1055
* supported and the compression mode is
1056
* <code>MODE_EXPLICIT</code>. If so, it returns the value of the
1057
* <code>compressionType</code> instance variable.
1058
*
1059
* @return the current compression type as a <code>String</code>,
1060
* or <code>null</code> if no type is set.
1061
*
1062
* @exception UnsupportedOperationException if the writer does not
1063
* support compression.
1064
* @exception IllegalStateException if the compression mode is not
1065
* <code>MODE_EXPLICIT</code>.
1066
*
1067
* @see #setCompressionType
1068
*/
1069
public String getCompressionType() {
1070
if (!canWriteCompressed()) {
1071
throw new UnsupportedOperationException(
1072
"Compression not supported.");
1073
}
1074
if (getCompressionMode() != MODE_EXPLICIT) {
1075
throw new IllegalStateException
1076
("Compression mode not MODE_EXPLICIT!");
1077
}
1078
return compressionType;
1079
}
1080
1081
/**
1082
* Removes any previous compression type and quality settings.
1083
*
1084
* <p> The default implementation sets the instance variable
1085
* <code>compressionType</code> to <code>null</code>, and the
1086
* instance variable <code>compressionQuality</code> to
1087
* <code>1.0F</code>.
1088
*
1089
* @exception UnsupportedOperationException if the plug-in does not
1090
* support compression.
1091
* @exception IllegalStateException if the compression mode is not
1092
* <code>MODE_EXPLICIT</code>.
1093
*
1094
* @see #setCompressionType
1095
* @see #setCompressionQuality
1096
*/
1097
public void unsetCompression() {
1098
if (!canWriteCompressed()) {
1099
throw new UnsupportedOperationException(
1100
"Compression not supported");
1101
}
1102
if (getCompressionMode() != MODE_EXPLICIT) {
1103
throw new IllegalStateException
1104
("Compression mode not MODE_EXPLICIT!");
1105
}
1106
this.compressionType = null;
1107
this.compressionQuality = 1.0F;
1108
}
1109
1110
/**
1111
* Returns a localized version of the name of the current
1112
* compression type, using the <code>Locale</code> returned by
1113
* <code>getLocale</code>.
1114
*
1115
* <p> The default implementation checks whether compression is
1116
* supported and the compression mode is
1117
* <code>MODE_EXPLICIT</code>. If so, if
1118
* <code>compressionType</code> is <code>non-null</code> the value
1119
* of <code>getCompressionType</code> is returned as a
1120
* convenience.
1121
*
1122
* @return a <code>String</code> containing a localized version of
1123
* the name of the current compression type.
1124
*
1125
* @exception UnsupportedOperationException if the writer does not
1126
* support compression.
1127
* @exception IllegalStateException if the compression mode is not
1128
* <code>MODE_EXPLICIT</code>.
1129
* @exception IllegalStateException if no compression type is set.
1130
*/
1131
public String getLocalizedCompressionTypeName() {
1132
if (!canWriteCompressed()) {
1133
throw new UnsupportedOperationException(
1134
"Compression not supported.");
1135
}
1136
if (getCompressionMode() != MODE_EXPLICIT) {
1137
throw new IllegalStateException
1138
("Compression mode not MODE_EXPLICIT!");
1139
}
1140
if (getCompressionType() == null) {
1141
throw new IllegalStateException("No compression type set!");
1142
}
1143
return getCompressionType();
1144
}
1145
1146
/**
1147
* Returns <code>true</code> if the current compression type
1148
* provides lossless compression. If a plug-in provides only
1149
* one mandatory compression type, then this method may be
1150
* called without calling <code>setCompressionType</code> first.
1151
*
1152
* <p> If there are multiple compression types but none has
1153
* been set, an <code>IllegalStateException</code> is thrown.
1154
*
1155
* <p> The default implementation checks whether compression is
1156
* supported and the compression mode is
1157
* <code>MODE_EXPLICIT</code>. If so, if
1158
* <code>getCompressionTypes()</code> is <code>null</code> or
1159
* <code>getCompressionType()</code> is non-<code>null</code>
1160
* <code>true</code> is returned as a convenience.
1161
*
1162
* @return <code>true</code> if the current compression type is
1163
* lossless.
1164
*
1165
* @exception UnsupportedOperationException if the writer does not
1166
* support compression.
1167
* @exception IllegalStateException if the compression mode is not
1168
* <code>MODE_EXPLICIT</code>.
1169
* @exception IllegalStateException if the set of legal
1170
* compression types is non-<code>null</code> and the current
1171
* compression type is <code>null</code>.
1172
*/
1173
public boolean isCompressionLossless() {
1174
if (!canWriteCompressed()) {
1175
throw new UnsupportedOperationException(
1176
"Compression not supported");
1177
}
1178
if (getCompressionMode() != MODE_EXPLICIT) {
1179
throw new IllegalStateException
1180
("Compression mode not MODE_EXPLICIT!");
1181
}
1182
if ((getCompressionTypes() != null) &&
1183
(getCompressionType() == null)) {
1184
throw new IllegalStateException("No compression type set!");
1185
}
1186
return true;
1187
}
1188
1189
/**
1190
* Sets the compression quality to a value between <code>0</code>
1191
* and <code>1</code>. Only a single compression quality setting
1192
* is supported by default; writers can provide extended versions
1193
* of <code>ImageWriteParam</code> that offer more control. For
1194
* lossy compression schemes, the compression quality should
1195
* control the tradeoff between file size and image quality (for
1196
* example, by choosing quantization tables when writing JPEG
1197
* images). For lossless schemes, the compression quality may be
1198
* used to control the tradeoff between file size and time taken
1199
* to perform the compression (for example, by optimizing row
1200
* filters and setting the ZLIB compression level when writing
1201
* PNG images).
1202
*
1203
* <p> A compression quality setting of 0.0 is most generically
1204
* interpreted as "high compression is important," while a setting of
1205
* 1.0 is most generically interpreted as "high image quality is
1206
* important."
1207
*
1208
* <p> If there are multiple compression types but none has been
1209
* set, an <code>IllegalStateException</code> is thrown.
1210
*
1211
* <p> The default implementation checks that compression is
1212
* supported, and that the compression mode is
1213
* <code>MODE_EXPLICIT</code>. If so, if
1214
* <code>getCompressionTypes()</code> returns <code>null</code> or
1215
* <code>compressionType</code> is non-<code>null</code> it sets
1216
* the <code>compressionQuality</code> instance variable.
1217
*
1218
* @param quality a <code>float</code> between <code>0</code>and
1219
* <code>1</code> indicating the desired quality level.
1220
*
1221
* @exception UnsupportedOperationException if the writer does not
1222
* support compression.
1223
* @exception IllegalStateException if the compression mode is not
1224
* <code>MODE_EXPLICIT</code>.
1225
* @exception IllegalStateException if the set of legal
1226
* compression types is non-<code>null</code> and the current
1227
* compression type is <code>null</code>.
1228
* @exception IllegalArgumentException if <code>quality</code> is
1229
* not between <code>0</code>and <code>1</code>, inclusive.
1230
*
1231
* @see #getCompressionQuality
1232
*/
1233
public void setCompressionQuality(float quality) {
1234
if (!canWriteCompressed()) {
1235
throw new UnsupportedOperationException(
1236
"Compression not supported");
1237
}
1238
if (getCompressionMode() != MODE_EXPLICIT) {
1239
throw new IllegalStateException
1240
("Compression mode not MODE_EXPLICIT!");
1241
}
1242
if (getCompressionTypes() != null && getCompressionType() == null) {
1243
throw new IllegalStateException("No compression type set!");
1244
}
1245
if (quality < 0.0F || quality > 1.0F) {
1246
throw new IllegalArgumentException("Quality out-of-bounds!");
1247
}
1248
this.compressionQuality = quality;
1249
}
1250
1251
/**
1252
* Returns the current compression quality setting.
1253
*
1254
* <p> If there are multiple compression types but none has been
1255
* set, an <code>IllegalStateException</code> is thrown.
1256
*
1257
* <p> The default implementation checks that compression is
1258
* supported and that the compression mode is
1259
* <code>MODE_EXPLICIT</code>. If so, if
1260
* <code>getCompressionTypes()</code> is <code>null</code> or
1261
* <code>getCompressionType()</code> is non-<code>null</code>, it
1262
* returns the value of the <code>compressionQuality</code>
1263
* instance variable.
1264
*
1265
* @return the current compression quality setting.
1266
*
1267
* @exception UnsupportedOperationException if the writer does not
1268
* support compression.
1269
* @exception IllegalStateException if the compression mode is not
1270
* <code>MODE_EXPLICIT</code>.
1271
* @exception IllegalStateException if the set of legal
1272
* compression types is non-<code>null</code> and the current
1273
* compression type is <code>null</code>.
1274
*
1275
* @see #setCompressionQuality
1276
*/
1277
public float getCompressionQuality() {
1278
if (!canWriteCompressed()) {
1279
throw new UnsupportedOperationException(
1280
"Compression not supported.");
1281
}
1282
if (getCompressionMode() != MODE_EXPLICIT) {
1283
throw new IllegalStateException
1284
("Compression mode not MODE_EXPLICIT!");
1285
}
1286
if ((getCompressionTypes() != null) &&
1287
(getCompressionType() == null)) {
1288
throw new IllegalStateException("No compression type set!");
1289
}
1290
return compressionQuality;
1291
}
1292
1293
1294
/**
1295
* Returns a <code>float</code> indicating an estimate of the
1296
* number of bits of output data for each bit of input image data
1297
* at the given quality level. The value will typically lie
1298
* between <code>0</code> and <code>1</code>, with smaller values
1299
* indicating more compression. A special value of
1300
* <code>-1.0F</code> is used to indicate that no estimate is
1301
* available.
1302
*
1303
* <p> If there are multiple compression types but none has been set,
1304
* an <code>IllegalStateException</code> is thrown.
1305
*
1306
* <p> The default implementation checks that compression is
1307
* supported and the compression mode is
1308
* <code>MODE_EXPLICIT</code>. If so, if
1309
* <code>getCompressionTypes()</code> is <code>null</code> or
1310
* <code>getCompressionType()</code> is non-<code>null</code>, and
1311
* <code>quality</code> is within bounds, it returns
1312
* <code>-1.0</code>.
1313
*
1314
* @param quality the quality setting whose bit rate is to be
1315
* queried.
1316
*
1317
* @return an estimate of the compressed bit rate, or
1318
* <code>-1.0F</code> if no estimate is available.
1319
*
1320
* @exception UnsupportedOperationException if the writer does not
1321
* support compression.
1322
* @exception IllegalStateException if the compression mode is not
1323
* <code>MODE_EXPLICIT</code>.
1324
* @exception IllegalStateException if the set of legal
1325
* compression types is non-<code>null</code> and the current
1326
* compression type is <code>null</code>.
1327
* @exception IllegalArgumentException if <code>quality</code> is
1328
* not between <code>0</code>and <code>1</code>, inclusive.
1329
*/
1330
public float getBitRate(float quality) {
1331
if (!canWriteCompressed()) {
1332
throw new UnsupportedOperationException(
1333
"Compression not supported.");
1334
}
1335
if (getCompressionMode() != MODE_EXPLICIT) {
1336
throw new IllegalStateException
1337
("Compression mode not MODE_EXPLICIT!");
1338
}
1339
if ((getCompressionTypes() != null) &&
1340
(getCompressionType() == null)) {
1341
throw new IllegalStateException("No compression type set!");
1342
}
1343
if (quality < 0.0F || quality > 1.0F) {
1344
throw new IllegalArgumentException("Quality out-of-bounds!");
1345
}
1346
return -1.0F;
1347
}
1348
1349
/**
1350
* Returns an array of <code>String</code>s that may be used along
1351
* with <code>getCompressionQualityValues</code> as part of a user
1352
* interface for setting or displaying the compression quality
1353
* level. The <code>String</code> with index <code>i</code>
1354
* provides a description of the range of quality levels between
1355
* <code>getCompressionQualityValues[i]</code> and
1356
* <code>getCompressionQualityValues[i + 1]</code>. Note that the
1357
* length of the array returned from
1358
* <code>getCompressionQualityValues</code> will always be one
1359
* greater than that returned from
1360
* <code>getCompressionQualityDescriptions</code>.
1361
*
1362
* <p> As an example, the strings "Good", "Better", and "Best"
1363
* could be associated with the ranges <code>[0, .33)</code>,
1364
* <code>[.33, .66)</code>, and <code>[.66, 1.0]</code>. In this
1365
* case, <code>getCompressionQualityDescriptions</code> would
1366
* return <code>{ "Good", "Better", "Best" }</code> and
1367
* <code>getCompressionQualityValues</code> would return
1368
* <code>{ 0.0F, .33F, .66F, 1.0F }</code>.
1369
*
1370
* <p> If no descriptions are available, <code>null</code> is
1371
* returned. If <code>null</code> is returned from
1372
* <code>getCompressionQualityValues</code>, this method must also
1373
* return <code>null</code>.
1374
*
1375
* <p> The descriptions should be localized for the
1376
* <code>Locale</code> returned by <code>getLocale</code>, if it
1377
* is non-<code>null</code>.
1378
*
1379
* <p> If there are multiple compression types but none has been set,
1380
* an <code>IllegalStateException</code> is thrown.
1381
*
1382
* <p> The default implementation checks that compression is
1383
* supported and that the compression mode is
1384
* <code>MODE_EXPLICIT</code>. If so, if
1385
* <code>getCompressionTypes()</code> is <code>null</code> or
1386
* <code>getCompressionType()</code> is non-<code>null</code>, it
1387
* returns <code>null</code>.
1388
*
1389
* @return an array of <code>String</code>s containing localized
1390
* descriptions of the compression quality levels.
1391
*
1392
* @exception UnsupportedOperationException if the writer does not
1393
* support compression.
1394
* @exception IllegalStateException if the compression mode is not
1395
* <code>MODE_EXPLICIT</code>.
1396
* @exception IllegalStateException if the set of legal
1397
* compression types is non-<code>null</code> and the current
1398
* compression type is <code>null</code>.
1399
*
1400
* @see #getCompressionQualityValues
1401
*/
1402
public String[] getCompressionQualityDescriptions() {
1403
if (!canWriteCompressed()) {
1404
throw new UnsupportedOperationException(
1405
"Compression not supported.");
1406
}
1407
if (getCompressionMode() != MODE_EXPLICIT) {
1408
throw new IllegalStateException
1409
("Compression mode not MODE_EXPLICIT!");
1410
}
1411
if ((getCompressionTypes() != null) &&
1412
(getCompressionType() == null)) {
1413
throw new IllegalStateException("No compression type set!");
1414
}
1415
return null;
1416
}
1417
1418
/**
1419
* Returns an array of <code>float</code>s that may be used along
1420
* with <code>getCompressionQualityDescriptions</code> as part of a user
1421
* interface for setting or displaying the compression quality
1422
* level. See {@link #getCompressionQualityDescriptions
1423
* getCompressionQualityDescriptions} for more information.
1424
*
1425
* <p> If no descriptions are available, <code>null</code> is
1426
* returned. If <code>null</code> is returned from
1427
* <code>getCompressionQualityDescriptions</code>, this method
1428
* must also return <code>null</code>.
1429
*
1430
* <p> If there are multiple compression types but none has been set,
1431
* an <code>IllegalStateException</code> is thrown.
1432
*
1433
* <p> The default implementation checks that compression is
1434
* supported and that the compression mode is
1435
* <code>MODE_EXPLICIT</code>. If so, if
1436
* <code>getCompressionTypes()</code> is <code>null</code> or
1437
* <code>getCompressionType()</code> is non-<code>null</code>, it
1438
* returns <code>null</code>.
1439
*
1440
* @return an array of <code>float</code>s indicating the
1441
* boundaries between the compression quality levels as described
1442
* by the <code>String</code>s from
1443
* <code>getCompressionQualityDescriptions</code>.
1444
*
1445
* @exception UnsupportedOperationException if the writer does not
1446
* support compression.
1447
* @exception IllegalStateException if the compression mode is not
1448
* <code>MODE_EXPLICIT</code>.
1449
* @exception IllegalStateException if the set of legal
1450
* compression types is non-<code>null</code> and the current
1451
* compression type is <code>null</code>.
1452
*
1453
* @see #getCompressionQualityDescriptions
1454
*/
1455
public float[] getCompressionQualityValues() {
1456
if (!canWriteCompressed()) {
1457
throw new UnsupportedOperationException(
1458
"Compression not supported.");
1459
}
1460
if (getCompressionMode() != MODE_EXPLICIT) {
1461
throw new IllegalStateException
1462
("Compression mode not MODE_EXPLICIT!");
1463
}
1464
if ((getCompressionTypes() != null) &&
1465
(getCompressionType() == null)) {
1466
throw new IllegalStateException("No compression type set!");
1467
}
1468
return null;
1469
}
1470
}
1471
1472