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</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 = 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 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 : writerSpiNames.clone(); 412 } 413 }