| /* |
| * 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 perfom |
| * reading and writing operations using registered |
| * ImageReader and ImageWriter objects. |
| */ |
| public final class ImageIO { |
| |
| /** The Constant registry. */ |
| private static final IIORegistry registry = IIORegistry.getDefaultInstance(); |
| |
| /** |
| * Instantiates a new image io. |
| */ |
| 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 signals that 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 signals that 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 imput 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 Signals that 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 Signals that 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 Signals that 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 Signals that 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 Signals that 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 Signals that 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 Signals that 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()"); |
| } |
| } |
| } |