replace a small part (BufferedImage ff) of classpath with OpenJDK

This commit is contained in:
smallsql 2008-12-19 09:53:42 +00:00
Родитель 344924593f
Коммит 08fbc6b63b
10 изменённых файлов: 8084 добавлений и 11 удалений

Просмотреть файл

@ -346,24 +346,15 @@
../../classpath-0.95/java/awt/image/AreaAveragingScaleFilter.java ../../classpath-0.95/java/awt/image/AreaAveragingScaleFilter.java
../../classpath-0.95/java/awt/image/BandCombineOp.java ../../classpath-0.95/java/awt/image/BandCombineOp.java
../../classpath-0.95/java/awt/image/BandedSampleModel.java ../../classpath-0.95/java/awt/image/BandedSampleModel.java
../../classpath-0.95/java/awt/image/BufferedImage.java
../../classpath-0.95/java/awt/image/BufferedImageFilter.java ../../classpath-0.95/java/awt/image/BufferedImageFilter.java
../../classpath-0.95/java/awt/image/BufferedImageOp.java ../../classpath-0.95/java/awt/image/BufferedImageOp.java
../../classpath-0.95/java/awt/image/BufferStrategy.java ../../classpath-0.95/java/awt/image/BufferStrategy.java
../../classpath-0.95/java/awt/image/ByteLookupTable.java ../../classpath-0.95/java/awt/image/ByteLookupTable.java
../../classpath-0.95/java/awt/image/ColorConvertOp.java
../../classpath-0.95/java/awt/image/ColorModel.java ../../classpath-0.95/java/awt/image/ColorModel.java
../../classpath-0.95/java/awt/image/ComponentColorModel.java ../../classpath-0.95/java/awt/image/ComponentColorModel.java
../../classpath-0.95/java/awt/image/ComponentSampleModel.java ../../classpath-0.95/java/awt/image/ComponentSampleModel.java
../../classpath-0.95/java/awt/image/ConvolveOp.java ../../classpath-0.95/java/awt/image/ConvolveOp.java
../../classpath-0.95/java/awt/image/CropImageFilter.java ../../classpath-0.95/java/awt/image/CropImageFilter.java
../../classpath-0.95/java/awt/image/DataBuffer.java
../../classpath-0.95/java/awt/image/DataBufferByte.java
../../classpath-0.95/java/awt/image/DataBufferDouble.java
../../classpath-0.95/java/awt/image/DataBufferFloat.java
../../classpath-0.95/java/awt/image/DataBufferInt.java
../../classpath-0.95/java/awt/image/DataBufferShort.java
../../classpath-0.95/java/awt/image/DataBufferUShort.java
../../classpath-0.95/java/awt/image/DirectColorModel.java ../../classpath-0.95/java/awt/image/DirectColorModel.java
../../classpath-0.95/java/awt/image/FilteredImageSource.java ../../classpath-0.95/java/awt/image/FilteredImageSource.java
../../classpath-0.95/java/awt/image/ImageConsumer.java ../../classpath-0.95/java/awt/image/ImageConsumer.java
@ -380,7 +371,6 @@
../../classpath-0.95/java/awt/image/PackedColorModel.java ../../classpath-0.95/java/awt/image/PackedColorModel.java
../../classpath-0.95/java/awt/image/PixelGrabber.java ../../classpath-0.95/java/awt/image/PixelGrabber.java
../../classpath-0.95/java/awt/image/PixelInterleavedSampleModel.java ../../classpath-0.95/java/awt/image/PixelInterleavedSampleModel.java
../../classpath-0.95/java/awt/image/Raster.java
../../classpath-0.95/java/awt/image/RasterFormatException.java ../../classpath-0.95/java/awt/image/RasterFormatException.java
../../classpath-0.95/java/awt/image/RasterOp.java ../../classpath-0.95/java/awt/image/RasterOp.java
../../classpath-0.95/java/awt/image/renderable/ContextualRenderedImageFactory.java ../../classpath-0.95/java/awt/image/renderable/ContextualRenderedImageFactory.java
@ -1039,13 +1029,14 @@
../classpath/java/util/concurrent/atomic/AtomicReferenceArray.java ../classpath/java/util/concurrent/atomic/AtomicReferenceArray.java
../classpath/sun/misc/Ref.java ../classpath/sun/misc/Ref.java
AssemblyInfo.java AssemblyInfo.java
ByteInterleavedRaster.java
Configuration.java Configuration.java
ConnectorBootstrap.java ConnectorBootstrap.java
com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java com/sun/imageio/plugins/jpeg/JPEGImageReaderSpi.java
com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java com/sun/imageio/plugins/jpeg/JPEGImageWriterSpi.java
ikvm/internal/AnnotationAttributeBase.java ikvm/internal/AnnotationAttributeBase.java
ikvm/internal/FieldReflectorBase.java ikvm/internal/FieldReflectorBase.java
java/awt/image/BufferedImage.java
java/awt/image/ColorConvertOp.java
java/io/DeleteOnExitHook.java java/io/DeleteOnExitHook.java
java/io/FileDescriptor.java java/io/FileDescriptor.java
java/io/FileInputStream.java java/io/FileInputStream.java
@ -1094,6 +1085,12 @@ java/util/zip/ZipEntry.java
java/util/zip/ZipFile.java java/util/zip/ZipFile.java
ServiceUI.java ServiceUI.java
sun/awt/AppContext.java sun/awt/AppContext.java
sun/awt/image/ByteComponentRaster.java
sun/awt/image/BytePackedRaster.java
sun/awt/image/IntegerComponentRaster.java
sun/awt/image/OffScreenImageSource.java
sun/awt/image/ShortComponentRaster.java
sun/awt/image/SunWritableRaster.java
sun/management/ManagementFactory.java sun/management/ManagementFactory.java
sun/misc/FileURLMapper.java sun/misc/FileURLMapper.java
sun/misc/Launcher.java sun/misc/Launcher.java
@ -7415,6 +7412,14 @@ SystemProperties.java
../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java ../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java
../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java ../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/util/AbstractSaslImpl.java
../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/util/PolicyUtils.java ../../openjdk6-b12/jdk/src/share/classes/com/sun/security/sasl/util/PolicyUtils.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBuffer.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferByte.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferDouble.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferFloat.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferInt.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferShort.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/DataBufferUShort.java
../../openjdk6-b12/jdk/src/share/classes/java/awt/image/Raster.java
../../openjdk6-b12/jdk/src/share/classes/java/beans/AppletInitializer.java ../../openjdk6-b12/jdk/src/share/classes/java/beans/AppletInitializer.java
../../openjdk6-b12/jdk/src/share/classes/java/beans/BeanDescriptor.java ../../openjdk6-b12/jdk/src/share/classes/java/beans/BeanDescriptor.java
../../openjdk6-b12/jdk/src/share/classes/java/beans/BeanInfo.java ../../openjdk6-b12/jdk/src/share/classes/java/beans/BeanInfo.java
@ -9226,6 +9231,11 @@ SystemProperties.java
../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java ../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java
../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java ../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java
../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java ../../openjdk6-b12/jdk/src/share/classes/org/relaxng/datatype/helpers/StreamingValidatorImpl.java
../../openjdk6-b12/jdk/src/share/classes/sun/awt/image/ByteBandedRaster.java
../../openjdk6-b12/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java
../../openjdk6-b12/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java
../../openjdk6-b12/jdk/src/share/classes/sun/awt/image/ShortBandedRaster.java
../../openjdk6-b12/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java
../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/BooleanEditor.java ../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/BooleanEditor.java
../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/ByteEditor.java ../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/ByteEditor.java
../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/ColorEditor.java ../../openjdk6-b12/jdk/src/share/classes/sun/beans/editors/ColorEditor.java
@ -9571,6 +9581,9 @@ SystemProperties.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/Disposer.java ../../openjdk6-b12/jdk/src/share/classes/sun/java2d/Disposer.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/DisposerRecord.java ../../openjdk6-b12/jdk/src/share/classes/sun/java2d/DisposerRecord.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/DisposerTarget.java ../../openjdk6-b12/jdk/src/share/classes/sun/java2d/DisposerTarget.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/StateTrackable.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/StateTrackableDelegate.java
../../openjdk6-b12/jdk/src/share/classes/sun/java2d/StateTracker.java
../../openjdk6-b12/jdk/src/share/classes/sun/management/LazyCompositeData.java ../../openjdk6-b12/jdk/src/share/classes/sun/management/LazyCompositeData.java
../../openjdk6-b12/jdk/src/share/classes/sun/management/LockDataConverter.java ../../openjdk6-b12/jdk/src/share/classes/sun/management/LockDataConverter.java
../../openjdk6-b12/jdk/src/share/classes/sun/management/LockDataConverterMXBean.java ../../openjdk6-b12/jdk/src/share/classes/sun/management/LockDataConverterMXBean.java

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,537 @@
/* ColorConvertOp.java --
Copyright (C) 2004, 2006 Free Software Foundation
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 for more details.
You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
Linking this library statically or dynamically with other modules is
making a combined work based on this library. Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module. An independent module is a module which is not derived from
or based on this library. If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
package java.awt.image;
import gnu.java.awt.Buffers;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* ColorConvertOp is a filter for converting images or rasters between
* colorspaces, either through a sequence of colorspaces or just from source to
* destination.
*
* Color conversion is done on the color components without alpha. Thus
* if a BufferedImage has alpha premultiplied, this is divided out before
* color conversion, and premultiplication applied if the destination
* requires it.
*
* Color rendering and dithering hints may be applied if specified. This is
* likely platform-dependent.
*
* @author jlquinn@optonline.net
*/
public class ColorConvertOp implements BufferedImageOp, RasterOp
{
private RenderingHints hints;
private ICC_Profile[] profiles = null;
private ColorSpace[] spaces;
/**
* Convert a BufferedImage through a ColorSpace.
*
* Objects created with this constructor can be used to convert
* BufferedImage's to a destination ColorSpace. Attempts to convert Rasters
* with this constructor will result in an IllegalArgumentException when the
* filter(Raster, WritableRaster) method is called.
*
* @param cspace The target color space.
* @param hints Rendering hints to use in conversion, if any (may be null)
* @throws NullPointerException if the ColorSpace is null.
*/
public ColorConvertOp(ColorSpace cspace, RenderingHints hints)
{
if (cspace == null)
throw new NullPointerException();
spaces = new ColorSpace[]{cspace};
this.hints = hints;
}
/**
* Convert from a source colorspace to a destination colorspace.
*
* This constructor takes two ColorSpace arguments as the source and
* destination color spaces. It is usually used with the
* filter(Raster, WritableRaster) method, in which case the source colorspace
* is assumed to correspond to the source Raster, and the destination
* colorspace with the destination Raster.
*
* If used with BufferedImages that do not match the source or destination
* colorspaces specified here, there is an implicit conversion from the
* source image to the source ColorSpace, or the destination ColorSpace to
* the destination image.
*
* @param srcCspace The source ColorSpace.
* @param dstCspace The destination ColorSpace.
* @param hints Rendering hints to use in conversion, if any (may be null).
* @throws NullPointerException if any ColorSpace is null.
*/
public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
RenderingHints hints)
{
if (srcCspace == null || dstCspace == null)
throw new NullPointerException();
spaces = new ColorSpace[]{srcCspace, dstCspace};
this.hints = hints;
}
/**
* Convert from a source colorspace to a destinatino colorspace.
*
* This constructor builds a ColorConvertOp from an array of ICC_Profiles.
* The source will be converted through the sequence of color spaces
* defined by the profiles. If the sequence of profiles doesn't give a
* well-defined conversion, an IllegalArgumentException is thrown.
*
* If used with BufferedImages that do not match the source or destination
* colorspaces specified here, there is an implicit conversion from the
* source image to the source ColorSpace, or the destination ColorSpace to
* the destination image.
*
* For Rasters, the first and last profiles must have the same number of
* bands as the source and destination Rasters, respectively. If this is
* not the case, or there fewer than 2 profiles, an IllegalArgumentException
* will be thrown.
*
* @param profiles An array of ICC_Profile's to convert through.
* @param hints Rendering hints to use in conversion, if any (may be null).
* @throws NullPointerException if the profile array is null.
* @throws IllegalArgumentException if the array is not a well-defined
* conversion.
*/
public ColorConvertOp(ICC_Profile[] profiles, RenderingHints hints)
{
if (profiles == null)
throw new NullPointerException();
this.hints = hints;
this.profiles = profiles;
// Create colorspace array with space for src and dest colorspace
// Note that the ICC_ColorSpace constructor will throw an
// IllegalArgumentException if the profile is invalid; thus we check
// for a "well defined conversion"
spaces = new ColorSpace[profiles.length];
for (int i = 0; i < profiles.length; i++)
spaces[i] = new ICC_ColorSpace(profiles[i]);
}
/**
* Convert from source color space to destination color space.
*
* Only valid for BufferedImage objects, this Op converts from the source
* image's color space to the destination image's color space.
*
* The destination in the filter(BufferedImage, BufferedImage) method cannot
* be null for this operation, and it also cannot be used with the
* filter(Raster, WritableRaster) method.
*
* @param hints Rendering hints to use in conversion, if any (may be null).
*/
public ColorConvertOp(RenderingHints hints)
{
this.hints = hints;
spaces = new ColorSpace[0];
}
/**
* Converts the source image using the conversion path specified in the
* constructor. The resulting image is stored in the destination image if one
* is provided; otherwise a new BufferedImage is created and returned.
*
* The source and destination BufferedImage (if one is supplied) must have
* the same dimensions.
*
* @param src The source image.
* @param dst The destination image.
* @throws IllegalArgumentException if the rasters and/or color spaces are
* incompatible.
* @return The transformed image.
*/
public final BufferedImage filter(BufferedImage src, BufferedImage dst)
{
// TODO: The plan is to create a scanline buffer for intermediate buffers.
// For now we just suck it up and create intermediate buffers.
if (dst == null && spaces.length == 0)
throw new IllegalArgumentException("Not enough color space information "
+ "to complete conversion.");
if (dst != null
&& (src.getHeight() != dst.getHeight() || src.getWidth() != dst.getWidth()))
throw new IllegalArgumentException("Source and destination images have "
+ "different dimensions");
// Make sure input isn't premultiplied by alpha
if (src.isAlphaPremultiplied())
{
BufferedImage tmp = createCompatibleDestImage(src, src.getColorModel());
copyimage(src, tmp);
tmp.coerceData(false);
src = tmp;
}
// Convert through defined intermediate conversions
BufferedImage tmp;
for (int i = 0; i < spaces.length; i++)
{
if (src.getColorModel().getColorSpace().getType() != spaces[i].getType())
{
tmp = createCompatibleDestImage(src,
createCompatibleColorModel(src,
spaces[i]));
copyimage(src, tmp);
src = tmp;
}
}
// No implicit conversion to destination type needed; return result from the
// last intermediate conversions (which was left in src)
if (dst == null)
dst = src;
// Implicit conversion to destination image's color space
else
copyimage(src, dst);
return dst;
}
/**
* Converts the source raster using the conversion path specified in the
* constructor. The resulting raster is stored in the destination raster if
* one is provided; otherwise a new WritableRaster is created and returned.
*
* This operation is not valid with every constructor of this class; see
* the constructors for details. Further, the source raster must have the
* same number of bands as the source ColorSpace, and the destination raster
* must have the same number of bands as the destination ColorSpace.
*
* The source and destination raster (if one is supplied) must also have the
* same dimensions.
*
* @param src The source raster.
* @param dest The destination raster.
* @throws IllegalArgumentException if the rasters and/or color spaces are
* incompatible.
* @return The transformed raster.
*/
public final WritableRaster filter(Raster src, WritableRaster dest)
{
// Various checks to ensure that the rasters and color spaces are compatible
if (spaces.length < 2)
throw new IllegalArgumentException("Not enough information about " +
"source and destination colorspaces.");
if (spaces[0].getNumComponents() != src.getNumBands()
|| (dest != null && spaces[spaces.length - 1].getNumComponents() != dest.getNumBands()))
throw new IllegalArgumentException("Source or destination raster " +
"contains the wrong number of bands.");
if (dest != null
&& (src.getHeight() != dest.getHeight() || src.getWidth() != dest.getWidth()))
throw new IllegalArgumentException("Source and destination rasters " +
"have different dimensions");
// Need to iterate through each color space.
// spaces[0] corresponds to the ColorSpace of the source raster, and
// spaces[spaces.length - 1] corresponds to the ColorSpace of the
// destination, with any number (or zero) of intermediate conversions.
for (int i = 0; i < spaces.length - 2; i++)
{
WritableRaster tmp = createCompatibleDestRaster(src, spaces[i + 1],
false,
src.getTransferType());
copyraster(src, spaces[i], tmp, spaces[i + 1]);
src = tmp;
}
// The last conversion is done outside of the loop so that we can
// use the dest raster supplied, instead of creating our own temp raster
if (dest == null)
dest = createCompatibleDestRaster(src, spaces[spaces.length - 1], false,
DataBuffer.TYPE_BYTE);
copyraster(src, spaces[spaces.length - 2], dest, spaces[spaces.length - 1]);
return dest;
}
/**
* Creates an empty BufferedImage with the size equal to the source and the
* correct number of bands for the conversion defined in this Op. The newly
* created image is created with the specified ColorModel, or if no ColorModel
* is supplied, an appropriate one is chosen.
*
* @param src The source image.
* @param dstCM A color model for the destination image (may be null).
* @throws IllegalArgumentException if an appropriate colormodel cannot be
* chosen with the information given.
* @return The new compatible destination image.
*/
public BufferedImage createCompatibleDestImage(BufferedImage src,
ColorModel dstCM)
{
if (dstCM == null && spaces.length == 0)
throw new IllegalArgumentException("Don't know the destination " +
"colormodel");
if (dstCM == null)
{
dstCM = createCompatibleColorModel(src, spaces[spaces.length - 1]);
}
return new BufferedImage(dstCM,
createCompatibleDestRaster(src.getRaster(),
dstCM.getColorSpace(),
src.getColorModel().hasAlpha,
dstCM.getTransferType()),
src.isAlphaPremultiplied, null);
}
/**
* Creates a new WritableRaster with the size equal to the source and the
* correct number of bands.
*
* Note, the new Raster will always use a BYTE storage size, regardless of
* the color model or defined destination; this is for compatibility with
* the reference implementation.
*
* @param src The source Raster.
* @throws IllegalArgumentException if there isn't enough colorspace
* information to create a compatible Raster.
* @return The new compatible destination raster.
*/
public WritableRaster createCompatibleDestRaster(Raster src)
{
if (spaces.length < 2)
throw new IllegalArgumentException("Not enough destination colorspace " +
"information");
// Create a new raster with the last ColorSpace in the conversion
// chain, and with no alpha (implied)
return createCompatibleDestRaster(src, spaces[spaces.length-1], false,
DataBuffer.TYPE_BYTE);
}
/**
* Returns the array of ICC_Profiles used to create this Op, or null if the
* Op was created using ColorSpace arguments.
*
* @return The array of ICC_Profiles, or null.
*/
public final ICC_Profile[] getICC_Profiles()
{
return profiles;
}
/**
* Returns the rendering hints for this op.
*
* @return The rendering hints for this Op, or null.
*/
public final RenderingHints getRenderingHints()
{
return hints;
}
/**
* Returns the corresponding destination point for a source point.
* Because this is not a geometric operation, the destination and source
* points will be identical.
*
* @param src The source point.
* @param dst The transformed destination point.
* @return The transformed destination point.
*/
public final Point2D getPoint2D(Point2D src, Point2D dst)
{
if (dst == null)
return (Point2D)src.clone();
dst.setLocation(src);
return dst;
}
/**
* Returns the corresponding destination boundary of a source boundary.
* Because this is not a geometric operation, the destination and source
* boundaries will be identical.
*
* @param src The source boundary.
* @return The boundaries of the destination.
*/
public final Rectangle2D getBounds2D(BufferedImage src)
{
return src.getRaster().getBounds();
}
/**
* Returns the corresponding destination boundary of a source boundary.
* Because this is not a geometric operation, the destination and source
* boundaries will be identical.
*
* @param src The source boundary.
* @return The boundaries of the destination.
*/
public final Rectangle2D getBounds2D(Raster src)
{
return src.getBounds();
}
/**
* Copy a source image to a destination image, respecting their colorspaces
* and performing colorspace conversions if necessary.
*
* @param src The source image.
* @param dst The destination image.
*/
private void copyimage(BufferedImage src, BufferedImage dst)
{
// This is done using Graphics2D in order to respect the rendering hints.
Graphics2D gg = dst.createGraphics();
// If no hints are set there is no need to call
// setRenderingHints on the Graphics2D object.
if (hints != null)
gg.setRenderingHints(hints);
gg.drawImage(src, 0, 0, null);
gg.dispose();
}
/**
* Copy a source raster to a destination raster, performing a colorspace
* conversion between the two. The conversion will respect the
* KEY_COLOR_RENDERING rendering hint if one is present.
*
* @param src The source raster.
* @param scs The colorspace of the source raster.
* @dst The destination raster.
* @dcs The colorspace of the destination raster.
*/
private void copyraster(Raster src, ColorSpace scs, WritableRaster dst, ColorSpace dcs)
{
float[] sbuf = new float[src.getNumBands()];
if (hints != null
&& hints.get(RenderingHints.KEY_COLOR_RENDERING) ==
RenderingHints.VALUE_COLOR_RENDER_QUALITY)
{
// use cie for accuracy
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
dst.setPixel(x, y,
dcs.fromCIEXYZ(scs.toCIEXYZ(src.getPixel(x, y, sbuf))));
}
else
{
// use rgb - it's probably faster
for (int y = src.getMinY(); y < src.getHeight() + src.getMinY(); y++)
for (int x = src.getMinX(); x < src.getWidth() + src.getMinX(); x++)
dst.setPixel(x, y,
dcs.fromRGB(scs.toRGB(src.getPixel(x, y, sbuf))));
}
}
/**
* This method creates a color model with the same colorspace and alpha
* settings as the source image. The created color model will always be a
* ComponentColorModel and have a BYTE transfer type.
*
* @param img The source image.
* @param cs The ColorSpace to use.
* @return A color model compatible with the source image.
*/
private ColorModel createCompatibleColorModel(BufferedImage img, ColorSpace cs)
{
// The choice of ComponentColorModel and DataBuffer.TYPE_BYTE is based on
// Mauve testing of the reference implementation.
return new ComponentColorModel(cs,
img.getColorModel().hasAlpha(),
img.isAlphaPremultiplied(),
img.getColorModel().getTransparency(),
DataBuffer.TYPE_BYTE);
}
/**
* This method creates a compatible Raster, given a source raster, colorspace,
* alpha value, and transfer type.
*
* @param src The source raster.
* @param cs The ColorSpace to use.
* @param hasAlpha Whether the raster should include a component for an alpha.
* @param transferType The size of a single data element.
* @return A compatible WritableRaster.
*/
private WritableRaster createCompatibleDestRaster(Raster src, ColorSpace cs,
boolean hasAlpha,
int transferType)
{
// The use of a PixelInterleavedSampleModel weas determined using mauve
// tests, based on the reference implementation
int numComponents = cs.getNumComponents();
if (hasAlpha)
numComponents++;
int[] offsets = new int[numComponents];
for (int i = 0; i < offsets.length; i++)
offsets[i] = i;
DataBuffer db = Buffers.createBuffer(transferType,
src.getWidth() * src.getHeight() * numComponents,
1);
return new WritableRaster(new PixelInterleavedSampleModel(transferType,
src.getWidth(),
src.getHeight(),
numComponents,
numComponents * src.getWidth(),
offsets),
db, new Point(src.getMinX(), src.getMinY()));
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,919 @@
/*
* Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.image;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.RasterFormatException;
import java.awt.image.SampleModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.Rectangle;
import java.awt.Point;
/**
* This class defines a Raster with pixels consisting of one or more 8-bit
* data elements stored in close proximity to each other in a single byte
* array.
* The bit precision per data element is that
* of the data type (that is, the bit precision for this Raster is 8).
* There is only one pixel stride and one scanline stride for all
* bands. This type of Raster can be used with a
* ComponentColorModel if there are multiple bands, or an
* IndexColorModel if there is only one band.
* <p>
* For example, 3-3-2 RGB image data can be represented by a
* ByteComponentRaster using a SinglePixelPackedSampleModel and
* a ComponentColorModel.
*
*/
public class ByteComponentRaster extends SunWritableRaster {
/** private band offset for use by native code */
protected int bandOffset;
/** Data offsets for each band of image data. */
protected int[] dataOffsets;
/** Scanline stride of the image data contained in this Raster. */
protected int scanlineStride;
/** Pixel stride of the image data contained in this Raster. */
protected int pixelStride;
/** The image data array. */
protected byte[] data;
int type;
/** A cached copy of minX + width for use in bounds checks. */
private int maxX;
/** A cached copy of minY + height for use in bounds checks. */
private int maxY;
/**
* Constructs a ByteComponentRaster with the given SampleModel.
* The Raster's upper left corner is origin and it is the same
* size as the SampleModel. A DataBuffer large enough to describe the
* Raster is automatically created. SampleModel must be of type
* SinglePixelPackedSampleModel or ComponentSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param origin The Point that specified the origin.
*/
public ByteComponentRaster(SampleModel sampleModel, Point origin) {
this(sampleModel,
sampleModel.createDataBuffer(),
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a ByteComponentRaster with the given SampleModel
* and DataBuffer. The Raster's upper left corner is origin and
* it is the same size as the SampleModel. The DataBuffer is not
* initialized and must be a DataBufferByte compatible with SampleModel.
* SampleModel must be of type SinglePixelPackedSampleModel
* or ComponentSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferShort that contains the image data.
* @param origin The Point that specifies the origin.
*/
public ByteComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin) {
this(sampleModel,
dataBuffer,
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a ByteComponentRaster with the given SampleModel,
* DataBuffer, and parent. DataBuffer must be a DataBufferByte and
* SampleModel must be of type SinglePixelPackedSampleModel
* or ComponentSampleModel.
* When translated into the base Raster's
* coordinate system, aRegion must be contained by the base Raster.
* Origin is the coordinate in the new Raster's coordinate system of
* the origin of the base Raster. (The base Raster is the Raster's
* ancestor which has no parent.)
*
* Note that this constructor should generally be called by other
* constructors or create methods, it should not be used directly.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferShort that contains the image data.
* @param aRegion The Rectangle that specifies the image area.
* @param origin The Point that specifies the origin.
* @param parent The parent (if any) of this raster.
*/
public ByteComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point origin,
ByteComponentRaster parent) {
super(sampleModel, dataBuffer, aRegion, origin, parent);
this.maxX = minX + width;
this.maxY = minY + height;
if (!(dataBuffer instanceof DataBufferByte)) {
throw new RasterFormatException("ByteComponentRasters must have " +
"byte DataBuffers");
}
DataBufferByte dbb = (DataBufferByte)dataBuffer;
this.data = stealData(dbb, 0);
if (dbb.getNumBanks() != 1) {
throw new
RasterFormatException("DataBuffer for ByteComponentRasters"+
" must only have 1 bank.");
}
int dbOffset = dbb.getOffset();
if (sampleModel instanceof ComponentSampleModel) {
ComponentSampleModel ism = (ComponentSampleModel)sampleModel;
this.type = IntegerComponentRaster.TYPE_BYTE_SAMPLES;
this.scanlineStride = ism.getScanlineStride();
this.pixelStride = ism.getPixelStride();
this.dataOffsets = ism.getBandOffsets();
int xOffset = aRegion.x - origin.x;
int yOffset = aRegion.y - origin.y;
for (int i = 0; i < getNumDataElements(); i++) {
dataOffsets[i] += dbOffset +
xOffset*pixelStride+yOffset*scanlineStride;
}
} else if (sampleModel instanceof SinglePixelPackedSampleModel) {
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel)sampleModel;
this.type = IntegerComponentRaster.TYPE_BYTE_PACKED_SAMPLES;
this.scanlineStride = sppsm.getScanlineStride();
this.pixelStride = 1;
this.dataOffsets = new int[1];
this.dataOffsets[0] = dbOffset;
int xOffset = aRegion.x - origin.x;
int yOffset = aRegion.y - origin.y;
dataOffsets[0] += xOffset*pixelStride+yOffset*scanlineStride;
} else {
throw new RasterFormatException("IntegerComponentRasters must " +
"have ComponentSampleModel or SinglePixelPackedSampleModel");
}
this.bandOffset = this.dataOffsets[0];
verify(false);
}
/**
* Returns a copy of the data offsets array. For each band the data offset
* is the index into the band's data array, of the first sample of the
* band.
*/
public int[] getDataOffsets() {
return (int[]) dataOffsets.clone();
}
/**
* Returns the data offset for the specified band. The data offset
* is the index into the data array
* in which the first sample of the first scanline is stored.
* @param band The band whose offset is returned.
*/
public int getDataOffset(int band) {
return dataOffsets[band];
}
/**
* Returns the scanline stride -- the number of data array elements between
* a given sample and the sample in the same column of the next row in the
* same band.
*/
public int getScanlineStride() {
return scanlineStride;
}
/**
* Returns pixel stride -- the number of data array elements between two
* samples for the same band on the same scanline.
*/
public int getPixelStride() {
return pixelStride;
}
/**
* Returns a reference to the data array.
*/
public byte[] getDataStorage() {
return data;
}
/**
* Returns the data elements for all bands at the specified
* location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param outData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
byte outData[];
if (obj == null) {
outData = new byte[numDataElements];
} else {
outData = (byte[])obj;
}
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int band = 0; band < numDataElements; band++) {
outData[band] = data[dataOffsets[band] + off];
}
return outData;
}
/**
* Returns an array of data elements from the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* <pre>
* byte[] bandData = (byte[])raster.getDataElements(x, y, w, h, null);
* int numDataElements = raster.getNumDataElements();
* byte[] pixel = new byte[numDataElements];
* // To find a data element at location (x2, y2)
* System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements,
* pixel, 0, numDataElements);
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param outData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
byte outData[];
if (obj == null) {
outData = new byte[w*h*numDataElements];
} else {
outData = (byte[])obj;
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
outData[off++] = data[dataOffsets[c] + xoff];
}
}
}
return outData;
}
/**
* Returns a byte array of data elements from the specified rectangular
* region for the specified band.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* <pre>
* byte[] bandData = raster.getByteData(x, y, w, h, null);
* // To find the data element at location (x2, y2)
* byte bandElement = bandData[((y2-y)*w + (x2-x))];
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param band The band to return.
* @param outData If non-null, data elements for all bands
* at the specified location are returned in this array.
* @return Data array with data elements for all bands.
*/
public byte[] getByteData(int x, int y, int w, int h,
int band, byte[] outData) {
// Bounds check for 'band' will be performed automatically
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
if (outData == null) {
outData = new byte[scanlineStride*h];
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride + dataOffsets[band];
int xoff;
int off = 0;
int xstart;
int ystart;
if (pixelStride == 1) {
if (scanlineStride == w) {
System.arraycopy(data, yoff, outData, 0, w*h);
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
System.arraycopy(data, yoff, outData, off, w);
off += w;
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
outData[off++] = data[xoff];
}
}
}
return outData;
}
/**
* Returns a byte array of data elements from the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* <pre>
* byte[] bandData = raster.getByteData(x, y, w, h, null);
* int numDataElements = raster.getnumDataElements();
* byte[] pixel = new byte[numDataElements];
* // To find a data element at location (x2, y2)
* System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements,
* pixel, 0, numDataElements);
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param outData If non-null, data elements for all bands
* at the specified location are returned in this array.
* @return Data array with data elements for all bands.
*/
public byte[] getByteData(int x, int y, int w, int h, byte[] outData) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
if (outData == null) {
outData = new byte[numDataElements*scanlineStride*h];
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
// REMIND: Should keep track if dataOffsets are in a nice order
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
outData[off++] = data[dataOffsets[c] + xoff];
}
}
}
return outData;
}
/**
* Stores the data elements for all bands at the specified location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements()
* containing the pixel data to place at x,y.
*/
public void setDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
byte inData[] = (byte[])obj;
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int i = 0; i < numDataElements; i++) {
data[dataOffsets[i] + off] = inData[i];
}
markDirty();
}
/**
* Stores the Raster data at the specified location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inRaster Raster of data to place at x,y location.
*/
public void setDataElements(int x, int y, Raster inRaster) {
int dstOffX = inRaster.getMinX() + x;
int dstOffY = inRaster.getMinY() + y;
int width = inRaster.getWidth();
int height = inRaster.getHeight();
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
(dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
setDataElements(dstOffX, dstOffY, width, height, inRaster);
}
/**
* Stores the Raster data at the specified location.
* @param dstX The absolute X coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param dstY The absolute Y coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param width The number of pixels to store horizontally
* @param height The number of pixels to store vertically
* @param inRaster Raster of data to place at x,y location.
*/
private void setDataElements(int dstX, int dstY,
int width, int height,
Raster inRaster) {
// Assume bounds checking has been performed previously
if (width <= 0 || height <= 0) {
return;
}
int srcOffX = inRaster.getMinX();
int srcOffY = inRaster.getMinY();
Object tdata = null;
if (inRaster instanceof ByteComponentRaster) {
ByteComponentRaster bct = (ByteComponentRaster) inRaster;
byte[] bdata = bct.getDataStorage();
// REMIND: Do something faster!
if (numDataElements == 1) {
int toff = bct.getDataOffset(0);
int tss = bct.getScanlineStride();
int srcOffset = toff;
int dstOffset = dataOffsets[0]+(dstY-minY)*scanlineStride+
(dstX-minX);
if (pixelStride == bct.getPixelStride()) {
width *= pixelStride;
for (int tmpY=0; tmpY < height; tmpY++) {
System.arraycopy(bdata, srcOffset,
data, dstOffset, width);
srcOffset += tss;
dstOffset += scanlineStride;
}
markDirty();
return;
}
}
}
for (int startY=0; startY < height; startY++) {
// Grab one scanline at a time
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
width, 1, tdata);
setDataElements(dstX, dstY+startY, width, 1, tdata);
}
}
/**
* Stores an array of data elements into the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* for the nth band at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))*numDataElements + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements()
* containing the pixel data to place between x,y and
* x+h, y+h.
*/
public void setDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
byte inData[] = (byte[])obj;
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
if (numDataElements == 1) {
int srcOffset = 0;
int dstOffset = yoff + dataOffsets[0];
for (ystart=0; ystart < h; ystart++) {
xoff = yoff;
System.arraycopy(inData, srcOffset,
data, dstOffset, w);
srcOffset += w;
dstOffset += scanlineStride;
}
markDirty();
return;
}
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
data[dataOffsets[c] + xoff] = inData[off++];
}
}
}
markDirty();
}
/**
* Stores a byte array of data elements into the specified rectangular
* region for the specified band.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x)) + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param band The band to set.
* @param inData The data elements to be stored.
*/
public void putByteData(int x, int y, int w, int h,
int band, byte[] inData) {
// Bounds check for 'band' will be performed automatically
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride + dataOffsets[band];
int xoff;
int off = 0;
int xstart;
int ystart;
if (pixelStride == 1) {
if (scanlineStride == w) {
System.arraycopy(inData, 0, data, yoff, w*h);
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
System.arraycopy(inData, off, data, yoff, w);
off += w;
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
data[xoff] = inData[off++];
}
}
}
markDirty();
}
/**
* Stores a byte array of data elements into the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* for the nth band at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))*numDataElements + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData The data elements to be stored.
*/
public void putByteData(int x, int y, int w, int h, byte[] inData) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
if (numDataElements == 1) {
yoff += dataOffsets[0];
if (pixelStride == 1) {
if (scanlineStride == w) {
System.arraycopy(inData, 0, data, yoff, w*h);
}
else {
for (ystart=0; ystart < h; ystart++) {
System.arraycopy(inData, off, data, yoff, w);
off += w;
yoff += scanlineStride;
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
data[xoff] = inData[off++];
}
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
data[dataOffsets[c] + xoff] = inData[off++];
}
}
}
}
markDirty();
}
/**
* Creates a subraster given a region of the raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this raster to the upper-left corner
* of the subraster. A subset of the bands of the parent Raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. A translation to the subRaster may also be specified.
* Note that the subraster will reference the same
* DataBuffer as the parent raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subraster.
* @param y0 Translated Y origin of the subraster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent raster.
*/
public Raster createChild(int x, int y,
int width, int height,
int x0, int y0, int[] bandList) {
WritableRaster newRaster = createWritableChild(x, y,
width, height,
x0, y0,
bandList);
return (Raster) newRaster;
}
/**
* Creates a Writable subRaster given a region of the Raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this Raster to the upper-left corner
* of the subRaster. A subset of the bands of the parent Raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. A translation to the subRaster may also be specified.
* Note that the subRaster will reference the same
* DataBuffer as the parent Raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subraster.
* @param y0 Translated Y origin of the subraster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent Raster.
*/
public WritableRaster createWritableChild(int x, int y,
int width, int height,
int x0, int y0,
int[] bandList) {
if (x < this.minX) {
throw new RasterFormatException("x lies outside the raster");
}
if (y < this.minY) {
throw new RasterFormatException("y lies outside the raster");
}
if ((x+width < x) || (x+width > this.minX + this.width)) {
throw new RasterFormatException("(x + width) is outside of Raster");
}
if ((y+height < y) || (y+height > this.minY + this.height)) {
throw new RasterFormatException("(y + height) is outside of Raster");
}
SampleModel sm;
if (bandList != null)
sm = sampleModel.createSubsetSampleModel(bandList);
else
sm = sampleModel;
int deltaX = x0 - x;
int deltaY = y0 - y;
return new ByteComponentRaster(sm,
dataBuffer,
new Rectangle(x0, y0, width, height),
new Point(sampleModelTranslateX+deltaX,
sampleModelTranslateY+deltaY),
this);
}
/**
* Creates a Raster with the same layout but using a different
* width and height, and with new zeroed data arrays.
*/
public WritableRaster createCompatibleWritableRaster(int w, int h) {
if (w <= 0 || h <=0) {
throw new RasterFormatException("negative "+
((w <= 0) ? "width" : "height"));
}
SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
return new ByteComponentRaster(sm , new Point(0,0));
}
/**
* Creates a Raster with the same layout and the same
* width and height, and with new zeroed data arrays. If
* the Raster is a subRaster, this will call
* createCompatibleRaster(width, height).
*/
public WritableRaster createCompatibleWritableRaster() {
return createCompatibleWritableRaster(width,height);
}
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
*/
private void verify (boolean strictCheck) {
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+
"("+dataOffsets[i]+
") must be >= 0");
}
}
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
}
}
public String toString() {
return new String ("ByteComponentRaster: width = "+width+" height = "
+ height
+" #numDataElements "+numDataElements
// +" xOff = "+xOffset+" yOff = "+yOffset
+" dataOff[0] = "+dataOffsets[0]);
}
// /**
// * For debugging... prints a region of a one-band ByteComponentRaster
// */
// public void print(int x, int y, int w, int h) {
// // REMIND: Only works for 1 band!
// System.out.println(this);
// int offset = dataOffsets[0] + y*scanlineStride + x*pixelStride;
// int off;
// for (int yoff=0; yoff < h; yoff++, offset += scanlineStride) {
// off = offset;
// System.out.print("Line "+(y+yoff)+": ");
// for (int xoff = 0; xoff < w; xoff++, off+= pixelStride) {
// String s = Integer.toHexString(data[off]);
// if (s.length() == 8) {
// s = s.substring(6,8);
// }
// System.out.print(s+" ");
// }
// System.out.println("");
// }
// }
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,685 @@
/*
* Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.image;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.RasterFormatException;
import java.awt.image.SampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.Rectangle;
import java.awt.Point;
/**
* This class defines a Raster with pixels consisting of one or more 32-bit
* data elements stored in close proximity to each other in a integer array.
* The bit precision per data element is that
* of the data type (that is, the bit precision for this raster is 32).
* There is only one pixel stride and one scanline stride for all
* bands. For a given pixel, all samples fit in N data elements and these
* N data elements hold samples for only one pixel. This type of Raster
* can be used with a PackedColorModel.
* <p>
* For example, if there is only one data element per pixel, a
* SinglePixelPackedSampleModel can be used to represent multiple
* bands with a PackedColorModel (including a DirectColorModel) for
* color interpretation.
*
*/
public class IntegerComponentRaster extends SunWritableRaster {
static final int TYPE_CUSTOM = 0;
static final int TYPE_BYTE_SAMPLES = 1;
static final int TYPE_USHORT_SAMPLES = 2;
static final int TYPE_INT_SAMPLES = 3;
static final int TYPE_BYTE_BANDED_SAMPLES = 4;
static final int TYPE_USHORT_BANDED_SAMPLES = 5;
static final int TYPE_INT_BANDED_SAMPLES = 6;
static final int TYPE_BYTE_PACKED_SAMPLES = 7;
static final int TYPE_USHORT_PACKED_SAMPLES = 8;
static final int TYPE_INT_PACKED_SAMPLES = 9;
static final int TYPE_INT_8BIT_SAMPLES = 10;
static final int TYPE_BYTE_BINARY_SAMPLES = 11;
/** private band offset for use by native code */
protected int bandOffset;
/** Data offsets for each band of image data. */
protected int[] dataOffsets;
/** Scanline stride of the image data contained in this Raster. */
protected int scanlineStride;
/** Pixel stride of the image data contained in this Raster. */
protected int pixelStride;
/** The image data array. */
protected int[] data;
/** The number of data elements required to store a pixel. */
protected int numDataElems;
int type;
/** A cached copy of minX + width for use in bounds checks. */
private int maxX;
/** A cached copy of minY + height for use in bounds checks. */
private int maxY;
/**
* Constructs a IntegerComponentRaster with the given SampleModel.
* The Raster's upper left corner is origin and it is the same
* size as the SampleModel. A DataBuffer large enough to describe the
* Raster is automatically created. SampleModel must be of type
* SinglePixelPackedSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param origin The Point that specified the origin.
*/
public IntegerComponentRaster(SampleModel sampleModel,
Point origin) {
this(sampleModel,
sampleModel.createDataBuffer(),
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a IntegerComponentRaster with the given SampleModel
* and DataBuffer. The Raster's upper left corner is origin and
* it is the same sizes the SampleModel. The DataBuffer is not
* initialized and must be a DataBufferInt compatible with SampleModel.
* SampleModel must be of type SinglePixelPackedSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferInt that contains the image data.
* @param origin The Point that specifies the origin.
*/
public IntegerComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin) {
this(sampleModel,
dataBuffer,
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a IntegerComponentRaster with the given SampleModel,
* DataBuffer, and parent. DataBuffer must be a DataBufferInt and
* SampleModel must be of type SinglePixelPackedSampleModel.
* When translated into the base Raster's
* coordinate system, aRegion must be contained by the base Raster.
* Origin is the coodinate in the new Raster's coordinate system of
* the origin of the base Raster. (The base Raster is the Raster's
* ancestor which has no parent.)
*
* Note that this constructor should generally be called by other
* constructors or create methods, it should not be used directly.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferInt that contains the image data.
* @param aRegion The Rectangle that specifies the image area.
* @param origin The Point that specifies the origin.
* @param parent The parent (if any) of this raster.
*/
public IntegerComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point origin,
IntegerComponentRaster parent){
super(sampleModel,dataBuffer,aRegion,origin,parent);
this.maxX = minX + width;
this.maxY = minY + height;
if (!(dataBuffer instanceof DataBufferInt)) {
throw new RasterFormatException("IntegerComponentRasters must have" +
"integer DataBuffers");
}
DataBufferInt dbi = (DataBufferInt)dataBuffer;
if (dbi.getNumBanks() != 1) {
throw new
RasterFormatException("DataBuffer for IntegerComponentRasters"+
" must only have 1 bank.");
}
this.data = stealData(dbi, 0);
if (sampleModel instanceof SinglePixelPackedSampleModel) {
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel)sampleModel;
int[] boffsets = sppsm.getBitOffsets();
boolean notByteBoundary = false;
for (int i=1; i < boffsets.length; i++) {
if ((boffsets[i]%8) != 0) {
notByteBoundary = true;
}
}
this.type = (notByteBoundary
? IntegerComponentRaster.TYPE_INT_PACKED_SAMPLES
: IntegerComponentRaster.TYPE_INT_8BIT_SAMPLES);
this.scanlineStride = sppsm.getScanlineStride();
this.pixelStride = 1;
this.dataOffsets = new int[1];
this.dataOffsets[0] = dbi.getOffset();
this.bandOffset = this.dataOffsets[0];
int xOffset = aRegion.x - origin.x;
int yOffset = aRegion.y - origin.y;
dataOffsets[0] += xOffset+yOffset*scanlineStride;
this.numDataElems = sppsm.getNumDataElements();
} else {
throw new RasterFormatException("IntegerComponentRasters must have"+
" SinglePixelPackedSampleModel");
}
verify(false);
}
/**
* Returns a copy of the data offsets array. For each band the data offset
* is the index into the band's data array, of the first sample of the
* band.
*/
public int[] getDataOffsets() {
return (int[]) dataOffsets.clone();
}
/**
* Returns data offset for the specified band. The data offset
* is the index into the data array in which the first sample
* of the first scanline is stored.
*/
public int getDataOffset(int band) {
return dataOffsets[band];
}
/**
* Returns the scanline stride -- the number of data array elements between
* a given sample and the sample in the same column of the next row.
*/
public int getScanlineStride() {
return scanlineStride;
}
/**
* Returns pixel stride -- the number of data array elements between two
* samples for the same band on the same scanline.
*/
public int getPixelStride() {
return pixelStride;
}
/**
* Returns a reference to the data array.
*/
public int[] getDataStorage() {
return data;
}
/**
* Returns the data elements for all bands at the specified
* location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param outData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int outData[];
if (obj == null) {
outData = new int[numDataElements];
} else {
outData = (int[])obj;
}
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int band = 0; band < numDataElements; band++) {
outData[band] = data[dataOffsets[band] + off];
}
return outData;
}
/**
* Returns an array of data elements from the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
<pre>
* int[] bandData = (int[])raster.getDataElements(x, y, w, h, null);
* int numDataElements = raster.getNumDataElements();
* int[] pixel = new int[numDataElements];
* // To find a data element at location (x2, y2)
* System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements,
* pixel, 0, numDataElements);
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param outData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int outData[];
if (obj instanceof int[]) {
outData = (int[])obj;
} else {
outData = new int[numDataElements*w*h];
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
outData[off++] = data[dataOffsets[c] + xoff];
}
}
}
return outData;
}
/**
* Stores the data elements for all bands at the specified location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements()
* containing the pixel data to place at x,y.
*/
public void setDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int inData[] = (int[])obj;
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int i = 0; i < numDataElements; i++) {
data[dataOffsets[i] + off] = inData[i];
}
markDirty();
}
/**
* Stores the Raster data at the specified location.
* The transferType of the inputRaster must match this raster.
* An ArrayIndexOutOfBoundsException will be thrown at runtime
* if the pixel coordinates are out of bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inRaster Raster of data to place at x,y location.
*/
public void setDataElements(int x, int y, Raster inRaster) {
int dstOffX = x + inRaster.getMinX();
int dstOffY = y + inRaster.getMinY();
int width = inRaster.getWidth();
int height = inRaster.getHeight();
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
(dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
setDataElements(dstOffX, dstOffY, width, height, inRaster);
}
/**
* Stores the Raster data at the specified location.
* @param dstX The absolute X coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param dstY The absolute Y coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param width The number of pixels to store horizontally
* @param height The number of pixels to store vertically
* @param inRaster Raster of data to place at x,y location.
*/
private void setDataElements(int dstX, int dstY,
int width, int height,
Raster inRaster) {
// Assume bounds checking has been performed previously
if (width <= 0 || height <= 0) {
return;
}
// Write inRaster (minX, minY) to (dstX, dstY)
int srcOffX = inRaster.getMinX();
int srcOffY = inRaster.getMinY();
int tdata[] = null;
if (inRaster instanceof IntegerComponentRaster &&
(pixelStride == 1) && (numDataElements == 1)) {
IntegerComponentRaster ict = (IntegerComponentRaster) inRaster;
if (ict.getNumDataElements() != 1) {
throw new ArrayIndexOutOfBoundsException("Number of bands"+
" does not match");
}
// Extract the raster parameters
tdata = ict.getDataStorage();
int tss = ict.getScanlineStride();
int toff = ict.getDataOffset(0);
int srcOffset = toff;
int dstOffset = dataOffsets[0]+(dstY-minY)*scanlineStride+
(dstX-minX);
// Fastest case. We can copy scanlines
if (ict.getPixelStride() == pixelStride) {
width *= pixelStride;
// Loop through all of the scanlines and copy the data
for (int startY=0; startY < height; startY++) {
System.arraycopy(tdata, srcOffset, data, dstOffset, width);
srcOffset += tss;
dstOffset += scanlineStride;
}
markDirty();
return;
}
}
Object odata = null;
for (int startY=0; startY < height; startY++) {
odata = inRaster.getDataElements(srcOffX, srcOffY+startY,
width, 1, odata);
setDataElements(dstX, dstY+startY,
width, 1, odata);
}
}
/**
* Stores an array of data elements into the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* for the nth band at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))*numDataElements + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements()
* containing the pixel data to place between x,y and
* x+h, y+h.
*/
public void setDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int inData[] = (int[])obj;
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
data[dataOffsets[c] + xoff] = inData[off++];
}
}
}
markDirty();
}
/**
* Creates a subraster given a region of the raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this raster to the upper-left corner
* of the subraster. A subset of the bands of the parent Raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. A translation to the subRaster may also be specified.
* Note that the subraster will reference the same
* DataBuffer as the parent raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subraster.
* @param y0 Translated Y origin of the subraster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent raster.
*/
public WritableRaster createWritableChild (int x, int y,
int width, int height,
int x0, int y0,
int bandList[]) {
if (x < this.minX) {
throw new RasterFormatException("x lies outside raster");
}
if (y < this.minY) {
throw new RasterFormatException("y lies outside raster");
}
if ((x+width < x) || (x+width > this.minX + this.width)) {
throw new RasterFormatException("(x + width) is outside raster");
}
if ((y+height < y) || (y+height > this.minY + this.height)) {
throw new RasterFormatException("(y + height) is outside raster");
}
SampleModel sm;
if (bandList != null)
sm = sampleModel.createSubsetSampleModel(bandList);
else
sm = sampleModel;
int deltaX = x0 - x;
int deltaY = y0 - y;
return new IntegerComponentRaster(sm,
dataBuffer,
new Rectangle(x0,y0,width,height),
new Point(sampleModelTranslateX+deltaX,
sampleModelTranslateY+deltaY),
this);
}
/**
* Creates a subraster given a region of the raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this raster to the upper-left corner
* of the subraster. A subset of the bands of the parent raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. Note that the subraster will reference the same
* DataBuffer as the parent raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subRaster.
* @param y0 Translated Y origin of the subRaster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent raster.
*/
public Raster createChild (int x, int y,
int width, int height,
int x0, int y0,
int bandList[]) {
return createWritableChild(x, y, width, height, x0, y0, bandList);
}
/**
* Creates a raster with the same band layout but using a different
* width and height, and with new zeroed data arrays.
*/
public WritableRaster createCompatibleWritableRaster(int w, int h) {
if (w <= 0 || h <=0) {
throw new RasterFormatException("negative "+
((w <= 0) ? "width" : "height"));
}
SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
return new IntegerComponentRaster(sm, new Point(0,0));
}
/**
* Creates a raster with the same data layout and the same
* width and height, and with new zeroed data arrays. If
* the raster is a subraster, this will call
* createCompatibleRaster(width, height).
*/
public WritableRaster createCompatibleWritableRaster() {
return createCompatibleWritableRaster(width,height);
}
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
*/
private void verify (boolean strictCheck) {
if (dataOffsets[0] < 0) {
throw new RasterFormatException("Data offset ("+dataOffsets[0]+
") must be >= 0");
}
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize
+" but is "+data.length+" )");
}
}
public String toString() {
return new String ("IntegerComponentRaster: width = "+width
+" height = " + height
+" #Bands = " + numBands
+" #DataElements "+numDataElements
+" xOff = "+sampleModelTranslateX
+" yOff = "+sampleModelTranslateY
+" dataOffset[0] "+dataOffsets[0]);
}
// /**
// * For debugging... prints a region of a one-band IntegerComponentRaster
// */
// public void print(int x, int y, int w, int h) {
// // REMIND: Only works for 1 band!
// System.out.println(this);
// int offset = dataOffsets[0] + y*scanlineStride + x*pixelStride;
// int off;
// for (int yoff=0; yoff < h; yoff++, offset += scanlineStride) {
// off = offset;
// System.out.print("Line "+(sampleModelTranslateY+y+yoff)+": ");
// for (int xoff = 0; xoff < w; xoff++, off+= pixelStride) {
// System.out.print(Integer.toHexString(data[off])+" ");
// }
// System.out.println("");
// }
// }
}

