blob: d32fa591d411aef9a4c942f8812796bcb74ef3d6 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17/**
18 * @author Rustem V. Rafikov
19 * @version $Revision: 1.3 $
20 */
21package javax.imageio;
22
23import java.util.Locale;
24import java.awt.*;
25
26/**
27 * The ImageWriteParam class provides information to an ImageWriter
28 * about how an image is to be encoded.
29 */
30public class ImageWriteParam extends IIOParam {
31
32 /**
33 * The Constant MODE_DISABLED indicates that
34 * stream is not tiled, progressive, or compressed.
35 */
36 public static final int MODE_DISABLED = 0;
37
38 /**
39 * The Constant MODE_DEFAULT indicates that the stream will be tiled,
40 * progressive, or compressed according to the plug-in's default.
41 */
42 public static final int MODE_DEFAULT = 1;
43
44 /**
45 * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
46 * progressive, or compressed according to current settings
47 * which are defined by set methods.
48 */
49 public static final int MODE_EXPLICIT = 2;
50
51 /**
52 * The Constant MODE_COPY_FROM_METADATA indicates that the stream
53 * will be tiled, progressive, or compressed according to
54 * stream or image metadata.
55 */
56 public static final int MODE_COPY_FROM_METADATA = 3;
57
58 /** Whether the ImageWriter can write tiles. */
59 protected boolean canWriteTiles = false;
60
61 /** The tiling mode. */
62 protected int tilingMode = MODE_COPY_FROM_METADATA;
63
64 /** The preferred tile sizes. */
65 protected Dimension[] preferredTileSizes = null;
66
67 /** The tiling set. */
68 protected boolean tilingSet = false;
69
70 /** The tile width. */
71 protected int tileWidth = 0;
72
73 /** The tile height. */
74 protected int tileHeight = 0;
75
76 /** Whether the ImageWriter can offset tiles. */
77 protected boolean canOffsetTiles = false;
78
79 /** The tile grid x offset. */
80 protected int tileGridXOffset = 0;
81
82 /** The tile grid y offset. */
83 protected int tileGridYOffset = 0;
84
85 /** Whether the ImageWriter can write in progressive mode. */
86 protected boolean canWriteProgressive = false;
87
88 /** The progressive mode. */
89 protected int progressiveMode = MODE_COPY_FROM_METADATA;
90
91 /** Whether the ImageWriter can write in compressed mode. */
92 protected boolean canWriteCompressed = false;
93
94 /** The compression mode. */
95 protected int compressionMode = MODE_COPY_FROM_METADATA;
96
97 /** The compression types. */
98 protected String[] compressionTypes = null;
99
100 /** The compression type. */
101 protected String compressionType = null;
102
103 /** The compression quality. */
104 protected float compressionQuality = 1.0f;
105
106 /** The locale. */
107 protected Locale locale = null;
108
109 /**
110 * Instantiates a new ImageWriteParam.
111 */
112 protected ImageWriteParam() {}
113
114 /**
115 * Instantiates a new ImageWriteParam with the specified Locale.
116 *
117 * @param locale the Locale.
118 */
119 public ImageWriteParam(Locale locale) {
120 this.locale = locale;
121
122 }
123
124 /**
125 * Gets the mode for writing the stream in a progressive sequence.
126 *
127 * @return the current progressive mode.
128 */
129 public int getProgressiveMode() {
130 if (canWriteProgressive()) {
131 return progressiveMode;
132 }
133 throw new UnsupportedOperationException("progressive mode is not supported");
134 }
135
136 /**
137 * Returns true if images can be written using
138 * increasing quality passes by progressive.
139 *
140 * @return true if images can be written using
141 * increasing quality passes by progressive, false otherwise.
142 */
143 public boolean canWriteProgressive() {
144 return canWriteProgressive;
145 }
146
147 /**
148 * Sets the progressive mode which defines whether the stream
149 * contains a progressive sequence of increasing quality
150 * during writing. The progressive mode should be one of
151 * the following values: MODE_DISABLED, MODE_DEFAULT, or
152 * MODE_COPY_FROM_METADATA.
153 *
154 * @param mode the new progressive mode.
155 */
156 public void setProgressiveMode(int mode) {
157 if (canWriteProgressive()) {
158 if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
159 throw new IllegalArgumentException("mode is not supported");
160 }
161 this.progressiveMode = mode;
162 }
163 throw new UnsupportedOperationException("progressive mode is not supported");
164 }
165
166 /**
167 * Returns true if the writer can use tiles with non zero
168 * grid offsets while writing.
169 *
170 * @return true if the writer can use tiles with non zero
171 * grid offsets while writing, false otherwise.
172 */
173 public boolean canOffsetTiles() {
174 return canOffsetTiles;
175 }
176
177 /**
178 * Returns true if this writer can write images with
179 * compression.
180 *
181 * @return true, true if this writer can write images with
182 * compression, false otherwise.
183 */
184 public boolean canWriteCompressed() {
185 return canWriteCompressed;
186 }
187
188 /**
189 * Returns true if the writer can write tiles.
190 *
191 * @return true if the writer can write tiles, false otherwise.
192 */
193 public boolean canWriteTiles() {
194 return canWriteTiles;
195 }
196
197 /**
198 * Check write compressed.
199 */
200 private final void checkWriteCompressed() {
201 if (!canWriteCompressed()) {
202 throw new UnsupportedOperationException("Compression not supported.");
203 }
204 }
205
206 /**
207 * Check compression mode.
208 */
209 private final void checkCompressionMode() {
210 if (getCompressionMode() != MODE_EXPLICIT) {
211 throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
212 }
213 }
214
215 /**
216 * Check compression type.
217 */
218 private final void checkCompressionType() {
219 if (getCompressionTypes() != null && getCompressionType() == null) {
220 throw new IllegalStateException("No compression type set!");
221 }
222 }
223
224 /**
225 * Gets the compression mode.
226 *
227 * @return the compression mode if it's supported.
228 */
229 public int getCompressionMode() {
230 checkWriteCompressed();
231 return compressionMode;
232 }
233
234 /**
235 * Gets the an array of supported compression types.
236 *
237 * @return the an array of supported compression types.
238 */
239 public String[] getCompressionTypes() {
240 checkWriteCompressed();
241 if (compressionTypes != null) {
242 return compressionTypes.clone();
243 }
244 return null;
245 }
246
247 /**
248 * Gets the current compression type, or returns null.
249 *
250 * @return the current compression type, or returns null
251 * if it is not set.
252 */
253 public String getCompressionType() {
254 checkWriteCompressed();
255 checkCompressionMode();
256 return compressionType;
257 }
258
259 /**
260 * Gets a bit rate which represents an estimate of the number of bits
261 * of output data for each bit of input image data with the specified
262 * quality.
263 *
264 * @param quality the quality.
265 *
266 * @return an estimate of the bit rate, or -1.0F if there is no
267 * estimate.
268 */
269 public float getBitRate(float quality) {
270 checkWriteCompressed();
271 checkCompressionMode();
272 checkCompressionType();
273 if (quality < 0 || quality > 1) {
274 throw new IllegalArgumentException("Quality out-of-bounds!");
275 }
276 return -1.0f;
277 }
278
279 /**
280 * Gets the compression quality.
281 *
282 * @return the compression quality.
283 */
284 public float getCompressionQuality() {
285 checkWriteCompressed();
286 checkCompressionMode();
287 checkCompressionType();
288 return compressionQuality;
289 }
290
291 /**
292 * Gets the array of compression quality descriptions.
293 *
294 * @return the string array of compression quality descriptions.
295 */
296 public String[] getCompressionQualityDescriptions() {
297 checkWriteCompressed();
298 checkCompressionMode();
299 checkCompressionType();
300 return null;
301 }
302
303 /**
304 * Gets an array of floats which decribe
305 * compression quality levels.
306 *
307 * @return the array of compression quality values.
308 */
309 public float[] getCompressionQualityValues() {
310 checkWriteCompressed();
311 checkCompressionMode();
312 checkCompressionType();
313 return null;
314 }
315
316 /**
317 * Gets the locale of this ImageWriteParam.
318 *
319 * @return the locale of this ImageWriteParam.
320 */
321 public Locale getLocale() {
322 return locale;
323 }
324
325 /**
326 * Gets the current compression type using the current Locale.
327 *
328 * @return the current compression type using the current Locale.
329 */
330 public String getLocalizedCompressionTypeName() {
331 checkWriteCompressed();
332 checkCompressionMode();
333
334 String compressionType = getCompressionType();
335 if (compressionType == null) {
336 throw new IllegalStateException("No compression type set!");
337 }
338 return compressionType;
339
340 }
341
342 /**
343 * Check tiling.
344 */
345 private final void checkTiling() {
346 if (!canWriteTiles()) {
347 throw new UnsupportedOperationException("Tiling not supported!");
348 }
349 }
350
351 /**
352 * Check tiling mode.
353 */
354 private final void checkTilingMode() {
355 if (getTilingMode() != MODE_EXPLICIT) {
356 throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
357 }
358 }
359
360 /**
361 * Check tiling params.
362 */
363 private final void checkTilingParams() {
364 if (!tilingSet) {
365 throw new IllegalStateException("Tiling parameters not set!");
366 }
367 }
368
369 /**
370 * Gets the tiling mode if tiling is supported.
371 *
372 * @return the tiling mode if tiling is supported.
373 */
374 public int getTilingMode() {
375 checkTiling();
376 return tilingMode;
377 }
378
379 /**
380 * Gets an array of Dimensions giving the sizes of the tiles as
381 * they are encoded in the output file or stream.
382 *
383 * @return the preferred tile sizes.
384 */
385 public Dimension[] getPreferredTileSizes() {
386 checkTiling();
387 if (preferredTileSizes == null) {
388 return null;
389 }
390
391 Dimension[] retval = new Dimension[preferredTileSizes.length];
392 for (int i = 0; i < preferredTileSizes.length; i++) {
393 retval[i] = new Dimension(retval[i]);
394 }
395 return retval;
396 }
397
398 /**
399 * Gets the tile grid X offset for encoding.
400 *
401 * @return the tile grid X offset for encoding.
402 */
403 public int getTileGridXOffset() {
404 checkTiling();
405 checkTilingMode();
406 checkTilingParams();
407 return tileGridXOffset;
408 }
409
410 /**
411 * Gets the tile grid Y offset for encoding.
412 *
413 * @return the tile grid Y offset for encoding.
414 */
415 public int getTileGridYOffset() {
416 checkTiling();
417 checkTilingMode();
418 checkTilingParams();
419 return tileGridYOffset;
420 }
421
422 /**
423 * Gets the tile height in an image as it is written to the
424 * output stream.
425 *
426 * @return the tile height in an image as it is written to the
427 * output stream.
428 */
429 public int getTileHeight() {
430 checkTiling();
431 checkTilingMode();
432 checkTilingParams();
433 return tileHeight;
434 }
435
436 /**
437 * Gets the tile width in an image as it is written to the
438 * output stream.
439 *
440 * @return the tile width in an image as it is written to the
441 * output stream.
442 */
443 public int getTileWidth() {
444 checkTiling();
445 checkTilingMode();
446 checkTilingParams();
447 return tileWidth;
448 }
449
450 /**
451 * Checks if the current compression type has lossless
452 * compression or not.
453 *
454 * @return true, if the current compression type has lossless
455 * compression, false otherwise.
456 */
457 public boolean isCompressionLossless() {
458 checkWriteCompressed();
459 checkCompressionMode();
460 checkCompressionType();
461 return true;
462 }
463
464 /**
465 * Removes current compression type.
466 */
467 public void unsetCompression() {
468 checkWriteCompressed();
469 checkCompressionMode();
470 compressionType = null;
471 compressionQuality = 1;
472 }
473
474 /**
475 * Sets the compression mode to the specified value.
476 * The specified mode can be one of the predefined
477 * constants: MODE_DEFAULT, MODE_DISABLED, MODE_EXPLICIT,
478 * or MODE_COPY_FROM_METADATA.
479 *
480 * @param mode the new compression mode to be set.
481 */
482 public void setCompressionMode(int mode) {
483 checkWriteCompressed();
484 switch (mode) {
485 case MODE_EXPLICIT: {
486 compressionMode = mode;
487 unsetCompression();
488 break;
489 }
490 case MODE_COPY_FROM_METADATA:
491 case MODE_DISABLED:
492 case MODE_DEFAULT: {
493 compressionMode = mode;
494 break;
495 }
496 default: {
497 throw new IllegalArgumentException("Illegal value for mode!");
498 }
499 }
500 }
501
502 /**
503 * Sets the compression quality. The value should be between 0 and 1.
504 *
505 * @param quality the new compression quality,
506 * float value between 0 and 1.
507 */
508 public void setCompressionQuality(float quality) {
509 checkWriteCompressed();
510 checkCompressionMode();
511 checkCompressionType();
512 if (quality < 0 || quality > 1) {
513 throw new IllegalArgumentException("Quality out-of-bounds!");
514 }
515 compressionQuality = quality;
516 }
517
518 /**
519 * Sets the compression type. The specified string
520 * should be one of the values returned
521 * by getCompressionTypes method.
522 *
523 * @param compressionType the new compression type.
524 */
525 public void setCompressionType(String compressionType) {
526 checkWriteCompressed();
527 checkCompressionMode();
528
529 if (compressionType == null) { // Don't check anything
530 this.compressionType = null;
531 } else {
532 String[] compressionTypes = getCompressionTypes();
533 if (compressionTypes == null) {
534 throw new UnsupportedOperationException("No settable compression types");
535 }
536
537 for (int i = 0; i < compressionTypes.length; i++) {
538 if (compressionTypes[i].equals(compressionType)) {
539 this.compressionType = compressionType;
540 return;
541 }
542 }
543
544 // Compression type is not in the list.
545 throw new IllegalArgumentException("Unknown compression type!");
546 }
547 }
548
549 /**
550 * Sets the instruction that tiling should be performed for
551 * the image in the output stream with the specified parameters.
552 *
553 * @param tileWidth the tile's width.
554 * @param tileHeight the tile's height.
555 * @param tileGridXOffset the tile grid's x offset.
556 * @param tileGridYOffset the tile grid's y offset.
557 */
558 public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
559 checkTiling();
560 checkTilingMode();
561
562 if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
563 throw new UnsupportedOperationException("Can't offset tiles!");
564 }
565
566 if (tileWidth <=0 || tileHeight <= 0) {
567 throw new IllegalArgumentException("tile dimensions are non-positive!");
568 }
569
570 Dimension preferredTileSizes[] = getPreferredTileSizes();
571 if (preferredTileSizes != null) {
572 for (int i = 0; i < preferredTileSizes.length; i+=2) {
573 Dimension minSize = preferredTileSizes[i];
574 Dimension maxSize = preferredTileSizes[i+1];
575 if (
576 tileWidth < minSize.width || tileWidth > maxSize.width ||
577 tileHeight < minSize.height || tileHeight > maxSize.height
578 ) {
579 throw new IllegalArgumentException("Illegal tile size!");
580 }
581 }
582 }
583
584 tilingSet = true;
585 this.tileWidth = tileWidth;
586 this.tileHeight = tileHeight;
587 this.tileGridXOffset = tileGridXOffset;
588 this.tileGridYOffset = tileGridYOffset;
589 }
590
591 /**
592 * Clears all tiling settings.
593 */
594 public void unsetTiling() {
595 checkTiling();
596 checkTilingMode();
597
598 tilingSet = false;
599 tileWidth = 0;
600 tileHeight = 0;
601 tileGridXOffset = 0;
602 tileGridYOffset = 0;
603 }
604
605 /**
606 * Sets the tiling mode. The specified mode should be one of the
607 * following values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT,
608 * or MODE_COPY_FROM_METADATA.
609 *
610 * @param mode the new tiling mode.
611 */
612 public void setTilingMode(int mode) {
613 checkTiling();
614
615 switch (mode) {
616 case MODE_EXPLICIT: {
617 tilingMode = mode;
618 unsetTiling();
619 break;
620 }
621 case MODE_COPY_FROM_METADATA:
622 case MODE_DISABLED:
623 case MODE_DEFAULT: {
624 tilingMode = mode;
625 break;
626 }
627 default: {
628 throw new IllegalArgumentException("Illegal value for mode!");
629 }
630 }
631 }
632}
633