| /* |
| * 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()"); |
| } |
| } |
| } |