|  | /* | 
|  | *  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 javax.imageio.stream.ImageInputStream; | 
|  | import javax.imageio.stream.ImageOutputStream; | 
|  | import javax.imageio.spi.*; | 
|  | import java.io.File; | 
|  | import java.io.IOException; | 
|  | import java.io.InputStream; | 
|  | import java.io.OutputStream; | 
|  | import java.util.Iterator; | 
|  | import java.util.Arrays; | 
|  | import java.awt.image.BufferedImage; | 
|  | import java.awt.image.RenderedImage; | 
|  | import java.net.URL; | 
|  |  | 
|  | /** | 
|  | * The ImageIO class provides static methods to perform reading and writing | 
|  | * operations using registered ImageReader and ImageWriter objects. | 
|  | * | 
|  | * @since Android 1.0 | 
|  | */ | 
|  | public final class ImageIO { | 
|  |  | 
|  | /** | 
|  | * The constant registry. | 
|  | */ | 
|  | private static final IIORegistry registry = IIORegistry.getDefaultInstance(); | 
|  |  | 
|  | /** | 
|  | * Instantiates a new ImageIO. | 
|  | */ | 
|  | private ImageIO() { | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Scans for plug-ins in the class path, loads spi classes, and registers | 
|  | * them with the IIORegistry. | 
|  | */ | 
|  | public static void scanForPlugins() { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Sets flag which indicates whether a cache file is used when creating | 
|  | * ImageInputStreams and ImageOutputStreams or not. | 
|  | * | 
|  | * @param useCache | 
|  | *            the use cache flag. | 
|  | */ | 
|  | public static void setUseCache(boolean useCache) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the flag which indicates whether a cache file is used when creating | 
|  | * ImageInputStreams and ImageOutputStreams or not. This method returns the | 
|  | * current value which is set by setUseCache method. | 
|  | * | 
|  | * @return the use cache flag. | 
|  | */ | 
|  | public static boolean getUseCache() { | 
|  | // TODO implement | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Sets the cache directory. | 
|  | * | 
|  | * @param cacheDirectory | 
|  | *            the File which specifies a cache directory. | 
|  | */ | 
|  | public static void setCacheDirectory(File cacheDirectory) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the directory where cache files are created, returned the file which | 
|  | * is set by setCacheDirectory method, or null. | 
|  | * | 
|  | * @return the File object which is set by setCacheDirectory method, or | 
|  | *         null. | 
|  | */ | 
|  | public static File getCacheDirectory() { | 
|  | // TODO implement | 
|  | // -- null indicates system-dep default temporary directory | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Creates an ImageInputStream from the specified Object. The specified | 
|  | * Object should obtain the input source such as File, or InputStream. | 
|  | * | 
|  | * @param input | 
|  | *            the input Object such as File, or InputStream. | 
|  | * @return the ImageInputStream object, or null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static ImageInputStream createImageInputStream(Object input) throws IOException { | 
|  |  | 
|  | if (input == null) { | 
|  | throw new IllegalArgumentException("input source cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageInputStreamSpi> it = registry.getServiceProviders(ImageInputStreamSpi.class, | 
|  | true); | 
|  |  | 
|  | while (it.hasNext()) { | 
|  | ImageInputStreamSpi spi = it.next(); | 
|  | if (spi.getInputClass().isInstance(input)) { | 
|  | return spi.createInputStreamInstance(input); | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Creates an ImageOutputStream using the specified Object. The specified | 
|  | * Object should obtain the output source such as File, or OutputStream. | 
|  | * | 
|  | * @param output | 
|  | *            the output Object such as File, or OutputStream. | 
|  | * @return the ImageOutputStream object, or null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static ImageOutputStream createImageOutputStream(Object output) throws IOException { | 
|  | if (output == null) { | 
|  | throw new IllegalArgumentException("output destination cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageOutputStreamSpi> it = registry.getServiceProviders( | 
|  | ImageOutputStreamSpi.class, true); | 
|  |  | 
|  | while (it.hasNext()) { | 
|  | ImageOutputStreamSpi spi = it.next(); | 
|  | if (spi.getOutputClass().isInstance(output)) { | 
|  | // todo - use getUseCache and getCacheDir here | 
|  | return spi.createOutputStreamInstance(output); | 
|  | } | 
|  | } | 
|  | return null; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the array of format names as String which can be decoded by | 
|  | * registered ImageReader objects. | 
|  | * | 
|  | * @return the array of format names. | 
|  | */ | 
|  | public static String[] getReaderFormatNames() { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the array of MIME types as String which can be decoded by registered | 
|  | * ImageReader objects. | 
|  | * | 
|  | * @return the array of MIME types. | 
|  | */ | 
|  | public static String[] getReaderMIMETypes() { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator of registered ImageReader which are able to decode an | 
|  | * input data specified by input Object. | 
|  | * | 
|  | * @param input | 
|  | *            the input Object with encoded data such as ImageInputStream | 
|  | *            object. | 
|  | * @return the Iterator of registered ImageReader. | 
|  | */ | 
|  | public static Iterator<ImageReader> getImageReaders(Object input) { | 
|  | if (input == null) { | 
|  | throw new NullPointerException("input cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class, | 
|  | new CanReadFilter(input), true); | 
|  |  | 
|  | return new SpiIteratorToReadersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator of registered ImageReader which are able to decode the | 
|  | * specified format. | 
|  | * | 
|  | * @param formatName | 
|  | *            the format name such as "jpeg", or "gif". | 
|  | * @return the Iterator of registered ImageReader. | 
|  | */ | 
|  | public static Iterator<ImageReader> getImageReadersByFormatName(String formatName) { | 
|  | if (formatName == null) { | 
|  | throw new NullPointerException("format name cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class, | 
|  | new FormatFilter(formatName), true); | 
|  |  | 
|  | return new SpiIteratorToReadersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator which lists the registered ImageReader objects that are | 
|  | * able to decode files with the specified suffix. | 
|  | * | 
|  | * @param fileSuffix | 
|  | *            the file suffix such as "jpg". | 
|  | * @return the Iterator of registered ImageReaders. | 
|  | */ | 
|  | public static Iterator<ImageReader> getImageReadersBySuffix(String fileSuffix) { | 
|  | if (fileSuffix == null) { | 
|  | throw new NullPointerException("suffix cannot be NULL"); | 
|  | } | 
|  | Iterator<ImageReaderSpi> it = registry.getServiceProviders(ImageReaderSpi.class, | 
|  | new SuffixFilter(fileSuffix), true); | 
|  |  | 
|  | return new SpiIteratorToReadersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator of registered ImageReader objects that are able to | 
|  | * decode files with the specified MIME type. | 
|  | * | 
|  | * @param MIMEType | 
|  | *            the MIME type such as "image/jpeg". | 
|  | * @return the Iterator of registered ImageReaders. | 
|  | */ | 
|  | public static Iterator<ImageReader> getImageReadersByMIMEType(String MIMEType) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets an array of Strings giving the names of the formats supported by | 
|  | * registered ImageWriter objects. | 
|  | * | 
|  | * @return the array of format names. | 
|  | */ | 
|  | public static String[] getWriterFormatNames() { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets an array of Strings giving the MIME types of the formats supported | 
|  | * by registered ImageWriter objects. | 
|  | * | 
|  | * @return the array of MIME types. | 
|  | */ | 
|  | public static String[] getWriterMIMETypes() { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator which lists the registered ImageReader objects that are | 
|  | * able to encode the specified image format. | 
|  | * | 
|  | * @param formatName | 
|  | *            the image format name such as "jpeg". | 
|  | * @return the Iterator of registered ImageWriter. | 
|  | */ | 
|  | public static Iterator<ImageWriter> getImageWritersByFormatName(String formatName) { | 
|  | if (formatName == null) { | 
|  | throw new NullPointerException("format name cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class, | 
|  | new FormatFilter(formatName), true); | 
|  |  | 
|  | return new SpiIteratorToWritersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator which lists the registered ImageReader objects that are | 
|  | * able to encode the specified suffix. | 
|  | * | 
|  | * @param fileSuffix | 
|  | *            the file suffix such as "jpg". | 
|  | * @return the Iterator of registered ImageWriter. | 
|  | */ | 
|  | public static Iterator<ImageWriter> getImageWritersBySuffix(String fileSuffix) { | 
|  | if (fileSuffix == null) { | 
|  | throw new NullPointerException("suffix cannot be NULL"); | 
|  | } | 
|  | Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class, | 
|  | new SuffixFilter(fileSuffix), true); | 
|  | return new SpiIteratorToWritersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator which lists the registered ImageReader objects that are | 
|  | * able to encode the specified MIME type. | 
|  | * | 
|  | * @param MIMEType | 
|  | *            the MIME type such as "image/jpeg". | 
|  | * @return the Iterator of registered ImageWriter. | 
|  | */ | 
|  | public static Iterator<ImageWriter> getImageWritersByMIMEType(String MIMEType) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets an ImageWriter object which corresponds to the specified | 
|  | * ImageReader, or returns null if the specified ImageReader is not | 
|  | * registered. | 
|  | * | 
|  | * @param reader | 
|  | *            the specified ImageReader. | 
|  | * @return the ImageWriter, or null. | 
|  | */ | 
|  | public static ImageWriter getImageWriter(ImageReader reader) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets an ImageReader object which corresponds to the specified | 
|  | * ImageWriter, or returns null if the specified ImageWriter is not | 
|  | * registered. | 
|  | * | 
|  | * @param writer | 
|  | *            the registered ImageWriter object. | 
|  | * @return the ImageReader. | 
|  | */ | 
|  | public static ImageReader getImageReader(ImageWriter writer) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator of ImageWriter objects which are able to encode images | 
|  | * with the specified ImageTypeSpecifier and format. | 
|  | * | 
|  | * @param type | 
|  | *            the ImageTypeSpecifier, which defines layout. | 
|  | * @param formatName | 
|  | *            the format name. | 
|  | * @return the Iterator of ImageWriter objects. | 
|  | */ | 
|  | public static Iterator<ImageWriter> getImageWriters(ImageTypeSpecifier type, String formatName) { | 
|  | if (type == null) { | 
|  | throw new NullPointerException("type cannot be NULL"); | 
|  | } | 
|  |  | 
|  | if (formatName == null) { | 
|  | throw new NullPointerException("format name cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageWriterSpi> it = registry.getServiceProviders(ImageWriterSpi.class, | 
|  | new FormatAndEncodeFilter(type, formatName), true); | 
|  |  | 
|  | return new SpiIteratorToWritersIteratorWrapper(it); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Gets the Iterator of registered ImageTranscoders which are able to | 
|  | * transcode the metadata of the specified ImageReader object to a suitable | 
|  | * object for encoding by the specified ImageWriter. | 
|  | * | 
|  | * @param reader | 
|  | *            the specified ImageReader. | 
|  | * @param writer | 
|  | *            the specified ImageWriter. | 
|  | * @return the Iterator of registered ImageTranscoders. | 
|  | */ | 
|  | public static Iterator<ImageTranscoder> getImageTranscoders(ImageReader reader, | 
|  | ImageWriter writer) { | 
|  | throw new UnsupportedOperationException("Not supported yet"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads image data from the specified File and decodes it using the | 
|  | * appropriate registered ImageReader object. The File is wrapped in an | 
|  | * ImageInputStream. | 
|  | * | 
|  | * @param input | 
|  | *            the File to be read. | 
|  | * @return the BufferedImage decoded from the specified File, or null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static BufferedImage read(File input) throws IOException { | 
|  | if (input == null) { | 
|  | throw new IllegalArgumentException("input == null!"); | 
|  | } | 
|  |  | 
|  | ImageInputStream stream = createImageInputStream(input); | 
|  | return read(stream); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads image data from the specified InputStream and decodes it using an | 
|  | * appropriate registered an ImageReader object. | 
|  | * | 
|  | * @param input | 
|  | *            the InputStream. | 
|  | * @return the BufferedImage decoded from the specified InputStream, or | 
|  | *         null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static BufferedImage read(InputStream input) throws IOException { | 
|  | if (input == null) { | 
|  | throw new IllegalArgumentException("input == null!"); | 
|  | } | 
|  |  | 
|  | ImageInputStream stream = createImageInputStream(input); | 
|  | return read(stream); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads image data from the specified URL and decodes it using the | 
|  | * appropriate registered ImageReader object. | 
|  | * | 
|  | * @param input | 
|  | *            the URL to be read. | 
|  | * @return the BufferedImage decoded from the specified URL, or null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static BufferedImage read(URL input) throws IOException { | 
|  | if (input == null) { | 
|  | throw new IllegalArgumentException("input == null!"); | 
|  | } | 
|  |  | 
|  | InputStream stream = input.openStream(); | 
|  | BufferedImage res = read(stream); | 
|  | stream.close(); | 
|  |  | 
|  | return res; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Reads image data from the specified ImageInputStream and decodes it using | 
|  | * appropriate registered an ImageReader object. | 
|  | * | 
|  | * @param stream | 
|  | *            the ImageInputStream. | 
|  | * @return the BufferedImage decoded from the specified ImageInputStream, or | 
|  | *         null. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static BufferedImage read(ImageInputStream stream) throws IOException { | 
|  | if (stream == null) { | 
|  | throw new IllegalArgumentException("stream == null!"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageReader> imageReaders = getImageReaders(stream); | 
|  | if (!imageReaders.hasNext()) { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | ImageReader reader = imageReaders.next(); | 
|  | reader.setInput(stream, false, true); | 
|  | BufferedImage res = reader.read(0); | 
|  | reader.dispose(); | 
|  |  | 
|  | try { | 
|  | stream.close(); | 
|  | } catch (IOException e) { | 
|  | // Stream could be already closed, proceed silently in this case | 
|  | } | 
|  |  | 
|  | return res; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Writes the specified image in the specified format (using an appropriate | 
|  | * ImageWriter) to the specified ImageOutputStream. | 
|  | * | 
|  | * @param im | 
|  | *            the RenderedImage. | 
|  | * @param formatName | 
|  | *            the format name. | 
|  | * @param output | 
|  | *            the ImageOutputStream where Image to be written. | 
|  | * @return true, if Image is written successfully, false otherwise. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static boolean write(RenderedImage im, String formatName, ImageOutputStream output) | 
|  | throws IOException { | 
|  |  | 
|  | if (im == null) { | 
|  | throw new IllegalArgumentException("image cannot be NULL"); | 
|  | } | 
|  | if (formatName == null) { | 
|  | throw new IllegalArgumentException("format name cannot be NULL"); | 
|  | } | 
|  | if (output == null) { | 
|  | throw new IllegalArgumentException("output cannot be NULL"); | 
|  | } | 
|  |  | 
|  | Iterator<ImageWriter> it = getImageWriters(ImageTypeSpecifier.createFromRenderedImage(im), | 
|  | formatName); | 
|  | if (it.hasNext()) { | 
|  | ImageWriter writer = it.next(); | 
|  | writer.setOutput(output); | 
|  | writer.write(im); | 
|  | output.flush(); | 
|  | writer.dispose(); | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Writes the specified image in the specified format (using an appropriate | 
|  | * ImageWriter) to the specified File. | 
|  | * | 
|  | * @param im | 
|  | *            the RenderedImage. | 
|  | * @param formatName | 
|  | *            the format name. | 
|  | * @param output | 
|  | *            the output File where Image to be written. | 
|  | * @return true, if Image is written successfully, false otherwise. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static boolean write(RenderedImage im, String formatName, File output) | 
|  | throws IOException { | 
|  |  | 
|  | if (output == null) { | 
|  | throw new IllegalArgumentException("output cannot be NULL"); | 
|  | } | 
|  |  | 
|  | if (output.exists()) { | 
|  | output.delete(); | 
|  | } | 
|  |  | 
|  | ImageOutputStream ios = createImageOutputStream(output); | 
|  | boolean rt = write(im, formatName, ios); | 
|  | ios.close(); | 
|  | return rt; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Writes the specified image in the specified format (using an appropriate | 
|  | * ImageWriter) to the specified OutputStream. | 
|  | * | 
|  | * @param im | 
|  | *            the RenderedImage. | 
|  | * @param formatName | 
|  | *            the format name. | 
|  | * @param output | 
|  | *            the OutputStream where Image is to be written. | 
|  | * @return true, if Image is written successfully, false otherwise. | 
|  | * @throws IOException | 
|  | *             if an I/O exception has occurred. | 
|  | */ | 
|  | public static boolean write(RenderedImage im, String formatName, OutputStream output) | 
|  | throws IOException { | 
|  |  | 
|  | if (output == null) { | 
|  | throw new IllegalArgumentException("output cannot be NULL"); | 
|  | } | 
|  |  | 
|  | ImageOutputStream ios = createImageOutputStream(output); | 
|  | boolean rt = write(im, formatName, ios); | 
|  | ios.close(); | 
|  | return rt; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Filter to match spi by format name. | 
|  | */ | 
|  | static class FormatFilter implements ServiceRegistry.Filter { | 
|  |  | 
|  | /** | 
|  | * The name. | 
|  | */ | 
|  | private String name; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new format filter. | 
|  | * | 
|  | * @param name | 
|  | *            the name. | 
|  | */ | 
|  | public FormatFilter(String name) { | 
|  | this.name = name; | 
|  | } | 
|  |  | 
|  | public boolean filter(Object provider) { | 
|  | ImageReaderWriterSpi spi = (ImageReaderWriterSpi)provider; | 
|  | return Arrays.asList(spi.getFormatNames()).contains(name); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Filter to match spi by format name and encoding possibility. | 
|  | */ | 
|  | static class FormatAndEncodeFilter extends FormatFilter { | 
|  |  | 
|  | /** | 
|  | * The type. | 
|  | */ | 
|  | private ImageTypeSpecifier type; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new format and encode filter. | 
|  | * | 
|  | * @param type | 
|  | *            the type. | 
|  | * @param name | 
|  | *            the name. | 
|  | */ | 
|  | public FormatAndEncodeFilter(ImageTypeSpecifier type, String name) { | 
|  | super(name); | 
|  | this.type = type; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public boolean filter(Object provider) { | 
|  | ImageWriterSpi spi = (ImageWriterSpi)provider; | 
|  | return super.filter(provider) && spi.canEncodeImage(type); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Filter to match spi by suffix. | 
|  | */ | 
|  | static class SuffixFilter implements ServiceRegistry.Filter { | 
|  |  | 
|  | /** | 
|  | * The suf. | 
|  | */ | 
|  | private String suf; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new suffix filter. | 
|  | * | 
|  | * @param suf | 
|  | *            the suf. | 
|  | */ | 
|  | public SuffixFilter(String suf) { | 
|  | this.suf = suf; | 
|  | } | 
|  |  | 
|  | public boolean filter(Object provider) { | 
|  | ImageReaderWriterSpi spi = (ImageReaderWriterSpi)provider; | 
|  | return Arrays.asList(spi.getFileSuffixes()).contains(suf); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Filter to match spi by decoding possibility. | 
|  | */ | 
|  | static class CanReadFilter implements ServiceRegistry.Filter { | 
|  |  | 
|  | /** | 
|  | * The input. | 
|  | */ | 
|  | private Object input; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new can read filter. | 
|  | * | 
|  | * @param input | 
|  | *            the input. | 
|  | */ | 
|  | public CanReadFilter(Object input) { | 
|  | this.input = input; | 
|  | } | 
|  |  | 
|  | public boolean filter(Object provider) { | 
|  | ImageReaderSpi spi = (ImageReaderSpi)provider; | 
|  | try { | 
|  | return spi.canDecodeInput(input); | 
|  | } catch (IOException e) { | 
|  | return false; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Wraps Spi's iterator to ImageWriter iterator. | 
|  | */ | 
|  | static class SpiIteratorToWritersIteratorWrapper implements Iterator<ImageWriter> { | 
|  |  | 
|  | /** | 
|  | * The backend. | 
|  | */ | 
|  | private Iterator<ImageWriterSpi> backend; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new spi iterator to writers iterator wrapper. | 
|  | * | 
|  | * @param backend | 
|  | *            the backend. | 
|  | */ | 
|  | public SpiIteratorToWritersIteratorWrapper(Iterator<ImageWriterSpi> backend) { | 
|  | this.backend = backend; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Next. | 
|  | * | 
|  | * @return the image writer. | 
|  | */ | 
|  | public ImageWriter next() { | 
|  | try { | 
|  | return backend.next().createWriterInstance(); | 
|  | } catch (IOException e) { | 
|  | e.printStackTrace(); | 
|  | return null; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Checks for next. | 
|  | * | 
|  | * @return true, if successful. | 
|  | */ | 
|  | public boolean hasNext() { | 
|  | return backend.hasNext(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Removes the. | 
|  | */ | 
|  | public void remove() { | 
|  | throw new UnsupportedOperationException( | 
|  | "Use deregisterServiceprovider instead of Iterator.remove()"); | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Wraps spi's iterator to ImageReader iterator. | 
|  | */ | 
|  | static class SpiIteratorToReadersIteratorWrapper implements Iterator<ImageReader> { | 
|  |  | 
|  | /** | 
|  | * The backend. | 
|  | */ | 
|  | private Iterator<ImageReaderSpi> backend; | 
|  |  | 
|  | /** | 
|  | * Instantiates a new spi iterator to readers iterator wrapper. | 
|  | * | 
|  | * @param backend | 
|  | *            the backend. | 
|  | */ | 
|  | public SpiIteratorToReadersIteratorWrapper(Iterator<ImageReaderSpi> backend) { | 
|  | this.backend = backend; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Next. | 
|  | * | 
|  | * @return the image reader. | 
|  | */ | 
|  | public ImageReader next() { | 
|  | try { | 
|  | return backend.next().createReaderInstance(); | 
|  | } catch (IOException e) { | 
|  | e.printStackTrace(); | 
|  | return null; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Checks for next. | 
|  | * | 
|  | * @return true, if successful. | 
|  | */ | 
|  | public boolean hasNext() { | 
|  | return backend.hasNext(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Removes the. | 
|  | */ | 
|  | public void remove() { | 
|  | throw new UnsupportedOperationException( | 
|  | "Use deregisterServiceprovider instead of Iterator.remove()"); | 
|  | } | 
|  | } | 
|  | } |