Просмотреть файл

@ -0,0 +1,195 @@
/*
* Copyright 1995-2003 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.image;
import java.util.Hashtable;
import java.awt.image.ImageConsumer;
import java.awt.image.ImageProducer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
public class OffScreenImageSource implements ImageProducer {
BufferedImage image;
int width;
int height;
Hashtable properties;
public OffScreenImageSource(BufferedImage image,
Hashtable properties) {
this.image = image;
if (properties != null) {
this.properties = properties;
} else {
this.properties = new Hashtable();
}
width = image.getWidth();
height = image.getHeight();
}
public OffScreenImageSource(BufferedImage image) {
this(image, null);
}
// We can only have one consumer since we immediately return the data...
private ImageConsumer theConsumer;
public synchronized void addConsumer(ImageConsumer ic) {
theConsumer = ic;
produce();
}
public synchronized boolean isConsumer(ImageConsumer ic) {
return (ic == theConsumer);
}
public synchronized void removeConsumer(ImageConsumer ic) {
if (theConsumer == ic) {
theConsumer = null;
}
}
public void startProduction(ImageConsumer ic) {
addConsumer(ic);
}
public void requestTopDownLeftRightResend(ImageConsumer ic) {
}
private void sendPixels() {
ColorModel cm = image.getColorModel();
WritableRaster raster = image.getRaster();
int numDataElements = raster.getNumDataElements();
int dataType = raster.getDataBuffer().getDataType();
int[] scanline = new int[width*numDataElements];
boolean needToCvt = true;
if (cm instanceof IndexColorModel) {
byte[] pixels = new byte[width];
theConsumer.setColorModel(cm);
if (raster instanceof ByteComponentRaster) {
needToCvt = false;
for (int y=0; y < height; y++) {
raster.getDataElements(0, y, width, 1, pixels);
theConsumer.setPixels(0, y, width, 1, cm, pixels, 0,
width);
}
}
else if (raster instanceof BytePackedRaster) {
needToCvt = false;
// Binary image. Need to unpack it
for (int y=0; y < height; y++) {
raster.getPixels(0, y, width, 1, scanline);
for (int x=0; x < width; x++) {
pixels[x] = (byte) scanline[x];
}
theConsumer.setPixels(0, y, width, 1, cm, pixels, 0,
width);
}
}
else if (dataType == DataBuffer.TYPE_SHORT ||
dataType == DataBuffer.TYPE_INT)
{
// Probably a short or int "GRAY" image
needToCvt = false;
for (int y=0; y < height; y++) {
raster.getPixels(0, y, width, 1, scanline);
theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
width);
}
}
}
else if (cm instanceof DirectColorModel) {
theConsumer.setColorModel(cm);
needToCvt = false;
switch (dataType) {
case DataBuffer.TYPE_INT:
for (int y=0; y < height; y++) {
raster.getDataElements(0, y, width, 1, scanline);
theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
width);
}
break;
case DataBuffer.TYPE_BYTE:
byte[] bscanline = new byte[width];
for (int y=0; y < height; y++) {
raster.getDataElements(0, y, width, 1, bscanline);
for (int x=0; x < width; x++) {
scanline[x] = bscanline[x]&0xff;
}
theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
width);
}
break;
case DataBuffer.TYPE_USHORT:
short[] sscanline = new short[width];
for (int y=0; y < height; y++) {
raster.getDataElements(0, y, width, 1, sscanline);
for (int x=0; x < width; x++) {
scanline[x] = sscanline[x]&0xffff;
}
theConsumer.setPixels(0, y, width, 1, cm, scanline, 0,
width);
}
break;
default:
needToCvt = true;
}
}
if (needToCvt) {
// REMIND: Need to add other types of CMs here
ColorModel newcm = ColorModel.getRGBdefault();
theConsumer.setColorModel(newcm);
for (int y=0; y < height; y++) {
for (int x=0; x < width; x++) {
scanline[x] = image.getRGB(x, y);
}
theConsumer.setPixels(0, y, width, 1, newcm, scanline, 0,
width);
}
}
}
private void produce() {
try {
theConsumer.setDimensions(image.getWidth(), image.getHeight());
theConsumer.setProperties(properties);
sendPixels();
theConsumer.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
} catch (NullPointerException e) {
if (theConsumer != null) {
theConsumer.imageComplete(ImageConsumer.IMAGEERROR);
}
}
}
}

Просмотреть файл

@ -0,0 +1,829 @@
/*
* Copyright 1997-2007 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.image;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.RasterFormatException;
import java.awt.image.SampleModel;
import java.awt.image.ComponentSampleModel;
import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferUShort;
import java.awt.Rectangle;
import java.awt.Point;
/**
* This class defines a Raster with pixels consisting of one or more 16-bit
* data elements stored in close proximity to each other in a short integer
* array. The bit precision per data element is that
* of the data type (that is, the bit precision for this Raster is 16).
* There is only one pixel stride and one scanline stride for all
* bands. This type of Raster can be used with a
* ComponentColorModel if there are multiple bands, or a
* IndexColorModel if there is only one band.
* <p>
* For example, 5-6-5 RGB image data can be represented by a
* ShortComponentRaster using a SinglePixelPackedSampleModel and
* a ComponentColorModel.
*
*
*/
public class ShortComponentRaster extends SunWritableRaster {
/** private band offset for use by native code */
protected int bandOffset;
/** Data offsets for each band of image data. */
protected int[] dataOffsets;
/** Scanline stride of the image data contained in this Raster. */
protected int scanlineStride;
/** Pixel stride of the image data contained in this Raster. */
protected int pixelStride;
/** The image data array. */
protected short[] data;
int type;
/** A cached copy of minX + width for use in bounds checks. */
private int maxX;
/** A cached copy of minY + height for use in bounds checks. */
private int maxY;
/**
* Constructs a ShortComponentRaster with the given SampleModel.
* The Raster's upper left corner is origin and it is the same
* size as the SampleModel. A DataBuffer large enough to describe the
* Raster is automatically created. SampleModel must be of type
* ComponentSampleModel or SinglePixelPackedSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param origin The Point that specified the origin.
*/
public ShortComponentRaster(SampleModel sampleModel, Point origin) {
this(sampleModel,
sampleModel.createDataBuffer(),
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a ShortComponentRaster with the given SampleModel
* and DataBuffer. The Raster's upper left corner is origin and
* it is the same sizes the SampleModel. The DataBuffer is not
* initialized and must be a DataBufferUShort compatible with SampleModel.
* SampleModel must be of type ComponentSampleModel or
* SinglePixelPackedSampleModel.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferUShort that contains the image data.
* @param origin The Point that specifies the origin.
*/
public ShortComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin) {
this(sampleModel,
dataBuffer,
new Rectangle(origin.x,
origin.y,
sampleModel.getWidth(),
sampleModel.getHeight()),
origin,
null);
}
/**
* Constructs a ShortComponentRaster with the given SampleModel,
* DataBuffer, and parent. DataBuffer must be a DataBufferUShort and
* SampleModel must be of type ComponentSampleModel or
* SinglePixelPackedSampleModel. When translated into the base Raster's
* coordinate system, aRegion must be contained by the base Raster.
* Origin is the coodinate in the new Raster's coordinate system of
* the origin of the base Raster. (The base Raster is the Raster's
* ancestor which has no parent.)
*
* Note that this constructor should generally be called by other
* constructors or create methods, it should not be used directly.
* @param sampleModel The SampleModel that specifies the layout.
* @param dataBuffer The DataBufferUShort that contains the image data.
* @param aRegion The Rectangle that specifies the image area.
* @param origin The Point that specifies the origin.
* @param parent The parent (if any) of this raster.
*/
public ShortComponentRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point origin,
ShortComponentRaster parent) {
super(sampleModel, dataBuffer, aRegion, origin, parent);
this.maxX = minX + width;
this.maxY = minY + height;
if(!(dataBuffer instanceof DataBufferUShort)) {
throw new RasterFormatException("ShortComponentRasters must have "+
"short DataBuffers");
}
DataBufferUShort dbus = (DataBufferUShort)dataBuffer;
this.data = stealData(dbus, 0);
if (dbus.getNumBanks() != 1) {
throw new
RasterFormatException("DataBuffer for ShortComponentRasters"+
" must only have 1 bank.");
}
int dbOffset = dbus.getOffset();
if (sampleModel instanceof ComponentSampleModel) {
ComponentSampleModel csm = (ComponentSampleModel)sampleModel;
this.type = IntegerComponentRaster.TYPE_USHORT_SAMPLES;
this.scanlineStride = csm.getScanlineStride();
this.pixelStride = csm.getPixelStride();
this.dataOffsets = csm.getBandOffsets();
int xOffset = aRegion.x - origin.x;
int yOffset = aRegion.y - origin.y;
for (int i = 0; i < getNumDataElements(); i++) {
dataOffsets[i] += dbOffset +
xOffset*pixelStride+yOffset*scanlineStride;
}
} else if (sampleModel instanceof SinglePixelPackedSampleModel) {
SinglePixelPackedSampleModel sppsm =
(SinglePixelPackedSampleModel)sampleModel;
this.type = IntegerComponentRaster.TYPE_USHORT_PACKED_SAMPLES;
this.scanlineStride = sppsm.getScanlineStride();
this.pixelStride = 1;
this.dataOffsets = new int[1];
this.dataOffsets[0] = dbOffset;
int xOffset = aRegion.x - origin.x;
int yOffset = aRegion.y - origin.y;
dataOffsets[0] += xOffset+yOffset*scanlineStride;
} else {
throw new RasterFormatException("ShortComponentRasters must have"+
"ComponentSampleModel or SinglePixelPackedSampleModel");
}
this.bandOffset = this.dataOffsets[0];
verify(false);
}
/**
* Returns a copy of the data offsets array. For each band the data offset
* is the index into the band's data array, of the first sample of the
* band.
*/
public int[] getDataOffsets() {
return (int[]) dataOffsets.clone();
}
/**
* Returns the data offset for the specified band. The data offset
* is the index into the data array in which the first sample
* of the first scanline is stored.
* @param band The band whose offset is returned.
*/
public int getDataOffset(int band) {
return dataOffsets[band];
}
/**
* Returns the scanline stride -- the number of data array elements between
* a given sample and the same sample in the same column of the next row.
*/
public int getScanlineStride() {
return scanlineStride;
}
/**
* Returns pixel stride -- the number of data array elements between two
* samples for the same band on the same scanline.
*/
public int getPixelStride() {
return pixelStride;
}
/**
* Returns a reference to the data array.
*/
public short[] getDataStorage() {
return data;
}
/**
* Returns the data elements for all bands at the specified
* location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param outData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
short outData[];
if (obj == null) {
outData = new short[numDataElements];
} else {
outData = (short[])obj;
}
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int band = 0; band < numDataElements; band++) {
outData[band] = data[dataOffsets[band] + off];
}
return outData;
}
/**
* Returns an array of data elements from the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* <pre>
* short[] bandData = (short[])Raster.getDataElements(x, y, w, h, null);
* int numDataElements = Raster.getBands();
* short[] pixel = new short[numDataElements];
* // To find the data element at location (x2, y2)
* System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements,
* pixel, 0, numDataElements);
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param outData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements().
* If null an array of appropriate type and size will be
* allocated.
* @return An object reference to an array of type defined by
* getTransferType() with the request pixel data.
*/
public Object getDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
short outData[];
if (obj == null) {
outData = new short[w*h*numDataElements];
} else {
outData = (short[])obj;
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
outData[off++] = data[dataOffsets[c] + xoff];
}
}
}
return outData;
}
/**
* Returns a short integer array of data elements from the
* specified rectangular region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* <pre>
* short[] bandData = Raster.getShortData(x, y, w, h, null);
* // To find the data element at location (x2, y2)
* short dataElenent = bandData[((y2-y)*w + (x2-x))];
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the sample rectangle.
* @param height Height of the sample rectangle.
* @param band The band to return.
* @param outData If non-null, data elements for all bands
* at the specified location are returned in this array.
* @return Data array with data elements for all bands.
*/
public short[] getShortData(int x, int y, int w, int h,
int band, short[] outData) {
// Bounds check for 'band' will be performed automatically
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
if (outData == null) {
outData = new short[numDataElements*w*h];
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride+ dataOffsets[band];
int xoff;
int off = 0;
int xstart;
int ystart;
if (pixelStride == 1) {
if (scanlineStride == w) {
System.arraycopy(data, yoff, outData, 0, w*h);
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
System.arraycopy(data, yoff, outData, off, w);
off += w;
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
outData[off++] = data[xoff];
}
}
}
return outData;
}
/**
* Returns a short integer array of data elements from the
* specified rectangular region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* <pre>
* short[] bandData = Raster.getShortData(x, y, w, h, null);
* int numDataElements = Raster.getNumBands();
* short[] pixel = new short[numDataElements];
* // To find the data element at location (x2, y2)
* System.arraycopy(bandData, ((y2-y)*w + (x2-x))*numDataElements,
* pixel, 0, numDataElements);
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param width Width of the pixel rectangle.
* @param height Height of the pixel rectangle.
* @param outData If non-null, data elements for all bands
* at the specified location are returned in this array.
* @return Data array with data elements for all bands.
*/
public short[] getShortData(int x, int y, int w, int h, short[] outData) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
if (outData == null) {
outData = new short[numDataElements*w*h];
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
outData[off++] = data[dataOffsets[c] + xoff];
}
}
}
return outData;
}
/**
* Stores the data elements for all bands at the specified location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinate is out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inData An object reference to an array of type defined by
* getTransferType() and length getNumDataElements()
* containing the pixel data to place at x,y.
*/
public void setDataElements(int x, int y, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x >= this.maxX) || (y >= this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
short inData[] = (short[])obj;
int off = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
for (int i = 0; i < numDataElements; i++) {
data[dataOffsets[i] + off] = (short) inData[i];
}
markDirty();
}
/**
* Stores the Raster data at the specified location.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* @param x The X coordinate of the pixel location.
* @param y The Y coordinate of the pixel location.
* @param inRaster Raster of data to place at x,y location.
*/
public void setDataElements(int x, int y, Raster inRaster) {
int dstOffX = x + inRaster.getMinX();
int dstOffY = y + inRaster.getMinY();
int width = inRaster.getWidth();
int height = inRaster.getHeight();
if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
(dstOffX + width > this.maxX) || (dstOffY + height > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
setDataElements(dstOffX, dstOffY, width, height, inRaster);
}
/**
* Stores the Raster data at the specified location.
* @param dstX The absolute X coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param dstY The absolute Y coordinate of the destination pixel
* that will receive a copy of the upper-left pixel of the
* inRaster
* @param width The number of pixels to store horizontally
* @param height The number of pixels to store vertically
* @param inRaster Raster of data to place at x,y location.
*/
private void setDataElements(int dstX, int dstY,
int width, int height,
Raster inRaster) {
// Assume bounds checking has been performed previously
if (width <= 0 || height <= 0) {
return;
}
// Write inRaster (minX, minY) to (dstX, dstY)
int srcOffX = inRaster.getMinX();
int srcOffY = inRaster.getMinY();
Object tdata = null;
// // REMIND: Do something faster!
// if (inRaster instanceof ShortComponentRaster) {
// }
for (int startY=0; startY < height; startY++) {
// Grab one scanline at a time
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
width, 1, tdata);
setDataElements(dstX, dstY + startY, width, 1, tdata);
}
}
/**
* Stores an array of data elements into the specified rectangular
* region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* A ClassCastException will be thrown if the input object is non null
* and references anything other than an array of transferType.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* for the nth band at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))*numDataElements + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData An object reference to an array of type defined by
* getTransferType() and length w*h*getNumDataElements()
* containing the pixel data to place between x,y and
* x+h, y+h.
*/
public void setDataElements(int x, int y, int w, int h, Object obj) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
short inData[] = (short[])obj;
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
data[dataOffsets[c] + xoff] = (short) inData[off++];
}
}
}
markDirty();
}
/**
* Stores a short integer array of data elements into the
* specified rectangular region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param band The band to set.
* @param inData The data elements to be stored.
*/
public void putShortData(int x, int y, int w, int h,
int band, short[] inData) {
// Bounds check for 'band' will be performed automatically
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride + dataOffsets[band];
int xoff;
int off = 0;
int xstart;
int ystart;
if (pixelStride == 1) {
if (scanlineStride == w) {
System.arraycopy(inData, 0, data, yoff, w*h);
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
System.arraycopy(inData, off, data, yoff, w);
off += w;
}
}
}
else {
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
data[xoff] = inData[off++];
}
}
}
markDirty();
}
/**
* Stores a short integer array of data elements into the
* specified rectangular region.
* An ArrayIndexOutOfBounds exception will be thrown at runtime
* if the pixel coordinates are out of bounds.
* The data elements in the
* data array are assumed to be packed. That is, a data element
* for the nth band at location (x2, y2) would be found at:
* <pre>
* inData[((y2-y)*w + (x2-x))*numDataElements + n]
* </pre>
* @param x The X coordinate of the upper left pixel location.
* @param y The Y coordinate of the upper left pixel location.
* @param w Width of the pixel rectangle.
* @param h Height of the pixel rectangle.
* @param inData The data elements to be stored.
*/
public void putShortData(int x, int y, int w, int h, short[] inData) {
if ((x < this.minX) || (y < this.minY) ||
(x + w > this.maxX) || (y + h > this.maxY)) {
throw new ArrayIndexOutOfBoundsException
("Coordinate out of bounds!");
}
int yoff = (y-minY)*scanlineStride +
(x-minX)*pixelStride;
int xoff;
int off = 0;
int xstart;
int ystart;
for (ystart=0; ystart < h; ystart++, yoff += scanlineStride) {
xoff = yoff;
for (xstart=0; xstart < w; xstart++, xoff += pixelStride) {
for (int c = 0; c < numDataElements; c++) {
data[dataOffsets[c] + xoff] = inData[off++];
}
}
}
markDirty();
}
/**
* Creates a subraster given a region of the raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this raster to the upper-left corner
* of the subraster. A subset of the bands of the parent Raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. A translation to the subRaster may also be specified.
* Note that the subraster will reference the same
* band objects as the parent raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subraster.
* @param y0 Translated Y origin of the subraster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent raster.
*/
public Raster createChild (int x, int y,
int width, int height,
int x0, int y0, int[] bandList) {
WritableRaster newRaster = createWritableChild(x, y,
width, height,
x0, y0,
bandList);
return (Raster) newRaster;
}
/**
* Creates a Writable subRaster given a region of the Raster. The x and y
* coordinates specify the horizontal and vertical offsets
* from the upper-left corner of this Raster to the upper-left corner
* of the subRaster. A subset of the bands of the parent Raster may
* be specified. If this is null, then all the bands are present in the
* subRaster. A translation to the subRaster may also be specified.
* Note that the subRaster will reference the same
* DataBuffers as the parent Raster, but using different offsets.
* @param x X offset.
* @param y Y offset.
* @param width Width (in pixels) of the subraster.
* @param height Height (in pixels) of the subraster.
* @param x0 Translated X origin of the subraster.
* @param y0 Translated Y origin of the subraster.
* @param bandList Array of band indices.
* @exception RasterFormatException
* if the specified bounding box is outside of the parent Raster.
*/
public WritableRaster createWritableChild(int x, int y,
int width, int height,
int x0, int y0,
int[] bandList) {
if (x < this.minX) {
throw new RasterFormatException("x lies outside the raster");
}
if (y < this.minY) {
throw new RasterFormatException("y lies outside the raster");
}
if ((x+width < x) || (x+width > this.minX + this.width)) {
throw new RasterFormatException("(x + width) is outside of Raster");
}
if ((y+height < y) || (y+height > this.minY + this.height)) {
throw new RasterFormatException("(y + height) is outside of Raster");
}
SampleModel sm;
if (bandList != null)
sm = sampleModel.createSubsetSampleModel(bandList);
else
sm = sampleModel;
int deltaX = x0 - x;
int deltaY = y0 - y;
return new ShortComponentRaster(sm,
dataBuffer,
new Rectangle(x0, y0, width, height),
new Point(sampleModelTranslateX+deltaX,
sampleModelTranslateY+deltaY),
this);
}
/**
* Creates a Raster with the same layout but using a different
* width and height, and with new zeroed data arrays.
*/
public WritableRaster createCompatibleWritableRaster(int w, int h) {
if (w <= 0 || h <=0) {
throw new RasterFormatException("negative "+
((w <= 0) ? "width" : "height"));
}
SampleModel sm = sampleModel.createCompatibleSampleModel(w, h);
return new ShortComponentRaster(sm, new Point(0, 0));
}
/**
* Creates a Raster with the same layout and the same
* width and height, and with new zeroed data arrays. If
* the Raster is a subRaster, this will call
* createCompatibleRaster(width, height).
*/
public WritableRaster createCompatibleWritableRaster() {
return createCompatibleWritableRaster(width,height);
}
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
*/
private void verify (boolean strictCheck) {
// Make sure data for Raster is in a legal range
for (int i=0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band "+i+
"("+dataOffsets[i]+
") must be >= 0");
}
}
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize+" )");
}
}
public String toString() {
return new String ("ShortComponentRaster: width = "+width
+" height = " + height
+" #numDataElements "+numDataElements);
// +" xOff = "+xOffset+" yOff = "+yOffset);
}
}

