зеркало из https://github.com/mono/ikvm-fork.git
replace a small part (BufferedImage ff) of classpath with OpenJDK
This commit is contained in:
Родитель
344924593f
Коммит
08fbc6b63b
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
Загрузка…
Ссылка в новой задаче