Home | History | Annotate | Download | only in imageio
      1 /*
      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  */
     21 
     22 package javax.imageio;
     23 
     24 import java.awt.Dimension;
     25 import java.awt.Rectangle;
     26 import java.awt.image.BufferedImage;
     27 import java.awt.image.Raster;
     28 import java.awt.image.RenderedImage;
     29 import java.io.IOException;
     30 import java.security.AccessController;
     31 import java.security.PrivilegedAction;
     32 import java.util.ArrayList;
     33 import java.util.List;
     34 import java.util.Locale;
     35 import java.util.MissingResourceException;
     36 import java.util.ResourceBundle;
     37 
     38 import javax.imageio.event.IIOWriteProgressListener;
     39 import javax.imageio.event.IIOWriteWarningListener;
     40 import javax.imageio.metadata.IIOMetadata;
     41 import javax.imageio.spi.ImageWriterSpi;
     42 
     43 /**
     44  * The ImageWriter class is an abstract class for encoding images. ImageWriter
     45  * objects are instantiated by the service provider interface, ImageWriterSpi
     46  * class, for the specific format. ImageWriterSpi class should be registered
     47  * with the IIORegistry, which uses them for format recognition and presentation
     48  * of available format readers and writers.
     49  *
     50  * @since Android 1.0
     51  */
     52 public abstract class ImageWriter implements ImageTranscoder {
     53 
     54     /**
     55      * The available locales.
     56      */
     57     protected Locale[] availableLocales;
     58 
     59     /**
     60      * The locale.
     61      */
     62     protected Locale locale;
     63 
     64     /**
     65      * The originating provider.
     66      */
     67     protected ImageWriterSpi originatingProvider;
     68 
     69     /**
     70      * The output.
     71      */
     72     protected Object output;
     73 
     74     /**
     75      * The progress listeners.
     76      */
     77     protected List<IIOWriteProgressListener> progressListeners;
     78 
     79     /**
     80      * The warning listeners.
     81      */
     82     protected List<IIOWriteWarningListener> warningListeners;
     83 
     84     /**
     85      * The warning locales.
     86      */
     87     protected List<Locale> warningLocales;
     88 
     89     // Indicates that abort operation is requested
     90     // Abort mechanism should be thread-safe
     91     /** The aborted. */
     92     private boolean aborted;
     93 
     94     /**
     95      * Instantiates a new ImageWriter.
     96      *
     97      * @param originatingProvider
     98      *            the ImageWriterSpi which instantiates this ImageWriter.
     99      */
    100     protected ImageWriter(ImageWriterSpi originatingProvider) {
    101         this.originatingProvider = originatingProvider;
    102     }
    103 
    104     public abstract IIOMetadata convertStreamMetadata(IIOMetadata iioMetadata,
    105             ImageWriteParam imageWriteParam);
    106 
    107     public abstract IIOMetadata convertImageMetadata(IIOMetadata iioMetadata,
    108             ImageTypeSpecifier imageTypeSpecifier, ImageWriteParam imageWriteParam);
    109 
    110     /**
    111      * Gets the ImageWriterSpi which instantiated this ImageWriter.
    112      *
    113      * @return the ImageWriterSpi.
    114      */
    115     public ImageWriterSpi getOriginatingProvider() {
    116         return originatingProvider;
    117     }
    118 
    119     /**
    120      * Processes the start of an image read by calling their imageStarted method
    121      * of registered IIOWriteProgressListeners.
    122      *
    123      * @param imageIndex
    124      *            the image index.
    125      */
    126     protected void processImageStarted(int imageIndex) {
    127         if (null != progressListeners) {
    128             for (IIOWriteProgressListener listener : progressListeners) {
    129                 listener.imageStarted(this, imageIndex);
    130             }
    131         }
    132     }
    133 
    134     /**
    135      * Processes the current percentage of image completion by calling
    136      * imageProgress method of registered IIOWriteProgressListener.
    137      *
    138      * @param percentageDone
    139      *            the percentage done.
    140      */
    141     protected void processImageProgress(float percentageDone) {
    142         if (null != progressListeners) {
    143             for (IIOWriteProgressListener listener : progressListeners) {
    144                 listener.imageProgress(this, percentageDone);
    145             }
    146         }
    147     }
    148 
    149     /**
    150      * Processes image completion by calling imageComplete method of registered
    151      * IIOWriteProgressListeners.
    152      */
    153     protected void processImageComplete() {
    154         if (null != progressListeners) {
    155             for (IIOWriteProgressListener listener : progressListeners) {
    156                 listener.imageComplete(this);
    157             }
    158         }
    159     }
    160 
    161     /**
    162      * Processes a warning message by calling warningOccurred method of
    163      * registered IIOWriteWarningListeners.
    164      *
    165      * @param imageIndex
    166      *            the image index.
    167      * @param warning
    168      *            the warning.
    169      */
    170     protected void processWarningOccurred(int imageIndex, String warning) {
    171         if (null == warning) {
    172             throw new NullPointerException("warning message should not be NULL");
    173         }
    174         if (null != warningListeners) {
    175             for (IIOWriteWarningListener listener : warningListeners) {
    176                 listener.warningOccurred(this, imageIndex, warning);
    177             }
    178         }
    179     }
    180 
    181     /**
    182      * Processes a warning message by calling warningOccurred method of
    183      * registered IIOWriteWarningListeners with string from ResourceBundle.
    184      *
    185      * @param imageIndex
    186      *            the image index.
    187      * @param bundle
    188      *            the name of ResourceBundle.
    189      * @param key
    190      *            the keyword.
    191      */
    192     protected void processWarningOccurred(int imageIndex, String bundle, String key) {
    193         if (warningListeners != null) { // Don't check the parameters
    194             return;
    195         }
    196 
    197         if (bundle == null) {
    198             throw new IllegalArgumentException("baseName == null!");
    199         }
    200         if (key == null) {
    201             throw new IllegalArgumentException("keyword == null!");
    202         }
    203 
    204         // Get the context class loader and try to locate the bundle with it
    205         // first
    206         ClassLoader contextClassloader = AccessController
    207                 .doPrivileged(new PrivilegedAction<ClassLoader>() {
    208                     public ClassLoader run() {
    209                         return Thread.currentThread().getContextClassLoader();
    210                     }
    211                 });
    212 
    213         // Iterate through both listeners and locales
    214         int n = warningListeners.size();
    215         for (int i = 0; i < n; i++) {
    216             IIOWriteWarningListener listener = warningListeners.get(i);
    217             Locale locale = warningLocales.get(i);
    218 
    219             // Now try to get the resource bundle
    220             ResourceBundle rb;
    221             try {
    222                 rb = ResourceBundle.getBundle(bundle, locale, contextClassloader);
    223             } catch (MissingResourceException e) {
    224                 try {
    225                     rb = ResourceBundle.getBundle(bundle, locale);
    226                 } catch (MissingResourceException e1) {
    227                     throw new IllegalArgumentException("Bundle not found!");
    228                 }
    229             }
    230 
    231             try {
    232                 String warning = rb.getString(key);
    233                 listener.warningOccurred(this, imageIndex, warning);
    234             } catch (MissingResourceException e) {
    235                 throw new IllegalArgumentException("Resource is missing!");
    236             } catch (ClassCastException e) {
    237                 throw new IllegalArgumentException("Resource is not a String!");
    238             }
    239         }
    240     }
    241 
    242     /**
    243      * Sets the specified Object to the output of this ImageWriter.
    244      *
    245      * @param output
    246      *            the Object which represents destination, it can be
    247      *            ImageOutputStream or other objects.
    248      */
    249     public void setOutput(Object output) {
    250         if (output != null) {
    251             ImageWriterSpi spi = getOriginatingProvider();
    252             if (null != spi) {
    253                 Class[] outTypes = spi.getOutputTypes();
    254                 boolean supported = false;
    255                 for (Class<?> element : outTypes) {
    256                     if (element.isInstance(output)) {
    257                         supported = true;
    258                         break;
    259                     }
    260                 }
    261                 if (!supported) {
    262                     throw new IllegalArgumentException("output " + output + " is not supported");
    263                 }
    264             }
    265         }
    266         this.output = output;
    267     }
    268 
    269     /**
    270      * Writes a completed image stream that contains the specified image,
    271      * default metadata, and thumbnails to the output.
    272      *
    273      * @param image
    274      *            the specified image to be written.
    275      * @throws IOException
    276      *             if an I/O exception has occurred during writing.
    277      */
    278     public void write(IIOImage image) throws IOException {
    279         write(null, image, null);
    280     }
    281 
    282     /**
    283      * Writes a completed image stream that contains the specified rendered
    284      * image, default metadata, and thumbnails to the output.
    285      *
    286      * @param image
    287      *            the specified RenderedImage to be written.
    288      * @throws IOException
    289      *             if an I/O exception has occurred during writing.
    290      */
    291     public void write(RenderedImage image) throws IOException {
    292         write(null, new IIOImage(image, null, null), null);
    293     }
    294 
    295     /**
    296      * Writes a completed image stream that contains the specified image,
    297      * metadata and thumbnails to the output.
    298      *
    299      * @param streamMetadata
    300      *            the stream metadata, or null.
    301      * @param image
    302      *            the specified image to be written, if canWriteRaster() method
    303      *            returns false, then Image must contain only RenderedImage.
    304      * @param param
    305      *            the ImageWriteParam, or null.
    306      * @throws IOException
    307      *             if an error occurs during writing.
    308      */
    309     public abstract void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param)
    310             throws IOException;
    311 
    312     /**
    313      * Disposes of any resources.
    314      */
    315     public void dispose() {
    316         // def impl. does nothing according to the spec.
    317     }
    318 
    319     /**
    320      * Requests an abort operation for current writing operation.
    321      */
    322     public synchronized void abort() {
    323         aborted = true;
    324     }
    325 
    326     /**
    327      * Checks whether or not a request to abort the current write operation has
    328      * been made successfully.
    329      *
    330      * @return true, if the request to abort the current write operation has
    331      *         been made successfully, false otherwise.
    332      */
    333     protected synchronized boolean abortRequested() {
    334         return aborted;
    335     }
    336 
    337     /**
    338      * Clears all previous abort request, and abortRequested returns false after
    339      * calling this method.
    340      */
    341     protected synchronized void clearAbortRequest() {
    342         aborted = false;
    343     }
    344 
    345     /**
    346      * Adds the IIOWriteProgressListener listener.
    347      *
    348      * @param listener
    349      *            the IIOWriteProgressListener listener.
    350      */
    351     public void addIIOWriteProgressListener(IIOWriteProgressListener listener) {
    352         if (listener == null) {
    353             return;
    354         }
    355 
    356         if (progressListeners == null) {
    357             progressListeners = new ArrayList<IIOWriteProgressListener>();
    358         }
    359 
    360         progressListeners.add(listener);
    361     }
    362 
    363     /**
    364      * Adds the IIOWriteWarningListener.
    365      *
    366      * @param listener
    367      *            the IIOWriteWarningListener listener.
    368      */
    369     public void addIIOWriteWarningListener(IIOWriteWarningListener listener) {
    370         if (listener == null) {
    371             return;
    372         }
    373 
    374         if (warningListeners == null) {
    375             warningListeners = new ArrayList<IIOWriteWarningListener>();
    376             warningLocales = new ArrayList<Locale>();
    377         }
    378 
    379         warningListeners.add(listener);
    380         warningLocales.add(getLocale());
    381     }
    382 
    383     /**
    384      * Gets the output object that was set by setOutput method.
    385      *
    386      * @return the output object such as ImageOutputStream, or null if it is not
    387      *         set.
    388      */
    389     public Object getOutput() {
    390         return output;
    391     }
    392 
    393     /**
    394      * Check output return false.
    395      *
    396      * @return true, if successful.
    397      */
    398     private final boolean checkOutputReturnFalse() {
    399         if (getOutput() == null) {
    400             throw new IllegalStateException("getOutput() == null!");
    401         }
    402         return false;
    403     }
    404 
    405     /**
    406      * Unsupported operation.
    407      */
    408     private final void unsupportedOperation() {
    409         if (getOutput() == null) {
    410             throw new IllegalStateException("getOutput() == null!");
    411         }
    412         throw new UnsupportedOperationException("Unsupported write variant!");
    413     }
    414 
    415     /**
    416      * Returns true if a new empty image can be inserted at the specified index.
    417      *
    418      * @param imageIndex
    419      *            the specified index of image.
    420      * @return true if a new empty image can be inserted at the specified index,
    421      *         false otherwise.
    422      * @throws IOException
    423      *             Signals that an I/O exception has occurred.
    424      */
    425     public boolean canInsertEmpty(int imageIndex) throws IOException {
    426         return checkOutputReturnFalse();
    427     }
    428 
    429     /**
    430      * Returns true if a new image can be inserted at the specified index.
    431      *
    432      * @param imageIndex
    433      *            the specified index of image.
    434      * @return true if a new image can be inserted at the specified index, false
    435      *         otherwise.
    436      * @throws IOException
    437      *             Signals that an I/O exception has occurred.
    438      */
    439     public boolean canInsertImage(int imageIndex) throws IOException {
    440         return checkOutputReturnFalse();
    441     }
    442 
    443     /**
    444      * Returns true if the image with the specified index can be removed.
    445      *
    446      * @param imageIndex
    447      *            the specified index of image.
    448      * @return true if the image with the specified index can be removed, false
    449      *         otherwise.
    450      * @throws IOException
    451      *             Signals that an I/O exception has occurred.
    452      */
    453     public boolean canRemoveImage(int imageIndex) throws IOException {
    454         return checkOutputReturnFalse();
    455     }
    456 
    457     /**
    458      * Returns true if metadata of the image with the specified index can be
    459      * replaced.
    460      *
    461      * @param imageIndex
    462      *            the specified image index.
    463      * @return true if metadata of the image with the specified index can be
    464      *         replaced, false otherwise.
    465      * @throws IOException
    466      *             if an I/O exception has occurred.
    467      */
    468     public boolean canReplaceImageMetadata(int imageIndex) throws IOException {
    469         return checkOutputReturnFalse();
    470     }
    471 
    472     /**
    473      * Returns true if pixels of the image with the specified index can be
    474      * replaced by the replacePixels methods.
    475      *
    476      * @param imageIndex
    477      *            the image's index.
    478      * @return true if pixels of the image with the specified index can be
    479      *         replaced by the replacePixels methods, false otherwise.
    480      * @throws IOException
    481      *             Signals that an I/O exception has occurred.
    482      */
    483     public boolean canReplacePixels(int imageIndex) throws IOException {
    484         return checkOutputReturnFalse();
    485     }
    486 
    487     /**
    488      * Returns true if the stream metadata presented in the output can be
    489      * removed.
    490      *
    491      * @return true if the stream metadata presented in the output can be
    492      *         removed, false otherwise.
    493      * @throws IOException
    494      *             if an I/O exception has occurred.
    495      */
    496     public boolean canReplaceStreamMetadata() throws IOException {
    497         return checkOutputReturnFalse();
    498     }
    499 
    500     /**
    501      * Returns true if the writing of a complete image stream which contains a
    502      * single image is supported with undefined pixel values and associated
    503      * metadata and thumbnails to the output.
    504      *
    505      * @return true if the writing of a complete image stream which contains a
    506      *         single image is supported, false otherwise.
    507      * @throws IOException
    508      *             if an I/O exception has occurred.
    509      */
    510     public boolean canWriteEmpty() throws IOException {
    511         return checkOutputReturnFalse();
    512     }
    513 
    514     /**
    515      * Returns true if the methods which taken an IIOImageParameter can deal
    516      * with a Raster source image.
    517      *
    518      * @return true if the methods which taken an IIOImageParameter can deal
    519      *         with a Raster source image, false otherwise.
    520      */
    521     public boolean canWriteRasters() {
    522         return false;
    523     }
    524 
    525     /**
    526      * Returns true if the writer can add an image to stream that already
    527      * contains header information.
    528      *
    529      * @return if the writer can add an image to stream that already contains
    530      *         header information, false otherwise.
    531      */
    532     public boolean canWriteSequence() {
    533         return false;
    534     }
    535 
    536     /**
    537      * Ends the insertion of a new image.
    538      *
    539      * @throws IOException
    540      *             if an I/O exception has occurred.
    541      */
    542     public void endInsertEmpty() throws IOException {
    543         unsupportedOperation();
    544     }
    545 
    546     /**
    547      * Ends the replace pixels operation.
    548      *
    549      * @throws IOException
    550      *             if an I/O exception has occurred.
    551      */
    552     public void endReplacePixels() throws IOException {
    553         unsupportedOperation();
    554     }
    555 
    556     /**
    557      * Ends an empty write operation.
    558      *
    559      * @throws IOException
    560      *             if an I/O exception has occurred.
    561      */
    562     public void endWriteEmpty() throws IOException {
    563         unsupportedOperation();
    564     }
    565 
    566     /**
    567      * Ends the sequence of write operations.
    568      *
    569      * @throws IOException
    570      *             if an I/O exception has occurred.
    571      */
    572     public void endWriteSequence() throws IOException {
    573         unsupportedOperation();
    574     }
    575 
    576     /**
    577      * Gets an array of available locales.
    578      *
    579      * @return an of array available locales.
    580      */
    581     public Locale[] getAvailableLocales() {
    582         if (availableLocales == null) {
    583             return null;
    584         }
    585 
    586         return availableLocales.clone();
    587     }
    588 
    589     /**
    590      * Gets an IIOMetadata object that contains default values for encoding an
    591      * image with the specified type.
    592      *
    593      * @param imageType
    594      *            the ImageTypeSpecifier.
    595      * @param param
    596      *            the ImageWriteParam.
    597      * @return the IIOMetadata object.
    598      */
    599     public abstract IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,
    600             ImageWriteParam param);
    601 
    602     /**
    603      * Gets an IIOMetadata object that contains default values for encoding a
    604      * stream of images.
    605      *
    606      * @param param
    607      *            the ImageWriteParam.
    608      * @return the IIOMetadata object.
    609      */
    610     public abstract IIOMetadata getDefaultStreamMetadata(ImageWriteParam param);
    611 
    612     /**
    613      * Gets the current locale of this ImageWriter.
    614      *
    615      * @return the current locale of this ImageWriter.
    616      */
    617     public Locale getLocale() {
    618         return locale;
    619     }
    620 
    621     /**
    622      * Gets the default write param. Gets a new ImageWriteParam object for this
    623      * ImageWriter with the current Locale.
    624      *
    625      * @return a new ImageWriteParam object for this ImageWriter.
    626      */
    627     public ImageWriteParam getDefaultWriteParam() {
    628         return new ImageWriteParam(getLocale());
    629     }
    630 
    631     /**
    632      * Gets the number of thumbnails supported by the format being written with
    633      * supported image type, image write parameters, stream, and image metadata
    634      * objects.
    635      *
    636      * @param imageType
    637      *            the ImageTypeSpecifier.
    638      * @param param
    639      *            the image's parameters.
    640      * @param streamMetadata
    641      *            the stream metadata.
    642      * @param imageMetadata
    643      *            the image metadata.
    644      * @return the number of thumbnails supported.
    645      */
    646     public int getNumThumbnailsSupported(ImageTypeSpecifier imageType, ImageWriteParam param,
    647             IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
    648         return 0;
    649     }
    650 
    651     /**
    652      * Gets the preferred thumbnail sizes. Gets an array of Dimensions with the
    653      * sizes for thumbnail images as they are encoded in the output file or
    654      * stream.
    655      *
    656      * @param imageType
    657      *            the ImageTypeSpecifier.
    658      * @param param
    659      *            the ImageWriteParam.
    660      * @param streamMetadata
    661      *            the stream metadata.
    662      * @param imageMetadata
    663      *            the image metadata.
    664      * @return the preferred thumbnail sizes.
    665      */
    666     public Dimension[] getPreferredThumbnailSizes(ImageTypeSpecifier imageType,
    667             ImageWriteParam param, IIOMetadata streamMetadata, IIOMetadata imageMetadata) {
    668         return null;
    669     }
    670 
    671     /**
    672      * Prepares insertion of an empty image by requesting the insertion of a new
    673      * image into an existing image stream.
    674      *
    675      * @param imageIndex
    676      *            the image index.
    677      * @param imageType
    678      *            the image type.
    679      * @param width
    680      *            the width of the image.
    681      * @param height
    682      *            the height of the image.
    683      * @param imageMetadata
    684      *            the image metadata, or null.
    685      * @param thumbnails
    686      *            the array thumbnails for this image, or null.
    687      * @param param
    688      *            the ImageWriteParam, or null.
    689      * @throws IOException
    690      *             if an I/O exception has occurred.
    691      */
    692     public void prepareInsertEmpty(int imageIndex, ImageTypeSpecifier imageType, int width,
    693             int height, IIOMetadata imageMetadata, List<? extends BufferedImage> thumbnails,
    694             ImageWriteParam param) throws IOException {
    695         unsupportedOperation();
    696     }
    697 
    698     /**
    699      * Prepares the writer to call the replacePixels method for the specified
    700      * region.
    701      *
    702      * @param imageIndex
    703      *            the image's index.
    704      * @param region
    705      *            the specified region.
    706      * @throws IOException
    707      *             if an I/O exception has occurred.
    708      */
    709     public void prepareReplacePixels(int imageIndex, Rectangle region) throws IOException {
    710         unsupportedOperation();
    711     }
    712 
    713     /**
    714      * Prepares the writer for writing an empty image by beginning the process
    715      * of writing a complete image stream that contains a single image with
    716      * undefined pixel values, metadata and thumbnails, to the output.
    717      *
    718      * @param streamMetadata
    719      *            the stream metadata.
    720      * @param imageType
    721      *            the image type.
    722      * @param width
    723      *            the width of the image.
    724      * @param height
    725      *            the height of the image.
    726      * @param imageMetadata
    727      *            the image's metadata, or null.
    728      * @param thumbnails
    729      *            the image's thumbnails, or null.
    730      * @param param
    731      *            the image's parameters, or null.
    732      * @throws IOException
    733      *             if an I/O exception has occurred.
    734      */
    735     public void prepareWriteEmpty(IIOMetadata streamMetadata, ImageTypeSpecifier imageType,
    736             int width, int height, IIOMetadata imageMetadata,
    737             List<? extends BufferedImage> thumbnails, ImageWriteParam param) throws IOException {
    738         unsupportedOperation();
    739     }
    740 
    741     /**
    742      * Prepares a stream to accept calls of writeToSequence method using the
    743      * metadata object.
    744      *
    745      * @param streamMetadata
    746      *            the stream metadata.
    747      * @throws IOException
    748      *             if an I/O exception has occurred.
    749      */
    750     public void prepareWriteSequence(IIOMetadata streamMetadata) throws IOException {
    751         unsupportedOperation();
    752     }
    753 
    754     /**
    755      * Processes the completion of a thumbnail read by calling their
    756      * thumbnailComplete method of registered IIOWriteProgressListeners.
    757      */
    758     protected void processThumbnailComplete() {
    759         if (progressListeners != null) {
    760             for (IIOWriteProgressListener listener : progressListeners) {
    761                 listener.thumbnailComplete(this);
    762             }
    763         }
    764     }
    765 
    766     /**
    767      * Processes the current percentage of thumbnail completion by calling their
    768      * thumbnailProgress method of registered IIOWriteProgressListeners.
    769      *
    770      * @param percentageDone
    771      *            the percentage done.
    772      */
    773     protected void processThumbnailProgress(float percentageDone) {
    774         if (progressListeners != null) {
    775             for (IIOWriteProgressListener listener : progressListeners) {
    776                 listener.thumbnailProgress(this, percentageDone);
    777             }
    778         }
    779     }
    780 
    781     /**
    782      * Processes the start of a thumbnail read by calling thumbnailStarted
    783      * method of registered IIOWriteProgressListeners.
    784      *
    785      * @param imageIndex
    786      *            the image index.
    787      * @param thumbnailIndex
    788      *            the thumbnail index.
    789      */
    790     protected void processThumbnailStarted(int imageIndex, int thumbnailIndex) {
    791         if (progressListeners != null) {
    792             for (IIOWriteProgressListener listener : progressListeners) {
    793                 listener.thumbnailStarted(this, imageIndex, thumbnailIndex);
    794             }
    795         }
    796     }
    797 
    798     /**
    799      * Processes that the writing has been aborted by calling writeAborted
    800      * method of registered IIOWriteProgressListeners.
    801      */
    802     protected void processWriteAborted() {
    803         if (progressListeners != null) {
    804             for (IIOWriteProgressListener listener : progressListeners) {
    805                 listener.writeAborted(this);
    806             }
    807         }
    808     }
    809 
    810     /**
    811      * Removes the all IIOWriteProgressListener listeners.
    812      */
    813     public void removeAllIIOWriteProgressListeners() {
    814         progressListeners = null;
    815     }
    816 
    817     /**
    818      * Removes the all IIOWriteWarningListener listeners.
    819      */
    820     public void removeAllIIOWriteWarningListeners() {
    821         warningListeners = null;
    822         warningLocales = null;
    823     }
    824 
    825     /**
    826      * Removes the specified IIOWriteProgressListener listener.
    827      *
    828      * @param listener
    829      *            the registered IIOWriteProgressListener to be removed.
    830      */
    831     public void removeIIOWriteProgressListener(IIOWriteProgressListener listener) {
    832         if (progressListeners != null && listener != null) {
    833             if (progressListeners.remove(listener) && progressListeners.isEmpty()) {
    834                 progressListeners = null;
    835             }
    836         }
    837     }
    838 
    839     /**
    840      * Removes the specified IIOWriteWarningListener listener.
    841      *
    842      * @param listener
    843      *            the registered IIOWriteWarningListener listener to be removed.
    844      */
    845     public void removeIIOWriteWarningListener(IIOWriteWarningListener listener) {
    846         if (warningListeners == null || listener == null) {
    847             return;
    848         }
    849 
    850         int idx = warningListeners.indexOf(listener);
    851         if (idx > -1) {
    852             warningListeners.remove(idx);
    853             warningLocales.remove(idx);
    854 
    855             if (warningListeners.isEmpty()) {
    856                 warningListeners = null;
    857                 warningLocales = null;
    858             }
    859         }
    860     }
    861 
    862     /**
    863      * Removes the image with the specified index from the stream.
    864      *
    865      * @param imageIndex
    866      *            the image's index.
    867      * @throws IOException
    868      *             if an I/O exception has occurred.
    869      */
    870     public void removeImage(int imageIndex) throws IOException {
    871         unsupportedOperation();
    872     }
    873 
    874     /**
    875      * Replaces image metadata of the image with specified index.
    876      *
    877      * @param imageIndex
    878      *            the image's index.
    879      * @param imageMetadata
    880      *            the image metadata.
    881      * @throws IOException
    882      *             if an I/O exception has occurred.
    883      */
    884     public void replaceImageMetadata(int imageIndex, IIOMetadata imageMetadata) throws IOException {
    885         unsupportedOperation();
    886     }
    887 
    888     /**
    889      * Replaces a part of an image presented in the output with the specified
    890      * RenderedImage.
    891      *
    892      * @param image
    893      *            the RenderedImage.
    894      * @param param
    895      *            the ImageWriteParam.
    896      * @throws IOException
    897      *             if an I/O exception has occurred.
    898      */
    899     public void replacePixels(RenderedImage image, ImageWriteParam param) throws IOException {
    900         unsupportedOperation();
    901     }
    902 
    903     /**
    904      * Replaces a part of an image presented in the output with the specified
    905      * Raster.
    906      *
    907      * @param raster
    908      *            the Raster.
    909      * @param param
    910      *            the ImageWriteParam.
    911      * @throws IOException
    912      *             if an I/O exception has occurred.
    913      */
    914     public void replacePixels(Raster raster, ImageWriteParam param) throws IOException {
    915         unsupportedOperation();
    916     }
    917 
    918     /**
    919      * Replaces the stream metadata of the output with new IIOMetadata.
    920      *
    921      * @param streamMetadata
    922      *            the new stream metadata.
    923      * @throws IOException
    924      *             if an I/O exception has occurred.
    925      */
    926     public void replaceStreamMetadata(IIOMetadata streamMetadata) throws IOException {
    927         unsupportedOperation();
    928     }
    929 
    930     /**
    931      * Sets the locale of this ImageWriter.
    932      *
    933      * @param locale
    934      *            the new locale.
    935      */
    936     public void setLocale(Locale locale) {
    937         if (locale == null) {
    938             this.locale = null;
    939             return;
    940         }
    941 
    942         Locale[] locales = getAvailableLocales();
    943         boolean validLocale = false;
    944         if (locales != null) {
    945             for (int i = 0; i < locales.length; i++) {
    946                 if (locale.equals(locales[i])) {
    947                     validLocale = true;
    948                     break;
    949                 }
    950             }
    951         }
    952 
    953         if (validLocale) {
    954             this.locale = locale;
    955         } else {
    956             throw new IllegalArgumentException("Invalid locale!");
    957         }
    958     }
    959 
    960     /**
    961      * Resets this ImageWriter.
    962      */
    963     public void reset() {
    964         setOutput(null);
    965         setLocale(null);
    966         removeAllIIOWriteWarningListeners();
    967         removeAllIIOWriteProgressListeners();
    968         clearAbortRequest();
    969     }
    970 
    971     /**
    972      * Inserts image into existing output stream.
    973      *
    974      * @param imageIndex
    975      *            the image index where an image will be written.
    976      * @param image
    977      *            the specified image to be written.
    978      * @param param
    979      *            the ImageWriteParam, or null.
    980      * @throws IOException
    981      *             if an I/O exception has occurred.
    982      */
    983     public void writeInsert(int imageIndex, IIOImage image, ImageWriteParam param)
    984             throws IOException {
    985         unsupportedOperation();
    986     }
    987 
    988     /**
    989      * Writes the specified image to the sequence.
    990      *
    991      * @param image
    992      *            the image to be written.
    993      * @param param
    994      *            the ImageWriteParam, or null.
    995      * @throws IOException
    996      *             if an I/O exception has occurred during writing.
    997      */
    998     public void writeToSequence(IIOImage image, ImageWriteParam param) throws IOException {
    999         unsupportedOperation();
   1000     }
   1001 }
   1002