Просмотреть файл

@ -0,0 +1,129 @@
/*
* Copyright 2001-2007 Sun Microsystems, Inc. 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.awt.image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Image;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferUShort;
import java.awt.image.DataBufferInt;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
//import sun.java2d.SurfaceData;
import sun.java2d.StateTrackableDelegate;
/**
* This class exists as a middle layer between WritableRaster and its
* implementation specific subclasses (ByteComponentRaster, ShortBandedRaster,
* etc).
* It provides utilities to steal the data arrays from the standard DataBuffer
* types and also steals the StateTrackableDelegate from the associated
* DataBuffer so that it can be updated when the data is changed.
*/
public class SunWritableRaster extends WritableRaster {
private static DataStealer stealer;
public static interface DataStealer {
public byte[] getData(DataBufferByte dbb, int bank);
public short[] getData(DataBufferUShort dbus, int bank);
public int[] getData(DataBufferInt dbi, int bank);
public StateTrackableDelegate getTrackable(DataBuffer db);
}
public static void setDataStealer(DataStealer ds) {
if (stealer != null) {
throw new InternalError("Attempt to set DataStealer twice");
}
stealer = ds;
}
public static byte[] stealData(DataBufferByte dbb, int bank) {
return stealer.getData(dbb, bank);
}
public static short[] stealData(DataBufferUShort dbus, int bank) {
return stealer.getData(dbus, bank);
}
public static int[] stealData(DataBufferInt dbi, int bank) {
return stealer.getData(dbi, bank);
}
public static StateTrackableDelegate stealTrackable(DataBuffer db) {
return stealer.getTrackable(db);
}
public static void markDirty(DataBuffer db) {
stealer.getTrackable(db).markDirty();
}
public static void markDirty(WritableRaster wr) {
if (wr instanceof SunWritableRaster) {
((SunWritableRaster) wr).markDirty();
} else {
markDirty(wr.getDataBuffer());
}
}
public static void markDirty(Image img) {
// SurfaceData.getPrimarySurfaceData(img).markDirty();
}
private StateTrackableDelegate theTrackable;
public SunWritableRaster(SampleModel sampleModel, Point origin) {
super(sampleModel, origin);
theTrackable = stealTrackable(dataBuffer);
}
public SunWritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Point origin)
{
super(sampleModel, dataBuffer, origin);
theTrackable = stealTrackable(dataBuffer);
}
public SunWritableRaster(SampleModel sampleModel,
DataBuffer dataBuffer,
Rectangle aRegion,
Point sampleModelTranslate,
WritableRaster parent)
{
super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
theTrackable = stealTrackable(dataBuffer);
}
/**
* Mark the TrackableDelegate of the associated DataBuffer dirty.
*/
public final void markDirty() {
theTrackable.markDirty();
}
}