View Javadoc
1   /*
2    * Copyright (c) 1999, 2013, 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  
26  package javax.imageio.spi;
27  
28  import java.io.IOException;
29  import javax.imageio.ImageReader;
30  import javax.imageio.stream.ImageInputStream;
31  
32  /**
33   * The service provider interface (SPI) for <code>ImageReader</code>s.
34   * For more information on service provider classes, see the class comment
35   * for the <code>IIORegistry</code> class.
36   *
37   * <p> Each <code>ImageReaderSpi</code> provides several types of information
38   * about the <code>ImageReader</code> 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>, <code>getDescription</code>,
43   * and <code>getVersion</code> 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>, <code>getFileSuffixes</code>, and
52   * <code>getMIMETypes</code> methods.  These methods may be used to
53   * identify candidate <code>ImageReader</code>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</code>s
59   * are likely to be able to parse a particular data stream is provided
60   * by the <code>canDecodeInput</code> method.  This methods allows the
61   * service provider to inspect the actual stream contents.
62   *
63   * <p> Finally, an instance of the <code>ImageReader</code> class
64   * associated with this service provider may be obtained by calling
65   * the <code>createReaderInstance</code> 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   */
74  public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
75  
76      /**
77       * A single-element array, initially containing
78       * <code>ImageInputStream.class</code>, to be returned from
79       * <code>getInputTypes</code>.
80       * @deprecated Instead of using this field, directly create
81       * the equivalent array <code>{ ImageInputStream.class }</code>.
82       */
83      @Deprecated
84      public static final Class[] STANDARD_INPUT_TYPE =
85          { ImageInputStream.class };
86  
87      /**
88       * An array of <code>Class</code> objects to be returned from
89       * <code>getInputTypes</code>, initially <code>null</code>.
90       */
91      protected Class[] inputTypes = null;
92  
93      /**
94       * An array of strings to be returned from
95       * <code>getImageWriterSpiNames</code>, initially
96       * <code>null</code>.
97       */
98      protected String[] writerSpiNames = null;
99  
100     /**
101      * The <code>Class</code> of the reader, initially
102      * <code>null</code>.
103      */
104     private Class readerClass = null;
105 
106     /**
107      * Constructs a blank <code>ImageReaderSpi</code>.  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</code> with a given
117      * set of values.
118      *
119      * @param vendorName the vendor name, as a non-<code>null</code>
120      * <code>String</code>.
121      * @param version a version identifier, as a non-<code>null</code>
122      * <code>String</code>.
123      * @param names a non-<code>null</code> array of
124      * <code>String</code>s indicating the format names.  At least one
125      * entry must be present.
126      * @param suffixes an array of <code>String</code>s indicating the
127      * common file suffixes.  If no suffixes are defined,
128      * <code>null</code> should be supplied.  An array of length 0
129      * will be normalized to <code>null</code>.
130      * @param MIMETypes an array of <code>String</code>s indicating
131      * the format's MIME types.  If no MIME types are defined,
132      * <code>null</code> should be supplied.  An array of length 0
133      * will be normalized to <code>null</code>.
134      * @param readerClassName the fully-qualified name of the
135      * associated <code>ImageReader</code> class, as a
136      * non-<code>null</code> <code>String</code>.
137      * @param inputTypes a non-<code>null</code> array of
138      * <code>Class</code> objects of length at least 1 indicating the
139      * legal input types.
140      * @param writerSpiNames an array <code>String</code>s naming the
141      * classes of all associated <code>ImageWriter</code>s, or
142      * <code>null</code>.  An array of length 0 is normalized to
143      * <code>null</code>.
144      * @param supportsStandardStreamMetadataFormat a
145      * <code>boolean</code> that indicates whether a stream metadata
146      * object can use trees described by the standard metadata format.
147      * @param nativeStreamMetadataFormatName a
148      * <code>String</code>, or <code>null</code>, to be returned from
149      * <code>getNativeStreamMetadataFormatName</code>.
150      * @param nativeStreamMetadataFormatClassName a
151      * <code>String</code>, or <code>null</code>, to be used to instantiate
152      * a metadata format object to be returned from
153      * <code>getNativeStreamMetadataFormat</code>.
154      * @param extraStreamMetadataFormatNames an array of
155      * <code>String</code>s, or <code>null</code>, to be returned from
156      * <code>getExtraStreamMetadataFormatNames</code>.  An array of length
157      * 0 is normalized to <code>null</code>.
158      * @param extraStreamMetadataFormatClassNames an array of
159      * <code>String</code>s, or <code>null</code>, to be used to instantiate
160      * a metadata format object to be returned from
161      * <code>getStreamMetadataFormat</code>.  An array of length
162      * 0 is normalized to <code>null</code>.
163      * @param supportsStandardImageMetadataFormat a
164      * <code>boolean</code> that indicates whether an image metadata
165      * object can use trees described by the standard metadata format.
166      * @param nativeImageMetadataFormatName a
167      * <code>String</code>, or <code>null</code>, to be returned from
168      * <code>getNativeImageMetadataFormatName</code>.
169      * @param nativeImageMetadataFormatClassName a
170      * <code>String</code>, or <code>null</code>, to be used to instantiate
171      * a metadata format object to be returned from
172      * <code>getNativeImageMetadataFormat</code>.
173      * @param extraImageMetadataFormatNames an array of
174      * <code>String</code>s to be returned from
175      * <code>getExtraImageMetadataFormatNames</code>.  An array of length 0
176      * is normalized to <code>null</code>.
177      * @param extraImageMetadataFormatClassNames an array of
178      * <code>String</code>s, or <code>null</code>, to be used to instantiate
179      * a metadata format object to be returned from
180      * <code>getImageMetadataFormat</code>.  An array of length
181      * 0 is normalized to <code>null</code>.
182      *
183      * @exception IllegalArgumentException if <code>vendorName</code>
184      * is <code>null</code>.
185      * @exception IllegalArgumentException if <code>version</code>
186      * is <code>null</code>.
187      * @exception IllegalArgumentException if <code>names</code>
188      * is <code>null</code> or has length 0.
189      * @exception IllegalArgumentException if <code>readerClassName</code>
190      * is <code>null</code>.
191      * @exception IllegalArgumentException if <code>inputTypes</code>
192      * is <code>null</code> 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 = (String[])writerSpiNames.clone();
241         }
242     }
243 
244     /**
245      * Returns an array of <code>Class</code> objects indicating what
246      * types of objects may be used as arguments to the reader's
247      * <code>setInput</code> method.
248      *
249      * <p> For most readers, which only accept input from an
250      * <code>ImageInputStream</code>, a single-element array
251      * containing <code>ImageInputStream.class</code> should be
252      * returned.
253      *
254      * @return a non-<code>null</code> array of
255      * <code>Class</code>objects of length at least 1.
256      */
257     public Class[] getInputTypes() {
258         return (Class[])inputTypes.clone();
259     }
260 
261     /**
262      * Returns <code>true</code> if the supplied source object appears
263      * to be of the format supported by this reader.  Returning
264      * <code>true</code> 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</code>, 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</code>s can
276      * properly determine whether they are able to decode the object.
277      * In particular, if the source is an
278      * <code>ImageInputStream</code>, a
279      * <code>mark</code>/<code>reset</code> 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</code>
284      * in order to avoid being invoked in preference to a closer
285      * match.
286      *
287      * <p> If <code>source</code> is not an instance of one of the
288      * classes returned by <code>getInputTypes</code>, the method
289      * should simply return <code>false</code>.
290      *
291      * @param source the object (typically an
292      * <code>ImageInputStream</code>) to be decoded.
293      *
294      * @return <code>true</code> if it is likely that this stream can
295      * be decoded.
296      *
297      * @exception IllegalArgumentException if <code>source</code> is
298      * <code>null</code>.
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</code>
306      * implementation associated with this service provider.
307      * The returned object will initially be in an initial state
308      * as if its <code>reset</code> method had been called.
309      *
310      * <p> The default implementation simply returns
311      * <code>createReaderInstance(null)</code>.
312      *
313      * @return an <code>ImageReader</code> 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</code>
325      * implementation associated with this service provider.
326      * The returned object will initially be in an initial state
327      * as if its <code>reset</code> method had been called.
328      *
329      * <p> An <code>Object</code> 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)</code>.
335      *
336      * @param extension a plug-in specific extension object, which may
337      * be <code>null</code>.
338      *
339      * @return an <code>ImageReader</code> instance.
340      *
341      * @exception IOException if the attempt to instantiate
342      * the reader fails.
343      * @exception IllegalArgumentException if the
344      * <code>ImageReader</code>'s constructor throws an
345      * <code>IllegalArgumentException</code> 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</code> if the <code>ImageReader</code> object
353      * passed in is an instance of the <code>ImageReader</code>
354      * associated with this service provider.
355      *
356      * <p> The default implementation compares the fully-qualified
357      * class name of the <code>reader</code> 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</code> instance.
362      *
363      * @return <code>true</code> if <code>reader</code> is recognized.
364      *
365      * @exception IllegalArgumentException if <code>reader</code> is
366      * <code>null</code>.
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</code>s containing the fully
378      * qualified names of all the <code>ImageWriterSpi</code> classes
379      * that can understand the internal metadata representation used
380      * by the <code>ImageReader</code> associated with this service
381      * provider, or <code>null</code> if there are no such
382      * <code>ImageWriter</code>s specified.  If a
383      * non-<code>null</code> 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</code> returned by
389      * <code>ImageIO.getImageWriter(ImageReader)</code>.
390      *
391      * <p> This mechanism may be used to obtain
392      * <code>ImageWriters</code> that will understand the internal
393      * structure of non-pixel meta-data (see
394      * <code>IIOTreeInfo</code>) generated by an
395      * <code>ImageReader</code>.  By obtaining this data from the
396      * <code>ImageReader</code> and passing it on to one of the
397      * <code>ImageWriters</code> 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</code>s of length at least 1
404      * containing names of <code>ImageWriterSpi</code>, or
405      * <code>null</code>.
406      *
407      * @see javax.imageio.ImageIO#getImageWriter(ImageReader)
408      */
409     public String[] getImageWriterSpiNames() {
410         return writerSpiNames == null ?
411             null : (String[])writerSpiNames.clone();
412     }
413 }