summaryrefslogtreecommitdiffstats
path: root/awt/javax/imageio/ImageWriteParam.java
blob: d661889b2fcfa67b1c24a6a15583aa0919091ba6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/**
 * @author Rustem V. Rafikov
 * @version $Revision: 1.3 $
 */

package javax.imageio;

import java.util.Locale;
import java.awt.*;

/**
 * The ImageWriteParam class provides information to an ImageWriter about how an
 * image is to be encoded.
 * 
 * @since Android 1.0
 */
public class ImageWriteParam extends IIOParam {

    /**
     * The Constant MODE_DISABLED indicates that stream is not tiled,
     * progressive, or compressed.
     */
    public static final int MODE_DISABLED = 0;

    /**
     * The Constant MODE_DEFAULT indicates that the stream will be tiled,
     * progressive, or compressed according to the plug-in's default.
     */
    public static final int MODE_DEFAULT = 1;

    /**
     * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
     * progressive, or compressed according to current settings which are
     * defined by set methods.
     */
    public static final int MODE_EXPLICIT = 2;

    /**
     * The Constant MODE_COPY_FROM_METADATA indicates that the stream will be
     * tiled, progressive, or compressed according to stream or image metadata.
     */
    public static final int MODE_COPY_FROM_METADATA = 3;

    /**
     * Whether the ImageWriter can write tiles.
     */
    protected boolean canWriteTiles = false;

    /**
     * The tiling mode.
     */
    protected int tilingMode = MODE_COPY_FROM_METADATA;

    /**
     * The preferred tile sizes.
     */
    protected Dimension[] preferredTileSizes = null;

    /**
     * The tiling set.
     */
    protected boolean tilingSet = false;

    /**
     * The tile width.
     */
    protected int tileWidth = 0;

    /**
     * The tile height.
     */
    protected int tileHeight = 0;

    /**
     * Whether the ImageWriter can offset tiles.
     */
    protected boolean canOffsetTiles = false;

    /**
     * The tile grid x offset.
     */
    protected int tileGridXOffset = 0;

    /**
     * The tile grid y offset.
     */
    protected int tileGridYOffset = 0;

    /**
     * Whether the ImageWriter can write in progressive mode.
     */
    protected boolean canWriteProgressive = false;

    /**
     * The progressive mode.
     */
    protected int progressiveMode = MODE_COPY_FROM_METADATA;

    /**
     * Whether the ImageWriter can write in compressed mode.
     */
    protected boolean canWriteCompressed = false;

    /**
     * The compression mode.
     */
    protected int compressionMode = MODE_COPY_FROM_METADATA;

    /**
     * The compression types.
     */
    protected String[] compressionTypes = null;

    /**
     * The compression type.
     */
    protected String compressionType = null;

    /**
     * The compression quality.
     */
    protected float compressionQuality = 1.0f;

    /**
     * The locale.
     */
    protected Locale locale = null;

    /**
     * Instantiates a new ImageWriteParam.
     */
    protected ImageWriteParam() {
    }

    /**
     * Instantiates a new ImageWriteParam with the specified Locale.
     * 
     * @param locale
     *            the Locale.
     */
    public ImageWriteParam(Locale locale) {
        this.locale = locale;

    }

    /**
     * Gets the mode for writing the stream in a progressive sequence.
     * 
     * @return the current progressive mode.
     */
    public int getProgressiveMode() {
        if (canWriteProgressive()) {
            return progressiveMode;
        }
        throw new UnsupportedOperationException("progressive mode is not supported");
    }

    /**
     * Returns true if images can be written using increasing quality passes by
     * progressive.
     * 
     * @return true if images can be written using increasing quality passes by
     *         progressive, false otherwise.
     */
    public boolean canWriteProgressive() {
        return canWriteProgressive;
    }

