/*
* Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.imageio.spi;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import javax.imageio.ImageReader;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormat;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.stream.ImageInputStream;
/**
* A superclass containing instance variables and methods common to
* ImageReaderSpi
and ImageWriterSpi
.
*
* @see IIORegistry
* @see ImageReaderSpi
* @see ImageWriterSpi
*
*/
public abstract class ImageReaderWriterSpi extends IIOServiceProvider {
/**
* An array of strings to be returned from
* getFormatNames
, initially null
.
* Constructors should set this to a non-null
value.
*/
protected String[] names = null;
/**
* An array of strings to be returned from
* getFileSuffixes
, initially null
.
*/
protected String[] suffixes = null;
/**
* An array of strings to be returned from
* getMIMETypes
, initially null
.
*/
protected String[] MIMETypes = null;
/**
* A String
containing the name of the associated
* plug-in class, initially null
.
*/
protected String pluginClassName = null;
/**
* A boolean indicating whether this plug-in supports the
* standard metadata format for stream metadata, initially
* false
.
*/
protected boolean supportsStandardStreamMetadataFormat = false;
/**
* A String
containing the name of the native stream
* metadata format supported by this plug-in, initially
* null
.
*/
protected String nativeStreamMetadataFormatName = null;
/**
* A String
containing the class name of the native
* stream metadata format supported by this plug-in, initially
* null
.
*/
protected String nativeStreamMetadataFormatClassName = null;
/**
* An array of String
s containing the names of any
* additional stream metadata formats supported by this plug-in,
* initially null
.
*/
protected String[] extraStreamMetadataFormatNames = null;
/**
* An array of String
s containing the class names of
* any additional stream metadata formats supported by this plug-in,
* initially null
.
*/
protected String[] extraStreamMetadataFormatClassNames = null;
/**
* A boolean indicating whether this plug-in supports the
* standard metadata format for image metadata, initially
* false
.
*/
protected boolean supportsStandardImageMetadataFormat = false;
/**
* A String
containing the name of the
* native stream metadata format supported by this plug-in,
* initially null
.
*/
protected String nativeImageMetadataFormatName = null;
/**
* A String
containing the class name of the
* native stream metadata format supported by this plug-in,
* initially null
.
*/
protected String nativeImageMetadataFormatClassName = null;
/**
* An array of String
s containing the names of any
* additional image metadata formats supported by this plug-in,
* initially null
.
*/
protected String[] extraImageMetadataFormatNames = null;
/**
* An array of String
s containing the class names of
* any additional image metadata formats supported by this
* plug-in, initially null
.
*/
protected String[] extraImageMetadataFormatClassNames = null;
/**
* Constructs an ImageReaderWriterSpi
with a given
* set of values.
*
* @param vendorName the vendor name, as a non-null
* String
.
* @param version a version identifier, as a non-null
* String
.
* @param names a non-null
array of
* String
s indicating the format names. At least one
* entry must be present.
* @param suffixes an array of String
s indicating the
* common file suffixes. If no suffixes are defined,
* null
should be supplied. An array of length 0
* will be normalized to null
.
* @param MIMETypes an array of String
s indicating
* the format's MIME types. If no MIME types are defined,
* null
should be supplied. An array of length 0
* will be normalized to null
.
* @param pluginClassName the fully-qualified name of the
* associated ImageReader
or ImageWriter
* class, as a non-null
String
.
* @param supportsStandardStreamMetadataFormat a
* boolean
that indicates whether a stream metadata
* object can use trees described by the standard metadata format.
* @param nativeStreamMetadataFormatName a
* String
, or null
, to be returned from
* getNativeStreamMetadataFormatName
.
* @param nativeStreamMetadataFormatClassName a
* String
, or null
, to be used to instantiate
* a metadata format object to be returned from
* getNativeStreamMetadataFormat
.
* @param extraStreamMetadataFormatNames an array of
* String
s, or null
, to be returned from
* getExtraStreamMetadataFormatNames
. An array of length
* 0 is normalized to null
.
* @param extraStreamMetadataFormatClassNames an array of
* String
s, or null
, to be used to instantiate
* a metadata format object to be returned from
* getStreamMetadataFormat
. An array of length
* 0 is normalized to null
.
* @param supportsStandardImageMetadataFormat a
* boolean
that indicates whether an image metadata
* object can use trees described by the standard metadata format.
* @param nativeImageMetadataFormatName a
* String
, or null
, to be returned from
* getNativeImageMetadataFormatName
.
* @param nativeImageMetadataFormatClassName a
* String
, or null
, to be used to instantiate
* a metadata format object to be returned from
* getNativeImageMetadataFormat
.
* @param extraImageMetadataFormatNames an array of
* String
s to be returned from
* getExtraImageMetadataFormatNames
. An array of length 0
* is normalized to null
.
* @param extraImageMetadataFormatClassNames an array of
* String
s, or null
, to be used to instantiate
* a metadata format object to be returned from
* getImageMetadataFormat
. An array of length
* 0 is normalized to null
.
*
* @exception IllegalArgumentException if vendorName
* is null
.
* @exception IllegalArgumentException if version
* is null
.
* @exception IllegalArgumentException if names
* is null
or has length 0.
* @exception IllegalArgumentException if pluginClassName
* is null
.
*/
public ImageReaderWriterSpi(String vendorName,
String version,
String[] names,
String[] suffixes,
String[] MIMETypes,
String pluginClassName,
boolean supportsStandardStreamMetadataFormat,
String nativeStreamMetadataFormatName,
String nativeStreamMetadataFormatClassName,
String[] extraStreamMetadataFormatNames,
String[] extraStreamMetadataFormatClassNames,
boolean supportsStandardImageMetadataFormat,
String nativeImageMetadataFormatName,
String nativeImageMetadataFormatClassName,
String[] extraImageMetadataFormatNames,
String[] extraImageMetadataFormatClassNames) {
super(vendorName, version);
if (names == null) {
throw new IllegalArgumentException("names == null!");
}
if (names.length == 0) {
throw new IllegalArgumentException("names.length == 0!");
}
if (pluginClassName == null) {
throw new IllegalArgumentException("pluginClassName == null!");
}
this.names = (String[])names.clone();
// If length == 0, leave it null
if (suffixes != null && suffixes.length > 0) {
this.suffixes = (String[])suffixes.clone();
}
// If length == 0, leave it null
if (MIMETypes != null && MIMETypes.length > 0) {
this.MIMETypes = (String[])MIMETypes.clone();
}
this.pluginClassName = pluginClassName;
this.supportsStandardStreamMetadataFormat =
supportsStandardStreamMetadataFormat;
this.nativeStreamMetadataFormatName = nativeStreamMetadataFormatName;
this.nativeStreamMetadataFormatClassName =
nativeStreamMetadataFormatClassName;
// If length == 0, leave it null
if (extraStreamMetadataFormatNames != null &&
extraStreamMetadataFormatNames.length > 0) {
this.extraStreamMetadataFormatNames =
(String[])extraStreamMetadataFormatNames.clone();
}
// If length == 0, leave it null
if (extraStreamMetadataFormatClassNames != null &&
extraStreamMetadataFormatClassNames.length > 0) {
this.extraStreamMetadataFormatClassNames =
(String[])extraStreamMetadataFormatClassNames.clone();
}
this.supportsStandardImageMetadataFormat =
supportsStandardImageMetadataFormat;
this.nativeImageMetadataFormatName = nativeImageMetadataFormatName;
this.nativeImageMetadataFormatClassName =
nativeImageMetadataFormatClassName;
// If length == 0, leave it null
if (extraImageMetadataFormatNames != null &&
extraImageMetadataFormatNames.length > 0) {
this.extraImageMetadataFormatNames =
(String[])extraImageMetadataFormatNames.clone();
}
// If length == 0, leave it null
if (extraImageMetadataFormatClassNames != null &&
extraImageMetadataFormatClassNames.length > 0) {
this.extraImageMetadataFormatClassNames =
(String[])extraImageMetadataFormatClassNames.clone();
}
}
/**
* Constructs a blank ImageReaderWriterSpi
. It is up
* to the subclass to initialize instance variables and/or
* override method implementations in order to provide working
* versions of all methods.
*/
public ImageReaderWriterSpi() {
}
/**
* Returns an array of String
s containing
* human-readable names for the formats that are generally usable
* by the ImageReader
or ImageWriter
* implementation associated with this service provider. For
* example, a single ImageReader
might be able to
* process both PBM and PNM files.
*
* @return a non-null
array of String
s
* or length at least 1 containing informal format names
* associated with this reader or writer.
*/
public String[] getFormatNames() {
return (String[])names.clone();
}
/**
* Returns an array of String
s containing a list of
* file suffixes associated with the formats that are generally
* usable by the ImageReader
or
* ImageWriter
implementation associated with this
* service provider. For example, a single
* ImageReader
might be able to process files with
* '.pbm' and '.pnm' suffixes, or both '.jpg' and '.jpeg'
* suffixes. If there are no known file suffixes,
* null
will be returned.
*
*
Returning a particular suffix does not guarantee that files
* with that suffix can be processed; it merely indicates that it
* may be worthwhile attempting to decode or encode such files
* using this service provider.
*
* @return an array of String
s or length at least 1
* containing common file suffixes associated with this reader or
* writer, or null
.
*/
public String[] getFileSuffixes() {
return suffixes == null ? null : (String[])suffixes.clone();
}
/**
* Returns an array of String
s containing a list of
* MIME types associated with the formats that are generally
* usable by the ImageReader
or
* ImageWriter
implementation associated with this
* service provider.
*
*
Ideally, only a single MIME type would be required in order
* to describe a particular format. However, for several reasons
* it is necessary to associate a list of types with each service
* provider. First, many common image file formats do not have
* standard MIME types, so a list of commonly used unofficial
* names will be required, such as image/x-pbm
and
* image/x-portable-bitmap
. Some file formats have
* official MIME types but may sometimes be referred to using
* their previous unofficial designations, such as
* image/x-png
instead of the official
* image/png
. Finally, a single service provider may
* be capable of parsing multiple distinct types from the MIME
* point of view, for example image/x-xbitmap
and
* image/x-xpixmap
.
*
*
Returning a particular MIME type does not guarantee that
* files claiming to be of that type can be processed; it merely
* indicates that it may be worthwhile attempting to decode or
* encode such files using this service provider.
*
* @return an array of String
s or length at least 1
* containing MIME types associated with this reader or writer, or
* null
.
*/
public String[] getMIMETypes() {
return MIMETypes == null ? null : (String[])MIMETypes.clone();
}
/**
* Returns the fully-qualified class name of the
* ImageReader
or ImageWriter
plug-in
* associated with this service provider.
*
* @return the class name, as a non-null
* String
.
*/
public String getPluginClassName() {
return pluginClassName;
}
/**
* Returns true
if the standard metadata format is
* among the document formats recognized by the
* getAsTree
and setFromTree
methods on
* the stream metadata objects produced or consumed by this
* plug-in.
*
* @return true
if the standard format is supported
* for stream metadata.
*/
public boolean isStandardStreamMetadataFormatSupported() {
return supportsStandardStreamMetadataFormat;
}
/**
* Returns the name of the "native" stream metadata format for
* this plug-in, which typically allows for lossless encoding and
* transmission of the stream metadata stored in the format handled by
* this plug-in. If no such format is supported,
* null
will be returned.
*
*
The default implementation returns the
* nativeStreamMetadataFormatName
instance variable,
* which is typically set by the constructor.
*
* @return the name of the native stream metadata format, or
* null
.
*
*/
public String getNativeStreamMetadataFormatName() {
return nativeStreamMetadataFormatName;
}
/**
* Returns an array of String
s containing the names
* of additional document formats, other than the native and
* standard formats, recognized by the
* getAsTree
and setFromTree
methods on
* the stream metadata objects produced or consumed by this
* plug-in.
*
*
If the plug-in does not handle metadata, null should be * returned. * *
The set of formats may differ according to the particular * images being read or written; this method should indicate all * the additional formats supported by the plug-in under any * circumstances. * *
The default implementation returns a clone of the
* extraStreamMetadataFormatNames
instance variable,
* which is typically set by the constructor.
*
* @return an array of String
s, or null.
*
* @see IIOMetadata#getMetadataFormatNames
* @see #getExtraImageMetadataFormatNames
* @see #getNativeStreamMetadataFormatName
*/
public String[] getExtraStreamMetadataFormatNames() {
return extraStreamMetadataFormatNames == null ?
null : (String[])extraStreamMetadataFormatNames.clone();
}
/**
* Returns true
if the standard metadata format is
* among the document formats recognized by the
* getAsTree
and setFromTree
methods on
* the image metadata objects produced or consumed by this
* plug-in.
*
* @return true
if the standard format is supported
* for image metadata.
*/
public boolean isStandardImageMetadataFormatSupported() {
return supportsStandardImageMetadataFormat;
}
/**
* Returns the name of the "native" image metadata format for
* this plug-in, which typically allows for lossless encoding and
* transmission of the image metadata stored in the format handled by
* this plug-in. If no such format is supported,
* null
will be returned.
*
*
The default implementation returns the
* nativeImageMetadataFormatName
instance variable,
* which is typically set by the constructor.
*
* @return the name of the native image metadata format, or
* null
.
*
* @see #getExtraImageMetadataFormatNames
*/
public String getNativeImageMetadataFormatName() {
return nativeImageMetadataFormatName;
}
/**
* Returns an array of String
s containing the names
* of additional document formats, other than the native and
* standard formats, recognized by the
* getAsTree
and setFromTree
methods on
* the image metadata objects produced or consumed by this
* plug-in.
*
*
If the plug-in does not handle image metadata, null should * be returned. * *
The set of formats may differ according to the particular * images being read or written; this method should indicate all * the additional formats supported by the plug-in under any circumstances. * *
The default implementation returns a clone of the
* extraImageMetadataFormatNames
instance variable,
* which is typically set by the constructor.
*
* @return an array of String
s, or null.
*
* @see IIOMetadata#getMetadataFormatNames
* @see #getExtraStreamMetadataFormatNames
* @see #getNativeImageMetadataFormatName
*/
public String[] getExtraImageMetadataFormatNames() {
return extraImageMetadataFormatNames == null ?
null : (String[])extraImageMetadataFormatNames.clone();
}
/**
* Returns an IIOMetadataFormat
object describing the
* given stream metadata format, or null
if no
* description is available. The supplied name must be the native
* stream metadata format name, the standard metadata format name,
* or one of those returned by
* getExtraStreamMetadataFormatNames
.
*
* @param formatName the desired stream metadata format.
*
* @return an IIOMetadataFormat
object.
*
* @exception IllegalArgumentException if formatName
* is null
or is not a supported name.
*/
public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
return getMetadataFormat(formatName,
supportsStandardStreamMetadataFormat,
nativeStreamMetadataFormatName,
nativeStreamMetadataFormatClassName,
extraStreamMetadataFormatNames,
extraStreamMetadataFormatClassNames);
}
/**
* Returns an IIOMetadataFormat
object describing the
* given image metadata format, or null
if no
* description is available. The supplied name must be the native
* iamge metadata format name, the standard metadata format name,
* or one of those returned by
* getExtraImageMetadataFormatNames
.
*
* @param formatName the desired image metadata format.
*
* @return an IIOMetadataFormat
object.
*
* @exception IllegalArgumentException if formatName
* is null
or is not a supported name.
*/
public IIOMetadataFormat getImageMetadataFormat(String formatName) {
return getMetadataFormat(formatName,
supportsStandardImageMetadataFormat,
nativeImageMetadataFormatName,
nativeImageMetadataFormatClassName,
extraImageMetadataFormatNames,
extraImageMetadataFormatClassNames);
}
private IIOMetadataFormat getMetadataFormat(String formatName,
boolean supportsStandard,
String nativeName,
String nativeClassName,
String [] extraNames,
String [] extraClassNames) {
if (formatName == null) {
throw new IllegalArgumentException("formatName == null!");
}
if (supportsStandard && formatName.equals
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
return IIOMetadataFormatImpl.getStandardFormatInstance();
}
String formatClassName = null;
if (formatName.equals(nativeName)) {
formatClassName = nativeClassName;
} else if (extraNames != null) {
for (int i = 0; i < extraNames.length; i++) {
if (formatName.equals(extraNames[i])) {
formatClassName = extraClassNames[i];
break; // out of for
}
}
}
if (formatClassName == null) {
throw new IllegalArgumentException("Unsupported format name");
}
try {
Class cls = Class.forName(formatClassName, true,
ClassLoader.getSystemClassLoader());
Method meth = cls.getMethod("getInstance");
return (IIOMetadataFormat) meth.invoke(null);
} catch (Exception e) {
RuntimeException ex =
new IllegalStateException ("Can't obtain format");
ex.initCause(e);
throw ex;
}
}
}