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 
  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}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  */
  74 public 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 }