001    /* ImageWriteParam.java --
002       Copyright (C) 2004  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.imageio;
040    
041    import java.awt.Dimension;
042    import java.util.Locale;
043    
044    /**
045     * DOCUMENT ME
046     */
047    public class ImageWriteParam extends IIOParam
048    {
049    
050      /**
051       * Can be passed to setTilingMode, setProgressiveMode and
052       * setCompressionMode to disable feature.
053       */
054      public static final int MODE_DISABLED = 0;
055    
056      /**
057       * Can be passed to setTilingMode, setProgressiveMode and
058       * setCompressionMode to enable feature.
059       */
060      public static final int MODE_DEFAULT = 1;
061    
062      /**
063       * Can be passed to setTilingMode, setCompressionMode to disable feature.
064       */
065      public static final int MODE_EXPLICIT = 2;
066    
067      /**
068       * Can be passed to setTilingMode, setProgressiveMode and
069       * setCompressionMode to enable feature.
070       */
071      public static final int MODE_COPY_FROM_METADATA = 3;
072    
073      /**
074       * True if tiling grid offset parameters can be set.
075       */
076      protected boolean canOffsetTiles;
077    
078      /**
079       * True if this writer can write images using compression.
080       */
081      protected boolean canWriteCompressed;
082    
083      /**
084       * True if images can be written as a progressive sequence
085       * of increasing quality.
086       */
087      protected boolean canWriteProgressive;
088    
089      /**
090       * True if tile width and height parameters can be set.
091       */
092      protected boolean canWriteTiles;
093    
094      /**
095       * Controls compression settings, which must be set to one of the four
096       * MODE_* values.
097       */
098      protected int compressionMode = MODE_COPY_FROM_METADATA;
099    
100      /**
101       * Contains the current compression quality setting.
102       */
103      protected float compressionQuality;
104    
105      /**
106       * Contains the name of the current compression type.
107       */
108      protected String compressionType;
109    
110      /**
111       * Array of the names of the available compression types.
112       */
113      protected String[] compressionTypes;
114    
115      /**
116       * Localizes compression type names and quality descriptions,
117       * or null to use default Locale.
118       */
119      protected Locale locale;
120    
121      /**
122       * Preferred tile size range pairs.
123       */
124      protected Dimension[] preferredTileSizes;
125    
126      /**
127       * The mode controlling progressive encoding, which must
128       * be set to one of the four MODE_* values, except
129       * MODE_EXPLICIT.
130       */
131      protected int progressiveMode = MODE_COPY_FROM_METADATA;
132    
133      /**
134       * The amount by which the tile grid origin should be offset
135       * horizontally from the image origin if tiling has been set.
136       */
137      protected int tileGridXOffset;
138    
139      /**
140       * The amount by which the tile grid origin should be offset
141       * vertically from the image origin if tiling has been set.
142       */
143      protected int tileGridYOffset;
144    
145      /**
146       * The height of each tile if tiling has been set.
147       */
148      protected int tileHeight;
149    
150      /**
151       * The width of each tile if tiling has been set.
152       */
153      protected int tileWidth;
154    
155      /**
156       * The mode controlling tiling settings, which must be
157       * set to one of the four MODE_* values.
158       */
159      protected int tilingMode;
160    
161      /**
162       * True if the tiling parameters have been specified.
163       */
164      protected boolean tilingSet;
165    
166      /**
167       * Creates an empty <code>ImageWriteParam</code> object.
168       * The subclass is responsible to initialize all fields.
169       */
170      protected ImageWriteParam()
171      {
172        // Do nothing here.
173      }
174    
175      /**
176       * Creates an <code>ImageWriteParam</code> object with the given locale.
177       *
178       * @param locale the locale to use for user visible strings
179       */
180      public ImageWriteParam(Locale locale)
181      {
182        this.locale = locale;
183      }
184    
185      public float getBitRate(float quality)
186      {
187        checkNotExplicitCompression();
188        checkCompressionTypesSet();
189    
190        return -1.0f;
191      }
192    
193      private void checkSupportsCompression()
194      {
195        if (! canWriteCompressed())
196          throw new UnsupportedOperationException("compression not supported");
197      }
198    
199      private void checkNotExplicitCompression()
200      {
201        if (getCompressionMode() != MODE_EXPLICIT)
202          throw new IllegalStateException("compression mode is not MODE_EXPLICIT");
203      }
204    
205      private void checkCompressionTypesSet()
206      {
207        if (getCompressionType() == null
208            && getCompressionTypes() != null)
209          throw new IllegalStateException("no compression type set");
210      }
211    
212      private void checkSupportsProgressiveEncoding()
213      {
214        if (! canWriteProgressive())
215          throw new UnsupportedOperationException
216            ("progressive output not supported");
217      }
218    
219      private void checkSupportsTiling()
220      {
221        if (! canWriteTiles())
222          throw new UnsupportedOperationException("tiling not supported");
223      }
224    
225      private void checkNotExplicitTiling()
226      {
227        if (getTilingMode() != MODE_EXPLICIT)
228          throw new IllegalStateException("tiling mode not MODE_EXPLICIT");
229      }
230    
231      private void checkTilingInitialized()
232      {
233        if (! tilingSet)
234          throw new IllegalStateException("tiling parameters not set");
235      }
236    
237      private void checkMode(int mode)
238      {
239        if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA)
240          throw new IllegalArgumentException("mode not supported");
241      }
242    
243      public boolean canOffsetTiles()
244      {
245        return canOffsetTiles;
246      }
247    
248      public boolean canWriteCompressed()
249      {
250        return canWriteCompressed;
251      }
252    
253      public boolean canWriteProgressive()
254      {
255        return canWriteProgressive;
256      }
257    
258      public boolean canWriteTiles()
259      {
260        return canWriteTiles;
261      }
262    
263      public int getCompressionMode()
264      {
265        checkSupportsCompression();
266    
267        return compressionMode;
268      }
269    
270      public float getCompressionQuality()
271      {
272        checkNotExplicitCompression();
273        checkCompressionTypesSet();
274    
275        return compressionQuality;
276      }
277    
278      public String[] getCompressionQualityDescriptions()
279      {
280        checkNotExplicitCompression();
281        checkCompressionTypesSet();
282    
283        return null;
284      }
285    
286      public float[] getCompressionQualityValues()
287      {
288        checkNotExplicitCompression();
289        checkCompressionTypesSet();
290    
291        return null;
292      }
293    
294      public String getCompressionType()
295      {
296        checkNotExplicitCompression();
297    
298        return compressionType;
299      }
300    
301      public String[] getCompressionTypes()
302      {
303        checkSupportsCompression();
304    
305        return compressionTypes != null ? (String[]) compressionTypes.clone() : null;
306      }
307    
308      public Locale getLocale()
309      {
310        return locale;
311      }
312    
313      public String getLocalizedCompressionTypeName()
314      {
315        checkNotExplicitCompression();
316        checkCompressionTypesSet();
317    
318        return getCompressionType();
319      }
320    
321      public Dimension[] getPreferredTileSizes()
322      {
323        checkSupportsTiling();
324    
325        return preferredTileSizes;
326      }
327    
328      public int getProgressiveMode()
329      {
330        checkSupportsProgressiveEncoding();
331    
332        return progressiveMode;
333      }
334    
335      public int getTileGridXOffset()
336      {
337        checkNotExplicitTiling();
338        checkTilingInitialized();
339    
340        return tileGridXOffset;
341      }
342    
343      public int getTileGridYOffset()
344      {
345        checkNotExplicitTiling();
346        checkTilingInitialized();
347    
348        return tileGridYOffset;
349      }
350    
351      public int getTileHeight()
352      {
353        checkNotExplicitTiling();
354        checkTilingInitialized();
355    
356        return tileHeight;
357      }
358    
359      public int getTileWidth()
360      {
361        checkNotExplicitTiling();
362        checkTilingInitialized();
363    
364        return tileWidth;
365      }
366    
367      public int getTilingMode()
368      {
369        checkSupportsTiling();
370    
371        return tilingMode;
372      }
373    
374      public boolean isCompressionLossless()
375      {
376        checkNotExplicitCompression();
377        checkCompressionTypesSet();
378    
379        return true;
380      }
381    
382      public void setCompressionMode(int mode)
383      {
384        checkSupportsCompression();
385        checkMode(mode);
386    
387        compressionMode = mode;
388    
389        if (mode == MODE_EXPLICIT)
390          unsetCompression();
391      }
392    
393      public void setCompressionQuality(float quality)
394      {
395        checkNotExplicitCompression();
396        checkCompressionTypesSet();
397    
398        if (quality < 0.0f || quality > 1.0f)
399          throw new IllegalArgumentException("quality out of range");
400    
401        compressionQuality = quality;
402      }
403    
404      public void setCompressionType(String compressionType)
405      {
406        checkNotExplicitCompression();
407    
408        String[] types = getCompressionTypes();
409    
410        if (types == null)
411          throw new UnsupportedOperationException("no settable compression types");
412    
413        if (compressionType == null)
414          this.compressionType = null;
415    
416        for (int i = types.length - 1; i >= 0; --i)
417          if (types[i].equals(compressionType))
418            {
419              this.compressionType = compressionType;
420              return;
421            }
422    
423        throw new IllegalArgumentException("unknown compression type");
424      }
425    
426      public void setProgressiveMode(int mode)
427      {
428        checkSupportsProgressiveEncoding();
429        checkMode(mode);
430    
431        progressiveMode = mode;
432      }
433    
434      public void setTiling(int tileWidth, int tileHeight,
435                            int tileGridXOffset, int tileGridYOffset)
436      {
437        checkNotExplicitTiling();
438    
439        if (! canOffsetTiles
440            && tileGridXOffset != 0
441            && tileGridYOffset != 0)
442          throw new UnsupportedOperationException("tile offsets not supported");
443    
444        if (tileWidth < 0 || tileHeight < 0)
445          throw new IllegalArgumentException("negative tile dimension");
446    
447        if (preferredTileSizes != null)
448          {
449            boolean found = false;
450    
451            for (int i = 0; i < preferredTileSizes.length; i += 2)
452              {
453                if (tileWidth >= preferredTileSizes[i].width
454                    && tileWidth <= preferredTileSizes[i + 1].width
455                    && tileHeight >= preferredTileSizes[i].height
456                    && tileHeight <= preferredTileSizes[i + 1].height)
457                  found = true;
458              }
459    
460            if (! found)
461              throw new IllegalArgumentException("illegal tile size");
462          }
463    
464        this.tilingSet = true;
465        this.tileWidth = tileWidth;
466        this.tileHeight = tileHeight;
467        this.tileGridXOffset = tileGridXOffset;
468        this.tileGridYOffset = tileGridYOffset;
469      }
470    
471      public void setTilingMode(int mode)
472      {
473        checkSupportsTiling();
474        checkMode(mode);
475        tilingMode = mode;
476      }
477    
478      public void unsetCompression()
479      {
480        checkNotExplicitCompression();
481    
482        compressionType = null;
483        compressionQuality = 1.0F;
484      }
485    
486      public void unsetTiling()
487      {
488        checkNotExplicitTiling();
489    
490        tileWidth = 0;
491        tileHeight = 0;
492        tileGridXOffset = 0;
493        tileGridYOffset = 0;
494      }
495    }