1/*
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package javax.imageio.spi;
27
28import java.io.IOException;
29import javax.imageio.ImageReader;
30import javax.imageio.stream.ImageInputStream;
31
32/**
33 * The service provider interface (SPI) for {@code ImageReader}s.
34 * For more information on service provider classes, see the class comment
35 * for the {@code IIORegistry} class.
36 *
37 * <p> Each {@code ImageReaderSpi} provides several types of information
38 * about the {@code ImageReader} class with which it is associated.
39 *
40 * <p> The name of the vendor who defined the SPI class and a
41 * brief description of the class are available via the
42 * {@code getVendorName}, {@code getDescription},
43 * and {@code getVersion} methods.
44 * These methods may be internationalized to provide locale-specific
45 * output.  These methods are intended mainly to provide short,
46 * human-readable information that might be used to organize a pop-up
47 * menu or other list.
48 *
49 * <p> Lists of format names, file suffixes, and MIME types associated
50 * with the service may be obtained by means of the
51 * {@code getFormatNames}, {@code getFileSuffixes}, and
52 * {@code getMIMETypes} methods.  These methods may be used to
53 * identify candidate {@code ImageReader}s for decoding a
54 * particular file or stream based on manual format selection, file
55 * naming, or MIME associations (for example, when accessing a file
56 * over HTTP or as an email attachment).
57 *
58 * <p> A more reliable way to determine which {@code ImageReader}s
59 * are likely to be able to parse a particular data stream is provided
60 * by the {@code canDecodeInput} method.  This methods allows the
61 * service provider to inspect the actual stream contents.
62 *
63 * <p> Finally, an instance of the {@code ImageReader} class
64 * associated with this service provider may be obtained by calling
65 * the {@code createReaderInstance} method.  Any heavyweight
66 * initialization, such as the loading of native libraries or creation
67 * of large tables, should be deferred at least until the first
68 * invocation of this method.
69 *
70 * @see IIORegistry
71 * @see javax.imageio.ImageReader
72 *
73 */
74public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
75
76    /**
77     * A single-element array, initially containing
78     * {@code ImageInputStream.class}, to be returned from
79     * {@code getInputTypes}.
80     * @deprecated Instead of using this field, directly create
81     * the equivalent array {@code { ImageInputStream.class }}.
82     */
83    @Deprecated
84    public static final Class<?>[] STANDARD_INPUT_TYPE =
85        { ImageInputStream.class };
86
87    /**
88     * An array of {@code Class} objects to be returned from
89     * {@code getInputTypes}, initially {@code null}.
90     */
91    protected Class<?>[] inputTypes = null;
92
93    /**
94     * An array of strings to be returned from
95     * {@code getImageWriterSpiNames}, initially
96     * {@code null}.
97     */
98    protected String[] writerSpiNames = null;
99
100    /**
101     * The {@code Class} of the reader, initially
102     * {@code null}.
103     */
104    private Class<?> readerClass = null;
105
106    /**
107     * Constructs a blank {@code ImageReaderSpi}.  It is up to
108     * the subclass to initialize instance variables and/or override
109     * method implementations in order to provide working versions of
110     * all methods.
111     */
112    protected ImageReaderSpi() {
113    }
114
115    /**
116     * Constructs an {@code ImageReaderSpi} with a given
117     * set of values.
118     *
119     * @param vendorName the vendor name, as a non-{@code null}
120     * {@code String}.
121     * @param version a version identifier, as a non-{@code null}
122     * {@code String}.
123     * @param names a non-{@code null} array of
124     * {@code String}s indicating the format names.  At least one
125     * entry must be present.
126     * @param suffixes an array of {@code String}s indicating the
127     * common file suffixes.  If no suffixes are defined,
128     * {@code null} should be supplied.  An array of length 0
129     * will be normalized to {@code null}.
130     * @param MIMETypes an array of {@code String}s indicating
131     * the format's MIME types.  If no MIME types are defined,
132     * {@code null} should be supplied.  An array of length 0
133     * will be normalized to {@code null}.
134     * @param readerClassName the fully-qualified name of the
135     * associated {@code ImageReader} class, as a
136     * non-{@code null String}.
137     * @param inputTypes a non-{@code null} array of
138     * {@code Class} objects of length at least 1 indicating the
139     * legal input types.
140     * @param writerSpiNames an array {@code String}s naming the
141     * classes of all associated {@code ImageWriter}s, or
142     * {@code null}.  An array of length 0 is normalized to
143     * {@code null}.
144     * @param supportsStandardStreamMetadataFormat a
145     * {@code boolean} that indicates whether a stream metadata
146     * object can use trees described by the standard metadata format.
147     * @param nativeStreamMetadataFormatName a
148     * {@code String}, or {@code null}, to be returned from
149     * {@code getNativeStreamMetadataFormatName}.
150     * @param nativeStreamMetadataFormatClassName a
151     * {@code String}, or {@code null}, to be used to instantiate
152     * a metadata format object to be returned from
153     * {@code getNativeStreamMetadataFormat}.
154     * @param extraStreamMetadataFormatNames an array of
155     * {@code String}s, or {@code null}, to be returned from
156     * {@code getExtraStreamMetadataFormatNames}.  An array of length
157     * 0 is normalized to {@code null}.
158     * @param extraStreamMetadataFormatClassNames an array of
159     * {@code String}s, or {@code null}, to be used to instantiate
160     * a metadata format object to be returned from
161     * {@code getStreamMetadataFormat}.  An array of length
162     * 0 is normalized to {@code null}.
163     * @param supportsStandardImageMetadataFormat a
164     * {@code boolean} that indicates whether an image metadata
165     * object can use trees described by the standard metadata format.
166     * @param nativeImageMetadataFormatName a
167     * {@code String}, or {@code null}, to be returned from
168     * {@code getNativeImageMetadataFormatName}.
169     * @param nativeImageMetadataFormatClassName a
170     * {@code String}, or {@code null}, to be used to instantiate
171     * a metadata format object to be returned from
172     * {@code getNativeImageMetadataFormat}.
173     * @param extraImageMetadataFormatNames an array of
174     * {@code String}s to be returned from
175     * {@code getExtraImageMetadataFormatNames}.  An array of length 0
176     * is normalized to {@code null}.
177     * @param extraImageMetadataFormatClassNames an array of
178     * {@code String}s, or {@code null}, to be used to instantiate
179     * a metadata format object to be returned from
180     * {@code getImageMetadataFormat}.  An array of length
181     * 0 is normalized to {@code null}.
182     *
183     * @exception IllegalArgumentException if {@code vendorName}
184     * is {@code null}.
185     * @exception IllegalArgumentException if {@code version}
186     * is {@code null}.
187     * @exception IllegalArgumentException if {@code names}
188     * is {@code null} or has length 0.
189     * @exception IllegalArgumentException if {@code readerClassName}
190     * is {@code null}.
191     * @exception IllegalArgumentException if {@code inputTypes}
192     * is {@code null} or has length 0.
193     */
194    public ImageReaderSpi(String vendorName,
195                          String version,
196                          String[] names,
197                          String[] suffixes,
198                          String[] MIMETypes,
199                          String readerClassName,
200                          Class<?>[] inputTypes,
201                          String[] writerSpiNames,
202                          boolean supportsStandardStreamMetadataFormat,
203                          String nativeStreamMetadataFormatName,
204                          String nativeStreamMetadataFormatClassName,
205                          String[] extraStreamMetadataFormatNames,
206                          String[] extraStreamMetadataFormatClassNames,
207                          boolean supportsStandardImageMetadataFormat,
208                          String nativeImageMetadataFormatName,
209                          String nativeImageMetadataFormatClassName,
210                          String[] extraImageMetadataFormatNames,
211                          String[] extraImageMetadataFormatClassNames) {
212        super(vendorName, version,
213              names, suffixes, MIMETypes, readerClassName,
214              supportsStandardStreamMetadataFormat,
215              nativeStreamMetadataFormatName,
216              nativeStreamMetadataFormatClassName,
217              extraStreamMetadataFormatNames,
218              extraStreamMetadataFormatClassNames,
219              supportsStandardImageMetadataFormat,
220              nativeImageMetadataFormatName,
221              nativeImageMetadataFormatClassName,
222              extraImageMetadataFormatNames,
223              extraImageMetadataFormatClassNames);
224
225        if (inputTypes == null) {
226            throw new IllegalArgumentException
227                ("inputTypes == null!");
228        }
229        if (inputTypes.length == 0) {
230            throw new IllegalArgumentException
231                ("inputTypes.length == 0!");
232        }
233
234        this.inputTypes = (inputTypes == STANDARD_INPUT_TYPE) ?
235            new Class<?>[] { ImageInputStream.class } :
236            inputTypes.clone();
237
238        // If length == 0, leave it null
239        if (writerSpiNames != null && writerSpiNames.length > 0) {
240            this.writerSpiNames = writerSpiNames.clone();
241        }
242    }
243
244    /**
245     * Returns an array of {@code Class} objects indicating what
246     * types of objects may be used as arguments to the reader's
247     * {@code setInput} method.
248     *
249     * <p> For most readers, which only accept input from an
250     * {@code ImageInputStream}, a single-element array
251     * containing {@code ImageInputStream.class} should be
252     * returned.
253     *
254     * @return a non-{@code null} array of
255     * {@code Class} objects of length at least 1.
256     */
257    public Class<?>[] getInputTypes() {
258        return inputTypes.clone();
259    }
260
261    /**
262     * Returns {@code true} if the supplied source object appears
263     * to be of the format supported by this reader.  Returning
264     * {@code true} from this method does not guarantee that
265     * reading will succeed, only that there appears to be a
266     * reasonable chance of success based on a brief inspection of the
267     * stream contents.  If the source is an
268     * {@code ImageInputStream}, implementations will commonly
269     * check the first several bytes of the stream for a "magic
270     * number" associated with the format.  Once actual reading has
271     * commenced, the reader may still indicate failure at any time
272     * prior to the completion of decoding.
273     *
274     * <p> It is important that the state of the object not be
275     * disturbed in order that other {@code ImageReaderSpi}s can
276     * properly determine whether they are able to decode the object.
277     * In particular, if the source is an
278     * {@code ImageInputStream}, a
279     * {@code mark}/{@code reset} pair should be used to
280     * preserve the stream position.
281     *
282     * <p> Formats such as "raw," which can potentially attempt
283     * to read nearly any stream, should return {@code false}
284     * in order to avoid being invoked in preference to a closer
285     * match.
286     *
287     * <p> If {@code source} is not an instance of one of the
288     * classes returned by {@code getInputTypes}, the method
289     * should simply return {@code false}.
290     *
291     * @param source the object (typically an
292     * {@code ImageInputStream}) to be decoded.
293     *
294     * @return {@code true} if it is likely that this stream can
295     * be decoded.
296     *
297     * @exception IllegalArgumentException if {@code source} is
298     * {@code null}.
299     * @exception IOException if an I/O error occurs while reading the
300     * stream.
301     */
302    public abstract boolean canDecodeInput(Object source) throws IOException;
303
304    /**
305     * Returns an instance of the {@code ImageReader}
306     * implementation associated with this service provider.
307     * The returned object will initially be in an initial state
308     * as if its {@code reset} method had been called.
309     *
310     * <p> The default implementation simply returns
311     * {@code createReaderInstance(null)}.
312     *
313     * @return an {@code ImageReader} instance.
314     *
315     * @exception IOException if an error occurs during loading,
316     * or initialization of the reader class, or during instantiation
317     * or initialization of the reader object.
318     */
319    public ImageReader createReaderInstance() throws IOException {
320        return createReaderInstance(null);
321    }
322
323    /**
324     * Returns an instance of the {@code ImageReader}
325     * implementation associated with this service provider.
326     * The returned object will initially be in an initial state
327     * as if its {@code reset} method had been called.
328     *
329     * <p> An {@code Object} may be supplied to the plug-in at
330     * construction time.  The nature of the object is entirely
331     * plug-in specific.
332     *
333     * <p> Typically, a plug-in will implement this method using code
334     * such as {@code return new MyImageReader(this)}.
335     *
336     * @param extension a plug-in specific extension object, which may
337     * be {@code null}.
338     *
339     * @return an {@code ImageReader} instance.
340     *
341     * @exception IOException if the attempt to instantiate
342     * the reader fails.
343     * @exception IllegalArgumentException if the
344     * {@code ImageReader}'s constructor throws an
345     * {@code IllegalArgumentException} to indicate that the
346     * extension object is unsuitable.
347     */
348    public abstract ImageReader createReaderInstance(Object extension)
349        throws IOException;
350
351    /**
352     * Returns {@code true} if the {@code ImageReader} object
353     * passed in is an instance of the {@code ImageReader}
354     * associated with this service provider.
355     *
356     * <p> The default implementation compares the fully-qualified
357     * class name of the {@code reader} argument with the class
358     * name passed into the constructor.  This method may be overridden
359     * if more sophisticated checking is required.
360     *
361     * @param reader an {@code ImageReader} instance.
362     *
363     * @return {@code true} if {@code reader} is recognized.
364     *
365     * @exception IllegalArgumentException if {@code reader} is
366     * {@code null}.
367     */
368    public boolean isOwnReader(ImageReader reader) {
369        if (reader == null) {
370            throw new IllegalArgumentException("reader == null!");
371        }
372        String name = reader.getClass().getName();
373        return name.equals(pluginClassName);
374    }
375
376    /**
377     * Returns an array of {@code String}s containing the fully
378     * qualified names of all the {@code ImageWriterSpi} classes
379     * that can understand the internal metadata representation used
380     * by the {@code ImageReader} associated with this service
381     * provider, or {@code null} if there are no such
382     * {@code ImageWriter}s specified.  If a
383     * non-{@code null} value is returned, it must have non-zero
384     * length.
385     *
386     * <p> The first item in the array must be the name of the service
387     * provider for the "preferred" writer, as it will be used to
388     * instantiate the {@code ImageWriter} returned by
389     * {@code ImageIO.getImageWriter(ImageReader)}.
390     *
391     * <p> This mechanism may be used to obtain
392     * {@code ImageWriters} that will understand the internal
393     * structure of non-pixel meta-data (see
394     * {@code IIOTreeInfo}) generated by an
395     * {@code ImageReader}.  By obtaining this data from the
396     * {@code ImageReader} and passing it on to one of the
397     * {@code ImageWriters} obtained with this method, a client
398     * program can read an image, modify it in some way, and write it
399     * back out while preserving all meta-data, without having to
400     * understand anything about the internal structure of the
401     * meta-data, or even about the image format.
402     *
403     * @return an array of {@code String}s of length at least 1
404     * containing names of {@code ImageWriterSpi}, or
405     * {@code null}.
406     *
407     * @see javax.imageio.ImageIO#getImageWriter(ImageReader)
408     */
409    public String[] getImageWriterSpiNames() {
410        return writerSpiNames == null ?
411            null : writerSpiNames.clone();
412    }
413}
414