    /**
     * Sets the progressive mode which defines whether the stream contains a
     * progressive sequence of increasing quality during writing. The
     * progressive mode should be one of the following values: MODE_DISABLED,
     * MODE_DEFAULT, or MODE_COPY_FROM_METADATA.
     * 
     * @param mode
     *            the new progressive mode.
     */
    public void setProgressiveMode(int mode) {
        if (canWriteProgressive()) {
            if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
                throw new IllegalArgumentException("mode is not supported");
            }
            this.progressiveMode = mode;
        }
        throw new UnsupportedOperationException("progressive mode is not supported");
    }

    /**
     * Returns true if the writer can use tiles with non zero grid offsets while
     * writing.
     * 
     * @return true, if the writer can use tiles with non zero grid offsets
     *         while writing, false otherwise.
     */
    public boolean canOffsetTiles() {
        return canOffsetTiles;
    }

    /**
     * Returns true if this writer can write images with compression.
     * 
     * @return true, if this writer can write images with compression, false
     *         otherwise.
     */
    public boolean canWriteCompressed() {
        return canWriteCompressed;
    }

    /**
     * Returns true if the writer can write tiles.
     * 
     * @return true, if the writer can write tiles, false otherwise.
     */
    public boolean canWriteTiles() {
        return canWriteTiles;
    }

    /**
     * Check write compressed.
     */
    private final void checkWriteCompressed() {
        if (!canWriteCompressed()) {
            throw new UnsupportedOperationException("Compression not supported.");
        }
    }

    /**
     * Check compression mode.
     */
    private final void checkCompressionMode() {
        if (getCompressionMode() != MODE_EXPLICIT) {
            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
        }
    }

    /**
     * Check compression type.
     */
    private final void checkCompressionType() {
        if (getCompressionTypes() != null && getCompressionType() == null) {
            throw new IllegalStateException("No compression type set!");
        }
    }

    /**
     * Gets the compression mode.
     * 
     * @return the compression mode if it's supported.
     */
    public int getCompressionMode() {
        checkWriteCompressed();
        return compressionMode;
    }

    /**
     * Gets the an array of supported compression types.
     * 
     * @return the an array of supported compression types.
     */
    public String[] getCompressionTypes() {
        checkWriteCompressed();
        if (compressionTypes != null) {
            return compressionTypes.clone();
        }
        return null;
    }

    /**
     * Gets the current compression type, or returns null.
     * 
     * @return the current compression type, or returns null if it is not set.
     */
    public String getCompressionType() {
        checkWriteCompressed();
        checkCompressionMode();
        return compressionType;
    }

    /**
     * Gets a bit rate which represents an estimate of the number of bits of
     * output data for each bit of input image data with the specified quality.
     * 
     * @param quality
     *            the quality.
     * @return an estimate of the bit rate, or -1.0F if there is no estimate.
     */
    public float getBitRate(float quality) {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        if (quality < 0 || quality > 1) {
            throw new IllegalArgumentException("Quality out-of-bounds!");
        }
        return -1.0f;
    }

    /**
     * Gets the compression quality.
     * 
     * @return the compression quality.
     */
    public float getCompressionQuality() {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        return compressionQuality;
    }

    /**
     * Gets the array of compression quality descriptions.
     * 
     * @return the string array of compression quality descriptions.
     */
    public String[] getCompressionQualityDescriptions() {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        return null;
    }

    /**
     * Gets an array of floats which describes compression quality levels.
     * 
     * @return the array of compression quality values.
     */
    public float[] getCompressionQualityValues() {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        return null;
    }

    /**
     * Gets the locale of this ImageWriteParam.
     * 
     * @return the locale of this ImageWriteParam.
     */
    public Locale getLocale() {
        return locale;
    }

    /**
     * Gets the current compression type using the current Locale.
     * 
     * @return the current compression type using the current Locale.
     */
    public String getLocalizedCompressionTypeName() {
        checkWriteCompressed();
        checkCompressionMode();

        String compressionType = getCompressionType();
        if (compressionType == null) {
            throw new IllegalStateException("No compression type set!");
        }
        return compressionType;

    }

    /**
     * Check tiling.
     */
    private final void checkTiling() {
        if (!canWriteTiles()) {
            throw new UnsupportedOperationException("Tiling not supported!");
        }
    }

    /**
     * Check tiling mode.
     */
    private final void checkTilingMode() {
        if (getTilingMode() != MODE_EXPLICIT) {
            throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
        }
    }

    /**
     * Check tiling params.
     */
    private final void checkTilingParams() {
        if (!tilingSet) {
            throw new IllegalStateException("Tiling parameters not set!");
        }
    }

    /**
     * Gets the tiling mode if tiling is supported.
     * 
     * @return the tiling mode if tiling is supported.
     */
    public int getTilingMode() {
        checkTiling();
        return tilingMode;
    }

    /**
     * Gets an array of Dimensions giving the sizes of the tiles as they are
     * encoded in the output file or stream.
     * 
     * @return the preferred tile sizes.
     */
    public Dimension[] getPreferredTileSizes() {
        checkTiling();
        if (preferredTileSizes == null) {
            return null;
        }

        Dimension[] retval = new Dimension[preferredTileSizes.length];
        for (int i = 0; i < preferredTileSizes.length; i++) {
            retval[i] = new Dimension(retval[i]);
        }
        return retval;
    }

    /**
     * Gets the tile grid X offset for encoding.
     * 
     * @return the tile grid X offset for encoding.
     */
    public int getTileGridXOffset() {
        checkTiling();
        checkTilingMode();
        checkTilingParams();
        return tileGridXOffset;
    }

    /**
     * Gets the tile grid Y offset for encoding.
     * 
     * @return the tile grid Y offset for encoding.
     */
    public int getTileGridYOffset() {
        checkTiling();
        checkTilingMode();
        checkTilingParams();
        return tileGridYOffset;
    }

    /**
     * Gets the tile height in an image as it is written to the output stream.
     * 
     * @return the tile height in an image as it is written to the output
     *         stream.
     */
    public int getTileHeight() {
        checkTiling();
        checkTilingMode();
        checkTilingParams();
        return tileHeight;
    }

    /**
     * Gets the tile width in an image as it is written to the output stream.
     * 
     * @return the tile width in an image as it is written to the output stream.
     */
    public int getTileWidth() {
        checkTiling();
        checkTilingMode();
        checkTilingParams();
        return tileWidth;
    }

    /**
     * Checks if the current compression type has lossless compression or not.
     * 
     * @return true, if the current compression type has lossless compression,
     *         false otherwise.
     */
    public boolean isCompressionLossless() {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        return true;
    }

    /**
     * Removes current compression type.
     */
    public void unsetCompression() {
        checkWriteCompressed();
        checkCompressionMode();
        compressionType = null;
        compressionQuality = 1;
    }

    /**
     * Sets the compression mode to the specified value. The specified mode can
     * be one of the predefined constants: MODE_DEFAULT, MODE_DISABLED,
     * MODE_EXPLICIT, or MODE_COPY_FROM_METADATA.
     * 
     * @param mode
     *            the new compression mode to be set.
     */
    public void setCompressionMode(int mode) {
        checkWriteCompressed();
        switch (mode) {
            case MODE_EXPLICIT: {
                compressionMode = mode;
                unsetCompression();
                break;
            }
            case MODE_COPY_FROM_METADATA:
            case MODE_DISABLED:
            case MODE_DEFAULT: {
                compressionMode = mode;
                break;
            }
            default: {
                throw new IllegalArgumentException("Illegal value for mode!");
            }
        }
    }

    /**
     * Sets the compression quality. The value should be between 0 and 1.
     * 
     * @param quality
     *            the new compression quality, float value between 0 and 1.
     */
    public void setCompressionQuality(float quality) {
        checkWriteCompressed();
        checkCompressionMode();
        checkCompressionType();
        if (quality < 0 || quality > 1) {
            throw new IllegalArgumentException("Quality out-of-bounds!");
        }
        compressionQuality = quality;
    }

    /**
     * Sets the compression type. The specified string should be one of the
     * values returned by getCompressionTypes method.
     * 
     * @param compressionType
     *            the new compression type.
     */
    public void setCompressionType(String compressionType) {
        checkWriteCompressed();
        checkCompressionMode();

        if (compressionType == null) { // Don't check anything
            this.compressionType = null;
        } else {
            String[] compressionTypes = getCompressionTypes();
            if (compressionTypes == null) {
                throw new UnsupportedOperationException("No settable compression types");
            }

            for (int i = 0; i < compressionTypes.length; i++) {
                if (compressionTypes[i].equals(compressionType)) {
                    this.compressionType = compressionType;
                    return;
                }
            }

            // Compression type is not in the list.
            throw new IllegalArgumentException("Unknown compression type!");
        }
    }

    /**
     * Sets the instruction that tiling should be performed for the image in the
     * output stream with the specified parameters.
     * 
     * @param tileWidth
     *            the tile's width.
     * @param tileHeight
     *            the tile's height.
     * @param tileGridXOffset
     *            the tile grid's x offset.
     * @param tileGridYOffset
     *            the tile grid's y offset.
     */
    public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
        checkTiling();
        checkTilingMode();

        if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
            throw new UnsupportedOperationException("Can't offset tiles!");
        }

        if (tileWidth <= 0 || tileHeight <= 0) {
            throw new IllegalArgumentException("tile dimensions are non-positive!");
        }

        Dimension preferredTileSizes[] = getPreferredTileSizes();
        if (preferredTileSizes != null) {
            for (int i = 0; i < preferredTileSizes.length; i += 2) {
                Dimension minSize = preferredTileSizes[i];
                Dimension maxSize = preferredTileSizes[i + 1];
                if (tileWidth < minSize.width || tileWidth > maxSize.width
                        || tileHeight < minSize.height || tileHeight > maxSize.height) {
                    throw new IllegalArgumentException("Illegal tile size!");
                }
            }
        }

        tilingSet = true;
        this.tileWidth = tileWidth;
        this.tileHeight = tileHeight;
        this.tileGridXOffset = tileGridXOffset;
        this.tileGridYOffset = tileGridYOffset;
    }

    /**
     * Clears all tiling settings.
     */
    public void unsetTiling() {
        checkTiling();
        checkTilingMode();

        tilingSet = false;
        tileWidth = 0;
        tileHeight = 0;
        tileGridXOffset = 0;
        tileGridYOffset = 0;
    }

    /**
     * Sets the tiling mode. The specified mode should be one of the following
     * values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT, or
     * MODE_COPY_FROM_METADATA.
     * 
     * @param mode
     *            the new tiling mode.
     */
    public void setTilingMode(int mode) {
        checkTiling();

        switch (mode) {
            case MODE_EXPLICIT: {
                tilingMode = mode;
                unsetTiling();
                break;
            }
            case MODE_COPY_FROM_METADATA:
            case MODE_DISABLED:
            case MODE_DEFAULT: {
                tilingMode = mode;
                break;
            }
            default: {
                throw new IllegalArgumentException("Illegal value for mode!");
            }
        }
    }
}