feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
73
jdkSrc/jdk8/javax/imageio/IIOException.java
Normal file
73
jdkSrc/jdk8/javax/imageio/IIOException.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* An exception class used for signaling run-time failure of reading
|
||||
* and writing operations.
|
||||
*
|
||||
* <p> In addition to a message string, a reference to another
|
||||
* <code>Throwable</code> (<code>Error</code> or
|
||||
* <code>Exception</code>) is maintained. This reference, if
|
||||
* non-<code>null</code>, refers to the event that caused this
|
||||
* exception to occur. For example, an <code>IOException</code> while
|
||||
* reading from a <code>File</code> would be stored there.
|
||||
*
|
||||
*/
|
||||
public class IIOException extends IOException {
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOException</code> with a given message
|
||||
* <code>String</code>. No underlying cause is set;
|
||||
* <code>getCause</code> will return <code>null</code>.
|
||||
*
|
||||
* @param message the error message.
|
||||
*
|
||||
* @see #getMessage
|
||||
*/
|
||||
public IIOException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOException</code> with a given message
|
||||
* <code>String</code> and a <code>Throwable</code> that was its
|
||||
* underlying cause.
|
||||
*
|
||||
* @param message the error message.
|
||||
* @param cause the <code>Throwable</code> (<code>Error</code> or
|
||||
* <code>Exception</code>) that caused this exception to occur.
|
||||
*
|
||||
* @see #getCause
|
||||
* @see #getMessage
|
||||
*/
|
||||
public IIOException(String message, Throwable cause) {
|
||||
super(message);
|
||||
initCause(cause);
|
||||
}
|
||||
}
|
||||
322
jdkSrc/jdk8/javax/imageio/IIOImage.java
Normal file
322
jdkSrc/jdk8/javax/imageio/IIOImage.java
Normal file
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.util.List;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
|
||||
/**
|
||||
* A simple container class to aggregate an image, a set of
|
||||
* thumbnail (preview) images, and an object representing metadata
|
||||
* associated with the image.
|
||||
*
|
||||
* <p> The image data may take the form of either a
|
||||
* <code>RenderedImage</code>, or a <code>Raster</code>. Reader
|
||||
* methods that return an <code>IIOImage</code> will always return a
|
||||
* <code>BufferedImage</code> using the <code>RenderedImage</code>
|
||||
* reference. Writer methods that accept an <code>IIOImage</code>
|
||||
* will always accept a <code>RenderedImage</code>, and may optionally
|
||||
* accept a <code>Raster</code>.
|
||||
*
|
||||
* <p> Exactly one of <code>getRenderedImage</code> and
|
||||
* <code>getRaster</code> will return a non-<code>null</code> value.
|
||||
* Subclasses are responsible for ensuring this behavior.
|
||||
*
|
||||
* @see ImageReader#readAll(int, ImageReadParam)
|
||||
* @see ImageReader#readAll(java.util.Iterator)
|
||||
* @see ImageWriter#write(javax.imageio.metadata.IIOMetadata,
|
||||
* IIOImage, ImageWriteParam)
|
||||
* @see ImageWriter#write(IIOImage)
|
||||
* @see ImageWriter#writeToSequence(IIOImage, ImageWriteParam)
|
||||
* @see ImageWriter#writeInsert(int, IIOImage, ImageWriteParam)
|
||||
*
|
||||
*/
|
||||
public class IIOImage {
|
||||
|
||||
/**
|
||||
* The <code>RenderedImage</code> being referenced.
|
||||
*/
|
||||
protected RenderedImage image;
|
||||
|
||||
/**
|
||||
* The <code>Raster</code> being referenced.
|
||||
*/
|
||||
protected Raster raster;
|
||||
|
||||
/**
|
||||
* A <code>List</code> of <code>BufferedImage</code> thumbnails,
|
||||
* or <code>null</code>. Non-<code>BufferedImage</code> objects
|
||||
* must not be stored in this <code>List</code>.
|
||||
*/
|
||||
protected List<? extends BufferedImage> thumbnails = null;
|
||||
|
||||
/**
|
||||
* An <code>IIOMetadata</code> object containing metadata
|
||||
* associated with the image.
|
||||
*/
|
||||
protected IIOMetadata metadata;
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOImage</code> containing a
|
||||
* <code>RenderedImage</code>, and thumbnails and metadata
|
||||
* associated with it.
|
||||
*
|
||||
* <p> All parameters are stored by reference.
|
||||
*
|
||||
* <p> The <code>thumbnails</code> argument must either be
|
||||
* <code>null</code> or contain only <code>BufferedImage</code>
|
||||
* objects.
|
||||
*
|
||||
* @param image a <code>RenderedImage</code>.
|
||||
* @param thumbnails a <code>List</code> of <code>BufferedImage</code>s,
|
||||
* or <code>null</code>.
|
||||
* @param metadata an <code>IIOMetadata</code> object, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>image</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public IIOImage(RenderedImage image,
|
||||
List<? extends BufferedImage> thumbnails,
|
||||
IIOMetadata metadata) {
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException("image == null!");
|
||||
}
|
||||
this.image = image;
|
||||
this.raster = null;
|
||||
this.thumbnails = thumbnails;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOImage</code> containing a
|
||||
* <code>Raster</code>, and thumbnails and metadata
|
||||
* associated with it.
|
||||
*
|
||||
* <p> All parameters are stored by reference.
|
||||
*
|
||||
* @param raster a <code>Raster</code>.
|
||||
* @param thumbnails a <code>List</code> of <code>BufferedImage</code>s,
|
||||
* or <code>null</code>.
|
||||
* @param metadata an <code>IIOMetadata</code> object, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>raster</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public IIOImage(Raster raster,
|
||||
List<? extends BufferedImage> thumbnails,
|
||||
IIOMetadata metadata) {
|
||||
if (raster == null) {
|
||||
throw new IllegalArgumentException("raster == null!");
|
||||
}
|
||||
this.raster = raster;
|
||||
this.image = null;
|
||||
this.thumbnails = thumbnails;
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently set <code>RenderedImage</code>, or
|
||||
* <code>null</code> if only a <code>Raster</code> is available.
|
||||
*
|
||||
* @return a <code>RenderedImage</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #setRenderedImage
|
||||
*/
|
||||
public RenderedImage getRenderedImage() {
|
||||
synchronized(this) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current <code>RenderedImage</code>. The value is
|
||||
* stored by reference. Any existing <code>Raster</code> is
|
||||
* discarded.
|
||||
*
|
||||
* @param image a <code>RenderedImage</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>image</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getRenderedImage
|
||||
*/
|
||||
public void setRenderedImage(RenderedImage image) {
|
||||
synchronized(this) {
|
||||
if (image == null) {
|
||||
throw new IllegalArgumentException("image == null!");
|
||||
}
|
||||
this.image = image;
|
||||
this.raster = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this <code>IIOImage</code> stores
|
||||
* a <code>Raster</code> rather than a <code>RenderedImage</code>.
|
||||
*
|
||||
* @return <code>true</code> if a <code>Raster</code> is
|
||||
* available.
|
||||
*/
|
||||
public boolean hasRaster() {
|
||||
synchronized(this) {
|
||||
return (raster != null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently set <code>Raster</code>, or
|
||||
* <code>null</code> if only a <code>RenderedImage</code> is
|
||||
* available.
|
||||
*
|
||||
* @return a <code>Raster</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #setRaster
|
||||
*/
|
||||
public Raster getRaster() {
|
||||
synchronized(this) {
|
||||
return raster;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current <code>Raster</code>. The value is
|
||||
* stored by reference. Any existing <code>RenderedImage</code> is
|
||||
* discarded.
|
||||
*
|
||||
* @param raster a <code>Raster</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>raster</code> is
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getRaster
|
||||
*/
|
||||
public void setRaster(Raster raster) {
|
||||
synchronized(this) {
|
||||
if (raster == null) {
|
||||
throw new IllegalArgumentException("raster == null!");
|
||||
}
|
||||
this.raster = raster;
|
||||
this.image = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of thumbnails stored in this
|
||||
* <code>IIOImage</code>.
|
||||
*
|
||||
* @return the number of thumbnails, as an <code>int</code>.
|
||||
*/
|
||||
public int getNumThumbnails() {
|
||||
return thumbnails == null ? 0 : thumbnails.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a thumbnail associated with the main image.
|
||||
*
|
||||
* @param index the index of the desired thumbnail image.
|
||||
*
|
||||
* @return a thumbnail image, as a <code>BufferedImage</code>.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if the supplied index is
|
||||
* negative or larger than the largest valid index.
|
||||
* @exception ClassCastException if a
|
||||
* non-<code>BufferedImage</code> object is encountered in the
|
||||
* list of thumbnails at the given index.
|
||||
*
|
||||
* @see #getThumbnails
|
||||
* @see #setThumbnails
|
||||
*/
|
||||
public BufferedImage getThumbnail(int index) {
|
||||
if (thumbnails == null) {
|
||||
throw new IndexOutOfBoundsException("No thumbnails available!");
|
||||
}
|
||||
return (BufferedImage)thumbnails.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current <code>List</code> of thumbnail
|
||||
* <code>BufferedImage</code>s, or <code>null</code> if none is
|
||||
* set. A live reference is returned.
|
||||
*
|
||||
* @return the current <code>List</code> of
|
||||
* <code>BufferedImage</code> thumbnails, or <code>null</code>.
|
||||
*
|
||||
* @see #getThumbnail(int)
|
||||
* @see #setThumbnails
|
||||
*/
|
||||
public List<? extends BufferedImage> getThumbnails() {
|
||||
return thumbnails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the list of thumbnails to a new <code>List</code> of
|
||||
* <code>BufferedImage</code>s, or to <code>null</code>. The
|
||||
* reference to the previous <code>List</code> is discarded.
|
||||
*
|
||||
* <p> The <code>thumbnails</code> argument must either be
|
||||
* <code>null</code> or contain only <code>BufferedImage</code>
|
||||
* objects.
|
||||
*
|
||||
* @param thumbnails a <code>List</code> of
|
||||
* <code>BufferedImage</code> thumbnails, or <code>null</code>.
|
||||
*
|
||||
* @see #getThumbnail(int)
|
||||
* @see #getThumbnails
|
||||
*/
|
||||
public void setThumbnails(List<? extends BufferedImage> thumbnails) {
|
||||
this.thumbnails = thumbnails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current <code>IIOMetadata</code>
|
||||
* object, or <code>null</code> is none is set.
|
||||
*
|
||||
* @return an <code>IIOMetadata</code> object, or <code>null</code>.
|
||||
*
|
||||
* @see #setMetadata
|
||||
*/
|
||||
public IIOMetadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>IIOMetadata</code> to a new object, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @param metadata an <code>IIOMetadata</code> object, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getMetadata
|
||||
*/
|
||||
public void setMetadata(IIOMetadata metadata) {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
}
|
||||
676
jdkSrc/jdk8/javax/imageio/IIOParam.java
Normal file
676
jdkSrc/jdk8/javax/imageio/IIOParam.java
Normal file
@@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
/**
|
||||
* A superclass of all classes describing how streams should be
|
||||
* decoded or encoded. This class contains all the variables and
|
||||
* methods that are shared by <code>ImageReadParam</code> and
|
||||
* <code>ImageWriteParam</code>.
|
||||
*
|
||||
* <p> This class provides mechanisms to specify a source region and a
|
||||
* destination region. When reading, the source is the stream and
|
||||
* the in-memory image is the destination. When writing, these are
|
||||
* reversed. In the case of writing, destination regions may be used
|
||||
* only with a writer that supports pixel replacement.
|
||||
* <p>
|
||||
* Decimation subsampling may be specified for both readers
|
||||
* and writers, using a movable subsampling grid.
|
||||
* <p>
|
||||
* Subsets of the source and destination bands may be selected.
|
||||
*
|
||||
*/
|
||||
public abstract class IIOParam {
|
||||
|
||||
/**
|
||||
* The source region, on <code>null</code> if none is set.
|
||||
*/
|
||||
protected Rectangle sourceRegion = null;
|
||||
|
||||
/**
|
||||
* The decimation subsampling to be applied in the horizontal
|
||||
* direction. By default, the value is <code>1</code>.
|
||||
* The value must not be negative or 0.
|
||||
*/
|
||||
protected int sourceXSubsampling = 1;
|
||||
|
||||
/**
|
||||
* The decimation subsampling to be applied in the vertical
|
||||
* direction. By default, the value is <code>1</code>.
|
||||
* The value must not be negative or 0.
|
||||
*/
|
||||
protected int sourceYSubsampling = 1;
|
||||
|
||||
/**
|
||||
* A horizontal offset to be applied to the subsampling grid before
|
||||
* subsampling. The first pixel to be used will be offset this
|
||||
* amount from the origin of the region, or of the image if no
|
||||
* region is specified.
|
||||
*/
|
||||
protected int subsamplingXOffset = 0;
|
||||
|
||||
/**
|
||||
* A vertical offset to be applied to the subsampling grid before
|
||||
* subsampling. The first pixel to be used will be offset this
|
||||
* amount from the origin of the region, or of the image if no
|
||||
* region is specified.
|
||||
*/
|
||||
protected int subsamplingYOffset = 0;
|
||||
|
||||
/**
|
||||
* An array of <code>int</code>s indicating which source bands
|
||||
* will be used, or <code>null</code>. If <code>null</code>, the
|
||||
* set of source bands to be used is as described in the comment
|
||||
* for the <code>setSourceBands</code> method. No value should
|
||||
* be allowed to be negative.
|
||||
*/
|
||||
protected int[] sourceBands = null;
|
||||
|
||||
/**
|
||||
* An <code>ImageTypeSpecifier</code> to be used to generate a
|
||||
* destination image when reading, or to set the output color type
|
||||
* when writing. If non has been set the value will be
|
||||
* <code>null</code>. By default, the value is <code>null</code>.
|
||||
*/
|
||||
protected ImageTypeSpecifier destinationType = null;
|
||||
|
||||
/**
|
||||
* The offset in the destination where the upper-left decoded
|
||||
* pixel should be placed. By default, the value is (0, 0).
|
||||
*/
|
||||
protected Point destinationOffset = new Point(0, 0);
|
||||
|
||||
/**
|
||||
* The default <code>IIOParamController</code> that will be
|
||||
* used to provide settings for this <code>IIOParam</code>
|
||||
* object when the <code>activateController</code> method
|
||||
* is called. This default should be set by subclasses
|
||||
* that choose to provide their own default controller,
|
||||
* usually a GUI, for setting parameters.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #getDefaultController
|
||||
* @see #activateController
|
||||
*/
|
||||
protected IIOParamController defaultController = null;
|
||||
|
||||
/**
|
||||
* The <code>IIOParamController</code> that will be
|
||||
* used to provide settings for this <code>IIOParam</code>
|
||||
* object when the <code>activateController</code> method
|
||||
* is called. This value overrides any default controller,
|
||||
* even when null.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #setController(IIOParamController)
|
||||
* @see #hasController()
|
||||
* @see #activateController()
|
||||
*/
|
||||
protected IIOParamController controller = null;
|
||||
|
||||
/**
|
||||
* Protected constructor may be called only by subclasses.
|
||||
*/
|
||||
protected IIOParam() {
|
||||
controller = defaultController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source region of interest. The region of interest is
|
||||
* described as a rectangle, with the upper-left corner of the
|
||||
* source image as pixel (0, 0) and increasing values down and to
|
||||
* the right. The actual number of pixels used will depend on
|
||||
* the subsampling factors set by <code>setSourceSubsampling</code>.
|
||||
* If subsampling has been set such that this number is zero,
|
||||
* an <code>IllegalStateException</code> will be thrown.
|
||||
*
|
||||
* <p> The source region of interest specified by this method will
|
||||
* be clipped as needed to fit within the source bounds, as well
|
||||
* as the destination offsets, width, and height at the time of
|
||||
* actual I/O.
|
||||
*
|
||||
* <p> A value of <code>null</code> for <code>sourceRegion</code>
|
||||
* will remove any region specification, causing the entire image
|
||||
* to be used.
|
||||
*
|
||||
* @param sourceRegion a <code>Rectangle</code> specifying the
|
||||
* source region of interest, or <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>sourceRegion</code> is non-<code>null</code> and either
|
||||
* <code>sourceRegion.x</code> or <code>sourceRegion.y</code> is
|
||||
* negative.
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>sourceRegion</code> is non-<code>null</code> and either
|
||||
* <code>sourceRegion.width</code> or
|
||||
* <code>sourceRegion.height</code> is negative or 0.
|
||||
* @exception IllegalStateException if subsampling is such that
|
||||
* this region will have a subsampled width or height of zero.
|
||||
*
|
||||
* @see #getSourceRegion
|
||||
* @see #setSourceSubsampling
|
||||
* @see ImageReadParam#setDestinationOffset
|
||||
* @see ImageReadParam#getDestinationOffset
|
||||
*/
|
||||
public void setSourceRegion(Rectangle sourceRegion) {
|
||||
if (sourceRegion == null) {
|
||||
this.sourceRegion = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sourceRegion.x < 0) {
|
||||
throw new IllegalArgumentException("sourceRegion.x < 0!");
|
||||
}
|
||||
if (sourceRegion.y < 0){
|
||||
throw new IllegalArgumentException("sourceRegion.y < 0!");
|
||||
}
|
||||
if (sourceRegion.width <= 0) {
|
||||
throw new IllegalArgumentException("sourceRegion.width <= 0!");
|
||||
}
|
||||
if (sourceRegion.height <= 0) {
|
||||
throw new IllegalArgumentException("sourceRegion.height <= 0!");
|
||||
}
|
||||
|
||||
// Throw an IllegalStateException if region falls between subsamples
|
||||
if (sourceRegion.width <= subsamplingXOffset) {
|
||||
throw new IllegalStateException
|
||||
("sourceRegion.width <= subsamplingXOffset!");
|
||||
}
|
||||
if (sourceRegion.height <= subsamplingYOffset) {
|
||||
throw new IllegalStateException
|
||||
("sourceRegion.height <= subsamplingYOffset!");
|
||||
}
|
||||
|
||||
this.sourceRegion = (Rectangle)sourceRegion.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source region to be used. The returned value is
|
||||
* that set by the most recent call to
|
||||
* <code>setSourceRegion</code>, and will be <code>null</code> if
|
||||
* there is no region set.
|
||||
*
|
||||
* @return the source region of interest as a
|
||||
* <code>Rectangle</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #setSourceRegion
|
||||
*/
|
||||
public Rectangle getSourceRegion() {
|
||||
if (sourceRegion == null) {
|
||||
return null;
|
||||
}
|
||||
return (Rectangle)sourceRegion.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a decimation subsampling to apply on I/O. The
|
||||
* <code>sourceXSubsampling</code> and
|
||||
* <code>sourceYSubsampling</code> parameters specify the
|
||||
* subsampling period (<i>i.e.</i>, the number of rows and columns
|
||||
* to advance after every source pixel). Specifically, a period of
|
||||
* 1 will use every row or column; a period of 2 will use every
|
||||
* other row or column. The <code>subsamplingXOffset</code> and
|
||||
* <code>subsamplingYOffset</code> parameters specify an offset
|
||||
* from the region (or image) origin for the first subsampled pixel.
|
||||
* Adjusting the origin of the subsample grid is useful for avoiding
|
||||
* seams when subsampling a very large source image into destination
|
||||
* regions that will be assembled into a complete subsampled image.
|
||||
* Most users will want to simply leave these parameters at 0.
|
||||
*
|
||||
* <p> The number of pixels and scanlines to be used are calculated
|
||||
* as follows.
|
||||
* <p>
|
||||
* The number of subsampled pixels in a scanline is given by
|
||||
* <p>
|
||||
* <code>truncate[(width - subsamplingXOffset + sourceXSubsampling - 1)
|
||||
* / sourceXSubsampling]</code>.
|
||||
* <p>
|
||||
* If the region is such that this width is zero, an
|
||||
* <code>IllegalStateException</code> is thrown.
|
||||
* <p>
|
||||
* The number of scanlines to be used can be computed similarly.
|
||||
*
|
||||
* <p>The ability to set the subsampling grid to start somewhere
|
||||
* other than the source region origin is useful if the
|
||||
* region is being used to create subsampled tiles of a large image,
|
||||
* where the tile width and height are not multiples of the
|
||||
* subsampling periods. If the subsampling grid does not remain
|
||||
* consistent from tile to tile, there will be artifacts at the tile
|
||||
* boundaries. By adjusting the subsampling grid offset for each
|
||||
* tile to compensate, these artifacts can be avoided. The tradeoff
|
||||
* is that in order to avoid these artifacts, the tiles are not all
|
||||
* the same size. The grid offset to use in this case is given by:
|
||||
* <br>
|
||||
* grid offset = [period - (region offset modulo period)] modulo period)
|
||||
*
|
||||
* <p> If either <code>sourceXSubsampling</code> or
|
||||
* <code>sourceYSubsampling</code> is 0 or negative, an
|
||||
* <code>IllegalArgumentException</code> will be thrown.
|
||||
*
|
||||
* <p> If either <code>subsamplingXOffset</code> or
|
||||
* <code>subsamplingYOffset</code> is negative or greater than or
|
||||
* equal to the corresponding period, an
|
||||
* <code>IllegalArgumentException</code> will be thrown.
|
||||
*
|
||||
* <p> There is no <code>unsetSourceSubsampling</code> method;
|
||||
* simply call <code>setSourceSubsampling(1, 1, 0, 0)</code> to
|
||||
* restore default values.
|
||||
*
|
||||
* @param sourceXSubsampling the number of columns to advance
|
||||
* between pixels.
|
||||
* @param sourceYSubsampling the number of rows to advance between
|
||||
* pixels.
|
||||
* @param subsamplingXOffset the horizontal offset of the first subsample
|
||||
* within the region, or within the image if no region is set.
|
||||
* @param subsamplingYOffset the horizontal offset of the first subsample
|
||||
* within the region, or within the image if no region is set.
|
||||
* @exception IllegalArgumentException if either period is
|
||||
* negative or 0, or if either grid offset is negative or greater than
|
||||
* the corresponding period.
|
||||
* @exception IllegalStateException if the source region is such that
|
||||
* the subsampled output would contain no pixels.
|
||||
*/
|
||||
public void setSourceSubsampling(int sourceXSubsampling,
|
||||
int sourceYSubsampling,
|
||||
int subsamplingXOffset,
|
||||
int subsamplingYOffset) {
|
||||
if (sourceXSubsampling <= 0) {
|
||||
throw new IllegalArgumentException("sourceXSubsampling <= 0!");
|
||||
}
|
||||
if (sourceYSubsampling <= 0) {
|
||||
throw new IllegalArgumentException("sourceYSubsampling <= 0!");
|
||||
}
|
||||
if (subsamplingXOffset < 0 ||
|
||||
subsamplingXOffset >= sourceXSubsampling) {
|
||||
throw new IllegalArgumentException
|
||||
("subsamplingXOffset out of range!");
|
||||
}
|
||||
if (subsamplingYOffset < 0 ||
|
||||
subsamplingYOffset >= sourceYSubsampling) {
|
||||
throw new IllegalArgumentException
|
||||
("subsamplingYOffset out of range!");
|
||||
}
|
||||
|
||||
// Throw an IllegalStateException if region falls between subsamples
|
||||
if (sourceRegion != null) {
|
||||
if (subsamplingXOffset >= sourceRegion.width ||
|
||||
subsamplingYOffset >= sourceRegion.height) {
|
||||
throw new IllegalStateException("region contains no pixels!");
|
||||
}
|
||||
}
|
||||
|
||||
this.sourceXSubsampling = sourceXSubsampling;
|
||||
this.sourceYSubsampling = sourceYSubsampling;
|
||||
this.subsamplingXOffset = subsamplingXOffset;
|
||||
this.subsamplingYOffset = subsamplingYOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of source columns to advance for each pixel.
|
||||
*
|
||||
* <p>If <code>setSourceSubsampling</code> has not been called, 1
|
||||
* is returned (which is the correct value).
|
||||
*
|
||||
* @return the source subsampling X period.
|
||||
*
|
||||
* @see #setSourceSubsampling
|
||||
* @see #getSourceYSubsampling
|
||||
*/
|
||||
public int getSourceXSubsampling() {
|
||||
return sourceXSubsampling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows to advance for each pixel.
|
||||
*
|
||||
* <p>If <code>setSourceSubsampling</code> has not been called, 1
|
||||
* is returned (which is the correct value).
|
||||
*
|
||||
* @return the source subsampling Y period.
|
||||
*
|
||||
* @see #setSourceSubsampling
|
||||
* @see #getSourceXSubsampling
|
||||
*/
|
||||
public int getSourceYSubsampling() {
|
||||
return sourceYSubsampling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the horizontal offset of the subsampling grid.
|
||||
*
|
||||
* <p>If <code>setSourceSubsampling</code> has not been called, 0
|
||||
* is returned (which is the correct value).
|
||||
*
|
||||
* @return the source subsampling grid X offset.
|
||||
*
|
||||
* @see #setSourceSubsampling
|
||||
* @see #getSubsamplingYOffset
|
||||
*/
|
||||
public int getSubsamplingXOffset() {
|
||||
return subsamplingXOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the vertical offset of the subsampling grid.
|
||||
*
|
||||
* <p>If <code>setSourceSubsampling</code> has not been called, 0
|
||||
* is returned (which is the correct value).
|
||||
*
|
||||
* @return the source subsampling grid Y offset.
|
||||
*
|
||||
* @see #setSourceSubsampling
|
||||
* @see #getSubsamplingXOffset
|
||||
*/
|
||||
public int getSubsamplingYOffset() {
|
||||
return subsamplingYOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indices of the source bands to be used. Duplicate
|
||||
* indices are not allowed.
|
||||
*
|
||||
* <p> A <code>null</code> value indicates that all source bands
|
||||
* will be used.
|
||||
*
|
||||
* <p> At the time of reading, an
|
||||
* <code>IllegalArgumentException</code> will be thrown by the
|
||||
* reader or writer if a value larger than the largest available
|
||||
* source band index has been specified or if the number of source
|
||||
* bands and destination bands to be used differ. The
|
||||
* <code>ImageReader.checkReadParamBandSettings</code> method may
|
||||
* be used to automate this test.
|
||||
*
|
||||
* <p> Semantically, a copy is made of the array; changes to the
|
||||
* array contents subsequent to this call have no effect on
|
||||
* this <code>IIOParam</code>.
|
||||
*
|
||||
* @param sourceBands an array of integer band indices to be
|
||||
* used.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>sourceBands</code>
|
||||
* contains a negative or duplicate value.
|
||||
*
|
||||
* @see #getSourceBands
|
||||
* @see ImageReadParam#setDestinationBands
|
||||
* @see ImageReader#checkReadParamBandSettings
|
||||
*/
|
||||
public void setSourceBands(int[] sourceBands) {
|
||||
if (sourceBands == null) {
|
||||
this.sourceBands = null;
|
||||
} else {
|
||||
int numBands = sourceBands.length;
|
||||
for (int i = 0; i < numBands; i++) {
|
||||
int band = sourceBands[i];
|
||||
if (band < 0) {
|
||||
throw new IllegalArgumentException("Band value < 0!");
|
||||
}
|
||||
for (int j = i + 1; j < numBands; j++) {
|
||||
if (band == sourceBands[j]) {
|
||||
throw new IllegalArgumentException("Duplicate band value!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
this.sourceBands = (int[])(sourceBands.clone());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of of source bands to be used. The returned
|
||||
* value is that set by the most recent call to
|
||||
* <code>setSourceBands</code>, or <code>null</code> if there have
|
||||
* been no calls to <code>setSourceBands</code>.
|
||||
*
|
||||
* <p> Semantically, the array returned is a copy; changes to
|
||||
* array contents subsequent to this call have no effect on this
|
||||
* <code>IIOParam</code>.
|
||||
*
|
||||
* @return the set of source bands to be used, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setSourceBands
|
||||
*/
|
||||
public int[] getSourceBands() {
|
||||
if (sourceBands == null) {
|
||||
return null;
|
||||
}
|
||||
return (int[])(sourceBands.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the desired image type for the destination image, using an
|
||||
* <code>ImageTypeSpecifier</code>.
|
||||
*
|
||||
* <p> When reading, if the layout of the destination has been set
|
||||
* using this method, each call to an <code>ImageReader</code>
|
||||
* <code>read</code> method will return a new
|
||||
* <code>BufferedImage</code> using the format specified by the
|
||||
* supplied type specifier. As a side effect, any destination
|
||||
* <code>BufferedImage</code> set by
|
||||
* <code>ImageReadParam.setDestination(BufferedImage)</code> will
|
||||
* no longer be set as the destination. In other words, this
|
||||
* method may be thought of as calling
|
||||
* <code>setDestination((BufferedImage)null)</code>.
|
||||
*
|
||||
* <p> When writing, the destination type maybe used to determine
|
||||
* the color type of the image. The <code>SampleModel</code>
|
||||
* information will be ignored, and may be <code>null</code>. For
|
||||
* example, a 4-banded image could represent either CMYK or RGBA
|
||||
* data. If a destination type is set, its
|
||||
* <code>ColorModel</code> will override any
|
||||
* <code>ColorModel</code> on the image itself. This is crucial
|
||||
* when <code>setSourceBands</code> is used since the image's
|
||||
* <code>ColorModel</code> will refer to the entire image rather
|
||||
* than to the subset of bands being written.
|
||||
*
|
||||
* @param destinationType the <code>ImageTypeSpecifier</code> to
|
||||
* be used to determine the destination layout and color type.
|
||||
*
|
||||
* @see #getDestinationType
|
||||
*/
|
||||
public void setDestinationType(ImageTypeSpecifier destinationType) {
|
||||
this.destinationType = destinationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of image to be returned by the read, if one
|
||||
* was set by a call to
|
||||
* <code>setDestination(ImageTypeSpecifier)</code>, as an
|
||||
* <code>ImageTypeSpecifier</code>. If none was set,
|
||||
* <code>null</code> is returned.
|
||||
*
|
||||
* @return an <code>ImageTypeSpecifier</code> describing the
|
||||
* destination type, or <code>null</code>.
|
||||
*
|
||||
* @see #setDestinationType
|
||||
*/
|
||||
public ImageTypeSpecifier getDestinationType() {
|
||||
return destinationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the offset in the destination image at which future
|
||||
* decoded pixels are to be placed, when reading, or where a
|
||||
* region will be written, when writing.
|
||||
*
|
||||
* <p> When reading, the region to be written within the
|
||||
* destination <code>BufferedImage</code> will start at this
|
||||
* offset and have a width and height determined by the source
|
||||
* region of interest, the subsampling parameters, and the
|
||||
* destination bounds.
|
||||
*
|
||||
* <p> Normal writes are not affected by this method, only writes
|
||||
* performed using <code>ImageWriter.replacePixels</code>. For
|
||||
* such writes, the offset specified is within the output stream
|
||||
* image whose pixels are being modified.
|
||||
*
|
||||
* <p> There is no <code>unsetDestinationOffset</code> method;
|
||||
* simply call <code>setDestinationOffset(new Point(0, 0))</code> to
|
||||
* restore default values.
|
||||
*
|
||||
* @param destinationOffset the offset in the destination, as a
|
||||
* <code>Point</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>destinationOffset</code> is <code>null</code>.
|
||||
*
|
||||
* @see #getDestinationOffset
|
||||
* @see ImageWriter#replacePixels
|
||||
*/
|
||||
public void setDestinationOffset(Point destinationOffset) {
|
||||
if (destinationOffset == null) {
|
||||
throw new IllegalArgumentException("destinationOffset == null!");
|
||||
}
|
||||
this.destinationOffset = (Point)destinationOffset.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset in the destination image at which pixels are
|
||||
* to be placed.
|
||||
*
|
||||
* <p> If <code>setDestinationOffsets</code> has not been called,
|
||||
* a <code>Point</code> with zero X and Y values is returned
|
||||
* (which is the correct value).
|
||||
*
|
||||
* @return the destination offset as a <code>Point</code>.
|
||||
*
|
||||
* @see #setDestinationOffset
|
||||
*/
|
||||
public Point getDestinationOffset() {
|
||||
return (Point)destinationOffset.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the <code>IIOParamController</code> to be used
|
||||
* to provide settings for this <code>IIOParam</code>
|
||||
* object when the <code>activateController</code> method
|
||||
* is called, overriding any default controller. If the
|
||||
* argument is <code>null</code>, no controller will be
|
||||
* used, including any default. To restore the default, use
|
||||
* <code>setController(getDefaultController())</code>.
|
||||
*
|
||||
* @param controller An appropriate
|
||||
* <code>IIOParamController</code>, or <code>null</code>.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public void setController(IIOParamController controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whatever <code>IIOParamController</code> is currently
|
||||
* installed. This could be the default if there is one,
|
||||
* <code>null</code>, or the argument of the most recent call
|
||||
* to <code>setController</code>.
|
||||
*
|
||||
* @return the currently installed
|
||||
* <code>IIOParamController</code>, or <code>null</code>.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #setController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public IIOParamController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default <code>IIOParamController</code>, if there
|
||||
* is one, regardless of the currently installed controller. If
|
||||
* there is no default controller, returns <code>null</code>.
|
||||
*
|
||||
* @return the default <code>IIOParamController</code>, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #setController(IIOParamController)
|
||||
* @see #getController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public IIOParamController getDefaultController() {
|
||||
return defaultController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if there is a controller installed
|
||||
* for this <code>IIOParam</code> object. This will return
|
||||
* <code>true</code> if <code>getController</code> would not
|
||||
* return <code>null</code>.
|
||||
*
|
||||
* @return <code>true</code> if a controller is installed.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #setController(IIOParamController)
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public boolean hasController() {
|
||||
return (controller != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the installed <code>IIOParamController</code> for
|
||||
* this <code>IIOParam</code> object and returns the resulting
|
||||
* value. When this method returns <code>true</code>, all values
|
||||
* for this <code>IIOParam</code> object will be ready for the
|
||||
* next read or write operation. If <code>false</code> is
|
||||
* returned, no settings in this object will have been disturbed
|
||||
* (<i>i.e.</i>, the user canceled the operation).
|
||||
*
|
||||
* <p> Ordinarily, the controller will be a GUI providing a user
|
||||
* interface for a subclass of <code>IIOParam</code> for a
|
||||
* particular plug-in. Controllers need not be GUIs, however.
|
||||
*
|
||||
* @return <code>true</code> if the controller completed normally.
|
||||
*
|
||||
* @exception IllegalStateException if there is no controller
|
||||
* currently installed.
|
||||
*
|
||||
* @see IIOParamController
|
||||
* @see #setController(IIOParamController)
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
*/
|
||||
public boolean activateController() {
|
||||
if (!hasController()) {
|
||||
throw new IllegalStateException("hasController() == false!");
|
||||
}
|
||||
return getController().activate(this);
|
||||
}
|
||||
}
|
||||
118
jdkSrc/jdk8/javax/imageio/IIOParamController.java
Normal file
118
jdkSrc/jdk8/javax/imageio/IIOParamController.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
/**
|
||||
* An interface to be implemented by objects that can determine the
|
||||
* settings of an <code>IIOParam</code> object, either by putting up a
|
||||
* GUI to obtain values from a user, or by other means. This
|
||||
* interface merely specifies a generic <code>activate</code> method
|
||||
* that invokes the controller, without regard for how the controller
|
||||
* obtains values (<i>i.e.</i>, whether the controller puts up a GUI
|
||||
* or merely computes a set of values is irrelevant to this
|
||||
* interface).
|
||||
*
|
||||
* <p> Within the <code>activate</code> method, a controller obtains
|
||||
* initial values by querying the <code>IIOParam</code> object's
|
||||
* <code>get</code> methods, modifies values by whatever means, then
|
||||
* invokes the <code>IIOParam</code> object's <code>set</code> methods
|
||||
* to modify the appropriate settings. Normally, these
|
||||
* <code>set</code> methods will be invoked all at once at a final
|
||||
* commit in order that a cancel operation not disturb existing
|
||||
* values. In general, applications may expect that when the
|
||||
* <code>activate</code> method returns <code>true</code>, the
|
||||
* <code>IIOParam</code> object is ready for use in a read or write
|
||||
* operation.
|
||||
*
|
||||
* <p> Vendors may choose to provide GUIs for the
|
||||
* <code>IIOParam</code> subclasses they define for a particular
|
||||
* plug-in. These can be set up as default controllers in the
|
||||
* corresponding <code>IIOParam</code> subclasses.
|
||||
*
|
||||
* <p> Applications may override any default GUIs and provide their
|
||||
* own controllers embedded in their own framework. All that is
|
||||
* required is that the<code>activate</code> method behave modally
|
||||
* (not returning until either cancelled or committed), though it need
|
||||
* not put up an explicitly modal dialog. Such a non-modal GUI
|
||||
* component would be coded roughly as follows:
|
||||
*
|
||||
* <br>
|
||||
* <pre>
|
||||
* class MyGUI extends SomeComponent implements IIOParamController {
|
||||
*
|
||||
* public MyGUI() {
|
||||
* // ...
|
||||
* setEnabled(false);
|
||||
* }
|
||||
*
|
||||
* public boolean activate(IIOParam param) {
|
||||
* // disable other components if desired
|
||||
* setEnabled(true);
|
||||
* // go to sleep until either cancelled or committed
|
||||
* boolean ret = false;
|
||||
* if (!cancelled) {
|
||||
* // set values on param
|
||||
* ret = true;
|
||||
* }
|
||||
* setEnabled(false);
|
||||
* // enable any components disabled above
|
||||
* return ret;
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p> Alternatively, an algorithmic process such as a database lookup
|
||||
* or the parsing of a command line could be used as a controller, in
|
||||
* which case the <code>activate</code> method would simply look up or
|
||||
* compute the settings, call the <code>IIOParam.setXXX</code>
|
||||
* methods, and return <code>true</code>.
|
||||
*
|
||||
* @see IIOParam#setController
|
||||
* @see IIOParam#getController
|
||||
* @see IIOParam#getDefaultController
|
||||
* @see IIOParam#hasController
|
||||
* @see IIOParam#activateController
|
||||
*
|
||||
*/
|
||||
public interface IIOParamController {
|
||||
|
||||
/**
|
||||
* Activates the controller. If <code>true</code> is returned,
|
||||
* all settings in the <code>IIOParam</code> object should be
|
||||
* ready for use in a read or write operation. If
|
||||
* <code>false</code> is returned, no settings in the
|
||||
* <code>IIOParam</code> object will be disturbed (<i>i.e.</i>,
|
||||
* the user canceled the operation).
|
||||
*
|
||||
* @param param the <code>IIOParam</code> object to be modified.
|
||||
*
|
||||
* @return <code>true</code> if the <code>IIOParam</code> has been
|
||||
* modified, <code>false</code> otherwise.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>param</code> is
|
||||
* <code>null</code> or is not an instance of the correct class.
|
||||
*/
|
||||
boolean activate(IIOParam param);
|
||||
}
|
||||
1629
jdkSrc/jdk8/javax/imageio/ImageIO.java
Normal file
1629
jdkSrc/jdk8/javax/imageio/ImageIO.java
Normal file
File diff suppressed because it is too large
Load Diff
508
jdkSrc/jdk8/javax/imageio/ImageReadParam.java
Normal file
508
jdkSrc/jdk8/javax/imageio/ImageReadParam.java
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* A class describing how a stream is to be decoded. Instances of
|
||||
* this class or its subclasses are used to supply prescriptive
|
||||
* "how-to" information to instances of <code>ImageReader</code>.
|
||||
*
|
||||
* <p> An image encoded as part of a file or stream may be thought of
|
||||
* extending out in multiple dimensions: the spatial dimensions of
|
||||
* width and height, a number of bands, and a number of progressive
|
||||
* decoding passes. This class allows a contiguous (hyper)rectangular
|
||||
* subarea of the image in all of these dimensions to be selected for
|
||||
* decoding. Additionally, the spatial dimensions may be subsampled
|
||||
* discontinuously. Finally, color and format conversions may be
|
||||
* specified by controlling the <code>ColorModel</code> and
|
||||
* <code>SampleModel</code> of the destination image, either by
|
||||
* providing a <code>BufferedImage</code> or by using an
|
||||
* <code>ImageTypeSpecifier</code>.
|
||||
*
|
||||
* <p> An <code>ImageReadParam</code> object is used to specify how an
|
||||
* image, or a set of images, will be converted on input from
|
||||
* a stream in the context of the Java Image I/O framework. A plug-in for a
|
||||
* specific image format will return instances of
|
||||
* <code>ImageReadParam</code> from the
|
||||
* <code>getDefaultReadParam</code> method of its
|
||||
* <code>ImageReader</code> implementation.
|
||||
*
|
||||
* <p> The state maintained by an instance of
|
||||
* <code>ImageReadParam</code> is independent of any particular image
|
||||
* being decoded. When actual decoding takes place, the values set in
|
||||
* the read param are combined with the actual properties of the image
|
||||
* being decoded from the stream and the destination
|
||||
* <code>BufferedImage</code> that will receive the decoded pixel
|
||||
* data. For example, the source region set using
|
||||
* <code>setSourceRegion</code> will first be intersected with the
|
||||
* actual valid source area. The result will be translated by the
|
||||
* value returned by <code>getDestinationOffset</code>, and the
|
||||
* resulting rectangle intersected with the actual valid destination
|
||||
* area to yield the destination area that will be written.
|
||||
*
|
||||
* <p> The parameters specified by an <code>ImageReadParam</code> are
|
||||
* applied to an image as follows. First, if a rendering size has
|
||||
* been set by <code>setSourceRenderSize</code>, the entire decoded
|
||||
* image is rendered at the size given by
|
||||
* <code>getSourceRenderSize</code>. Otherwise, the image has its
|
||||
* natural size given by <code>ImageReader.getWidth</code> and
|
||||
* <code>ImageReader.getHeight</code>.
|
||||
*
|
||||
* <p> Next, the image is clipped against the source region
|
||||
* specified by <code>getSourceXOffset</code>, <code>getSourceYOffset</code>,
|
||||
* <code>getSourceWidth</code>, and <code>getSourceHeight</code>.
|
||||
*
|
||||
* <p> The resulting region is then subsampled according to the
|
||||
* factors given in {@link IIOParam#setSourceSubsampling
|
||||
* IIOParam.setSourceSubsampling}. The first pixel,
|
||||
* the number of pixels per row, and the number of rows all depend
|
||||
* on the subsampling settings.
|
||||
* Call the minimum X and Y coordinates of the resulting rectangle
|
||||
* (<code>minX</code>, <code>minY</code>), its width <code>w</code>
|
||||
* and its height <code>h</code>.
|
||||
*
|
||||
* <p> This rectangle is offset by
|
||||
* (<code>getDestinationOffset().x</code>,
|
||||
* <code>getDestinationOffset().y</code>) and clipped against the
|
||||
* destination bounds. If no destination image has been set, the
|
||||
* destination is defined to have a width of
|
||||
* <code>getDestinationOffset().x</code> + <code>w</code>, and a
|
||||
* height of <code>getDestinationOffset().y</code> + <code>h</code> so
|
||||
* that all pixels of the source region may be written to the
|
||||
* destination.
|
||||
*
|
||||
* <p> Pixels that land, after subsampling, within the destination
|
||||
* image, and that are written in one of the progressive passes
|
||||
* specified by <code>getSourceMinProgressivePass</code> and
|
||||
* <code>getSourceNumProgressivePasses</code> are passed along to the
|
||||
* next step.
|
||||
*
|
||||
* <p> Finally, the source samples of each pixel are mapped into
|
||||
* destination bands according to the algorithm described in the
|
||||
* comment for <code>setDestinationBands</code>.
|
||||
*
|
||||
* <p> Plug-in writers may extend the functionality of
|
||||
* <code>ImageReadParam</code> by providing a subclass that implements
|
||||
* additional, plug-in specific interfaces. It is up to the plug-in
|
||||
* to document what interfaces are available and how they are to be
|
||||
* used. Readers will silently ignore any extended features of an
|
||||
* <code>ImageReadParam</code> subclass of which they are not aware.
|
||||
* Also, they may ignore any optional features that they normally
|
||||
* disable when creating their own <code>ImageReadParam</code>
|
||||
* instances via <code>getDefaultReadParam</code>.
|
||||
*
|
||||
* <p> Note that unless a query method exists for a capability, it must
|
||||
* be supported by all <code>ImageReader</code> implementations
|
||||
* (<i>e.g.</i> source render size is optional, but subsampling must be
|
||||
* supported).
|
||||
*
|
||||
*
|
||||
* @see ImageReader
|
||||
* @see ImageWriter
|
||||
* @see ImageWriteParam
|
||||
*/
|
||||
public class ImageReadParam extends IIOParam {
|
||||
|
||||
/**
|
||||
* <code>true</code> if this <code>ImageReadParam</code> allows
|
||||
* the source rendering dimensions to be set. By default, the
|
||||
* value is <code>false</code>. Subclasses must set this value
|
||||
* manually.
|
||||
*
|
||||
* <p> <code>ImageReader</code>s that do not support setting of
|
||||
* the source render size should set this value to
|
||||
* <code>false</code>.
|
||||
*/
|
||||
protected boolean canSetSourceRenderSize = false;
|
||||
|
||||
/**
|
||||
* The desired rendering width and height of the source, if
|
||||
* <code>canSetSourceRenderSize</code> is <code>true</code>, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* <p> <code>ImageReader</code>s that do not support setting of
|
||||
* the source render size may ignore this value.
|
||||
*/
|
||||
protected Dimension sourceRenderSize = null;
|
||||
|
||||
/**
|
||||
* The current destination <code>BufferedImage</code>, or
|
||||
* <code>null</code> if none has been set. By default, the value
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
protected BufferedImage destination = null;
|
||||
|
||||
/**
|
||||
* The set of destination bands to be used, as an array of
|
||||
* <code>int</code>s. By default, the value is <code>null</code>,
|
||||
* indicating all destination bands should be written in order.
|
||||
*/
|
||||
protected int[] destinationBands = null;
|
||||
|
||||
/**
|
||||
* The minimum index of a progressive pass to read from the
|
||||
* source. By default, the value is set to 0, which indicates
|
||||
* that passes starting with the first available pass should be
|
||||
* decoded.
|
||||
*
|
||||
* <p> Subclasses should ensure that this value is
|
||||
* non-negative.
|
||||
*/
|
||||
protected int minProgressivePass = 0;
|
||||
|
||||
/**
|
||||
* The maximum number of progressive passes to read from the
|
||||
* source. By default, the value is set to
|
||||
* <code>Integer.MAX_VALUE</code>, which indicates that passes up
|
||||
* to and including the last available pass should be decoded.
|
||||
*
|
||||
* <p> Subclasses should ensure that this value is positive.
|
||||
* Additionally, if the value is not
|
||||
* <code>Integer.MAX_VALUE</code>, then <code>minProgressivePass +
|
||||
* numProgressivePasses - 1</code> should not exceed
|
||||
* <code>Integer.MAX_VALUE</code>.
|
||||
*/
|
||||
protected int numProgressivePasses = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageReadParam</code>.
|
||||
*/
|
||||
public ImageReadParam() {}
|
||||
|
||||
// Comment inherited
|
||||
public void setDestinationType(ImageTypeSpecifier destinationType) {
|
||||
super.setDestinationType(destinationType);
|
||||
setDestination(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplies a <code>BufferedImage</code> to be used as the
|
||||
* destination for decoded pixel data. The currently set image
|
||||
* will be written to by the <code>read</code>,
|
||||
* <code>readAll</code>, and <code>readRaster</code> methods, and
|
||||
* a reference to it will be returned by those methods.
|
||||
*
|
||||
* <p> Pixel data from the aforementioned methods will be written
|
||||
* starting at the offset specified by
|
||||
* <code>getDestinationOffset</code>.
|
||||
*
|
||||
* <p> If <code>destination</code> is <code>null</code>, a
|
||||
* newly-created <code>BufferedImage</code> will be returned by
|
||||
* those methods.
|
||||
*
|
||||
* <p> At the time of reading, the image is checked to verify that
|
||||
* its <code>ColorModel</code> and <code>SampleModel</code>
|
||||
* correspond to one of the <code>ImageTypeSpecifier</code>s
|
||||
* returned from the <code>ImageReader</code>'s
|
||||
* <code>getImageTypes</code> method. If it does not, the reader
|
||||
* will throw an <code>IIOException</code>.
|
||||
*
|
||||
* @param destination the BufferedImage to be written to, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getDestination
|
||||
*/
|
||||
public void setDestination(BufferedImage destination) {
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>BufferedImage</code> currently set by the
|
||||
* <code>setDestination</code> method, or <code>null</code>
|
||||
* if none is set.
|
||||
*
|
||||
* @return the BufferedImage to be written to.
|
||||
*
|
||||
* @see #setDestination
|
||||
*/
|
||||
public BufferedImage getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indices of the destination bands where data
|
||||
* will be placed. Duplicate indices are not allowed.
|
||||
*
|
||||
* <p> A <code>null</code> value indicates that all destination
|
||||
* bands will be used.
|
||||
*
|
||||
* <p> Choosing a destination band subset will not affect the
|
||||
* number of bands in the output image of a read if no destination
|
||||
* image is specified; the created destination image will still
|
||||
* have the same number of bands as if this method had never been
|
||||
* called. If a different number of bands in the destination
|
||||
* image is desired, an image must be supplied using the
|
||||
* <code>ImageReadParam.setDestination</code> method.
|
||||
*
|
||||
* <p> At the time of reading or writing, an
|
||||
* <code>IllegalArgumentException</code> will be thrown by the
|
||||
* reader or writer if a value larger than the largest destination
|
||||
* band index has been specified, or if the number of source bands
|
||||
* and destination bands to be used differ. The
|
||||
* <code>ImageReader.checkReadParamBandSettings</code> method may
|
||||
* be used to automate this test.
|
||||
*
|
||||
* @param destinationBands an array of integer band indices to be
|
||||
* used.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>destinationBands</code>
|
||||
* contains a negative or duplicate value.
|
||||
*
|
||||
* @see #getDestinationBands
|
||||
* @see #getSourceBands
|
||||
* @see ImageReader#checkReadParamBandSettings
|
||||
*/
|
||||
public void setDestinationBands(int[] destinationBands) {
|
||||
if (destinationBands == null) {
|
||||
this.destinationBands = null;
|
||||
} else {
|
||||
int numBands = destinationBands.length;
|
||||
for (int i = 0; i < numBands; i++) {
|
||||
int band = destinationBands[i];
|
||||
if (band < 0) {
|
||||
throw new IllegalArgumentException("Band value < 0!");
|
||||
}
|
||||
for (int j = i + 1; j < numBands; j++) {
|
||||
if (band == destinationBands[j]) {
|
||||
throw new IllegalArgumentException("Duplicate band value!");
|
||||
}
|
||||
}
|
||||
}
|
||||
this.destinationBands = (int[])destinationBands.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of band indices where data will be placed.
|
||||
* If no value has been set, <code>null</code> is returned to
|
||||
* indicate that all destination bands will be used.
|
||||
*
|
||||
* @return the indices of the destination bands to be used,
|
||||
* or <code>null</code>.
|
||||
*
|
||||
* @see #setDestinationBands
|
||||
*/
|
||||
public int[] getDestinationBands() {
|
||||
if (destinationBands == null) {
|
||||
return null;
|
||||
} else {
|
||||
return (int[])(destinationBands.clone());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this reader allows the source
|
||||
* image to be rendered at an arbitrary size as part of the
|
||||
* decoding process, by means of the
|
||||
* <code>setSourceRenderSize</code> method. If this method
|
||||
* returns <code>false</code>, calls to
|
||||
* <code>setSourceRenderSize</code> will throw an
|
||||
* <code>UnsupportedOperationException</code>.
|
||||
*
|
||||
* @return <code>true</code> if setting source rendering size is
|
||||
* supported.
|
||||
*
|
||||
* @see #setSourceRenderSize
|
||||
*/
|
||||
public boolean canSetSourceRenderSize() {
|
||||
return canSetSourceRenderSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the image is able to be rendered at an arbitrary size, sets
|
||||
* the source width and height to the supplied values. Note that
|
||||
* the values returned from the <code>getWidth</code> and
|
||||
* <code>getHeight</code> methods on <code>ImageReader</code> are
|
||||
* not affected by this method; they will continue to return the
|
||||
* default size for the image. Similarly, if the image is also
|
||||
* tiled the tile width and height are given in terms of the default
|
||||
* size.
|
||||
*
|
||||
* <p> Typically, the width and height should be chosen such that
|
||||
* the ratio of width to height closely approximates the aspect
|
||||
* ratio of the image, as returned from
|
||||
* <code>ImageReader.getAspectRatio</code>.
|
||||
*
|
||||
* <p> If this plug-in does not allow the rendering size to be
|
||||
* set, an <code>UnsupportedOperationException</code> will be
|
||||
* thrown.
|
||||
*
|
||||
* <p> To remove the render size setting, pass in a value of
|
||||
* <code>null</code> for <code>size</code>.
|
||||
*
|
||||
* @param size a <code>Dimension</code> indicating the desired
|
||||
* width and height.
|
||||
*
|
||||
* @exception IllegalArgumentException if either the width or the
|
||||
* height is negative or 0.
|
||||
* @exception UnsupportedOperationException if image resizing
|
||||
* is not supported by this plug-in.
|
||||
*
|
||||
* @see #getSourceRenderSize
|
||||
* @see ImageReader#getWidth
|
||||
* @see ImageReader#getHeight
|
||||
* @see ImageReader#getAspectRatio
|
||||
*/
|
||||
public void setSourceRenderSize(Dimension size)
|
||||
throws UnsupportedOperationException {
|
||||
if (!canSetSourceRenderSize()) {
|
||||
throw new UnsupportedOperationException
|
||||
("Can't set source render size!");
|
||||
}
|
||||
|
||||
if (size == null) {
|
||||
this.sourceRenderSize = null;
|
||||
} else {
|
||||
if (size.width <= 0 || size.height <= 0) {
|
||||
throw new IllegalArgumentException("width or height <= 0!");
|
||||
}
|
||||
this.sourceRenderSize = (Dimension)size.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width and height of the source image as it
|
||||
* will be rendered during decoding, if they have been set via the
|
||||
* <code>setSourceRenderSize</code> method. A
|
||||
* <code>null</code>value indicates that no setting has been made.
|
||||
*
|
||||
* @return the rendered width and height of the source image
|
||||
* as a <code>Dimension</code>.
|
||||
*
|
||||
* @see #setSourceRenderSize
|
||||
*/
|
||||
public Dimension getSourceRenderSize() {
|
||||
return (sourceRenderSize == null) ?
|
||||
null : (Dimension)sourceRenderSize.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the range of progressive passes that will be decoded.
|
||||
* Passes outside of this range will be ignored.
|
||||
*
|
||||
* <p> A progressive pass is a re-encoding of the entire image,
|
||||
* generally at progressively higher effective resolutions, but
|
||||
* requiring greater transmission bandwidth. The most common use
|
||||
* of progressive encoding is found in the JPEG format, where
|
||||
* successive passes include more detailed representations of the
|
||||
* high-frequency image content.
|
||||
*
|
||||
* <p> The actual number of passes to be decoded is determined
|
||||
* during decoding, based on the number of actual passes available
|
||||
* in the stream. Thus if <code>minPass + numPasses - 1</code> is
|
||||
* larger than the index of the last available passes, decoding
|
||||
* will end with that pass.
|
||||
*
|
||||
* <p> A value of <code>numPasses</code> of
|
||||
* <code>Integer.MAX_VALUE</code> indicates that all passes from
|
||||
* <code>minPass</code> forward should be read. Otherwise, the
|
||||
* index of the last pass (<i>i.e.</i>, <code>minPass + numPasses
|
||||
* - 1</code>) must not exceed <code>Integer.MAX_VALUE</code>.
|
||||
*
|
||||
* <p> There is no <code>unsetSourceProgressivePasses</code>
|
||||
* method; the same effect may be obtained by calling
|
||||
* <code>setSourceProgressivePasses(0, Integer.MAX_VALUE)</code>.
|
||||
*
|
||||
* @param minPass the index of the first pass to be decoded.
|
||||
* @param numPasses the maximum number of passes to be decoded.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>minPass</code> is
|
||||
* negative, <code>numPasses</code> is negative or 0, or
|
||||
* <code>numPasses</code> is smaller than
|
||||
* <code>Integer.MAX_VALUE</code> but <code>minPass +
|
||||
* numPasses - 1</code> is greater than
|
||||
* <code>INTEGER.MAX_VALUE</code>.
|
||||
*
|
||||
* @see #getSourceMinProgressivePass
|
||||
* @see #getSourceMaxProgressivePass
|
||||
*/
|
||||
public void setSourceProgressivePasses(int minPass, int numPasses) {
|
||||
if (minPass < 0) {
|
||||
throw new IllegalArgumentException("minPass < 0!");
|
||||
}
|
||||
if (numPasses <= 0) {
|
||||
throw new IllegalArgumentException("numPasses <= 0!");
|
||||
}
|
||||
if ((numPasses != Integer.MAX_VALUE) &&
|
||||
(((minPass + numPasses - 1) & 0x80000000) != 0)) {
|
||||
throw new IllegalArgumentException
|
||||
("minPass + numPasses - 1 > INTEGER.MAX_VALUE!");
|
||||
}
|
||||
|
||||
this.minProgressivePass = minPass;
|
||||
this.numProgressivePasses = numPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the first progressive pass that will be
|
||||
* decoded. If no value has been set, 0 will be returned (which is
|
||||
* the correct value).
|
||||
*
|
||||
* @return the index of the first pass that will be decoded.
|
||||
*
|
||||
* @see #setSourceProgressivePasses
|
||||
* @see #getSourceNumProgressivePasses
|
||||
*/
|
||||
public int getSourceMinProgressivePass() {
|
||||
return minProgressivePass;
|
||||
}
|
||||
|
||||
/**
|
||||
* If <code>getSourceNumProgressivePasses</code> is equal to
|
||||
* <code>Integer.MAX_VALUE</code>, returns
|
||||
* <code>Integer.MAX_VALUE</code>. Otherwise, returns
|
||||
* <code>getSourceMinProgressivePass() +
|
||||
* getSourceNumProgressivePasses() - 1</code>.
|
||||
*
|
||||
* @return the index of the last pass to be read, or
|
||||
* <code>Integer.MAX_VALUE</code>.
|
||||
*/
|
||||
public int getSourceMaxProgressivePass() {
|
||||
if (numProgressivePasses == Integer.MAX_VALUE) {
|
||||
return Integer.MAX_VALUE;
|
||||
} else {
|
||||
return minProgressivePass + numProgressivePasses - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the progressive passes that will be
|
||||
* decoded. If no value has been set,
|
||||
* <code>Integer.MAX_VALUE</code> will be returned (which is the
|
||||
* correct value).
|
||||
*
|
||||
* @return the number of the passes that will be decoded.
|
||||
*
|
||||
* @see #setSourceProgressivePasses
|
||||
* @see #getSourceMinProgressivePass
|
||||
*/
|
||||
public int getSourceNumProgressivePasses() {
|
||||
return numProgressivePasses;
|
||||
}
|
||||
}
|
||||
2894
jdkSrc/jdk8/javax/imageio/ImageReader.java
Normal file
2894
jdkSrc/jdk8/javax/imageio/ImageReader.java
Normal file
File diff suppressed because it is too large
Load Diff
152
jdkSrc/jdk8/javax/imageio/ImageTranscoder.java
Normal file
152
jdkSrc/jdk8/javax/imageio/ImageTranscoder.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
|
||||
/**
|
||||
* An interface providing metadata transcoding capability.
|
||||
*
|
||||
* <p> Any image may be transcoded (written to a different format
|
||||
* than the one it was originally stored in) simply by performing
|
||||
* a read operation followed by a write operation. However, loss
|
||||
* of data may occur in this process due to format differences.
|
||||
*
|
||||
* <p> In general, the best results will be achieved when
|
||||
* format-specific metadata objects can be created to encapsulate as
|
||||
* much information about the image and its associated metadata as
|
||||
* possible, in terms that are understood by the specific
|
||||
* <code>ImageWriter</code> used to perform the encoding.
|
||||
*
|
||||
* <p> An <code>ImageTranscoder</code> may be used to convert the
|
||||
* <code>IIOMetadata</code> objects supplied by the
|
||||
* <code>ImageReader</code> (representing per-stream and per-image
|
||||
* metadata) into corresponding objects suitable for encoding by a
|
||||
* particular <code>ImageWriter</code>. In the case where the methods
|
||||
* of this interface are being called directly on an
|
||||
* <code>ImageWriter</code>, the output will be suitable for that
|
||||
* writer.
|
||||
*
|
||||
* <p> The internal details of converting an <code>IIOMetadata</code>
|
||||
* object into a writer-specific format will vary according to the
|
||||
* context of the operation. Typically, an <code>ImageWriter</code>
|
||||
* will inspect the incoming object to see if it implements additional
|
||||
* interfaces with which the writer is familiar. This might be the
|
||||
* case, for example, if the object was obtained by means of a read
|
||||
* operation on a reader plug-in written by the same vendor as the
|
||||
* writer. In this case, the writer may access the incoming object by
|
||||
* means of its plug-in specific interfaces. In this case, the
|
||||
* re-encoding may be close to lossless if the image file format is
|
||||
* kept constant. If the format is changing, the writer may still
|
||||
* attempt to preserve as much information as possible.
|
||||
*
|
||||
* <p> If the incoming object does not implement any additional
|
||||
* interfaces known to the writer, the writer has no choice but to
|
||||
* access it via the standard <code>IIOMetadata</code> interfaces such
|
||||
* as the tree view provided by <code>IIOMetadata.getAsTree</code>.
|
||||
* In this case, there is likely to be significant loss of
|
||||
* information.
|
||||
*
|
||||
* <p> An independent <code>ImageTranscoder</code> essentially takes
|
||||
* on the same role as the writer plug-in in the above examples. It
|
||||
* must be familiar with the private interfaces used by both the
|
||||
* reader and writer plug-ins, and manually instantiate an object that
|
||||
* will be usable by the writer. The resulting metadata objects may
|
||||
* be used by the writer directly.
|
||||
*
|
||||
* <p> No independent implementations of <code>ImageTranscoder</code>
|
||||
* are provided as part of the standard API. Instead, the intention
|
||||
* of this interface is to provide a way for implementations to be
|
||||
* created and discovered by applications as the need arises.
|
||||
*
|
||||
*/
|
||||
public interface ImageTranscoder {
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadata</code> object that may be used for
|
||||
* encoding and optionally modified using its document interfaces
|
||||
* or other interfaces specific to the writer plug-in that will be
|
||||
* used for encoding.
|
||||
*
|
||||
* <p> An optional <code>ImageWriteParam</code> may be supplied
|
||||
* for cases where it may affect the structure of the stream
|
||||
* metadata.
|
||||
*
|
||||
* <p> If the supplied <code>ImageWriteParam</code> contains
|
||||
* optional setting values not understood by this writer or
|
||||
* transcoder, they will be ignored.
|
||||
*
|
||||
* @param inData an <code>IIOMetadata</code> object representing
|
||||
* stream metadata, used to initialize the state of the returned
|
||||
* object.
|
||||
* @param param an <code>ImageWriteParam</code> that will be used to
|
||||
* encode the image, or <code>null</code>.
|
||||
*
|
||||
* @return an <code>IIOMetadata</code> object, or
|
||||
* <code>null</code> if the plug-in does not provide metadata
|
||||
* encoding capabilities.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>inData</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
IIOMetadata convertStreamMetadata(IIOMetadata inData,
|
||||
ImageWriteParam param);
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadata</code> object that may be used for
|
||||
* encoding and optionally modified using its document interfaces
|
||||
* or other interfaces specific to the writer plug-in that will be
|
||||
* used for encoding.
|
||||
*
|
||||
* <p> An optional <code>ImageWriteParam</code> may be supplied
|
||||
* for cases where it may affect the structure of the image
|
||||
* metadata.
|
||||
*
|
||||
* <p> If the supplied <code>ImageWriteParam</code> contains
|
||||
* optional setting values not understood by this writer or
|
||||
* transcoder, they will be ignored.
|
||||
*
|
||||
* @param inData an <code>IIOMetadata</code> object representing
|
||||
* image metadata, used to initialize the state of the returned
|
||||
* object.
|
||||
* @param imageType an <code>ImageTypeSpecifier</code> indicating
|
||||
* the layout and color information of the image with which the
|
||||
* metadata will be associated.
|
||||
* @param param an <code>ImageWriteParam</code> that will be used to
|
||||
* encode the image, or <code>null</code>.
|
||||
*
|
||||
* @return an <code>IIOMetadata</code> object,
|
||||
* or <code>null</code> if the plug-in does not provide
|
||||
* metadata encoding capabilities.
|
||||
*
|
||||
* @exception IllegalArgumentException if either of
|
||||
* <code>inData</code> or <code>imageType</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
IIOMetadata convertImageMetadata(IIOMetadata inData,
|
||||
ImageTypeSpecifier imageType,
|
||||
ImageWriteParam param);
|
||||
}
|
||||
1241
jdkSrc/jdk8/javax/imageio/ImageTypeSpecifier.java
Normal file
1241
jdkSrc/jdk8/javax/imageio/ImageTypeSpecifier.java
Normal file
File diff suppressed because it is too large
Load Diff
1470
jdkSrc/jdk8/javax/imageio/ImageWriteParam.java
Normal file
1470
jdkSrc/jdk8/javax/imageio/ImageWriteParam.java
Normal file
File diff suppressed because it is too large
Load Diff
2037
jdkSrc/jdk8/javax/imageio/ImageWriter.java
Normal file
2037
jdkSrc/jdk8/javax/imageio/ImageWriter.java
Normal file
File diff suppressed because it is too large
Load Diff
170
jdkSrc/jdk8/javax/imageio/event/IIOReadProgressListener.java
Normal file
170
jdkSrc/jdk8/javax/imageio/event/IIOReadProgressListener.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
import javax.imageio.ImageReader;
|
||||
|
||||
/**
|
||||
* An interface used by <code>ImageReader</code> implementations to
|
||||
* notify callers of their image and thumbnail reading methods of
|
||||
* progress.
|
||||
*
|
||||
* <p> This interface receives general indications of decoding
|
||||
* progress (via the <code>imageProgress</code> and
|
||||
* <code>thumbnailProgress</code> methods), and events indicating when
|
||||
* an entire image has been updated (via the
|
||||
* <code>imageStarted</code>, <code>imageComplete</code>,
|
||||
* <code>thumbnailStarted</code> and <code>thumbnailComplete</code>
|
||||
* methods). Applications that wish to be informed of pixel updates
|
||||
* as they happen (for example, during progressive decoding), should
|
||||
* provide an <code>IIOReadUpdateListener</code>.
|
||||
*
|
||||
* @see IIOReadUpdateListener
|
||||
* @see javax.imageio.ImageReader#addIIOReadProgressListener
|
||||
* @see javax.imageio.ImageReader#removeIIOReadProgressListener
|
||||
*
|
||||
*/
|
||||
public interface IIOReadProgressListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports that a sequence of read operations is beginning.
|
||||
* <code>ImageReader</code> implementations are required to call
|
||||
* this method exactly once from their
|
||||
* <code>readAll(Iterator)</code> method.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param minIndex the index of the first image to be read.
|
||||
*/
|
||||
void sequenceStarted(ImageReader source, int minIndex);
|
||||
|
||||
/**
|
||||
* Reports that a sequence of read operations has completed.
|
||||
* <code>ImageReader</code> implementations are required to call
|
||||
* this method exactly once from their
|
||||
* <code>readAll(Iterator)</code> method.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
*/
|
||||
void sequenceComplete(ImageReader source);
|
||||
|
||||
/**
|
||||
* Reports that an image read operation is beginning. All
|
||||
* <code>ImageReader</code> implementations are required to call
|
||||
* this method exactly once when beginning an image read
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param imageIndex the index of the image being read within its
|
||||
* containing input file or stream.
|
||||
*/
|
||||
void imageStarted(ImageReader source, int imageIndex);
|
||||
|
||||
/**
|
||||
* Reports the approximate degree of completion of the current
|
||||
* <code>read</code> call of the associated
|
||||
* <code>ImageReader</code>.
|
||||
*
|
||||
* <p> The degree of completion is expressed as a percentage
|
||||
* varying from <code>0.0F</code> to <code>100.0F</code>. The
|
||||
* percentage should ideally be calculated in terms of the
|
||||
* remaining time to completion, but it is usually more practical
|
||||
* to use a more well-defined metric such as pixels decoded or
|
||||
* portion of input stream consumed. In any case, a sequence of
|
||||
* calls to this method during a given read operation should
|
||||
* supply a monotonically increasing sequence of percentage
|
||||
* values. It is not necessary to supply the exact values
|
||||
* <code>0</code> and <code>100</code>, as these may be inferred
|
||||
* by the callee from other methods.
|
||||
*
|
||||
* <p> Each particular <code>ImageReader</code> implementation may
|
||||
* call this method at whatever frequency it desires. A rule of
|
||||
* thumb is to call it around each 5 percent mark.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param percentageDone the approximate percentage of decoding that
|
||||
* has been completed.
|
||||
*/
|
||||
void imageProgress(ImageReader source, float percentageDone);
|
||||
|
||||
/**
|
||||
* Reports that the current image read operation has completed.
|
||||
* All <code>ImageReader</code> implementations are required to
|
||||
* call this method exactly once upon completion of each image
|
||||
* read operation.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
*/
|
||||
void imageComplete(ImageReader source);
|
||||
|
||||
/**
|
||||
* Reports that a thumbnail read operation is beginning. All
|
||||
* <code>ImageReader</code> implementations are required to call
|
||||
* this method exactly once when beginning a thumbnail read
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param imageIndex the index of the image being read within its
|
||||
* containing input file or stream.
|
||||
* @param thumbnailIndex the index of the thumbnail being read.
|
||||
*/
|
||||
void thumbnailStarted(ImageReader source,
|
||||
int imageIndex, int thumbnailIndex);
|
||||
|
||||
/**
|
||||
* Reports the approximate degree of completion of the current
|
||||
* <code>getThumbnail</code> call within the associated
|
||||
* <code>ImageReader</code>. The semantics are identical to those
|
||||
* of <code>imageProgress</code>.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param percentageDone the approximate percentage of decoding that
|
||||
* has been completed.
|
||||
*/
|
||||
void thumbnailProgress(ImageReader source, float percentageDone);
|
||||
|
||||
/**
|
||||
* Reports that a thumbnail read operation has completed. All
|
||||
* <code>ImageReader</code> implementations are required to call
|
||||
* this method exactly once upon completion of each thumbnail read
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
*/
|
||||
void thumbnailComplete(ImageReader source);
|
||||
|
||||
/**
|
||||
* Reports that a read has been aborted via the reader's
|
||||
* <code>abort</code> method. No further notifications will be
|
||||
* given.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
*/
|
||||
void readAborted(ImageReader source);
|
||||
}
|
||||
249
jdkSrc/jdk8/javax/imageio/event/IIOReadUpdateListener.java
Normal file
249
jdkSrc/jdk8/javax/imageio/event/IIOReadUpdateListener.java
Normal file
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.event;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.EventListener;
|
||||
import javax.imageio.ImageReader;
|
||||
|
||||
/**
|
||||
* An interface used by <code>ImageReader</code> implementations to
|
||||
* notify callers of their image and thumbnail reading methods of
|
||||
* pixel updates.
|
||||
*
|
||||
* @see javax.imageio.ImageReader#addIIOReadUpdateListener
|
||||
* @see javax.imageio.ImageReader#removeIIOReadUpdateListener
|
||||
*
|
||||
*/
|
||||
public interface IIOReadUpdateListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports that the current read operation is about to begin a
|
||||
* progressive pass. Readers of formats that support progressive
|
||||
* encoding should use this to notify clients when each pass is
|
||||
* completed when reading a progressively encoded image.
|
||||
*
|
||||
* <p> An estimate of the area that will be updated by the pass is
|
||||
* indicated by the <code>minX</code>, <code>minY</code>,
|
||||
* <code>width</code>, and <code>height</code> parameters. If the
|
||||
* pass is interlaced, that is, it only updates selected rows or
|
||||
* columns, the <code>periodX</code> and <code>periodY</code>
|
||||
* parameters will indicate the degree of subsampling. The set of
|
||||
* bands that may be affected is indicated by the value of
|
||||
* <code>bands</code>.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
* @param theImage the <code>BufferedImage</code> being updated.
|
||||
* @param pass the number of the pass that is about to begin,
|
||||
* starting with 0.
|
||||
* @param minPass the index of the first pass that will be decoded.
|
||||
* @param maxPass the index of the last pass that will be decoded.
|
||||
* @param minX the X coordinate of the leftmost updated column
|
||||
* of pixels.
|
||||
* @param minY the Y coordinate of the uppermost updated row
|
||||
* of pixels.
|
||||
* @param periodX the horizontal spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param periodY the vertical spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param bands an array of <code>int</code>s indicating the the
|
||||
* set bands that may be updated.
|
||||
*/
|
||||
void passStarted(ImageReader source,
|
||||
BufferedImage theImage,
|
||||
int pass,
|
||||
int minPass, int maxPass,
|
||||
int minX, int minY,
|
||||
int periodX, int periodY,
|
||||
int[] bands);
|
||||
|
||||
/**
|
||||
* Reports that a given region of the image has been updated.
|
||||
* The application might choose to redisplay the specified area,
|
||||
* for example, in order to provide a progressive display effect,
|
||||
* or perform other incremental processing.
|
||||
*
|
||||
* <p> Note that different image format readers may produce
|
||||
* decoded pixels in a variety of different orders. Many readers
|
||||
* will produce pixels in a simple top-to-bottom,
|
||||
* left-to-right-order, but others may use multiple passes of
|
||||
* interlacing, tiling, etc. The sequence of updates may even
|
||||
* differ from call to call depending on network speeds, for
|
||||
* example. A call to this method does not guarantee that all the
|
||||
* specified pixels have actually been updated, only that some
|
||||
* activity has taken place within some subregion of the one
|
||||
* specified.
|
||||
*
|
||||
* <p> The particular <code>ImageReader</code> implementation may
|
||||
* choose how often to provide updates. Each update specifies
|
||||
* that a given region of the image has been updated since the
|
||||
* last update. A region is described by its spatial bounding box
|
||||
* (<code>minX</code>, <code>minY</code>, <code>width</code>, and
|
||||
* <code>height</code>); X and Y subsampling factors
|
||||
* (<code>periodX</code> and <code>periodY</code>); and a set of
|
||||
* updated bands (<code>bands</code>). For example, the update:
|
||||
*
|
||||
* <pre>
|
||||
* minX = 10
|
||||
* minY = 20
|
||||
* width = 3
|
||||
* height = 4
|
||||
* periodX = 2
|
||||
* periodY = 3
|
||||
* bands = { 1, 3 }
|
||||
* </pre>
|
||||
*
|
||||
* would indicate that bands 1 and 3 of the following pixels were
|
||||
* updated:
|
||||
*
|
||||
* <pre>
|
||||
* (10, 20) (12, 20) (14, 20)
|
||||
* (10, 23) (12, 23) (14, 23)
|
||||
* (10, 26) (12, 26) (14, 26)
|
||||
* (10, 29) (12, 29) (14, 29)
|
||||
* </pre>
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param theImage the <code>BufferedImage</code> being updated.
|
||||
* @param minX the X coordinate of the leftmost updated column
|
||||
* of pixels.
|
||||
* @param minY the Y coordinate of the uppermost updated row
|
||||
* of pixels.
|
||||
* @param width the number of updated pixels horizontally.
|
||||
* @param height the number of updated pixels vertically.
|
||||
* @param periodX the horizontal spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param periodY the vertical spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param bands an array of <code>int</code>s indicating which
|
||||
* bands are being updated.
|
||||
*/
|
||||
void imageUpdate(ImageReader source,
|
||||
BufferedImage theImage,
|
||||
int minX, int minY,
|
||||
int width, int height,
|
||||
int periodX, int periodY,
|
||||
int[] bands);
|
||||
|
||||
/**
|
||||
* Reports that the current read operation has completed a
|
||||
* progressive pass. Readers of formats that support
|
||||
* progressive encoding should use this to notify clients when
|
||||
* each pass is completed when reading a progressively
|
||||
* encoded image.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
* @param theImage the <code>BufferedImage</code> being updated.
|
||||
*
|
||||
* @see javax.imageio.ImageReadParam#setSourceProgressivePasses(int, int)
|
||||
*/
|
||||
void passComplete(ImageReader source, BufferedImage theImage);
|
||||
|
||||
/**
|
||||
* Reports that the current thumbnail read operation is about to
|
||||
* begin a progressive pass. Readers of formats that support
|
||||
* progressive encoding should use this to notify clients when
|
||||
* each pass is completed when reading a progressively encoded
|
||||
* thumbnail image.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
* @param theThumbnail the <code>BufferedImage</code> thumbnail
|
||||
* being updated.
|
||||
* @param pass the number of the pass that is about to begin,
|
||||
* starting with 0.
|
||||
* @param minPass the index of the first pass that will be decoded.
|
||||
* @param maxPass the index of the last pass that will be decoded.
|
||||
* @param minX the X coordinate of the leftmost updated column
|
||||
* of pixels.
|
||||
* @param minY the Y coordinate of the uppermost updated row
|
||||
* of pixels.
|
||||
* @param periodX the horizontal spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param periodY the vertical spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param bands an array of <code>int</code>s indicating the the
|
||||
* set bands that may be updated.
|
||||
*
|
||||
* @see #passStarted
|
||||
*/
|
||||
void thumbnailPassStarted(ImageReader source,
|
||||
BufferedImage theThumbnail,
|
||||
int pass,
|
||||
int minPass, int maxPass,
|
||||
int minX, int minY,
|
||||
int periodX, int periodY,
|
||||
int[] bands);
|
||||
|
||||
/**
|
||||
* Reports that a given region of a thumbnail image has been updated.
|
||||
* The application might choose to redisplay the specified area,
|
||||
* for example, in order to provide a progressive display effect,
|
||||
* or perform other incremental processing.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param theThumbnail the <code>BufferedImage</code> thumbnail
|
||||
* being updated.
|
||||
* @param minX the X coordinate of the leftmost updated column
|
||||
* of pixels.
|
||||
* @param minY the Y coordinate of the uppermost updated row
|
||||
* of pixels.
|
||||
* @param width the number of updated pixels horizontally.
|
||||
* @param height the number of updated pixels vertically.
|
||||
* @param periodX the horizontal spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param periodY the vertical spacing between updated pixels;
|
||||
* a value of 1 means no gaps.
|
||||
* @param bands an array of <code>int</code>s indicating which
|
||||
* bands are being updated.
|
||||
*
|
||||
* @see #imageUpdate
|
||||
*/
|
||||
void thumbnailUpdate(ImageReader source,
|
||||
BufferedImage theThumbnail,
|
||||
int minX, int minY,
|
||||
int width, int height,
|
||||
int periodX, int periodY,
|
||||
int[] bands);
|
||||
|
||||
/**
|
||||
* Reports that the current thumbnail read operation has completed
|
||||
* a progressive pass. Readers of formats that support
|
||||
* progressive encoding should use this to notify clients when
|
||||
* each pass is completed when reading a progressively encoded
|
||||
* thumbnail image.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this
|
||||
* method.
|
||||
* @param theThumbnail the <code>BufferedImage</code> thumbnail
|
||||
* being updated.
|
||||
*
|
||||
* @see #passComplete
|
||||
*/
|
||||
void thumbnailPassComplete(ImageReader source, BufferedImage theThumbnail);
|
||||
}
|
||||
58
jdkSrc/jdk8/javax/imageio/event/IIOReadWarningListener.java
Normal file
58
jdkSrc/jdk8/javax/imageio/event/IIOReadWarningListener.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
import javax.imageio.ImageReader;
|
||||
|
||||
/**
|
||||
* An interface used by <code>ImageReader</code> implementations to
|
||||
* notify callers of their image and thumbnail reading methods of
|
||||
* warnings (non-fatal errors). Fatal errors cause the relevant
|
||||
* read method to throw an <code>IIOException</code>.
|
||||
*
|
||||
* <p> Localization is handled by associating a <code>Locale</code>
|
||||
* with each <code>IIOReadWarningListener</code> as it is registered
|
||||
* with an <code>ImageReader</code>. It is up to the
|
||||
* <code>ImageReader</code> to provide localized messages.
|
||||
*
|
||||
* @see javax.imageio.ImageReader#addIIOReadWarningListener
|
||||
* @see javax.imageio.ImageReader#removeIIOReadWarningListener
|
||||
*
|
||||
*/
|
||||
public interface IIOReadWarningListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports the occurrence of a non-fatal error in decoding. Decoding
|
||||
* will continue following the call to this method. The application
|
||||
* may choose to display a dialog, print the warning to the console,
|
||||
* ignore the warning, or take any other action it chooses.
|
||||
*
|
||||
* @param source the <code>ImageReader</code> object calling this method.
|
||||
* @param warning a <code>String</code> containing the warning.
|
||||
*/
|
||||
void warningOccurred(ImageReader source, String warning);
|
||||
}
|
||||
140
jdkSrc/jdk8/javax/imageio/event/IIOWriteProgressListener.java
Normal file
140
jdkSrc/jdk8/javax/imageio/event/IIOWriteProgressListener.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
import javax.imageio.ImageWriter;
|
||||
|
||||
/**
|
||||
* An interface used by <code>ImageWriter</code> implementations to notify
|
||||
* callers of their image writing methods of progress.
|
||||
*
|
||||
* @see javax.imageio.ImageWriter#write
|
||||
*
|
||||
*/
|
||||
public interface IIOWriteProgressListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports that an image write operation is beginning. All
|
||||
* <code>ImageWriter</code> implementations are required to call
|
||||
* this method exactly once when beginning an image write
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this
|
||||
* method.
|
||||
* @param imageIndex the index of the image being written within
|
||||
* its containing input file or stream.
|
||||
*/
|
||||
void imageStarted(ImageWriter source, int imageIndex);
|
||||
|
||||
/**
|
||||
* Reports the approximate degree of completion of the current
|
||||
* <code>write</code> call within the associated
|
||||
* <code>ImageWriter</code>.
|
||||
*
|
||||
* <p> The degree of completion is expressed as an index
|
||||
* indicating which image is being written, and a percentage
|
||||
* varying from <code>0.0F</code> to <code>100.0F</code>
|
||||
* indicating how much of the current image has been output. The
|
||||
* percentage should ideally be calculated in terms of the
|
||||
* remaining time to completion, but it is usually more practical
|
||||
* to use a more well-defined metric such as pixels decoded or
|
||||
* portion of input stream consumed. In any case, a sequence of
|
||||
* calls to this method during a given read operation should
|
||||
* supply a monotonically increasing sequence of percentage
|
||||
* values. It is not necessary to supply the exact values
|
||||
* <code>0</code> and <code>100</code>, as these may be inferred
|
||||
* by the callee from other methods.
|
||||
*
|
||||
* <p> Each particular <code>ImageWriter</code> implementation may
|
||||
* call this method at whatever frequency it desires. A rule of
|
||||
* thumb is to call it around each 5 percent mark.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this method.
|
||||
* @param percentageDone the approximate percentage of decoding that
|
||||
* has been completed.
|
||||
*/
|
||||
void imageProgress(ImageWriter source,
|
||||
float percentageDone);
|
||||
|
||||
/**
|
||||
* Reports that the image write operation has completed. All
|
||||
* <code>ImageWriter</code> implementations are required to call
|
||||
* this method exactly once upon completion of each image write
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this method.
|
||||
*/
|
||||
void imageComplete(ImageWriter source);
|
||||
|
||||
/**
|
||||
* Reports that a thumbnail write operation is beginning. All
|
||||
* <code>ImageWriter</code> implementations are required to call
|
||||
* this method exactly once when beginning a thumbnail write
|
||||
* operation.
|
||||
*
|
||||
* @param source the <code>ImageWrite</code> object calling this method.
|
||||
* @param imageIndex the index of the image being written within its
|
||||
* containing input file or stream.
|
||||
* @param thumbnailIndex the index of the thumbnail being written.
|
||||
*/
|
||||
void thumbnailStarted(ImageWriter source,
|
||||
int imageIndex, int thumbnailIndex);
|
||||
|
||||
/**
|
||||
* Reports the approximate degree of completion of the current
|
||||
* thumbnail write within the associated <code>ImageWriter</code>.
|
||||
* The semantics are identical to those of
|
||||
* <code>imageProgress</code>.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this
|
||||
* method.
|
||||
* @param percentageDone the approximate percentage of decoding that
|
||||
* has been completed.
|
||||
*/
|
||||
void thumbnailProgress(ImageWriter source, float percentageDone);
|
||||
|
||||
/**
|
||||
* Reports that a thumbnail write operation has completed. All
|
||||
* <code>ImageWriter</code> implementations are required to call
|
||||
* this method exactly once upon completion of each thumbnail
|
||||
* write operation.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this
|
||||
* method.
|
||||
*/
|
||||
void thumbnailComplete(ImageWriter source);
|
||||
|
||||
/**
|
||||
* Reports that a write has been aborted via the writer's
|
||||
* <code>abort</code> method. No further notifications will be
|
||||
* given.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this
|
||||
* method.
|
||||
*/
|
||||
void writeAborted(ImageWriter source);
|
||||
}
|
||||
62
jdkSrc/jdk8/javax/imageio/event/IIOWriteWarningListener.java
Normal file
62
jdkSrc/jdk8/javax/imageio/event/IIOWriteWarningListener.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.event;
|
||||
|
||||
import java.util.EventListener;
|
||||
import javax.imageio.ImageWriter;
|
||||
|
||||
/**
|
||||
* An interface used by <code>ImageWriter</code> implementations to
|
||||
* notify callers of their image and thumbnail reading methods of
|
||||
* warnings (non-fatal errors). Fatal errors cause the relevant
|
||||
* read method to throw an <code>IIOException</code>.
|
||||
*
|
||||
* <p> Localization is handled by associating a <code>Locale</code>
|
||||
* with each <code>IIOWriteWarningListener</code> as it is registered
|
||||
* with an <code>ImageWriter</code>. It is up to the
|
||||
* <code>ImageWriter</code> to provide localized messages.
|
||||
*
|
||||
* @see javax.imageio.ImageWriter#addIIOWriteWarningListener
|
||||
* @see javax.imageio.ImageWriter#removeIIOWriteWarningListener
|
||||
*
|
||||
*/
|
||||
public interface IIOWriteWarningListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports the occurrence of a non-fatal error in encoding. Encoding
|
||||
* will continue following the call to this method. The application
|
||||
* may choose to display a dialog, print the warning to the console,
|
||||
* ignore the warning, or take any other action it chooses.
|
||||
*
|
||||
* @param source the <code>ImageWriter</code> object calling this method.
|
||||
* @param imageIndex the index, starting with 0, of the image
|
||||
* generating the warning.
|
||||
* @param warning a <code>String</code> containing the warning.
|
||||
*/
|
||||
void warningOccurred(ImageWriter source,
|
||||
int imageIndex,
|
||||
String warning);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.metadata;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* An <code>IIOInvalidTreeException</code> is thrown when an attempt
|
||||
* by an <code>IIOMetadata</code> object to parse a tree of
|
||||
* <code>IIOMetadataNode</code>s fails. The node that led to the
|
||||
* parsing error may be stored. As with any parsing error, the actual
|
||||
* error may occur at a different point that that where it is
|
||||
* detected. The node returned by <code>getOffendingNode</code>
|
||||
* should merely be considered as a clue to the actual nature of the
|
||||
* problem.
|
||||
*
|
||||
* @see IIOMetadata#setFromTree
|
||||
* @see IIOMetadata#mergeTree
|
||||
* @see IIOMetadataNode
|
||||
*
|
||||
*/
|
||||
public class IIOInvalidTreeException extends IIOException {
|
||||
|
||||
/**
|
||||
* The <code>Node</code> that led to the parsing error, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
protected Node offendingNode = null;
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOInvalidTreeException</code> with a
|
||||
* message string and a reference to the <code>Node</code> that
|
||||
* caused the parsing error.
|
||||
*
|
||||
* @param message a <code>String</code> containing the reason for
|
||||
* the parsing failure.
|
||||
* @param offendingNode the DOM <code>Node</code> that caused the
|
||||
* exception, or <code>null</code>.
|
||||
*/
|
||||
public IIOInvalidTreeException(String message, Node offendingNode) {
|
||||
super(message);
|
||||
this.offendingNode = offendingNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOInvalidTreeException</code> with a
|
||||
* message string, a reference to an exception that caused this
|
||||
* exception, and a reference to the <code>Node</code> that caused
|
||||
* the parsing error.
|
||||
*
|
||||
* @param message a <code>String</code> containing the reason for
|
||||
* the parsing failure.
|
||||
* @param cause the <code>Throwable</code> (<code>Error</code> or
|
||||
* <code>Exception</code>) that caused this exception to occur,
|
||||
* or <code>null</code>.
|
||||
* @param offendingNode the DOM <code>Node</code> that caused the
|
||||
* exception, or <code>null</code>.
|
||||
*/
|
||||
public IIOInvalidTreeException(String message, Throwable cause,
|
||||
Node offendingNode) {
|
||||
super(message, cause);
|
||||
this.offendingNode = offendingNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>Node</code> that caused the error in parsing.
|
||||
*
|
||||
* @return the offending <code>Node</code>.
|
||||
*/
|
||||
public Node getOffendingNode() {
|
||||
return offendingNode;
|
||||
}
|
||||
}
|
||||
900
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadata.java
Normal file
900
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadata.java
Normal file
@@ -0,0 +1,900 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.metadata;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* An abstract class to be extended by objects that represent metadata
|
||||
* (non-image data) associated with images and streams. Plug-ins
|
||||
* represent metadata using opaque, plug-in specific objects. These
|
||||
* objects, however, provide the ability to access their internal
|
||||
* information as a tree of <code>IIOMetadataNode</code> objects that
|
||||
* support the XML DOM interfaces as well as additional interfaces for
|
||||
* storing non-textual data and retrieving information about legal
|
||||
* data values. The format of such trees is plug-in dependent, but
|
||||
* plug-ins may choose to support a plug-in neutral format described
|
||||
* below. A single plug-in may support multiple metadata formats,
|
||||
* whose names maybe determined by calling
|
||||
* <code>getMetadataFormatNames</code>. The plug-in may also support
|
||||
* a single special format, referred to as the "native" format, which
|
||||
* is designed to encode its metadata losslessly. This format will
|
||||
* typically be designed specifically to work with a specific file
|
||||
* format, so that images may be loaded and saved in the same format
|
||||
* with no loss of metadata, but may be less useful for transferring
|
||||
* metadata between an <code>ImageReader</code> and an
|
||||
* <code>ImageWriter</code> for different image formats. To convert
|
||||
* between two native formats as losslessly as the image file formats
|
||||
* will allow, an <code>ImageTranscoder</code> object must be used.
|
||||
*
|
||||
* @see javax.imageio.ImageReader#getImageMetadata
|
||||
* @see javax.imageio.ImageReader#getStreamMetadata
|
||||
* @see javax.imageio.ImageReader#readAll
|
||||
* @see javax.imageio.ImageWriter#getDefaultStreamMetadata
|
||||
* @see javax.imageio.ImageWriter#getDefaultImageMetadata
|
||||
* @see javax.imageio.ImageWriter#write
|
||||
* @see javax.imageio.ImageWriter#convertImageMetadata
|
||||
* @see javax.imageio.ImageWriter#convertStreamMetadata
|
||||
* @see javax.imageio.IIOImage
|
||||
* @see javax.imageio.ImageTranscoder
|
||||
*
|
||||
*/
|
||||
public abstract class IIOMetadata {
|
||||
|
||||
/**
|
||||
* A boolean indicating whether the concrete subclass supports the
|
||||
* standard metadata format, set via the constructor.
|
||||
*/
|
||||
protected boolean standardFormatSupported;
|
||||
|
||||
/**
|
||||
* The name of the native metadata format for this object,
|
||||
* initialized to <code>null</code> and set via the constructor.
|
||||
*/
|
||||
protected String nativeMetadataFormatName = null;
|
||||
|
||||
/**
|
||||
* The name of the class implementing <code>IIOMetadataFormat</code>
|
||||
* and representing the native metadata format, initialized to
|
||||
* <code>null</code> and set via the constructor.
|
||||
*/
|
||||
protected String nativeMetadataFormatClassName = null;
|
||||
|
||||
/**
|
||||
* An array of names of formats, other than the standard and
|
||||
* native formats, that are supported by this plug-in,
|
||||
* initialized to <code>null</code> and set via the constructor.
|
||||
*/
|
||||
protected String[] extraMetadataFormatNames = null;
|
||||
|
||||
/**
|
||||
* An array of names of classes implementing <code>IIOMetadataFormat</code>
|
||||
* and representing the metadata formats, other than the standard and
|
||||
* native formats, that are supported by this plug-in,
|
||||
* initialized to <code>null</code> and set via the constructor.
|
||||
*/
|
||||
protected String[] extraMetadataFormatClassNames = null;
|
||||
|
||||
/**
|
||||
* An <code>IIOMetadataController</code> that is suggested for use
|
||||
* as the controller for this <code>IIOMetadata</code> object. It
|
||||
* may be retrieved via <code>getDefaultController</code>. To
|
||||
* install the default controller, call
|
||||
* <code>setController(getDefaultController())</code>. This
|
||||
* instance variable should be set by subclasses that choose to
|
||||
* provide their own default controller, usually a GUI, for
|
||||
* setting parameters.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #getDefaultController
|
||||
*/
|
||||
protected IIOMetadataController defaultController = null;
|
||||
|
||||
/**
|
||||
* The <code>IIOMetadataController</code> that will be
|
||||
* used to provide settings for this <code>IIOMetadata</code>
|
||||
* object when the <code>activateController</code> method
|
||||
* is called. This value overrides any default controller,
|
||||
* even when <code>null</code>.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #setController(IIOMetadataController)
|
||||
* @see #hasController()
|
||||
* @see #activateController()
|
||||
*/
|
||||
protected IIOMetadataController controller = null;
|
||||
|
||||
/**
|
||||
* Constructs an empty <code>IIOMetadata</code> object. The
|
||||
* subclass is responsible for supplying values for all protected
|
||||
* instance variables that will allow any non-overridden default
|
||||
* implementations of methods to satisfy their contracts. For example,
|
||||
* <code>extraMetadataFormatNames</code> should not have length 0.
|
||||
*/
|
||||
protected IIOMetadata() {}
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOMetadata</code> object with the given
|
||||
* format names and format class names, as well as a boolean
|
||||
* indicating whether the standard format is supported.
|
||||
*
|
||||
* <p> This constructor does not attempt to check the class names
|
||||
* for validity. Invalid class names may cause exceptions in
|
||||
* subsequent calls to <code>getMetadataFormat</code>.
|
||||
*
|
||||
* @param standardMetadataFormatSupported <code>true</code> if
|
||||
* this object can return or accept a DOM tree using the standard
|
||||
* metadata format.
|
||||
* @param nativeMetadataFormatName the name of the native metadata
|
||||
* format, as a <code>String</code>, or <code>null</code> if there
|
||||
* is no native format.
|
||||
* @param nativeMetadataFormatClassName the name of the class of
|
||||
* the native metadata format, or <code>null</code> if there is
|
||||
* no native format.
|
||||
* @param extraMetadataFormatNames an array of <code>String</code>s
|
||||
* indicating additional formats supported by this object, or
|
||||
* <code>null</code> if there are none.
|
||||
* @param extraMetadataFormatClassNames an array of <code>String</code>s
|
||||
* indicating the class names of any additional formats supported by
|
||||
* this object, or <code>null</code> if there are none.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>extraMetadataFormatNames</code> has length 0.
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>extraMetadataFormatNames</code> and
|
||||
* <code>extraMetadataFormatClassNames</code> are neither both
|
||||
* <code>null</code>, nor of the same length.
|
||||
*/
|
||||
protected IIOMetadata(boolean standardMetadataFormatSupported,
|
||||
String nativeMetadataFormatName,
|
||||
String nativeMetadataFormatClassName,
|
||||
String[] extraMetadataFormatNames,
|
||||
String[] extraMetadataFormatClassNames) {
|
||||
this.standardFormatSupported = standardMetadataFormatSupported;
|
||||
this.nativeMetadataFormatName = nativeMetadataFormatName;
|
||||
this.nativeMetadataFormatClassName = nativeMetadataFormatClassName;
|
||||
if (extraMetadataFormatNames != null) {
|
||||
if (extraMetadataFormatNames.length == 0) {
|
||||
throw new IllegalArgumentException
|
||||
("extraMetadataFormatNames.length == 0!");
|
||||
}
|
||||
if (extraMetadataFormatClassNames == null) {
|
||||
throw new IllegalArgumentException
|
||||
("extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!");
|
||||
}
|
||||
if (extraMetadataFormatClassNames.length !=
|
||||
extraMetadataFormatNames.length) {
|
||||
throw new IllegalArgumentException
|
||||
("extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!");
|
||||
}
|
||||
this.extraMetadataFormatNames =
|
||||
(String[]) extraMetadataFormatNames.clone();
|
||||
this.extraMetadataFormatClassNames =
|
||||
(String[]) extraMetadataFormatClassNames.clone();
|
||||
} else {
|
||||
if (extraMetadataFormatClassNames != null) {
|
||||
throw new IllegalArgumentException
|
||||
("extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the standard metadata format is
|
||||
* supported by <code>getMetadataFormat</code>,
|
||||
* <code>getAsTree</code>, <code>setFromTree</code>, and
|
||||
* <code>mergeTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>standardFormatSupported</code> instance variable.
|
||||
*
|
||||
* @return <code>true</code> if the standard metadata format
|
||||
* is supported.
|
||||
*
|
||||
* @see #getAsTree
|
||||
* @see #setFromTree
|
||||
* @see #mergeTree
|
||||
* @see #getMetadataFormat
|
||||
*/
|
||||
public boolean isStandardMetadataFormatSupported() {
|
||||
return standardFormatSupported;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this object does not support the
|
||||
* <code>mergeTree</code>, <code>setFromTree</code>, and
|
||||
* <code>reset</code> methods.
|
||||
*
|
||||
* @return true if this <code>IIOMetadata</code> object cannot be
|
||||
* modified.
|
||||
*/
|
||||
public abstract boolean isReadOnly();
|
||||
|
||||
/**
|
||||
* Returns the name of the "native" metadata format for this
|
||||
* plug-in, which typically allows for lossless encoding and
|
||||
* transmission of the metadata stored in the format handled by
|
||||
* this plug-in. If no such format is supported,
|
||||
* <code>null</code>will be returned.
|
||||
*
|
||||
* <p> The structure and contents of the "native" metadata format
|
||||
* are defined by the plug-in that created this
|
||||
* <code>IIOMetadata</code> object. Plug-ins for simple formats
|
||||
* will usually create a dummy node for the root, and then a
|
||||
* series of child nodes representing individual tags, chunks, or
|
||||
* keyword/value pairs. A plug-in may choose whether or not to
|
||||
* document its native format.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>nativeMetadataFormatName</code> instance variable.
|
||||
*
|
||||
* @return the name of the native format, or <code>null</code>.
|
||||
*
|
||||
* @see #getExtraMetadataFormatNames
|
||||
* @see #getMetadataFormatNames
|
||||
*/
|
||||
public String getNativeMetadataFormatName() {
|
||||
return nativeMetadataFormatName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the names
|
||||
* of additional metadata formats, other than the native and standard
|
||||
* formats, recognized by this plug-in's
|
||||
* <code>getAsTree</code>, <code>setFromTree</code>, and
|
||||
* <code>mergeTree</code> methods. If there are no such additional
|
||||
* formats, <code>null</code> is returned.
|
||||
*
|
||||
* <p> The default implementation returns a clone of the
|
||||
* <code>extraMetadataFormatNames</code> instance variable.
|
||||
*
|
||||
* @return an array of <code>String</code>s with length at least
|
||||
* 1, or <code>null</code>.
|
||||
*
|
||||
* @see #getAsTree
|
||||
* @see #setFromTree
|
||||
* @see #mergeTree
|
||||
* @see #getNativeMetadataFormatName
|
||||
* @see #getMetadataFormatNames
|
||||
*/
|
||||
public String[] getExtraMetadataFormatNames() {
|
||||
if (extraMetadataFormatNames == null) {
|
||||
return null;
|
||||
}
|
||||
return (String[])extraMetadataFormatNames.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the names
|
||||
* of all metadata formats, including the native and standard
|
||||
* formats, recognized by this plug-in's <code>getAsTree</code>,
|
||||
* <code>setFromTree</code>, and <code>mergeTree</code> methods.
|
||||
* If there are no such formats, <code>null</code> is returned.
|
||||
*
|
||||
* <p> The default implementation calls
|
||||
* <code>getNativeMetadataFormatName</code>,
|
||||
* <code>isStandardMetadataFormatSupported</code>, and
|
||||
* <code>getExtraMetadataFormatNames</code> and returns the
|
||||
* combined results.
|
||||
*
|
||||
* @return an array of <code>String</code>s.
|
||||
*
|
||||
* @see #getNativeMetadataFormatName
|
||||
* @see #isStandardMetadataFormatSupported
|
||||
* @see #getExtraMetadataFormatNames
|
||||
*/
|
||||
public String[] getMetadataFormatNames() {
|
||||
String nativeName = getNativeMetadataFormatName();
|
||||
String standardName = isStandardMetadataFormatSupported() ?
|
||||
IIOMetadataFormatImpl.standardMetadataFormatName : null;
|
||||
String[] extraNames = getExtraMetadataFormatNames();
|
||||
|
||||
int numFormats = 0;
|
||||
if (nativeName != null) {
|
||||
++numFormats;
|
||||
}
|
||||
if (standardName != null) {
|
||||
++numFormats;
|
||||
}
|
||||
if (extraNames != null) {
|
||||
numFormats += extraNames.length;
|
||||
}
|
||||
if (numFormats == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] formats = new String[numFormats];
|
||||
int index = 0;
|
||||
if (nativeName != null) {
|
||||
formats[index++] = nativeName;
|
||||
}
|
||||
if (standardName != null) {
|
||||
formats[index++] = standardName;
|
||||
}
|
||||
if (extraNames != null) {
|
||||
for (int i = 0; i < extraNames.length; i++) {
|
||||
formats[index++] = extraNames[i];
|
||||
}
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataFormat</code> object describing the
|
||||
* given metadata format, or <code>null</code> if no description
|
||||
* is available. The supplied name must be one of those returned
|
||||
* by <code>getMetadataFormatNames</code> (<i>i.e.</i>, either the
|
||||
* native format name, the standard format name, or one of those
|
||||
* returned by <code>getExtraMetadataFormatNames</code>).
|
||||
*
|
||||
* <p> The default implementation checks the name against the
|
||||
* global standard metadata format name, and returns that format
|
||||
* if it is supported. Otherwise, it checks against the native
|
||||
* format names followed by any additional format names. If a
|
||||
* match is found, it retrieves the name of the
|
||||
* <code>IIOMetadataFormat</code> class from
|
||||
* <code>nativeMetadataFormatClassName</code> or
|
||||
* <code>extraMetadataFormatClassNames</code> as appropriate, and
|
||||
* constructs an instance of that class using its
|
||||
* <code>getInstance</code> method.
|
||||
*
|
||||
* @param formatName the desired metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataFormat</code> object.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> or is not one of the names recognized by
|
||||
* the plug-in.
|
||||
* @exception IllegalStateException if the class corresponding to
|
||||
* the format name cannot be loaded.
|
||||
*/
|
||||
public IIOMetadataFormat getMetadataFormat(String formatName) {
|
||||
if (formatName == null) {
|
||||
throw new IllegalArgumentException("formatName == null!");
|
||||
}
|
||||
if (standardFormatSupported
|
||||
&& formatName.equals
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName)) {
|
||||
return IIOMetadataFormatImpl.getStandardFormatInstance();
|
||||
}
|
||||
String formatClassName = null;
|
||||
if (formatName.equals(nativeMetadataFormatName)) {
|
||||
formatClassName = nativeMetadataFormatClassName;
|
||||
} else if (extraMetadataFormatNames != null) {
|
||||
for (int i = 0; i < extraMetadataFormatNames.length; i++) {
|
||||
if (formatName.equals(extraMetadataFormatNames[i])) {
|
||||
formatClassName = extraMetadataFormatClassNames[i];
|
||||
break; // out of for
|
||||
}
|
||||
}
|
||||
}
|
||||
if (formatClassName == null) {
|
||||
throw new IllegalArgumentException("Unsupported format name");
|
||||
}
|
||||
try {
|
||||
Class cls = null;
|
||||
final Object o = this;
|
||||
|
||||
// firstly we try to use classloader used for loading
|
||||
// the IIOMetadata implemantation for this plugin.
|
||||
ClassLoader loader = (ClassLoader)
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
return o.getClass().getClassLoader();
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
cls = Class.forName(formatClassName, true,
|
||||
loader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// we failed to load IIOMetadataFormat class by
|
||||
// using IIOMetadata classloader.Next try is to
|
||||
// use thread context classloader.
|
||||
loader = (ClassLoader)
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction() {
|
||||
public Object run() {
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
});
|
||||
try {
|
||||
cls = Class.forName(formatClassName, true,
|
||||
loader);
|
||||
} catch (ClassNotFoundException e1) {
|
||||
// finally we try to use system classloader in case
|
||||
// if we failed to load IIOMetadataFormat implementation
|
||||
// class above.
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an XML DOM <code>Node</code> object that represents the
|
||||
* root of a tree of metadata contained within this object
|
||||
* according to the conventions defined by a given metadata
|
||||
* format.
|
||||
*
|
||||
* <p> The names of the available metadata formats may be queried
|
||||
* using the <code>getMetadataFormatNames</code> method.
|
||||
*
|
||||
* @param formatName the desired metadata format.
|
||||
*
|
||||
* @return an XML DOM <code>Node</code> object forming the
|
||||
* root of a tree.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> or is not one of the names returned by
|
||||
* <code>getMetadataFormatNames</code>.
|
||||
*
|
||||
* @see #getMetadataFormatNames
|
||||
* @see #setFromTree
|
||||
* @see #mergeTree
|
||||
*/
|
||||
public abstract Node getAsTree(String formatName);
|
||||
|
||||
/**
|
||||
* Alters the internal state of this <code>IIOMetadata</code>
|
||||
* object from a tree of XML DOM <code>Node</code>s whose syntax
|
||||
* is defined by the given metadata format. The previous state is
|
||||
* altered only as necessary to accommodate the nodes that are
|
||||
* present in the given tree. If the tree structure or contents
|
||||
* are invalid, an <code>IIOInvalidTreeException</code> will be
|
||||
* thrown.
|
||||
*
|
||||
* <p> As the semantics of how a tree or subtree may be merged with
|
||||
* another tree are completely format-specific, plug-in authors may
|
||||
* implement this method in whatever manner is most appropriate for
|
||||
* the format, including simply replacing all existing state with the
|
||||
* contents of the given tree.
|
||||
*
|
||||
* @param formatName the desired metadata format.
|
||||
* @param root an XML DOM <code>Node</code> object forming the
|
||||
* root of a tree.
|
||||
*
|
||||
* @exception IllegalStateException if this object is read-only.
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> or is not one of the names returned by
|
||||
* <code>getMetadataFormatNames</code>.
|
||||
* @exception IllegalArgumentException if <code>root</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IIOInvalidTreeException if the tree cannot be parsed
|
||||
* successfully using the rules of the given format.
|
||||
*
|
||||
* @see #getMetadataFormatNames
|
||||
* @see #getAsTree
|
||||
* @see #setFromTree
|
||||
*/
|
||||
public abstract void mergeTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException;
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the chroma
|
||||
* information of the standard <code>javax_imageio_1.0</code>
|
||||
* metadata format, or <code>null</code> if no such information is
|
||||
* available. This method is intended to be called by the utility
|
||||
* routine <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the
|
||||
* compression information of the standard
|
||||
* <code>javax_imageio_1.0</code> metadata format, or
|
||||
* <code>null</code> if no such information is available. This
|
||||
* method is intended to be called by the utility routine
|
||||
* <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardCompressionNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the data
|
||||
* format information of the standard
|
||||
* <code>javax_imageio_1.0</code> metadata format, or
|
||||
* <code>null</code> if no such information is available. This
|
||||
* method is intended to be called by the utility routine
|
||||
* <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardDataNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the
|
||||
* dimension information of the standard
|
||||
* <code>javax_imageio_1.0</code> metadata format, or
|
||||
* <code>null</code> if no such information is available. This
|
||||
* method is intended to be called by the utility routine
|
||||
* <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardDimensionNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the document
|
||||
* information of the standard <code>javax_imageio_1.0</code>
|
||||
* metadata format, or <code>null</code> if no such information is
|
||||
* available. This method is intended to be called by the utility
|
||||
* routine <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardDocumentNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the textual
|
||||
* information of the standard <code>javax_imageio_1.0</code>
|
||||
* metadata format, or <code>null</code> if no such information is
|
||||
* available. This method is intended to be called by the utility
|
||||
* routine <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardTextNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the tiling
|
||||
* information of the standard <code>javax_imageio_1.0</code>
|
||||
* metadata format, or <code>null</code> if no such information is
|
||||
* available. This method is intended to be called by the utility
|
||||
* routine <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*
|
||||
* @see #getStandardTree
|
||||
*/
|
||||
protected IIOMetadataNode getStandardTileNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataNode</code> representing the
|
||||
* transparency information of the standard
|
||||
* <code>javax_imageio_1.0</code> metadata format, or
|
||||
* <code>null</code> if no such information is available. This
|
||||
* method is intended to be called by the utility routine
|
||||
* <code>getStandardTree</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>null</code>.
|
||||
*
|
||||
* <p> Subclasses should override this method to produce an
|
||||
* appropriate subtree if they wish to support the standard
|
||||
* metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code>, or <code>null</code>.
|
||||
*/
|
||||
protected IIOMetadataNode getStandardTransparencyNode() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a new node to an existing node, if the new node is
|
||||
* non-<code>null</code>.
|
||||
*/
|
||||
private void append(IIOMetadataNode root, IIOMetadataNode node) {
|
||||
if (node != null) {
|
||||
root.appendChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility method to return a tree of
|
||||
* <code>IIOMetadataNode</code>s representing the metadata
|
||||
* contained within this object according to the conventions of
|
||||
* the standard <code>javax_imageio_1.0</code> metadata format.
|
||||
*
|
||||
* <p> This method calls the various <code>getStandard*Node</code>
|
||||
* methods to supply each of the subtrees rooted at the children
|
||||
* of the root node. If any of those methods returns
|
||||
* <code>null</code>, the corresponding subtree will be omitted.
|
||||
* If all of them return <code>null</code>, a tree consisting of a
|
||||
* single root node will be returned.
|
||||
*
|
||||
* @return an <code>IIOMetadataNode</code> representing the root
|
||||
* of a metadata tree in the <code>javax_imageio_1.0</code>
|
||||
* format.
|
||||
*
|
||||
* @see #getStandardChromaNode
|
||||
* @see #getStandardCompressionNode
|
||||
* @see #getStandardDataNode
|
||||
* @see #getStandardDimensionNode
|
||||
* @see #getStandardDocumentNode
|
||||
* @see #getStandardTextNode
|
||||
* @see #getStandardTileNode
|
||||
* @see #getStandardTransparencyNode
|
||||
*/
|
||||
protected final IIOMetadataNode getStandardTree() {
|
||||
IIOMetadataNode root = new IIOMetadataNode
|
||||
(IIOMetadataFormatImpl.standardMetadataFormatName);
|
||||
append(root, getStandardChromaNode());
|
||||
append(root, getStandardCompressionNode());
|
||||
append(root, getStandardDataNode());
|
||||
append(root, getStandardDimensionNode());
|
||||
append(root, getStandardDocumentNode());
|
||||
append(root, getStandardTextNode());
|
||||
append(root, getStandardTileNode());
|
||||
append(root, getStandardTransparencyNode());
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the internal state of this <code>IIOMetadata</code> object
|
||||
* from a tree of XML DOM <code>Node</code>s whose syntax is
|
||||
* defined by the given metadata format. The previous state is
|
||||
* discarded. If the tree's structure or contents are invalid, an
|
||||
* <code>IIOInvalidTreeException</code> will be thrown.
|
||||
*
|
||||
* <p> The default implementation calls <code>reset</code>
|
||||
* followed by <code>mergeTree(formatName, root)</code>.
|
||||
*
|
||||
* @param formatName the desired metadata format.
|
||||
* @param root an XML DOM <code>Node</code> object forming the
|
||||
* root of a tree.
|
||||
*
|
||||
* @exception IllegalStateException if this object is read-only.
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> or is not one of the names returned by
|
||||
* <code>getMetadataFormatNames</code>.
|
||||
* @exception IllegalArgumentException if <code>root</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IIOInvalidTreeException if the tree cannot be parsed
|
||||
* successfully using the rules of the given format.
|
||||
*
|
||||
* @see #getMetadataFormatNames
|
||||
* @see #getAsTree
|
||||
* @see #mergeTree
|
||||
*/
|
||||
public void setFromTree(String formatName, Node root)
|
||||
throws IIOInvalidTreeException {
|
||||
reset();
|
||||
mergeTree(formatName, root);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets all the data stored in this object to default values,
|
||||
* usually to the state this object was in immediately after
|
||||
* construction, though the precise semantics are plug-in specific.
|
||||
* Note that there are many possible default values, depending on
|
||||
* how the object was created.
|
||||
*
|
||||
* @exception IllegalStateException if this object is read-only.
|
||||
*
|
||||
* @see javax.imageio.ImageReader#getStreamMetadata
|
||||
* @see javax.imageio.ImageReader#getImageMetadata
|
||||
* @see javax.imageio.ImageWriter#getDefaultStreamMetadata
|
||||
* @see javax.imageio.ImageWriter#getDefaultImageMetadata
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
/**
|
||||
* Sets the <code>IIOMetadataController</code> to be used
|
||||
* to provide settings for this <code>IIOMetadata</code>
|
||||
* object when the <code>activateController</code> method
|
||||
* is called, overriding any default controller. If the
|
||||
* argument is <code>null</code>, no controller will be
|
||||
* used, including any default. To restore the default, use
|
||||
* <code>setController(getDefaultController())</code>.
|
||||
*
|
||||
* <p> The default implementation sets the <code>controller</code>
|
||||
* instance variable to the supplied value.
|
||||
*
|
||||
* @param controller An appropriate
|
||||
* <code>IIOMetadataController</code>, or <code>null</code>.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public void setController(IIOMetadataController controller) {
|
||||
this.controller = controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whatever <code>IIOMetadataController</code> is currently
|
||||
* installed. This could be the default if there is one,
|
||||
* <code>null</code>, or the argument of the most recent call
|
||||
* to <code>setController</code>.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>controller</code> instance variable.
|
||||
*
|
||||
* @return the currently installed
|
||||
* <code>IIOMetadataController</code>, or <code>null</code>.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #setController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public IIOMetadataController getController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default <code>IIOMetadataController</code>, if there
|
||||
* is one, regardless of the currently installed controller. If
|
||||
* there is no default controller, returns <code>null</code>.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>defaultController</code> instance variable.
|
||||
*
|
||||
* @return the default <code>IIOMetadataController</code>, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #setController(IIOMetadataController)
|
||||
* @see #getController
|
||||
* @see #hasController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public IIOMetadataController getDefaultController() {
|
||||
return defaultController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if there is a controller installed
|
||||
* for this <code>IIOMetadata</code> object.
|
||||
*
|
||||
* <p> The default implementation returns <code>true</code> if the
|
||||
* <code>getController</code> method returns a
|
||||
* non-<code>null</code> value.
|
||||
*
|
||||
* @return <code>true</code> if a controller is installed.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #setController(IIOMetadataController)
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #activateController()
|
||||
*/
|
||||
public boolean hasController() {
|
||||
return (getController() != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates the installed <code>IIOMetadataController</code> for
|
||||
* this <code>IIOMetadata</code> object and returns the resulting
|
||||
* value. When this method returns <code>true</code>, all values for this
|
||||
* <code>IIOMetadata</code> object will be ready for the next write
|
||||
* operation. If <code>false</code> is
|
||||
* returned, no settings in this object will have been disturbed
|
||||
* (<i>i.e.</i>, the user canceled the operation).
|
||||
*
|
||||
* <p> Ordinarily, the controller will be a GUI providing a user
|
||||
* interface for a subclass of <code>IIOMetadata</code> for a
|
||||
* particular plug-in. Controllers need not be GUIs, however.
|
||||
*
|
||||
* <p> The default implementation calls <code>getController</code>
|
||||
* and the calls <code>activate</code> on the returned object if
|
||||
* <code>hasController</code> returns <code>true</code>.
|
||||
*
|
||||
* @return <code>true</code> if the controller completed normally.
|
||||
*
|
||||
* @exception IllegalStateException if there is no controller
|
||||
* currently installed.
|
||||
*
|
||||
* @see IIOMetadataController
|
||||
* @see #setController(IIOMetadataController)
|
||||
* @see #getController
|
||||
* @see #getDefaultController
|
||||
* @see #hasController
|
||||
*/
|
||||
public boolean activateController() {
|
||||
if (!hasController()) {
|
||||
throw new IllegalStateException("hasController() == false!");
|
||||
}
|
||||
return getController().activate(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.metadata;
|
||||
|
||||
/**
|
||||
* An interface to be implemented by objects that can determine the
|
||||
* settings of an <code>IIOMetadata</code> object, either by putting
|
||||
* up a GUI to obtain values from a user, or by other means. This
|
||||
* interface merely specifies a generic <code>activate</code> method
|
||||
* that invokes the controller, without regard for how the controller
|
||||
* obtains values (<i>i.e.</i>, whether the controller puts up a GUI
|
||||
* or merely computes a set of values is irrelevant to this
|
||||
* interface).
|
||||
*
|
||||
* <p> Within the <code>activate</code> method, a controller obtains
|
||||
* initial values by querying the <code>IIOMetadata</code> object's
|
||||
* settings, either using the XML DOM tree or a plug-in specific
|
||||
* interface, modifies values by whatever means, then modifies the
|
||||
* <code>IIOMetadata</code> object's settings, using either the
|
||||
* <code>setFromTree</code> or <code>mergeTree</code> methods, or a
|
||||
* plug-in specific interface. In general, applications may expect
|
||||
* that when the <code>activate</code> method returns
|
||||
* <code>true</code>, the <code>IIOMetadata</code> object is ready for
|
||||
* use in a write operation.
|
||||
*
|
||||
* <p> Vendors may choose to provide GUIs for the
|
||||
* <code>IIOMetadata</code> subclasses they define for a particular
|
||||
* plug-in. These can be set up as default controllers in the
|
||||
* corresponding <code>IIOMetadata</code> subclasses.
|
||||
*
|
||||
* <p> Alternatively, an algorithmic process such as a database lookup
|
||||
* or the parsing of a command line could be used as a controller, in
|
||||
* which case the <code>activate</code> method would simply look up or
|
||||
* compute the settings, call methods on <code>IIOMetadata</code> to
|
||||
* set its state, and return <code>true</code>.
|
||||
*
|
||||
* @see IIOMetadata#setController
|
||||
* @see IIOMetadata#getController
|
||||
* @see IIOMetadata#getDefaultController
|
||||
* @see IIOMetadata#hasController
|
||||
* @see IIOMetadata#activateController
|
||||
*
|
||||
*/
|
||||
public interface IIOMetadataController {
|
||||
|
||||
/**
|
||||
* Activates the controller. If <code>true</code> is returned,
|
||||
* all settings in the <code>IIOMetadata</code> object should be
|
||||
* ready for use in a write operation. If <code>false</code> is
|
||||
* returned, no settings in the <code>IIOMetadata</code> object
|
||||
* will be disturbed (<i>i.e.</i>, the user canceled the
|
||||
* operation).
|
||||
*
|
||||
* @param metadata the <code>IIOMetadata</code> object to be modified.
|
||||
*
|
||||
* @return <code>true</code> if the <code>IIOMetadata</code> has been
|
||||
* modified, <code>false</code> otherwise.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>metadata</code> is
|
||||
* <code>null</code> or is not an instance of the correct class.
|
||||
*/
|
||||
boolean activate(IIOMetadata metadata);
|
||||
}
|
||||
839
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataFormat.java
Normal file
839
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataFormat.java
Normal file
@@ -0,0 +1,839 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.metadata;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
/**
|
||||
* An object describing the structure of metadata documents returned
|
||||
* from <code>IIOMetadata.getAsTree</code> and passed to
|
||||
* <code>IIOMetadata.setFromTree</code> and <code>mergeTree</code>.
|
||||
* Document structures are described by a set of constraints on the
|
||||
* type and number of child elements that may belong to a given parent
|
||||
* element type, the names, types, and values of attributes that may
|
||||
* belong to an element, and the type and values of
|
||||
* <code>Object</code> reference that may be stored at a node.
|
||||
*
|
||||
* <p> N.B: classes that implement this interface should contain a
|
||||
* method declared as <code>public static getInstance()</code> which
|
||||
* returns an instance of the class. Commonly, an implementation will
|
||||
* construct only a single instance and cache it for future
|
||||
* invocations of <code>getInstance</code>.
|
||||
*
|
||||
* <p> The structures that may be described by this class are a subset
|
||||
* of those expressible using XML document type definitions (DTDs),
|
||||
* with the addition of some basic information on the datatypes of
|
||||
* attributes and the ability to store an <code>Object</code>
|
||||
* reference within a node. In the future, XML Schemas could be used
|
||||
* to represent these structures, and many others.
|
||||
*
|
||||
* <p> The differences between
|
||||
* <code>IIOMetadataFormat</code>-described structures and DTDs are as
|
||||
* follows:
|
||||
*
|
||||
* <ul>
|
||||
* <li> Elements may not contain text or mix text with embedded
|
||||
* tags.
|
||||
*
|
||||
* <li> The children of an element must conform to one of a few simple
|
||||
* patterns, described in the documentation for the
|
||||
* <code>CHILD_*</code> constants;
|
||||
*
|
||||
* <li> The in-memory representation of an elements may contain a
|
||||
* reference to an <code>Object</code>. There is no provision for
|
||||
* representing such objects textually.
|
||||
* </ul>
|
||||
*
|
||||
*/
|
||||
public interface IIOMetadataFormat {
|
||||
|
||||
// Child policies
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element may not have any children. In other words, it
|
||||
* is required to be a leaf node.
|
||||
*/
|
||||
int CHILD_POLICY_EMPTY = 0;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element must have a single instance of each of its
|
||||
* legal child elements, in order. In DTD terms, the contents of
|
||||
* the element are defined by a sequence <code>a,b,c,d,...</code>.
|
||||
*/
|
||||
int CHILD_POLICY_ALL = 1;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element must have zero or one instance of each of its
|
||||
* legal child elements, in order. In DTD terms, the contents of
|
||||
* the element are defined by a sequence
|
||||
* <code>a?,b?,c?,d?,...</code>.
|
||||
*/
|
||||
int CHILD_POLICY_SOME = 2;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element must have zero or one children, selected from
|
||||
* among its legal child elements. In DTD terms, the contents of
|
||||
* the element are defined by a selection
|
||||
* <code>a|b|c|d|...</code>.
|
||||
*/
|
||||
int CHILD_POLICY_CHOICE = 3;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element must have a sequence of instances of any of its
|
||||
* legal child elements. In DTD terms, the contents of the
|
||||
* element are defined by a sequence <code>(a|b|c|d|...)*</code>.
|
||||
*/
|
||||
int CHILD_POLICY_SEQUENCE = 4;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getChildPolicy</code> to indicate
|
||||
* that an element must have zero or more instances of its unique
|
||||
* legal child element. In DTD terms, the contents of the element
|
||||
* are defined by a starred expression <code>a*</code>.
|
||||
*/
|
||||
int CHILD_POLICY_REPEAT = 5;
|
||||
|
||||
/**
|
||||
* The largest valid <code>CHILD_POLICY_*</code> constant,
|
||||
* to be used for range checks.
|
||||
*/
|
||||
int CHILD_POLICY_MAX = CHILD_POLICY_REPEAT;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getObjectValueType</code> to
|
||||
* indicate the absence of a user object.
|
||||
*/
|
||||
int VALUE_NONE = 0;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set a single, arbitrary value.
|
||||
*/
|
||||
int VALUE_ARBITRARY = 1;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set a range of values. Both the minimum
|
||||
* and maximum values of the range are exclusive. It is
|
||||
* recommended that ranges of integers be inclusive on both ends,
|
||||
* and that exclusive ranges be used only for floating-point data.
|
||||
*
|
||||
* @see #VALUE_RANGE_MIN_MAX_INCLUSIVE
|
||||
*/
|
||||
int VALUE_RANGE = 2;
|
||||
|
||||
/**
|
||||
* A value that may be or'ed with <code>VALUE_RANGE</code> to
|
||||
* obtain <code>VALUE_RANGE_MIN_INCLUSIVE</code>, and with
|
||||
* <code>VALUE_RANGE_MAX_INCLUSIVE</code> to obtain
|
||||
* <code>VALUE_RANGE_MIN_MAX_INCLUSIVE</code>.
|
||||
*
|
||||
* <p> Similarly, the value may be and'ed with the value of
|
||||
* <code>getAttributeValueType</code>or
|
||||
* <code>getObjectValueType</code> to determine if the minimum
|
||||
* value of the range is inclusive.
|
||||
*/
|
||||
int VALUE_RANGE_MIN_INCLUSIVE_MASK = 4;
|
||||
|
||||
/**
|
||||
* A value that may be or'ed with <code>VALUE_RANGE</code> to
|
||||
* obtain <code>VALUE_RANGE_MAX_INCLUSIVE</code>, and with
|
||||
* <code>VALUE_RANGE_MIN_INCLUSIVE</code> to obtain
|
||||
* <code>VALUE_RANGE_MIN_MAX_INCLUSIVE</code>.
|
||||
*
|
||||
* <p> Similarly, the value may be and'ed with the value of
|
||||
* <code>getAttributeValueType</code>or
|
||||
* <code>getObjectValueType</code> to determine if the maximum
|
||||
* value of the range is inclusive.
|
||||
*/
|
||||
int VALUE_RANGE_MAX_INCLUSIVE_MASK = 8;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set to a range of values. The minimum
|
||||
* (but not the maximum) value of the range is inclusive.
|
||||
*/
|
||||
int VALUE_RANGE_MIN_INCLUSIVE = VALUE_RANGE |
|
||||
VALUE_RANGE_MIN_INCLUSIVE_MASK;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set to a range of values. The maximum
|
||||
* (but not the minimum) value of the range is inclusive.
|
||||
*/
|
||||
int VALUE_RANGE_MAX_INCLUSIVE = VALUE_RANGE |
|
||||
VALUE_RANGE_MAX_INCLUSIVE_MASK;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set a range of values. Both the minimum
|
||||
* and maximum values of the range are inclusive. It is
|
||||
* recommended that ranges of integers be inclusive on both ends,
|
||||
* and that exclusive ranges be used only for floating-point data.
|
||||
*/
|
||||
int VALUE_RANGE_MIN_MAX_INCLUSIVE =
|
||||
VALUE_RANGE |
|
||||
VALUE_RANGE_MIN_INCLUSIVE_MASK |
|
||||
VALUE_RANGE_MAX_INCLUSIVE_MASK;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set one of a number of enumerated values.
|
||||
* In the case of attributes, these values are
|
||||
* <code>String</code>s; for objects, they are
|
||||
* <code>Object</code>s implementing a given class or interface.
|
||||
*
|
||||
* <p> Attribute values of type <code>DATATYPE_BOOLEAN</code>
|
||||
* should be marked as enumerations.
|
||||
*/
|
||||
int VALUE_ENUMERATION = 16;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeValueType</code> and
|
||||
* <code>getObjectValueType</code> to indicate that the attribute
|
||||
* or user object may be set to a list or array of values. In the
|
||||
* case of attributes, the list will consist of
|
||||
* whitespace-separated values within a <code>String</code>; for
|
||||
* objects, an array will be used.
|
||||
*/
|
||||
int VALUE_LIST = 32;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeDataType</code>
|
||||
* indicating that the value of an attribute is a general Unicode
|
||||
* string.
|
||||
*/
|
||||
int DATATYPE_STRING = 0;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeDataType</code>
|
||||
* indicating that the value of an attribute is one of the boolean
|
||||
* values 'true' or 'false'.
|
||||
* Attribute values of type DATATYPE_BOOLEAN should be marked as
|
||||
* enumerations, and the permitted values should be the string
|
||||
* literal values "TRUE" or "FALSE", although a plugin may also
|
||||
* recognise lower or mixed case equivalents.
|
||||
*/
|
||||
int DATATYPE_BOOLEAN = 1;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeDataType</code>
|
||||
* indicating that the value of an attribute is a string
|
||||
* representation of an integer.
|
||||
*/
|
||||
int DATATYPE_INTEGER = 2;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeDataType</code>
|
||||
* indicating that the value of an attribute is a string
|
||||
* representation of a decimal floating-point number.
|
||||
*/
|
||||
int DATATYPE_FLOAT = 3;
|
||||
|
||||
/**
|
||||
* A constant returned by <code>getAttributeDataType</code>
|
||||
* indicating that the value of an attribute is a string
|
||||
* representation of a double-precision decimal floating-point
|
||||
* number.
|
||||
*/
|
||||
int DATATYPE_DOUBLE = 4;
|
||||
|
||||
// Root
|
||||
|
||||
/**
|
||||
* Returns the name of the root element of the format.
|
||||
*
|
||||
* @return a <code>String</code>.
|
||||
*/
|
||||
String getRootName();
|
||||
|
||||
// Multiplicity
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the element (and the subtree below
|
||||
* it) is allowed to appear in a metadata document for an image of
|
||||
* the given type, defined by an <code>ImageTypeSpecifier</code>.
|
||||
* For example, a metadata document format might contain an
|
||||
* element that describes the primary colors of the image, which
|
||||
* would not be allowed when writing a grayscale image.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param imageType an <code>ImageTypeSpecifier</code> indicating
|
||||
* the type of the image that will be associated with the
|
||||
* metadata.
|
||||
*
|
||||
* @return <code>true</code> if the node is meaningful for images
|
||||
* of the given type.
|
||||
*/
|
||||
boolean canNodeAppear(String elementName, ImageTypeSpecifier imageType);
|
||||
|
||||
/**
|
||||
* Returns the minimum number of children of the named element
|
||||
* with child policy <code>CHILD_POLICY_REPEAT</code>. For
|
||||
* example, an element representing color primary information
|
||||
* might be required to have at least 3 children, one for each
|
||||
* primary.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an <code>int</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element does
|
||||
* not have a child policy of <code>CHILD_POLICY_REPEAT</code>.
|
||||
*/
|
||||
int getElementMinChildren(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of children of the named element
|
||||
* with child policy <code>CHILD_POLICY_REPEAT</code>. For
|
||||
* example, an element representing an entry in an 8-bit color
|
||||
* palette might be allowed to repeat up to 256 times. A value of
|
||||
* <code>Integer.MAX_VALUE</code> may be used to specify that
|
||||
* there is no upper bound.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an <code>int</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element does
|
||||
* not have a child policy of <code>CHILD_POLICY_REPEAT</code>.
|
||||
*/
|
||||
int getElementMaxChildren(String elementName);
|
||||
|
||||
/**
|
||||
* Returns a <code>String</code> containing a description of the
|
||||
* named element, or <code>null</code>. The description will be
|
||||
* localized for the supplied <code>Locale</code> if possible.
|
||||
*
|
||||
* <p> If <code>locale</code> is <code>null</code>, the current
|
||||
* default <code>Locale</code> returned by <code>Locale.getLocale</code>
|
||||
* will be used.
|
||||
*
|
||||
* @param elementName the name of the element.
|
||||
* @param locale the <code>Locale</code> for which localization
|
||||
* will be attempted.
|
||||
*
|
||||
* @return the element description.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code>, or is not a legal element name for this format.
|
||||
*/
|
||||
String getElementDescription(String elementName, Locale locale);
|
||||
|
||||
// Children
|
||||
|
||||
/**
|
||||
* Returns one of the constants starting with
|
||||
* <code>CHILD_POLICY_</code>, indicating the legal pattern of
|
||||
* children for the named element.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return one of the <code>CHILD_POLICY_*</code> constants.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
*/
|
||||
int getChildPolicy(String elementName);
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s indicating the names
|
||||
* of the element which are allowed to be children of the named
|
||||
* element, in the order in which they should appear. If the
|
||||
* element cannot have children, <code>null</code> is returned.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an array of <code>String</code>s, or null.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
*/
|
||||
String[] getChildNames(String elementName);
|
||||
|
||||
// Attributes
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s listing the names of
|
||||
* the attributes that may be associated with the named element.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an array of <code>String</code>s.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
*/
|
||||
String[] getAttributeNames(String elementName);
|
||||
|
||||
/**
|
||||
* Returns one of the constants starting with <code>VALUE_</code>,
|
||||
* indicating whether the values of the given attribute within the
|
||||
* named element are arbitrary, constrained to lie within a
|
||||
* specified range, constrained to be one of a set of enumerated
|
||||
* values, or are a whitespace-separated list of arbitrary values.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return one of the <code>VALUE_*</code> constants.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
*/
|
||||
int getAttributeValueType(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns one of the constants starting with
|
||||
* <code>DATATYPE_</code>, indicating the format and
|
||||
* interpretation of the value of the given attribute within the
|
||||
* named element. If <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_LIST</code>, then the legal value is a
|
||||
* whitespace-spearated list of values of the returned datatype.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return one of the <code>DATATYPE_*</code> constants.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
*/
|
||||
int getAttributeDataType(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the named attribute must be
|
||||
* present within the named element.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return <code>true</code> if the attribute must be present.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
*/
|
||||
boolean isAttributeRequired(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns the default value of the named attribute, if it is not
|
||||
* explicitly present within the named element, as a
|
||||
* <code>String</code>, or <code>null</code> if no default value
|
||||
* is available.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return a <code>String</code> containing the default value, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
*/
|
||||
String getAttributeDefaultValue(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the legal
|
||||
* enumerated values for the given attribute within the named
|
||||
* element. This method should only be called if
|
||||
* <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_ENUMERATION</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return an array of <code>String</code>s.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
* @exception IllegalArgumentException if the given attribute is
|
||||
* not defined as an enumeration.
|
||||
*/
|
||||
String[] getAttributeEnumerations(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns the minimum legal value for the attribute. Whether
|
||||
* this value is inclusive or exclusive may be determined by the
|
||||
* value of <code>getAttributeValueType</code>. The value is
|
||||
* returned as a <code>String</code>; its interpretation is
|
||||
* dependent on the value of <code>getAttributeDataType</code>.
|
||||
* This method should only be called if
|
||||
* <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_RANGE_*</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return a <code>String</code> containing the smallest legal
|
||||
* value for the attribute.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
* @exception IllegalArgumentException if the given attribute is
|
||||
* not defined as a range.
|
||||
*/
|
||||
String getAttributeMinValue(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns the maximum legal value for the attribute. Whether
|
||||
* this value is inclusive or exclusive may be determined by the
|
||||
* value of <code>getAttributeValueType</code>. The value is
|
||||
* returned as a <code>String</code>; its interpretation is
|
||||
* dependent on the value of <code>getAttributeDataType</code>.
|
||||
* This method should only be called if
|
||||
* <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_RANGE_*</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried, as a
|
||||
* <code>String</code>.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return a <code>String</code> containing the largest legal
|
||||
* value for the attribute.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
* @exception IllegalArgumentException if the given attribute is
|
||||
* not defined as a range.
|
||||
*/
|
||||
String getAttributeMaxValue(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns the minimum number of list items that may be used to
|
||||
* define this attribute. The attribute itself is defined as a
|
||||
* <code>String</code> containing multiple whitespace-separated
|
||||
* items. This method should only be called if
|
||||
* <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_LIST</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return the smallest legal number of list items for the
|
||||
* attribute.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
* @exception IllegalArgumentException if the given attribute is
|
||||
* not defined as a list.
|
||||
*/
|
||||
int getAttributeListMinLength(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of list items that may be used to
|
||||
* define this attribute. A value of
|
||||
* <code>Integer.MAX_VALUE</code> may be used to specify that
|
||||
* there is no upper bound. The attribute itself is defined as a
|
||||
* <code>String</code> containing multiple whitespace-separated
|
||||
* items. This method should only be called if
|
||||
* <code>getAttributeValueType</code> returns
|
||||
* <code>VALUE_LIST</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
* @param attrName the name of the attribute being queried.
|
||||
*
|
||||
* @return the largest legal number of list items for the
|
||||
* attribute.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
* @exception IllegalArgumentException if the given attribute is
|
||||
* not defined as a list.
|
||||
*/
|
||||
int getAttributeListMaxLength(String elementName, String attrName);
|
||||
|
||||
/**
|
||||
* Returns a <code>String</code> containing a description of the
|
||||
* named attribute, or <code>null</code>. The description will be
|
||||
* localized for the supplied <code>Locale</code> if possible.
|
||||
*
|
||||
* <p> If <code>locale</code> is <code>null</code>, the current
|
||||
* default <code>Locale</code> returned by <code>Locale.getLocale</code>
|
||||
* will be used.
|
||||
*
|
||||
* @param elementName the name of the element.
|
||||
* @param attrName the name of the attribute.
|
||||
* @param locale the <code>Locale</code> for which localization
|
||||
* will be attempted.
|
||||
*
|
||||
* @return the attribute description.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code>, or is not a legal element name for this format.
|
||||
* @exception IllegalArgumentException if <code>attrName</code> is
|
||||
* <code>null</code> or is not a legal attribute name for this
|
||||
* element.
|
||||
*/
|
||||
String getAttributeDescription(String elementName, String attrName,
|
||||
Locale locale);
|
||||
|
||||
// Object value
|
||||
|
||||
/**
|
||||
* Returns one of the enumerated values starting with
|
||||
* <code>VALUE_</code>, indicating the type of values
|
||||
* (enumeration, range, or array) that are allowed for the
|
||||
* <code>Object</code> reference. If no object value can be
|
||||
* stored within the given element, the result of this method will
|
||||
* be <code>VALUE_NONE</code>.
|
||||
*
|
||||
* <p> <code>Object</code> references whose legal values are
|
||||
* defined as a range must implement the <code>Comparable</code>
|
||||
* interface.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return one of the <code>VALUE_*</code> constants.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
*
|
||||
* @see Comparable
|
||||
*/
|
||||
int getObjectValueType(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the <code>Class</code> type of the <code>Object</code>
|
||||
* reference stored within the element. If this element may not
|
||||
* contain an <code>Object</code> reference, an
|
||||
* <code>IllegalArgumentException</code> will be thrown. If the
|
||||
* class type is an array, this field indicates the underlying
|
||||
* class type (<i>e.g</i>, for an array of <code>int</code>s, this
|
||||
* method would return <code>int.class</code>).
|
||||
*
|
||||
* <p> <code>Object</code> references whose legal values are
|
||||
* defined as a range must implement the <code>Comparable</code>
|
||||
* interface.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return a <code>Class</code> object.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
*/
|
||||
Class<?> getObjectClass(String elementName);
|
||||
|
||||
/**
|
||||
* Returns an <code>Object</code>s containing the default
|
||||
* value for the <code>Object</code> reference within
|
||||
* the named element.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an <code>Object</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
*/
|
||||
Object getObjectDefaultValue(String elementName);
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Object</code>s containing the legal
|
||||
* enumerated values for the <code>Object</code> reference within
|
||||
* the named element. This method should only be called if
|
||||
* <code>getObjectValueType</code> returns
|
||||
* <code>VALUE_ENUMERATION</code>.
|
||||
*
|
||||
* <p> The <code>Object</code> associated with a node that accepts
|
||||
* enumerated values must be equal to one of the values returned by
|
||||
* this method, as defined by the <code>==</code> operator (as
|
||||
* opposed to the <code>Object.equals</code> method).
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return an array of <code>Object</code>s.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
* @exception IllegalArgumentException if the <code>Object</code>
|
||||
* is not defined as an enumeration.
|
||||
*/
|
||||
Object[] getObjectEnumerations(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the minimum legal value for the <code>Object</code>
|
||||
* reference within the named element. Whether this value is
|
||||
* inclusive or exclusive may be determined by the value of
|
||||
* <code>getObjectValueType</code>. This method should only be
|
||||
* called if <code>getObjectValueType</code> returns one of the
|
||||
* constants starting with <code>VALUE_RANGE</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return the smallest legal value for the attribute.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
* @exception IllegalArgumentException if the <code>Object</code>
|
||||
* is not defined as a range.
|
||||
*/
|
||||
Comparable<?> getObjectMinValue(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the maximum legal value for the <code>Object</code>
|
||||
* reference within the named element. Whether this value is
|
||||
* inclusive or exclusive may be determined by the value of
|
||||
* <code>getObjectValueType</code>. This method should only be
|
||||
* called if <code>getObjectValueType</code> returns one of the
|
||||
* constants starting with <code>VALUE_RANGE</code>.
|
||||
*
|
||||
* @return the smallest legal value for the attribute.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
* @exception IllegalArgumentException if the <code>Object</code>
|
||||
* is not defined as a range.
|
||||
*/
|
||||
Comparable<?> getObjectMaxValue(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the minimum number of array elements that may be used
|
||||
* to define the <code>Object</code> reference within the named
|
||||
* element. This method should only be called if
|
||||
* <code>getObjectValueType</code> returns
|
||||
* <code>VALUE_LIST</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return the smallest valid array length for the
|
||||
* <code>Object</code> reference.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
* @exception IllegalArgumentException if the <code>Object</code> is not
|
||||
* an array.
|
||||
*/
|
||||
int getObjectArrayMinLength(String elementName);
|
||||
|
||||
/**
|
||||
* Returns the maximum number of array elements that may be used
|
||||
* to define the <code>Object</code> reference within the named
|
||||
* element. A value of <code>Integer.MAX_VALUE</code> may be used
|
||||
* to specify that there is no upper bound. This method should
|
||||
* only be called if <code>getObjectValueType</code> returns
|
||||
* <code>VALUE_LIST</code>.
|
||||
*
|
||||
* @param elementName the name of the element being queried.
|
||||
*
|
||||
* @return the largest valid array length for the
|
||||
* <code>Object</code> reference.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>elementName</code>
|
||||
* is <code>null</code> or is not a legal element name for this
|
||||
* format.
|
||||
* @exception IllegalArgumentException if the named element cannot
|
||||
* contain an object value (<i>i.e.</i>, if
|
||||
* <code>getObjectValueType(elementName) == VALUE_NONE</code>).
|
||||
* @exception IllegalArgumentException if the <code>Object</code> is not
|
||||
* an array.
|
||||
*/
|
||||
int getObjectArrayMaxLength(String elementName);
|
||||
}
|
||||
1273
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataFormatImpl.java
Normal file
1273
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataFormatImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
1132
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataNode.java
Normal file
1132
jdkSrc/jdk8/javax/imageio/metadata/IIOMetadataNode.java
Normal file
File diff suppressed because it is too large
Load Diff
117
jdkSrc/jdk8/javax/imageio/plugins/bmp/BMPImageWriteParam.java
Normal file
117
jdkSrc/jdk8/javax/imageio/plugins/bmp/BMPImageWriteParam.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.plugins.bmp;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
|
||||
import com.sun.imageio.plugins.bmp.BMPConstants;
|
||||
import com.sun.imageio.plugins.bmp.BMPCompressionTypes;
|
||||
|
||||
/**
|
||||
* A subclass of <code>ImageWriteParam</code> for encoding images in
|
||||
* the BMP format.
|
||||
*
|
||||
* <p> This class allows for the specification of various parameters
|
||||
* while writing a BMP format image file. By default, the data layout
|
||||
* is bottom-up, such that the pixels are stored in bottom-up order,
|
||||
* the first scanline being stored last.
|
||||
*
|
||||
* <p>The particular compression scheme to be used can be specified by using
|
||||
* the <code>setCompressionType()</code> method with the appropriate type
|
||||
* string. The compression scheme specified will be honored if and only if it
|
||||
* is compatible with the type of image being written. If the specified
|
||||
* compression scheme is not compatible with the type of image being written
|
||||
* then the <code>IOException</code> will be thrown by the BMP image writer.
|
||||
* If the compression type is not set explicitly then <code>getCompressionType()</code>
|
||||
* will return <code>null</code>. In this case the BMP image writer will select
|
||||
* a compression type that supports encoding of the given image without loss
|
||||
* of the color resolution.
|
||||
* <p>The compression type strings and the image type(s) each supports are
|
||||
* listed in the following
|
||||
* table:
|
||||
*
|
||||
* <p><table border=1>
|
||||
* <caption><b>Compression Types</b></caption>
|
||||
* <tr><th>Type String</th> <th>Description</th> <th>Image Types</th></tr>
|
||||
* <tr><td>BI_RGB</td> <td>Uncompressed RLE</td> <td>{@literal <= } 8-bits/sample</td></tr>
|
||||
* <tr><td>BI_RLE8</td> <td>8-bit Run Length Encoding</td> <td>{@literal <=} 8-bits/sample</td></tr>
|
||||
* <tr><td>BI_RLE4</td> <td>4-bit Run Length Encoding</td> <td>{@literal <=} 4-bits/sample</td></tr>
|
||||
* <tr><td>BI_BITFIELDS</td> <td>Packed data</td> <td> 16 or 32 bits/sample</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
public class BMPImageWriteParam extends ImageWriteParam {
|
||||
|
||||
private boolean topDown = false;
|
||||
|
||||
/**
|
||||
* Constructs a <code>BMPImageWriteParam</code> set to use a given
|
||||
* <code>Locale</code> and with default values for all parameters.
|
||||
*
|
||||
* @param locale a <code>Locale</code> to be used to localize
|
||||
* compression type names and quality descriptions, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public BMPImageWriteParam(Locale locale) {
|
||||
super(locale);
|
||||
|
||||
// Set compression types ("BI_RGB" denotes uncompressed).
|
||||
compressionTypes = BMPCompressionTypes.getCompressionTypes();
|
||||
|
||||
// Set compression flag.
|
||||
canWriteCompressed = true;
|
||||
compressionMode = MODE_COPY_FROM_METADATA;
|
||||
compressionType = compressionTypes[BMPConstants.BI_RGB];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>BMPImageWriteParam</code> object with default
|
||||
* values for all parameters and a <code>null</code> <code>Locale</code>.
|
||||
*/
|
||||
public BMPImageWriteParam() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, the data will be written out in a top-down manner, the first
|
||||
* scanline being written first.
|
||||
*
|
||||
* @param topDown whether the data are written in top-down order.
|
||||
*/
|
||||
public void setTopDown(boolean topDown) {
|
||||
this.topDown = topDown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the <code>topDown</code> parameter.
|
||||
* The default is <code>false</code>.
|
||||
*
|
||||
* @return whether the data are written in top-down order.
|
||||
*/
|
||||
public boolean isTopDown() {
|
||||
return topDown;
|
||||
}
|
||||
}
|
||||
256
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
Normal file
256
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A class encapsulating a single JPEG Huffman table.
|
||||
* Fields are provided for the "standard" tables taken
|
||||
* from Annex K of the JPEG specification.
|
||||
* These are the tables used as defaults.
|
||||
* <p>
|
||||
* For more information about the operation of the standard JPEG plug-in,
|
||||
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
|
||||
* metadata format specification and usage notes</A>
|
||||
*/
|
||||
|
||||
public class JPEGHuffmanTable {
|
||||
|
||||
/* The data for the publically defined tables, as specified in ITU T.81
|
||||
* JPEG specification section K3.3 and used in the IJG library.
|
||||
*/
|
||||
private static final short[] StdDCLuminanceLengths = {
|
||||
0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
private static final short[] StdDCLuminanceValues = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b,
|
||||
};
|
||||
|
||||
private static final short[] StdDCChrominanceLengths = {
|
||||
0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
private static final short[] StdDCChrominanceValues = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b,
|
||||
};
|
||||
|
||||
private static final short[] StdACLuminanceLengths = {
|
||||
0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03,
|
||||
0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d,
|
||||
};
|
||||
|
||||
private static final short[] StdACLuminanceValues = {
|
||||
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
|
||||
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
|
||||
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
|
||||
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
|
||||
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
|
||||
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
||||
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
|
||||
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
|
||||
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
|
||||
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
|
||||
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
|
||||
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
|
||||
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
||||
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
|
||||
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
|
||||
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
|
||||
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
|
||||
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
|
||||
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa,
|
||||
};
|
||||
|
||||
private static final short[] StdACChrominanceLengths = {
|
||||
0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04,
|
||||
0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77,
|
||||
};
|
||||
|
||||
private static final short[] StdACChrominanceValues = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
|
||||
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
|
||||
0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
|
||||
0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
|
||||
0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
|
||||
0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
|
||||
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
|
||||
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
|
||||
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
|
||||
0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
|
||||
0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
||||
0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
|
||||
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
|
||||
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
|
||||
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
|
||||
0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
|
||||
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
|
||||
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
|
||||
0xf9, 0xfa,
|
||||
};
|
||||
|
||||
/**
|
||||
* The standard DC luminance Huffman table.
|
||||
*/
|
||||
public static final JPEGHuffmanTable
|
||||
StdDCLuminance = new JPEGHuffmanTable(StdDCLuminanceLengths,
|
||||
StdDCLuminanceValues, false);
|
||||
|
||||
/**
|
||||
* The standard DC chrominance Huffman table.
|
||||
*/
|
||||
public static final JPEGHuffmanTable
|
||||
StdDCChrominance = new JPEGHuffmanTable(StdDCChrominanceLengths,
|
||||
StdDCChrominanceValues, false);
|
||||
|
||||
/**
|
||||
* The standard AC luminance Huffman table.
|
||||
*/
|
||||
public static final JPEGHuffmanTable
|
||||
StdACLuminance = new JPEGHuffmanTable(StdACLuminanceLengths,
|
||||
StdACLuminanceValues, false);
|
||||
|
||||
/**
|
||||
* The standard AC chrominance Huffman table.
|
||||
*/
|
||||
public static final JPEGHuffmanTable
|
||||
StdACChrominance = new JPEGHuffmanTable(StdACChrominanceLengths,
|
||||
StdACChrominanceValues, false);
|
||||
|
||||
private short[] lengths;
|
||||
private short[] values;
|
||||
|
||||
/**
|
||||
* Creates a Huffman table and initializes it. The input arrays are copied.
|
||||
* The arrays must describe a possible Huffman table.
|
||||
* For example, 3 codes cannot be expressed with a single bit.
|
||||
*
|
||||
* @param lengths an array of {@code short}s where <code>lengths[k]</code>
|
||||
* is equal to the number of values with corresponding codes of
|
||||
* length <code>k + 1</code> bits.
|
||||
* @param values an array of shorts containing the values in
|
||||
* order of increasing code length.
|
||||
* @throws IllegalArgumentException if <code>lengths</code> or
|
||||
* <code>values</code> are null, the length of <code>lengths</code> is
|
||||
* greater than 16, the length of <code>values</code> is greater than 256,
|
||||
* if any value in <code>lengths</code> or <code>values</code> is less
|
||||
* than zero, or if the arrays do not describe a valid Huffman table.
|
||||
*/
|
||||
public JPEGHuffmanTable(short[] lengths, short[] values) {
|
||||
if (lengths == null || values == null ||
|
||||
lengths.length == 0 || values.length == 0 ||
|
||||
lengths.length > 16 || values.length > 256) {
|
||||
throw new IllegalArgumentException("Illegal lengths or values");
|
||||
}
|
||||
for (int i = 0; i<lengths.length; i++) {
|
||||
if (lengths[i] < 0) {
|
||||
throw new IllegalArgumentException("lengths["+i+"] < 0");
|
||||
}
|
||||
}
|
||||
for (int i = 0; i<values.length; i++) {
|
||||
if (values[i] < 0) {
|
||||
throw new IllegalArgumentException("values["+i+"] < 0");
|
||||
}
|
||||
}
|
||||
this.lengths = Arrays.copyOf(lengths, lengths.length);
|
||||
this.values = Arrays.copyOf(values, values.length);
|
||||
validate();
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
int sumOfLengths = 0;
|
||||
for (int i=0; i<lengths.length; i++) {
|
||||
sumOfLengths += lengths[i];
|
||||
}
|
||||
if (sumOfLengths != values.length) {
|
||||
throw new IllegalArgumentException("lengths do not correspond " +
|
||||
"to length of value table");
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal version which avoids the overhead of copying and checking */
|
||||
private JPEGHuffmanTable(short[] lengths, short[] values, boolean copy) {
|
||||
if (copy) {
|
||||
this.lengths = Arrays.copyOf(lengths, lengths.length);
|
||||
this.values = Arrays.copyOf(values, values.length);
|
||||
} else {
|
||||
this.lengths = lengths;
|
||||
this.values = values;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>short</code>s containing the number of values
|
||||
* for each length in the Huffman table. The returned array is a copy.
|
||||
*
|
||||
* @return a <code>short</code> array where <code>array[k-1]</code>
|
||||
* is equal to the number of values in the table of length <code>k</code>.
|
||||
* @see #getValues
|
||||
*/
|
||||
public short[] getLengths() {
|
||||
return Arrays.copyOf(lengths, lengths.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>short</code>s containing the values arranged
|
||||
* by increasing length of their corresponding codes.
|
||||
* The interpretation of the array is dependent on the values returned
|
||||
* from <code>getLengths</code>. The returned array is a copy.
|
||||
*
|
||||
* @return a <code>short</code> array of values.
|
||||
* @see #getLengths
|
||||
*/
|
||||
public short[] getValues() {
|
||||
return Arrays.copyOf(values, values.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code String} representing this Huffman table.
|
||||
* @return a {@code String} representing this Huffman table.
|
||||
*/
|
||||
public String toString() {
|
||||
String ls = System.getProperty("line.separator", "\n");
|
||||
StringBuilder sb = new StringBuilder("JPEGHuffmanTable");
|
||||
sb.append(ls).append("lengths:");
|
||||
for (int i=0; i<lengths.length; i++) {
|
||||
sb.append(" ").append(lengths[i]);
|
||||
}
|
||||
sb.append(ls).append("values:");
|
||||
for (int i=0; i<values.length; i++) {
|
||||
sb.append(" ").append(values[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
197
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
Normal file
197
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.plugins.jpeg;
|
||||
|
||||
import javax.imageio.ImageReadParam;
|
||||
|
||||
/**
|
||||
* This class adds the ability to set JPEG quantization and Huffman
|
||||
* tables when using the built-in JPEG reader plug-in. An instance of
|
||||
* this class will be returned from the
|
||||
* <code>getDefaultImageReadParam</code> methods of the built-in JPEG
|
||||
* <code>ImageReader</code>.
|
||||
*
|
||||
* <p> The sole purpose of these additions is to allow the
|
||||
* specification of tables for use in decoding abbreviated streams.
|
||||
* The built-in JPEG reader will also accept an ordinary
|
||||
* <code>ImageReadParam</code>, which is sufficient for decoding
|
||||
* non-abbreviated streams.
|
||||
*
|
||||
* <p> While tables for abbreviated streams are often obtained by
|
||||
* first reading another abbreviated stream containing only the
|
||||
* tables, in some applications the tables are fixed ahead of time.
|
||||
* This class allows the tables to be specified directly from client
|
||||
* code. If no tables are specified either in the stream or in a
|
||||
* <code>JPEGImageReadParam</code>, then the stream is presumed to use
|
||||
* the "standard" visually lossless tables. See {@link JPEGQTable JPEGQTable}
|
||||
* and {@link JPEGHuffmanTable JPEGHuffmanTable} for more information
|
||||
* on the default tables.
|
||||
*
|
||||
* <p> The default <code>JPEGImageReadParam</code> returned by the
|
||||
* <code>getDefaultReadParam</code> method of the builtin JPEG reader
|
||||
* contains no tables. Default tables may be obtained from the table
|
||||
* classes {@link JPEGQTable JPEGQTable} and
|
||||
* {@link JPEGHuffmanTable JPEGHuffmanTable}.
|
||||
*
|
||||
* <p> If a stream does contain tables, the tables given in a
|
||||
* <code>JPEGImageReadParam</code> are ignored. Furthermore, if the
|
||||
* first image in a stream does contain tables and subsequent ones do
|
||||
* not, then the tables given in the first image are used for all the
|
||||
* abbreviated images. Once tables have been read from a stream, they
|
||||
* can be overridden only by tables subsequently read from the same
|
||||
* stream. In order to specify new tables, the {@link
|
||||
* javax.imageio.ImageReader#setInput setInput} method of
|
||||
* the reader must be called to change the stream.
|
||||
*
|
||||
* <p> Note that this class does not provide a means for obtaining the
|
||||
* tables found in a stream. These may be extracted from a stream by
|
||||
* consulting the IIOMetadata object returned by the reader.
|
||||
*
|
||||
* <p>
|
||||
* For more information about the operation of the built-in JPEG plug-ins,
|
||||
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
|
||||
* metadata format specification and usage notes</A>.
|
||||
*
|
||||
*/
|
||||
public class JPEGImageReadParam extends ImageReadParam {
|
||||
|
||||
private JPEGQTable[] qTables = null;
|
||||
private JPEGHuffmanTable[] DCHuffmanTables = null;
|
||||
private JPEGHuffmanTable[] ACHuffmanTables = null;
|
||||
|
||||
/**
|
||||
* Constructs a <code>JPEGImageReadParam</code>.
|
||||
*/
|
||||
public JPEGImageReadParam() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if tables are currently set.
|
||||
*
|
||||
* @return <code>true</code> if tables are present.
|
||||
*/
|
||||
public boolean areTablesSet() {
|
||||
return (qTables != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the quantization and Huffman tables to use in decoding
|
||||
* abbreviated streams. There may be a maximum of 4 tables of
|
||||
* each type. These tables are ignored once tables are
|
||||
* encountered in the stream. All arguments must be
|
||||
* non-<code>null</code>. The two arrays of Huffman tables must
|
||||
* have the same number of elements. The table specifiers in the
|
||||
* frame and scan headers in the stream are assumed to be
|
||||
* equivalent to indices into these arrays. The argument arrays
|
||||
* are copied by this method.
|
||||
*
|
||||
* @param qTables an array of quantization table objects.
|
||||
* @param DCHuffmanTables an array of Huffman table objects.
|
||||
* @param ACHuffmanTables an array of Huffman table objects.
|
||||
*
|
||||
* @exception IllegalArgumentException if any of the arguments
|
||||
* is <code>null</code>, has more than 4 elements, or if the
|
||||
* numbers of DC and AC tables differ.
|
||||
*
|
||||
* @see #unsetDecodeTables
|
||||
*/
|
||||
public void setDecodeTables(JPEGQTable[] qTables,
|
||||
JPEGHuffmanTable[] DCHuffmanTables,
|
||||
JPEGHuffmanTable[] ACHuffmanTables) {
|
||||
if ((qTables == null) ||
|
||||
(DCHuffmanTables == null) ||
|
||||
(ACHuffmanTables == null) ||
|
||||
(qTables.length > 4) ||
|
||||
(DCHuffmanTables.length > 4) ||
|
||||
(ACHuffmanTables.length > 4) ||
|
||||
(DCHuffmanTables.length != ACHuffmanTables.length)) {
|
||||
throw new IllegalArgumentException
|
||||
("Invalid JPEG table arrays");
|
||||
}
|
||||
this.qTables = (JPEGQTable[])qTables.clone();
|
||||
this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
|
||||
this.ACHuffmanTables = (JPEGHuffmanTable[])ACHuffmanTables.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any quantization and Huffman tables that are currently
|
||||
* set.
|
||||
*
|
||||
* @see #setDecodeTables
|
||||
*/
|
||||
public void unsetDecodeTables() {
|
||||
this.qTables = null;
|
||||
this.DCHuffmanTables = null;
|
||||
this.ACHuffmanTables = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of quantization tables set on the
|
||||
* most recent call to <code>setDecodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGQTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setDecodeTables
|
||||
*/
|
||||
public JPEGQTable[] getQTables() {
|
||||
return (qTables != null) ? (JPEGQTable[])qTables.clone() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of DC Huffman tables set on the
|
||||
* most recent call to <code>setDecodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGHuffmanTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setDecodeTables
|
||||
*/
|
||||
public JPEGHuffmanTable[] getDCHuffmanTables() {
|
||||
return (DCHuffmanTables != null)
|
||||
? (JPEGHuffmanTable[])DCHuffmanTables.clone()
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of AC Huffman tables set on the
|
||||
* most recent call to <code>setDecodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGHuffmanTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setDecodeTables
|
||||
*/
|
||||
public JPEGHuffmanTable[] getACHuffmanTables() {
|
||||
return (ACHuffmanTables != null)
|
||||
? (JPEGHuffmanTable[])ACHuffmanTables.clone()
|
||||
: null;
|
||||
}
|
||||
}
|
||||
320
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
Normal file
320
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.ImageWriteParam;
|
||||
|
||||
import com.sun.imageio.plugins.jpeg.JPEG;
|
||||
|
||||
/**
|
||||
* This class adds the ability to set JPEG quantization and Huffman
|
||||
* tables when using the built-in JPEG writer plug-in, and to request that
|
||||
* optimized Huffman tables be computed for an image. An instance of
|
||||
* this class will be returned from the
|
||||
* <code>getDefaultImageWriteParam</code> methods of the built-in JPEG
|
||||
* <code>ImageWriter</code>.
|
||||
|
||||
* <p> The principal purpose of these additions is to allow the
|
||||
* specification of tables to use in encoding abbreviated streams.
|
||||
* The built-in JPEG writer will also accept an ordinary
|
||||
* <code>ImageWriteParam</code>, in which case the writer will
|
||||
* construct the necessary tables internally.
|
||||
*
|
||||
* <p> In either case, the quality setting in an <code>ImageWriteParam</code>
|
||||
* has the same meaning as for the underlying library: 1.00 means a
|
||||
* quantization table of all 1's, 0.75 means the "standard", visually
|
||||
* lossless quantization table, and 0.00 means aquantization table of
|
||||
* all 255's.
|
||||
*
|
||||
* <p> While tables for abbreviated streams are often specified by
|
||||
* first writing an abbreviated stream containing only the tables, in
|
||||
* some applications the tables are fixed ahead of time. This class
|
||||
* allows the tables to be specified directly from client code.
|
||||
*
|
||||
* <p> Normally, the tables are specified in the
|
||||
* <code>IIOMetadata</code> objects passed in to the writer, and any
|
||||
* tables included in these objects are written to the stream.
|
||||
* If no tables are specified in the metadata, then an abbreviated
|
||||
* stream is written. If no tables are included in the metadata and
|
||||
* no tables are specified in a <code>JPEGImageWriteParam</code>, then
|
||||
* an abbreviated stream is encoded using the "standard" visually
|
||||
* lossless tables. This class is necessary for specifying tables
|
||||
* when an abbreviated stream must be written without writing any tables
|
||||
* to a stream first. In order to use this class, the metadata object
|
||||
* passed into the writer must contain no tables, and no stream metadata
|
||||
* must be provided. See {@link JPEGQTable JPEGQTable} and
|
||||
* {@link JPEGHuffmanTable JPEGHuffmanTable} for more
|
||||
* information on the default tables.
|
||||
*
|
||||
* <p> The default <code>JPEGImageWriteParam</code> returned by the
|
||||
* <code>getDefaultWriteParam</code> method of the writer contains no
|
||||
* tables. Default tables are included in the default
|
||||
* <code>IIOMetadata</code> objects returned by the writer.
|
||||
*
|
||||
* <p> If the metadata does contain tables, the tables given in a
|
||||
* <code>JPEGImageWriteParam</code> are ignored. Furthermore, once a
|
||||
* set of tables has been written, only tables in the metadata can
|
||||
* override them for subsequent writes, whether to the same stream or
|
||||
* a different one. In order to specify new tables using this class,
|
||||
* the {@link javax.imageio.ImageWriter#reset reset}
|
||||
* method of the writer must be called.
|
||||
*
|
||||
* <p>
|
||||
* For more information about the operation of the built-in JPEG plug-ins,
|
||||
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
|
||||
* metadata format specification and usage notes</A>.
|
||||
*
|
||||
*/
|
||||
public class JPEGImageWriteParam extends ImageWriteParam {
|
||||
|
||||
private JPEGQTable[] qTables = null;
|
||||
private JPEGHuffmanTable[] DCHuffmanTables = null;
|
||||
private JPEGHuffmanTable[] ACHuffmanTables = null;
|
||||
private boolean optimizeHuffman = false;
|
||||
private String[] compressionNames = {"JPEG"};
|
||||
private float[] qualityVals = { 0.00F, 0.30F, 0.75F, 1.00F };
|
||||
private String[] qualityDescs = {
|
||||
"Low quality", // 0.00 -> 0.30
|
||||
"Medium quality", // 0.30 -> 0.75
|
||||
"Visually lossless" // 0.75 -> 1.00
|
||||
};
|
||||
|
||||
/**
|
||||
* Constructs a <code>JPEGImageWriteParam</code>. Tiling is not
|
||||
* supported. Progressive encoding is supported. The default
|
||||
* progressive mode is MODE_DISABLED. A single form of compression,
|
||||
* named "JPEG", is supported. The default compression quality is
|
||||
* 0.75.
|
||||
*
|
||||
* @param locale a <code>Locale</code> to be used by the
|
||||
* superclass to localize compression type names and quality
|
||||
* descriptions, or <code>null</code>.
|
||||
*/
|
||||
public JPEGImageWriteParam(Locale locale) {
|
||||
super(locale);
|
||||
this.canWriteProgressive = true;
|
||||
this.progressiveMode = MODE_DISABLED;
|
||||
this.canWriteCompressed = true;
|
||||
this.compressionTypes = compressionNames;
|
||||
this.compressionType = compressionTypes[0];
|
||||
this.compressionQuality = JPEG.DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any previous compression quality setting.
|
||||
*
|
||||
* <p> The default implementation resets the compression quality
|
||||
* to <code>0.75F</code>.
|
||||
*
|
||||
* @exception IllegalStateException if the compression mode is not
|
||||
* <code>MODE_EXPLICIT</code>.
|
||||
*/
|
||||
public void unsetCompression() {
|
||||
if (getCompressionMode() != MODE_EXPLICIT) {
|
||||
throw new IllegalStateException
|
||||
("Compression mode not MODE_EXPLICIT!");
|
||||
}
|
||||
this.compressionQuality = JPEG.DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>false</code> since the JPEG plug-in only supports
|
||||
* lossy compression.
|
||||
*
|
||||
* @return <code>false</code>.
|
||||
*
|
||||
* @exception IllegalStateException if the compression mode is not
|
||||
* <code>MODE_EXPLICIT</code>.
|
||||
*/
|
||||
public boolean isCompressionLossless() {
|
||||
if (getCompressionMode() != MODE_EXPLICIT) {
|
||||
throw new IllegalStateException
|
||||
("Compression mode not MODE_EXPLICIT!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String[] getCompressionQualityDescriptions() {
|
||||
if (getCompressionMode() != MODE_EXPLICIT) {
|
||||
throw new IllegalStateException
|
||||
("Compression mode not MODE_EXPLICIT!");
|
||||
}
|
||||
if ((getCompressionTypes() != null) &&
|
||||
(getCompressionType() == null)) {
|
||||
throw new IllegalStateException("No compression type set!");
|
||||
}
|
||||
return (String[])qualityDescs.clone();
|
||||
}
|
||||
|
||||
public float[] getCompressionQualityValues() {
|
||||
if (getCompressionMode() != MODE_EXPLICIT) {
|
||||
throw new IllegalStateException
|
||||
("Compression mode not MODE_EXPLICIT!");
|
||||
}
|
||||
if ((getCompressionTypes() != null) &&
|
||||
(getCompressionType() == null)) {
|
||||
throw new IllegalStateException("No compression type set!");
|
||||
}
|
||||
return (float[])qualityVals.clone();
|
||||
}
|
||||
/**
|
||||
* Returns <code>true</code> if tables are currently set.
|
||||
*
|
||||
* @return <code>true</code> if tables are present.
|
||||
*/
|
||||
public boolean areTablesSet() {
|
||||
return (qTables != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the quantization and Huffman tables to use in encoding
|
||||
* abbreviated streams. There may be a maximum of 4 tables of
|
||||
* each type. These tables are ignored if tables are specified in
|
||||
* the metadata. All arguments must be non-<code>null</code>.
|
||||
* The two arrays of Huffman tables must have the same number of
|
||||
* elements. The table specifiers in the frame and scan headers
|
||||
* in the metadata are assumed to be equivalent to indices into
|
||||
* these arrays. The argument arrays are copied by this method.
|
||||
*
|
||||
* @param qTables An array of quantization table objects.
|
||||
* @param DCHuffmanTables An array of Huffman table objects.
|
||||
* @param ACHuffmanTables An array of Huffman table objects.
|
||||
*
|
||||
* @exception IllegalArgumentException if any of the arguments
|
||||
* is <code>null</code> or has more than 4 elements, or if the
|
||||
* numbers of DC and AC tables differ.
|
||||
*
|
||||
* @see #unsetEncodeTables
|
||||
*/
|
||||
public void setEncodeTables(JPEGQTable[] qTables,
|
||||
JPEGHuffmanTable[] DCHuffmanTables,
|
||||
JPEGHuffmanTable[] ACHuffmanTables) {
|
||||
if ((qTables == null) ||
|
||||
(DCHuffmanTables == null) ||
|
||||
(ACHuffmanTables == null) ||
|
||||
(qTables.length > 4) ||
|
||||
(DCHuffmanTables.length > 4) ||
|
||||
(ACHuffmanTables.length > 4) ||
|
||||
(DCHuffmanTables.length != ACHuffmanTables.length)) {
|
||||
throw new IllegalArgumentException("Invalid JPEG table arrays");
|
||||
}
|
||||
this.qTables = (JPEGQTable[])qTables.clone();
|
||||
this.DCHuffmanTables = (JPEGHuffmanTable[])DCHuffmanTables.clone();
|
||||
this.ACHuffmanTables = (JPEGHuffmanTable[])ACHuffmanTables.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any quantization and Huffman tables that are currently
|
||||
* set.
|
||||
*
|
||||
* @see #setEncodeTables
|
||||
*/
|
||||
public void unsetEncodeTables() {
|
||||
this.qTables = null;
|
||||
this.DCHuffmanTables = null;
|
||||
this.ACHuffmanTables = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of quantization tables set on the
|
||||
* most recent call to <code>setEncodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGQTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setEncodeTables
|
||||
*/
|
||||
public JPEGQTable[] getQTables() {
|
||||
return (qTables != null) ? (JPEGQTable[])qTables.clone() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of DC Huffman tables set on the
|
||||
* most recent call to <code>setEncodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGHuffmanTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setEncodeTables
|
||||
*/
|
||||
public JPEGHuffmanTable[] getDCHuffmanTables() {
|
||||
return (DCHuffmanTables != null)
|
||||
? (JPEGHuffmanTable[])DCHuffmanTables.clone()
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the array of AC Huffman tables set on the
|
||||
* most recent call to <code>setEncodeTables</code>, or
|
||||
* <code>null</code> if tables are not currently set.
|
||||
*
|
||||
* @return an array of <code>JPEGHuffmanTable</code> objects, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #setEncodeTables
|
||||
*/
|
||||
public JPEGHuffmanTable[] getACHuffmanTables() {
|
||||
return (ACHuffmanTables != null)
|
||||
? (JPEGHuffmanTable[])ACHuffmanTables.clone()
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells the writer to generate optimized Huffman tables
|
||||
* for the image as part of the writing process. The
|
||||
* default is <code>false</code>. If this flag is set
|
||||
* to <code>true</code>, it overrides any tables specified
|
||||
* in the metadata. Note that this means that any image
|
||||
* written with this flag set to <code>true</code> will
|
||||
* always contain Huffman tables.
|
||||
*
|
||||
* @param optimize A boolean indicating whether to generate
|
||||
* optimized Huffman tables when writing.
|
||||
*
|
||||
* @see #getOptimizeHuffmanTables
|
||||
*/
|
||||
public void setOptimizeHuffmanTables(boolean optimize) {
|
||||
optimizeHuffman = optimize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value passed into the most recent call
|
||||
* to <code>setOptimizeHuffmanTables</code>, or
|
||||
* <code>false</code> if <code>setOptimizeHuffmanTables</code>
|
||||
* has never been called.
|
||||
*
|
||||
* @return <code>true</code> if the writer will generate optimized
|
||||
* Huffman tables.
|
||||
*
|
||||
* @see #setOptimizeHuffmanTables
|
||||
*/
|
||||
public boolean getOptimizeHuffmanTables() {
|
||||
return optimizeHuffman;
|
||||
}
|
||||
}
|
||||
210
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGQTable.java
Normal file
210
jdkSrc/jdk8/javax/imageio/plugins/jpeg/JPEGQTable.java
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.plugins.jpeg;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A class encapsulating a single JPEG quantization table.
|
||||
* The elements appear in natural order (as opposed to zig-zag order).
|
||||
* Static variables are provided for the "standard" tables taken from
|
||||
* Annex K of the JPEG specification, as well as the default tables
|
||||
* conventionally used for visually lossless encoding.
|
||||
* <p>
|
||||
* For more information about the operation of the standard JPEG plug-in,
|
||||
* see the <A HREF="../../metadata/doc-files/jpeg_metadata.html">JPEG
|
||||
* metadata format specification and usage notes</A>
|
||||
*/
|
||||
|
||||
public class JPEGQTable {
|
||||
|
||||
private static final int[] k1 = {
|
||||
16, 11, 10, 16, 24, 40, 51, 61,
|
||||
12, 12, 14, 19, 26, 58, 60, 55,
|
||||
14, 13, 16, 24, 40, 57, 69, 56,
|
||||
14, 17, 22, 29, 51, 87, 80, 62,
|
||||
18, 22, 37, 56, 68, 109, 103, 77,
|
||||
24, 35, 55, 64, 81, 104, 113, 92,
|
||||
49, 64, 78, 87, 103, 121, 120, 101,
|
||||
72, 92, 95, 98, 112, 100, 103, 99,
|
||||
};
|
||||
|
||||
private static final int[] k1div2 = {
|
||||
8, 6, 5, 8, 12, 20, 26, 31,
|
||||
6, 6, 7, 10, 13, 29, 30, 28,
|
||||
7, 7, 8, 12, 20, 29, 35, 28,
|
||||
7, 9, 11, 15, 26, 44, 40, 31,
|
||||
9, 11, 19, 28, 34, 55, 52, 39,
|
||||
12, 18, 28, 32, 41, 52, 57, 46,
|
||||
25, 32, 39, 44, 52, 61, 60, 51,
|
||||
36, 46, 48, 49, 56, 50, 52, 50,
|
||||
};
|
||||
|
||||
private static final int[] k2 = {
|
||||
17, 18, 24, 47, 99, 99, 99, 99,
|
||||
18, 21, 26, 66, 99, 99, 99, 99,
|
||||
24, 26, 56, 99, 99, 99, 99, 99,
|
||||
47, 66, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
99, 99, 99, 99, 99, 99, 99, 99,
|
||||
};
|
||||
|
||||
private static final int[] k2div2 = {
|
||||
9, 9, 12, 24, 50, 50, 50, 50,
|
||||
9, 11, 13, 33, 50, 50, 50, 50,
|
||||
12, 13, 28, 50, 50, 50, 50, 50,
|
||||
24, 33, 50, 50, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 50, 50,
|
||||
50, 50, 50, 50, 50, 50, 50, 50,
|
||||
};
|
||||
|
||||
/**
|
||||
* The sample luminance quantization table given in the JPEG
|
||||
* specification, table K.1. According to the specification,
|
||||
* these values produce "good" quality output.
|
||||
* @see #K1Div2Luminance
|
||||
*/
|
||||
public static final JPEGQTable
|
||||
K1Luminance = new JPEGQTable(k1, false);
|
||||
|
||||
/**
|
||||
* The sample luminance quantization table given in the JPEG
|
||||
* specification, table K.1, with all elements divided by 2.
|
||||
* According to the specification, these values produce "very good"
|
||||
* quality output. This is the table usually used for "visually lossless"
|
||||
* encoding, and is the default luminance table used if the default
|
||||
* tables and quality settings are used.
|
||||
* @see #K1Luminance
|
||||
*/
|
||||
public static final JPEGQTable
|
||||
K1Div2Luminance = new JPEGQTable(k1div2, false);
|
||||
|
||||
/**
|
||||
* The sample chrominance quantization table given in the JPEG
|
||||
* specification, table K.2. According to the specification,
|
||||
* these values produce "good" quality output.
|
||||
* @see #K2Div2Chrominance
|
||||
*/
|
||||
public static final JPEGQTable K2Chrominance =
|
||||
new JPEGQTable(k2, false);
|
||||
|
||||
/**
|
||||
* The sample chrominance quantization table given in the JPEG
|
||||
* specification, table K.1, with all elements divided by 2.
|
||||
* According to the specification, these values produce "very good"
|
||||
* quality output. This is the table usually used for "visually lossless"
|
||||
* encoding, and is the default chrominance table used if the default
|
||||
* tables and quality settings are used.
|
||||
* @see #K2Chrominance
|
||||
*/
|
||||
public static final JPEGQTable K2Div2Chrominance =
|
||||
new JPEGQTable(k2div2, false);
|
||||
|
||||
private int[] qTable;
|
||||
|
||||
private JPEGQTable(int[] table, boolean copy) {
|
||||
qTable = (copy) ? Arrays.copyOf(table, table.length) : table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a quantization table from the argument, which must
|
||||
* contain 64 elements in natural order (not zig-zag order).
|
||||
* A copy is made of the the input array.
|
||||
* @param table the quantization table, as an <code>int</code> array.
|
||||
* @throws IllegalArgumentException if <code>table</code> is
|
||||
* <code>null</code> or <code>table.length</code> is not equal to 64.
|
||||
*/
|
||||
public JPEGQTable(int[] table) {
|
||||
if (table == null) {
|
||||
throw new IllegalArgumentException("table must not be null.");
|
||||
}
|
||||
if (table.length != 64) {
|
||||
throw new IllegalArgumentException("table.length != 64");
|
||||
}
|
||||
qTable = Arrays.copyOf(table, table.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the current quantization table as an array
|
||||
* of {@code int}s in natural (not zig-zag) order.
|
||||
* @return A copy of the current quantization table.
|
||||
*/
|
||||
public int[] getTable() {
|
||||
return Arrays.copyOf(qTable, qTable.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new quantization table where the values are multiplied
|
||||
* by <code>scaleFactor</code> and then clamped to the range 1..32767
|
||||
* (or to 1..255 if <code>forceBaseline</code> is true).
|
||||
* <p>
|
||||
* Values of <code>scaleFactor</code> less than 1 tend to improve
|
||||
* the quality level of the table, and values greater than 1.0
|
||||
* degrade the quality level of the table.
|
||||
* @param scaleFactor multiplication factor for the table.
|
||||
* @param forceBaseline if <code>true</code>,
|
||||
* the values will be clamped to the range 1..255
|
||||
* @return a new quantization table that is a linear multiple
|
||||
* of the current table.
|
||||
*/
|
||||
public JPEGQTable getScaledInstance(float scaleFactor,
|
||||
boolean forceBaseline) {
|
||||
int max = (forceBaseline) ? 255 : 32767;
|
||||
int[] scaledTable = new int[qTable.length];
|
||||
for (int i=0; i<qTable.length; i++) {
|
||||
int sv = (int)((qTable[i] * scaleFactor)+0.5f);
|
||||
if (sv < 1) {
|
||||
sv = 1;
|
||||
}
|
||||
if (sv > max) {
|
||||
sv = max;
|
||||
}
|
||||
scaledTable[i] = sv;
|
||||
}
|
||||
return new JPEGQTable(scaledTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code String} representing this quantization table.
|
||||
* @return a {@code String} representing this quantization table.
|
||||
*/
|
||||
public String toString() {
|
||||
String ls = System.getProperty("line.separator", "\n");
|
||||
StringBuilder sb = new StringBuilder("JPEGQTable:"+ls);
|
||||
for (int i=0; i < qTable.length; i++) {
|
||||
if (i % 8 == 0) {
|
||||
sb.append('\t');
|
||||
}
|
||||
sb.append(qTable[i]);
|
||||
sb.append(((i % 8) == 7) ? ls : ' ');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/javax/imageio/spi/DigraphNode.java
Normal file
161
jdkSrc/jdk8/javax/imageio/spi/DigraphNode.java
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A node in a directed graph. In addition to an arbitrary
|
||||
* <code>Object</code> containing user data associated with the node,
|
||||
* each node maintains a <code>Set</code>s of nodes which are pointed
|
||||
* to by the current node (available from <code>getOutNodes</code>).
|
||||
* The in-degree of the node (that is, number of nodes that point to
|
||||
* the current node) may be queried.
|
||||
*
|
||||
*/
|
||||
class DigraphNode implements Cloneable, Serializable {
|
||||
|
||||
/** The data associated with this node. */
|
||||
protected Object data;
|
||||
|
||||
/**
|
||||
* A <code>Set</code> of neighboring nodes pointed to by this
|
||||
* node.
|
||||
*/
|
||||
protected Set outNodes = new HashSet();
|
||||
|
||||
/** The in-degree of the node. */
|
||||
protected int inDegree = 0;
|
||||
|
||||
/**
|
||||
* A <code>Set</code> of neighboring nodes that point to this
|
||||
* node.
|
||||
*/
|
||||
private Set inNodes = new HashSet();
|
||||
|
||||
public DigraphNode(Object data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/** Returns the <code>Object</code> referenced by this node. */
|
||||
public Object getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> containing the nodes pointed
|
||||
* to by this node.
|
||||
*/
|
||||
public Iterator getOutNodes() {
|
||||
return outNodes.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a directed edge to the graph. The outNodes list of this
|
||||
* node is updated and the in-degree of the other node is incremented.
|
||||
*
|
||||
* @param node a <code>DigraphNode</code>.
|
||||
*
|
||||
* @return <code>true</code> if the node was not previously the
|
||||
* target of an edge.
|
||||
*/
|
||||
public boolean addEdge(DigraphNode node) {
|
||||
if (outNodes.contains(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outNodes.add(node);
|
||||
node.inNodes.add(this);
|
||||
node.incrementInDegree();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if an edge exists between this node
|
||||
* and the given node.
|
||||
*
|
||||
* @param node a <code>DigraphNode</code>.
|
||||
*
|
||||
* @return <code>true</code> if the node is the target of an edge.
|
||||
*/
|
||||
public boolean hasEdge(DigraphNode node) {
|
||||
return outNodes.contains(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a directed edge from the graph. The outNodes list of this
|
||||
* node is updated and the in-degree of the other node is decremented.
|
||||
*
|
||||
* @return <code>true</code> if the node was previously the target
|
||||
* of an edge.
|
||||
*/
|
||||
public boolean removeEdge(DigraphNode node) {
|
||||
if (!outNodes.contains(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outNodes.remove(node);
|
||||
node.inNodes.remove(this);
|
||||
node.decrementInDegree();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes this node from the graph, updating neighboring nodes
|
||||
* appropriately.
|
||||
*/
|
||||
public void dispose() {
|
||||
Object[] inNodesArray = inNodes.toArray();
|
||||
for(int i=0; i<inNodesArray.length; i++) {
|
||||
DigraphNode node = (DigraphNode) inNodesArray[i];
|
||||
node.removeEdge(this);
|
||||
}
|
||||
|
||||
Object[] outNodesArray = outNodes.toArray();
|
||||
for(int i=0; i<outNodesArray.length; i++) {
|
||||
DigraphNode node = (DigraphNode) outNodesArray[i];
|
||||
removeEdge(node);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the in-degree of this node. */
|
||||
public int getInDegree() {
|
||||
return inDegree;
|
||||
}
|
||||
|
||||
/** Increments the in-degree of this node. */
|
||||
private void incrementInDegree() {
|
||||
++inDegree;
|
||||
}
|
||||
|
||||
/** Decrements the in-degree of this node. */
|
||||
private void decrementInDegree() {
|
||||
--inDegree;
|
||||
}
|
||||
}
|
||||
253
jdkSrc/jdk8/javax/imageio/spi/IIORegistry.java
Normal file
253
jdkSrc/jdk8/javax/imageio/spi/IIORegistry.java
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.AccessController;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
import com.sun.imageio.spi.FileImageInputStreamSpi;
|
||||
import com.sun.imageio.spi.FileImageOutputStreamSpi;
|
||||
import com.sun.imageio.spi.InputStreamImageInputStreamSpi;
|
||||
import com.sun.imageio.spi.OutputStreamImageOutputStreamSpi;
|
||||
import com.sun.imageio.spi.RAFImageInputStreamSpi;
|
||||
import com.sun.imageio.spi.RAFImageOutputStreamSpi;
|
||||
import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
|
||||
import com.sun.imageio.plugins.gif.GIFImageWriterSpi;
|
||||
import com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi;
|
||||
import com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi;
|
||||
import com.sun.imageio.plugins.png.PNGImageReaderSpi;
|
||||
import com.sun.imageio.plugins.png.PNGImageWriterSpi;
|
||||
import com.sun.imageio.plugins.bmp.BMPImageReaderSpi;
|
||||
import com.sun.imageio.plugins.bmp.BMPImageWriterSpi;
|
||||
import com.sun.imageio.plugins.wbmp.WBMPImageReaderSpi;
|
||||
import com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi;
|
||||
import sun.awt.AppContext;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.ServiceConfigurationError;
|
||||
|
||||
/**
|
||||
* A registry for service provider instances. Service provider
|
||||
* classes may be detected at run time by means of meta-information in
|
||||
* the JAR files containing them. The intent is that it be relatively
|
||||
* inexpensive to load and inspect all available service provider
|
||||
* classes. These classes may them be used to locate and instantiate
|
||||
* more heavyweight classes that will perform actual work, in this
|
||||
* case instances of <code>ImageReader</code>,
|
||||
* <code>ImageWriter</code>, <code>ImageTranscoder</code>,
|
||||
* <code>ImageInputStream</code>, and <code>ImageOutputStream</code>.
|
||||
*
|
||||
* <p> Service providers found on the system classpath (typically
|
||||
* the <code>lib/ext</code> directory in the Java
|
||||
* installation directory) are automatically loaded as soon as this class is
|
||||
* instantiated.
|
||||
*
|
||||
* <p> When the <code>registerApplicationClasspathSpis</code> method
|
||||
* is called, service provider instances declared in the
|
||||
* meta-information section of JAR files on the application class path
|
||||
* are loaded. To declare a service provider, a <code>services</code>
|
||||
* subdirectory is placed within the <code>META-INF</code> directory
|
||||
* that is present in every JAR file. This directory contains a file
|
||||
* for each service provider interface that has one or more
|
||||
* implementation classes present in the JAR file. For example, if
|
||||
* the JAR file contained a class named
|
||||
* <code>com.mycompany.imageio.MyFormatReaderSpi</code> which
|
||||
* implements the <code>ImageReaderSpi</code> interface, the JAR file
|
||||
* would contain a file named:
|
||||
*
|
||||
* <pre>
|
||||
* META-INF/services/javax.imageio.spi.ImageReaderSpi
|
||||
* </pre>
|
||||
*
|
||||
* containing the line:
|
||||
*
|
||||
* <pre>
|
||||
* com.mycompany.imageio.MyFormatReaderSpi
|
||||
* </pre>
|
||||
*
|
||||
* <p> The service provider classes are intended to be lightweight
|
||||
* and quick to load. Implementations of these interfaces
|
||||
* should avoid complex dependencies on other classes and on
|
||||
* native code.
|
||||
*
|
||||
* <p> It is also possible to manually add service providers not found
|
||||
* automatically, as well as to remove those that are using the
|
||||
* interfaces of the <code>ServiceRegistry</code> class. Thus
|
||||
* the application may customize the contents of the registry as it
|
||||
* sees fit.
|
||||
*
|
||||
* <p> For more details on declaring service providers, and the JAR
|
||||
* format in general, see the <a
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html">
|
||||
* JAR File Specification</a>.
|
||||
*
|
||||
*/
|
||||
public final class IIORegistry extends ServiceRegistry {
|
||||
|
||||
/**
|
||||
* A <code>Vector</code> containing the valid IIO registry
|
||||
* categories (superinterfaces) to be used in the constructor.
|
||||
*/
|
||||
private static final Vector initialCategories = new Vector(5);
|
||||
|
||||
static {
|
||||
initialCategories.add(ImageReaderSpi.class);
|
||||
initialCategories.add(ImageWriterSpi.class);
|
||||
initialCategories.add(ImageTranscoderSpi.class);
|
||||
initialCategories.add(ImageInputStreamSpi.class);
|
||||
initialCategories.add(ImageOutputStreamSpi.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the valid service provider categories and automatically
|
||||
* register all available service providers.
|
||||
*
|
||||
* <p> The constructor is private in order to prevent creation of
|
||||
* additional instances.
|
||||
*/
|
||||
private IIORegistry() {
|
||||
super(initialCategories.iterator());
|
||||
registerStandardSpis();
|
||||
registerApplicationClasspathSpis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default <code>IIORegistry</code> instance used by
|
||||
* the Image I/O API. This instance should be used for all
|
||||
* registry functions.
|
||||
*
|
||||
* <p> Each <code>ThreadGroup</code> will receive its own
|
||||
* instance; this allows different <code>Applet</code>s in the
|
||||
* same browser (for example) to each have their own registry.
|
||||
*
|
||||
* @return the default registry for the current
|
||||
* <code>ThreadGroup</code>.
|
||||
*/
|
||||
public static IIORegistry getDefaultInstance() {
|
||||
AppContext context = AppContext.getAppContext();
|
||||
IIORegistry registry =
|
||||
(IIORegistry)context.get(IIORegistry.class);
|
||||
if (registry == null) {
|
||||
// Create an instance for this AppContext
|
||||
registry = new IIORegistry();
|
||||
context.put(IIORegistry.class, registry);
|
||||
}
|
||||
return registry;
|
||||
}
|
||||
|
||||
private void registerStandardSpis() {
|
||||
// Hardwire standard SPIs
|
||||
registerServiceProvider(new GIFImageReaderSpi());
|
||||
registerServiceProvider(new GIFImageWriterSpi());
|
||||
registerServiceProvider(new BMPImageReaderSpi());
|
||||
registerServiceProvider(new BMPImageWriterSpi());
|
||||
registerServiceProvider(new WBMPImageReaderSpi());
|
||||
registerServiceProvider(new WBMPImageWriterSpi());
|
||||
registerServiceProvider(new PNGImageReaderSpi());
|
||||
registerServiceProvider(new PNGImageWriterSpi());
|
||||
registerServiceProvider(new JPEGImageReaderSpi());
|
||||
registerServiceProvider(new JPEGImageWriterSpi());
|
||||
registerServiceProvider(new FileImageInputStreamSpi());
|
||||
registerServiceProvider(new FileImageOutputStreamSpi());
|
||||
registerServiceProvider(new InputStreamImageInputStreamSpi());
|
||||
registerServiceProvider(new OutputStreamImageOutputStreamSpi());
|
||||
registerServiceProvider(new RAFImageInputStreamSpi());
|
||||
registerServiceProvider(new RAFImageOutputStreamSpi());
|
||||
|
||||
registerInstalledProviders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all available service providers found on the
|
||||
* application class path, using the default
|
||||
* <code>ClassLoader</code>. This method is typically invoked by
|
||||
* the <code>ImageIO.scanForPlugins</code> method.
|
||||
*
|
||||
* @see javax.imageio.ImageIO#scanForPlugins
|
||||
* @see ClassLoader#getResources
|
||||
*/
|
||||
public void registerApplicationClasspathSpis() {
|
||||
// FIX: load only from application classpath
|
||||
|
||||
ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
Iterator categories = getCategories();
|
||||
while (categories.hasNext()) {
|
||||
Class<IIOServiceProvider> c = (Class)categories.next();
|
||||
Iterator<IIOServiceProvider> riter =
|
||||
ServiceLoader.load(c, loader).iterator();
|
||||
while (riter.hasNext()) {
|
||||
try {
|
||||
// Note that the next() call is required to be inside
|
||||
// the try/catch block; see 6342404.
|
||||
IIOServiceProvider r = riter.next();
|
||||
registerServiceProvider(r);
|
||||
} catch (ServiceConfigurationError err) {
|
||||
if (System.getSecurityManager() != null) {
|
||||
// In the applet case, we will catch the error so
|
||||
// registration of other plugins can proceed
|
||||
err.printStackTrace();
|
||||
} else {
|
||||
// In the application case, we will throw the
|
||||
// error to indicate app/system misconfiguration
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerInstalledProviders() {
|
||||
/*
|
||||
We need to load installed providers from the
|
||||
system classpath (typically the <code>lib/ext</code>
|
||||
directory in in the Java installation directory)
|
||||
in the privileged mode in order to
|
||||
be able read corresponding jar files even if
|
||||
file read capability is restricted (like the
|
||||
applet context case).
|
||||
*/
|
||||
PrivilegedAction doRegistration =
|
||||
new PrivilegedAction() {
|
||||
public Object run() {
|
||||
Iterator categories = getCategories();
|
||||
while (categories.hasNext()) {
|
||||
Class<IIOServiceProvider> c = (Class)categories.next();
|
||||
for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) {
|
||||
registerServiceProvider(p);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
AccessController.doPrivileged(doRegistration);
|
||||
}
|
||||
}
|
||||
172
jdkSrc/jdk8/javax/imageio/spi/IIOServiceProvider.java
Normal file
172
jdkSrc/jdk8/javax/imageio/spi/IIOServiceProvider.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.util.Locale;
|
||||
import javax.imageio.spi.RegisterableService;
|
||||
import javax.imageio.spi.ServiceRegistry;
|
||||
|
||||
/**
|
||||
* A superinterface for functionality common to all Image I/O service
|
||||
* provider interfaces (SPIs). For more information on service
|
||||
* provider classes, see the class comment for the
|
||||
* <code>IIORegistry</code> class.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.spi.ImageReaderSpi
|
||||
* @see javax.imageio.spi.ImageWriterSpi
|
||||
* @see javax.imageio.spi.ImageTranscoderSpi
|
||||
* @see javax.imageio.spi.ImageInputStreamSpi
|
||||
*
|
||||
*/
|
||||
public abstract class IIOServiceProvider implements RegisterableService {
|
||||
|
||||
/**
|
||||
* A <code>String</code> to be returned from
|
||||
* <code>getVendorName</code>, initially <code>null</code>.
|
||||
* Constructors should set this to a non-<code>null</code> value.
|
||||
*/
|
||||
protected String vendorName;
|
||||
|
||||
/**
|
||||
* A <code>String</code> to be returned from
|
||||
* <code>getVersion</code>, initially null. Constructors should
|
||||
* set this to a non-<code>null</code> value.
|
||||
*/
|
||||
protected String version;
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOServiceProvider</code> with a given
|
||||
* vendor name and version identifier.
|
||||
*
|
||||
* @param vendorName the vendor name.
|
||||
* @param version a version identifier.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public IIOServiceProvider(String vendorName,
|
||||
String version) {
|
||||
if (vendorName == null) {
|
||||
throw new IllegalArgumentException("vendorName == null!");
|
||||
}
|
||||
if (version == null) {
|
||||
throw new IllegalArgumentException("version == null!");
|
||||
}
|
||||
this.vendorName = vendorName;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>IIOServiceProvider</code>. It is up
|
||||
* to the subclass to initialize instance variables and/or
|
||||
* override method implementations in order to ensure that the
|
||||
* <code>getVendorName</code> and <code>getVersion</code> methods
|
||||
* will return non-<code>null</code> values.
|
||||
*/
|
||||
public IIOServiceProvider() {
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback that will be called exactly once after the Spi class
|
||||
* has been instantiated and registered in a
|
||||
* <code>ServiceRegistry</code>. This may be used to verify that
|
||||
* the environment is suitable for this service, for example that
|
||||
* native libraries can be loaded. If the service cannot function
|
||||
* in the environment where it finds itself, it should deregister
|
||||
* itself from the registry.
|
||||
*
|
||||
* <p> Only the registry should call this method.
|
||||
*
|
||||
* <p> The default implementation does nothing.
|
||||
*
|
||||
* @see ServiceRegistry#registerServiceProvider(Object provider)
|
||||
*/
|
||||
public void onRegistration(ServiceRegistry registry,
|
||||
Class<?> category) {}
|
||||
|
||||
/**
|
||||
* A callback that will be whenever the Spi class has been
|
||||
* deregistered from a <code>ServiceRegistry</code>.
|
||||
*
|
||||
* <p> Only the registry should call this method.
|
||||
*
|
||||
* <p> The default implementation does nothing.
|
||||
*
|
||||
* @see ServiceRegistry#deregisterServiceProvider(Object provider)
|
||||
*/
|
||||
public void onDeregistration(ServiceRegistry registry,
|
||||
Class<?> category) {}
|
||||
|
||||
/**
|
||||
* Returns the name of the vendor responsible for creating this
|
||||
* service provider and its associated implementation. Because
|
||||
* the vendor name may be used to select a service provider,
|
||||
* it is not localized.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>vendorName</code> instance variable.
|
||||
*
|
||||
* @return a non-<code>null</code> <code>String</code> containing
|
||||
* the name of the vendor.
|
||||
*/
|
||||
public String getVendorName() {
|
||||
return vendorName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string describing the version
|
||||
* number of this service provider and its associated
|
||||
* implementation. Because the version may be used by transcoders
|
||||
* to identify the service providers they understand, this method
|
||||
* is not localized.
|
||||
*
|
||||
* <p> The default implementation returns the value of the
|
||||
* <code>version</code> instance variable.
|
||||
*
|
||||
* @return a non-<code>null</code> <code>String</code> containing
|
||||
* the version of this service provider.
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a brief, human-readable description of this service
|
||||
* provider and its associated implementation. The resulting
|
||||
* string should be localized for the supplied
|
||||
* <code>Locale</code>, if possible.
|
||||
*
|
||||
* @param locale a <code>Locale</code> for which the return value
|
||||
* should be localized.
|
||||
*
|
||||
* @return a <code>String</code> containing a description of this
|
||||
* service provider.
|
||||
*/
|
||||
public abstract String getDescription(Locale locale);
|
||||
}
|
||||
201
jdkSrc/jdk8/javax/imageio/spi/ImageInputStreamSpi.java
Normal file
201
jdkSrc/jdk8/javax/imageio/spi/ImageInputStreamSpi.java
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* The service provider interface (SPI) for
|
||||
* <code>ImageInputStream</code>s. For more information on service
|
||||
* provider interfaces, see the class comment for the
|
||||
* <code>IIORegistry</code> class.
|
||||
*
|
||||
* <p> This interface allows arbitrary objects to be "wrapped" by
|
||||
* instances of <code>ImageInputStream</code>. For example,
|
||||
* a particular <code>ImageInputStreamSpi</code> might allow
|
||||
* a generic <code>InputStream</code> to be used as an input source;
|
||||
* another might take input from a <code>URL</code>.
|
||||
*
|
||||
* <p> By treating the creation of <code>ImageInputStream</code>s as a
|
||||
* pluggable service, it becomes possible to handle future input
|
||||
* sources without changing the API. Also, high-performance
|
||||
* implementations of <code>ImageInputStream</code> (for example,
|
||||
* native implementations for a particular platform) can be installed
|
||||
* and used transparently by applications.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.stream.ImageInputStream
|
||||
*
|
||||
*/
|
||||
public abstract class ImageInputStreamSpi extends IIOServiceProvider {
|
||||
|
||||
/**
|
||||
* A <code>Class</code> object indicating the legal object type
|
||||
* for use by the <code>createInputStreamInstance</code> method.
|
||||
*/
|
||||
protected Class<?> inputClass;
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>ImageInputStreamSpi</code>. It is up
|
||||
* to the subclass to initialize instance variables and/or
|
||||
* override method implementations in order to provide working
|
||||
* versions of all methods.
|
||||
*/
|
||||
protected ImageInputStreamSpi() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageInputStreamSpi</code> with a given set
|
||||
* of values.
|
||||
*
|
||||
* @param vendorName the vendor name.
|
||||
* @param version a version identifier.
|
||||
* @param inputClass a <code>Class</code> object indicating the
|
||||
* legal object type for use by the
|
||||
* <code>createInputStreamInstance</code> method.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public ImageInputStreamSpi(String vendorName,
|
||||
String version,
|
||||
Class<?> inputClass) {
|
||||
super(vendorName, version);
|
||||
this.inputClass = inputClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Class</code> object representing the class or
|
||||
* interface type that must be implemented by an input source in
|
||||
* order to be "wrapped" in an <code>ImageInputStream</code> via
|
||||
* the <code>createInputStreamInstance</code> method.
|
||||
*
|
||||
* <p> Typical return values might include
|
||||
* <code>InputStream.class</code> or <code>URL.class</code>, but
|
||||
* any class may be used.
|
||||
*
|
||||
* @return a <code>Class</code> variable.
|
||||
*
|
||||
* @see #createInputStreamInstance(Object, boolean, File)
|
||||
*/
|
||||
public Class<?> getInputClass() {
|
||||
return inputClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageInputStream</code>
|
||||
* implementation associated with this service provider can
|
||||
* optionally make use of a cache file for improved performance
|
||||
* and/or memory footrprint. If <code>false</code>, the value of
|
||||
* the <code>useCache</code> argument to
|
||||
* <code>createInputStreamInstance</code> will be ignored.
|
||||
*
|
||||
* <p> The default implementation returns <code>false</code>.
|
||||
*
|
||||
* @return <code>true</code> if a cache file can be used by the
|
||||
* input streams created by this service provider.
|
||||
*/
|
||||
public boolean canUseCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageInputStream</code>
|
||||
* implementation associated with this service provider requires
|
||||
* the use of a cache <code>File</code>. If <code>true</code>,
|
||||
* the value of the <code>useCache</code> argument to
|
||||
* <code>createInputStreamInstance</code> will be ignored.
|
||||
*
|
||||
* <p> The default implementation returns <code>false</code>.
|
||||
*
|
||||
* @return <code>true</code> if a cache file is needed by the
|
||||
* input streams created by this service provider.
|
||||
*/
|
||||
public boolean needsCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageInputStream</code>
|
||||
* implementation associated with this service provider. If the
|
||||
* use of a cache file is optional, the <code>useCache</code>
|
||||
* parameter will be consulted. Where a cache is required, or
|
||||
* not applicable, the value of <code>useCache</code> will be ignored.
|
||||
*
|
||||
* @param input an object of the class type returned by
|
||||
* <code>getInputClass</code>.
|
||||
* @param useCache a <code>boolean</code> indicating whether a
|
||||
* cache file should be used, in cases where it is optional.
|
||||
* @param cacheDir a <code>File</code> indicating where the
|
||||
* cache file should be created, or <code>null</code> to use the
|
||||
* system directory.
|
||||
*
|
||||
* @return an <code>ImageInputStream</code> instance.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>input</code> is
|
||||
* not an instance of the correct class or is <code>null</code>.
|
||||
* @exception IllegalArgumentException if a cache file is needed
|
||||
* but <code>cacheDir</code> is non-<code>null</code> and is not a
|
||||
* directory.
|
||||
* @exception IOException if a cache file is needed but cannot be
|
||||
* created.
|
||||
*
|
||||
* @see #getInputClass
|
||||
* @see #canUseCacheFile
|
||||
* @see #needsCacheFile
|
||||
*/
|
||||
public abstract ImageInputStream
|
||||
createInputStreamInstance(Object input,
|
||||
boolean useCache,
|
||||
File cacheDir) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageInputStream</code>
|
||||
* implementation associated with this service provider. A cache
|
||||
* file will be created in the system-dependent default
|
||||
* temporary-file directory, if needed.
|
||||
*
|
||||
* @param input an object of the class type returned by
|
||||
* <code>getInputClass</code>.
|
||||
*
|
||||
* @return an <code>ImageInputStream</code> instance.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>input</code> is
|
||||
* not an instance of the correct class or is <code>null</code>.
|
||||
* @exception IOException if a cache file is needed but cannot be
|
||||
* created.
|
||||
*
|
||||
* @see #getInputClass()
|
||||
*/
|
||||
public ImageInputStream createInputStreamInstance(Object input)
|
||||
throws IOException {
|
||||
return createInputStreamInstance(input, true, null);
|
||||
}
|
||||
}
|
||||
200
jdkSrc/jdk8/javax/imageio/spi/ImageOutputStreamSpi.java
Normal file
200
jdkSrc/jdk8/javax/imageio/spi/ImageOutputStreamSpi.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
/**
|
||||
* The service provider interface (SPI) for
|
||||
* <code>ImageOutputStream</code>s. For more information on service
|
||||
* provider interfaces, see the class comment for the
|
||||
* <code>IIORegistry</code> class.
|
||||
*
|
||||
* <p> This interface allows arbitrary objects to be "wrapped" by
|
||||
* instances of <code>ImageOutputStream</code>. For example, a
|
||||
* particular <code>ImageOutputStreamSpi</code> might allow a generic
|
||||
* <code>OutputStream</code> to be used as a destination; another
|
||||
* might output to a <code>File</code> or to a device such as a serial
|
||||
* port.
|
||||
*
|
||||
* <p> By treating the creation of <code>ImageOutputStream</code>s as
|
||||
* a pluggable service, it becomes possible to handle future output
|
||||
* destinations without changing the API. Also, high-performance
|
||||
* implementations of <code>ImageOutputStream</code> (for example,
|
||||
* native implementations for a particular platform) can be installed
|
||||
* and used transparently by applications.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.stream.ImageOutputStream
|
||||
*
|
||||
*/
|
||||
public abstract class ImageOutputStreamSpi extends IIOServiceProvider {
|
||||
|
||||
/**
|
||||
* A <code>Class</code> object indicating the legal object type
|
||||
* for use by the <code>createInputStreamInstance</code> method.
|
||||
*/
|
||||
protected Class<?> outputClass;
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>ImageOutputStreamSpi</code>. It is up
|
||||
* to the subclass to initialize instance variables and/or
|
||||
* override method implementations in order to provide working
|
||||
* versions of all methods.
|
||||
*/
|
||||
protected ImageOutputStreamSpi() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageOutputStreamSpi</code> with a given
|
||||
* set of values.
|
||||
*
|
||||
* @param vendorName the vendor name.
|
||||
* @param version a version identifier.
|
||||
* @param outputClass a <code>Class</code> object indicating the
|
||||
* legal object type for use by the
|
||||
* <code>createOutputStreamInstance</code> method.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public ImageOutputStreamSpi(String vendorName,
|
||||
String version,
|
||||
Class<?> outputClass) {
|
||||
super(vendorName, version);
|
||||
this.outputClass = outputClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Class</code> object representing the class or
|
||||
* interface type that must be implemented by an output
|
||||
* destination in order to be "wrapped" in an
|
||||
* <code>ImageOutputStream</code> via the
|
||||
* <code>createOutputStreamInstance</code> method.
|
||||
*
|
||||
* <p> Typical return values might include
|
||||
* <code>OutputStream.class</code> or <code>File.class</code>, but
|
||||
* any class may be used.
|
||||
*
|
||||
* @return a <code>Class</code> variable.
|
||||
*
|
||||
* @see #createOutputStreamInstance(Object, boolean, File)
|
||||
*/
|
||||
public Class<?> getOutputClass() {
|
||||
return outputClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageOutputStream</code>
|
||||
* implementation associated with this service provider can
|
||||
* optionally make use of a cache <code>File</code> for improved
|
||||
* performance and/or memory footrprint. If <code>false</code>,
|
||||
* the value of the <code>cacheFile</code> argument to
|
||||
* <code>createOutputStreamInstance</code> will be ignored.
|
||||
*
|
||||
* <p> The default implementation returns <code>false</code>.
|
||||
*
|
||||
* @return <code>true</code> if a cache file can be used by the
|
||||
* output streams created by this service provider.
|
||||
*/
|
||||
public boolean canUseCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageOutputStream</code>
|
||||
* implementation associated with this service provider requires
|
||||
* the use of a cache <code>File</code>.
|
||||
*
|
||||
* <p> The default implementation returns <code>false</code>.
|
||||
*
|
||||
* @return <code>true</code> if a cache file is needed by the
|
||||
* output streams created by this service provider.
|
||||
*/
|
||||
public boolean needsCacheFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageOutputStream</code>
|
||||
* implementation associated with this service provider. If the
|
||||
* use of a cache file is optional, the <code>useCache</code>
|
||||
* parameter will be consulted. Where a cache is required, or
|
||||
* not applicable, the value of <code>useCache</code> will be ignored.
|
||||
*
|
||||
* @param output an object of the class type returned by
|
||||
* <code>getOutputClass</code>.
|
||||
* @param useCache a <code>boolean</code> indicating whether a
|
||||
* cache file should be used, in cases where it is optional.
|
||||
* @param cacheDir a <code>File</code> indicating where the
|
||||
* cache file should be created, or <code>null</code> to use the
|
||||
* system directory.
|
||||
*
|
||||
* @return an <code>ImageOutputStream</code> instance.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>output</code> is
|
||||
* not an instance of the correct class or is <code>null</code>.
|
||||
* @exception IllegalArgumentException if a cache file is needed,
|
||||
* but <code>cacheDir</code> is non-<code>null</code> and is not a
|
||||
* directory.
|
||||
* @exception IOException if a cache file is needed but cannot be
|
||||
* created.
|
||||
*
|
||||
* @see #getOutputClass
|
||||
*/
|
||||
public abstract
|
||||
ImageOutputStream createOutputStreamInstance(Object output,
|
||||
boolean useCache,
|
||||
File cacheDir)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageOutputStream</code>
|
||||
* implementation associated with this service provider. A cache
|
||||
* file will be created in the system-dependent default
|
||||
* temporary-file directory, if needed.
|
||||
*
|
||||
* @param output an object of the class type returned by
|
||||
* <code>getOutputClass</code>.
|
||||
*
|
||||
* @return an <code>ImageOutputStream</code> instance.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>output</code> is
|
||||
* not an instance of the correct class or is <code>null</code>.
|
||||
* @exception IOException if a cache file is needed but cannot be
|
||||
* created.
|
||||
*
|
||||
* @see #getOutputClass()
|
||||
*/
|
||||
public ImageOutputStream createOutputStreamInstance(Object output)
|
||||
throws IOException {
|
||||
return createOutputStreamInstance(output, true, null);
|
||||
}
|
||||
}
|
||||
413
jdkSrc/jdk8/javax/imageio/spi/ImageReaderSpi.java
Normal file
413
jdkSrc/jdk8/javax/imageio/spi/ImageReaderSpi.java
Normal file
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
|
||||
/**
|
||||
* The service provider interface (SPI) for <code>ImageReader</code>s.
|
||||
* For more information on service provider classes, see the class comment
|
||||
* for the <code>IIORegistry</code> class.
|
||||
*
|
||||
* <p> Each <code>ImageReaderSpi</code> provides several types of information
|
||||
* about the <code>ImageReader</code> class with which it is associated.
|
||||
*
|
||||
* <p> The name of the vendor who defined the SPI class and a
|
||||
* brief description of the class are available via the
|
||||
* <code>getVendorName</code>, <code>getDescription</code>,
|
||||
* and <code>getVersion</code> methods.
|
||||
* These methods may be internationalized to provide locale-specific
|
||||
* output. These methods are intended mainly to provide short,
|
||||
* human-readable information that might be used to organize a pop-up
|
||||
* menu or other list.
|
||||
*
|
||||
* <p> Lists of format names, file suffixes, and MIME types associated
|
||||
* with the service may be obtained by means of the
|
||||
* <code>getFormatNames</code>, <code>getFileSuffixes</code>, and
|
||||
* <code>getMIMETypes</code> methods. These methods may be used to
|
||||
* identify candidate <code>ImageReader</code>s for decoding a
|
||||
* particular file or stream based on manual format selection, file
|
||||
* naming, or MIME associations (for example, when accessing a file
|
||||
* over HTTP or as an email attachment).
|
||||
*
|
||||
* <p> A more reliable way to determine which <code>ImageReader</code>s
|
||||
* are likely to be able to parse a particular data stream is provided
|
||||
* by the <code>canDecodeInput</code> method. This methods allows the
|
||||
* service provider to inspect the actual stream contents.
|
||||
*
|
||||
* <p> Finally, an instance of the <code>ImageReader</code> class
|
||||
* associated with this service provider may be obtained by calling
|
||||
* the <code>createReaderInstance</code> method. Any heavyweight
|
||||
* initialization, such as the loading of native libraries or creation
|
||||
* of large tables, should be deferred at least until the first
|
||||
* invocation of this method.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.ImageReader
|
||||
*
|
||||
*/
|
||||
public abstract class ImageReaderSpi extends ImageReaderWriterSpi {
|
||||
|
||||
/**
|
||||
* A single-element array, initially containing
|
||||
* <code>ImageInputStream.class</code>, to be returned from
|
||||
* <code>getInputTypes</code>.
|
||||
* @deprecated Instead of using this field, directly create
|
||||
* the equivalent array <code>{ ImageInputStream.class }</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Class[] STANDARD_INPUT_TYPE =
|
||||
{ ImageInputStream.class };
|
||||
|
||||
/**
|
||||
* An array of <code>Class</code> objects to be returned from
|
||||
* <code>getInputTypes</code>, initially <code>null</code>.
|
||||
*/
|
||||
protected Class[] inputTypes = null;
|
||||
|
||||
/**
|
||||
* An array of strings to be returned from
|
||||
* <code>getImageWriterSpiNames</code>, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
protected String[] writerSpiNames = null;
|
||||
|
||||
/**
|
||||
* The <code>Class</code> of the reader, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
private Class readerClass = null;
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>ImageReaderSpi</code>. It is up to
|
||||
* the subclass to initialize instance variables and/or override
|
||||
* method implementations in order to provide working versions of
|
||||
* all methods.
|
||||
*/
|
||||
protected ImageReaderSpi() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageReaderSpi</code> with a given
|
||||
* set of values.
|
||||
*
|
||||
* @param vendorName the vendor name, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param version a version identifier, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param names a non-<code>null</code> array of
|
||||
* <code>String</code>s indicating the format names. At least one
|
||||
* entry must be present.
|
||||
* @param suffixes an array of <code>String</code>s indicating the
|
||||
* common file suffixes. If no suffixes are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param MIMETypes an array of <code>String</code>s indicating
|
||||
* the format's MIME types. If no MIME types are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param readerClassName the fully-qualified name of the
|
||||
* associated <code>ImageReader</code> class, as a
|
||||
* non-<code>null</code> <code>String</code>.
|
||||
* @param inputTypes a non-<code>null</code> array of
|
||||
* <code>Class</code> objects of length at least 1 indicating the
|
||||
* legal input types.
|
||||
* @param writerSpiNames an array <code>String</code>s naming the
|
||||
* classes of all associated <code>ImageWriter</code>s, or
|
||||
* <code>null</code>. An array of length 0 is normalized to
|
||||
* <code>null</code>.
|
||||
* @param supportsStandardStreamMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether a stream metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeStreamMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeStreamMetadataFormatName</code>.
|
||||
* @param nativeStreamMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeStreamMetadataFormat</code>.
|
||||
* @param extraStreamMetadataFormatNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be returned from
|
||||
* <code>getExtraStreamMetadataFormatNames</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param extraStreamMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getStreamMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param supportsStandardImageMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether an image metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeImageMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeImageMetadataFormatName</code>.
|
||||
* @param nativeImageMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeImageMetadataFormat</code>.
|
||||
* @param extraImageMetadataFormatNames an array of
|
||||
* <code>String</code>s to be returned from
|
||||
* <code>getExtraImageMetadataFormatNames</code>. An array of length 0
|
||||
* is normalized to <code>null</code>.
|
||||
* @param extraImageMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getImageMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>names</code>
|
||||
* is <code>null</code> or has length 0.
|
||||
* @exception IllegalArgumentException if <code>readerClassName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>inputTypes</code>
|
||||
* is <code>null</code> or has length 0.
|
||||
*/
|
||||
public ImageReaderSpi(String vendorName,
|
||||
String version,
|
||||
String[] names,
|
||||
String[] suffixes,
|
||||
String[] MIMETypes,
|
||||
String readerClassName,
|
||||
Class[] inputTypes,
|
||||
String[] writerSpiNames,
|
||||
boolean supportsStandardStreamMetadataFormat,
|
||||
String nativeStreamMetadataFormatName,
|
||||
String nativeStreamMetadataFormatClassName,
|
||||
String[] extraStreamMetadataFormatNames,
|
||||
String[] extraStreamMetadataFormatClassNames,
|
||||
boolean supportsStandardImageMetadataFormat,
|
||||
String nativeImageMetadataFormatName,
|
||||
String nativeImageMetadataFormatClassName,
|
||||
String[] extraImageMetadataFormatNames,
|
||||
String[] extraImageMetadataFormatClassNames) {
|
||||
super(vendorName, version,
|
||||
names, suffixes, MIMETypes, readerClassName,
|
||||
supportsStandardStreamMetadataFormat,
|
||||
nativeStreamMetadataFormatName,
|
||||
nativeStreamMetadataFormatClassName,
|
||||
extraStreamMetadataFormatNames,
|
||||
extraStreamMetadataFormatClassNames,
|
||||
supportsStandardImageMetadataFormat,
|
||||
nativeImageMetadataFormatName,
|
||||
nativeImageMetadataFormatClassName,
|
||||
extraImageMetadataFormatNames,
|
||||
extraImageMetadataFormatClassNames);
|
||||
|
||||
if (inputTypes == null) {
|
||||
throw new IllegalArgumentException
|
||||
("inputTypes == null!");
|
||||
}
|
||||
if (inputTypes.length == 0) {
|
||||
throw new IllegalArgumentException
|
||||
("inputTypes.length == 0!");
|
||||
}
|
||||
|
||||
this.inputTypes = (inputTypes == STANDARD_INPUT_TYPE) ?
|
||||
new Class<?>[] { ImageInputStream.class } :
|
||||
inputTypes.clone();
|
||||
|
||||
// If length == 0, leave it null
|
||||
if (writerSpiNames != null && writerSpiNames.length > 0) {
|
||||
this.writerSpiNames = (String[])writerSpiNames.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Class</code> objects indicating what
|
||||
* types of objects may be used as arguments to the reader's
|
||||
* <code>setInput</code> method.
|
||||
*
|
||||
* <p> For most readers, which only accept input from an
|
||||
* <code>ImageInputStream</code>, a single-element array
|
||||
* containing <code>ImageInputStream.class</code> should be
|
||||
* returned.
|
||||
*
|
||||
* @return a non-<code>null</code> array of
|
||||
* <code>Class</code>objects of length at least 1.
|
||||
*/
|
||||
public Class[] getInputTypes() {
|
||||
return (Class[])inputTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the supplied source object appears
|
||||
* to be of the format supported by this reader. Returning
|
||||
* <code>true</code> from this method does not guarantee that
|
||||
* reading will succeed, only that there appears to be a
|
||||
* reasonable chance of success based on a brief inspection of the
|
||||
* stream contents. If the source is an
|
||||
* <code>ImageInputStream</code>, implementations will commonly
|
||||
* check the first several bytes of the stream for a "magic
|
||||
* number" associated with the format. Once actual reading has
|
||||
* commenced, the reader may still indicate failure at any time
|
||||
* prior to the completion of decoding.
|
||||
*
|
||||
* <p> It is important that the state of the object not be
|
||||
* disturbed in order that other <code>ImageReaderSpi</code>s can
|
||||
* properly determine whether they are able to decode the object.
|
||||
* In particular, if the source is an
|
||||
* <code>ImageInputStream</code>, a
|
||||
* <code>mark</code>/<code>reset</code> pair should be used to
|
||||
* preserve the stream position.
|
||||
*
|
||||
* <p> Formats such as "raw," which can potentially attempt
|
||||
* to read nearly any stream, should return <code>false</code>
|
||||
* in order to avoid being invoked in preference to a closer
|
||||
* match.
|
||||
*
|
||||
* <p> If <code>source</code> is not an instance of one of the
|
||||
* classes returned by <code>getInputTypes</code>, the method
|
||||
* should simply return <code>false</code>.
|
||||
*
|
||||
* @param source the object (typically an
|
||||
* <code>ImageInputStream</code>) to be decoded.
|
||||
*
|
||||
* @return <code>true</code> if it is likely that this stream can
|
||||
* be decoded.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>source</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs while reading the
|
||||
* stream.
|
||||
*/
|
||||
public abstract boolean canDecodeInput(Object source) throws IOException;
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageReader</code>
|
||||
* implementation associated with this service provider.
|
||||
* The returned object will initially be in an initial state
|
||||
* as if its <code>reset</code> method had been called.
|
||||
*
|
||||
* <p> The default implementation simply returns
|
||||
* <code>createReaderInstance(null)</code>.
|
||||
*
|
||||
* @return an <code>ImageReader</code> instance.
|
||||
*
|
||||
* @exception IOException if an error occurs during loading,
|
||||
* or initialization of the reader class, or during instantiation
|
||||
* or initialization of the reader object.
|
||||
*/
|
||||
public ImageReader createReaderInstance() throws IOException {
|
||||
return createReaderInstance(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageReader</code>
|
||||
* implementation associated with this service provider.
|
||||
* The returned object will initially be in an initial state
|
||||
* as if its <code>reset</code> method had been called.
|
||||
*
|
||||
* <p> An <code>Object</code> may be supplied to the plug-in at
|
||||
* construction time. The nature of the object is entirely
|
||||
* plug-in specific.
|
||||
*
|
||||
* <p> Typically, a plug-in will implement this method using code
|
||||
* such as <code>return new MyImageReader(this)</code>.
|
||||
*
|
||||
* @param extension a plug-in specific extension object, which may
|
||||
* be <code>null</code>.
|
||||
*
|
||||
* @return an <code>ImageReader</code> instance.
|
||||
*
|
||||
* @exception IOException if the attempt to instantiate
|
||||
* the reader fails.
|
||||
* @exception IllegalArgumentException if the
|
||||
* <code>ImageReader</code>'s constructor throws an
|
||||
* <code>IllegalArgumentException</code> to indicate that the
|
||||
* extension object is unsuitable.
|
||||
*/
|
||||
public abstract ImageReader createReaderInstance(Object extension)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageReader</code> object
|
||||
* passed in is an instance of the <code>ImageReader</code>
|
||||
* associated with this service provider.
|
||||
*
|
||||
* <p> The default implementation compares the fully-qualified
|
||||
* class name of the <code>reader</code> argument with the class
|
||||
* name passed into the constructor. This method may be overridden
|
||||
* if more sophisticated checking is required.
|
||||
*
|
||||
* @param reader an <code>ImageReader</code> instance.
|
||||
*
|
||||
* @return <code>true</code> if <code>reader</code> is recognized.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>reader</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public boolean isOwnReader(ImageReader reader) {
|
||||
if (reader == null) {
|
||||
throw new IllegalArgumentException("reader == null!");
|
||||
}
|
||||
String name = reader.getClass().getName();
|
||||
return name.equals(pluginClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the fully
|
||||
* qualified names of all the <code>ImageWriterSpi</code> classes
|
||||
* that can understand the internal metadata representation used
|
||||
* by the <code>ImageReader</code> associated with this service
|
||||
* provider, or <code>null</code> if there are no such
|
||||
* <code>ImageWriter</code>s specified. If a
|
||||
* non-<code>null</code> value is returned, it must have non-zero
|
||||
* length.
|
||||
*
|
||||
* <p> The first item in the array must be the name of the service
|
||||
* provider for the "preferred" writer, as it will be used to
|
||||
* instantiate the <code>ImageWriter</code> returned by
|
||||
* <code>ImageIO.getImageWriter(ImageReader)</code>.
|
||||
*
|
||||
* <p> This mechanism may be used to obtain
|
||||
* <code>ImageWriters</code> that will understand the internal
|
||||
* structure of non-pixel meta-data (see
|
||||
* <code>IIOTreeInfo</code>) generated by an
|
||||
* <code>ImageReader</code>. By obtaining this data from the
|
||||
* <code>ImageReader</code> and passing it on to one of the
|
||||
* <code>ImageWriters</code> obtained with this method, a client
|
||||
* program can read an image, modify it in some way, and write it
|
||||
* back out while preserving all meta-data, without having to
|
||||
* understand anything about the internal structure of the
|
||||
* meta-data, or even about the image format.
|
||||
*
|
||||
* @return an array of <code>String</code>s of length at least 1
|
||||
* containing names of <code>ImageWriterSpi</code>, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see javax.imageio.ImageIO#getImageWriter(ImageReader)
|
||||
*/
|
||||
public String[] getImageWriterSpiNames() {
|
||||
return writerSpiNames == null ?
|
||||
null : (String[])writerSpiNames.clone();
|
||||
}
|
||||
}
|
||||
601
jdkSrc/jdk8/javax/imageio/spi/ImageReaderWriterSpi.java
Normal file
601
jdkSrc/jdk8/javax/imageio/spi/ImageReaderWriterSpi.java
Normal file
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
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
|
||||
* <code>ImageReaderSpi</code> and <code>ImageWriterSpi</code>.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see ImageReaderSpi
|
||||
* @see ImageWriterSpi
|
||||
*
|
||||
*/
|
||||
public abstract class ImageReaderWriterSpi extends IIOServiceProvider {
|
||||
|
||||
/**
|
||||
* An array of strings to be returned from
|
||||
* <code>getFormatNames</code>, initially <code>null</code>.
|
||||
* Constructors should set this to a non-<code>null</code> value.
|
||||
*/
|
||||
protected String[] names = null;
|
||||
|
||||
/**
|
||||
* An array of strings to be returned from
|
||||
* <code>getFileSuffixes</code>, initially <code>null</code>.
|
||||
*/
|
||||
protected String[] suffixes = null;
|
||||
|
||||
/**
|
||||
* An array of strings to be returned from
|
||||
* <code>getMIMETypes</code>, initially <code>null</code>.
|
||||
*/
|
||||
protected String[] MIMETypes = null;
|
||||
|
||||
/**
|
||||
* A <code>String</code> containing the name of the associated
|
||||
* plug-in class, initially <code>null</code>.
|
||||
*/
|
||||
protected String pluginClassName = null;
|
||||
|
||||
/**
|
||||
* A boolean indicating whether this plug-in supports the
|
||||
* standard metadata format for stream metadata, initially
|
||||
* <code>false</code>.
|
||||
*/
|
||||
protected boolean supportsStandardStreamMetadataFormat = false;
|
||||
|
||||
/**
|
||||
* A <code>String</code> containing the name of the native stream
|
||||
* metadata format supported by this plug-in, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
protected String nativeStreamMetadataFormatName = null;
|
||||
|
||||
/**
|
||||
* A <code>String</code> containing the class name of the native
|
||||
* stream metadata format supported by this plug-in, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
protected String nativeStreamMetadataFormatClassName = null;
|
||||
|
||||
/**
|
||||
* An array of <code>String</code>s containing the names of any
|
||||
* additional stream metadata formats supported by this plug-in,
|
||||
* initially <code>null</code>.
|
||||
*/
|
||||
protected String[] extraStreamMetadataFormatNames = null;
|
||||
|
||||
/**
|
||||
* An array of <code>String</code>s containing the class names of
|
||||
* any additional stream metadata formats supported by this plug-in,
|
||||
* initially <code>null</code>.
|
||||
*/
|
||||
protected String[] extraStreamMetadataFormatClassNames = null;
|
||||
|
||||
/**
|
||||
* A boolean indicating whether this plug-in supports the
|
||||
* standard metadata format for image metadata, initially
|
||||
* <code>false</code>.
|
||||
*/
|
||||
protected boolean supportsStandardImageMetadataFormat = false;
|
||||
|
||||
/**
|
||||
* A <code>String</code> containing the name of the
|
||||
* native stream metadata format supported by this plug-in,
|
||||
* initially <code>null</code>.
|
||||
*/
|
||||
protected String nativeImageMetadataFormatName = null;
|
||||
|
||||
/**
|
||||
* A <code>String</code> containing the class name of the
|
||||
* native stream metadata format supported by this plug-in,
|
||||
* initially <code>null</code>.
|
||||
*/
|
||||
protected String nativeImageMetadataFormatClassName = null;
|
||||
|
||||
/**
|
||||
* An array of <code>String</code>s containing the names of any
|
||||
* additional image metadata formats supported by this plug-in,
|
||||
* initially <code>null</code>.
|
||||
*/
|
||||
protected String[] extraImageMetadataFormatNames = null;
|
||||
|
||||
/**
|
||||
* An array of <code>String</code>s containing the class names of
|
||||
* any additional image metadata formats supported by this
|
||||
* plug-in, initially <code>null</code>.
|
||||
*/
|
||||
protected String[] extraImageMetadataFormatClassNames = null;
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageReaderWriterSpi</code> with a given
|
||||
* set of values.
|
||||
*
|
||||
* @param vendorName the vendor name, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param version a version identifier, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param names a non-<code>null</code> array of
|
||||
* <code>String</code>s indicating the format names. At least one
|
||||
* entry must be present.
|
||||
* @param suffixes an array of <code>String</code>s indicating the
|
||||
* common file suffixes. If no suffixes are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param MIMETypes an array of <code>String</code>s indicating
|
||||
* the format's MIME types. If no MIME types are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param pluginClassName the fully-qualified name of the
|
||||
* associated <code>ImageReader</code> or <code>ImageWriter</code>
|
||||
* class, as a non-<code>null</code> <code>String</code>.
|
||||
* @param supportsStandardStreamMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether a stream metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeStreamMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeStreamMetadataFormatName</code>.
|
||||
* @param nativeStreamMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeStreamMetadataFormat</code>.
|
||||
* @param extraStreamMetadataFormatNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be returned from
|
||||
* <code>getExtraStreamMetadataFormatNames</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param extraStreamMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getStreamMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param supportsStandardImageMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether an image metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeImageMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeImageMetadataFormatName</code>.
|
||||
* @param nativeImageMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeImageMetadataFormat</code>.
|
||||
* @param extraImageMetadataFormatNames an array of
|
||||
* <code>String</code>s to be returned from
|
||||
* <code>getExtraImageMetadataFormatNames</code>. An array of length 0
|
||||
* is normalized to <code>null</code>.
|
||||
* @param extraImageMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getImageMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>names</code>
|
||||
* is <code>null</code> or has length 0.
|
||||
* @exception IllegalArgumentException if <code>pluginClassName</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
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 <code>ImageReaderWriterSpi</code>. 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 <code>String</code>s containing
|
||||
* human-readable names for the formats that are generally usable
|
||||
* by the <code>ImageReader</code> or <code>ImageWriter</code>
|
||||
* implementation associated with this service provider. For
|
||||
* example, a single <code>ImageReader</code> might be able to
|
||||
* process both PBM and PNM files.
|
||||
*
|
||||
* @return a non-<code>null</code> array of <code>String</code>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 <code>String</code>s containing a list of
|
||||
* file suffixes associated with the formats that are generally
|
||||
* usable by the <code>ImageReader</code> or
|
||||
* <code>ImageWriter</code> implementation associated with this
|
||||
* service provider. For example, a single
|
||||
* <code>ImageReader</code> might be able to process files with
|
||||
* '.pbm' and '.pnm' suffixes, or both '.jpg' and '.jpeg'
|
||||
* suffixes. If there are no known file suffixes,
|
||||
* <code>null</code> will be returned.
|
||||
*
|
||||
* <p> 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 <code>String</code>s or length at least 1
|
||||
* containing common file suffixes associated with this reader or
|
||||
* writer, or <code>null</code>.
|
||||
*/
|
||||
public String[] getFileSuffixes() {
|
||||
return suffixes == null ? null : (String[])suffixes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing a list of
|
||||
* MIME types associated with the formats that are generally
|
||||
* usable by the <code>ImageReader</code> or
|
||||
* <code>ImageWriter</code> implementation associated with this
|
||||
* service provider.
|
||||
*
|
||||
* <p> 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 <code>image/x-pbm</code> and
|
||||
* <code>image/x-portable-bitmap</code>. Some file formats have
|
||||
* official MIME types but may sometimes be referred to using
|
||||
* their previous unofficial designations, such as
|
||||
* <code>image/x-png</code> instead of the official
|
||||
* <code>image/png</code>. Finally, a single service provider may
|
||||
* be capable of parsing multiple distinct types from the MIME
|
||||
* point of view, for example <code>image/x-xbitmap</code> and
|
||||
* <code>image/x-xpixmap</code>.
|
||||
*
|
||||
* <p> 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 <code>String</code>s or length at least 1
|
||||
* containing MIME types associated with this reader or writer, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public String[] getMIMETypes() {
|
||||
return MIMETypes == null ? null : (String[])MIMETypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully-qualified class name of the
|
||||
* <code>ImageReader</code> or <code>ImageWriter</code> plug-in
|
||||
* associated with this service provider.
|
||||
*
|
||||
* @return the class name, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
*/
|
||||
public String getPluginClassName() {
|
||||
return pluginClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the standard metadata format is
|
||||
* among the document formats recognized by the
|
||||
* <code>getAsTree</code> and <code>setFromTree</code> methods on
|
||||
* the stream metadata objects produced or consumed by this
|
||||
* plug-in.
|
||||
*
|
||||
* @return <code>true</code> 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,
|
||||
* <code>null</code>will be returned.
|
||||
*
|
||||
* <p> The default implementation returns the
|
||||
* <code>nativeStreamMetadataFormatName</code> instance variable,
|
||||
* which is typically set by the constructor.
|
||||
*
|
||||
* @return the name of the native stream metadata format, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
*/
|
||||
public String getNativeStreamMetadataFormatName() {
|
||||
return nativeStreamMetadataFormatName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the names
|
||||
* of additional document formats, other than the native and
|
||||
* standard formats, recognized by the
|
||||
* <code>getAsTree</code> and <code>setFromTree</code> methods on
|
||||
* the stream metadata objects produced or consumed by this
|
||||
* plug-in.
|
||||
*
|
||||
* <p> If the plug-in does not handle metadata, null should be
|
||||
* returned.
|
||||
*
|
||||
* <p> 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.
|
||||
*
|
||||
* <p> The default implementation returns a clone of the
|
||||
* <code>extraStreamMetadataFormatNames</code> instance variable,
|
||||
* which is typically set by the constructor.
|
||||
*
|
||||
* @return an array of <code>String</code>s, or null.
|
||||
*
|
||||
* @see IIOMetadata#getMetadataFormatNames
|
||||
* @see #getExtraImageMetadataFormatNames
|
||||
* @see #getNativeStreamMetadataFormatName
|
||||
*/
|
||||
public String[] getExtraStreamMetadataFormatNames() {
|
||||
return extraStreamMetadataFormatNames == null ?
|
||||
null : (String[])extraStreamMetadataFormatNames.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the standard metadata format is
|
||||
* among the document formats recognized by the
|
||||
* <code>getAsTree</code> and <code>setFromTree</code> methods on
|
||||
* the image metadata objects produced or consumed by this
|
||||
* plug-in.
|
||||
*
|
||||
* @return <code>true</code> 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,
|
||||
* <code>null</code>will be returned.
|
||||
*
|
||||
* <p> The default implementation returns the
|
||||
* <code>nativeImageMetadataFormatName</code> instance variable,
|
||||
* which is typically set by the constructor.
|
||||
*
|
||||
* @return the name of the native image metadata format, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see #getExtraImageMetadataFormatNames
|
||||
*/
|
||||
public String getNativeImageMetadataFormatName() {
|
||||
return nativeImageMetadataFormatName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing the names
|
||||
* of additional document formats, other than the native and
|
||||
* standard formats, recognized by the
|
||||
* <code>getAsTree</code> and <code>setFromTree</code> methods on
|
||||
* the image metadata objects produced or consumed by this
|
||||
* plug-in.
|
||||
*
|
||||
* <p> If the plug-in does not handle image metadata, null should
|
||||
* be returned.
|
||||
*
|
||||
* <p> 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.
|
||||
*
|
||||
* <p> The default implementation returns a clone of the
|
||||
* <code>extraImageMetadataFormatNames</code> instance variable,
|
||||
* which is typically set by the constructor.
|
||||
*
|
||||
* @return an array of <code>String</code>s, or null.
|
||||
*
|
||||
* @see IIOMetadata#getMetadataFormatNames
|
||||
* @see #getExtraStreamMetadataFormatNames
|
||||
* @see #getNativeImageMetadataFormatName
|
||||
*/
|
||||
public String[] getExtraImageMetadataFormatNames() {
|
||||
return extraImageMetadataFormatNames == null ?
|
||||
null : (String[])extraImageMetadataFormatNames.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataFormat</code> object describing the
|
||||
* given stream metadata format, or <code>null</code> 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
|
||||
* <code>getExtraStreamMetadataFormatNames</code>.
|
||||
*
|
||||
* @param formatName the desired stream metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataFormat</code> object.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> or is not a supported name.
|
||||
*/
|
||||
public IIOMetadataFormat getStreamMetadataFormat(String formatName) {
|
||||
return getMetadataFormat(formatName,
|
||||
supportsStandardStreamMetadataFormat,
|
||||
nativeStreamMetadataFormatName,
|
||||
nativeStreamMetadataFormatClassName,
|
||||
extraStreamMetadataFormatNames,
|
||||
extraStreamMetadataFormatClassNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>IIOMetadataFormat</code> object describing the
|
||||
* given image metadata format, or <code>null</code> if no
|
||||
* description is available. The supplied name must be the native
|
||||
* image metadata format name, the standard metadata format name,
|
||||
* or one of those returned by
|
||||
* <code>getExtraImageMetadataFormatNames</code>.
|
||||
*
|
||||
* @param formatName the desired image metadata format.
|
||||
*
|
||||
* @return an <code>IIOMetadataFormat</code> object.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>formatName</code>
|
||||
* is <code>null</code> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
95
jdkSrc/jdk8/javax/imageio/spi/ImageTranscoderSpi.java
Normal file
95
jdkSrc/jdk8/javax/imageio/spi/ImageTranscoderSpi.java
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import javax.imageio.ImageTranscoder;
|
||||
|
||||
/**
|
||||
* The service provider interface (SPI) for <code>ImageTranscoder</code>s.
|
||||
* For more information on service provider classes, see the class comment
|
||||
* for the <code>IIORegistry</code> class.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.ImageTranscoder
|
||||
*
|
||||
*/
|
||||
public abstract class ImageTranscoderSpi extends IIOServiceProvider {
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>ImageTranscoderSpi</code>. It is up
|
||||
* to the subclass to initialize instance variables and/or
|
||||
* override method implementations in order to provide working
|
||||
* versions of all methods.
|
||||
*/
|
||||
protected ImageTranscoderSpi() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageTranscoderSpi</code> with a given set
|
||||
* of values.
|
||||
*
|
||||
* @param vendorName the vendor name.
|
||||
* @param version a version identifier.
|
||||
*/
|
||||
public ImageTranscoderSpi(String vendorName,
|
||||
String version) {
|
||||
super(vendorName, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the fully qualified class name of an
|
||||
* <code>ImageReaderSpi</code> class that generates
|
||||
* <code>IIOMetadata</code> objects that may be used as input to
|
||||
* this transcoder.
|
||||
*
|
||||
* @return a <code>String</code> containing the fully-qualified
|
||||
* class name of the <code>ImageReaderSpi</code> implementation class.
|
||||
*
|
||||
* @see ImageReaderSpi
|
||||
*/
|
||||
public abstract String getReaderServiceProviderName();
|
||||
|
||||
/**
|
||||
* Returns the fully qualified class name of an
|
||||
* <code>ImageWriterSpi</code> class that generates
|
||||
* <code>IIOMetadata</code> objects that may be used as input to
|
||||
* this transcoder.
|
||||
*
|
||||
* @return a <code>String</code> containing the fully-qualified
|
||||
* class name of the <code>ImageWriterSpi</code> implementation class.
|
||||
*
|
||||
* @see ImageWriterSpi
|
||||
*/
|
||||
public abstract String getWriterServiceProviderName();
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageTranscoder</code>
|
||||
* implementation associated with this service provider.
|
||||
*
|
||||
* @return an <code>ImageTranscoder</code> instance.
|
||||
*/
|
||||
public abstract ImageTranscoder createTranscoderInstance();
|
||||
}
|
||||
440
jdkSrc/jdk8/javax/imageio/spi/ImageWriterSpi.java
Normal file
440
jdkSrc/jdk8/javax/imageio/spi/ImageWriterSpi.java
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
|
||||
/**
|
||||
* The service provider interface (SPI) for <code>ImageWriter</code>s.
|
||||
* For more information on service provider classes, see the class comment
|
||||
* for the <code>IIORegistry</code> class.
|
||||
*
|
||||
* <p> Each <code>ImageWriterSpi</code> provides several types of information
|
||||
* about the <code>ImageWriter</code> class with which it is associated.
|
||||
*
|
||||
* <p> The name of the vendor who defined the SPI class and a
|
||||
* brief description of the class are available via the
|
||||
* <code>getVendorName</code>, <code>getDescription</code>,
|
||||
* and <code>getVersion</code> methods.
|
||||
* These methods may be internationalized to provide locale-specific
|
||||
* output. These methods are intended mainly to provide short,
|
||||
* human-writable information that might be used to organize a pop-up
|
||||
* menu or other list.
|
||||
*
|
||||
* <p> Lists of format names, file suffixes, and MIME types associated
|
||||
* with the service may be obtained by means of the
|
||||
* <code>getFormatNames</code>, <code>getFileSuffixes</code>, and
|
||||
* <code>getMIMEType</code> methods. These methods may be used to
|
||||
* identify candidate <code>ImageWriter</code>s for writing a
|
||||
* particular file or stream based on manual format selection, file
|
||||
* naming, or MIME associations.
|
||||
*
|
||||
* <p> A more reliable way to determine which <code>ImageWriter</code>s
|
||||
* are likely to be able to parse a particular data stream is provided
|
||||
* by the <code>canEncodeImage</code> method. This methods allows the
|
||||
* service provider to inspect the actual image contents.
|
||||
*
|
||||
* <p> Finally, an instance of the <code>ImageWriter</code> class
|
||||
* associated with this service provider may be obtained by calling
|
||||
* the <code>createWriterInstance</code> method. Any heavyweight
|
||||
* initialization, such as the loading of native libraries or creation
|
||||
* of large tables, should be deferred at least until the first
|
||||
* invocation of this method.
|
||||
*
|
||||
* @see IIORegistry
|
||||
* @see javax.imageio.ImageTypeSpecifier
|
||||
* @see javax.imageio.ImageWriter
|
||||
*
|
||||
*/
|
||||
public abstract class ImageWriterSpi extends ImageReaderWriterSpi {
|
||||
|
||||
/**
|
||||
* A single-element array, initially containing
|
||||
* <code>ImageOutputStream.class</code>, to be returned from
|
||||
* <code>getOutputTypes</code>.
|
||||
* @deprecated Instead of using this field, directly create
|
||||
* the equivalent array <code>{ ImageOutputStream.class }</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final Class[] STANDARD_OUTPUT_TYPE =
|
||||
{ ImageOutputStream.class };
|
||||
|
||||
/**
|
||||
* An array of <code>Class</code> objects to be returned from
|
||||
* <code>getOutputTypes</code>, initially <code>null</code>.
|
||||
*/
|
||||
protected Class[] outputTypes = null;
|
||||
|
||||
/**
|
||||
* An array of strings to be returned from
|
||||
* <code>getImageReaderSpiNames</code>, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
protected String[] readerSpiNames = null;
|
||||
|
||||
/**
|
||||
* The <code>Class</code> of the writer, initially
|
||||
* <code>null</code>.
|
||||
*/
|
||||
private Class writerClass = null;
|
||||
|
||||
/**
|
||||
* Constructs a blank <code>ImageWriterSpi</code>. It is up to
|
||||
* the subclass to initialize instance variables and/or override
|
||||
* method implementations in order to provide working versions of
|
||||
* all methods.
|
||||
*/
|
||||
protected ImageWriterSpi() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageWriterSpi</code> with a given
|
||||
* set of values.
|
||||
*
|
||||
* @param vendorName the vendor name, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param version a version identifier, as a non-<code>null</code>
|
||||
* <code>String</code>.
|
||||
* @param names a non-<code>null</code> array of
|
||||
* <code>String</code>s indicating the format names. At least one
|
||||
* entry must be present.
|
||||
* @param suffixes an array of <code>String</code>s indicating the
|
||||
* common file suffixes. If no suffixes are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param MIMETypes an array of <code>String</code>s indicating
|
||||
* the format's MIME types. If no suffixes are defined,
|
||||
* <code>null</code> should be supplied. An array of length 0
|
||||
* will be normalized to <code>null</code>.
|
||||
* @param writerClassName the fully-qualified name of the
|
||||
* associated <code>ImageWriterSpi</code> class, as a
|
||||
* non-<code>null</code> <code>String</code>.
|
||||
* @param outputTypes an array of <code>Class</code> objects of
|
||||
* length at least 1 indicating the legal output types.
|
||||
* @param readerSpiNames an array <code>String</code>s of length
|
||||
* at least 1 naming the classes of all associated
|
||||
* <code>ImageReader</code>s, or <code>null</code>. An array of
|
||||
* length 0 is normalized to <code>null</code>.
|
||||
* @param supportsStandardStreamMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether a stream metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeStreamMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeStreamMetadataFormatName</code>.
|
||||
* @param nativeStreamMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeStreamMetadataFormat</code>.
|
||||
* @param extraStreamMetadataFormatNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be returned from
|
||||
* <code>getExtraStreamMetadataFormatNames</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param extraStreamMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getStreamMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
* @param supportsStandardImageMetadataFormat a
|
||||
* <code>boolean</code> that indicates whether an image metadata
|
||||
* object can use trees described by the standard metadata format.
|
||||
* @param nativeImageMetadataFormatName a
|
||||
* <code>String</code>, or <code>null</code>, to be returned from
|
||||
* <code>getNativeImageMetadataFormatName</code>.
|
||||
* @param nativeImageMetadataFormatClassName a
|
||||
* <code>String</code>, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getNativeImageMetadataFormat</code>.
|
||||
* @param extraImageMetadataFormatNames an array of
|
||||
* <code>String</code>s to be returned from
|
||||
* <code>getExtraImageMetadataFormatNames</code>. An array of length 0
|
||||
* is normalized to <code>null</code>.
|
||||
* @param extraImageMetadataFormatClassNames an array of
|
||||
* <code>String</code>s, or <code>null</code>, to be used to instantiate
|
||||
* a metadata format object to be returned from
|
||||
* <code>getImageMetadataFormat</code>. An array of length
|
||||
* 0 is normalized to <code>null</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>vendorName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>version</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>names</code>
|
||||
* is <code>null</code> or has length 0.
|
||||
* @exception IllegalArgumentException if <code>writerClassName</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>outputTypes</code>
|
||||
* is <code>null</code> or has length 0.
|
||||
*/
|
||||
public ImageWriterSpi(String vendorName,
|
||||
String version,
|
||||
String[] names,
|
||||
String[] suffixes,
|
||||
String[] MIMETypes,
|
||||
String writerClassName,
|
||||
Class[] outputTypes,
|
||||
String[] readerSpiNames,
|
||||
boolean supportsStandardStreamMetadataFormat,
|
||||
String nativeStreamMetadataFormatName,
|
||||
String nativeStreamMetadataFormatClassName,
|
||||
String[] extraStreamMetadataFormatNames,
|
||||
String[] extraStreamMetadataFormatClassNames,
|
||||
boolean supportsStandardImageMetadataFormat,
|
||||
String nativeImageMetadataFormatName,
|
||||
String nativeImageMetadataFormatClassName,
|
||||
String[] extraImageMetadataFormatNames,
|
||||
String[] extraImageMetadataFormatClassNames) {
|
||||
super(vendorName, version,
|
||||
names, suffixes, MIMETypes, writerClassName,
|
||||
supportsStandardStreamMetadataFormat,
|
||||
nativeStreamMetadataFormatName,
|
||||
nativeStreamMetadataFormatClassName,
|
||||
extraStreamMetadataFormatNames,
|
||||
extraStreamMetadataFormatClassNames,
|
||||
supportsStandardImageMetadataFormat,
|
||||
nativeImageMetadataFormatName,
|
||||
nativeImageMetadataFormatClassName,
|
||||
extraImageMetadataFormatNames,
|
||||
extraImageMetadataFormatClassNames);
|
||||
|
||||
if (outputTypes == null) {
|
||||
throw new IllegalArgumentException
|
||||
("outputTypes == null!");
|
||||
}
|
||||
if (outputTypes.length == 0) {
|
||||
throw new IllegalArgumentException
|
||||
("outputTypes.length == 0!");
|
||||
}
|
||||
|
||||
this.outputTypes = (outputTypes == STANDARD_OUTPUT_TYPE) ?
|
||||
new Class<?>[] { ImageOutputStream.class } :
|
||||
outputTypes.clone();
|
||||
|
||||
// If length == 0, leave it null
|
||||
if (readerSpiNames != null && readerSpiNames.length > 0) {
|
||||
this.readerSpiNames = (String[])readerSpiNames.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the format that this writer
|
||||
* outputs preserves pixel data bit-accurately. The default
|
||||
* implementation returns <code>true</code>.
|
||||
*
|
||||
* @return <code>true</code> if the format preserves full pixel
|
||||
* accuracy.
|
||||
*/
|
||||
public boolean isFormatLossless() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>Class</code> objects indicating what
|
||||
* types of objects may be used as arguments to the writer's
|
||||
* <code>setOutput</code> method.
|
||||
*
|
||||
* <p> For most writers, which only output to an
|
||||
* <code>ImageOutputStream</code>, a single-element array
|
||||
* containing <code>ImageOutputStream.class</code> should be
|
||||
* returned.
|
||||
*
|
||||
* @return a non-<code>null</code> array of
|
||||
* <code>Class</code>objects of length at least 1.
|
||||
*/
|
||||
public Class[] getOutputTypes() {
|
||||
return (Class[])outputTypes.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageWriter</code>
|
||||
* implementation associated with this service provider is able to
|
||||
* encode an image with the given layout. The layout
|
||||
* (<i>i.e.</i>, the image's <code>SampleModel</code> and
|
||||
* <code>ColorModel</code>) is described by an
|
||||
* <code>ImageTypeSpecifier</code> object.
|
||||
*
|
||||
* <p> A return value of <code>true</code> is not an absolute
|
||||
* guarantee of successful encoding; the encoding process may still
|
||||
* produce errors due to factors such as I/O errors, inconsistent
|
||||
* or malformed data structures, etc. The intent is that a
|
||||
* reasonable inspection of the basic structure of the image be
|
||||
* performed in order to determine if it is within the scope of
|
||||
* the encoding format. For example, a service provider for a
|
||||
* format that can only encode greyscale would return
|
||||
* <code>false</code> if handed an RGB <code>BufferedImage</code>.
|
||||
* Similarly, a service provider for a format that can encode
|
||||
* 8-bit RGB imagery might refuse to encode an image with an
|
||||
* associated alpha channel.
|
||||
*
|
||||
* <p> Different <code>ImageWriter</code>s, and thus service
|
||||
* providers, may choose to be more or less strict. For example,
|
||||
* they might accept an image with premultiplied alpha even though
|
||||
* it will have to be divided out of each pixel, at some loss of
|
||||
* precision, in order to be stored.
|
||||
*
|
||||
* @param type an <code>ImageTypeSpecifier</code> specifying the
|
||||
* layout of the image to be written.
|
||||
*
|
||||
* @return <code>true</code> if this writer is likely to be able
|
||||
* to encode images with the given layout.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>type</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public abstract boolean canEncodeImage(ImageTypeSpecifier type);
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageWriter</code>
|
||||
* implementation associated with this service provider is able to
|
||||
* encode the given <code>RenderedImage</code> instance. Note
|
||||
* that this includes instances of
|
||||
* <code>java.awt.image.BufferedImage</code>.
|
||||
*
|
||||
* <p> See the discussion for
|
||||
* <code>canEncodeImage(ImageTypeSpecifier)</code> for information
|
||||
* on the semantics of this method.
|
||||
*
|
||||
* @param im an instance of <code>RenderedImage</code> to be encoded.
|
||||
*
|
||||
* @return <code>true</code> if this writer is likely to be able
|
||||
* to encode this image.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>im</code>
|
||||
* is <code>null</code>.
|
||||
*/
|
||||
public boolean canEncodeImage(RenderedImage im) {
|
||||
return canEncodeImage(ImageTypeSpecifier.createFromRenderedImage(im));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageWriter</code>
|
||||
* implementation associated with this service provider.
|
||||
* The returned object will initially be in an initial state as if
|
||||
* its <code>reset</code> method had been called.
|
||||
*
|
||||
* <p> The default implementation simply returns
|
||||
* <code>createWriterInstance(null)</code>.
|
||||
*
|
||||
* @return an <code>ImageWriter</code> instance.
|
||||
*
|
||||
* @exception IOException if an error occurs during loading,
|
||||
* or initialization of the writer class, or during instantiation
|
||||
* or initialization of the writer object.
|
||||
*/
|
||||
public ImageWriter createWriterInstance() throws IOException {
|
||||
return createWriterInstance(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of the <code>ImageWriter</code>
|
||||
* implementation associated with this service provider.
|
||||
* The returned object will initially be in an initial state
|
||||
* as if its <code>reset</code> method had been called.
|
||||
*
|
||||
* <p> An <code>Object</code> may be supplied to the plug-in at
|
||||
* construction time. The nature of the object is entirely
|
||||
* plug-in specific.
|
||||
*
|
||||
* <p> Typically, a plug-in will implement this method using code
|
||||
* such as <code>return new MyImageWriter(this)</code>.
|
||||
*
|
||||
* @param extension a plug-in specific extension object, which may
|
||||
* be <code>null</code>.
|
||||
*
|
||||
* @return an <code>ImageWriter</code> instance.
|
||||
*
|
||||
* @exception IOException if the attempt to instantiate
|
||||
* the writer fails.
|
||||
* @exception IllegalArgumentException if the
|
||||
* <code>ImageWriter</code>'s constructor throws an
|
||||
* <code>IllegalArgumentException</code> to indicate that the
|
||||
* extension object is unsuitable.
|
||||
*/
|
||||
public abstract ImageWriter createWriterInstance(Object extension)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the <code>ImageWriter</code> object
|
||||
* passed in is an instance of the <code>ImageWriter</code>
|
||||
* associated with this service provider.
|
||||
*
|
||||
* @param writer an <code>ImageWriter</code> instance.
|
||||
*
|
||||
* @return <code>true</code> if <code>writer</code> is recognized
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>writer</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public boolean isOwnWriter(ImageWriter writer) {
|
||||
if (writer == null) {
|
||||
throw new IllegalArgumentException("writer == null!");
|
||||
}
|
||||
String name = writer.getClass().getName();
|
||||
return name.equals(pluginClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of <code>String</code>s containing all the
|
||||
* fully qualified names of all the <code>ImageReaderSpi</code>
|
||||
* classes that can understand the internal metadata
|
||||
* representation used by the <code>ImageWriter</code> associated
|
||||
* with this service provider, or <code>null</code> if there are
|
||||
* no such <code>ImageReaders</code> specified. If a
|
||||
* non-<code>null</code> value is returned, it must have non-zero
|
||||
* length.
|
||||
*
|
||||
* <p> The first item in the array must be the name of the service
|
||||
* provider for the "preferred" reader, as it will be used to
|
||||
* instantiate the <code>ImageReader</code> returned by
|
||||
* <code>ImageIO.getImageReader(ImageWriter)</code>.
|
||||
*
|
||||
* <p> This mechanism may be used to obtain
|
||||
* <code>ImageReaders</code> that will generated non-pixel
|
||||
* meta-data (see <code>IIOExtraDataInfo</code>) in a structure
|
||||
* understood by an <code>ImageWriter</code>. By reading the
|
||||
* image and obtaining this data from one of the
|
||||
* <code>ImageReaders</code> obtained with this method and passing
|
||||
* it on to the <code>ImageWriter</code>, a client program can
|
||||
* read an image, modify it in some way, and write it back out
|
||||
* preserving all meta-data, without having to understand anything
|
||||
* about the internal structure of the meta-data, or even about
|
||||
* the image format.
|
||||
*
|
||||
* @return an array of <code>String</code>s of length at least 1
|
||||
* containing names of <code>ImageReaderSpi</code>s, or
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @see javax.imageio.ImageIO#getImageReader(ImageWriter)
|
||||
* @see ImageReaderSpi#getImageWriterSpiNames()
|
||||
*/
|
||||
public String[] getImageReaderSpiNames() {
|
||||
return readerSpiNames == null ?
|
||||
null : (String[])readerSpiNames.clone();
|
||||
}
|
||||
}
|
||||
214
jdkSrc/jdk8/javax/imageio/spi/PartiallyOrderedSet.java
Normal file
214
jdkSrc/jdk8/javax/imageio/spi/PartiallyOrderedSet.java
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.util.AbstractSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A set of <code>Object</code>s with pairwise orderings between them.
|
||||
* The <code>iterator</code> method provides the elements in
|
||||
* topologically sorted order. Elements participating in a cycle
|
||||
* are not returned.
|
||||
*
|
||||
* Unlike the <code>SortedSet</code> and <code>SortedMap</code>
|
||||
* interfaces, which require their elements to implement the
|
||||
* <code>Comparable</code> interface, this class receives ordering
|
||||
* information via its <code>setOrdering</code> and
|
||||
* <code>unsetPreference</code> methods. This difference is due to
|
||||
* the fact that the relevant ordering between elements is unlikely to
|
||||
* be inherent in the elements themselves; rather, it is set
|
||||
* dynamically accoring to application policy. For example, in a
|
||||
* service provider registry situation, an application might allow the
|
||||
* user to set a preference order for service provider objects
|
||||
* supplied by a trusted vendor over those supplied by another.
|
||||
*
|
||||
*/
|
||||
class PartiallyOrderedSet extends AbstractSet {
|
||||
|
||||
// The topological sort (roughly) follows the algorithm described in
|
||||
// Horowitz and Sahni, _Fundamentals of Data Structures_ (1976),
|
||||
// p. 315.
|
||||
|
||||
// Maps Objects to DigraphNodes that contain them
|
||||
private Map poNodes = new HashMap();
|
||||
|
||||
// The set of Objects
|
||||
private Set nodes = poNodes.keySet();
|
||||
|
||||
/**
|
||||
* Constructs a <code>PartiallyOrderedSet</code>.
|
||||
*/
|
||||
public PartiallyOrderedSet() {}
|
||||
|
||||
public int size() {
|
||||
return nodes.size();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
return nodes.contains(o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the elements contained in this
|
||||
* collection, with an ordering that respects the orderings set
|
||||
* by the <code>setOrdering</code> method.
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
return new PartialOrderIterator(poNodes.values().iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an <code>Object</code> to this
|
||||
* <code>PartiallyOrderedSet</code>.
|
||||
*/
|
||||
public boolean add(Object o) {
|
||||
if (nodes.contains(o)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DigraphNode node = new DigraphNode(o);
|
||||
poNodes.put(o, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an <code>Object</code> from this
|
||||
* <code>PartiallyOrderedSet</code>.
|
||||
*/
|
||||
public boolean remove(Object o) {
|
||||
DigraphNode node = (DigraphNode)poNodes.get(o);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
poNodes.remove(o);
|
||||
node.dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
poNodes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an ordering between two nodes. When an iterator is
|
||||
* requested, the first node will appear earlier in the
|
||||
* sequence than the second node. If a prior ordering existed
|
||||
* between the nodes in the opposite order, it is removed.
|
||||
*
|
||||
* @return <code>true</code> if no prior ordering existed
|
||||
* between the nodes, <code>false</code>otherwise.
|
||||
*/
|
||||
public boolean setOrdering(Object first, Object second) {
|
||||
DigraphNode firstPONode =
|
||||
(DigraphNode)poNodes.get(first);
|
||||
DigraphNode secondPONode =
|
||||
(DigraphNode)poNodes.get(second);
|
||||
|
||||
secondPONode.removeEdge(firstPONode);
|
||||
return firstPONode.addEdge(secondPONode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any ordering between two nodes.
|
||||
*
|
||||
* @return true if a prior prefence existed between the nodes.
|
||||
*/
|
||||
public boolean unsetOrdering(Object first, Object second) {
|
||||
DigraphNode firstPONode =
|
||||
(DigraphNode)poNodes.get(first);
|
||||
DigraphNode secondPONode =
|
||||
(DigraphNode)poNodes.get(second);
|
||||
|
||||
return firstPONode.removeEdge(secondPONode) ||
|
||||
secondPONode.removeEdge(firstPONode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if an ordering exists between two
|
||||
* nodes.
|
||||
*/
|
||||
public boolean hasOrdering(Object preferred, Object other) {
|
||||
DigraphNode preferredPONode =
|
||||
(DigraphNode)poNodes.get(preferred);
|
||||
DigraphNode otherPONode =
|
||||
(DigraphNode)poNodes.get(other);
|
||||
|
||||
return preferredPONode.hasEdge(otherPONode);
|
||||
}
|
||||
}
|
||||
|
||||
class PartialOrderIterator implements Iterator {
|
||||
|
||||
LinkedList zeroList = new LinkedList();
|
||||
Map inDegrees = new HashMap(); // DigraphNode -> Integer
|
||||
|
||||
public PartialOrderIterator(Iterator iter) {
|
||||
// Initialize scratch in-degree values, zero list
|
||||
while (iter.hasNext()) {
|
||||
DigraphNode node = (DigraphNode)iter.next();
|
||||
int inDegree = node.getInDegree();
|
||||
inDegrees.put(node, new Integer(inDegree));
|
||||
|
||||
// Add nodes with zero in-degree to the zero list
|
||||
if (inDegree == 0) {
|
||||
zeroList.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return !zeroList.isEmpty();
|
||||
}
|
||||
|
||||
public Object next() {
|
||||
DigraphNode first = (DigraphNode)zeroList.removeFirst();
|
||||
|
||||
// For each out node of the output node, decrement its in-degree
|
||||
Iterator outNodes = first.getOutNodes();
|
||||
while (outNodes.hasNext()) {
|
||||
DigraphNode node = (DigraphNode)outNodes.next();
|
||||
int inDegree = ((Integer)inDegrees.get(node)).intValue() - 1;
|
||||
inDegrees.put(node, new Integer(inDegree));
|
||||
|
||||
// If the in-degree has fallen to 0, place the node on the list
|
||||
if (inDegree == 0) {
|
||||
zeroList.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
return first.getData();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
64
jdkSrc/jdk8/javax/imageio/spi/RegisterableService.java
Normal file
64
jdkSrc/jdk8/javax/imageio/spi/RegisterableService.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
/**
|
||||
* An optional interface that may be provided by service provider
|
||||
* objects that will be registered with a
|
||||
* <code>ServiceRegistry</code>. If this interface is present,
|
||||
* notification of registration and deregistration will be performed.
|
||||
*
|
||||
* @see ServiceRegistry
|
||||
*
|
||||
*/
|
||||
public interface RegisterableService {
|
||||
|
||||
/**
|
||||
* Called when an object implementing this interface is added to
|
||||
* the given <code>category</code> of the given
|
||||
* <code>registry</code>. The object may already be registered
|
||||
* under another category or categories.
|
||||
*
|
||||
* @param registry a <code>ServiceRegistry</code> where this
|
||||
* object has been registered.
|
||||
* @param category a <code>Class</code> object indicating the
|
||||
* registry category under which this object has been registered.
|
||||
*/
|
||||
void onRegistration(ServiceRegistry registry, Class<?> category);
|
||||
|
||||
/**
|
||||
* Called when an object implementing this interface is removed
|
||||
* from the given <code>category</code> of the given
|
||||
* <code>registry</code>. The object may still be registered
|
||||
* under another category or categories.
|
||||
*
|
||||
* @param registry a <code>ServiceRegistry</code> from which this
|
||||
* object is being (wholly or partially) deregistered.
|
||||
* @param category a <code>Class</code> object indicating the
|
||||
* registry category from which this object is being deregistered.
|
||||
*/
|
||||
void onDeregistration(ServiceRegistry registry, Class<?> category);
|
||||
}
|
||||
859
jdkSrc/jdk8/javax/imageio/spi/ServiceRegistry.java
Normal file
859
jdkSrc/jdk8/javax/imageio/spi/ServiceRegistry.java
Normal file
@@ -0,0 +1,859 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.spi;
|
||||
|
||||
import java.io.File;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/**
|
||||
* A registry for service provider instances.
|
||||
*
|
||||
* <p> A <i>service</i> is a well-known set of interfaces and (usually
|
||||
* abstract) classes. A <i>service provider</i> is a specific
|
||||
* implementation of a service. The classes in a provider typically
|
||||
* implement the interface or subclass the class defined by the
|
||||
* service itself.
|
||||
*
|
||||
* <p> Service providers are stored in one or more <i>categories</i>,
|
||||
* each of which is defined by a class of interface (described by a
|
||||
* <code>Class</code> object) that all of its members must implement.
|
||||
* The set of categories may be changed dynamically.
|
||||
*
|
||||
* <p> Only a single instance of a given leaf class (that is, the
|
||||
* actual class returned by <code>getClass()</code>, as opposed to any
|
||||
* inherited classes or interfaces) may be registered. That is,
|
||||
* suppose that the
|
||||
* <code>com.mycompany.mypkg.GreenServiceProvider</code> class
|
||||
* implements the <code>com.mycompany.mypkg.MyService</code>
|
||||
* interface. If a <code>GreenServiceProvider</code> instance is
|
||||
* registered, it will be stored in the category defined by the
|
||||
* <code>MyService</code> class. If a new instance of
|
||||
* <code>GreenServiceProvider</code> is registered, it will replace
|
||||
* the previous instance. In practice, service provider objects are
|
||||
* usually singletons so this behavior is appropriate.
|
||||
*
|
||||
* <p> To declare a service provider, a <code>services</code>
|
||||
* subdirectory is placed within the <code>META-INF</code> directory
|
||||
* that is present in every JAR file. This directory contains a file
|
||||
* for each service provider interface that has one or more
|
||||
* implementation classes present in the JAR file. For example, if
|
||||
* the JAR file contained a class named
|
||||
* <code>com.mycompany.mypkg.MyServiceImpl</code> which implements the
|
||||
* <code>javax.someapi.SomeService</code> interface, the JAR file
|
||||
* would contain a file named: <pre>
|
||||
* META-INF/services/javax.someapi.SomeService </pre>
|
||||
*
|
||||
* containing the line:
|
||||
*
|
||||
* <pre>
|
||||
* com.mycompany.mypkg.MyService
|
||||
* </pre>
|
||||
*
|
||||
* <p> The service provider classes should be to be lightweight and
|
||||
* quick to load. Implementations of these interfaces should avoid
|
||||
* complex dependencies on other classes and on native code. The usual
|
||||
* pattern for more complex services is to register a lightweight
|
||||
* proxy for the heavyweight service.
|
||||
*
|
||||
* <p> An application may customize the contents of a registry as it
|
||||
* sees fit, so long as it has the appropriate runtime permission.
|
||||
*
|
||||
* <p> For more details on declaring service providers, and the JAR
|
||||
* format in general, see the <a
|
||||
* href="../../../../technotes/guides/jar/jar.html">
|
||||
* JAR File Specification</a>.
|
||||
*
|
||||
* @see RegisterableService
|
||||
*
|
||||
*/
|
||||
public class ServiceRegistry {
|
||||
|
||||
// Class -> Registry
|
||||
private Map categoryMap = new HashMap();
|
||||
|
||||
/**
|
||||
* Constructs a <code>ServiceRegistry</code> instance with a
|
||||
* set of categories taken from the <code>categories</code>
|
||||
* argument.
|
||||
*
|
||||
* @param categories an <code>Iterator</code> containing
|
||||
* <code>Class</code> objects to be used to define categories.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>categories</code> is <code>null</code>.
|
||||
*/
|
||||
public ServiceRegistry(Iterator<Class<?>> categories) {
|
||||
if (categories == null) {
|
||||
throw new IllegalArgumentException("categories == null!");
|
||||
}
|
||||
while (categories.hasNext()) {
|
||||
Class category = (Class)categories.next();
|
||||
SubRegistry reg = new SubRegistry(this, category);
|
||||
categoryMap.put(category, reg);
|
||||
}
|
||||
}
|
||||
|
||||
// The following two methods expose functionality from
|
||||
// sun.misc.Service. If that class is made public, they may be
|
||||
// removed.
|
||||
//
|
||||
// The sun.misc.ServiceConfigurationError class may also be
|
||||
// exposed, in which case the references to 'an
|
||||
// <code>Error</code>' below should be changed to 'a
|
||||
// <code>ServiceConfigurationError</code>'.
|
||||
|
||||
/**
|
||||
* Searches for implementations of a particular service class
|
||||
* using the given class loader.
|
||||
*
|
||||
* <p> This method transforms the name of the given service class
|
||||
* into a provider-configuration filename as described in the
|
||||
* class comment and then uses the <code>getResources</code>
|
||||
* method of the given class loader to find all available files
|
||||
* with that name. These files are then read and parsed to
|
||||
* produce a list of provider-class names. The iterator that is
|
||||
* returned uses the given class loader to look up and then
|
||||
* instantiate each element of the list.
|
||||
*
|
||||
* <p> Because it is possible for extensions to be installed into
|
||||
* a running Java virtual machine, this method may return
|
||||
* different results each time it is invoked.
|
||||
*
|
||||
* @param providerClass a <code>Class</code>object indicating the
|
||||
* class or interface of the service providers being detected.
|
||||
*
|
||||
* @param loader the class loader to be used to load
|
||||
* provider-configuration files and instantiate provider classes,
|
||||
* or <code>null</code> if the system class loader (or, failing that
|
||||
* the bootstrap class loader) is to be used.
|
||||
*
|
||||
* @param <T> the type of the providerClass.
|
||||
*
|
||||
* @return An <code>Iterator</code> that yields provider objects
|
||||
* for the given service, in some arbitrary order. The iterator
|
||||
* will throw an <code>Error</code> if a provider-configuration
|
||||
* file violates the specified format or if a provider class
|
||||
* cannot be found and instantiated.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>providerClass</code> is <code>null</code>.
|
||||
*/
|
||||
public static <T> Iterator<T> lookupProviders(Class<T> providerClass,
|
||||
ClassLoader loader)
|
||||
{
|
||||
if (providerClass == null) {
|
||||
throw new IllegalArgumentException("providerClass == null!");
|
||||
}
|
||||
return ServiceLoader.load(providerClass, loader).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates and incrementally instantiates the available providers
|
||||
* of a given service using the context class loader. This
|
||||
* convenience method is equivalent to:
|
||||
*
|
||||
* <pre>
|
||||
* ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
* return Service.providers(service, cl);
|
||||
* </pre>
|
||||
*
|
||||
* @param providerClass a <code>Class</code>object indicating the
|
||||
* class or interface of the service providers being detected.
|
||||
*
|
||||
* @param <T> the type of the providerClass.
|
||||
*
|
||||
* @return An <code>Iterator</code> that yields provider objects
|
||||
* for the given service, in some arbitrary order. The iterator
|
||||
* will throw an <code>Error</code> if a provider-configuration
|
||||
* file violates the specified format or if a provider class
|
||||
* cannot be found and instantiated.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>providerClass</code> is <code>null</code>.
|
||||
*/
|
||||
public static <T> Iterator<T> lookupProviders(Class<T> providerClass) {
|
||||
if (providerClass == null) {
|
||||
throw new IllegalArgumentException("providerClass == null!");
|
||||
}
|
||||
return ServiceLoader.load(providerClass).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> of <code>Class</code> objects
|
||||
* indicating the current set of categories. The iterator will be
|
||||
* empty if no categories exist.
|
||||
*
|
||||
* @return an <code>Iterator</code> containing
|
||||
* <code>Class</code>objects.
|
||||
*/
|
||||
public Iterator<Class<?>> getCategories() {
|
||||
Set keySet = categoryMap.keySet();
|
||||
return keySet.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator containing the subregistries to which the
|
||||
* provider belongs.
|
||||
*/
|
||||
private Iterator getSubRegistries(Object provider) {
|
||||
List l = new ArrayList();
|
||||
Iterator iter = categoryMap.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Class c = (Class)iter.next();
|
||||
if (c.isAssignableFrom(provider.getClass())) {
|
||||
l.add((SubRegistry)categoryMap.get(c));
|
||||
}
|
||||
}
|
||||
return l.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service provider object to the registry. The provider
|
||||
* is associated with the given category.
|
||||
*
|
||||
* <p> If <code>provider</code> implements the
|
||||
* <code>RegisterableService</code> interface, its
|
||||
* <code>onRegistration</code> method will be called. Its
|
||||
* <code>onDeregistration</code> method will be called each time
|
||||
* it is deregistered from a category, for example if a
|
||||
* category is removed or the registry is garbage collected.
|
||||
*
|
||||
* @param provider the service provide object to be registered.
|
||||
* @param category the category under which to register the
|
||||
* provider.
|
||||
* @param <T> the type of the provider.
|
||||
*
|
||||
* @return true if no provider of the same class was previously
|
||||
* registered in the same category category.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>provider</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
* @exception ClassCastException if provider does not implement
|
||||
* the <code>Class</code> defined by <code>category</code>.
|
||||
*/
|
||||
public <T> boolean registerServiceProvider(T provider,
|
||||
Class<T> category) {
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
if (!category.isAssignableFrom(provider.getClass())) {
|
||||
throw new ClassCastException();
|
||||
}
|
||||
|
||||
return reg.registerServiceProvider(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service provider object to the registry. The provider
|
||||
* is associated within each category present in the registry
|
||||
* whose <code>Class</code> it implements.
|
||||
*
|
||||
* <p> If <code>provider</code> implements the
|
||||
* <code>RegisterableService</code> interface, its
|
||||
* <code>onRegistration</code> method will be called once for each
|
||||
* category it is registered under. Its
|
||||
* <code>onDeregistration</code> method will be called each time
|
||||
* it is deregistered from a category or when the registry is
|
||||
* finalized.
|
||||
*
|
||||
* @param provider the service provider object to be registered.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>provider</code> is <code>null</code>.
|
||||
*/
|
||||
public void registerServiceProvider(Object provider) {
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
Iterator regs = getSubRegistries(provider);
|
||||
while (regs.hasNext()) {
|
||||
SubRegistry reg = (SubRegistry)regs.next();
|
||||
reg.registerServiceProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a set of service provider objects, taken from an
|
||||
* <code>Iterator</code> to the registry. Each provider is
|
||||
* associated within each category present in the registry whose
|
||||
* <code>Class</code> it implements.
|
||||
*
|
||||
* <p> For each entry of <code>providers</code> that implements
|
||||
* the <code>RegisterableService</code> interface, its
|
||||
* <code>onRegistration</code> method will be called once for each
|
||||
* category it is registered under. Its
|
||||
* <code>onDeregistration</code> method will be called each time
|
||||
* it is deregistered from a category or when the registry is
|
||||
* finalized.
|
||||
*
|
||||
* @param providers an Iterator containing service provider
|
||||
* objects to be registered.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>providers</code>
|
||||
* is <code>null</code> or contains a <code>null</code> entry.
|
||||
*/
|
||||
public void registerServiceProviders(Iterator<?> providers) {
|
||||
if (providers == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
while (providers.hasNext()) {
|
||||
registerServiceProvider(providers.next());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a service provider object from the given category. If
|
||||
* the provider was not previously registered, nothing happens and
|
||||
* <code>false</code> is returned. Otherwise, <code>true</code>
|
||||
* is returned. If an object of the same class as
|
||||
* <code>provider</code> but not equal (using <code>==</code>) to
|
||||
* <code>provider</code> is registered, it will not be
|
||||
* deregistered.
|
||||
*
|
||||
* <p> If <code>provider</code> implements the
|
||||
* <code>RegisterableService</code> interface, its
|
||||
* <code>onDeregistration</code> method will be called.
|
||||
*
|
||||
* @param provider the service provider object to be deregistered.
|
||||
* @param category the category from which to deregister the
|
||||
* provider.
|
||||
* @param <T> the type of the provider.
|
||||
*
|
||||
* @return <code>true</code> if the provider was previously
|
||||
* registered in the same category category,
|
||||
* <code>false</code> otherwise.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>provider</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
* @exception ClassCastException if provider does not implement
|
||||
* the class defined by <code>category</code>.
|
||||
*/
|
||||
public <T> boolean deregisterServiceProvider(T provider,
|
||||
Class<T> category) {
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
if (!category.isAssignableFrom(provider.getClass())) {
|
||||
throw new ClassCastException();
|
||||
}
|
||||
return reg.deregisterServiceProvider(provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a service provider object from all categories that
|
||||
* contain it.
|
||||
*
|
||||
* @param provider the service provider object to be deregistered.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>provider</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public void deregisterServiceProvider(Object provider) {
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
Iterator regs = getSubRegistries(provider);
|
||||
while (regs.hasNext()) {
|
||||
SubRegistry reg = (SubRegistry)regs.next();
|
||||
reg.deregisterServiceProvider(provider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if <code>provider</code> is currently
|
||||
* registered.
|
||||
*
|
||||
* @param provider the service provider object to be queried.
|
||||
*
|
||||
* @return <code>true</code> if the given provider has been
|
||||
* registered.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>provider</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public boolean contains(Object provider) {
|
||||
if (provider == null) {
|
||||
throw new IllegalArgumentException("provider == null!");
|
||||
}
|
||||
Iterator regs = getSubRegistries(provider);
|
||||
while (regs.hasNext()) {
|
||||
SubRegistry reg = (SubRegistry)regs.next();
|
||||
if (reg.contains(provider)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> containing all registered
|
||||
* service providers in the given category. If
|
||||
* <code>useOrdering</code> is <code>false</code>, the iterator
|
||||
* will return all of the server provider objects in an arbitrary
|
||||
* order. Otherwise, the ordering will respect any pairwise
|
||||
* orderings that have been set. If the graph of pairwise
|
||||
* orderings contains cycles, any providers that belong to a cycle
|
||||
* will not be returned.
|
||||
*
|
||||
* @param category the category to be retrieved from.
|
||||
* @param useOrdering <code>true</code> if pairwise orderings
|
||||
* should be taken account in ordering the returned objects.
|
||||
* @param <T> the type of the category.
|
||||
*
|
||||
* @return an <code>Iterator</code> containing service provider
|
||||
* objects from the given category, possibly in order.
|
||||
*
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
*/
|
||||
public <T> Iterator<T> getServiceProviders(Class<T> category,
|
||||
boolean useOrdering) {
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
return reg.getServiceProviders(useOrdering);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple filter interface used by
|
||||
* <code>ServiceRegistry.getServiceProviders</code> to select
|
||||
* providers matching an arbitrary criterion. Classes that
|
||||
* implement this interface should be defined in order to make use
|
||||
* of the <code>getServiceProviders</code> method of
|
||||
* <code>ServiceRegistry</code> that takes a <code>Filter</code>.
|
||||
*
|
||||
* @see ServiceRegistry#getServiceProviders(Class, ServiceRegistry.Filter, boolean)
|
||||
*/
|
||||
public interface Filter {
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given
|
||||
* <code>provider</code> object matches the criterion defined
|
||||
* by this <code>Filter</code>.
|
||||
*
|
||||
* @param provider a service provider <code>Object</code>.
|
||||
*
|
||||
* @return true if the provider matches the criterion.
|
||||
*/
|
||||
boolean filter(Object provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>Iterator</code> containing service provider
|
||||
* objects within a given category that satisfy a criterion
|
||||
* imposed by the supplied <code>ServiceRegistry.Filter</code>
|
||||
* object's <code>filter</code> method.
|
||||
*
|
||||
* <p> The <code>useOrdering</code> argument controls the
|
||||
* ordering of the results using the same rules as
|
||||
* <code>getServiceProviders(Class, boolean)</code>.
|
||||
*
|
||||
* @param category the category to be retrieved from.
|
||||
* @param filter an instance of <code>ServiceRegistry.Filter</code>
|
||||
* whose <code>filter</code> method will be invoked.
|
||||
* @param useOrdering <code>true</code> if pairwise orderings
|
||||
* should be taken account in ordering the returned objects.
|
||||
* @param <T> the type of the category.
|
||||
*
|
||||
* @return an <code>Iterator</code> containing service provider
|
||||
* objects from the given category, possibly in order.
|
||||
*
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
*/
|
||||
public <T> Iterator<T> getServiceProviders(Class<T> category,
|
||||
Filter filter,
|
||||
boolean useOrdering) {
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
Iterator iter = getServiceProviders(category, useOrdering);
|
||||
return new FilterIterator(iter, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered service provider object that
|
||||
* is of the given class type. At most one object of a given
|
||||
* class is allowed to be registered at any given time. If no
|
||||
* registered object has the desired class type, <code>null</code>
|
||||
* is returned.
|
||||
*
|
||||
* @param providerClass the <code>Class</code> of the desired
|
||||
* service provider object.
|
||||
* @param <T> the type of the provider.
|
||||
*
|
||||
* @return a currently registered service provider object with the
|
||||
* desired <code>Class</code>type, or <code>null</code> is none is
|
||||
* present.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>providerClass</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public <T> T getServiceProviderByClass(Class<T> providerClass) {
|
||||
if (providerClass == null) {
|
||||
throw new IllegalArgumentException("providerClass == null!");
|
||||
}
|
||||
Iterator iter = categoryMap.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Class c = (Class)iter.next();
|
||||
if (c.isAssignableFrom(providerClass)) {
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(c);
|
||||
T provider = reg.getServiceProviderByClass(providerClass);
|
||||
if (provider != null) {
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pairwise ordering between two service provider objects
|
||||
* within a given category. If one or both objects are not
|
||||
* currently registered within the given category, or if the
|
||||
* desired ordering is already set, nothing happens and
|
||||
* <code>false</code> is returned. If the providers previously
|
||||
* were ordered in the reverse direction, that ordering is
|
||||
* removed.
|
||||
*
|
||||
* <p> The ordering will be used by the
|
||||
* <code>getServiceProviders</code> methods when their
|
||||
* <code>useOrdering</code> argument is <code>true</code>.
|
||||
*
|
||||
* @param category a <code>Class</code> object indicating the
|
||||
* category under which the preference is to be established.
|
||||
* @param firstProvider the preferred provider.
|
||||
* @param secondProvider the provider to which
|
||||
* <code>firstProvider</code> is preferred.
|
||||
* @param <T> the type of the category.
|
||||
*
|
||||
* @return <code>true</code> if a previously unset ordering
|
||||
* was established.
|
||||
*
|
||||
* @exception IllegalArgumentException if either provider is
|
||||
* <code>null</code> or they are the same object.
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
*/
|
||||
public <T> boolean setOrdering(Class<T> category,
|
||||
T firstProvider,
|
||||
T secondProvider) {
|
||||
if (firstProvider == null || secondProvider == null) {
|
||||
throw new IllegalArgumentException("provider is null!");
|
||||
}
|
||||
if (firstProvider == secondProvider) {
|
||||
throw new IllegalArgumentException("providers are the same!");
|
||||
}
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
if (reg.contains(firstProvider) &&
|
||||
reg.contains(secondProvider)) {
|
||||
return reg.setOrdering(firstProvider, secondProvider);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pairwise ordering between two service provider objects
|
||||
* within a given category. If one or both objects are not
|
||||
* currently registered within the given category, or if no
|
||||
* ordering is currently set between them, nothing happens
|
||||
* and <code>false</code> is returned.
|
||||
*
|
||||
* <p> The ordering will be used by the
|
||||
* <code>getServiceProviders</code> methods when their
|
||||
* <code>useOrdering</code> argument is <code>true</code>.
|
||||
*
|
||||
* @param category a <code>Class</code> object indicating the
|
||||
* category under which the preference is to be disestablished.
|
||||
* @param firstProvider the formerly preferred provider.
|
||||
* @param secondProvider the provider to which
|
||||
* <code>firstProvider</code> was formerly preferred.
|
||||
* @param <T> the type of the category.
|
||||
*
|
||||
* @return <code>true</code> if a previously set ordering was
|
||||
* disestablished.
|
||||
*
|
||||
* @exception IllegalArgumentException if either provider is
|
||||
* <code>null</code> or they are the same object.
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
*/
|
||||
public <T> boolean unsetOrdering(Class<T> category,
|
||||
T firstProvider,
|
||||
T secondProvider) {
|
||||
if (firstProvider == null || secondProvider == null) {
|
||||
throw new IllegalArgumentException("provider is null!");
|
||||
}
|
||||
if (firstProvider == secondProvider) {
|
||||
throw new IllegalArgumentException("providers are the same!");
|
||||
}
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
if (reg.contains(firstProvider) &&
|
||||
reg.contains(secondProvider)) {
|
||||
return reg.unsetOrdering(firstProvider, secondProvider);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregisters all service provider object currently registered
|
||||
* under the given category.
|
||||
*
|
||||
* @param category the category to be emptied.
|
||||
*
|
||||
* @exception IllegalArgumentException if there is no category
|
||||
* corresponding to <code>category</code>.
|
||||
*/
|
||||
public void deregisterAll(Class<?> category) {
|
||||
SubRegistry reg = (SubRegistry)categoryMap.get(category);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("category unknown!");
|
||||
}
|
||||
reg.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deregisters all currently registered service providers from all
|
||||
* categories.
|
||||
*/
|
||||
public void deregisterAll() {
|
||||
Iterator iter = categoryMap.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
SubRegistry reg = (SubRegistry)iter.next();
|
||||
reg.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes this object prior to garbage collection. The
|
||||
* <code>deregisterAll</code> method is called to deregister all
|
||||
* currently registered service providers. This method should not
|
||||
* be called from application code.
|
||||
*
|
||||
* @exception Throwable if an error occurs during superclass
|
||||
* finalization.
|
||||
*/
|
||||
public void finalize() throws Throwable {
|
||||
deregisterAll();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A portion of a registry dealing with a single superclass or
|
||||
* interface.
|
||||
*/
|
||||
class SubRegistry {
|
||||
|
||||
ServiceRegistry registry;
|
||||
|
||||
Class category;
|
||||
|
||||
// Provider Objects organized by partial ordering
|
||||
final PartiallyOrderedSet poset = new PartiallyOrderedSet();
|
||||
|
||||
// Class -> Provider Object of that class
|
||||
final Map<Class<?>,Object> map = new HashMap();
|
||||
final Map<Class<?>,AccessControlContext> accMap = new HashMap<>();
|
||||
|
||||
public SubRegistry(ServiceRegistry registry, Class category) {
|
||||
this.registry = registry;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public boolean registerServiceProvider(Object provider) {
|
||||
Object oprovider = map.get(provider.getClass());
|
||||
boolean present = oprovider != null;
|
||||
|
||||
if (present) {
|
||||
deregisterServiceProvider(oprovider);
|
||||
}
|
||||
map.put(provider.getClass(), provider);
|
||||
accMap.put(provider.getClass(), AccessController.getContext());
|
||||
poset.add(provider);
|
||||
if (provider instanceof RegisterableService) {
|
||||
RegisterableService rs = (RegisterableService)provider;
|
||||
rs.onRegistration(registry, category);
|
||||
}
|
||||
|
||||
return !present;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the provider was not previously registered, do nothing.
|
||||
*
|
||||
* @return true if the provider was previously registered.
|
||||
*/
|
||||
public boolean deregisterServiceProvider(Object provider) {
|
||||
Object oprovider = map.get(provider.getClass());
|
||||
|
||||
if (provider == oprovider) {
|
||||
map.remove(provider.getClass());
|
||||
accMap.remove(provider.getClass());
|
||||
poset.remove(provider);
|
||||
if (provider instanceof RegisterableService) {
|
||||
RegisterableService rs = (RegisterableService)provider;
|
||||
rs.onDeregistration(registry, category);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean contains(Object provider) {
|
||||
Object oprovider = map.get(provider.getClass());
|
||||
return oprovider == provider;
|
||||
}
|
||||
|
||||
public boolean setOrdering(Object firstProvider,
|
||||
Object secondProvider) {
|
||||
return poset.setOrdering(firstProvider, secondProvider);
|
||||
}
|
||||
|
||||
public boolean unsetOrdering(Object firstProvider,
|
||||
Object secondProvider) {
|
||||
return poset.unsetOrdering(firstProvider, secondProvider);
|
||||
}
|
||||
|
||||
public Iterator getServiceProviders(boolean useOrdering) {
|
||||
if (useOrdering) {
|
||||
return poset.iterator();
|
||||
} else {
|
||||
return map.values().iterator();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T getServiceProviderByClass(Class<T> providerClass) {
|
||||
return (T)map.get(providerClass);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
Iterator iter = map.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Object provider = iter.next();
|
||||
iter.remove();
|
||||
|
||||
if (provider instanceof RegisterableService) {
|
||||
RegisterableService rs = (RegisterableService)provider;
|
||||
AccessControlContext acc = accMap.get(provider.getClass());
|
||||
if (acc != null || System.getSecurityManager() == null) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
|
||||
rs.onDeregistration(registry, category);
|
||||
return null;
|
||||
}, acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
poset.clear();
|
||||
accMap.clear();
|
||||
}
|
||||
|
||||
public void finalize() {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A class for wrapping <code>Iterators</code> with a filter function.
|
||||
* This provides an iterator for a subset without duplication.
|
||||
*/
|
||||
class FilterIterator<T> implements Iterator<T> {
|
||||
|
||||
private Iterator<T> iter;
|
||||
private ServiceRegistry.Filter filter;
|
||||
|
||||
private T next = null;
|
||||
|
||||
public FilterIterator(Iterator<T> iter,
|
||||
ServiceRegistry.Filter filter) {
|
||||
this.iter = iter;
|
||||
this.filter = filter;
|
||||
advance();
|
||||
}
|
||||
|
||||
private void advance() {
|
||||
while (iter.hasNext()) {
|
||||
T elt = iter.next();
|
||||
if (filter.filter(elt)) {
|
||||
next = elt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
next = null;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return next != null;
|
||||
}
|
||||
|
||||
public T next() {
|
||||
if (next == null) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
T o = next;
|
||||
advance();
|
||||
return o;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
294
jdkSrc/jdk8/javax/imageio/stream/FileCacheImageInputStream.java
Normal file
294
jdkSrc/jdk8/javax/imageio/stream/FileCacheImageInputStream.java
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import com.sun.imageio.stream.StreamCloser;
|
||||
import com.sun.imageio.stream.StreamFinalizer;
|
||||
import sun.java2d.Disposer;
|
||||
import sun.java2d.DisposerRecord;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageInputStream</code> that gets its
|
||||
* input from a regular <code>InputStream</code>. A file is used to
|
||||
* cache previously read data.
|
||||
*
|
||||
*/
|
||||
public class FileCacheImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
private InputStream stream;
|
||||
|
||||
private File cacheFile;
|
||||
|
||||
private RandomAccessFile cache;
|
||||
|
||||
private static final int BUFFER_LENGTH = 1024;
|
||||
|
||||
private byte[] buf = new byte[BUFFER_LENGTH];
|
||||
|
||||
private long length = 0L;
|
||||
|
||||
private boolean foundEOF = false;
|
||||
|
||||
/** The referent to be registered with the Disposer. */
|
||||
private final Object disposerReferent;
|
||||
|
||||
/** The DisposerRecord that closes the underlying cache. */
|
||||
private final DisposerRecord disposerRecord;
|
||||
|
||||
/** The CloseAction that closes the stream in
|
||||
* the StreamCloser's shutdown hook */
|
||||
private final StreamCloser.CloseAction closeAction;
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileCacheImageInputStream</code> that will read
|
||||
* from a given <code>InputStream</code>.
|
||||
*
|
||||
* <p> A temporary file is used as a cache. If
|
||||
* <code>cacheDir</code>is non-<code>null</code> and is a
|
||||
* directory, the file will be created there. If it is
|
||||
* <code>null</code>, the system-dependent default temporary-file
|
||||
* directory will be used (see the documentation for
|
||||
* <code>File.createTempFile</code> for details).
|
||||
*
|
||||
* @param stream an <code>InputStream</code> to read from.
|
||||
* @param cacheDir a <code>File</code> indicating where the
|
||||
* cache file should be created, or <code>null</code> to use the
|
||||
* system directory.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>stream</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>cacheDir</code> is
|
||||
* non-<code>null</code> but is not a directory.
|
||||
* @exception IOException if a cache file cannot be created.
|
||||
*/
|
||||
public FileCacheImageInputStream(InputStream stream, File cacheDir)
|
||||
throws IOException {
|
||||
if (stream == null) {
|
||||
throw new IllegalArgumentException("stream == null!");
|
||||
}
|
||||
if ((cacheDir != null) && !(cacheDir.isDirectory())) {
|
||||
throw new IllegalArgumentException("Not a directory!");
|
||||
}
|
||||
this.stream = stream;
|
||||
if (cacheDir == null)
|
||||
this.cacheFile = Files.createTempFile("imageio", ".tmp").toFile();
|
||||
else
|
||||
this.cacheFile = Files.createTempFile(cacheDir.toPath(), "imageio", ".tmp")
|
||||
.toFile();
|
||||
this.cache = new RandomAccessFile(cacheFile, "rw");
|
||||
|
||||
this.closeAction = StreamCloser.createCloseAction(this);
|
||||
StreamCloser.addToQueue(closeAction);
|
||||
|
||||
disposerRecord = new StreamDisposerRecord(cacheFile, cache);
|
||||
if (getClass() == FileCacheImageInputStream.class) {
|
||||
disposerReferent = new Object();
|
||||
Disposer.addRecord(disposerReferent, disposerRecord);
|
||||
} else {
|
||||
disposerReferent = new StreamFinalizer(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that at least <code>pos</code> bytes are cached,
|
||||
* or the end of the source is reached. The return value
|
||||
* is equal to the smaller of <code>pos</code> and the
|
||||
* length of the source file.
|
||||
*/
|
||||
private long readUntil(long pos) throws IOException {
|
||||
// We've already got enough data cached
|
||||
if (pos < length) {
|
||||
return pos;
|
||||
}
|
||||
// pos >= length but length isn't getting any bigger, so return it
|
||||
if (foundEOF) {
|
||||
return length;
|
||||
}
|
||||
|
||||
long len = pos - length;
|
||||
cache.seek(length);
|
||||
while (len > 0) {
|
||||
// Copy a buffer's worth of data from the source to the cache
|
||||
// BUFFER_LENGTH will always fit into an int so this is safe
|
||||
int nbytes =
|
||||
stream.read(buf, 0, (int)Math.min(len, (long)BUFFER_LENGTH));
|
||||
if (nbytes == -1) {
|
||||
foundEOF = true;
|
||||
return length;
|
||||
}
|
||||
|
||||
cache.write(buf, 0, nbytes);
|
||||
len -= nbytes;
|
||||
length += nbytes;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
long next = streamPos + 1;
|
||||
long pos = readUntil(next);
|
||||
if (pos >= next) {
|
||||
cache.seek(streamPos++);
|
||||
return cache.read();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
|
||||
}
|
||||
|
||||
bitOffset = 0;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long pos = readUntil(streamPos + len);
|
||||
|
||||
// len will always fit into an int so this is safe
|
||||
len = (int)Math.min((long)len, pos - streamPos);
|
||||
if (len > 0) {
|
||||
cache.seek(streamPos);
|
||||
cache.readFully(b, off, len);
|
||||
streamPos += len;
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageInputStream</code> caches data in order to allow
|
||||
* seeking backwards.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCachedMemory
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageInputStream</code> maintains a file cache.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedMemory
|
||||
*/
|
||||
public boolean isCachedFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>false</code> since this
|
||||
* <code>ImageInputStream</code> does not maintain a main memory
|
||||
* cache.
|
||||
*
|
||||
* @return <code>false</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCachedMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this <code>FileCacheImageInputStream</code>, closing
|
||||
* and removing the cache file. The source <code>InputStream</code>
|
||||
* is not closed.
|
||||
*
|
||||
* @exception IOException if an error occurs.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
disposerRecord.dispose(); // this will close/delete the cache file
|
||||
stream = null;
|
||||
cache = null;
|
||||
cacheFile = null;
|
||||
StreamCloser.removeFromQueue(closeAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
// Empty finalizer: for performance reasons we instead use the
|
||||
// Disposer mechanism for ensuring that the underlying
|
||||
// RandomAccessFile is closed/deleted prior to garbage collection
|
||||
}
|
||||
|
||||
private static class StreamDisposerRecord implements DisposerRecord {
|
||||
private File cacheFile;
|
||||
private RandomAccessFile cache;
|
||||
|
||||
public StreamDisposerRecord(File cacheFile, RandomAccessFile cache) {
|
||||
this.cacheFile = cacheFile;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (cache != null) {
|
||||
try {
|
||||
cache.close();
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
cache = null;
|
||||
}
|
||||
}
|
||||
if (cacheFile != null) {
|
||||
cacheFile.delete();
|
||||
cacheFile = null;
|
||||
}
|
||||
// Note: Explicit removal of the stream from the StreamCloser
|
||||
// queue is not mandatory in this case, as it will be removed
|
||||
// automatically by GC shortly after this method is called.
|
||||
}
|
||||
}
|
||||
}
|
||||
261
jdkSrc/jdk8/javax/imageio/stream/FileCacheImageOutputStream.java
Normal file
261
jdkSrc/jdk8/javax/imageio/stream/FileCacheImageOutputStream.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.file.Files;
|
||||
import com.sun.imageio.stream.StreamCloser;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageOutputStream</code> that writes its
|
||||
* output to a regular <code>OutputStream</code>. A file is used to
|
||||
* cache data until it is flushed to the output stream.
|
||||
*
|
||||
*/
|
||||
public class FileCacheImageOutputStream extends ImageOutputStreamImpl {
|
||||
|
||||
private OutputStream stream;
|
||||
|
||||
private File cacheFile;
|
||||
|
||||
private RandomAccessFile cache;
|
||||
|
||||
// Pos after last (rightmost) byte written
|
||||
private long maxStreamPos = 0L;
|
||||
|
||||
/** The CloseAction that closes the stream in
|
||||
* the StreamCloser's shutdown hook */
|
||||
private final StreamCloser.CloseAction closeAction;
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileCacheImageOutputStream</code> that will write
|
||||
* to a given <code>outputStream</code>.
|
||||
*
|
||||
* <p> A temporary file is used as a cache. If
|
||||
* <code>cacheDir</code>is non-<code>null</code> and is a
|
||||
* directory, the file will be created there. If it is
|
||||
* <code>null</code>, the system-dependent default temporary-file
|
||||
* directory will be used (see the documentation for
|
||||
* <code>File.createTempFile</code> for details).
|
||||
*
|
||||
* @param stream an <code>OutputStream</code> to write to.
|
||||
* @param cacheDir a <code>File</code> indicating where the
|
||||
* cache file should be created, or <code>null</code> to use the
|
||||
* system directory.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>stream</code>
|
||||
* is <code>null</code>.
|
||||
* @exception IllegalArgumentException if <code>cacheDir</code> is
|
||||
* non-<code>null</code> but is not a directory.
|
||||
* @exception IOException if a cache file cannot be created.
|
||||
*/
|
||||
public FileCacheImageOutputStream(OutputStream stream, File cacheDir)
|
||||
throws IOException {
|
||||
if (stream == null) {
|
||||
throw new IllegalArgumentException("stream == null!");
|
||||
}
|
||||
if ((cacheDir != null) && !(cacheDir.isDirectory())) {
|
||||
throw new IllegalArgumentException("Not a directory!");
|
||||
}
|
||||
this.stream = stream;
|
||||
if (cacheDir == null)
|
||||
this.cacheFile = Files.createTempFile("imageio", ".tmp").toFile();
|
||||
else
|
||||
this.cacheFile = Files.createTempFile(cacheDir.toPath(), "imageio", ".tmp")
|
||||
.toFile();
|
||||
this.cache = new RandomAccessFile(cacheFile, "rw");
|
||||
|
||||
this.closeAction = StreamCloser.createCloseAction(this);
|
||||
StreamCloser.addToQueue(closeAction);
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
int val = cache.read();
|
||||
if (val != -1) {
|
||||
++streamPos;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
|
||||
}
|
||||
|
||||
bitOffset = 0;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nbytes = cache.read(b, off, len);
|
||||
if (nbytes != -1) {
|
||||
streamPos += nbytes;
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
cache.write(b);
|
||||
++streamPos;
|
||||
maxStreamPos = Math.max(maxStreamPos, streamPos);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
cache.write(b, off, len);
|
||||
streamPos += len;
|
||||
maxStreamPos = Math.max(maxStreamPos, streamPos);
|
||||
}
|
||||
|
||||
public long length() {
|
||||
try {
|
||||
checkClosed();
|
||||
return cache.length();
|
||||
} catch (IOException e) {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current stream position and resets the bit offset to
|
||||
* 0. It is legal to seek past the end of the file; an
|
||||
* <code>EOFException</code> will be thrown only if a read is
|
||||
* performed. The file length will not be increased until a write
|
||||
* is performed.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code> is smaller
|
||||
* than the flushed position.
|
||||
* @exception IOException if any other I/O error occurs.
|
||||
*/
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
cache.seek(pos);
|
||||
this.streamPos = cache.getFilePointer();
|
||||
maxStreamPos = Math.max(maxStreamPos, streamPos);
|
||||
this.bitOffset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageOutputStream</code> caches data in order to allow
|
||||
* seeking backwards.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCachedMemory
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageOutputStream</code> maintains a file cache.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedMemory
|
||||
*/
|
||||
public boolean isCachedFile() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>false</code> since this
|
||||
* <code>ImageOutputStream</code> does not maintain a main memory
|
||||
* cache.
|
||||
*
|
||||
* @return <code>false</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCachedMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this <code>FileCacheImageOutputStream</code>. All
|
||||
* pending data is flushed to the output, and the cache file
|
||||
* is closed and removed. The destination <code>OutputStream</code>
|
||||
* is not closed.
|
||||
*
|
||||
* @exception IOException if an error occurs.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
maxStreamPos = cache.length();
|
||||
|
||||
seek(maxStreamPos);
|
||||
flushBefore(maxStreamPos);
|
||||
super.close();
|
||||
cache.close();
|
||||
cache = null;
|
||||
cacheFile.delete();
|
||||
cacheFile = null;
|
||||
stream.flush();
|
||||
stream = null;
|
||||
StreamCloser.removeFromQueue(closeAction);
|
||||
}
|
||||
|
||||
public void flushBefore(long pos) throws IOException {
|
||||
long oFlushedPos = flushedPos;
|
||||
super.flushBefore(pos); // this will call checkClosed() for us
|
||||
|
||||
long flushBytes = flushedPos - oFlushedPos;
|
||||
if (flushBytes > 0) {
|
||||
int bufLen = 512;
|
||||
byte[] buf = new byte[bufLen];
|
||||
cache.seek(oFlushedPos);
|
||||
while (flushBytes > 0) {
|
||||
int len = (int)Math.min(flushBytes, bufLen);
|
||||
cache.readFully(buf, 0, len);
|
||||
stream.write(buf, 0, len);
|
||||
flushBytes -= len;
|
||||
}
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
164
jdkSrc/jdk8/javax/imageio/stream/FileImageInputStream.java
Normal file
164
jdkSrc/jdk8/javax/imageio/stream/FileImageInputStream.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import com.sun.imageio.stream.CloseableDisposerRecord;
|
||||
import com.sun.imageio.stream.StreamFinalizer;
|
||||
import sun.java2d.Disposer;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageInputStream</code> that gets its
|
||||
* input from a <code>File</code> or <code>RandomAccessFile</code>.
|
||||
* The file contents are assumed to be stable during the lifetime of
|
||||
* the object.
|
||||
*
|
||||
*/
|
||||
public class FileImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
private RandomAccessFile raf;
|
||||
|
||||
/** The referent to be registered with the Disposer. */
|
||||
private final Object disposerReferent;
|
||||
|
||||
/** The DisposerRecord that closes the underlying RandomAccessFile. */
|
||||
private final CloseableDisposerRecord disposerRecord;
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileImageInputStream</code> that will read
|
||||
* from a given <code>File</code>.
|
||||
*
|
||||
* <p> The file contents must not change between the time this
|
||||
* object is constructed and the time of the last call to a read
|
||||
* method.
|
||||
*
|
||||
* @param f a <code>File</code> to read from.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>f</code> is
|
||||
* <code>null</code>.
|
||||
* @exception SecurityException if a security manager exists
|
||||
* and does not allow read access to the file.
|
||||
* @exception FileNotFoundException if <code>f</code> is a
|
||||
* directory or cannot be opened for reading for any other reason.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public FileImageInputStream(File f)
|
||||
throws FileNotFoundException, IOException {
|
||||
this(f == null ? null : new RandomAccessFile(f, "r"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileImageInputStream</code> that will read
|
||||
* from a given <code>RandomAccessFile</code>.
|
||||
*
|
||||
* <p> The file contents must not change between the time this
|
||||
* object is constructed and the time of the last call to a read
|
||||
* method.
|
||||
*
|
||||
* @param raf a <code>RandomAccessFile</code> to read from.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>raf</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public FileImageInputStream(RandomAccessFile raf) {
|
||||
if (raf == null) {
|
||||
throw new IllegalArgumentException("raf == null!");
|
||||
}
|
||||
this.raf = raf;
|
||||
|
||||
disposerRecord = new CloseableDisposerRecord(raf);
|
||||
if (getClass() == FileImageInputStream.class) {
|
||||
disposerReferent = new Object();
|
||||
Disposer.addRecord(disposerReferent, disposerRecord);
|
||||
} else {
|
||||
disposerReferent = new StreamFinalizer(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
int val = raf.read();
|
||||
if (val != -1) {
|
||||
++streamPos;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
int nbytes = raf.read(b, off, len);
|
||||
if (nbytes != -1) {
|
||||
streamPos += nbytes;
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the underlying file, or <code>-1</code>
|
||||
* if it is unknown.
|
||||
*
|
||||
* @return the file length as a <code>long</code>, or
|
||||
* <code>-1</code>.
|
||||
*/
|
||||
public long length() {
|
||||
try {
|
||||
checkClosed();
|
||||
return raf.length();
|
||||
} catch (IOException e) {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
bitOffset = 0;
|
||||
raf.seek(pos);
|
||||
streamPos = raf.getFilePointer();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
disposerRecord.dispose(); // this closes the RandomAccessFile
|
||||
raf = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
// Empty finalizer: for performance reasons we instead use the
|
||||
// Disposer mechanism for ensuring that the underlying
|
||||
// RandomAccessFile is closed prior to garbage collection
|
||||
}
|
||||
}
|
||||
172
jdkSrc/jdk8/javax/imageio/stream/FileImageOutputStream.java
Normal file
172
jdkSrc/jdk8/javax/imageio/stream/FileImageOutputStream.java
Normal file
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import com.sun.imageio.stream.CloseableDisposerRecord;
|
||||
import com.sun.imageio.stream.StreamFinalizer;
|
||||
import sun.java2d.Disposer;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageOutputStream</code> that writes its
|
||||
* output directly to a <code>File</code> or
|
||||
* <code>RandomAccessFile</code>.
|
||||
*
|
||||
*/
|
||||
public class FileImageOutputStream extends ImageOutputStreamImpl {
|
||||
|
||||
private RandomAccessFile raf;
|
||||
|
||||
/** The referent to be registered with the Disposer. */
|
||||
private final Object disposerReferent;
|
||||
|
||||
/** The DisposerRecord that closes the underlying RandomAccessFile. */
|
||||
private final CloseableDisposerRecord disposerRecord;
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileImageOutputStream</code> that will write
|
||||
* to a given <code>File</code>.
|
||||
*
|
||||
* @param f a <code>File</code> to write to.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>f</code> is
|
||||
* <code>null</code>.
|
||||
* @exception SecurityException if a security manager exists
|
||||
* and does not allow write access to the file.
|
||||
* @exception FileNotFoundException if <code>f</code> does not denote
|
||||
* a regular file or it cannot be opened for reading and writing for any
|
||||
* other reason.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public FileImageOutputStream(File f)
|
||||
throws FileNotFoundException, IOException {
|
||||
this(f == null ? null : new RandomAccessFile(f, "rw"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>FileImageOutputStream</code> that will write
|
||||
* to a given <code>RandomAccessFile</code>.
|
||||
*
|
||||
* @param raf a <code>RandomAccessFile</code> to write to.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>raf</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public FileImageOutputStream(RandomAccessFile raf) {
|
||||
if (raf == null) {
|
||||
throw new IllegalArgumentException("raf == null!");
|
||||
}
|
||||
this.raf = raf;
|
||||
|
||||
disposerRecord = new CloseableDisposerRecord(raf);
|
||||
if (getClass() == FileImageOutputStream.class) {
|
||||
disposerReferent = new Object();
|
||||
Disposer.addRecord(disposerReferent, disposerRecord);
|
||||
} else {
|
||||
disposerReferent = new StreamFinalizer(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
int val = raf.read();
|
||||
if (val != -1) {
|
||||
++streamPos;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
int nbytes = raf.read(b, off, len);
|
||||
if (nbytes != -1) {
|
||||
streamPos += nbytes;
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
raf.write(b);
|
||||
++streamPos;
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
raf.write(b, off, len);
|
||||
streamPos += len;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
try {
|
||||
checkClosed();
|
||||
return raf.length();
|
||||
} catch (IOException e) {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current stream position and resets the bit offset to
|
||||
* 0. It is legal to seeking past the end of the file; an
|
||||
* <code>EOFException</code> will be thrown only if a read is
|
||||
* performed. The file length will not be increased until a write
|
||||
* is performed.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code> is smaller
|
||||
* than the flushed position.
|
||||
* @exception IOException if any other I/O error occurs.
|
||||
*/
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
bitOffset = 0;
|
||||
raf.seek(pos);
|
||||
streamPos = raf.getFilePointer();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
disposerRecord.dispose(); // this closes the RandomAccessFile
|
||||
raf = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
// Empty finalizer: for performance reasons we instead use the
|
||||
// Disposer mechanism for ensuring that the underlying
|
||||
// RandomAccessFile is closed prior to garbage collection
|
||||
}
|
||||
}
|
||||
143
jdkSrc/jdk8/javax/imageio/stream/IIOByteBuffer.java
Normal file
143
jdkSrc/jdk8/javax/imageio/stream/IIOByteBuffer.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
/**
|
||||
* A class representing a mutable reference to an array of bytes and
|
||||
* an offset and length within that array. <code>IIOByteBuffer</code>
|
||||
* is used by <code>ImageInputStream</code> to supply a sequence of bytes
|
||||
* to the caller, possibly with fewer copies than using the conventional
|
||||
* <code>read</code> methods that take a user-supplied byte array.
|
||||
*
|
||||
* <p> The byte array referenced by an <code>IIOByteBuffer</code> will
|
||||
* generally be part of an internal data structure belonging to an
|
||||
* <code>ImageReader</code> implementation; its contents should be
|
||||
* considered read-only and must not be modified.
|
||||
*
|
||||
*/
|
||||
public class IIOByteBuffer {
|
||||
|
||||
private byte[] data;
|
||||
|
||||
private int offset;
|
||||
|
||||
private int length;
|
||||
|
||||
/**
|
||||
* Constructs an <code>IIOByteBuffer</code> that references a
|
||||
* given byte array, offset, and length.
|
||||
*
|
||||
* @param data a byte array.
|
||||
* @param offset an int offset within the array.
|
||||
* @param length an int specifying the length of the data of
|
||||
* interest within byte array, in bytes.
|
||||
*/
|
||||
public IIOByteBuffer(byte[] data, int offset, int length) {
|
||||
this.data = data;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the byte array. The returned value should
|
||||
* be treated as read-only, and only the portion specified by the
|
||||
* values of <code>getOffset</code> and <code>getLength</code> should
|
||||
* be used.
|
||||
*
|
||||
* @return a byte array reference.
|
||||
*
|
||||
* @see #getOffset
|
||||
* @see #getLength
|
||||
* @see #setData
|
||||
*/
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the array reference that will be returned by subsequent calls
|
||||
* to the <code>getData</code> method.
|
||||
*
|
||||
* @param data a byte array reference containing the new data value.
|
||||
*
|
||||
* @see #getData
|
||||
*/
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset within the byte array returned by
|
||||
* <code>getData</code> at which the data of interest start.
|
||||
*
|
||||
* @return an int offset.
|
||||
*
|
||||
* @see #getData
|
||||
* @see #getLength
|
||||
* @see #setOffset
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value that will be returned by subsequent calls
|
||||
* to the <code>getOffset</code> method.
|
||||
*
|
||||
* @param offset an int containing the new offset value.
|
||||
*
|
||||
* @see #getOffset
|
||||
*/
|
||||
public void setOffset(int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the data of interest within the byte
|
||||
* array returned by <code>getData</code>.
|
||||
*
|
||||
* @return an int length.
|
||||
*
|
||||
* @see #getData
|
||||
* @see #getOffset
|
||||
* @see #setLength
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value that will be returned by subsequent calls
|
||||
* to the <code>getLength</code> method.
|
||||
*
|
||||
* @param length an int containing the new length value.
|
||||
*
|
||||
* @see #getLength
|
||||
*/
|
||||
public void setLength(int length) {
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
1000
jdkSrc/jdk8/javax/imageio/stream/ImageInputStream.java
Normal file
1000
jdkSrc/jdk8/javax/imageio/stream/ImageInputStream.java
Normal file
File diff suppressed because it is too large
Load Diff
880
jdkSrc/jdk8/javax/imageio/stream/ImageInputStreamImpl.java
Normal file
880
jdkSrc/jdk8/javax/imageio/stream/ImageInputStreamImpl.java
Normal file
@@ -0,0 +1,880 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.Stack;
|
||||
import javax.imageio.IIOException;
|
||||
|
||||
/**
|
||||
* An abstract class implementing the <code>ImageInputStream</code> interface.
|
||||
* This class is designed to reduce the number of methods that must
|
||||
* be implemented by subclasses.
|
||||
*
|
||||
* <p> In particular, this class handles most or all of the details of
|
||||
* byte order interpretation, buffering, mark/reset, discarding,
|
||||
* closing, and disposing.
|
||||
*/
|
||||
public abstract class ImageInputStreamImpl implements ImageInputStream {
|
||||
|
||||
private Stack markByteStack = new Stack();
|
||||
|
||||
private Stack markBitStack = new Stack();
|
||||
|
||||
private boolean isClosed = false;
|
||||
|
||||
// Length of the buffer used for readFully(type[], int, int)
|
||||
private static final int BYTE_BUF_LENGTH = 8192;
|
||||
|
||||
/**
|
||||
* Byte buffer used for readFully(type[], int, int). Note that this
|
||||
* array is also used for bulk reads in readShort(), readInt(), etc, so
|
||||
* it should be large enough to hold a primitive value (i.e. >= 8 bytes).
|
||||
* Also note that this array is package protected, so that it can be
|
||||
* used by ImageOutputStreamImpl in a similar manner.
|
||||
*/
|
||||
byte[] byteBuf = new byte[BYTE_BUF_LENGTH];
|
||||
|
||||
/**
|
||||
* The byte order of the stream as an instance of the enumeration
|
||||
* class <code>java.nio.ByteOrder</code>, where
|
||||
* <code>ByteOrder.BIG_ENDIAN</code> indicates network byte order
|
||||
* and <code>ByteOrder.LITTLE_ENDIAN</code> indicates the reverse
|
||||
* order. By default, the value is
|
||||
* <code>ByteOrder.BIG_ENDIAN</code>.
|
||||
*/
|
||||
protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
|
||||
|
||||
/**
|
||||
* The current read position within the stream. Subclasses are
|
||||
* responsible for keeping this value current from any method they
|
||||
* override that alters the read position.
|
||||
*/
|
||||
protected long streamPos;
|
||||
|
||||
/**
|
||||
* The current bit offset within the stream. Subclasses are
|
||||
* responsible for keeping this value current from any method they
|
||||
* override that alters the bit offset.
|
||||
*/
|
||||
protected int bitOffset;
|
||||
|
||||
/**
|
||||
* The position prior to which data may be discarded. Seeking
|
||||
* to a smaller position is not allowed. <code>flushedPos</code>
|
||||
* will always be {@literal >= 0}.
|
||||
*/
|
||||
protected long flushedPos = 0;
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageInputStreamImpl</code>.
|
||||
*/
|
||||
public ImageInputStreamImpl() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an <code>IOException</code> if the stream has been closed.
|
||||
* Subclasses may call this method from any of their methods that
|
||||
* require the stream not to be closed.
|
||||
*
|
||||
* @exception IOException if the stream is closed.
|
||||
*/
|
||||
protected final void checkClosed() throws IOException {
|
||||
if (isClosed) {
|
||||
throw new IOException("closed");
|
||||
}
|
||||
}
|
||||
|
||||
public void setByteOrder(ByteOrder byteOrder) {
|
||||
this.byteOrder = byteOrder;
|
||||
}
|
||||
|
||||
public ByteOrder getByteOrder() {
|
||||
return byteOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single byte from the stream and returns it as an
|
||||
* <code>int</code> between 0 and 255. If EOF is reached,
|
||||
* <code>-1</code> is returned.
|
||||
*
|
||||
* <p> Subclasses must provide an implementation for this method.
|
||||
* The subclass implementation should update the stream position
|
||||
* before exiting.
|
||||
*
|
||||
* <p> The bit offset within the stream must be reset to zero before
|
||||
* the read occurs.
|
||||
*
|
||||
* @return the value of the next byte in the stream, or <code>-1</code>
|
||||
* if EOF is reached.
|
||||
*
|
||||
* @exception IOException if the stream has been closed.
|
||||
*/
|
||||
public abstract int read() throws IOException;
|
||||
|
||||
/**
|
||||
* A convenience method that calls <code>read(b, 0, b.length)</code>.
|
||||
*
|
||||
* <p> The bit offset within the stream is reset to zero before
|
||||
* the read occurs.
|
||||
*
|
||||
* @return the number of bytes actually read, or <code>-1</code>
|
||||
* to indicate EOF.
|
||||
*
|
||||
* @exception NullPointerException if <code>b</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to <code>len</code> bytes from the stream, and stores
|
||||
* them into <code>b</code> starting at index <code>off</code>.
|
||||
* If no bytes can be read because the end of the stream has been
|
||||
* reached, <code>-1</code> is returned.
|
||||
*
|
||||
* <p> The bit offset within the stream must be reset to zero before
|
||||
* the read occurs.
|
||||
*
|
||||
* <p> Subclasses must provide an implementation for this method.
|
||||
* The subclass implementation should update the stream position
|
||||
* before exiting.
|
||||
*
|
||||
* @param b an array of bytes to be written to.
|
||||
* @param off the starting position within <code>b</code> to write to.
|
||||
* @param len the maximum number of bytes to read.
|
||||
*
|
||||
* @return the number of bytes actually read, or <code>-1</code>
|
||||
* to indicate EOF.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>b.length</code>.
|
||||
* @exception NullPointerException if <code>b</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public abstract int read(byte[] b, int off, int len) throws IOException;
|
||||
|
||||
public void readBytes(IIOByteBuffer buf, int len) throws IOException {
|
||||
if (len < 0) {
|
||||
throw new IndexOutOfBoundsException("len < 0!");
|
||||
}
|
||||
if (buf == null) {
|
||||
throw new NullPointerException("buf == null!");
|
||||
}
|
||||
|
||||
byte[] data = new byte[len];
|
||||
len = read(data, 0, len);
|
||||
|
||||
buf.setData(data);
|
||||
buf.setOffset(0);
|
||||
buf.setLength(len);
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
int ch = this.read();
|
||||
if (ch < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return (ch != 0);
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
int ch = this.read();
|
||||
if (ch < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return (byte)ch;
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
int ch = this.read();
|
||||
if (ch < 0) {
|
||||
throw new EOFException();
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
if (read(byteBuf, 0, 2) != 2) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return (short)
|
||||
(((byteBuf[0] & 0xff) << 8) | ((byteBuf[1] & 0xff) << 0));
|
||||
} else {
|
||||
return (short)
|
||||
(((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
return ((int)readShort()) & 0xffff;
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
return (char)readShort();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
if (read(byteBuf, 0, 4) != 4) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return
|
||||
(((byteBuf[0] & 0xff) << 24) | ((byteBuf[1] & 0xff) << 16) |
|
||||
((byteBuf[2] & 0xff) << 8) | ((byteBuf[3] & 0xff) << 0));
|
||||
} else {
|
||||
return
|
||||
(((byteBuf[3] & 0xff) << 24) | ((byteBuf[2] & 0xff) << 16) |
|
||||
((byteBuf[1] & 0xff) << 8) | ((byteBuf[0] & 0xff) << 0));
|
||||
}
|
||||
}
|
||||
|
||||
public long readUnsignedInt() throws IOException {
|
||||
return ((long)readInt()) & 0xffffffffL;
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
// REMIND: Once 6277756 is fixed, we should do a bulk read of all 8
|
||||
// bytes here as we do in readShort() and readInt() for even better
|
||||
// performance (see 6347575 for details).
|
||||
int i1 = readInt();
|
||||
int i2 = readInt();
|
||||
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
return ((long)i1 << 32) + (i2 & 0xFFFFFFFFL);
|
||||
} else {
|
||||
return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL);
|
||||
}
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
StringBuffer input = new StringBuffer();
|
||||
int c = -1;
|
||||
boolean eol = false;
|
||||
|
||||
while (!eol) {
|
||||
switch (c = read()) {
|
||||
case -1:
|
||||
case '\n':
|
||||
eol = true;
|
||||
break;
|
||||
case '\r':
|
||||
eol = true;
|
||||
long cur = getStreamPosition();
|
||||
if ((read()) != '\n') {
|
||||
seek(cur);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
input.append((char)c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((c == -1) && (input.length() == 0)) {
|
||||
return null;
|
||||
}
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
this.bitOffset = 0;
|
||||
|
||||
// Fix 4494369: method ImageInputStreamImpl.readUTF()
|
||||
// does not work as specified (it should always assume
|
||||
// network byte order).
|
||||
ByteOrder oldByteOrder = getByteOrder();
|
||||
setByteOrder(ByteOrder.BIG_ENDIAN);
|
||||
|
||||
String ret;
|
||||
try {
|
||||
ret = DataInputStream.readUTF(this);
|
||||
} catch (IOException e) {
|
||||
// Restore the old byte order even if an exception occurs
|
||||
setByteOrder(oldByteOrder);
|
||||
throw e;
|
||||
}
|
||||
|
||||
setByteOrder(oldByteOrder);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void readFully(byte[] b, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > b.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nbytes = read(b, off, len);
|
||||
if (nbytes == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
off += nbytes;
|
||||
len -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void readFully(short[] s, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > s.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > s.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/2);
|
||||
readFully(byteBuf, 0, nelts*2);
|
||||
toShorts(byteBuf, s, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(char[] c, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > c.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > c.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/2);
|
||||
readFully(byteBuf, 0, nelts*2);
|
||||
toChars(byteBuf, c, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(int[] i, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > i.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/4);
|
||||
readFully(byteBuf, 0, nelts*4);
|
||||
toInts(byteBuf, i, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(long[] l, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > l.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > l.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/8);
|
||||
readFully(byteBuf, 0, nelts*8);
|
||||
toLongs(byteBuf, l, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(float[] f, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > f.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > f.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/4);
|
||||
readFully(byteBuf, 0, nelts*4);
|
||||
toFloats(byteBuf, f, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
public void readFully(double[] d, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > d.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > d.length!");
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int nelts = Math.min(len, byteBuf.length/8);
|
||||
readFully(byteBuf, 0, nelts*8);
|
||||
toDoubles(byteBuf, d, off, nelts);
|
||||
off += nelts;
|
||||
len -= nelts;
|
||||
}
|
||||
}
|
||||
|
||||
private void toShorts(byte[] b, short[] s, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
s[off + j] = (short)((b0 << 8) | b1);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 1];
|
||||
int b1 = b[boff] & 0xff;
|
||||
s[off + j] = (short)((b0 << 8) | b1);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toChars(byte[] b, char[] c, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
c[off + j] = (char)((b0 << 8) | b1);
|
||||
boff += 2;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 1];
|
||||
int b1 = b[boff] & 0xff;
|
||||
c[off + j] = (char)((b0 << 8) | b1);
|
||||
boff += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toInts(byte[] b, int[] i, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 3];
|
||||
int b1 = b[boff + 2] & 0xff;
|
||||
int b2 = b[boff + 1] & 0xff;
|
||||
int b3 = b[boff] & 0xff;
|
||||
i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toLongs(byte[] b, long[] l, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int b4 = b[boff + 4];
|
||||
int b5 = b[boff + 5] & 0xff;
|
||||
int b6 = b[boff + 6] & 0xff;
|
||||
int b7 = b[boff + 7] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
|
||||
l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 7];
|
||||
int b1 = b[boff + 6] & 0xff;
|
||||
int b2 = b[boff + 5] & 0xff;
|
||||
int b3 = b[boff + 4] & 0xff;
|
||||
int b4 = b[boff + 3];
|
||||
int b5 = b[boff + 2] & 0xff;
|
||||
int b6 = b[boff + 1] & 0xff;
|
||||
int b7 = b[boff] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
|
||||
l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toFloats(byte[] b, float[] f, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
f[off + j] = Float.intBitsToFloat(i);
|
||||
boff += 4;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 3];
|
||||
int b1 = b[boff + 2] & 0xff;
|
||||
int b2 = b[boff + 1] & 0xff;
|
||||
int b3 = b[boff + 0] & 0xff;
|
||||
int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
f[off + j] = Float.intBitsToFloat(i);
|
||||
boff += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void toDoubles(byte[] b, double[] d, int off, int len) {
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff];
|
||||
int b1 = b[boff + 1] & 0xff;
|
||||
int b2 = b[boff + 2] & 0xff;
|
||||
int b3 = b[boff + 3] & 0xff;
|
||||
int b4 = b[boff + 4];
|
||||
int b5 = b[boff + 5] & 0xff;
|
||||
int b6 = b[boff + 6] & 0xff;
|
||||
int b7 = b[boff + 7] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
long l = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
|
||||
d[off + j] = Double.longBitsToDouble(l);
|
||||
boff += 8;
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int b0 = b[boff + 7];
|
||||
int b1 = b[boff + 6] & 0xff;
|
||||
int b2 = b[boff + 5] & 0xff;
|
||||
int b3 = b[boff + 4] & 0xff;
|
||||
int b4 = b[boff + 3];
|
||||
int b5 = b[boff + 2] & 0xff;
|
||||
int b6 = b[boff + 1] & 0xff;
|
||||
int b7 = b[boff] & 0xff;
|
||||
|
||||
int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
|
||||
int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
|
||||
long l = ((long)i0 << 32) | (i1 & 0xffffffffL);
|
||||
|
||||
d[off + j] = Double.longBitsToDouble(l);
|
||||
boff += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getStreamPosition() throws IOException {
|
||||
checkClosed();
|
||||
return streamPos;
|
||||
}
|
||||
|
||||
public int getBitOffset() throws IOException {
|
||||
checkClosed();
|
||||
return bitOffset;
|
||||
}
|
||||
|
||||
public void setBitOffset(int bitOffset) throws IOException {
|
||||
checkClosed();
|
||||
if (bitOffset < 0 || bitOffset > 7) {
|
||||
throw new IllegalArgumentException("bitOffset must be betwwen 0 and 7!");
|
||||
}
|
||||
this.bitOffset = bitOffset;
|
||||
}
|
||||
|
||||
public int readBit() throws IOException {
|
||||
checkClosed();
|
||||
|
||||
// Compute final bit offset before we call read() and seek()
|
||||
int newBitOffset = (this.bitOffset + 1) & 0x7;
|
||||
|
||||
int val = read();
|
||||
if (val == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
if (newBitOffset != 0) {
|
||||
// Move byte position back if in the middle of a byte
|
||||
seek(getStreamPosition() - 1);
|
||||
// Shift the bit to be read to the rightmost position
|
||||
val >>= 8 - newBitOffset;
|
||||
}
|
||||
this.bitOffset = newBitOffset;
|
||||
|
||||
return val & 0x1;
|
||||
}
|
||||
|
||||
public long readBits(int numBits) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (numBits < 0 || numBits > 64) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (numBits == 0) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// Have to read additional bits on the left equal to the bit offset
|
||||
int bitsToRead = numBits + bitOffset;
|
||||
|
||||
// Compute final bit offset before we call read() and seek()
|
||||
int newBitOffset = (this.bitOffset + numBits) & 0x7;
|
||||
|
||||
// Read a byte at a time, accumulate
|
||||
long accum = 0L;
|
||||
while (bitsToRead > 0) {
|
||||
int val = read();
|
||||
if (val == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
accum <<= 8;
|
||||
accum |= val;
|
||||
bitsToRead -= 8;
|
||||
}
|
||||
|
||||
// Move byte position back if in the middle of a byte
|
||||
if (newBitOffset != 0) {
|
||||
seek(getStreamPosition() - 1);
|
||||
}
|
||||
this.bitOffset = newBitOffset;
|
||||
|
||||
// Shift away unwanted bits on the right.
|
||||
accum >>>= (-bitsToRead); // Negative of bitsToRead == extra bits read
|
||||
|
||||
// Mask out unwanted bits on the left
|
||||
accum &= (-1L >>> (64 - numBits));
|
||||
|
||||
return accum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>-1L</code> to indicate that the stream has unknown
|
||||
* length. Subclasses must override this method to provide actual
|
||||
* length information.
|
||||
*
|
||||
* @return -1L to indicate unknown length.
|
||||
*/
|
||||
public long length() {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the current stream position by calling
|
||||
* <code>seek(getStreamPosition() + n)</code>.
|
||||
*
|
||||
* <p> The bit offset is reset to zero.
|
||||
*
|
||||
* @param n the number of bytes to seek forward.
|
||||
*
|
||||
* @return an <code>int</code> representing the number of bytes
|
||||
* skipped.
|
||||
*
|
||||
* @exception IOException if <code>getStreamPosition</code>
|
||||
* throws an <code>IOException</code> when computing either
|
||||
* the starting or ending position.
|
||||
*/
|
||||
public int skipBytes(int n) throws IOException {
|
||||
long pos = getStreamPosition();
|
||||
seek(pos + n);
|
||||
return (int)(getStreamPosition() - pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances the current stream position by calling
|
||||
* <code>seek(getStreamPosition() + n)</code>.
|
||||
*
|
||||
* <p> The bit offset is reset to zero.
|
||||
*
|
||||
* @param n the number of bytes to seek forward.
|
||||
*
|
||||
* @return a <code>long</code> representing the number of bytes
|
||||
* skipped.
|
||||
*
|
||||
* @exception IOException if <code>getStreamPosition</code>
|
||||
* throws an <code>IOException</code> when computing either
|
||||
* the starting or ending position.
|
||||
*/
|
||||
public long skipBytes(long n) throws IOException {
|
||||
long pos = getStreamPosition();
|
||||
seek(pos + n);
|
||||
return getStreamPosition() - pos;
|
||||
}
|
||||
|
||||
public void seek(long pos) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
// This test also covers pos < 0
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
|
||||
this.streamPos = pos;
|
||||
this.bitOffset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes the current stream position onto a stack of marked
|
||||
* positions.
|
||||
*/
|
||||
public void mark() {
|
||||
try {
|
||||
markByteStack.push(Long.valueOf(getStreamPosition()));
|
||||
markBitStack.push(Integer.valueOf(getBitOffset()));
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the current stream byte and bit positions from the stack
|
||||
* of marked positions.
|
||||
*
|
||||
* <p> An <code>IOException</code> will be thrown if the previous
|
||||
* marked position lies in the discarded portion of the stream.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
public void reset() throws IOException {
|
||||
if (markByteStack.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
long pos = ((Long)markByteStack.pop()).longValue();
|
||||
if (pos < flushedPos) {
|
||||
throw new IIOException
|
||||
("Previous marked position has been discarded!");
|
||||
}
|
||||
seek(pos);
|
||||
|
||||
int offset = ((Integer)markBitStack.pop()).intValue();
|
||||
setBitOffset(offset);
|
||||
}
|
||||
|
||||
public void flushBefore(long pos) throws IOException {
|
||||
checkClosed();
|
||||
if (pos < flushedPos) {
|
||||
throw new IndexOutOfBoundsException("pos < flushedPos!");
|
||||
}
|
||||
if (pos > getStreamPosition()) {
|
||||
throw new IndexOutOfBoundsException("pos > getStreamPosition()!");
|
||||
}
|
||||
// Invariant: flushedPos >= 0
|
||||
flushedPos = pos;
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
flushBefore(getStreamPosition());
|
||||
}
|
||||
|
||||
public long getFlushedPosition() {
|
||||
return flushedPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation returns false. Subclasses should
|
||||
* override this if they cache data.
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation returns false. Subclasses should
|
||||
* override this if they cache data in main memory.
|
||||
*/
|
||||
public boolean isCachedMemory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation returns false. Subclasses should
|
||||
* override this if they cache data in a temporary file.
|
||||
*/
|
||||
public boolean isCachedFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
checkClosed();
|
||||
|
||||
isClosed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalizes this object prior to garbage collection. The
|
||||
* <code>close</code> method is called to close any open input
|
||||
* source. This method should not be called from application
|
||||
* code.
|
||||
*
|
||||
* @exception Throwable if an error occurs during superclass
|
||||
* finalization.
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
if (!isClosed) {
|
||||
try {
|
||||
close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
662
jdkSrc/jdk8/javax/imageio/stream/ImageOutputStream.java
Normal file
662
jdkSrc/jdk8/javax/imageio/stream/ImageOutputStream.java
Normal file
@@ -0,0 +1,662 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A seekable output stream interface for use by
|
||||
* <code>ImageWriter</code>s. Various output destinations, such as
|
||||
* <code>OutputStream</code>s and <code>File</code>s, as well as
|
||||
* future fast I/O destinations may be "wrapped" by a suitable
|
||||
* implementation of this interface for use by the Image I/O API.
|
||||
*
|
||||
* <p> Unlike a standard <code>OutputStream</code>, ImageOutputStream
|
||||
* extends its counterpart, <code>ImageInputStream</code>. Thus it is
|
||||
* possible to read from the stream as it is being written. The same
|
||||
* seek and flush positions apply to both reading and writing, although
|
||||
* the semantics for dealing with a non-zero bit offset before a byte-aligned
|
||||
* write are necessarily different from the semantics for dealing with
|
||||
* a non-zero bit offset before a byte-aligned read. When reading bytes,
|
||||
* any bit offset is set to 0 before the read; when writing bytes, a
|
||||
* non-zero bit offset causes the remaining bits in the byte to be written
|
||||
* as 0s. The byte-aligned write then starts at the next byte position.
|
||||
*
|
||||
* @see ImageInputStream
|
||||
*
|
||||
*/
|
||||
public interface ImageOutputStream extends ImageInputStream, DataOutput {
|
||||
|
||||
/**
|
||||
* Writes a single byte to the stream at the current position.
|
||||
* The 24 high-order bits of <code>b</code> are ignored.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write. Implementers can use the
|
||||
* {@link ImageOutputStreamImpl#flushBits flushBits}
|
||||
* method of {@link ImageOutputStreamImpl ImageOutputStreamImpl}
|
||||
* to guarantee this.
|
||||
*
|
||||
* @param b an <code>int</code> whose lower 8 bits are to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void write(int b) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes to the stream at the current
|
||||
* position. If <code>b.length</code> is 0, nothing is written.
|
||||
* The byte <code>b[0]</code> is written first, then the byte
|
||||
* <code>b[1]</code>, and so on.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param b an array of <code>byte</code>s to be written.
|
||||
*
|
||||
* @exception NullPointerException if <code>b</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void write(byte b[]) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bytes to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The byte <code>b[off]</code> is written first, then the byte
|
||||
* <code>b[off + 1]</code>, and so on.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write. Implementers can use the
|
||||
* {@link ImageOutputStreamImpl#flushBits flushBits}
|
||||
* method of {@link ImageOutputStreamImpl ImageOutputStreamImpl}
|
||||
* to guarantee this.
|
||||
*
|
||||
* @param b an array of <code>byte</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>byte</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>b.length</code>.
|
||||
* @exception NullPointerException if <code>b</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void write(byte b[], int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a <code>boolean</code> value to the stream. If
|
||||
* <code>v</code> is true, the value <code>(byte)1</code> is
|
||||
* written; if <code>v</code> is false, the value
|
||||
* <code>(byte)0</code> is written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v the <code>boolean</code> to be written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeBoolean(boolean v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes the 8 low-order bits of <code>v</code> to the
|
||||
* stream. The 24 high-order bits of <code>v</code> are ignored.
|
||||
* (This means that <code>writeByte</code> does exactly the same
|
||||
* thing as <code>write</code> for an integer argument.)
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v an <code>int</code> containing the byte value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeByte(int v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes the 16 low-order bits of <code>v</code> to the
|
||||
* stream. The 16 high-order bits of <code>v</code> are ignored.
|
||||
* If the stream uses network byte order, the bytes written, in
|
||||
* order, will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* (byte)(v & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* Otherwise, the bytes written will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)(v & 0xff)
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v an <code>int</code> containing the short value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeShort(int v) throws IOException;
|
||||
|
||||
/**
|
||||
* This method is a synonym for {@link #writeShort writeShort}.
|
||||
*
|
||||
* @param v an <code>int</code> containing the char (unsigned
|
||||
* short) value to be written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*
|
||||
* @see #writeShort(int)
|
||||
*/
|
||||
void writeChar(int v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes the 32 bits of <code>v</code> to the stream. If the
|
||||
* stream uses network byte order, the bytes written, in order,
|
||||
* will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)((v >> 24) & 0xff)
|
||||
* (byte)((v >> 16) & 0xff)
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* (byte)(v & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* Otheriwse, the bytes written will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)(v & 0xff)
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* (byte)((v >> 16) & 0xff)
|
||||
* (byte)((v >> 24) & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v an <code>int</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeInt(int v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes the 64 bits of <code>v</code> to the stream. If the
|
||||
* stream uses network byte order, the bytes written, in order,
|
||||
* will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)((v >> 56) & 0xff)
|
||||
* (byte)((v >> 48) & 0xff)
|
||||
* (byte)((v >> 40) & 0xff)
|
||||
* (byte)((v >> 32) & 0xff)
|
||||
* (byte)((v >> 24) & 0xff)
|
||||
* (byte)((v >> 16) & 0xff)
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* (byte)(v & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* Otherwise, the bytes written will be:
|
||||
*
|
||||
* <pre>
|
||||
* (byte)(v & 0xff)
|
||||
* (byte)((v >> 8) & 0xff)
|
||||
* (byte)((v >> 16) & 0xff)
|
||||
* (byte)((v >> 24) & 0xff)
|
||||
* (byte)((v >> 32) & 0xff)
|
||||
* (byte)((v >> 40) & 0xff)
|
||||
* (byte)((v >> 48) & 0xff)
|
||||
* (byte)((v >> 56) & 0xff)
|
||||
* </pre>
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v a <code>long</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeLong(long v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a <code>float</code> value, which is comprised of four
|
||||
* bytes, to the output stream. It does this as if it first
|
||||
* converts this <code>float</code> value to an <code>int</code>
|
||||
* in exactly the manner of the <code>Float.floatToIntBits</code>
|
||||
* method and then writes the int value in exactly the manner of
|
||||
* the <code>writeInt</code> method.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v a <code>float</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeFloat(float v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a <code>double</code> value, which is comprised of four
|
||||
* bytes, to the output stream. It does this as if it first
|
||||
* converts this <code>double</code> value to an <code>long</code>
|
||||
* in exactly the manner of the
|
||||
* <code>Double.doubleToLongBits</code> method and then writes the
|
||||
* long value in exactly the manner of the <code>writeLong</code>
|
||||
* method.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param v a <code>double</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeDouble(double v) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a string to the output stream. For every character in
|
||||
* the string <code>s</code>, taken in order, one byte is written
|
||||
* to the output stream. If <code>s</code> is <code>null</code>, a
|
||||
* <code>NullPointerException</code> is thrown.
|
||||
*
|
||||
* <p> If <code>s.length</code> is zero, then no bytes are
|
||||
* written. Otherwise, the character <code>s[0]</code> is written
|
||||
* first, then <code>s[1]</code>, and so on; the last character
|
||||
* written is <code>s[s.length-1]</code>. For each character, one
|
||||
* byte is written, the low-order byte, in exactly the manner of
|
||||
* the <code>writeByte</code> method. The high-order eight bits of
|
||||
* each character in the string are ignored.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param s a <code>String</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception NullPointerException if <code>s</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeBytes(String s) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a string to the output stream. For every character in
|
||||
* the string <code>s</code>, taken in order, two bytes are
|
||||
* written to the output stream, ordered according to the current
|
||||
* byte order setting. If network byte order is being used, the
|
||||
* high-order byte is written first; the order is reversed
|
||||
* otherwise. If <code>s</code> is <code>null</code>, a
|
||||
* <code>NullPointerException</code> is thrown.
|
||||
*
|
||||
* <p> If <code>s.length</code> is zero, then no bytes are
|
||||
* written. Otherwise, the character <code>s[0]</code> is written
|
||||
* first, then <code>s[1]</code>, and so on; the last character
|
||||
* written is <code>s[s.length-1]</code>.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param s a <code>String</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception NullPointerException if <code>s</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeChars(String s) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes two bytes of length information to the output stream in
|
||||
* network byte order, followed by the
|
||||
* <a href="../../../java/io/DataInput.html#modified-utf-8">modified
|
||||
* UTF-8</a>
|
||||
* representation of every character in the string <code>s</code>.
|
||||
* If <code>s</code> is <code>null</code>, a
|
||||
* <code>NullPointerException</code> is thrown. Each character in
|
||||
* the string <code>s</code> is converted to a group of one, two,
|
||||
* or three bytes, depending on the value of the character.
|
||||
*
|
||||
* <p> If a character <code>c</code> is in the range
|
||||
* <code>\u0001</code> through <code>\u007f</code>, it is
|
||||
* represented by one byte:
|
||||
*
|
||||
* <p><pre>
|
||||
* (byte)c
|
||||
* </pre>
|
||||
*
|
||||
* <p> If a character <code>c</code> is <code>\u0000</code> or
|
||||
* is in the range <code>\u0080</code> through
|
||||
* <code>\u07ff</code>, then it is represented by two bytes,
|
||||
* to be written in the order shown:
|
||||
*
|
||||
* <p> <pre><code>
|
||||
* (byte)(0xc0 | (0x1f & (c >> 6)))
|
||||
* (byte)(0x80 | (0x3f & c))
|
||||
* </code></pre>
|
||||
*
|
||||
* <p> If a character <code>c</code> is in the range
|
||||
* <code>\u0800</code> through <code>uffff</code>, then it is
|
||||
* represented by three bytes, to be written in the order shown:
|
||||
*
|
||||
* <p> <pre><code>
|
||||
* (byte)(0xe0 | (0x0f & (c >> 12)))
|
||||
* (byte)(0x80 | (0x3f & (c >> 6)))
|
||||
* (byte)(0x80 | (0x3f & c))
|
||||
* </code></pre>
|
||||
*
|
||||
* <p> First, the total number of bytes needed to represent all
|
||||
* the characters of <code>s</code> is calculated. If this number
|
||||
* is larger than <code>65535</code>, then a
|
||||
* <code>UTFDataFormatException</code> is thrown. Otherwise, this
|
||||
* length is written to the output stream in exactly the manner of
|
||||
* the <code>writeShort</code> method; after this, the one-, two-,
|
||||
* or three-byte representation of each character in the string
|
||||
* <code>s</code> is written.
|
||||
*
|
||||
* <p> The current byte order setting is ignored.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* <p><strong>Note:</strong> This method should not be used in
|
||||
* the implementation of image formats that use standard UTF-8,
|
||||
* because the modified UTF-8 used here is incompatible with
|
||||
* standard UTF-8.
|
||||
*
|
||||
* @param s a <code>String</code> containing the value to be
|
||||
* written.
|
||||
*
|
||||
* @exception NullPointerException if <code>s</code> is
|
||||
* <code>null</code>.
|
||||
* @exception java.io.UTFDataFormatException if the modified UTF-8
|
||||
* representation of <code>s</code> requires more than 65536 bytes.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeUTF(String s) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of shorts to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The short <code>s[off]</code> is written first, then the short
|
||||
* <code>s[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param s an array of <code>short</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>short</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>s.length</code>.
|
||||
* @exception NullPointerException if <code>s</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeShorts(short[] s, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of chars to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The char <code>c[off]</code> is written first, then the char
|
||||
* <code>c[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param c an array of <code>char</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>char</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>c.length</code>.
|
||||
* @exception NullPointerException if <code>c</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeChars(char[] c, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of ints to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The int <code>i[off]</code> is written first, then the int
|
||||
* <code>i[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param i an array of <code>int</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>int</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>i.length</code>.
|
||||
* @exception NullPointerException if <code>i</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeInts(int[] i, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of longs to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The long <code>l[off]</code> is written first, then the long
|
||||
* <code>l[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param l an array of <code>long</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>long</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>l.length</code>.
|
||||
* @exception NullPointerException if <code>l</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeLongs(long[] l, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of floats to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The float <code>f[off]</code> is written first, then the float
|
||||
* <code>f[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param f an array of <code>float</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>float</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>f.length</code>.
|
||||
* @exception NullPointerException if <code>f</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeFloats(float[] f, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of doubles to the stream at the current
|
||||
* position. If <code>len</code> is 0, nothing is written.
|
||||
* The double <code>d[off]</code> is written first, then the double
|
||||
* <code>d[off + 1]</code>, and so on. The byte order of the
|
||||
* stream is used to determine the order in which the individual
|
||||
* bytes are written.
|
||||
*
|
||||
* <p> If the bit offset within the stream is non-zero, the
|
||||
* remainder of the current byte is padded with 0s
|
||||
* and written out first. The bit offset will be 0 after the
|
||||
* write.
|
||||
*
|
||||
* @param d an array of <code>doubles</code>s to be written.
|
||||
* @param off the start offset in the data.
|
||||
* @param len the number of <code>double</code>s to write.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>off</code> is
|
||||
* negative, <code>len</code> is negative, or <code>off +
|
||||
* len</code> is greater than <code>d.length</code>.
|
||||
* @exception NullPointerException if <code>d</code> is
|
||||
* <code>null</code>.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeDoubles(double[] d, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a single bit, given by the least significant bit of the
|
||||
* argument, to the stream at the current bit offset within the
|
||||
* current byte position. The upper 31 bits of the argument are
|
||||
* ignored. The given bit replaces the previous bit at that
|
||||
* position. The bit offset is advanced by one and reduced modulo
|
||||
* 8.
|
||||
*
|
||||
* <p> If any bits of a particular byte have never been set
|
||||
* at the time the byte is flushed to the destination, those
|
||||
* bits will be set to 0 automatically.
|
||||
*
|
||||
* @param bit an <code>int</code> whose least significant bit
|
||||
* is to be written to the stream.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeBit(int bit) throws IOException;
|
||||
|
||||
/**
|
||||
* Writes a sequence of bits, given by the <code>numBits</code>
|
||||
* least significant bits of the <code>bits</code> argument in
|
||||
* left-to-right order, to the stream at the current bit offset
|
||||
* within the current byte position. The upper <code>64 -
|
||||
* numBits</code> bits of the argument are ignored. The bit
|
||||
* offset is advanced by <code>numBits</code> and reduced modulo
|
||||
* 8. Note that a bit offset of 0 always indicates the
|
||||
* most-significant bit of the byte, and bytes of bits are written
|
||||
* out in sequence as they are encountered. Thus bit writes are
|
||||
* always effectively in network byte order. The actual stream
|
||||
* byte order setting is ignored.
|
||||
*
|
||||
* <p> Bit data may be accumulated in memory indefinitely, until
|
||||
* <code>flushBefore</code> is called. At that time, all bit data
|
||||
* prior to the flushed position will be written.
|
||||
*
|
||||
* <p> If any bits of a particular byte have never been set
|
||||
* at the time the byte is flushed to the destination, those
|
||||
* bits will be set to 0 automatically.
|
||||
*
|
||||
* @param bits a <code>long</code> containing the bits to be
|
||||
* written, starting with the bit in position <code>numBits -
|
||||
* 1</code> down to the least significant bit.
|
||||
*
|
||||
* @param numBits an <code>int</code> between 0 and 64, inclusive.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>numBits</code> is
|
||||
* not between 0 and 64, inclusive.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void writeBits(long bits, int numBits) throws IOException;
|
||||
|
||||
/**
|
||||
* Flushes all data prior to the given position to the underlying
|
||||
* destination, such as an <code>OutputStream</code> or
|
||||
* <code>File</code>. Attempting to seek to the flushed portion
|
||||
* of the stream will result in an
|
||||
* <code>IndexOutOfBoundsException</code>.
|
||||
*
|
||||
* @param pos a <code>long</code> containing the length of the
|
||||
* stream prefix that may be flushed to the destination.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code> lies
|
||||
* in the flushed portion of the stream or past the current stream
|
||||
* position.
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
void flushBefore(long pos) throws IOException;
|
||||
}
|
||||
510
jdkSrc/jdk8/javax/imageio/stream/ImageOutputStreamImpl.java
Normal file
510
jdkSrc/jdk8/javax/imageio/stream/ImageOutputStreamImpl.java
Normal file
@@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UTFDataFormatException;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* An abstract class implementing the <code>ImageOutputStream</code> interface.
|
||||
* This class is designed to reduce the number of methods that must
|
||||
* be implemented by subclasses.
|
||||
*
|
||||
*/
|
||||
public abstract class ImageOutputStreamImpl
|
||||
extends ImageInputStreamImpl
|
||||
implements ImageOutputStream {
|
||||
|
||||
/**
|
||||
* Constructs an <code>ImageOutputStreamImpl</code>.
|
||||
*/
|
||||
public ImageOutputStreamImpl() {
|
||||
}
|
||||
|
||||
public abstract void write(int b) throws IOException;
|
||||
|
||||
public void write(byte b[]) throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public abstract void write(byte b[], int off, int len) throws IOException;
|
||||
|
||||
public void writeBoolean(boolean v) throws IOException {
|
||||
write(v ? 1 : 0);
|
||||
}
|
||||
|
||||
public void writeByte(int v) throws IOException {
|
||||
write(v);
|
||||
}
|
||||
|
||||
public void writeShort(int v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 8);
|
||||
byteBuf[1] = (byte)(v >>> 0);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
}
|
||||
write(byteBuf, 0, 2);
|
||||
}
|
||||
|
||||
public void writeChar(int v) throws IOException {
|
||||
writeShort(v);
|
||||
}
|
||||
|
||||
public void writeInt(int v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 24);
|
||||
byteBuf[1] = (byte)(v >>> 16);
|
||||
byteBuf[2] = (byte)(v >>> 8);
|
||||
byteBuf[3] = (byte)(v >>> 0);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
byteBuf[2] = (byte)(v >>> 16);
|
||||
byteBuf[3] = (byte)(v >>> 24);
|
||||
}
|
||||
write(byteBuf, 0, 4);
|
||||
}
|
||||
|
||||
public void writeLong(long v) throws IOException {
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
byteBuf[0] = (byte)(v >>> 56);
|
||||
byteBuf[1] = (byte)(v >>> 48);
|
||||
byteBuf[2] = (byte)(v >>> 40);
|
||||
byteBuf[3] = (byte)(v >>> 32);
|
||||
byteBuf[4] = (byte)(v >>> 24);
|
||||
byteBuf[5] = (byte)(v >>> 16);
|
||||
byteBuf[6] = (byte)(v >>> 8);
|
||||
byteBuf[7] = (byte)(v >>> 0);
|
||||
} else {
|
||||
byteBuf[0] = (byte)(v >>> 0);
|
||||
byteBuf[1] = (byte)(v >>> 8);
|
||||
byteBuf[2] = (byte)(v >>> 16);
|
||||
byteBuf[3] = (byte)(v >>> 24);
|
||||
byteBuf[4] = (byte)(v >>> 32);
|
||||
byteBuf[5] = (byte)(v >>> 40);
|
||||
byteBuf[6] = (byte)(v >>> 48);
|
||||
byteBuf[7] = (byte)(v >>> 56);
|
||||
}
|
||||
// REMIND: Once 6277756 is fixed, we should do a bulk write of all 8
|
||||
// bytes here as we do in writeShort() and writeInt() for even better
|
||||
// performance. For now, two bulk writes of 4 bytes each is still
|
||||
// faster than 8 individual write() calls (see 6347575 for details).
|
||||
write(byteBuf, 0, 4);
|
||||
write(byteBuf, 4, 4);
|
||||
}
|
||||
|
||||
public void writeFloat(float v) throws IOException {
|
||||
writeInt(Float.floatToIntBits(v));
|
||||
}
|
||||
|
||||
public void writeDouble(double v) throws IOException {
|
||||
writeLong(Double.doubleToLongBits(v));
|
||||
}
|
||||
|
||||
public void writeBytes(String s) throws IOException {
|
||||
int len = s.length();
|
||||
for (int i = 0 ; i < len ; i++) {
|
||||
write((byte)s.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeChars(String s) throws IOException {
|
||||
int len = s.length();
|
||||
|
||||
byte[] b = new byte[len*2];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len ; i++) {
|
||||
int v = s.charAt(i);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len ; i++) {
|
||||
int v = s.charAt(i);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*2);
|
||||
}
|
||||
|
||||
public void writeUTF(String s) throws IOException {
|
||||
int strlen = s.length();
|
||||
int utflen = 0;
|
||||
char[] charr = new char[strlen];
|
||||
int c, boff = 0;
|
||||
|
||||
s.getChars(0, strlen, charr, 0);
|
||||
|
||||
for (int i = 0; i < strlen; i++) {
|
||||
c = charr[i];
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
utflen++;
|
||||
} else if (c > 0x07FF) {
|
||||
utflen += 3;
|
||||
} else {
|
||||
utflen += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (utflen > 65535) {
|
||||
throw new UTFDataFormatException("utflen > 65536!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[utflen+2];
|
||||
b[boff++] = (byte) ((utflen >>> 8) & 0xFF);
|
||||
b[boff++] = (byte) ((utflen >>> 0) & 0xFF);
|
||||
for (int i = 0; i < strlen; i++) {
|
||||
c = charr[i];
|
||||
if ((c >= 0x0001) && (c <= 0x007F)) {
|
||||
b[boff++] = (byte) c;
|
||||
} else if (c > 0x07FF) {
|
||||
b[boff++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
|
||||
b[boff++] = (byte) (0x80 | ((c >> 6) & 0x3F));
|
||||
b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
|
||||
} else {
|
||||
b[boff++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
|
||||
b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
|
||||
}
|
||||
}
|
||||
write(b, 0, utflen + 2);
|
||||
}
|
||||
|
||||
public void writeShorts(short[] s, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > s.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > s.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*2];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
short v = s[off + i];
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
short v = s[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*2);
|
||||
}
|
||||
|
||||
public void writeChars(char[] c, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > c.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > c.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*2];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
char v = c[off + i];
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
char v = c[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*2);
|
||||
}
|
||||
|
||||
public void writeInts(int[] i, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > i.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*4];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < len; j++) {
|
||||
int v = i[off + j];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*4);
|
||||
}
|
||||
|
||||
public void writeLongs(long[] l, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > l.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > l.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*8];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = l[off + i];
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = l[off + i];
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*8);
|
||||
}
|
||||
|
||||
public void writeFloats(float[] f, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > f.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > f.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*4];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
int v = Float.floatToIntBits(f[off + i]);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
int v = Float.floatToIntBits(f[off + i]);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*4);
|
||||
}
|
||||
|
||||
public void writeDoubles(double[] d, int off, int len) throws IOException {
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if (off < 0 || len < 0 || off + len > d.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off + len > d.length!");
|
||||
}
|
||||
|
||||
byte[] b = new byte[len*8];
|
||||
int boff = 0;
|
||||
if (byteOrder == ByteOrder.BIG_ENDIAN) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = Double.doubleToLongBits(d[off + i]);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < len; i++) {
|
||||
long v = Double.doubleToLongBits(d[off + i]);
|
||||
b[boff++] = (byte)(v >>> 0);
|
||||
b[boff++] = (byte)(v >>> 8);
|
||||
b[boff++] = (byte)(v >>> 16);
|
||||
b[boff++] = (byte)(v >>> 24);
|
||||
b[boff++] = (byte)(v >>> 32);
|
||||
b[boff++] = (byte)(v >>> 40);
|
||||
b[boff++] = (byte)(v >>> 48);
|
||||
b[boff++] = (byte)(v >>> 56);
|
||||
}
|
||||
}
|
||||
|
||||
write(b, 0, len*8);
|
||||
}
|
||||
|
||||
public void writeBit(int bit) throws IOException {
|
||||
writeBits((1L & bit), 1);
|
||||
}
|
||||
|
||||
public void writeBits(long bits, int numBits) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (numBits < 0 || numBits > 64) {
|
||||
throw new IllegalArgumentException("Bad value for numBits!");
|
||||
}
|
||||
if (numBits == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prologue: deal with pre-existing bits
|
||||
|
||||
// Bug 4499158, 4507868 - if we're at the beginning of the stream
|
||||
// and the bit offset is 0, there can't be any pre-existing bits
|
||||
if ((getStreamPosition() > 0) || (bitOffset > 0)) {
|
||||
int offset = bitOffset; // read() will reset bitOffset
|
||||
int partialByte = read();
|
||||
if (partialByte != -1) {
|
||||
seek(getStreamPosition() - 1);
|
||||
} else {
|
||||
partialByte = 0;
|
||||
}
|
||||
|
||||
if (numBits + offset < 8) {
|
||||
// Notch out the partial byte and drop in the new bits
|
||||
int shift = 8 - (offset+numBits);
|
||||
int mask = -1 >>> (32 - numBits);
|
||||
partialByte &= ~(mask << shift); // Clear out old bits
|
||||
partialByte |= ((bits & mask) << shift); // Or in new ones
|
||||
write(partialByte);
|
||||
seek(getStreamPosition() - 1);
|
||||
bitOffset = offset + numBits;
|
||||
numBits = 0; // Signal that we are done
|
||||
} else {
|
||||
// Fill out the partial byte and reduce numBits
|
||||
int num = 8 - offset;
|
||||
int mask = -1 >>> (32 - num);
|
||||
partialByte &= ~mask; // Clear out bits
|
||||
partialByte |= ((bits >> (numBits - num)) & mask);
|
||||
// Note that bitOffset is already 0, so there is no risk
|
||||
// of this advancing to the next byte
|
||||
write(partialByte);
|
||||
numBits -= num;
|
||||
}
|
||||
}
|
||||
|
||||
// Now write any whole bytes
|
||||
if (numBits > 7) {
|
||||
int extra = numBits % 8;
|
||||
for (int numBytes = numBits / 8; numBytes > 0; numBytes--) {
|
||||
int shift = (numBytes-1)*8+extra;
|
||||
int value = (int) ((shift == 0)
|
||||
? bits & 0xFF
|
||||
: (bits>>shift) & 0xFF);
|
||||
write(value);
|
||||
}
|
||||
numBits = extra;
|
||||
}
|
||||
|
||||
// Epilogue: write out remaining partial byte, if any
|
||||
// Note that we may be at EOF, in which case we pad with 0,
|
||||
// or not, in which case we must preserve the existing bits
|
||||
if (numBits != 0) {
|
||||
// If we are not at the end of the file, read the current byte
|
||||
// If we are at the end of the file, initialize our byte to 0.
|
||||
int partialByte = 0;
|
||||
partialByte = read();
|
||||
if (partialByte != -1) {
|
||||
seek(getStreamPosition() - 1);
|
||||
}
|
||||
// Fix 4494976: writeBit(int) does not pad the remainder
|
||||
// of the current byte with 0s
|
||||
else { // EOF
|
||||
partialByte = 0;
|
||||
}
|
||||
|
||||
int shift = 8 - numBits;
|
||||
int mask = -1 >>> (32 - numBits);
|
||||
partialByte &= ~(mask << shift);
|
||||
partialByte |= (bits & mask) << shift;
|
||||
// bitOffset is always already 0 when we get here.
|
||||
write(partialByte);
|
||||
seek(getStreamPosition() - 1);
|
||||
bitOffset = numBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the bit offset is non-zero, forces the remaining bits
|
||||
* in the current byte to 0 and advances the stream position
|
||||
* by one. This method should be called by subclasses at the
|
||||
* beginning of the <code>write(int)</code> and
|
||||
* <code>write(byte[], int, int)</code> methods.
|
||||
*
|
||||
* @exception IOException if an I/O error occurs.
|
||||
*/
|
||||
protected final void flushBits() throws IOException {
|
||||
checkClosed();
|
||||
if (bitOffset != 0) {
|
||||
int offset = bitOffset;
|
||||
int partialByte = read(); // Sets bitOffset to 0
|
||||
if (partialByte < 0) {
|
||||
// Fix 4465683: When bitOffset is set
|
||||
// to something non-zero beyond EOF,
|
||||
// we should set that whole byte to
|
||||
// zero and write it to stream.
|
||||
partialByte = 0;
|
||||
bitOffset = 0;
|
||||
}
|
||||
else {
|
||||
seek(getStreamPosition() - 1);
|
||||
partialByte &= -1 << (8 - offset);
|
||||
}
|
||||
write(partialByte);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
364
jdkSrc/jdk8/javax/imageio/stream/MemoryCache.java
Normal file
364
jdkSrc/jdk8/javax/imageio/stream/MemoryCache.java
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Package-visible class consolidating common code for
|
||||
* <code>MemoryCacheImageInputStream</code> and
|
||||
* <code>MemoryCacheImageOutputStream</code>.
|
||||
* This class keeps an <code>ArrayList</code> of 8K blocks,
|
||||
* loaded sequentially. Blocks may only be disposed of
|
||||
* from the index 0 forward. As blocks are freed, the
|
||||
* corresponding entries in the array list are set to
|
||||
* <code>null</code>, but no compacting is performed.
|
||||
* This allows the index for each block to never change,
|
||||
* and the length of the cache is always the same as the
|
||||
* total amount of data ever cached. Cached data is
|
||||
* therefore always contiguous from the point of last
|
||||
* disposal to the current length.
|
||||
*
|
||||
* <p> The total number of blocks resident in the cache must not
|
||||
* exceed <code>Integer.MAX_VALUE</code>. In practice, the limit of
|
||||
* available memory will be exceeded long before this becomes an
|
||||
* issue, since a full cache would contain 8192*2^31 = 16 terabytes of
|
||||
* data.
|
||||
*
|
||||
* A <code>MemoryCache</code> may be reused after a call
|
||||
* to <code>reset()</code>.
|
||||
*/
|
||||
class MemoryCache {
|
||||
|
||||
private static final int BUFFER_LENGTH = 8192;
|
||||
|
||||
private ArrayList cache = new ArrayList();
|
||||
|
||||
private long cacheStart = 0L;
|
||||
|
||||
/**
|
||||
* The largest position ever written to the cache.
|
||||
*/
|
||||
private long length = 0L;
|
||||
|
||||
private byte[] getCacheBlock(long blockNum) throws IOException {
|
||||
long blockOffset = blockNum - cacheStart;
|
||||
if (blockOffset > Integer.MAX_VALUE) {
|
||||
// This can only happen when the cache hits 16 terabytes of
|
||||
// contiguous data...
|
||||
throw new IOException("Cache addressing limit exceeded!");
|
||||
}
|
||||
return (byte[])cache.get((int)blockOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that at least <code>pos</code> bytes are cached,
|
||||
* or the end of the source is reached. The return value
|
||||
* is equal to the smaller of <code>pos</code> and the
|
||||
* length of the source.
|
||||
*/
|
||||
public long loadFromStream(InputStream stream, long pos)
|
||||
throws IOException {
|
||||
// We've already got enough data cached
|
||||
if (pos < length) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
int offset = (int)(length % BUFFER_LENGTH);
|
||||
byte [] buf = null;
|
||||
|
||||
long len = pos - length;
|
||||
if (offset != 0) {
|
||||
buf = getCacheBlock(length/BUFFER_LENGTH);
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
if (buf == null) {
|
||||
try {
|
||||
buf = new byte[BUFFER_LENGTH];
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new IOException("No memory left for cache!");
|
||||
}
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
int left = BUFFER_LENGTH - offset;
|
||||
int nbytes = (int)Math.min(len, (long)left);
|
||||
nbytes = stream.read(buf, offset, nbytes);
|
||||
if (nbytes == -1) {
|
||||
return length; // EOF
|
||||
}
|
||||
|
||||
if (offset == 0) {
|
||||
cache.add(buf);
|
||||
}
|
||||
|
||||
len -= nbytes;
|
||||
length += nbytes;
|
||||
offset += nbytes;
|
||||
|
||||
if (offset >= BUFFER_LENGTH) {
|
||||
// we've filled the current buffer, so a new one will be
|
||||
// allocated next time around (and offset will be reset to 0)
|
||||
buf = null;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes out a portion of the cache to an <code>OutputStream</code>.
|
||||
* This method preserves no state about the output stream, and does
|
||||
* not dispose of any blocks containing bytes written. To dispose
|
||||
* blocks, use {@link #disposeBefore <code>disposeBefore()</code>}.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if any portion of
|
||||
* the requested data is not in the cache (including if <code>pos</code>
|
||||
* is in a block already disposed), or if either <code>pos</code> or
|
||||
* <code>len</code> is < 0.
|
||||
*/
|
||||
public void writeToStream(OutputStream stream, long pos, long len)
|
||||
throws IOException {
|
||||
if (pos + len > length) {
|
||||
throw new IndexOutOfBoundsException("Argument out of cache");
|
||||
}
|
||||
if ((pos < 0) || (len < 0)) {
|
||||
throw new IndexOutOfBoundsException("Negative pos or len");
|
||||
}
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
long bufIndex = pos/BUFFER_LENGTH;
|
||||
if (bufIndex < cacheStart) {
|
||||
throw new IndexOutOfBoundsException("pos already disposed");
|
||||
}
|
||||
int offset = (int)(pos % BUFFER_LENGTH);
|
||||
|
||||
byte[] buf = getCacheBlock(bufIndex++);
|
||||
while (len > 0) {
|
||||
if (buf == null) {
|
||||
buf = getCacheBlock(bufIndex++);
|
||||
offset = 0;
|
||||
}
|
||||
int nbytes = (int)Math.min(len, (long)(BUFFER_LENGTH - offset));
|
||||
stream.write(buf, offset, nbytes);
|
||||
buf = null;
|
||||
len -= nbytes;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there is space to write a byte at the given position.
|
||||
*/
|
||||
private void pad(long pos) throws IOException {
|
||||
long currIndex = cacheStart + cache.size() - 1;
|
||||
long lastIndex = pos/BUFFER_LENGTH;
|
||||
long numNewBuffers = lastIndex - currIndex;
|
||||
for (long i = 0; i < numNewBuffers; i++) {
|
||||
try {
|
||||
cache.add(new byte[BUFFER_LENGTH]);
|
||||
} catch (OutOfMemoryError e) {
|
||||
throw new IOException("No memory left for cache!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites and/or appends the cache from a byte array.
|
||||
* The length of the cache will be extended as needed to hold
|
||||
* the incoming data.
|
||||
*
|
||||
* @param b an array of bytes containing data to be written.
|
||||
* @param off the starting offset withing the data array.
|
||||
* @param len the number of bytes to be written.
|
||||
* @param pos the cache position at which to begin writing.
|
||||
*
|
||||
* @exception NullPointerException if <code>b</code> is <code>null</code>.
|
||||
* @exception IndexOutOfBoundsException if <code>off</code>,
|
||||
* <code>len</code>, or <code>pos</code> are negative,
|
||||
* or if <code>off+len > b.length</code>.
|
||||
*/
|
||||
public void write(byte[] b, int off, int len, long pos)
|
||||
throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if ((off < 0) || (len < 0) || (pos < 0) ||
|
||||
(off + len > b.length) || (off + len < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
// Ensure there is space for the incoming data
|
||||
long lastPos = pos + len - 1;
|
||||
if (lastPos >= length) {
|
||||
pad(lastPos);
|
||||
length = lastPos + 1;
|
||||
}
|
||||
|
||||
// Copy the data into the cache, block by block
|
||||
int offset = (int)(pos % BUFFER_LENGTH);
|
||||
while (len > 0) {
|
||||
byte[] buf = getCacheBlock(pos/BUFFER_LENGTH);
|
||||
int nbytes = Math.min(len, BUFFER_LENGTH - offset);
|
||||
System.arraycopy(b, off, buf, offset, nbytes);
|
||||
|
||||
pos += nbytes;
|
||||
off += nbytes;
|
||||
len -= nbytes;
|
||||
offset = 0; // Always after the first time
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites or appends a single byte to the cache.
|
||||
* The length of the cache will be extended as needed to hold
|
||||
* the incoming data.
|
||||
*
|
||||
* @param b an <code>int</code> whose 8 least significant bits
|
||||
* will be written.
|
||||
* @param pos the cache position at which to begin writing.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code> is negative.
|
||||
*/
|
||||
public void write(int b, long pos) throws IOException {
|
||||
if (pos < 0) {
|
||||
throw new ArrayIndexOutOfBoundsException("pos < 0");
|
||||
}
|
||||
|
||||
// Ensure there is space for the incoming data
|
||||
if (pos >= length) {
|
||||
pad(pos);
|
||||
length = pos + 1;
|
||||
}
|
||||
|
||||
// Insert the data.
|
||||
byte[] buf = getCacheBlock(pos/BUFFER_LENGTH);
|
||||
int offset = (int)(pos % BUFFER_LENGTH);
|
||||
buf[offset] = (byte)b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total length of data that has been cached,
|
||||
* regardless of whether any early blocks have been disposed.
|
||||
* This value will only ever increase.
|
||||
*/
|
||||
public long getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the single byte at the given position, as an
|
||||
* <code>int</code>. Returns -1 if this position has
|
||||
* not been cached or has been disposed.
|
||||
*/
|
||||
public int read(long pos) throws IOException {
|
||||
if (pos >= length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte[] buf = getCacheBlock(pos/BUFFER_LENGTH);
|
||||
if (buf == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return buf[(int)(pos % BUFFER_LENGTH)] & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy <code>len</code> bytes from the cache, starting
|
||||
* at cache position <code>pos</code>, into the array
|
||||
* <code>b</code> at offset <code>off</code>.
|
||||
*
|
||||
* @exception NullPointerException if b is <code>null</code>
|
||||
* @exception IndexOutOfBoundsException if <code>off</code>,
|
||||
* <code>len</code> or <code>pos</code> are negative or if
|
||||
* <code>off + len > b.length</code> or if any portion of the
|
||||
* requested data is not in the cache (including if
|
||||
* <code>pos</code> is in a block that has already been disposed).
|
||||
*/
|
||||
public void read(byte[] b, int off, int len, long pos)
|
||||
throws IOException {
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
// Fix 4430357 - if off + len < 0, overflow occurred
|
||||
if ((off < 0) || (len < 0) || (pos < 0) ||
|
||||
(off + len > b.length) || (off + len < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if (pos + len > length) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
long index = pos/BUFFER_LENGTH;
|
||||
int offset = (int)pos % BUFFER_LENGTH;
|
||||
while (len > 0) {
|
||||
int nbytes = Math.min(len, BUFFER_LENGTH - offset);
|
||||
byte[] buf = getCacheBlock(index++);
|
||||
System.arraycopy(buf, offset, b, off, nbytes);
|
||||
|
||||
len -= nbytes;
|
||||
off += nbytes;
|
||||
offset = 0; // Always after the first time
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the blocks up to the position <code>pos</code>.
|
||||
* The byte at <code>pos</code> remains available.
|
||||
*
|
||||
* @exception IndexOutOfBoundsException if <code>pos</code>
|
||||
* is in a block that has already been disposed.
|
||||
*/
|
||||
public void disposeBefore(long pos) {
|
||||
long index = pos/BUFFER_LENGTH;
|
||||
if (index < cacheStart) {
|
||||
throw new IndexOutOfBoundsException("pos already disposed");
|
||||
}
|
||||
long numBlocks = Math.min(index - cacheStart, cache.size());
|
||||
for (long i = 0; i < numBlocks; i++) {
|
||||
cache.remove(0);
|
||||
}
|
||||
this.cacheStart = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erase the entire cache contents and reset the length to 0.
|
||||
* The cache object may subsequently be reused as though it had just
|
||||
* been allocated.
|
||||
*/
|
||||
public void reset() {
|
||||
cache.clear();
|
||||
cacheStart = 0;
|
||||
length = 0L;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import com.sun.imageio.stream.StreamFinalizer;
|
||||
import sun.java2d.Disposer;
|
||||
import sun.java2d.DisposerRecord;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageInputStream</code> that gets its
|
||||
* input from a regular <code>InputStream</code>. A memory buffer is
|
||||
* used to cache at least the data between the discard position and
|
||||
* the current read position.
|
||||
*
|
||||
* <p> In general, it is preferable to use a
|
||||
* <code>FileCacheImageInputStream</code> when reading from a regular
|
||||
* <code>InputStream</code>. This class is provided for cases where
|
||||
* it is not possible to create a writable temporary file.
|
||||
*
|
||||
*/
|
||||
public class MemoryCacheImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
private InputStream stream;
|
||||
|
||||
private MemoryCache cache = new MemoryCache();
|
||||
|
||||
/** The referent to be registered with the Disposer. */
|
||||
private final Object disposerReferent;
|
||||
|
||||
/** The DisposerRecord that resets the underlying MemoryCache. */
|
||||
private final DisposerRecord disposerRecord;
|
||||
|
||||
/**
|
||||
* Constructs a <code>MemoryCacheImageInputStream</code> that will read
|
||||
* from a given <code>InputStream</code>.
|
||||
*
|
||||
* @param stream an <code>InputStream</code> to read from.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>stream</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public MemoryCacheImageInputStream(InputStream stream) {
|
||||
if (stream == null) {
|
||||
throw new IllegalArgumentException("stream == null!");
|
||||
}
|
||||
this.stream = stream;
|
||||
|
||||
disposerRecord = new StreamDisposerRecord(cache);
|
||||
if (getClass() == MemoryCacheImageInputStream.class) {
|
||||
disposerReferent = new Object();
|
||||
Disposer.addRecord(disposerReferent, disposerRecord);
|
||||
} else {
|
||||
disposerReferent = new StreamFinalizer(this);
|
||||
}
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
bitOffset = 0;
|
||||
long pos = cache.loadFromStream(stream, streamPos+1);
|
||||
if (pos >= streamPos+1) {
|
||||
return cache.read(streamPos++);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
|
||||
}
|
||||
|
||||
bitOffset = 0;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long pos = cache.loadFromStream(stream, streamPos+len);
|
||||
|
||||
len = (int)(pos - streamPos); // In case stream ended early
|
||||
|
||||
if (len > 0) {
|
||||
cache.read(b, off, len, streamPos);
|
||||
streamPos += len;
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void flushBefore(long pos) throws IOException {
|
||||
super.flushBefore(pos); // this will call checkClosed() for us
|
||||
cache.disposeBefore(pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageInputStream</code> caches data in order to allow
|
||||
* seeking backwards.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCachedMemory
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>false</code> since this
|
||||
* <code>ImageInputStream</code> does not maintain a file cache.
|
||||
*
|
||||
* @return <code>false</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedMemory
|
||||
*/
|
||||
public boolean isCachedFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageInputStream</code> maintains a main memory cache.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCachedMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this <code>MemoryCacheImageInputStream</code>, freeing
|
||||
* the cache. The source <code>InputStream</code> is not closed.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
disposerRecord.dispose(); // this resets the MemoryCache
|
||||
stream = null;
|
||||
cache = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void finalize() throws Throwable {
|
||||
// Empty finalizer: for performance reasons we instead use the
|
||||
// Disposer mechanism for ensuring that the underlying
|
||||
// MemoryCache is reset prior to garbage collection
|
||||
}
|
||||
|
||||
private static class StreamDisposerRecord implements DisposerRecord {
|
||||
private MemoryCache cache;
|
||||
|
||||
public StreamDisposerRecord(MemoryCache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public synchronized void dispose() {
|
||||
if (cache != null) {
|
||||
cache.reset();
|
||||
cache = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.imageio.stream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* An implementation of <code>ImageOutputStream</code> that writes its
|
||||
* output to a regular <code>OutputStream</code>. A memory buffer is
|
||||
* used to cache at least the data between the discard position and
|
||||
* the current write position. The only constructor takes an
|
||||
* <code>OutputStream</code>, so this class may not be used for
|
||||
* read/modify/write operations. Reading can occur only on parts of
|
||||
* the stream that have already been written to the cache and not
|
||||
* yet flushed.
|
||||
*
|
||||
*/
|
||||
public class MemoryCacheImageOutputStream extends ImageOutputStreamImpl {
|
||||
|
||||
private OutputStream stream;
|
||||
|
||||
private MemoryCache cache = new MemoryCache();
|
||||
|
||||
/**
|
||||
* Constructs a <code>MemoryCacheImageOutputStream</code> that will write
|
||||
* to a given <code>OutputStream</code>.
|
||||
*
|
||||
* @param stream an <code>OutputStream</code> to write to.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>stream</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public MemoryCacheImageOutputStream(OutputStream stream) {
|
||||
if (stream == null) {
|
||||
throw new IllegalArgumentException("stream == null!");
|
||||
}
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
checkClosed();
|
||||
|
||||
bitOffset = 0;
|
||||
|
||||
int val = cache.read(streamPos);
|
||||
if (val != -1) {
|
||||
++streamPos;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
checkClosed();
|
||||
|
||||
if (b == null) {
|
||||
throw new NullPointerException("b == null!");
|
||||
}
|
||||
// Fix 4467608: read([B,I,I) works incorrectly if len<=0
|
||||
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
|
||||
throw new IndexOutOfBoundsException
|
||||
("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
|
||||
}
|
||||
|
||||
bitOffset = 0;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check if we're already at/past EOF i.e.
|
||||
// no more bytes left to read from cache
|
||||
long bytesLeftInCache = cache.getLength() - streamPos;
|
||||
if (bytesLeftInCache <= 0) {
|
||||
return -1; // EOF
|
||||
}
|
||||
|
||||
// guaranteed by now that bytesLeftInCache > 0 && len > 0
|
||||
// and so the rest of the error checking is done by cache.read()
|
||||
// NOTE that alot of error checking is duplicated
|
||||
len = (int)Math.min(bytesLeftInCache, (long)len);
|
||||
cache.read(b, off, len, streamPos);
|
||||
streamPos += len;
|
||||
return len;
|
||||
}
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
cache.write(b, streamPos);
|
||||
++streamPos;
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
flushBits(); // this will call checkClosed() for us
|
||||
cache.write(b, off, len, streamPos);
|
||||
streamPos += len;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
try {
|
||||
checkClosed();
|
||||
return cache.getLength();
|
||||
} catch (IOException e) {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageOutputStream</code> caches data in order to allow
|
||||
* seeking backwards.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCachedMemory
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>false</code> since this
|
||||
* <code>ImageOutputStream</code> does not maintain a file cache.
|
||||
*
|
||||
* @return <code>false</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedMemory
|
||||
*/
|
||||
public boolean isCachedFile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> since this
|
||||
* <code>ImageOutputStream</code> maintains a main memory cache.
|
||||
*
|
||||
* @return <code>true</code>.
|
||||
*
|
||||
* @see #isCached
|
||||
* @see #isCachedFile
|
||||
*/
|
||||
public boolean isCachedMemory() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this <code>MemoryCacheImageOutputStream</code>. All
|
||||
* pending data is flushed to the output, and the cache
|
||||
* is released. The destination <code>OutputStream</code>
|
||||
* is not closed.
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
long length = cache.getLength();
|
||||
seek(length);
|
||||
flushBefore(length);
|
||||
super.close();
|
||||
cache.reset();
|
||||
cache = null;
|
||||
stream = null;
|
||||
}
|
||||
|
||||
public void flushBefore(long pos) throws IOException {
|
||||
long oFlushedPos = flushedPos;
|
||||
super.flushBefore(pos); // this will call checkClosed() for us
|
||||
|
||||
long flushBytes = flushedPos - oFlushedPos;
|
||||
cache.writeToStream(stream, oFlushedPos, flushBytes);
|
||||
cache.disposeBefore(flushedPos);
|
||||
stream.flush();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user