Merge
This commit is contained in:
commit
1d540f665e
jdk
make
src/share/classes/java/awt
color
CMMException.javaColorSpace.javaICC_ColorSpace.javaICC_Profile.javaICC_ProfileGray.javaICC_ProfileRGB.java
image
BandedSampleModel.javaColorConvertOp.javaComponentSampleModel.javaDataBuffer.javaDataBufferByte.javaDataBufferInt.javaDataBufferShort.javaDataBufferUShort.javaMultiPixelPackedSampleModel.javaRaster.javaRenderedImage.javaSampleModel.javaSinglePixelPackedSampleModel.javaWritableRaster.javaWritableRenderedImage.java
renderable
@ -126,44 +126,10 @@ com/sun/media/sound/SimpleInputDeviceProvider\$$1.class \
|
||||
com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
|
||||
com/sun/media/sound/SimpleInputDeviceProvider.class
|
||||
|
||||
PLUG_AWT_CLASS_NAMES = \
|
||||
java/awt/color/CMMException.class \
|
||||
java/awt/color/ColorSpace.class \
|
||||
java/awt/color/ICC_ColorSpace.class \
|
||||
java/awt/color/ICC_Profile\$$1.class \
|
||||
java/awt/color/ICC_Profile\$$2.class \
|
||||
java/awt/color/ICC_Profile\$$3.class \
|
||||
java/awt/color/ICC_Profile.class \
|
||||
java/awt/color/ICC_ProfileGray.class \
|
||||
java/awt/color/ICC_ProfileRGB.class \
|
||||
java/awt/image/BandedSampleModel.class \
|
||||
java/awt/image/ColorConvertOp.class \
|
||||
java/awt/image/ComponentSampleModel.class \
|
||||
java/awt/image/DataBuffer\$$1.class \
|
||||
java/awt/image/DataBuffer.class \
|
||||
java/awt/image/DataBufferByte.class \
|
||||
java/awt/image/DataBufferInt.class \
|
||||
java/awt/image/DataBufferShort.class \
|
||||
java/awt/image/DataBufferUShort.class \
|
||||
java/awt/image/MultiPixelPackedSampleModel.class \
|
||||
java/awt/image/Raster.class \
|
||||
java/awt/image/RenderedImage.class \
|
||||
java/awt/image/SampleModel.class \
|
||||
java/awt/image/SinglePixelPackedSampleModel.class \
|
||||
java/awt/image/WritableRaster.class \
|
||||
java/awt/image/WritableRenderedImage.class \
|
||||
java/awt/image/renderable/ContextualRenderedImageFactory.class \
|
||||
java/awt/image/renderable/ParameterBlock.class \
|
||||
java/awt/image/renderable/RenderContext.class \
|
||||
java/awt/image/renderable/RenderableImage.class \
|
||||
java/awt/image/renderable/RenderableImageOp.class \
|
||||
java/awt/image/renderable/RenderableImageProducer.class \
|
||||
java/awt/image/renderable/RenderedImageFactory.class
|
||||
|
||||
# Class list temp files (used by both import and export of plugs)
|
||||
|
||||
PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
|
||||
PLUG_CLASS_AREAS = jmf sound awt
|
||||
PLUG_CLASS_AREAS = jmf sound
|
||||
PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
|
||||
|
||||
# Create jargs file command
|
||||
@ -186,11 +152,6 @@ $(PLUG_TEMPDIR)/sound.clist:
|
||||
@for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
|
||||
$(ECHO) "$$i" >> $@ ; \
|
||||
done
|
||||
$(PLUG_TEMPDIR)/awt.clist:
|
||||
@$(prep-target)
|
||||
@for i in $(PLUG_AWT_CLASS_NAMES) ; do \
|
||||
$(ECHO) "$$i" >> $@ ; \
|
||||
done
|
||||
$(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
|
||||
@$(prep-target)
|
||||
$(CAT) $(PLUG_CLISTS) > $@
|
||||
@ -198,8 +159,6 @@ $(PLUG_TEMPDIR)/jmf.jargs: $(PLUG_TEMPDIR)/jmf.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/awt.jargs: $(PLUG_TEMPDIR)/awt.clist
|
||||
$(plug-create-jargs)
|
||||
$(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
|
||||
$(plug-create-jargs)
|
||||
|
||||
@ -235,15 +194,12 @@ import-binary-plug-jmf-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/jmf.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
|
||||
import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
|
||||
import-binary-plug-awt-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/awt.clist
|
||||
$(call import-binary-plug-classes,$(PLUG_TEMPDIR)/awt.clist)
|
||||
|
||||
# Import all classes from the jar file
|
||||
|
||||
import-binary-plug-jar: \
|
||||
import-binary-plug-jmf-classes \
|
||||
import-binary-plug-sound-classes \
|
||||
import-binary-plug-awt-classes
|
||||
import-binary-plug-sound-classes
|
||||
|
||||
# Import native libraries
|
||||
|
||||
@ -286,7 +242,6 @@ import-binary-plugs: \
|
||||
import-binary-plug-jar \
|
||||
import-binary-plug-jmf-classes \
|
||||
import-binary-plug-sound-classes \
|
||||
import-binary-plug-awt-classes \
|
||||
import-binary-plug-jsound-library
|
||||
|
||||
else # !OPENJDK
|
||||
|
@ -28,24 +28,12 @@ PACKAGE = java.awt
|
||||
PRODUCT = sun
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
# WARNING: Make sure the OPENJDK plugs are up-to-date, see make/common/internal/BinaryPlugs.gmk
|
||||
|
||||
#
|
||||
# Files
|
||||
#
|
||||
AUTO_FILES_JAVA_DIRS = java/awt sun/awt/geom
|
||||
|
||||
#
|
||||
# Specific to OPENJDK
|
||||
#
|
||||
ifdef OPENJDK
|
||||
|
||||
build: import-binary-plug-awt-classes
|
||||
|
||||
include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
|
||||
|
||||
endif
|
||||
|
||||
build: properties cursors
|
||||
|
||||
#
|
||||
|
57
jdk/src/share/classes/java/awt/color/CMMException.java
Normal file
57
jdk/src/share/classes/java/awt/color/CMMException.java
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
Created by gbp, October 25, 1997
|
||||
|
||||
*
|
||||
*/
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
|
||||
/**
|
||||
* This exception is thrown if the native CMM returns an error.
|
||||
*/
|
||||
|
||||
public class CMMException extends java.lang.RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructs a CMMException with the specified detail message.
|
||||
* @param s the specified detail message
|
||||
*/
|
||||
public CMMException (String s) {
|
||||
super (s);
|
||||
}
|
||||
}
|
611
jdk/src/share/classes/java/awt/color/ColorSpace.java
Normal file
611
jdk/src/share/classes/java/awt/color/ColorSpace.java
Normal file
@ -0,0 +1,611 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 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.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import sun.java2d.cmm.PCMM;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
|
||||
|
||||
/**
|
||||
* This abstract class is used to serve as a color space tag to identify the
|
||||
* specific color space of a Color object or, via a ColorModel object,
|
||||
* of an Image, a BufferedImage, or a GraphicsDevice. It contains
|
||||
* methods that transform colors in a specific color space to/from sRGB
|
||||
* and to/from a well-defined CIEXYZ color space.
|
||||
* <p>
|
||||
* For purposes of the methods in this class, colors are represented as
|
||||
* arrays of color components represented as floats in a normalized range
|
||||
* defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
|
||||
* range is 0.0 to 1.0. However, some ColorSpaces have components whose
|
||||
* values have a different range. Methods are provided to inquire per
|
||||
* component minimum and maximum normalized values.
|
||||
* <p>
|
||||
* Several variables are defined for purposes of referring to color
|
||||
* space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
|
||||
* color spaces (e.g. CS_sRGB and CS_CIEXYZ).
|
||||
* sRGB is a proposed standard RGB color space. For more information,
|
||||
* see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
|
||||
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
|
||||
* </A>.
|
||||
* <p>
|
||||
* The purpose of the methods to transform to/from the well-defined
|
||||
* CIEXYZ color space is to support conversions between any two color
|
||||
* spaces at a reasonably high degree of accuracy. It is expected that
|
||||
* particular implementations of subclasses of ColorSpace (e.g.
|
||||
* ICC_ColorSpace) will support high performance conversion based on
|
||||
* underlying platform color management systems.
|
||||
* <p>
|
||||
* The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
|
||||
* described as follows:
|
||||
<pre>
|
||||
|
||||
CIEXYZ
|
||||
viewing illuminance: 200 lux
|
||||
viewing white point: CIE D50
|
||||
media white point: "that of a perfectly reflecting diffuser" -- D50
|
||||
media black point: 0 lux or 0 Reflectance
|
||||
flare: 1 percent
|
||||
surround: 20percent of the media white point
|
||||
media description: reflection print (i.e., RLAB, Hunt viewing media)
|
||||
note: For developers creating an ICC profile for this conversion
|
||||
space, the following is applicable. Use a simple Von Kries
|
||||
white point adaptation folded into the 3X3 matrix parameters
|
||||
and fold the flare and surround effects into the three
|
||||
one-dimensional lookup tables (assuming one uses the minimal
|
||||
model for monitors).
|
||||
|
||||
</pre>
|
||||
*
|
||||
* <p>
|
||||
* @see ICC_ColorSpace
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public abstract class ColorSpace implements java.io.Serializable {
|
||||
|
||||
static final long serialVersionUID = -409452704308689724L;
|
||||
|
||||
private int type;
|
||||
private int numComponents;
|
||||
private transient String [] compName = null;
|
||||
|
||||
// Cache of singletons for the predefined color spaces.
|
||||
private static ColorSpace sRGBspace;
|
||||
private static ColorSpace XYZspace;
|
||||
private static ColorSpace PYCCspace;
|
||||
private static ColorSpace GRAYspace;
|
||||
private static ColorSpace LINEAR_RGBspace;
|
||||
|
||||
/**
|
||||
* Any of the family of XYZ color spaces.
|
||||
*/
|
||||
public static final int TYPE_XYZ = 0;
|
||||
|
||||
/**
|
||||
* Any of the family of Lab color spaces.
|
||||
*/
|
||||
public static final int TYPE_Lab = 1;
|
||||
|
||||
/**
|
||||
* Any of the family of Luv color spaces.
|
||||
*/
|
||||
public static final int TYPE_Luv = 2;
|
||||
|
||||
/**
|
||||
* Any of the family of YCbCr color spaces.
|
||||
*/
|
||||
public static final int TYPE_YCbCr = 3;
|
||||
|
||||
/**
|
||||
* Any of the family of Yxy color spaces.
|
||||
*/
|
||||
public static final int TYPE_Yxy = 4;
|
||||
|
||||
/**
|
||||
* Any of the family of RGB color spaces.
|
||||
*/
|
||||
public static final int TYPE_RGB = 5;
|
||||
|
||||
/**
|
||||
* Any of the family of GRAY color spaces.
|
||||
*/
|
||||
public static final int TYPE_GRAY = 6;
|
||||
|
||||
/**
|
||||
* Any of the family of HSV color spaces.
|
||||
*/
|
||||
public static final int TYPE_HSV = 7;
|
||||
|
||||
/**
|
||||
* Any of the family of HLS color spaces.
|
||||
*/
|
||||
public static final int TYPE_HLS = 8;
|
||||
|
||||
/**
|
||||
* Any of the family of CMYK color spaces.
|
||||
*/
|
||||
public static final int TYPE_CMYK = 9;
|
||||
|
||||
/**
|
||||
* Any of the family of CMY color spaces.
|
||||
*/
|
||||
public static final int TYPE_CMY = 11;
|
||||
|
||||
/**
|
||||
* Generic 2 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_2CLR = 12;
|
||||
|
||||
/**
|
||||
* Generic 3 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_3CLR = 13;
|
||||
|
||||
/**
|
||||
* Generic 4 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_4CLR = 14;
|
||||
|
||||
/**
|
||||
* Generic 5 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_5CLR = 15;
|
||||
|
||||
/**
|
||||
* Generic 6 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_6CLR = 16;
|
||||
|
||||
/**
|
||||
* Generic 7 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_7CLR = 17;
|
||||
|
||||
/**
|
||||
* Generic 8 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_8CLR = 18;
|
||||
|
||||
/**
|
||||
* Generic 9 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_9CLR = 19;
|
||||
|
||||
/**
|
||||
* Generic 10 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_ACLR = 20;
|
||||
|
||||
/**
|
||||
* Generic 11 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_BCLR = 21;
|
||||
|
||||
/**
|
||||
* Generic 12 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_CCLR = 22;
|
||||
|
||||
/**
|
||||
* Generic 13 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_DCLR = 23;
|
||||
|
||||
/**
|
||||
* Generic 14 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_ECLR = 24;
|
||||
|
||||
/**
|
||||
* Generic 15 component color spaces.
|
||||
*/
|
||||
public static final int TYPE_FCLR = 25;
|
||||
|
||||
/**
|
||||
* The sRGB color space defined at
|
||||
* <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
|
||||
* http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
|
||||
* </A>.
|
||||
*/
|
||||
public static final int CS_sRGB = 1000;
|
||||
|
||||
/**
|
||||
* A built-in linear RGB color space. This space is based on the
|
||||
* same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
|
||||
*/
|
||||
public static final int CS_LINEAR_RGB = 1004;
|
||||
|
||||
/**
|
||||
* The CIEXYZ conversion color space defined above.
|
||||
*/
|
||||
public static final int CS_CIEXYZ = 1001;
|
||||
|
||||
/**
|
||||
* The Photo YCC conversion color space.
|
||||
*/
|
||||
public static final int CS_PYCC = 1002;
|
||||
|
||||
/**
|
||||
* The built-in linear gray scale color space.
|
||||
*/
|
||||
public static final int CS_GRAY = 1003;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a ColorSpace object given a color space type
|
||||
* and the number of components.
|
||||
* @param type one of the <CODE>ColorSpace</CODE> type constants
|
||||
* @param numcomponents the number of components in the color space
|
||||
*/
|
||||
protected ColorSpace (int type, int numcomponents) {
|
||||
this.type = type;
|
||||
this.numComponents = numcomponents;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a ColorSpace representing one of the specific
|
||||
* predefined color spaces.
|
||||
* @param colorspace a specific color space identified by one of
|
||||
* the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
|
||||
* CS_CIEXYZ, CS_GRAY, or CS_PYCC)
|
||||
* @return the requested <CODE>ColorSpace</CODE> object
|
||||
*/
|
||||
// NOTE: This method may be called by privileged threads.
|
||||
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
|
||||
public static ColorSpace getInstance (int colorspace)
|
||||
{
|
||||
ColorSpace theColorSpace;
|
||||
|
||||
switch (colorspace) {
|
||||
case CS_sRGB:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (sRGBspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
|
||||
sRGBspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = sRGBspace;
|
||||
}
|
||||
break;
|
||||
|
||||
case CS_CIEXYZ:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (XYZspace == null) {
|
||||
ICC_Profile theProfile =
|
||||
ICC_Profile.getInstance (CS_CIEXYZ);
|
||||
XYZspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = XYZspace;
|
||||
}
|
||||
break;
|
||||
|
||||
case CS_PYCC:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (PYCCspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
|
||||
PYCCspace = new ICC_ColorSpace (theProfile);
|
||||
}
|
||||
|
||||
theColorSpace = PYCCspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_GRAY:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (GRAYspace == null) {
|
||||
ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
|
||||
GRAYspace = new ICC_ColorSpace (theProfile);
|
||||
/* to allow access from java.awt.ColorModel */
|
||||
CMSManager.GRAYspace = GRAYspace;
|
||||
}
|
||||
|
||||
theColorSpace = GRAYspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case CS_LINEAR_RGB:
|
||||
synchronized(ColorSpace.class) {
|
||||
if (LINEAR_RGBspace == null) {
|
||||
ICC_Profile theProfile =
|
||||
ICC_Profile.getInstance(CS_LINEAR_RGB);
|
||||
LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
|
||||
/* to allow access from java.awt.ColorModel */
|
||||
CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
|
||||
}
|
||||
|
||||
theColorSpace = LINEAR_RGBspace;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException ("Unknown color space");
|
||||
}
|
||||
|
||||
return theColorSpace;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the ColorSpace is CS_sRGB.
|
||||
* @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
|
||||
* space, <code>false</code> if it is not
|
||||
*/
|
||||
public boolean isCS_sRGB () {
|
||||
/* REMIND - make sure we know sRGBspace exists already */
|
||||
return (this == sRGBspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into a value in the default CS_sRGB color space.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of this color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace
|
||||
* @return a float array of length 3
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace
|
||||
*/
|
||||
public abstract float[] toRGB(float[] colorvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the default CS_sRGB
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of the CS_sRGB color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of this color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param rgbvalue a float array with length of at least 3
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3
|
||||
*/
|
||||
public abstract float[] fromRGB(float[] rgbvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into the CS_CIEXYZ conversion color space.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the International Color Consortium standard. This
|
||||
* means that the XYZ values returned by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. This
|
||||
* representation is not the same as the XYZ values that would
|
||||
* be measured from the given color value by a colorimeter.
|
||||
* A further transformation is necessary to compute the XYZ values
|
||||
* that would be measured using current CIE recommended practices.
|
||||
* See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
|
||||
* <code>ICC_ColorSpace</code> for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace
|
||||
* @return a float array of length 3
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public abstract float[] toCIEXYZ(float[] colorvalue);
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the International Color Consortium standard. This
|
||||
* means that the XYZ argument values taken by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. The color
|
||||
* values returned by this method are not those that would produce
|
||||
* the XYZ value passed to the method when measured by a colorimeter.
|
||||
* If you have XYZ values corresponding to measurements made using
|
||||
* current CIE recommended practices, they must be converted to D50
|
||||
* relative values before being passed to this method.
|
||||
* See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
|
||||
* <code>ICC_ColorSpace</code> for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least 3
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3
|
||||
*/
|
||||
public abstract float[] fromCIEXYZ(float[] colorvalue);
|
||||
|
||||
/**
|
||||
* Returns the color space type of this ColorSpace (for example
|
||||
* TYPE_RGB, TYPE_XYZ, ...). The type defines the
|
||||
* number of components of the color space and the interpretation,
|
||||
* e.g. TYPE_RGB identifies a color space with three components - red,
|
||||
* green, and blue. It does not define the particular color
|
||||
* characteristics of the space, e.g. the chromaticities of the
|
||||
* primaries.
|
||||
*
|
||||
* @return the type constant that represents the type of this
|
||||
* <CODE>ColorSpace</CODE>
|
||||
*/
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of components of this ColorSpace.
|
||||
* @return The number of components in this <CODE>ColorSpace</CODE>.
|
||||
*/
|
||||
public int getNumComponents() {
|
||||
return numComponents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the component given the component index.
|
||||
*
|
||||
* @param idx the component index
|
||||
* @return the name of the component at the specified index
|
||||
* @throws IllegalArgumentException if <code>idx</code> is
|
||||
* less than 0 or greater than numComponents - 1
|
||||
*/
|
||||
public String getName (int idx) {
|
||||
/* REMIND - handle common cases here */
|
||||
if ((idx < 0) || (idx > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + idx);
|
||||
}
|
||||
|
||||
if (compName == null) {
|
||||
switch (type) {
|
||||
case ColorSpace.TYPE_XYZ:
|
||||
compName = new String[] {"X", "Y", "Z"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Lab:
|
||||
compName = new String[] {"L", "a", "b"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Luv:
|
||||
compName = new String[] {"L", "u", "v"};
|
||||
break;
|
||||
case ColorSpace.TYPE_YCbCr:
|
||||
compName = new String[] {"Y", "Cb", "Cr"};
|
||||
break;
|
||||
case ColorSpace.TYPE_Yxy:
|
||||
compName = new String[] {"Y", "x", "y"};
|
||||
break;
|
||||
case ColorSpace.TYPE_RGB:
|
||||
compName = new String[] {"Red", "Green", "Blue"};
|
||||
break;
|
||||
case ColorSpace.TYPE_GRAY:
|
||||
compName = new String[] {"Gray"};
|
||||
break;
|
||||
case ColorSpace.TYPE_HSV:
|
||||
compName = new String[] {"Hue", "Saturation", "Value"};
|
||||
break;
|
||||
case ColorSpace.TYPE_HLS:
|
||||
compName = new String[] {"Hue", "Lightness",
|
||||
"Saturation"};
|
||||
break;
|
||||
case ColorSpace.TYPE_CMYK:
|
||||
compName = new String[] {"Cyan", "Magenta", "Yellow",
|
||||
"Black"};
|
||||
break;
|
||||
case ColorSpace.TYPE_CMY:
|
||||
compName = new String[] {"Cyan", "Magenta", "Yellow"};
|
||||
break;
|
||||
default:
|
||||
String [] tmp = new String[numComponents];
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
tmp[i] = "Unnamed color component(" + i + ")";
|
||||
}
|
||||
compName = tmp;
|
||||
}
|
||||
}
|
||||
return compName[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum normalized color component value for the
|
||||
* specified component. The default implementation in this abstract
|
||||
* class returns 0.0 for all components. Subclasses should override
|
||||
* this method if necessary.
|
||||
*
|
||||
* @param component the component index
|
||||
* @return the minimum normalized component value
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMinValue(int component) {
|
||||
if ((component < 0) || (component > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + component);
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum normalized color component value for the
|
||||
* specified component. The default implementation in this abstract
|
||||
* class returns 1.0 for all components. Subclasses should override
|
||||
* this method if necessary.
|
||||
*
|
||||
* @param component the component index
|
||||
* @return the maximum normalized component value
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMaxValue(int component) {
|
||||
if ((component < 0) || (component > numComponents - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: " + component);
|
||||
}
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/* Returns true if cspace is the XYZspace.
|
||||
*/
|
||||
static boolean isCS_CIEXYZ(ColorSpace cspace) {
|
||||
return (cspace == XYZspace);
|
||||
}
|
||||
}
|
616
jdk/src/share/classes/java/awt/color/ICC_ColorSpace.java
Normal file
616
jdk/src/share/classes/java/awt/color/ICC_ColorSpace.java
Normal file
@ -0,0 +1,616 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import sun.java2d.cmm.ColorTransform;
|
||||
import sun.java2d.cmm.CMSManager;
|
||||
import sun.java2d.cmm.PCMM;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* The ICC_ColorSpace class is an implementation of the abstract
|
||||
* ColorSpace class. This representation of
|
||||
* device independent and device dependent color spaces is based on the
|
||||
* International Color Consortium Specification ICC.1:2001-12, File Format for
|
||||
* Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
|
||||
* <p>
|
||||
* Typically, a Color or ColorModel would be associated with an ICC
|
||||
* Profile which is either an input, display, or output profile (see
|
||||
* the ICC specification). There are other types of ICC Profiles, e.g.
|
||||
* abstract profiles, device link profiles, and named color profiles,
|
||||
* which do not contain information appropriate for representing the color
|
||||
* space of a color, image, or device (see ICC_Profile).
|
||||
* Attempting to create an ICC_ColorSpace object from an inappropriate ICC
|
||||
* Profile is an error.
|
||||
* <p>
|
||||
* ICC Profiles represent transformations from the color space of
|
||||
* the profile (e.g. a monitor) to a Profile Connection Space (PCS).
|
||||
* Profiles of interest for tagging images or colors have a
|
||||
* PCS which is one of the device independent
|
||||
* spaces (one CIEXYZ space and two CIELab spaces) defined in the
|
||||
* ICC Profile Format Specification. Most profiles of interest
|
||||
* either have invertible transformations or explicitly specify
|
||||
* transformations going both directions. Should an ICC_ColorSpace
|
||||
* object be used in a way requiring a conversion from PCS to
|
||||
* the profile's native space and there is inadequate data to
|
||||
* correctly perform the conversion, the ICC_ColorSpace object will
|
||||
* produce output in the specified type of color space (e.g. TYPE_RGB,
|
||||
* TYPE_CMYK, etc.), but the specific color values of the output data
|
||||
* will be undefined.
|
||||
* <p>
|
||||
* The details of this class are not important for simple applets,
|
||||
* which draw in a default color space or manipulate and display
|
||||
* imported images with a known color space. At most, such applets
|
||||
* would need to get one of the default color spaces via
|
||||
* ColorSpace.getInstance().
|
||||
* <p>
|
||||
* @see ColorSpace
|
||||
* @see ICC_Profile
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ColorSpace extends ColorSpace {
|
||||
|
||||
static final long serialVersionUID = 3455889114070431483L;
|
||||
|
||||
private ICC_Profile thisProfile;
|
||||
private float[] minVal;
|
||||
private float[] maxVal;
|
||||
private float[] diffMinMax;
|
||||
private float[] invDiffMinMax;
|
||||
private boolean needScaleInit = true;
|
||||
|
||||
// {to,from}{RGB,CIEXYZ} methods create and cache these when needed
|
||||
private transient ColorTransform this2srgb;
|
||||
private transient ColorTransform srgb2this;
|
||||
private transient ColorTransform this2xyz;
|
||||
private transient ColorTransform xyz2this;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ColorSpace from an ICC_Profile object.
|
||||
* @param profile the specified ICC_Profile object
|
||||
* @exception IllegalArgumentException if profile is inappropriate for
|
||||
* representing a ColorSpace.
|
||||
*/
|
||||
public ICC_ColorSpace (ICC_Profile profile) {
|
||||
super (profile.getColorSpaceType(), profile.getNumComponents());
|
||||
|
||||
int profileClass = profile.getProfileClass();
|
||||
|
||||
/* REMIND - is NAMEDCOLOR OK? */
|
||||
if ((profileClass != ICC_Profile.CLASS_INPUT) &&
|
||||
(profileClass != ICC_Profile.CLASS_DISPLAY) &&
|
||||
(profileClass != ICC_Profile.CLASS_OUTPUT) &&
|
||||
(profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
|
||||
(profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
|
||||
(profileClass != ICC_Profile.CLASS_ABSTRACT)) {
|
||||
throw new IllegalArgumentException("Invalid profile type");
|
||||
}
|
||||
|
||||
thisProfile = profile;
|
||||
setMinMax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ICC_Profile for this ICC_ColorSpace.
|
||||
* @return the ICC_Profile for this ICC_ColorSpace.
|
||||
*/
|
||||
public ICC_Profile getProfile() {
|
||||
return thisProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into a value in the default CS_sRGB color space.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of this color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of the CS_sRGB color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace.
|
||||
* @return a float array of length 3.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public float[] toRGB (float[] colorvalue) {
|
||||
|
||||
if (this2srgb == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace srgbCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.In);
|
||||
transformList[1] = mdl.createTransform(
|
||||
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
|
||||
this2srgb = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
int nc = this.getNumComponents();
|
||||
short tmp[] = new short[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
tmp[i] = (short)
|
||||
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
|
||||
}
|
||||
tmp = this2srgb.colorConvert(tmp, null);
|
||||
float[] result = new float [3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the default CS_sRGB
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using algorithms designed
|
||||
* to produce the best perceptual match between input and output
|
||||
* colors. In order to do colorimetric conversion of color values,
|
||||
* you should use the <code>toCIEXYZ</code>
|
||||
* method of the CS_sRGB color space to first convert from the input
|
||||
* color space to the CS_CIEXYZ color space, and then use the
|
||||
* <code>fromCIEXYZ</code> method of this color space to
|
||||
* convert from CS_CIEXYZ to the output color space.
|
||||
* See {@link #toCIEXYZ(float[]) toCIEXYZ} and
|
||||
* {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
|
||||
* <p>
|
||||
* @param rgbvalue a float array with length of at least 3.
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3.
|
||||
*/
|
||||
public float[] fromRGB(float[] rgbvalue) {
|
||||
|
||||
if (srgb2this == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace srgbCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform(
|
||||
srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
|
||||
transformList[1] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.Out);
|
||||
srgb2this = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
short tmp[] = new short[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
|
||||
}
|
||||
tmp = srgb2this.colorConvert(tmp, null);
|
||||
int nc = this.getNumComponents();
|
||||
float[] result = new float [nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
|
||||
diffMinMax[i] + minVal[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in this ColorSpace
|
||||
* into the CS_CIEXYZ conversion color space.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the ICC Specification. This
|
||||
* means that the XYZ values returned by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. This
|
||||
* representation is not the same as the XYZ values that would
|
||||
* be measured from the given color value by a colorimeter.
|
||||
* A further transformation is necessary to compute the XYZ values
|
||||
* that would be measured using current CIE recommended practices.
|
||||
* The paragraphs below explain this in more detail.
|
||||
* <p>
|
||||
* The ICC standard uses a device independent color space (DICS) as the
|
||||
* mechanism for converting color from one device to another device. In
|
||||
* this architecture, colors are converted from the source device's color
|
||||
* space to the ICC DICS and then from the ICC DICS to the destination
|
||||
* device's color space. The ICC standard defines device profiles which
|
||||
* contain transforms which will convert between a device's color space
|
||||
* and the ICC DICS. The overall conversion of colors from a source
|
||||
* device to colors of a destination device is done by connecting the
|
||||
* device-to-DICS transform of the profile for the source device to the
|
||||
* DICS-to-device transform of the profile for the destination device.
|
||||
* For this reason, the ICC DICS is commonly referred to as the profile
|
||||
* connection space (PCS). The color space used in the methods
|
||||
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
|
||||
* Specification. This is also the color space represented by
|
||||
* ColorSpace.CS_CIEXYZ.
|
||||
* <p>
|
||||
* The XYZ values of a color are often represented as relative to some
|
||||
* white point, so the actual meaning of the XYZ values cannot be known
|
||||
* without knowing the white point of those values. This is known as
|
||||
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
|
||||
* values of the PCS are relative to D50. For example, white in the PCS
|
||||
* will have the XYZ values of D50, which is defined to be X=.9642,
|
||||
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
|
||||
* arts applications, but others are often used in other applications.
|
||||
* <p>
|
||||
* To quantify the color characteristics of a device such as a printer
|
||||
* or monitor, measurements of XYZ values for particular device colors
|
||||
* are typically made. For purposes of this discussion, the term
|
||||
* device XYZ values is used to mean the XYZ values that would be
|
||||
* measured from device colors using current CIE recommended practices.
|
||||
* <p>
|
||||
* Converting between device XYZ values and the PCS XYZ values returned
|
||||
* by this method corresponds to converting between the device's color
|
||||
* space, as represented by CIE colorimetric values, and the PCS. There
|
||||
* are many factors involved in this process, some of which are quite
|
||||
* subtle. The most important, however, is the adjustment made to account
|
||||
* for differences between the device's white point and the white point of
|
||||
* the PCS. There are many techniques for doing this and it is the
|
||||
* subject of much current research and controversy. Some commonly used
|
||||
* methods are XYZ scaling, the von Kries transform, and the Bradford
|
||||
* transform. The proper method to use depends upon each particular
|
||||
* application.
|
||||
* <p>
|
||||
* The simplest method is XYZ scaling. In this method each device XYZ
|
||||
* value is converted to a PCS XYZ value by multiplying it by the ratio
|
||||
* of the PCS white point (D50) to the device white point.
|
||||
* <pre>
|
||||
*
|
||||
* Xd, Yd, Zd are the device XYZ values
|
||||
* Xdw, Ydw, Zdw are the device XYZ white point values
|
||||
* Xp, Yp, Zp are the PCS XYZ values
|
||||
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
|
||||
*
|
||||
* Xp = Xd * (Xd50 / Xdw)
|
||||
* Yp = Yd * (Yd50 / Ydw)
|
||||
* Zp = Zd * (Zd50 / Zdw)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Conversion from the PCS to the device would be done by inverting these
|
||||
* equations:
|
||||
* <pre>
|
||||
*
|
||||
* Xd = Xp * (Xdw / Xd50)
|
||||
* Yd = Yp * (Ydw / Yd50)
|
||||
* Zd = Zp * (Zdw / Zd50)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Note that the media white point tag in an ICC profile is not the same
|
||||
* as the device white point. The media white point tag is expressed in
|
||||
* PCS values and is used to represent the difference between the XYZ of
|
||||
* device illuminant and the XYZ of the device media when measured under
|
||||
* that illuminant. The device white point is expressed as the device
|
||||
* XYZ values corresponding to white displayed on the device. For
|
||||
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
|
||||
* will result in a measured device XYZ value of D65. This will not
|
||||
* be the same as the media white point tag XYZ value in the ICC
|
||||
* profile for an sRGB device.
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least the number
|
||||
* of components in this ColorSpace.
|
||||
* @return a float array of length 3.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least the number of components in this ColorSpace.
|
||||
*/
|
||||
public float[] toCIEXYZ(float[] colorvalue) {
|
||||
|
||||
if (this2xyz == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace xyzCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
try {
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ICC_Profile.icRelativeColorimetric,
|
||||
ColorTransform.In);
|
||||
} catch (CMMException e) {
|
||||
transformList[0] = mdl.createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.In);
|
||||
}
|
||||
transformList[1] = mdl.createTransform(
|
||||
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
|
||||
this2xyz = mdl.createTransform (transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
int nc = this.getNumComponents();
|
||||
short tmp[] = new short[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
tmp[i] = (short)
|
||||
((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
|
||||
}
|
||||
tmp = this2xyz.colorConvert(tmp, null);
|
||||
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
|
||||
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
|
||||
float[] result = new float [3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Transforms a color value assumed to be in the CS_CIEXYZ conversion
|
||||
* color space into this ColorSpace.
|
||||
* <p>
|
||||
* This method transforms color values using relative colorimetry,
|
||||
* as defined by the ICC Specification. This
|
||||
* means that the XYZ argument values taken by this method are represented
|
||||
* relative to the D50 white point of the CS_CIEXYZ color space.
|
||||
* This representation is useful in a two-step color conversion
|
||||
* process in which colors are transformed from an input color
|
||||
* space to CS_CIEXYZ and then to an output color space. The color
|
||||
* values returned by this method are not those that would produce
|
||||
* the XYZ value passed to the method when measured by a colorimeter.
|
||||
* If you have XYZ values corresponding to measurements made using
|
||||
* current CIE recommended practices, they must be converted to D50
|
||||
* relative values before being passed to this method.
|
||||
* The paragraphs below explain this in more detail.
|
||||
* <p>
|
||||
* The ICC standard uses a device independent color space (DICS) as the
|
||||
* mechanism for converting color from one device to another device. In
|
||||
* this architecture, colors are converted from the source device's color
|
||||
* space to the ICC DICS and then from the ICC DICS to the destination
|
||||
* device's color space. The ICC standard defines device profiles which
|
||||
* contain transforms which will convert between a device's color space
|
||||
* and the ICC DICS. The overall conversion of colors from a source
|
||||
* device to colors of a destination device is done by connecting the
|
||||
* device-to-DICS transform of the profile for the source device to the
|
||||
* DICS-to-device transform of the profile for the destination device.
|
||||
* For this reason, the ICC DICS is commonly referred to as the profile
|
||||
* connection space (PCS). The color space used in the methods
|
||||
* toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
|
||||
* Specification. This is also the color space represented by
|
||||
* ColorSpace.CS_CIEXYZ.
|
||||
* <p>
|
||||
* The XYZ values of a color are often represented as relative to some
|
||||
* white point, so the actual meaning of the XYZ values cannot be known
|
||||
* without knowing the white point of those values. This is known as
|
||||
* relative colorimetry. The PCS uses a white point of D50, so the XYZ
|
||||
* values of the PCS are relative to D50. For example, white in the PCS
|
||||
* will have the XYZ values of D50, which is defined to be X=.9642,
|
||||
* Y=1.000, and Z=0.8249. This white point is commonly used for graphic
|
||||
* arts applications, but others are often used in other applications.
|
||||
* <p>
|
||||
* To quantify the color characteristics of a device such as a printer
|
||||
* or monitor, measurements of XYZ values for particular device colors
|
||||
* are typically made. For purposes of this discussion, the term
|
||||
* device XYZ values is used to mean the XYZ values that would be
|
||||
* measured from device colors using current CIE recommended practices.
|
||||
* <p>
|
||||
* Converting between device XYZ values and the PCS XYZ values taken as
|
||||
* arguments by this method corresponds to converting between the device's
|
||||
* color space, as represented by CIE colorimetric values, and the PCS.
|
||||
* There are many factors involved in this process, some of which are quite
|
||||
* subtle. The most important, however, is the adjustment made to account
|
||||
* for differences between the device's white point and the white point of
|
||||
* the PCS. There are many techniques for doing this and it is the
|
||||
* subject of much current research and controversy. Some commonly used
|
||||
* methods are XYZ scaling, the von Kries transform, and the Bradford
|
||||
* transform. The proper method to use depends upon each particular
|
||||
* application.
|
||||
* <p>
|
||||
* The simplest method is XYZ scaling. In this method each device XYZ
|
||||
* value is converted to a PCS XYZ value by multiplying it by the ratio
|
||||
* of the PCS white point (D50) to the device white point.
|
||||
* <pre>
|
||||
*
|
||||
* Xd, Yd, Zd are the device XYZ values
|
||||
* Xdw, Ydw, Zdw are the device XYZ white point values
|
||||
* Xp, Yp, Zp are the PCS XYZ values
|
||||
* Xd50, Yd50, Zd50 are the PCS XYZ white point values
|
||||
*
|
||||
* Xp = Xd * (Xd50 / Xdw)
|
||||
* Yp = Yd * (Yd50 / Ydw)
|
||||
* Zp = Zd * (Zd50 / Zdw)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Conversion from the PCS to the device would be done by inverting these
|
||||
* equations:
|
||||
* <pre>
|
||||
*
|
||||
* Xd = Xp * (Xdw / Xd50)
|
||||
* Yd = Yp * (Ydw / Yd50)
|
||||
* Zd = Zp * (Zdw / Zd50)
|
||||
*
|
||||
* </pre>
|
||||
* <p>
|
||||
* Note that the media white point tag in an ICC profile is not the same
|
||||
* as the device white point. The media white point tag is expressed in
|
||||
* PCS values and is used to represent the difference between the XYZ of
|
||||
* device illuminant and the XYZ of the device media when measured under
|
||||
* that illuminant. The device white point is expressed as the device
|
||||
* XYZ values corresponding to white displayed on the device. For
|
||||
* example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
|
||||
* will result in a measured device XYZ value of D65. This will not
|
||||
* be the same as the media white point tag XYZ value in the ICC
|
||||
* profile for an sRGB device.
|
||||
* <p>
|
||||
* <p>
|
||||
* @param colorvalue a float array with length of at least 3.
|
||||
* @return a float array with length equal to the number of
|
||||
* components in this ColorSpace.
|
||||
* @throws ArrayIndexOutOfBoundsException if array length is not
|
||||
* at least 3.
|
||||
*/
|
||||
public float[] fromCIEXYZ(float[] colorvalue) {
|
||||
|
||||
if (xyz2this == null) {
|
||||
ColorTransform[] transformList = new ColorTransform [2];
|
||||
ICC_ColorSpace xyzCS =
|
||||
(ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
|
||||
PCMM mdl = CMSManager.getModule();
|
||||
transformList[0] = mdl.createTransform (
|
||||
xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
|
||||
try {
|
||||
transformList[1] = mdl.createTransform(
|
||||
thisProfile, ICC_Profile.icRelativeColorimetric,
|
||||
ColorTransform.Out);
|
||||
} catch (CMMException e) {
|
||||
transformList[1] = CMSManager.getModule().createTransform(
|
||||
thisProfile, ColorTransform.Any, ColorTransform.Out);
|
||||
}
|
||||
xyz2this = mdl.createTransform(transformList);
|
||||
if (needScaleInit) {
|
||||
setComponentScaling();
|
||||
}
|
||||
}
|
||||
|
||||
short tmp[] = new short[3];
|
||||
float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
|
||||
float factor = 65535.0f / ALMOST_TWO;
|
||||
// For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
|
||||
for (int i = 0; i < 3; i++) {
|
||||
tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
|
||||
}
|
||||
tmp = xyz2this.colorConvert(tmp, null);
|
||||
int nc = this.getNumComponents();
|
||||
float[] result = new float [nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
|
||||
diffMinMax[i] + minVal[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum normalized color component value for the
|
||||
* specified component. For TYPE_XYZ spaces, this method returns
|
||||
* minimum values of 0.0 for all components. For TYPE_Lab spaces,
|
||||
* this method returns 0.0 for L and -128.0 for a and b components.
|
||||
* This is consistent with the encoding of the XYZ and Lab Profile
|
||||
* Connection Spaces in the ICC specification. For all other types, this
|
||||
* method returns 0.0 for all components. When using an ICC_ColorSpace
|
||||
* with a profile that requires different minimum component values,
|
||||
* it is necessary to subclass this class and override this method.
|
||||
* @param component The component index.
|
||||
* @return The minimum normalized component value.
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1.
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMinValue(int component) {
|
||||
if ((component < 0) || (component > this.getNumComponents() - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: + component");
|
||||
}
|
||||
return minVal[component];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum normalized color component value for the
|
||||
* specified component. For TYPE_XYZ spaces, this method returns
|
||||
* maximum values of 1.0 + (32767.0 / 32768.0) for all components.
|
||||
* For TYPE_Lab spaces,
|
||||
* this method returns 100.0 for L and 127.0 for a and b components.
|
||||
* This is consistent with the encoding of the XYZ and Lab Profile
|
||||
* Connection Spaces in the ICC specification. For all other types, this
|
||||
* method returns 1.0 for all components. When using an ICC_ColorSpace
|
||||
* with a profile that requires different maximum component values,
|
||||
* it is necessary to subclass this class and override this method.
|
||||
* @param component The component index.
|
||||
* @return The maximum normalized component value.
|
||||
* @throws IllegalArgumentException if component is less than 0 or
|
||||
* greater than numComponents - 1.
|
||||
* @since 1.4
|
||||
*/
|
||||
public float getMaxValue(int component) {
|
||||
if ((component < 0) || (component > this.getNumComponents() - 1)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Component index out of range: + component");
|
||||
}
|
||||
return maxVal[component];
|
||||
}
|
||||
|
||||
private void setMinMax() {
|
||||
int nc = this.getNumComponents();
|
||||
int type = this.getType();
|
||||
minVal = new float[nc];
|
||||
maxVal = new float[nc];
|
||||
if (type == ColorSpace.TYPE_Lab) {
|
||||
minVal[0] = 0.0f; // L
|
||||
maxVal[0] = 100.0f;
|
||||
minVal[1] = -128.0f; // a
|
||||
maxVal[1] = 127.0f;
|
||||
minVal[2] = -128.0f; // b
|
||||
maxVal[2] = 127.0f;
|
||||
} else if (type == ColorSpace.TYPE_XYZ) {
|
||||
minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
|
||||
maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
|
||||
} else {
|
||||
for (int i = 0; i < nc; i++) {
|
||||
minVal[i] = 0.0f;
|
||||
maxVal[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setComponentScaling() {
|
||||
int nc = this.getNumComponents();
|
||||
diffMinMax = new float[nc];
|
||||
invDiffMinMax = new float[nc];
|
||||
for (int i = 0; i < nc; i++) {
|
||||
minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
|
||||
maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
|
||||
diffMinMax[i] = maxVal[i] - minVal[i];
|
||||
invDiffMinMax[i] = 65535.0f / diffMinMax[i];
|
||||
}
|
||||
needScaleInit = false;
|
||||
}
|
||||
|
||||
}
|
2003
jdk/src/share/classes/java/awt/color/ICC_Profile.java
Normal file
2003
jdk/src/share/classes/java/awt/color/ICC_Profile.java
Normal file
File diff suppressed because it is too large
Load Diff
150
jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
Normal file
150
jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import java.awt.image.LookupTable;
|
||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* A subclass of the ICC_Profile class which represents profiles
|
||||
* which meet the following criteria: the color space type of the
|
||||
* profile is TYPE_GRAY and the profile includes the grayTRCTag and
|
||||
* mediaWhitePointTag tags. Examples of this kind of profile are
|
||||
* monochrome input profiles, monochrome display profiles, and
|
||||
* monochrome output profiles. The getInstance methods in the
|
||||
* ICC_Profile class will
|
||||
* return an ICC_ProfileGray object when the above conditions are
|
||||
* met. The advantage of this class is that it provides a lookup
|
||||
* table that Java or native methods may be able to use directly to
|
||||
* optimize color conversion in some cases.
|
||||
* <p>
|
||||
* To transform from a GRAY device profile color space to the CIEXYZ Profile
|
||||
* Connection Space, the device gray component is transformed by
|
||||
* a lookup through the tone reproduction curve (TRC). The result is
|
||||
* treated as the achromatic component of the PCS.
|
||||
<pre>
|
||||
|
||||
PCSY = grayTRC[deviceGray]
|
||||
|
||||
</pre>
|
||||
* The inverse transform is done by converting the PCS Y components to
|
||||
* device Gray via the inverse of the grayTRC.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ProfileGray
|
||||
extends ICC_Profile {
|
||||
|
||||
static final long serialVersionUID = -1124721290732002649L;
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ProfileGray from a CMM ID.
|
||||
*/
|
||||
ICC_ProfileGray(long ID) {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object.
|
||||
*/
|
||||
ICC_ProfileGray(ProfileDeferralInfo pdi) {
|
||||
super(pdi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a float array of length 3 containing the X, Y, and Z
|
||||
* components of the mediaWhitePointTag in the ICC profile.
|
||||
* @return an array containing the components of the
|
||||
* mediaWhitePointTag in the ICC profile.
|
||||
*/
|
||||
public float[] getMediaWhitePoint() {
|
||||
return super.getMediaWhitePoint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a gamma value representing the tone reproduction
|
||||
* curve (TRC). If the profile represents the TRC as a table rather
|
||||
* than a single gamma value, then an exception is thrown. In this
|
||||
* case the actual table can be obtained via getTRC(). When
|
||||
* using a gamma value, the PCS Y component is computed as follows:
|
||||
<pre>
|
||||
|
||||
gamma
|
||||
PCSY = deviceGray
|
||||
|
||||
</pre>
|
||||
* @return the gamma value as a float.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the TRC as a single gamma value.
|
||||
*/
|
||||
public float getGamma() {
|
||||
float theGamma;
|
||||
|
||||
theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag);
|
||||
return theGamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TRC as an array of shorts. If the profile has
|
||||
* specified the TRC as linear (gamma = 1.0) or as a simple gamma
|
||||
* value, this method throws an exception, and the getGamma() method
|
||||
* should be used to get the gamma value. Otherwise the short array
|
||||
* returned here represents a lookup table where the input Gray value
|
||||
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
|
||||
* to array index 0 and value 1.0 maps to array index length-1.
|
||||
* Interpolation may be used to generate output values for
|
||||
* input values which do not map exactly to an index in the
|
||||
* array. Output values also map linearly to the range [0.0, 1.0].
|
||||
* Value 0.0 is represented by an array value of 0x0000 and
|
||||
* value 1.0 by 0xFFFF, i.e. the values are really unsigned
|
||||
* short values, although they are returned in a short array.
|
||||
* @return a short array representing the TRC.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the TRC as a table.
|
||||
*/
|
||||
public short[] getTRC() {
|
||||
short[] theTRC;
|
||||
|
||||
theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag);
|
||||
return theTRC;
|
||||
}
|
||||
|
||||
}
|
282
jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
Normal file
282
jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.color;
|
||||
|
||||
import java.awt.image.LookupTable;
|
||||
import sun.java2d.cmm.ProfileDeferralInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* The ICC_ProfileRGB class is a subclass of the ICC_Profile class
|
||||
* that represents profiles which meet the following criteria:
|
||||
* <ul>
|
||||
* <li>The profile's color space type is RGB.</li>
|
||||
* <li>The profile includes the <code>redColorantTag</code>,
|
||||
* <code>greenColorantTag</code>, <code>blueColorantTag</code>,
|
||||
* <code>redTRCTag</code>, <code>greenTRCTag</code>,
|
||||
* <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
|
||||
* </ul>
|
||||
* The <code>ICC_Profile</code> <code>getInstance</code> method will
|
||||
* return an <code>ICC_ProfileRGB</code> object when these conditions are met.
|
||||
* Three-component, matrix-based input profiles and RGB display profiles are
|
||||
* examples of this type of profile.
|
||||
* <p>
|
||||
* This profile class provides color transform matrices and lookup tables
|
||||
* that Java or native methods can use directly to
|
||||
* optimize color conversion in some cases.
|
||||
* <p>
|
||||
* To transform from a device profile color space to the CIEXYZ Profile
|
||||
* Connection Space, each device color component is first linearized by
|
||||
* a lookup through the corresponding tone reproduction curve (TRC).
|
||||
* The resulting linear RGB components are converted to the CIEXYZ PCS
|
||||
* using a a 3x3 matrix constructed from the RGB colorants.
|
||||
* <pre>
|
||||
*
|
||||
* linearR = redTRC[deviceR]
|
||||
*
|
||||
* linearG = greenTRC[deviceG]
|
||||
*
|
||||
* linearB = blueTRC[deviceB]
|
||||
*
|
||||
* _ _ _ _ _ _
|
||||
* [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
|
||||
* [ ] [ ] [ ]
|
||||
* [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
|
||||
* [ ] [ ] [ ]
|
||||
* [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
|
||||
*
|
||||
* </pre>
|
||||
* The inverse transform is performed by converting PCS XYZ components to linear
|
||||
* RGB components through the inverse of the above 3x3 matrix, and then converting
|
||||
* linear RGB to device RGB through inverses of the TRCs.
|
||||
* <p>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public class ICC_ProfileRGB
|
||||
extends ICC_Profile {
|
||||
|
||||
static final long serialVersionUID = 8505067385152579334L;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the red component.
|
||||
*/
|
||||
public static final int REDCOMPONENT = 0;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the green component.
|
||||
*/
|
||||
public static final int GREENCOMPONENT = 1;
|
||||
|
||||
/**
|
||||
* Used to get a gamma value or TRC for the blue component.
|
||||
*/
|
||||
public static final int BLUECOMPONENT = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
|
||||
*
|
||||
* @param ID The CMM ID for the profile.
|
||||
*
|
||||
*/
|
||||
ICC_ProfileRGB(long ID) {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>ICC_ProfileRGB</code> from a
|
||||
* ProfileDeferralInfo object.
|
||||
*
|
||||
* @param pdi
|
||||
*/
|
||||
ICC_ProfileRGB(ProfileDeferralInfo pdi) {
|
||||
super(pdi);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array that contains the components of the profile's
|
||||
* <CODE>mediaWhitePointTag</CODE>.
|
||||
*
|
||||
* @return A 3-element <CODE>float</CODE> array containing the x, y,
|
||||
* and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
|
||||
*/
|
||||
public float[] getMediaWhitePoint() {
|
||||
return super.getMediaWhitePoint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a 3x3 <CODE>float</CODE> matrix constructed from the
|
||||
* X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
|
||||
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
|
||||
* <p>
|
||||
* This matrix can be used for color transforms in the forward
|
||||
* direction of the profile--from the profile color space
|
||||
* to the CIEXYZ PCS.
|
||||
*
|
||||
* @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
|
||||
* components of the profile's <CODE>redColorantTag</CODE>,
|
||||
* <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
|
||||
*/
|
||||
public float[][] getMatrix() {
|
||||
float[][] theMatrix = new float[3][3];
|
||||
float[] tmpMatrix;
|
||||
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
|
||||
theMatrix[0][0] = tmpMatrix[0];
|
||||
theMatrix[1][0] = tmpMatrix[1];
|
||||
theMatrix[2][0] = tmpMatrix[2];
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
|
||||
theMatrix[0][1] = tmpMatrix[0];
|
||||
theMatrix[1][1] = tmpMatrix[1];
|
||||
theMatrix[2][1] = tmpMatrix[2];
|
||||
tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
|
||||
theMatrix[0][2] = tmpMatrix[0];
|
||||
theMatrix[1][2] = tmpMatrix[1];
|
||||
theMatrix[2][2] = tmpMatrix[2];
|
||||
return theMatrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a gamma value representing the tone reproduction curve
|
||||
* (TRC) for a particular component. The component parameter
|
||||
* must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
|
||||
* <p>
|
||||
* If the profile
|
||||
* represents the TRC for the corresponding component
|
||||
* as a table rather than a single gamma value, an
|
||||
* exception is thrown. In this case the actual table
|
||||
* can be obtained through the {@link #getTRC(int)} method.
|
||||
* When using a gamma value,
|
||||
* the linear component (R, G, or B) is computed as follows:
|
||||
* <pre>
|
||||
*
|
||||
* gamma
|
||||
* linearComponent = deviceComponent
|
||||
*
|
||||
*</pre>
|
||||
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
|
||||
* represents the component whose TRC you want to retrieve
|
||||
* @return the gamma value as a float.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the corresponding TRC as a single gamma value.
|
||||
*/
|
||||
public float getGamma(int component) {
|
||||
float theGamma;
|
||||
int theSignature;
|
||||
|
||||
switch (component) {
|
||||
case REDCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigRedTRCTag;
|
||||
break;
|
||||
|
||||
case GREENCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigGreenTRCTag;
|
||||
break;
|
||||
|
||||
case BLUECOMPONENT:
|
||||
theSignature = ICC_Profile.icSigBlueTRCTag;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Must be Red, Green, or Blue");
|
||||
}
|
||||
|
||||
theGamma = super.getGamma(theSignature);
|
||||
|
||||
return theGamma;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TRC for a particular component as an array.
|
||||
* Component must be <code>REDCOMPONENT</code>,
|
||||
* <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
|
||||
* Otherwise the returned array
|
||||
* represents a lookup table where the input component value
|
||||
* is conceptually in the range [0.0, 1.0]. Value 0.0 maps
|
||||
* to array index 0 and value 1.0 maps to array index length-1.
|
||||
* Interpolation might be used to generate output values for
|
||||
* input values that do not map exactly to an index in the
|
||||
* array. Output values also map linearly to the range [0.0, 1.0].
|
||||
* Value 0.0 is represented by an array value of 0x0000 and
|
||||
* value 1.0 by 0xFFFF. In other words, the values are really unsigned
|
||||
* <code>short</code> values even though they are returned in a
|
||||
* <code>short</code> array.
|
||||
*
|
||||
* If the profile has specified the corresponding TRC
|
||||
* as linear (gamma = 1.0) or as a simple gamma value, this method
|
||||
* throws an exception. In this case, the {@link #getGamma(int)}
|
||||
* method should be used to get the gamma value.
|
||||
*
|
||||
* @param component The <CODE>ICC_ProfileRGB</CODE> constant that
|
||||
* represents the component whose TRC you want to retrieve:
|
||||
* <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
|
||||
* <CODE>BLUECOMPONENT</CODE>.
|
||||
*
|
||||
* @return a short array representing the TRC.
|
||||
* @exception ProfileDataException if the profile does not specify
|
||||
* the corresponding TRC as a table.
|
||||
*/
|
||||
public short[] getTRC(int component) {
|
||||
short[] theTRC;
|
||||
int theSignature;
|
||||
|
||||
switch (component) {
|
||||
case REDCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigRedTRCTag;
|
||||
break;
|
||||
|
||||
case GREENCOMPONENT:
|
||||
theSignature = ICC_Profile.icSigGreenTRCTag;
|
||||
break;
|
||||
|
||||
case BLUECOMPONENT:
|
||||
theSignature = ICC_Profile.icSigBlueTRCTag;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Must be Red, Green, or Blue");
|
||||
}
|
||||
|
||||
theTRC = super.getTRC(theSignature);
|
||||
|
||||
return theTRC;
|
||||
}
|
||||
|
||||
}
|
839
jdk/src/share/classes/java/awt/image/BandedSampleModel.java
Normal file
839
jdk/src/share/classes/java/awt/image/BandedSampleModel.java
Normal file
@ -0,0 +1,839 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* This class represents image data which is stored in a band interleaved
|
||||
* fashion and for
|
||||
* which each sample of a pixel occupies one data element of the DataBuffer.
|
||||
* It subclasses ComponentSampleModel but provides a more efficent
|
||||
* implementation for accessing band interleaved image data than is provided
|
||||
* by ComponentSampleModel. This class should typically be used when working
|
||||
* with images which store sample data for each band in a different bank of the
|
||||
* DataBuffer. Accessor methods are provided so that image data can be
|
||||
* manipulated directly. Pixel stride is the number of
|
||||
* data array elements between two samples for the same band on the same
|
||||
* scanline. The pixel stride for a BandedSampleModel is one.
|
||||
* Scanline stride is the number of data array elements between
|
||||
* a given sample and the corresponding sample in the same column of the next
|
||||
* scanline. Band offsets denote the number
|
||||
* of data array elements from the first data array element of the bank
|
||||
* of the DataBuffer holding each band to the first sample of the band.
|
||||
* The bands are numbered from 0 to N-1.
|
||||
* Bank indices denote the correspondence between a bank of the data buffer
|
||||
* and a band of image data. This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT},
|
||||
* {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
|
||||
* {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
|
||||
*/
|
||||
|
||||
|
||||
public final class BandedSampleModel extends ComponentSampleModel
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The pixel stride will be one data element. The scanline stride
|
||||
* will be the same as the width. Each band will be stored in
|
||||
* a separate bank and all band offsets will be zero.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of image
|
||||
* data described.
|
||||
* @param numBands The number of bands for the image data.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType, int w, int h, int numBands) {
|
||||
super(dataType, w, h, 1, w,
|
||||
BandedSampleModel.createIndicesArray(numBands),
|
||||
BandedSampleModel.createOffsetArray(numBands));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a BandedSampleModel with the specified parameters.
|
||||
* The number of bands will be inferred from the lengths of the
|
||||
* bandOffsets bankIndices arrays, which must be equal. The pixel
|
||||
* stride will be one data element.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the of the image data.
|
||||
* @param bankIndices The bank index for each band.
|
||||
* @param bandOffsets The band offset for each band.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public BandedSampleModel(int dataType,
|
||||
int w, int h,
|
||||
int scanlineStride,
|
||||
int bankIndices[],
|
||||
int bandOffsets[]) {
|
||||
|
||||
super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with the specified
|
||||
* width and height. The new BandedSampleModel will have the same
|
||||
* number of bands, storage data type, and bank indices
|
||||
* as this BandedSampleModel. The band offsets will be compressed
|
||||
* such that the offset between bands will be w*pixelStride and
|
||||
* the minimum of all of the band offsets is zero.
|
||||
* @param w the width of the resulting <code>BandedSampleModel</code>
|
||||
* @param h the height of the resulting <code>BandedSampleModel</code>
|
||||
* @return a new <code>BandedSampleModel</code> with the specified
|
||||
* width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> equals either
|
||||
* <code>Integer.MAX_VALUE</code> or
|
||||
* <code>Integer.MIN_VALUE</code>
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
int[] bandOffs;
|
||||
|
||||
if (numBanks == 1) {
|
||||
bandOffs = orderBands(bandOffsets, w*h);
|
||||
}
|
||||
else {
|
||||
bandOffs = new int[bandOffsets.length];
|
||||
}
|
||||
|
||||
SampleModel sampleModel =
|
||||
new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new BandedSampleModel with a subset of the bands of this
|
||||
* BandedSampleModel. The new BandedSampleModel can be
|
||||
* used with any DataBuffer that the existing BandedSampleModel
|
||||
* can be used with. The new BandedSampleModel/DataBuffer
|
||||
* combination will represent an image with a subset of the bands
|
||||
* of the original BandedSampleModel/DataBuffer combination.
|
||||
* @throws RasterFormatException if the number of bands is greater than
|
||||
* the number of banks in this sample model.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported data types
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > bankIndices.length)
|
||||
throw new RasterFormatException("There are only " +
|
||||
bankIndices.length +
|
||||
" bands");
|
||||
int newBankIndices[] = new int[bands.length];
|
||||
int newBandOffsets[] = new int[bands.length];
|
||||
|
||||
for (int i=0; i<bands.length; i++) {
|
||||
newBankIndices[i] = bankIndices[bands[i]];
|
||||
newBandOffsets[i] = bandOffsets[bands[i]];
|
||||
}
|
||||
|
||||
return new BandedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride,
|
||||
newBankIndices, newBandOffsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this BandedSampleModel,
|
||||
* The DataBuffer's data type, number of banks, and size
|
||||
* will be consistent with this BandedSampleModel.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* one of the supported types.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = scanlineStride * height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
dataBuffer = new DataBufferShort(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
dataBuffer = new DataBufferFloat(size, numBanks);
|
||||
break;
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
dataBuffer = new DataBufferDouble(size, numBanks);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("dataType is not one " +
|
||||
"of the supported types.");
|
||||
}
|
||||
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a BandedSampleModel, this will be the same
|
||||
* as the data type, and samples will be returned one per array
|
||||
* element. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null) {
|
||||
bdata = new byte[numDataElems];
|
||||
} else {
|
||||
bdata = (byte[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
bdata[i] = (byte)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null) {
|
||||
sdata = new short[numDataElems];
|
||||
} else {
|
||||
sdata = (short[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
sdata[i] = (short)data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null) {
|
||||
idata = new int[numDataElems];
|
||||
} else {
|
||||
idata = (int[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
idata[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] fdata;
|
||||
|
||||
if (obj == null) {
|
||||
fdata = new float[numDataElems];
|
||||
} else {
|
||||
fdata = (float[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
fdata[i] = data.getElemFloat(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)fdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] ddata;
|
||||
|
||||
if (obj == null) {
|
||||
ddata = new double[numDataElems];
|
||||
} else {
|
||||
ddata = (double[])obj;
|
||||
}
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
ddata[i] = data.getElemDouble(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
|
||||
obj = (Object)ddata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = data.getElem(bankIndices[i],
|
||||
pixelOffset + bandOffsets[i]);
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples for the pixels within the specified region.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int[] pixels;
|
||||
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int[w*h*numBands];
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
pixels[srcOffset] = data.getElem(bank, pixelOffset++);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the sample in the specified band for the specified pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample =
|
||||
data.getElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for the pixel located at (x,y) as a float.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a float value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public float getSampleFloat(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
float sample = data.getElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sample in a specified band
|
||||
* for a pixel located at (x,y) as a double.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to return
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return a double value that represents the sample in the specified
|
||||
* band for the specified pixel.
|
||||
*/
|
||||
public double getSampleDouble(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
double sample = data.getElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b]);
|
||||
return sample;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples in a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to return
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @return the samples in the specified band for the pixels within
|
||||
* the specified region.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
samples[srcOffset++] = data.getElem(bank, sampleOffset++);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a BandedSampleModel,
|
||||
* this will be the same as the data type, and samples are transferred
|
||||
* one per array element.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* BandedSampleModel <code>bsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* BandedSampleModel bsm1, bsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
|
||||
* db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param obj If non-null, returns the primitive array in this
|
||||
* object
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int type = getTransferType();
|
||||
int numDataElems = getNumDataElements();
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
barray[i] & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
sarray[i] & 0xffff);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iarray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
|
||||
float[] farray = (float[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
farray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
|
||||
double[] darray = (double[])obj;
|
||||
|
||||
for (int i=0; i<numDataElems; i++) {
|
||||
data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
darray[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixelOffset = y*scanlineStride + x;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
|
||||
iArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param iArray The input samples in an int array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
for (int k = 0; k < numBands; k++) {
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[k];
|
||||
int srcOffset = k;
|
||||
int bank = bankIndices[k];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int pixelOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, pixelOffset++, iArray[srcOffset]);
|
||||
srcOffset += numBands;
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as an int
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElem(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a float
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
float s ,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemFloat(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location
|
||||
* @param y The Y coordinate of the pixel location
|
||||
* @param b The band to set
|
||||
* @param s The input sample as a double
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b,
|
||||
double s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
data.setElemDouble(bankIndices[b],
|
||||
y*scanlineStride + x + bandOffsets[b], s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per data array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location
|
||||
* @param y The Y coordinate of the upper left pixel location
|
||||
* @param w The width of the pixel rectangle
|
||||
* @param h The height of the pixel rectangle
|
||||
* @param b The band to set
|
||||
* @param iArray The input sample array
|
||||
* @param data The DataBuffer containing the image data
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x + bandOffsets[b];
|
||||
int srcOffset = 0;
|
||||
int bank = bankIndices[b];
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
int sampleOffset = lineOffset;
|
||||
for (int j = 0; j < w; j++) {
|
||||
data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] createOffsetArray(int numBands) {
|
||||
int[] bandOffsets = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bandOffsets[i] = 0;
|
||||
}
|
||||
return bandOffsets;
|
||||
}
|
||||
|
||||
private static int[] createIndicesArray(int numBands) {
|
||||
int[] bankIndices = new int[numBands];
|
||||
for (int i=0; i < numBands; i++) {
|
||||
bankIndices[i] = i;
|
||||
}
|
||||
return bankIndices;
|
||||
}
|
||||
|
||||
// Differentiate hash code from other ComponentSampleModel subclasses
|
||||
public int hashCode() {
|
||||
return super.hashCode() ^ 0x2;
|
||||
}
|
||||
}
|
1109
jdk/src/share/classes/java/awt/image/ColorConvertOp.java
Normal file
1109
jdk/src/share/classes/java/awt/image/ColorConvertOp.java
Normal file
File diff suppressed because it is too large
Load Diff
1202
jdk/src/share/classes/java/awt/image/ComponentSampleModel.java
Normal file
1202
jdk/src/share/classes/java/awt/image/ComponentSampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
535
jdk/src/share/classes/java/awt/image/DataBuffer.java
Normal file
535
jdk/src/share/classes/java/awt/image/DataBuffer.java
Normal file
@ -0,0 +1,535 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import sun.java2d.StateTrackable.State;
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
import sun.java2d.StateTrackableDelegate;
|
||||
|
||||
import sun.awt.image.SunWritableRaster;
|
||||
|
||||
/**
|
||||
* This class exists to wrap one or more data arrays. Each data array in
|
||||
* the DataBuffer is referred to as a bank. Accessor methods for getting
|
||||
* and setting elements of the DataBuffer's banks exist with and without
|
||||
* a bank specifier. The methods without a bank specifier use the default 0th
|
||||
* bank. The DataBuffer can optionally take an offset per bank, so that
|
||||
* data in an existing array can be used even if the interesting data
|
||||
* doesn't start at array location zero. Getting or setting the 0th
|
||||
* element of a bank, uses the (0+offset)th element of the array. The
|
||||
* size field specifies how much of the data array is available for
|
||||
* use. Size + offset for a given bank should never be greater
|
||||
* than the length of the associated data array. The data type of
|
||||
* a data buffer indicates the type of the data array(s) and may also
|
||||
* indicate additional semantics, e.g. storing unsigned 8-bit data
|
||||
* in elements of a byte array. The data type may be TYPE_UNDEFINED
|
||||
* or one of the types defined below. Other types may be added in
|
||||
* the future. Generally, an object of class DataBuffer will be cast down
|
||||
* to one of its data type specific subclasses to access data type specific
|
||||
* methods for improved performance. Currently, the Java 2D(tm) API
|
||||
* image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
|
||||
* TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
|
||||
* @see java.awt.image.Raster
|
||||
* @see java.awt.image.SampleModel
|
||||
*/
|
||||
public abstract class DataBuffer {
|
||||
|
||||
/** Tag for unsigned byte data. */
|
||||
public static final int TYPE_BYTE = 0;
|
||||
|
||||
/** Tag for unsigned short data. */
|
||||
public static final int TYPE_USHORT = 1;
|
||||
|
||||
/** Tag for signed short data. Placeholder for future use. */
|
||||
public static final int TYPE_SHORT = 2;
|
||||
|
||||
/** Tag for int data. */
|
||||
public static final int TYPE_INT = 3;
|
||||
|
||||
/** Tag for float data. Placeholder for future use. */
|
||||
public static final int TYPE_FLOAT = 4;
|
||||
|
||||
/** Tag for double data. Placeholder for future use. */
|
||||
public static final int TYPE_DOUBLE = 5;
|
||||
|
||||
/** Tag for undefined data. */
|
||||
public static final int TYPE_UNDEFINED = 32;
|
||||
|
||||
/** The data type of this DataBuffer. */
|
||||
protected int dataType;
|
||||
|
||||
/** The number of banks in this DataBuffer. */
|
||||
protected int banks;
|
||||
|
||||
/** Offset into default (first) bank from which to get the first element. */
|
||||
protected int offset;
|
||||
|
||||
/** Usable size of all banks. */
|
||||
protected int size;
|
||||
|
||||
/** Offsets into all banks. */
|
||||
protected int offsets[];
|
||||
|
||||
/* The current StateTrackable state. */
|
||||
StateTrackableDelegate theTrackable;
|
||||
|
||||
/** Size of the data types indexed by DataType tags defined above. */
|
||||
private static final int dataTypeSize[] = {8,16,16,32,32,64};
|
||||
|
||||
/** Returns the size (in bits) of the data type, given a datatype tag.
|
||||
* @param type the value of one of the defined datatype tags
|
||||
* @return the size of the data type
|
||||
* @throws IllegalArgumentException if <code>type</code> is less than
|
||||
* zero or greater than {@link #TYPE_DOUBLE}
|
||||
*/
|
||||
public static int getDataTypeSize(int type) {
|
||||
if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
|
||||
throw new IllegalArgumentException("Unknown data type "+type);
|
||||
}
|
||||
return dataTypeSize[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size) {
|
||||
this(UNTRACKABLE, dataType, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing one bank of the specified
|
||||
* data type and size with the indicated initial {@link State State}.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = 1;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[1]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks. Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer containing the specified number of
|
||||
* banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified size and an offset of 0.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = 0;
|
||||
this.offsets = new int[banks]; // init to 0 by new
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks. Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offset) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer that contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype, size and offset.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offset the offset for each bank
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offset)
|
||||
{
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offset;
|
||||
this.offsets = new int[numBanks];
|
||||
for (int i = 0; i < numBanks; i++) {
|
||||
this.offsets[i] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks. Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
*/
|
||||
protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
|
||||
this(UNTRACKABLE, dataType, size, numBanks, offsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a DataBuffer which contains the specified number
|
||||
* of banks with the indicated initial {@link State State}.
|
||||
* Each bank has the specified datatype and size. The
|
||||
* offset for each bank is specified by its respective entry in
|
||||
* the offsets array.
|
||||
*
|
||||
* @param initialState the initial {@link State State} state of the data
|
||||
* @param dataType the data type of this <code>DataBuffer</code>
|
||||
* @param size the size of the banks
|
||||
* @param numBanks the number of banks in this
|
||||
* <code>DataBuffer</code>
|
||||
* @param offsets an array containing an offset for each bank.
|
||||
* @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
|
||||
* does not equal the length of <code>offsets</code>
|
||||
* @since 1.7
|
||||
*/
|
||||
DataBuffer(State initialState,
|
||||
int dataType, int size, int numBanks, int offsets[])
|
||||
{
|
||||
if (numBanks != offsets.length) {
|
||||
throw new ArrayIndexOutOfBoundsException("Number of banks" +
|
||||
" does not match number of bank offsets");
|
||||
}
|
||||
this.theTrackable = StateTrackableDelegate.createInstance(initialState);
|
||||
this.dataType = dataType;
|
||||
this.banks = numBanks;
|
||||
this.size = size;
|
||||
this.offset = offsets[0];
|
||||
this.offsets = (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the data type of this DataBuffer.
|
||||
* @return the data type of this <code>DataBuffer</code>.
|
||||
*/
|
||||
public int getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
/** Returns the size (in array elements) of all banks.
|
||||
* @return the size of all banks.
|
||||
*/
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/** Returns the offset of the default bank in array elements.
|
||||
* @return the offset of the default bank.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the offsets (in array elements) of all the banks.
|
||||
* @return the offsets of all banks.
|
||||
*/
|
||||
public int[] getOffsets() {
|
||||
return (int[])offsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the number of banks in this DataBuffer.
|
||||
* @return the number of banks.
|
||||
*/
|
||||
public int getNumBanks() {
|
||||
return banks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as an integer.
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return getElem(0,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as an integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return the data array element at the specified index from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public abstract int getElem(int bank, int i);
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given integer.
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
setElem(0,i,val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index into the data array
|
||||
* @param val the data to set the element in the specified bank
|
||||
* at the specified index in the data array
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public abstract void setElem(int bank, int i, int val);
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a float. The implementation in this class is to cast getElem(i)
|
||||
* to a float. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element at the
|
||||
* specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int i) {
|
||||
return (float)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank
|
||||
* as a float. The implementation in this class is to cast
|
||||
* {@link #getElem(int, int)}
|
||||
* to a float. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the index of the requested data array element
|
||||
* @return a float value representing the data array element from the
|
||||
* specified bank at the specified index.
|
||||
* @see #setElemFloat(int, float)
|
||||
* @see #setElemFloat(int, int, float)
|
||||
*/
|
||||
public float getElemFloat(int bank, int i) {
|
||||
return (float)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses
|
||||
* can override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index in
|
||||
* the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int i, float val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given float. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank at
|
||||
* the specified index in the data array
|
||||
* @see #getElemFloat(int)
|
||||
* @see #getElemFloat(int, int)
|
||||
*/
|
||||
public void setElemFloat(int bank, int i, float val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank
|
||||
* as a double. The implementation in this class is to cast
|
||||
* {@link #getElem(int)}
|
||||
* to a double. Subclasses can override this method if another
|
||||
* implementation is needed.
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element at the specified
|
||||
* index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int i) {
|
||||
return (double)getElem(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank as
|
||||
* a double. The implementation in this class is to cast getElem(bank, i)
|
||||
* to a double. Subclasses may override this method if another
|
||||
* implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @return a double value representing the element from the specified
|
||||
* bank at the specified index in the data array.
|
||||
* @see #setElemDouble(int, double)
|
||||
* @see #setElemDouble(int, int, double)
|
||||
*/
|
||||
public double getElemDouble(int bank, int i) {
|
||||
return (double)getElem(bank,i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element at the specified index
|
||||
* in the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int i, double val) {
|
||||
setElem(i,(int)val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given double. The implementation in this class is to cast
|
||||
* val to an int and call {@link #setElem(int, int)}. Subclasses can
|
||||
* override this method if another implementation is needed.
|
||||
* @param bank the specified bank
|
||||
* @param i the specified index
|
||||
* @param val the value to set the element in the specified bank
|
||||
* at the specified index of the data array
|
||||
* @see #getElemDouble(int)
|
||||
* @see #getElemDouble(int, int)
|
||||
*/
|
||||
public void setElemDouble(int bank, int i, double val) {
|
||||
setElem(bank,i,(int)val);
|
||||
}
|
||||
|
||||
static int[] toIntArray(Object obj) {
|
||||
if (obj instanceof int[]) {
|
||||
return (int[])obj;
|
||||
} else if (obj == null) {
|
||||
return null;
|
||||
} else if (obj instanceof short[]) {
|
||||
short sdata[] = (short[])obj;
|
||||
int idata[] = new int[sdata.length];
|
||||
for (int i = 0; i < sdata.length; i++) {
|
||||
idata[i] = (int)sdata[i] & 0xffff;
|
||||
}
|
||||
return idata;
|
||||
} else if (obj instanceof byte[]) {
|
||||
byte bdata[] = (byte[])obj;
|
||||
int idata[] = new int[bdata.length];
|
||||
for (int i = 0; i < bdata.length; i++) {
|
||||
idata[i] = 0xff & (int)bdata[i];
|
||||
}
|
||||
return idata;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static {
|
||||
SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
|
||||
public byte[] getData(DataBufferByte dbb, int bank) {
|
||||
return dbb.bankdata[bank];
|
||||
}
|
||||
|
||||
public short[] getData(DataBufferUShort dbus, int bank) {
|
||||
return dbus.bankdata[bank];
|
||||
}
|
||||
|
||||
public int[] getData(DataBufferInt dbi, int bank) {
|
||||
return dbi.bankdata[bank];
|
||||
}
|
||||
|
||||
public StateTrackableDelegate getTrackable(DataBuffer db) {
|
||||
return db.theTrackable;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
286
jdk/src/share/classes/java/awt/image/DataBufferByte.java
Normal file
286
jdk/src/share/classes/java/awt/image/DataBufferByte.java
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
|
||||
* Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
|
||||
* unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array, as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferByte extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
byte data[];
|
||||
|
||||
/** All data banks */
|
||||
byte bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size) {
|
||||
super(STABLE, TYPE_BYTE, size);
|
||||
data = new byte[size];
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(int size, int numBanks) {
|
||||
super(STABLE, TYPE_BYTE, size, numBanks);
|
||||
bankdata = new byte[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new byte[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
|
||||
* must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[], int size, int offset){
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new byte[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
|
||||
* There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
|
||||
* entry. For each bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
|
||||
* <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
|
||||
bankdata = (byte[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first byte data array.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public byte[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public byte[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (byte[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (byte)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
284
jdk/src/share/classes/java/awt/image/DataBufferInt.java
Normal file
284
jdk/src/share/classes/java/awt/image/DataBufferInt.java
Normal file
@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally
|
||||
* as integers.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferInt extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
int data[];
|
||||
|
||||
/** All data banks */
|
||||
int bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
|
||||
* and the specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size) {
|
||||
super(STABLE, TYPE_INT, size);
|
||||
data = new int[size];
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int size, int numBanks) {
|
||||
super(STABLE, TYPE_INT, size, numBanks);
|
||||
bankdata = new int[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new int[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new int[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferInt(int dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
|
||||
bankdata = (int [][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first integer data array.
|
||||
*/
|
||||
public int[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public int[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public int[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (int [][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return data[i+offset];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return bankdata[bank][i+offsets[bank]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* to the integer value <CODE>i</CODE>.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (int)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
283
jdk/src/share/classes/java/awt/image/DataBufferShort.java
Normal file
283
jdk/src/share/classes/java/awt/image/DataBufferShort.java
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size) {
|
||||
super(STABLE, TYPE_SHORT,size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_SHORT,size,numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
|
||||
* specified array, size, and offset. <CODE>dataArray</CODE> must have at least
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
|
||||
* through <CODE>offset</CODE> + <CODE>size</CODE> - 1
|
||||
* should be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
|
||||
* and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) byte data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)val;
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
318
jdk/src/share/classes/java/awt/image/DataBufferUShort.java
Normal file
318
jdk/src/share/classes/java/awt/image/DataBufferUShort.java
Normal file
@ -0,0 +1,318 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import static sun.java2d.StateTrackable.State.*;
|
||||
|
||||
/**
|
||||
* This class extends <CODE>DataBuffer</CODE> and stores data internally as
|
||||
* shorts. Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
|
||||
* are treated as unsigned values.
|
||||
* <p>
|
||||
* <a name="optimizations">
|
||||
* Note that some implementations may function more efficiently
|
||||
* if they can maintain control over how the data for an image is
|
||||
* stored.
|
||||
* For example, optimizations such as caching an image in video
|
||||
* memory require that the implementation track all modifications
|
||||
* to that data.
|
||||
* Other implementations may operate better if they can store the
|
||||
* data in locations other than a Java array.
|
||||
* To maintain optimum compatibility with various optimizations
|
||||
* it is best to avoid constructors and methods which expose the
|
||||
* underlying storage as a Java array as noted below in the
|
||||
* documentation for those methods.
|
||||
* </a>
|
||||
*/
|
||||
public final class DataBufferUShort extends DataBuffer
|
||||
{
|
||||
/** The default data bank. */
|
||||
short data[];
|
||||
|
||||
/** All data banks */
|
||||
short bankdata[][];
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
|
||||
* specified size.
|
||||
*
|
||||
* @param size The size of the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size) {
|
||||
super(STABLE, TYPE_USHORT, size);
|
||||
data = new short[size];
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
|
||||
* banks, all of which are the specified size.
|
||||
*
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(int size, int numBanks) {
|
||||
super(STABLE, TYPE_USHORT, size, numBanks);
|
||||
bankdata = new short[numBanks][];
|
||||
for (int i= 0; i < numBanks; i++) {
|
||||
bankdata[i] = new short[size];
|
||||
}
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array.
|
||||
* Only the first <CODE>size</CODE> elements should be used by accessors of
|
||||
* this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
|
||||
* hold <CODE>size</CODE> elements.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
|
||||
* using the specified array, size, and offset. <CODE>dataArray</CODE> must have at
|
||||
* least <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements
|
||||
* <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
|
||||
* be used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the <CODE>DataBuffer</CODE> bank.
|
||||
* @param offset The offset into the <CODE>dataArray</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[], int size, int offset) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
if ((size+offset) > dataArray.length) {
|
||||
throw new IllegalArgumentException("Length of dataArray is less "+
|
||||
" than size+offset.");
|
||||
}
|
||||
data = dataArray;
|
||||
bankdata = new short[1][];
|
||||
bankdata[0] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
|
||||
* The number of banks will be equal to <CODE>dataArray.length</CODE>.
|
||||
* Only the first <CODE>size</CODE> elements of each array should be used by
|
||||
* accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
}
|
||||
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
|
||||
* size, and offsets.
|
||||
* The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
|
||||
* be at least as large as <CODE>size</CODE> + the corresponding offset. There must
|
||||
* be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
|
||||
* bank, only elements <CODE>offset</CODE> through
|
||||
* <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
|
||||
* used by accessors of this <CODE>DataBuffer</CODE>.
|
||||
* <p>
|
||||
* Note that {@code DataBuffer} objects created by this constructor
|
||||
* may be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
|
||||
* @param size The size of the banks in the <CODE>DataBuffer</CODE>.
|
||||
* @param offsets The offsets into each array.
|
||||
*/
|
||||
public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
|
||||
super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
|
||||
if (dataArray == null) {
|
||||
throw new NullPointerException("dataArray is null");
|
||||
}
|
||||
for (int i=0; i < dataArray.length; i++) {
|
||||
if (dataArray[i] == null) {
|
||||
throw new NullPointerException("dataArray["+i+"] is null");
|
||||
}
|
||||
if ((size+offsets[i]) > dataArray[i].length) {
|
||||
throw new IllegalArgumentException("Length of dataArray["+i+
|
||||
"] is less than size+"+
|
||||
"offsets["+i+"].");
|
||||
}
|
||||
|
||||
}
|
||||
bankdata = (short[][]) dataArray.clone();
|
||||
data = bankdata[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default (first) unsigned-short data array.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return The first unsigned-short data array.
|
||||
*/
|
||||
public short[] getData() {
|
||||
theTrackable.setUntrackable();
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data array for the specified bank.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @param bank The bank whose data array you want to get.
|
||||
* @return The data array for the specified bank.
|
||||
*/
|
||||
public short[] getData(int bank) {
|
||||
theTrackable.setUntrackable();
|
||||
return bankdata[bank];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data arrays for all banks.
|
||||
* <p>
|
||||
* Note that calling this method may cause this {@code DataBuffer}
|
||||
* object to be incompatible with <a href="#optimizations">performance
|
||||
* optimizations</a> used by some implementations (such as caching
|
||||
* an associated image in video memory).
|
||||
*
|
||||
* @return All of the data arrays.
|
||||
*/
|
||||
public short[][] getBankData() {
|
||||
theTrackable.setUntrackable();
|
||||
return (short[][]) bankdata.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the first (default) bank.
|
||||
*
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int i) {
|
||||
return (int)(data[i+offset]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the requested data array element from the specified bank.
|
||||
*
|
||||
* @param bank The bank from which you want to get a data array element.
|
||||
* @param i The data array element you want to get.
|
||||
* @return The requested data array element as an integer.
|
||||
* @see #setElem(int, int)
|
||||
* @see #setElem(int, int, int)
|
||||
*/
|
||||
public int getElem(int bank, int i) {
|
||||
return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the first (default) bank
|
||||
* to the specified value.
|
||||
*
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int i, int val) {
|
||||
data[i+offset] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the requested data array element in the specified bank
|
||||
* from the given integer.
|
||||
* @param bank The bank in which you want to set the data array element.
|
||||
* @param i The data array element you want to set.
|
||||
* @param val The integer value to which you want to set the specified data array element.
|
||||
* @see #getElem(int)
|
||||
* @see #getElem(int, int)
|
||||
*/
|
||||
public void setElem(int bank, int i, int val) {
|
||||
bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
|
||||
theTrackable.markDirty();
|
||||
}
|
||||
}
|
@ -0,0 +1,699 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2006 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
/**
|
||||
* The <code>MultiPixelPackedSampleModel</code> class represents
|
||||
* one-banded images and can pack multiple one-sample
|
||||
* pixels into one data element. Pixels are not allowed to span data elements.
|
||||
* The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
|
||||
* and a power of 2 number of pixels must fit exactly in one data element.
|
||||
* Pixel bit stride is equal to the number of bits per pixel. Scanline
|
||||
* stride is in data elements and the last several data elements might be
|
||||
* padded with unused pixels. Data bit offset is the offset in bits from
|
||||
* the beginning of the {@link DataBuffer} to the first pixel and must be
|
||||
* a multiple of pixel bit stride.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits for pixel
|
||||
* <code>x, y</code> from <code>DataBuffer</code> <code>data</code>
|
||||
* and storing the pixel data in data elements of type
|
||||
* <code>dataType</code>:
|
||||
* <pre>
|
||||
* int dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
* int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
* int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
* int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
* - pixelBitStride;
|
||||
* int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class MultiPixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** The number of bits from one pixel to the next. */
|
||||
int pixelBitStride;
|
||||
|
||||
/** Bitmask that extracts the rightmost pixel of a data element. */
|
||||
int bitMask;
|
||||
|
||||
/**
|
||||
* The number of pixels that fit in a data element. Also used
|
||||
* as the number of bits per pixel.
|
||||
*/
|
||||
int pixelsPerDataElement;
|
||||
|
||||
/** The size of a data element in bits. */
|
||||
int dataElementSize;
|
||||
|
||||
/** The bit offset into the data array where the first pixel begins.
|
||||
*/
|
||||
int dataBitOffset;
|
||||
|
||||
/** ScanlineStride of the data buffer described in data array elements. */
|
||||
int scanlineStride;
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified data type, width, height and number of bits per pixel.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType,
|
||||
int w,
|
||||
int h,
|
||||
int numberOfBits) {
|
||||
this(dataType,w,h,
|
||||
numberOfBits,
|
||||
(w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
|
||||
DataBuffer.getDataTypeSize(dataType),
|
||||
0);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a <code>MultiPixelPackedSampleModel</code> with
|
||||
* specified data type, width, height, number of bits per pixel,
|
||||
* scanline stride and data bit offset.
|
||||
* @param dataType the data type for storing samples
|
||||
* @param w the width, in pixels, of the region of
|
||||
* image data described
|
||||
* @param h the height, in pixels, of the region of
|
||||
* image data described
|
||||
* @param numberOfBits the number of bits per pixel
|
||||
* @param scanlineStride the line stride of the image data
|
||||
* @param dataBitOffset the data bit offset for the region of image
|
||||
* data described
|
||||
* @exception RasterFormatException if the number of bits per pixel
|
||||
* is not a power of 2 or if a power of 2 number of
|
||||
* pixels do not fit in one data element.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public MultiPixelPackedSampleModel(int dataType, int w, int h,
|
||||
int numberOfBits,
|
||||
int scanlineStride,
|
||||
int dataBitOffset) {
|
||||
super(dataType, w, h, 1);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.pixelBitStride = numberOfBits;
|
||||
this.scanlineStride = scanlineStride;
|
||||
this.dataBitOffset = dataBitOffset;
|
||||
this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
|
||||
this.pixelsPerDataElement = dataElementSize/numberOfBits;
|
||||
if (pixelsPerDataElement*numberOfBits != dataElementSize) {
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel " +
|
||||
"does not allow pixels to " +
|
||||
"span data element boundaries");
|
||||
}
|
||||
this.bitMask = (1 << numberOfBits) - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with the
|
||||
* specified width and height. The new
|
||||
* <code>MultiPixelPackedSampleModel</code> has the
|
||||
* same storage data type and number of bits per pixel as this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
* @param w the specified width
|
||||
* @param h the specified height
|
||||
* @return a {@link SampleModel} with the specified width and height
|
||||
* and with the same storage data type and number of bits per pixel
|
||||
* as this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel =
|
||||
new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>DataBuffer</code> that corresponds to this
|
||||
* <code>MultiPixelPackedSampleModel</code>. The
|
||||
* <code>DataBuffer</code> object's data type and size
|
||||
* is consistent with this <code>MultiPixelPackedSampleModel</code>.
|
||||
* The <code>DataBuffer</code> has a single bank.
|
||||
* @return a <code>DataBuffer</code> with the same data type and
|
||||
* size as this <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)scanlineStride*height;
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the {@link #getDataElements} and {@link #setDataElements}
|
||||
* methods. For a <code>MultiPixelPackedSampleModel</code>, this is
|
||||
* one.
|
||||
* @return the number of data elements.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for all bands.
|
||||
* @return the number of bits per sample.
|
||||
*/
|
||||
public int[] getSampleSize() {
|
||||
int sampleSize[] = {pixelBitStride};
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits per sample for the specified band.
|
||||
* @param band the specified band
|
||||
* @return the number of bits per sample for the specified band.
|
||||
*/
|
||||
public int getSampleSize(int band) {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of pixel (x, y) in data array elements.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride;
|
||||
offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset, in bits, into the data element in which it is
|
||||
* stored for the <code>x</code>th pixel of a scanline.
|
||||
* This offset is the same for all scanlines.
|
||||
* @param x the specified pixel
|
||||
* @return the bit offset of the specified pixel.
|
||||
*/
|
||||
public int getBitOffset(int x){
|
||||
return (x*pixelBitStride+dataBitOffset)%dataElementSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scanline stride.
|
||||
* @return the scanline stride of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pixel bit stride in bits. This value is the same as
|
||||
* the number of bits per pixel.
|
||||
* @return the <code>pixelBitStride</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getPixelBitStride() {
|
||||
return pixelBitStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data bit offset in bits.
|
||||
* @return the <code>dataBitOffset</code> of this
|
||||
* <code>MultiPixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getDataBitOffset() {
|
||||
return dataBitOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the TransferType used to transfer pixels by way of the
|
||||
* <code>getDataElements</code> and <code>setDataElements</code>
|
||||
* methods. The TransferType might or might not be the same as the
|
||||
* storage DataType. The TransferType is one of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
|
||||
* or DataBuffer.TYPE_INT.
|
||||
* @return the transfertype.
|
||||
*/
|
||||
public int getTransferType() {
|
||||
if (pixelBitStride > 16)
|
||||
return DataBuffer.TYPE_INT;
|
||||
else if (pixelBitStride > 8)
|
||||
return DataBuffer.TYPE_USHORT;
|
||||
else
|
||||
return DataBuffer.TYPE_BYTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>MultiPixelPackedSampleModel</code> with a
|
||||
* subset of the bands of this
|
||||
* <code>MultiPixelPackedSampleModel</code>. Since a
|
||||
* <code>MultiPixelPackedSampleModel</code> only has one band, the
|
||||
* bands argument must have a length of one and indicate the zeroth
|
||||
* band.
|
||||
* @param bands the specified bands
|
||||
* @return a new <code>SampleModel</code> with a subset of bands of
|
||||
* this <code>MultiPixelPackedSampleModel</code>.
|
||||
* @exception RasterFormatException if the number of bands requested
|
||||
* is not one.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands != null) {
|
||||
if (bands.length != 1)
|
||||
throw new RasterFormatException("MultiPixelPackedSampleModel has "
|
||||
+ "only one band.");
|
||||
}
|
||||
SampleModel sm = createCompatibleSampleModel(width, height);
|
||||
return sm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as <code>int</code> the sample in a specified band for the
|
||||
* pixel located at (x, y). An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param data the <code>DataBuffer</code> containing the image
|
||||
* data
|
||||
* @return the specified band containing the sample of the specified
|
||||
* pixel.
|
||||
* @exception ArrayIndexOutOfBoundException if the specified
|
||||
* coordinates are not in bounds.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
return (element >> shift) & bitMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at
|
||||
* (x, y) in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> for input.
|
||||
* An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param b the band to return, which is assumed to be 0
|
||||
* @param s the input sample as an <code>int</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// 'b' must be 0
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
|
||||
(b != 0)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (s & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* the array has one element, and the type is the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel. Generally, <code>obj</code>
|
||||
* should be passed in as <code>null</code>, so that the
|
||||
* <code>Object</code> is created automatically and is the
|
||||
* correct primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code>
|
||||
* to transfer between two <code>DataBuffer/SampleModel</code> pairs
|
||||
* is legitimate if the <code>SampleModels</code> have the same number
|
||||
* of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If <code>obj</code> is not <code>null</code>, it should be a
|
||||
* primitive array of type TransferType. Otherwise, a
|
||||
* <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not
|
||||
* <code>null</code> and is not large enough to hold the pixel data.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param obj a primitive array in which to return the pixel data or
|
||||
* <code>null</code>.
|
||||
* @param data the <code>DataBuffer</code> containing the image data.
|
||||
* @return an <code>Object</code> containing data for the specified
|
||||
* pixel.
|
||||
* @exception ClassCastException if <code>obj</code> is not a
|
||||
* primitive array of type TransferType or is not <code>null</code>
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates are
|
||||
* not in bounds, or if <code>obj</code> is not <code>null</code> or
|
||||
* not large enough to hold the pixel data
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = 0;
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
bdata[0] = (byte)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
sdata[0] = (short)((element >> shift) & bitMask);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
element = data.getElem(y*scanlineStride +
|
||||
bitnum/dataElementSize);
|
||||
idata[0] = (element >> shift) & bitMask;
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the specified single band pixel in the first element
|
||||
* of an <code>int</code> array.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds.
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @param iArray the array containing the pixel to be returned or
|
||||
* <code>null</code>
|
||||
* @param data the <code>DataBuffer</code> where image data is stored
|
||||
* @return an array containing the specified pixel.
|
||||
* @exception ArrayIndexOutOfBoundsException if the coordinates
|
||||
* are not in bounds
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [numBands];
|
||||
}
|
||||
int bitnum = dataBitOffset + x*pixelBitStride;
|
||||
int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
pixels[0] = (element >> shift) & bitMask;
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified
|
||||
* <code>DataBuffer</code> from a primitive array of type
|
||||
* TransferType. For a <code>MultiPixelPackedSampleModel</code>,
|
||||
* only the first element of the array holds valid data,
|
||||
* and the type must be the smallest of
|
||||
* DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
|
||||
* that can hold a single pixel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* <code>DataBuffer</code> <code>db1</code>, whose storage layout is
|
||||
* described by <code>MultiPixelPackedSampleModel</code>
|
||||
* <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
|
||||
* whose storage layout is described by
|
||||
* <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
|
||||
* The transfer is generally more efficient than using
|
||||
* <code>getPixel</code> or <code>setPixel</code>.
|
||||
* <pre>
|
||||
* MultiPixelPackedSampleModel mppsm1, mppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using <code>getDataElements</code> or <code>setDataElements</code> to
|
||||
* transfer between two <code>DataBuffer/SampleModel</code> pairs is
|
||||
* legitimate if the <code>SampleModel</code> objects have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* <code>obj</code> must be a primitive array of type TransferType.
|
||||
* Otherwise, a <code>ClassCastException</code> is thrown. An
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if the
|
||||
* coordinates are not in bounds, or if <code>obj</code> is not large
|
||||
* enough to hold the pixel data.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param obj a primitive array containing pixel data
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
element |= (iarray[0] & bitMask) << shift;
|
||||
data.setElem(index, element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the <code>DataBuffer</code> using an
|
||||
* <code>int</code> array for input.
|
||||
* <code>ArrayIndexOutOfBoundsException</code> is thrown if
|
||||
* the coordinates are not in bounds.
|
||||
* @param x the X coordinate of the pixel location
|
||||
* @param y the Y coordinate of the pixel location
|
||||
* @param iArray the input pixel in an <code>int</code> array
|
||||
* @param data the <code>DataBuffer</code> containing the image data
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int bitnum = dataBitOffset + x * pixelBitStride;
|
||||
int index = y * scanlineStride + (bitnum / dataElementSize);
|
||||
int shift = dataElementSize - (bitnum & (dataElementSize-1))
|
||||
- pixelBitStride;
|
||||
int element = data.getElem(index);
|
||||
element &= ~(bitMask << shift);
|
||||
element |= (iArray[0] & bitMask) << shift;
|
||||
data.setElem(index,element);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
this.pixelBitStride == that.pixelBitStride &&
|
||||
this.bitMask == that.bitMask &&
|
||||
this.pixelsPerDataElement == that.pixelsPerDataElement &&
|
||||
this.dataElementSize == that.dataElementSize &&
|
||||
this.dataBitOffset == that.dataBitOffset &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
hash ^= pixelBitStride;
|
||||
hash <<= 8;
|
||||
hash ^= bitMask;
|
||||
hash <<= 8;
|
||||
hash ^= pixelsPerDataElement;
|
||||
hash <<= 8;
|
||||
hash ^= dataElementSize;
|
||||
hash <<= 8;
|
||||
hash ^= dataBitOffset;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
1777
jdk/src/share/classes/java/awt/image/Raster.java
Normal file
1777
jdk/src/share/classes/java/awt/image/Raster.java
Normal file
File diff suppressed because it is too large
Load Diff
217
jdk/src/share/classes/java/awt/image/RenderedImage.java
Normal file
217
jdk/src/share/classes/java/awt/image/RenderedImage.java
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2000 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* RenderedImage is a common interface for objects which contain
|
||||
* or can produce image data in the form of Rasters. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
*/
|
||||
|
||||
public interface RenderedImage {
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderedImages that are the immediate sources of
|
||||
* image data for this RenderedImage. This method returns null if
|
||||
* the RenderedImage object has no information about its immediate
|
||||
* sources. It returns an empty Vector if the RenderedImage object has
|
||||
* no immediate sources.
|
||||
* @return a Vector of <code>RenderedImage</code> objects.
|
||||
*/
|
||||
Vector<RenderedImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image. The set of
|
||||
* properties and whether it is immutable is determined by the
|
||||
* implementing class. This method returns
|
||||
* java.awt.Image.UndefinedProperty if the specified property is
|
||||
* not defined for this RenderedImage.
|
||||
* @param name the name of the property
|
||||
* @return the property indicated by the specified name.
|
||||
* @see java.awt.Image#UndefinedProperty
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns an array of names recognized by
|
||||
* {@link #getProperty(String) getProperty(String)}
|
||||
* or <code>null</code>, if no property names are recognized.
|
||||
* @return a <code>String</code> array containing all of the
|
||||
* property names that <code>getProperty(String)</code> recognizes;
|
||||
* or <code>null</code> if no property names are recognized.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns the ColorModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their ColorModel. This
|
||||
* can return null.
|
||||
* @return the <code>ColorModel</code> of this image.
|
||||
*/
|
||||
ColorModel getColorModel();
|
||||
|
||||
/**
|
||||
* Returns the SampleModel associated with this image. All Rasters
|
||||
* returned from this image will have this as their SampleModel.
|
||||
* @return the <code>SampleModel</code> of this image.
|
||||
*/
|
||||
SampleModel getSampleModel();
|
||||
|
||||
/**
|
||||
* Returns the width of the RenderedImage.
|
||||
* @return the width of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of the RenderedImage.
|
||||
* @return the height of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getHeight();
|
||||
|
||||
/**
|
||||
* Returns the minimum X coordinate (inclusive) of the RenderedImage.
|
||||
* @return the X coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinX();
|
||||
|
||||
/**
|
||||
* Returns the minimum Y coordinate (inclusive) of the RenderedImage.
|
||||
* @return the Y coordinate of this <code>RenderedImage</code>.
|
||||
*/
|
||||
int getMinY();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the X direction.
|
||||
* @return the number of tiles in the X direction.
|
||||
*/
|
||||
int getNumXTiles();
|
||||
|
||||
/**
|
||||
* Returns the number of tiles in the Y direction.
|
||||
* @return the number of tiles in the Y direction.
|
||||
*/
|
||||
int getNumYTiles();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the X direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileX();
|
||||
|
||||
/**
|
||||
* Returns the minimum tile index in the Y direction.
|
||||
* @return the minimum tile index in the X direction.
|
||||
*/
|
||||
int getMinTileY();
|
||||
|
||||
/**
|
||||
* Returns the tile width in pixels. All tiles must have the same
|
||||
* width.
|
||||
* @return the tile width in pixels.
|
||||
*/
|
||||
int getTileWidth();
|
||||
|
||||
/**
|
||||
* Returns the tile height in pixels. All tiles must have the same
|
||||
* height.
|
||||
* @return the tile height in pixels.
|
||||
*/
|
||||
int getTileHeight();
|
||||
|
||||
/**
|
||||
* Returns the X offset of the tile grid relative to the origin,
|
||||
* i.e., the X coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the X offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridXOffset();
|
||||
|
||||
/**
|
||||
* Returns the Y offset of the tile grid relative to the origin,
|
||||
* i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
|
||||
* (Note that tile (0, 0) may not actually exist.)
|
||||
* @return the Y offset of the tile grid relative to the origin.
|
||||
*/
|
||||
int getTileGridYOffset();
|
||||
|
||||
/**
|
||||
* Returns tile (tileX, tileY). Note that tileX and tileY are indices
|
||||
* into the tile array, not pixel locations. The Raster that is returned
|
||||
* is live and will be updated if the image is changed.
|
||||
* @param tileX the X index of the requested tile in the tile array
|
||||
* @param tileY the Y index of the requested tile in the tile array
|
||||
* @return the tile given the specified indices.
|
||||
*/
|
||||
Raster getTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns the image as one large tile (for tile based
|
||||
* images this will require fetching the whole image
|
||||
* and copying the image data over). The Raster returned is
|
||||
* a copy of the image data and will not be updated if the image
|
||||
* is changed.
|
||||
* @return the image as one large tile.
|
||||
*/
|
||||
Raster getData();
|
||||
|
||||
/**
|
||||
* Computes and returns an arbitrary region of the RenderedImage.
|
||||
* The Raster returned is a copy of the image data and will not
|
||||
* be updated if the image is changed.
|
||||
* @param rect the region of the RenderedImage to be returned.
|
||||
* @return the region of the <code>RenderedImage</code>
|
||||
* indicated by the specified <code>Rectangle</code>.
|
||||
*/
|
||||
Raster getData(Rectangle rect);
|
||||
|
||||
/**
|
||||
* Computes an arbitrary rectangular region of the RenderedImage
|
||||
* and copies it into a caller-supplied WritableRaster. The region
|
||||
* to be computed is determined from the bounds of the supplied
|
||||
* WritableRaster. The supplied WritableRaster must have a
|
||||
* SampleModel that is compatible with this image. If raster is null,
|
||||
* an appropriate WritableRaster is created.
|
||||
* @param raster a WritableRaster to hold the returned portion of the
|
||||
* image, or null.
|
||||
* @return a reference to the supplied or created WritableRaster.
|
||||
*/
|
||||
WritableRaster copyData(WritableRaster raster);
|
||||
}
|
1393
jdk/src/share/classes/java/awt/image/SampleModel.java
Normal file
1393
jdk/src/share/classes/java/awt/image/SampleModel.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,805 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2001 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents pixel data packed such that the N samples which make
|
||||
* up a single pixel are stored in a single data array element, and each data
|
||||
* data array element holds samples for only one pixel.
|
||||
* This class supports
|
||||
* {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
|
||||
* {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
|
||||
* {@link DataBuffer#TYPE_INT TYPE_INT} data types.
|
||||
* All data array elements reside
|
||||
* in the first bank of a DataBuffer. Accessor methods are provided so
|
||||
* that the image data can be manipulated directly. Scanline stride is the
|
||||
* number of data array elements between a given sample and the corresponding
|
||||
* sample in the same column of the next scanline. Bit masks are the masks
|
||||
* required to extract the samples representing the bands of the pixel.
|
||||
* Bit offsets are the offsets in bits into the data array
|
||||
* element of the samples representing the bands of the pixel.
|
||||
* <p>
|
||||
* The following code illustrates extracting the bits of the sample
|
||||
* representing band <code>b</code> for pixel <code>x,y</code>
|
||||
* from DataBuffer <code>data</code>:
|
||||
* <pre>
|
||||
* int sample = data.getElem(y * scanlineStride + x);
|
||||
* sample = (sample & bitMasks[b]) >>> bitOffsets[b];
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
public class SinglePixelPackedSampleModel extends SampleModel
|
||||
{
|
||||
/** Bit masks for all bands of the image data. */
|
||||
private int bitMasks[];
|
||||
|
||||
/** Bit Offsets for all bands of the image data. */
|
||||
private int bitOffsets[];
|
||||
|
||||
/** Bit sizes for all the bands of the image data. */
|
||||
private int bitSizes[];
|
||||
|
||||
/** Maximum bit size. */
|
||||
private int maxBitSize;
|
||||
|
||||
/** Line stride of the region of image data described by this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private int scanlineStride;
|
||||
|
||||
private static native void initIDs();
|
||||
static {
|
||||
ColorModel.loadLibraries();
|
||||
initIDs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of the
|
||||
* image data described.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int bitMasks[]) {
|
||||
this(dataType, w, h, w, bitMasks);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
|
||||
* and a scanline stride equal to scanlineStride data array elements.
|
||||
* Each sample is stored in a data array element in the position of
|
||||
* its corresponding bit mask. Each bit mask must be contiguous and
|
||||
* masks must not overlap.
|
||||
* @param dataType The data type for storing samples.
|
||||
* @param w The width (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param h The height (in pixels) of the region of
|
||||
* image data described.
|
||||
* @param scanlineStride The line stride of the image data.
|
||||
* @param bitMasks The bit masks for all bands.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
* @throws IllegalArgumentException if any mask in
|
||||
* <code>bitMask</code> is not contiguous
|
||||
* @throws IllegalArgumentException if <code>dataType</code> is not
|
||||
* either <code>DataBuffer.TYPE_BYTE</code>,
|
||||
* <code>DataBuffer.TYPE_USHORT</code>, or
|
||||
* <code>DataBuffer.TYPE_INT</code>
|
||||
*/
|
||||
public SinglePixelPackedSampleModel(int dataType, int w, int h,
|
||||
int scanlineStride, int bitMasks[]) {
|
||||
super(dataType, w, h, bitMasks.length);
|
||||
if (dataType != DataBuffer.TYPE_BYTE &&
|
||||
dataType != DataBuffer.TYPE_USHORT &&
|
||||
dataType != DataBuffer.TYPE_INT) {
|
||||
throw new IllegalArgumentException("Unsupported data type "+
|
||||
dataType);
|
||||
}
|
||||
this.dataType = dataType;
|
||||
this.bitMasks = (int[]) bitMasks.clone();
|
||||
this.scanlineStride = scanlineStride;
|
||||
|
||||
this.bitOffsets = new int[numBands];
|
||||
this.bitSizes = new int[numBands];
|
||||
|
||||
this.maxBitSize = 0;
|
||||
for (int i=0; i<numBands; i++) {
|
||||
int bitOffset = 0, bitSize = 0, mask;
|
||||
mask = bitMasks[i];
|
||||
|
||||
if (mask != 0) {
|
||||
while ((mask & 1) == 0) {
|
||||
mask = mask >>> 1;
|
||||
bitOffset++;
|
||||
}
|
||||
while ((mask & 1) == 1) {
|
||||
mask = mask >>> 1;
|
||||
bitSize++;
|
||||
}
|
||||
if (mask != 0) {
|
||||
throw new IllegalArgumentException("Mask "+bitMasks[i]+
|
||||
" must be contiguous");
|
||||
}
|
||||
}
|
||||
bitOffsets[i] = bitOffset;
|
||||
bitSizes[i] = bitSize;
|
||||
if (bitSize > maxBitSize) {
|
||||
maxBitSize = bitSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data elements needed to transfer one pixel
|
||||
* via the getDataElements and setDataElements methods.
|
||||
* For a SinglePixelPackedSampleModel, this is one.
|
||||
*/
|
||||
public int getNumDataElements() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the buffer (in data array elements)
|
||||
* needed for a data buffer that matches this
|
||||
* SinglePixelPackedSampleModel.
|
||||
*/
|
||||
private long getBufferSize() {
|
||||
long size = scanlineStride * (height-1) + width;
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SinglePixelPackedSampleModel with the specified
|
||||
* width and height. The new SinglePixelPackedSampleModel will have the
|
||||
* same storage data type and bit masks as this
|
||||
* SinglePixelPackedSampleModel.
|
||||
* @param w the width of the resulting <code>SampleModel</code>
|
||||
* @param h the height of the resulting <code>SampleModel</code>
|
||||
* @return a <code>SinglePixelPackedSampleModel</code> with the
|
||||
* specified width and height.
|
||||
* @throws IllegalArgumentException if <code>w</code> or
|
||||
* <code>h</code> is not greater than 0
|
||||
*/
|
||||
public SampleModel createCompatibleSampleModel(int w, int h) {
|
||||
SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
|
||||
bitMasks);
|
||||
return sampleModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a DataBuffer that corresponds to this
|
||||
* SinglePixelPackedSampleModel. The DataBuffer's data type and size
|
||||
* will be consistent with this SinglePixelPackedSampleModel. The
|
||||
* DataBuffer will have a single bank.
|
||||
*/
|
||||
public DataBuffer createDataBuffer() {
|
||||
DataBuffer dataBuffer = null;
|
||||
|
||||
int size = (int)getBufferSize();
|
||||
switch (dataType) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
dataBuffer = new DataBufferByte(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
dataBuffer = new DataBufferUShort(size);
|
||||
break;
|
||||
case DataBuffer.TYPE_INT:
|
||||
dataBuffer = new DataBufferInt(size);
|
||||
break;
|
||||
}
|
||||
return dataBuffer;
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for all bands. */
|
||||
public int[] getSampleSize() {
|
||||
int mask;
|
||||
int sampleSize[] = new int [numBands];
|
||||
for (int i=0; i<numBands; i++) {
|
||||
sampleSize[i] = 0;
|
||||
mask = bitMasks[i] >>> bitOffsets[i];
|
||||
while ((mask & 1) != 0) {
|
||||
sampleSize[i] ++;
|
||||
mask = mask >>> 1;
|
||||
}
|
||||
}
|
||||
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/** Returns the number of bits per sample for the specified band. */
|
||||
public int getSampleSize(int band) {
|
||||
int sampleSize = 0;
|
||||
int mask = bitMasks[band] >>> bitOffsets[band];
|
||||
while ((mask & 1) != 0) {
|
||||
sampleSize ++;
|
||||
mask = mask >>> 1;
|
||||
}
|
||||
|
||||
return sampleSize;
|
||||
}
|
||||
|
||||
/** Returns the offset (in data array elements) of pixel (x,y).
|
||||
* The data element containing pixel <code>x,y</code>
|
||||
* can be retrieved from a DataBuffer <code>data</code> with a
|
||||
* SinglePixelPackedSampleModel <code>sppsm</code> as:
|
||||
* <pre>
|
||||
* data.getElem(sppsm.getOffset(x, y));
|
||||
* </pre>
|
||||
* @param x the X coordinate of the specified pixel
|
||||
* @param y the Y coordinate of the specified pixel
|
||||
* @return the offset of the specified pixel.
|
||||
*/
|
||||
public int getOffset(int x, int y) {
|
||||
int offset = y * scanlineStride + x;
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** Returns the bit offsets into the data array element representing
|
||||
* a pixel for all bands.
|
||||
* @return the bit offsets representing a pixel for all bands.
|
||||
*/
|
||||
public int [] getBitOffsets() {
|
||||
return (int[])bitOffsets.clone();
|
||||
}
|
||||
|
||||
/** Returns the bit masks for all bands.
|
||||
* @return the bit masks for all bands.
|
||||
*/
|
||||
public int [] getBitMasks() {
|
||||
return (int[])bitMasks.clone();
|
||||
}
|
||||
|
||||
/** Returns the scanline stride of this SinglePixelPackedSampleModel.
|
||||
* @return the scanline stride of this
|
||||
* <code>SinglePixelPackedSampleModel</code>.
|
||||
*/
|
||||
public int getScanlineStride() {
|
||||
return scanlineStride;
|
||||
}
|
||||
|
||||
/**
|
||||
* This creates a new SinglePixelPackedSampleModel with a subset of the
|
||||
* bands of this SinglePixelPackedSampleModel. The new
|
||||
* SinglePixelPackedSampleModel can be used with any DataBuffer that the
|
||||
* existing SinglePixelPackedSampleModel can be used with. The new
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination will represent
|
||||
* an image with a subset of the bands of the original
|
||||
* SinglePixelPackedSampleModel/DataBuffer combination.
|
||||
* @exception RasterFormatException if the length of the bands argument is
|
||||
* greater than the number of bands in
|
||||
* the sample model.
|
||||
*/
|
||||
public SampleModel createSubsetSampleModel(int bands[]) {
|
||||
if (bands.length > numBands)
|
||||
throw new RasterFormatException("There are only " +
|
||||
numBands +
|
||||
" bands");
|
||||
int newBitMasks[] = new int[bands.length];
|
||||
for (int i=0; i<bands.length; i++)
|
||||
newBitMasks[i] = bitMasks[bands[i]];
|
||||
|
||||
return new SinglePixelPackedSampleModel(this.dataType, width, height,
|
||||
this.scanlineStride, newBitMasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns data for a single pixel in a primitive array of type
|
||||
* TransferType. For a SinglePixelPackedSampleModel, the array will
|
||||
* have one element, and the type will be the same as the storage
|
||||
* data type. Generally, obj
|
||||
* should be passed in as null, so that the Object will be created
|
||||
* automatically and will be of the right primitive data type.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>, to
|
||||
* DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* If obj is non-null, it should be a primitive array of type TransferType.
|
||||
* Otherwise, a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is non-null and is not large enough to hold
|
||||
* the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj If non-null, a primitive array in which to return
|
||||
* the pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the data for the specified pixel.
|
||||
* @see #setDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] bdata;
|
||||
|
||||
if (obj == null)
|
||||
bdata = new byte[1];
|
||||
else
|
||||
bdata = (byte[])obj;
|
||||
|
||||
bdata[0] = (byte)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)bdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sdata;
|
||||
|
||||
if (obj == null)
|
||||
sdata = new short[1];
|
||||
else
|
||||
sdata = (short[])obj;
|
||||
|
||||
sdata[0] = (short)data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)sdata;
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] idata;
|
||||
|
||||
if (obj == null)
|
||||
idata = new int[1];
|
||||
else
|
||||
idata = (int[])obj;
|
||||
|
||||
idata[0] = data.getElem(y * scanlineStride + x);
|
||||
|
||||
obj = (Object)idata;
|
||||
break;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples in for the specified pixel in an int array.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray If non-null, returns the samples in this array
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified pixel.
|
||||
* @see #setPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray == null) {
|
||||
pixels = new int [numBands];
|
||||
} else {
|
||||
pixels = iArray;
|
||||
}
|
||||
|
||||
int value = data.getElem(y * scanlineStride + x);
|
||||
for (int i=0; i<numBands; i++) {
|
||||
pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all samples for the specified rectangle of pixels in
|
||||
* an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return all samples for the specified region of pixels.
|
||||
* @see #setPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int pixels[];
|
||||
if (iArray != null) {
|
||||
pixels = iArray;
|
||||
} else {
|
||||
pixels = new int [w*h*numBands];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
pixels[dstOffset++] =
|
||||
((value & bitMasks[k]) >>> bitOffsets[k]);
|
||||
}
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns as int the sample in a specified band for the pixel
|
||||
* located at (x,y).
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to return.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the sample in a specified band for the specified
|
||||
* pixel.
|
||||
* @see #setSample(int, int, int, int, DataBuffer)
|
||||
*/
|
||||
public int getSample(int x, int y, int b, DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int sample = data.getElem(y * scanlineStride + x);
|
||||
return ((sample & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the samples for a specified band for the specified rectangle
|
||||
* of pixels in an int array, one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to return.
|
||||
* @param iArray If non-null, returns the samples in this array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @return the samples for the specified band for the specified
|
||||
* region of pixels.
|
||||
* @see #setSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public int[] getSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int samples[];
|
||||
if (iArray != null) {
|
||||
samples = iArray;
|
||||
} else {
|
||||
samples = new int [w*h];
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int dstOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
samples[dstOffset++] =
|
||||
((value & bitMasks[b]) >>> bitOffsets[b]);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel in the specified DataBuffer from a
|
||||
* primitive array of type TransferType. For a
|
||||
* SinglePixelPackedSampleModel, only the first element of the array
|
||||
* will hold valid data, and the type of the array must be the same as
|
||||
* the storage data type of the SinglePixelPackedSampleModel.
|
||||
* <p>
|
||||
* The following code illustrates transferring data for one pixel from
|
||||
* DataBuffer <code>db1</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm1</code>,
|
||||
* to DataBuffer <code>db2</code>, whose storage layout is described by
|
||||
* SinglePixelPackedSampleModel <code>sppsm2</code>.
|
||||
* The transfer will generally be more efficient than using
|
||||
* getPixel/setPixel.
|
||||
* <pre>
|
||||
* SinglePixelPackedSampleModel sppsm1, sppsm2;
|
||||
* DataBufferInt db1, db2;
|
||||
* sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
|
||||
* db1), db2);
|
||||
* </pre>
|
||||
* Using getDataElements/setDataElements to transfer between two
|
||||
* DataBuffer/SampleModel pairs is legitimate if the SampleModels have
|
||||
* the same number of bands, corresponding bands have the same number of
|
||||
* bits per sample, and the TransferTypes are the same.
|
||||
* <p>
|
||||
* obj must be a primitive array of type TransferType. Otherwise,
|
||||
* a ClassCastException is thrown. An
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if obj is not large enough to hold the pixel data.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param obj A primitive array containing pixel data.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getDataElements(int, int, Object, DataBuffer)
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object obj, DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int type = getTransferType();
|
||||
|
||||
switch(type) {
|
||||
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
|
||||
byte[] barray = (byte[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
|
||||
short[] sarray = (short[])obj;
|
||||
data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_INT:
|
||||
|
||||
int[] iarray = (int[])obj;
|
||||
data.setElem(y*scanlineStride+x, iarray[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixel(int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixel(int x, int y,
|
||||
int iArray[],
|
||||
DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y * scanlineStride + x;
|
||||
int value = data.getElem(lineOffset);
|
||||
for (int i=0; i < numBands; i++) {
|
||||
value &= ~bitMasks[i];
|
||||
value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
|
||||
}
|
||||
data.setElem(lineOffset, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getPixels(int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h,
|
||||
int iArray[], DataBuffer data) {
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
for (int k=0; k < numBands; k++) {
|
||||
value &= ~bitMasks[k];
|
||||
int srcValue = iArray[srcOffset++];
|
||||
value |= ((srcValue << bitOffsets[k])
|
||||
& bitMasks[k]);
|
||||
}
|
||||
data.setElem(lineOffset+j, value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as an int.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSample(int, int, int, DataBuffer)
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s,
|
||||
DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int value = data.getElem(y*scanlineStride + x);
|
||||
value &= ~bitMasks[b];
|
||||
value |= (s << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(y*scanlineStride + x,value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* @param x The X coordinate of the upper left pixel location.
|
||||
* @param y The Y coordinate of the upper left pixel location.
|
||||
* @param w The width of the pixel rectangle.
|
||||
* @param h The height of the pixel rectangle.
|
||||
* @param b The band to set.
|
||||
* @param iArray The input samples in an int array.
|
||||
* @param data The DataBuffer containing the image data.
|
||||
* @see #getSamples(int, int, int, int, int, int[], DataBuffer)
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[], DataBuffer data) {
|
||||
// Bounds check for 'b' will be performed automatically
|
||||
if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
int lineOffset = y*scanlineStride + x;
|
||||
int srcOffset = 0;
|
||||
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++) {
|
||||
int value = data.getElem(lineOffset+j);
|
||||
value &= ~bitMasks[b];
|
||||
int sample = iArray[srcOffset++];
|
||||
value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
|
||||
data.setElem(lineOffset+j,value);
|
||||
}
|
||||
lineOffset += scanlineStride;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
|
||||
return this.width == that.width &&
|
||||
this.height == that.height &&
|
||||
this.numBands == that.numBands &&
|
||||
this.dataType == that.dataType &&
|
||||
Arrays.equals(this.bitMasks, that.bitMasks) &&
|
||||
Arrays.equals(this.bitOffsets, that.bitOffsets) &&
|
||||
Arrays.equals(this.bitSizes, that.bitSizes) &&
|
||||
this.maxBitSize == that.maxBitSize &&
|
||||
this.scanlineStride == that.scanlineStride;
|
||||
}
|
||||
|
||||
// If we implement equals() we must also implement hashCode
|
||||
public int hashCode() {
|
||||
int hash = 0;
|
||||
hash = width;
|
||||
hash <<= 8;
|
||||
hash ^= height;
|
||||
hash <<= 8;
|
||||
hash ^= numBands;
|
||||
hash <<= 8;
|
||||
hash ^= dataType;
|
||||
hash <<= 8;
|
||||
for (int i = 0; i < bitMasks.length; i++) {
|
||||
hash ^= bitMasks[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitOffsets.length; i++) {
|
||||
hash ^= bitOffsets[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
for (int i = 0; i < bitSizes.length; i++) {
|
||||
hash ^= bitSizes[i];
|
||||
hash <<= 8;
|
||||
}
|
||||
hash ^= maxBitSize;
|
||||
hash <<= 8;
|
||||
hash ^= scanlineStride;
|
||||
return hash;
|
||||
}
|
||||
}
|
741
jdk/src/share/classes/java/awt/image/WritableRaster.java
Normal file
741
jdk/src/share/classes/java/awt/image/WritableRaster.java
Normal file
@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Portions 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* This class extends Raster to provide pixel writing capabilities.
|
||||
* Refer to the class comment for Raster for descriptions of how
|
||||
* a Raster stores pixels.
|
||||
*
|
||||
* <p> The constructors of this class are protected. To instantiate
|
||||
* a WritableRaster, use one of the createWritableRaster factory methods
|
||||
* in the Raster class.
|
||||
*/
|
||||
public class WritableRaster extends Raster {
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel. The
|
||||
* WritableRaster's upper left corner is origin and it is the
|
||||
* same size as the SampleModel. A DataBuffer large enough to
|
||||
* describe the WritableRaster is automatically created.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
sampleModel.createDataBuffer(),
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel and DataBuffer.
|
||||
* The WritableRaster's upper left corner is origin and it is the same
|
||||
* size as the SampleModel. The DataBuffer is not initialized and must
|
||||
* be compatible with SampleModel.
|
||||
* @param sampleModel The SampleModel that specifies the layout.
|
||||
* @param dataBuffer The DataBuffer that contains the image data.
|
||||
* @param origin The Point that specifies the origin.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>origin.x + sampleModel.getWidth()</code> or
|
||||
* <code>origin.y + sampleModel.getHeight()</code> results
|
||||
* in integer overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Point origin) {
|
||||
this(sampleModel,
|
||||
dataBuffer,
|
||||
new Rectangle(origin.x,
|
||||
origin.y,
|
||||
sampleModel.getWidth(),
|
||||
sampleModel.getHeight()),
|
||||
origin,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a WritableRaster with the given SampleModel, DataBuffer,
|
||||
* and parent. aRegion specifies the bounding rectangle of the new
|
||||
* Raster. When translated into the base Raster's coordinate
|
||||
* system, aRegion must be contained by the base Raster.
|
||||
* (The base Raster is the Raster's ancestor which has no parent.)
|
||||
* sampleModelTranslate specifies the sampleModelTranslateX and
|
||||
* sampleModelTranslateY values of the new Raster.
|
||||
*
|
||||
* 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 DataBuffer that contains the image data.
|
||||
* @param aRegion The Rectangle that specifies the image area.
|
||||
* @param sampleModelTranslate The Point that specifies the translation
|
||||
* from SampleModel to Raster coordinates.
|
||||
* @param parent The parent (if any) of this raster.
|
||||
* @throws RasterFormatException if <code>aRegion</code> has width
|
||||
* or height less than or equal to zero, or computing either
|
||||
* <code>aRegion.x + aRegion.width</code> or
|
||||
* <code>aRegion.y + aRegion.height</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
protected WritableRaster(SampleModel sampleModel,
|
||||
DataBuffer dataBuffer,
|
||||
Rectangle aRegion,
|
||||
Point sampleModelTranslate,
|
||||
WritableRaster parent){
|
||||
super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
|
||||
}
|
||||
|
||||
/** Returns the parent WritableRaster (if any) of this WritableRaster,
|
||||
* or else null.
|
||||
* @return the parent of this <code>WritableRaster</code>, or
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public WritableRaster getWritableParent() {
|
||||
return (WritableRaster)parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a WritableRaster with the same size, SampleModel and DataBuffer
|
||||
* as this one, but with a different location. The new WritableRaster
|
||||
* will possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* @param childMinX X coord of the upper left corner of the new Raster.
|
||||
* @param childMinY Y coord of the upper left corner of the new Raster.
|
||||
* @return a <code>WritableRaster</code> the same as this one except
|
||||
* for the specified location.
|
||||
* @throws RasterFormatException if computing either
|
||||
* <code>childMinX + this.getWidth()</code> or
|
||||
* <code>childMinY + this.getHeight()</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableTranslatedChild(int childMinX,
|
||||
int childMinY) {
|
||||
return createWritableChild(minX,minY,width,height,
|
||||
childMinX,childMinY,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new WritableRaster which shares all or part of this
|
||||
* WritableRaster's DataBuffer. The new WritableRaster will
|
||||
* possess a reference to the current WritableRaster, accessible
|
||||
* through its getParent() and getWritableParent() methods.
|
||||
*
|
||||
* <p> The parentX, parentY, width and height parameters form a
|
||||
* Rectangle in this WritableRaster's coordinate space, indicating
|
||||
* the area of pixels to be shared. An error will be thrown if
|
||||
* this Rectangle is not contained with the bounds of the current
|
||||
* WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may additionally be translated to a
|
||||
* different coordinate system for the plane than that used by the current
|
||||
* WritableRaster. The childMinX and childMinY parameters give
|
||||
* the new (x, y) coordinate of the upper-left pixel of the
|
||||
* returned WritableRaster; the coordinate (childMinX, childMinY)
|
||||
* in the new WritableRaster will map to the same pixel as the
|
||||
* coordinate (parentX, parentY) in the current WritableRaster.
|
||||
*
|
||||
* <p> The new WritableRaster may be defined to contain only a
|
||||
* subset of the bands of the current WritableRaster, possibly
|
||||
* reordered, by means of the bandList parameter. If bandList is
|
||||
* null, it is taken to include all of the bands of the current
|
||||
* WritableRaster in their current order.
|
||||
*
|
||||
* <p> To create a new WritableRaster that contains a subregion of
|
||||
* the current WritableRaster, but shares its coordinate system
|
||||
* and bands, this method should be called with childMinX equal to
|
||||
* parentX, childMinY equal to parentY, and bandList equal to
|
||||
* null.
|
||||
*
|
||||
* @param parentX X coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param parentY Y coordinate of the upper left corner in this
|
||||
* WritableRaster's coordinates.
|
||||
* @param w Width of the region starting at (parentX, parentY).
|
||||
* @param h Height of the region starting at (parentX, parentY).
|
||||
* @param childMinX X coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param childMinY Y coordinate of the upper left corner of
|
||||
* the returned WritableRaster.
|
||||
* @param bandList Array of band indices, or null to use all bands.
|
||||
* @return a <code>WritableRaster</code> sharing all or part of the
|
||||
* <code>DataBuffer</code> of this <code>WritableRaster</code>.
|
||||
* @exception RasterFormatException if the subregion is outside of the
|
||||
* raster bounds.
|
||||
* @throws RasterFormatException if <code>w</code> or
|
||||
* <code>h</code>
|
||||
* is less than or equal to zero, or computing any of
|
||||
* <code>parentX + w</code>, <code>parentY + h</code>,
|
||||
* <code>childMinX + w</code>, or
|
||||
* <code>childMinY + h</code> results in integer
|
||||
* overflow
|
||||
*/
|
||||
public WritableRaster createWritableChild(int parentX, int parentY,
|
||||
int w, int h,
|
||||
int childMinX, int childMinY,
|
||||
int bandList[]) {
|
||||
if (parentX < this.minX) {
|
||||
throw new RasterFormatException("parentX lies outside raster");
|
||||
}
|
||||
if (parentY < this.minY) {
|
||||
throw new RasterFormatException("parentY lies outside raster");
|
||||
}
|
||||
if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
|
||||
throw new RasterFormatException("(parentX + width) is outside raster");
|
||||
}
|
||||
if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
|
||||
throw new RasterFormatException("(parentY + height) is outside raster");
|
||||
}
|
||||
|
||||
SampleModel sm;
|
||||
// Note: the SampleModel for the child Raster should have the same
|
||||
// width and height as that for the parent, since it represents
|
||||
// the physical layout of the pixel data. The child Raster's width
|
||||
// and height represent a "virtual" view of the pixel data, so
|
||||
// they may be different than those of the SampleModel.
|
||||
if (bandList != null) {
|
||||
sm = sampleModel.createSubsetSampleModel(bandList);
|
||||
}
|
||||
else {
|
||||
sm = sampleModel;
|
||||
}
|
||||
|
||||
int deltaX = childMinX - parentX;
|
||||
int deltaY = childMinY - parentY;
|
||||
|
||||
return new WritableRaster(sm,
|
||||
getDataBuffer(),
|
||||
new Rectangle(childMinX,childMinY,
|
||||
w, h),
|
||||
new Point(sampleModelTranslateX+deltaX,
|
||||
sampleModelTranslateY+deltaY),
|
||||
this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a single pixel from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
|
||||
* @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.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
inData, dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from an input Raster.
|
||||
* The input Raster must be compatible with this WritableRaster
|
||||
* in that they must have the same number of bands, corresponding bands
|
||||
* must have the same number of bits per sample, the TransferTypes
|
||||
* and NumDataElements must be the same, and the packing used by
|
||||
* the getDataElements/setDataElements must be identical.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param inRaster Raster containing data to place at x,y.
|
||||
*
|
||||
* @throws NullPointerException if inRaster is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds.
|
||||
*/
|
||||
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.minX + this.width) ||
|
||||
(dstOffY + height > this.minY + this.height)) {
|
||||
throw new ArrayIndexOutOfBoundsException
|
||||
("Coordinate out of bounds!");
|
||||
}
|
||||
|
||||
int srcOffX = inRaster.getMinX();
|
||||
int srcOffY = inRaster.getMinY();
|
||||
Object tdata = null;
|
||||
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
|
||||
width, 1, tdata);
|
||||
setDataElements(dstOffX, dstOffY+startY,
|
||||
width, 1, tdata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a rectangle of pixels from a
|
||||
* primitive array of type TransferType. For image data supported by
|
||||
* the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
|
||||
* DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
|
||||
* DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
|
||||
* may be in a packed format, thus increasing efficiency for data
|
||||
* transfers.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds, or if inData is not large enough to hold the pixel data.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* A ClassCastException will be thrown if the input object is not null
|
||||
* and references anything other than an array of TransferType.
|
||||
* @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
|
||||
* @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+w-1, y+h-1.
|
||||
*
|
||||
* @throws NullPointerException if inData is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if inData is too small to hold the input.
|
||||
*/
|
||||
public void setDataElements(int x, int y, int w, int h, Object inData) {
|
||||
sampleModel.setDataElements(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY,
|
||||
w,h,inData,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster. Each pixel
|
||||
* in srcRaster is copied to the same x,y address in this raster, unless
|
||||
* the address falls outside the bounds of this raster. srcRaster
|
||||
* must have the same number of bands as this WritableRaster. The
|
||||
* copy is a simple copy of source samples to the corresponding destination
|
||||
* samples.
|
||||
* <p>
|
||||
* If all samples of both source and destination Rasters are of
|
||||
* integral type and less than or equal to 32 bits in size, then calling
|
||||
* this method is equivalent to executing the following code for all
|
||||
* <code>x,y</code> addresses valid in both Rasters.
|
||||
* <pre>
|
||||
* Raster srcRaster;
|
||||
* WritableRaster dstRaster;
|
||||
* for (int b = 0; b < srcRaster.getNumBands(); b++) {
|
||||
* dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
|
||||
* }
|
||||
* </pre>
|
||||
* Thus, when copying an integral type source to an integral type
|
||||
* destination, if the source sample size is greater than the destination
|
||||
* sample size for a particular band, the high order bits of the source
|
||||
* sample are truncated. If the source sample size is less than the
|
||||
* destination size for a particular band, the high order bits of the
|
||||
* destination are zero-extended or sign-extended depending on whether
|
||||
* srcRaster's SampleModel treats the sample as a signed or unsigned
|
||||
* quantity.
|
||||
* <p>
|
||||
* When copying a float or double source to an integral type destination,
|
||||
* each source sample is cast to the destination type. When copying an
|
||||
* integral type source to a float or double destination, the source
|
||||
* is first converted to a 32-bit int (if necessary), using the above
|
||||
* rules for integral types, and then the int is cast to float or
|
||||
* double.
|
||||
* <p>
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(Raster srcRaster) {
|
||||
setRect(0,0,srcRaster);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies pixels from Raster srcRaster to this WritableRaster.
|
||||
* For each (x, y) address in srcRaster, the corresponding pixel
|
||||
* is copied to address (x+dx, y+dy) in this WritableRaster,
|
||||
* unless (x+dx, y+dy) falls outside the bounds of this raster.
|
||||
* srcRaster must have the same number of bands as this WritableRaster.
|
||||
* The copy is a simple copy of source samples to the corresponding
|
||||
* destination samples. For details, see
|
||||
* {@link WritableRaster#setRect(Raster)}.
|
||||
*
|
||||
* @param dx The X translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param dy The Y translation factor from src space to dst space
|
||||
* of the copy.
|
||||
* @param srcRaster The Raster from which to copy pixels.
|
||||
*
|
||||
* @throws NullPointerException if srcRaster is null.
|
||||
*/
|
||||
public void setRect(int dx, int dy, Raster srcRaster) {
|
||||
int width = srcRaster.getWidth();
|
||||
int height = srcRaster.getHeight();
|
||||
int srcOffX = srcRaster.getMinX();
|
||||
int srcOffY = srcRaster.getMinY();
|
||||
int dstOffX = dx+srcOffX;
|
||||
int dstOffY = dy+srcOffY;
|
||||
|
||||
// Clip to this raster
|
||||
if (dstOffX < this.minX) {
|
||||
int skipX = this.minX - dstOffX;
|
||||
width -= skipX;
|
||||
srcOffX += skipX;
|
||||
dstOffX = this.minX;
|
||||
}
|
||||
if (dstOffY < this.minY) {
|
||||
int skipY = this.minY - dstOffY;
|
||||
height -= skipY;
|
||||
srcOffY += skipY;
|
||||
dstOffY = this.minY;
|
||||
}
|
||||
if (dstOffX+width > this.minX+this.width) {
|
||||
width = this.minX + this.width - dstOffX;
|
||||
}
|
||||
if (dstOffY+height > this.minY+this.height) {
|
||||
height = this.minY + this.height - dstOffY;
|
||||
}
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (srcRaster.getSampleModel().getDataType()) {
|
||||
case DataBuffer.TYPE_BYTE:
|
||||
case DataBuffer.TYPE_SHORT:
|
||||
case DataBuffer.TYPE_USHORT:
|
||||
case DataBuffer.TYPE_INT:
|
||||
int[] iData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
iData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
iData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, iData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_FLOAT:
|
||||
float[] fData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
fData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
fData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, fData);
|
||||
}
|
||||
break;
|
||||
|
||||
case DataBuffer.TYPE_DOUBLE:
|
||||
double[] dData = null;
|
||||
for (int startY=0; startY < height; startY++) {
|
||||
// Grab one scanline at a time
|
||||
dData =
|
||||
srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
|
||||
dData);
|
||||
setPixels(dstOffX, dstOffY+startY, width, 1, dData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using an int array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param iArray The input samples in a int array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, int iArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a float array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param fArray The input samples in a float array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, float fArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a pixel in the DataBuffer using a double array of samples for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param dArray The input samples in a double array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixel(int x, int y, double dArray[]) {
|
||||
sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from an int array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 iArray The input int pixel array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if iArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, int iArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a float array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 fArray The input float pixel array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if fArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, float fArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all samples for a rectangle of pixels from a double array containing
|
||||
* one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 dArray The input double pixel array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates are not
|
||||
* in bounds, or if dArray is too small to hold the input.
|
||||
*/
|
||||
public void setPixels(int x, int y, int w, int h, double dArray[]) {
|
||||
sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,dArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using an int for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, int s) {
|
||||
sampleModel.setSample(x-sampleModelTranslateX,
|
||||
y-sampleModelTranslateY, b, s,
|
||||
dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a float for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a float.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, float s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a sample in the specified band for the pixel located at (x,y)
|
||||
* in the DataBuffer using a double for input.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @param x The X coordinate of the pixel location.
|
||||
* @param y The Y coordinate of the pixel location.
|
||||
* @param b The band to set.
|
||||
* @param s The input sample as a double.
|
||||
*
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds.
|
||||
*/
|
||||
public void setSample(int x, int y, int b, double s){
|
||||
sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
b,s,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from an int array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 b The band to set.
|
||||
* @param iArray The input int sample array.
|
||||
*
|
||||
* @throws NullPointerException if iArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if iArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
int iArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,iArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a float array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 b The band to set.
|
||||
* @param fArray The input float sample array.
|
||||
*
|
||||
* @throws NullPointerException if fArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if fArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
float fArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,fArray,dataBuffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the samples in the specified band for the specified rectangle
|
||||
* of pixels from a double array containing one sample per array element.
|
||||
* An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
|
||||
* not in bounds.
|
||||
* However, explicit bounds checking is not guaranteed.
|
||||
* @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 b The band to set.
|
||||
* @param dArray The input double sample array.
|
||||
*
|
||||
* @throws NullPointerException if dArray is null.
|
||||
* @throws ArrayIndexOutOfBoundsException if the coordinates or
|
||||
* the band index are not in bounds, or if dArray is too small to
|
||||
* hold the input.
|
||||
*/
|
||||
public void setSamples(int x, int y, int w, int h, int b,
|
||||
double dArray[]) {
|
||||
sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
|
||||
w,h,b,dArray,dataBuffer);
|
||||
}
|
||||
|
||||
}
|
151
jdk/src/share/classes/java/awt/image/WritableRenderedImage.java
Normal file
151
jdk/src/share/classes/java/awt/image/WritableRenderedImage.java
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Portions Copyright 1997-2000 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.
|
||||
*/
|
||||
|
||||
/* ****************************************************************
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997
|
||||
*** As an unpublished work pursuant to Title 17 of the United
|
||||
*** States Code. All rights reserved.
|
||||
******************************************************************
|
||||
******************************************************************
|
||||
******************************************************************/
|
||||
|
||||
package java.awt.image;
|
||||
import java.awt.Point;
|
||||
|
||||
/**
|
||||
* WriteableRenderedImage is a common interface for objects which
|
||||
* contain or can produce image data in the form of Rasters and
|
||||
* which can be modified and/or written over. The image
|
||||
* data may be stored/produced as a single tile or a regular array
|
||||
* of tiles.
|
||||
* <p>
|
||||
* WritableRenderedImage provides notification to other interested
|
||||
* objects when a tile is checked out for writing (via the
|
||||
* getWritableTile method) and when the last writer of a particular
|
||||
* tile relinquishes its access (via a call to releaseWritableTile).
|
||||
* Additionally, it allows any caller to determine whether any tiles
|
||||
* are currently checked out (via hasTileWriters), and to obtain a
|
||||
* list of such tiles (via getWritableTileIndices, in the form of a Vector
|
||||
* of Point objects).
|
||||
* <p>
|
||||
* Objects wishing to be notified of changes in tile writability must
|
||||
* implement the TileObserver interface, and are added by a
|
||||
* call to addTileObserver. Multiple calls to
|
||||
* addTileObserver for the same object will result in multiple
|
||||
* notifications. An existing observer may reduce its notifications
|
||||
* by calling removeTileObserver; if the observer had no
|
||||
* notifications the operation is a no-op.
|
||||
* <p>
|
||||
* It is necessary for a WritableRenderedImage to ensure that
|
||||
* notifications occur only when the first writer acquires a tile and
|
||||
* the last writer releases it.
|
||||
*
|
||||
*/
|
||||
|
||||
public interface WritableRenderedImage extends RenderedImage
|
||||
{
|
||||
|
||||
/**
|
||||
* Adds an observer. If the observer is already present,
|
||||
* it will receive multiple notifications.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void addTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Removes an observer. If the observer was not registered,
|
||||
* nothing happens. If the observer was registered for multiple
|
||||
* notifications, it will now be registered for one fewer.
|
||||
* @param to the specified <code>TileObserver</code>
|
||||
*/
|
||||
public void removeTileObserver(TileObserver to);
|
||||
|
||||
/**
|
||||
* Checks out a tile for writing.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all
|
||||
* of its TileObservers when a tile goes from having
|
||||
* no writers to having one writer.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return a writable tile.
|
||||
*/
|
||||
public WritableRaster getWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Relinquishes the right to write to a tile. If the caller
|
||||
* continues to write to the tile, the results are undefined.
|
||||
* Calls to this method should only appear in matching pairs
|
||||
* with calls to getWritableTile; any other use will lead
|
||||
* to undefined results.
|
||||
*
|
||||
* The WritableRenderedImage is responsible for notifying all of
|
||||
* its TileObservers when a tile goes from having one writer
|
||||
* to having no writers.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
*/
|
||||
public void releaseWritableTile(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns whether a tile is currently checked out for writing.
|
||||
*
|
||||
* @param tileX the X index of the tile.
|
||||
* @param tileY the Y index of the tile.
|
||||
* @return <code>true</code> if specified tile is checked out
|
||||
* for writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isTileWritable(int tileX, int tileY);
|
||||
|
||||
/**
|
||||
* Returns an array of Point objects indicating which tiles
|
||||
* are checked out for writing. Returns null if none are
|
||||
* checked out.
|
||||
* @return an array containing the locations of tiles that are
|
||||
* checked out for writing.
|
||||
*/
|
||||
public Point[] getWritableTileIndices();
|
||||
|
||||
/**
|
||||
* Returns whether any tile is checked out for writing.
|
||||
* Semantically equivalent to (getWritableTileIndices() != null).
|
||||
* @return <code>true</code> if any tiles are checked out for
|
||||
* writing; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasTileWriters();
|
||||
|
||||
/**
|
||||
* Sets a rect of the image to the contents of the Raster r, which is
|
||||
* assumed to be in the same coordinate space as the WritableRenderedImage.
|
||||
* The operation is clipped to the bounds of the WritableRenderedImage.
|
||||
* @param r the specified <code>Raster</code>
|
||||
*/
|
||||
public void setData(Raster r);
|
||||
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
|
||||
/**
|
||||
* ContextualRenderedImageFactory provides an interface for the
|
||||
* functionality that may differ between instances of
|
||||
* RenderableImageOp. Thus different operations on RenderableImages
|
||||
* may be performed by a single class such as RenderedImageOp through
|
||||
* the use of multiple instances of ContextualRenderedImageFactory.
|
||||
* The name ContextualRenderedImageFactory is commonly shortened to
|
||||
* "CRIF."
|
||||
*
|
||||
* <p> All operations that are to be used in a rendering-independent
|
||||
* chain must implement ContextualRenderedImageFactory.
|
||||
*
|
||||
* <p> Classes that implement this interface must provide a
|
||||
* constructor with no arguments.
|
||||
*/
|
||||
public interface ContextualRenderedImageFactory extends RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Maps the operation's output RenderContext into a RenderContext
|
||||
* for each of the operation's sources. This is useful for
|
||||
* operations that can be expressed in whole or in part simply as
|
||||
* alterations in the RenderContext, such as an affine mapping, or
|
||||
* operations that wish to obtain lower quality renderings of
|
||||
* their sources in order to save processing effort or
|
||||
* transmission bandwith. Some operations, such as blur, can also
|
||||
* use this mechanism to avoid obtaining sources of higher quality
|
||||
* than necessary.
|
||||
*
|
||||
* @param i the index of the source image.
|
||||
* @param renderContext the RenderContext being applied to the operation.
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param image the RenderableImage being rendered.
|
||||
* @return a <code>RenderContext</code> for
|
||||
* the source at the specified index of the parameters
|
||||
* Vector contained in the specified ParameterBlock.
|
||||
*/
|
||||
RenderContext mapRenderContext(int i,
|
||||
RenderContext renderContext,
|
||||
ParameterBlock paramBlock,
|
||||
RenderableImage image);
|
||||
|
||||
/**
|
||||
* Creates a rendering, given a RenderContext and a ParameterBlock
|
||||
* containing the operation's sources and parameters. The output
|
||||
* is a RenderedImage that takes the RenderContext into account to
|
||||
* determine its dimensions and placement on the image plane.
|
||||
* This method houses the "intelligence" that allows a
|
||||
* rendering-independent operation to adapt to a specific
|
||||
* RenderContext.
|
||||
*
|
||||
* @param renderContext The RenderContext specifying the rendering
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters
|
||||
* @return a <code>RenderedImage</code> from the sources and parameters
|
||||
* in the specified ParameterBlock and according to the
|
||||
* rendering instructions in the specified RenderContext.
|
||||
*/
|
||||
RenderedImage create(RenderContext renderContext,
|
||||
ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Returns the bounding box for the output of the operation,
|
||||
* performed on a given set of sources, in rendering-independent
|
||||
* space. The bounds are returned as a Rectangle2D, that is, an
|
||||
* axis-aligned rectangle with floating-point corner coordinates.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @return a Rectangle2D specifying the rendering-independent
|
||||
* bounding box of the output.
|
||||
*/
|
||||
Rectangle2D getBounds2D(ParameterBlock paramBlock);
|
||||
|
||||
/**
|
||||
* Gets the appropriate instance of the property specified by the name
|
||||
* parameter. This method must determine which instance of a property to
|
||||
* return when there are multiple sources that each specify the property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing the operation's
|
||||
* sources and parameters.
|
||||
* @param name a String naming the desired property.
|
||||
* @return an object reference to the value of the property requested.
|
||||
*/
|
||||
Object getProperty(ParameterBlock paramBlock, String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return the list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* create(RenderContext, ParameterBlock)) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
}
|
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderContext encapsulates the information needed to produce a
|
||||
* specific rendering from a RenderableImage. It contains the area to
|
||||
* be rendered specified in rendering-independent terms, the
|
||||
* resolution at which the rendering is to be performed, and hints
|
||||
* used to control the rendering process.
|
||||
*
|
||||
* <p> Users create RenderContexts and pass them to the
|
||||
* RenderableImage via the createRendering method. Most of the methods of
|
||||
* RenderContexts are not meant to be used directly by applications,
|
||||
* but by the RenderableImage and operator classes to which it is
|
||||
* passed.
|
||||
*
|
||||
* <p> The AffineTransform parameter passed into and out of this class
|
||||
* are cloned. The RenderingHints and Shape parameters are not
|
||||
* necessarily cloneable and are therefore only reference copied.
|
||||
* Altering RenderingHints or Shape instances that are in use by
|
||||
* instances of RenderContext may have undesired side effects.
|
||||
*/
|
||||
public class RenderContext implements Cloneable {
|
||||
|
||||
/** Table of hints. May be null. */
|
||||
RenderingHints hints;
|
||||
|
||||
/** Transform to convert user coordinates to device coordinates. */
|
||||
AffineTransform usr2dev;
|
||||
|
||||
/** The area of interest. May be null. */
|
||||
Shape aoi;
|
||||
|
||||
// Various constructors that allow different levels of
|
||||
// specificity. If the Shape is missing the whole renderable area
|
||||
// is assumed. If hints is missing no hints are assumed.
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is supplied as a Shape,
|
||||
* and the rendering hints are supplied as a RenderingHints object.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev,
|
||||
Shape aoi,
|
||||
RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
this.aoi = aoi;
|
||||
this.usr2dev = (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev) {
|
||||
this(usr2dev, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and rendering hints.
|
||||
* The area of interest is taken to be the entire renderable area.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param hints a RenderingHints object containing rendering hints.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
|
||||
this(usr2dev, null, hints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a RenderContext with a given transform and area of interest.
|
||||
* The area of interest is supplied as a Shape.
|
||||
* No rendering hints are used.
|
||||
*
|
||||
* @param usr2dev an AffineTransform.
|
||||
* @param aoi a Shape representing the area of interest.
|
||||
*/
|
||||
public RenderContext(AffineTransform usr2dev, Shape aoi) {
|
||||
this(usr2dev, aoi, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rendering hints of this <code>RenderContext</code>.
|
||||
* @return a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints of this <code>RenderContext</code>.
|
||||
* @see #setRenderingHints(RenderingHints)
|
||||
*/
|
||||
public RenderingHints getRenderingHints() {
|
||||
return hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rendering hints of this <code>RenderContext</code>.
|
||||
* @param hints a <code>RenderingHints</code> object that represents
|
||||
* the rendering hints to assign to this <code>RenderContext</code>.
|
||||
* @see #getRenderingHints
|
||||
*/
|
||||
public void setRenderingHints(RenderingHints hints) {
|
||||
this.hints = hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current user-to-device AffineTransform contained
|
||||
* in the RenderContext to a given transform.
|
||||
*
|
||||
* @param newTransform the new AffineTransform.
|
||||
* @see #getTransform
|
||||
*/
|
||||
public void setTransform(AffineTransform newTransform) {
|
||||
usr2dev = (AffineTransform)newTransform.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void preConcatenateTransform(AffineTransform modTransform) {
|
||||
this.preConcetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by prepending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [modTransform] x [this]
|
||||
* </pre>
|
||||
* This method does the same thing as the preConcatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to prepend to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>preConcatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void preConcetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.preConcatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @since 1.3
|
||||
*/
|
||||
public void concatenateTransform(AffineTransform modTransform) {
|
||||
this.concetenateTransform(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current user-to-device transform by appending another
|
||||
* transform. In matrix notation the operation is:
|
||||
* <pre>
|
||||
* [this] = [this] x [modTransform]
|
||||
* </pre>
|
||||
* This method does the same thing as the concatenateTransform
|
||||
* method. It is here for backward compatibility with previous releases
|
||||
* which misspelled the method name.
|
||||
*
|
||||
* @param modTransform the AffineTransform to append to the
|
||||
* current usr2dev transform.
|
||||
* @deprecated replaced by
|
||||
* <code>concatenateTransform(AffineTransform)</code>.
|
||||
*/
|
||||
@Deprecated
|
||||
public void concetenateTransform(AffineTransform modTransform) {
|
||||
usr2dev.concatenate(modTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current user-to-device AffineTransform.
|
||||
*
|
||||
* @return a reference to the current AffineTransform.
|
||||
* @see #setTransform(AffineTransform)
|
||||
*/
|
||||
public AffineTransform getTransform() {
|
||||
return (AffineTransform)usr2dev.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current area of interest. The old area is discarded.
|
||||
*
|
||||
* @param newAoi The new area of interest.
|
||||
* @see #getAreaOfInterest
|
||||
*/
|
||||
public void setAreaOfInterest(Shape newAoi) {
|
||||
aoi = newAoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ares of interest currently contained in the
|
||||
* RenderContext.
|
||||
*
|
||||
* @return a reference to the area of interest of the RenderContext,
|
||||
* or null if none is specified.
|
||||
* @see #setAreaOfInterest(Shape)
|
||||
*/
|
||||
public Shape getAreaOfInterest() {
|
||||
return aoi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a copy of a RenderContext. The area of interest is copied
|
||||
* by reference. The usr2dev AffineTransform and hints are cloned,
|
||||
* while the area of interest is copied by reference.
|
||||
*
|
||||
* @return the new cloned RenderContext.
|
||||
*/
|
||||
public Object clone() {
|
||||
RenderContext newRenderContext = new RenderContext(usr2dev,
|
||||
aoi, hints);
|
||||
return newRenderContext;
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.util.Vector;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* A RenderableImage is a common interface for rendering-independent
|
||||
* images (a notion which subsumes resolution independence). That is,
|
||||
* images which are described and have operations applied to them
|
||||
* independent of any specific rendering of the image. For example, a
|
||||
* RenderableImage can be rotated and cropped in
|
||||
* resolution-independent terms. Then, it can be rendered for various
|
||||
* specific contexts, such as a draft preview, a high-quality screen
|
||||
* display, or a printer, each in an optimal fashion.
|
||||
*
|
||||
* <p> A RenderedImage is returned from a RenderableImage via the
|
||||
* createRendering() method, which takes a RenderContext. The
|
||||
* RenderContext specifies how the RenderedImage should be
|
||||
* constructed. Note that it is not possible to extract pixels
|
||||
* directly from a RenderableImage.
|
||||
*
|
||||
* <p> The createDefaultRendering() and createScaledRendering() methods are
|
||||
* convenience methods that construct an appropriate RenderContext
|
||||
* internally. All of the rendering methods may return a reference to a
|
||||
* previously produced rendering.
|
||||
*/
|
||||
public interface RenderableImage {
|
||||
|
||||
/**
|
||||
* String constant that can be used to identify a property on
|
||||
* a RenderedImage obtained via the createRendering or
|
||||
* createScaledRendering methods. If such a property exists,
|
||||
* the value of the propoery will be a RenderingHints object
|
||||
* specifying which hints were observed in creating the rendering.
|
||||
*/
|
||||
static final String HINTS_OBSERVED = "HINTS_OBSERVED";
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
Vector<RenderableImage> getSources();
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
Object getProperty(String name);
|
||||
|
||||
/**
|
||||
* Returns a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
String[] getPropertyNames();
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. It is always safe to return true.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isDynamic();
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
float getWidth();
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
float getHeight();
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
* @return the minimum X coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinX();
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
* @return the minimum Y coordinate of the rendering-independent image
|
||||
* data.
|
||||
*/
|
||||
float getMinY();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containg hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
|
||||
|
||||
/**
|
||||
* Returnd a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. The rendering hints are
|
||||
* empty. createDefaultRendering may make use of a stored
|
||||
* rendering for speed.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createDefaultRendering();
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage that represented a rendering of this image
|
||||
* using a given RenderContext. This is the most general way to obtain a
|
||||
* rendering of a RenderableImage.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext the RenderContext to use to produce the rendering.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
RenderedImage createRendering(RenderContext renderContext);
|
||||
}
|
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Portions Copyright 1998-2000 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* This class handles the renderable aspects of an operation with help
|
||||
* from its associated instance of a ContextualRenderedImageFactory.
|
||||
*/
|
||||
public class RenderableImageOp implements RenderableImage {
|
||||
|
||||
/** A ParameterBlock containing source and parameters. */
|
||||
ParameterBlock paramBlock;
|
||||
|
||||
/** The associated ContextualRenderedImageFactory. */
|
||||
ContextualRenderedImageFactory myCRIF;
|
||||
|
||||
/** The bounding box of the results of this RenderableImageOp. */
|
||||
Rectangle2D boundingBox;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a RenderedImageOp given a
|
||||
* ContextualRenderedImageFactory object, and
|
||||
* a ParameterBlock containing RenderableImage sources and other
|
||||
* parameters. Any RenderedImage sources referenced by the
|
||||
* ParameterBlock will be ignored.
|
||||
*
|
||||
* @param CRIF a ContextualRenderedImageFactory object
|
||||
* @param paramBlock a ParameterBlock containing this operation's source
|
||||
* images and other parameters necessary for the operation
|
||||
* to run.
|
||||
*/
|
||||
public RenderableImageOp(ContextualRenderedImageFactory CRIF,
|
||||
ParameterBlock paramBlock) {
|
||||
this.myCRIF = CRIF;
|
||||
this.paramBlock = (ParameterBlock) paramBlock.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector of RenderableImages that are the sources of
|
||||
* image data for this RenderableImage. Note that this method may
|
||||
* return an empty vector, to indicate that the image has no sources,
|
||||
* or null, to indicate that no information is available.
|
||||
*
|
||||
* @return a (possibly empty) Vector of RenderableImages, or null.
|
||||
*/
|
||||
public Vector<RenderableImage> getSources() {
|
||||
return getRenderableSources();
|
||||
}
|
||||
|
||||
private Vector getRenderableSources() {
|
||||
Vector sources = null;
|
||||
|
||||
if (paramBlock.getNumSources() > 0) {
|
||||
sources = new Vector();
|
||||
int i = 0;
|
||||
while (i < paramBlock.getNumSources()) {
|
||||
Object o = paramBlock.getSource(i);
|
||||
if (o instanceof RenderableImage) {
|
||||
sources.add((RenderableImage)o);
|
||||
i++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a property from the property set of this image.
|
||||
* If the property name is not recognized, java.awt.Image.UndefinedProperty
|
||||
* will be returned.
|
||||
*
|
||||
* @param name the name of the property to get, as a String.
|
||||
* @return a reference to the property Object, or the value
|
||||
* java.awt.Image.UndefinedProperty.
|
||||
*/
|
||||
public Object getProperty(String name) {
|
||||
return myCRIF.getProperty(paramBlock, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of names recognized by getProperty.
|
||||
* @return a list of property names.
|
||||
*/
|
||||
public String[] getPropertyNames() {
|
||||
return myCRIF.getPropertyNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if successive renderings (that is, calls to
|
||||
* createRendering() or createScaledRendering()) with the same arguments
|
||||
* may produce different results. This method may be used to
|
||||
* determine whether an existing rendering may be cached and
|
||||
* reused. The CRIF's isDynamic method will be called.
|
||||
* @return <code>true</code> if successive renderings with the
|
||||
* same arguments might produce different results;
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return myCRIF.isDynamic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width in user coordinate space. By convention, the
|
||||
* usual width of a RenderableImage is equal to the image's aspect
|
||||
* ratio (width divided by height).
|
||||
*
|
||||
* @return the width of the image in user coordinates.
|
||||
*/
|
||||
public float getWidth() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height in user coordinate space. By convention, the
|
||||
* usual height of a RenderedImage is equal to 1.0F.
|
||||
*
|
||||
* @return the height of the image in user coordinates.
|
||||
*/
|
||||
public float getHeight() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum X coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinX() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum Y coordinate of the rendering-independent image data.
|
||||
*/
|
||||
public float getMinY() {
|
||||
if (boundingBox == null) {
|
||||
boundingBox = myCRIF.getBounds2D(paramBlock);
|
||||
}
|
||||
return (float)boundingBox.getMinY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the current ParameterBlock of the operation, allowing
|
||||
* editing of image rendering chains. The effects of such a
|
||||
* change will be visible when a new rendering is created from
|
||||
* this RenderableImageOp or any dependent RenderableImageOp.
|
||||
*
|
||||
* @param paramBlock the new ParameterBlock.
|
||||
* @return the old ParameterBlock.
|
||||
* @see #getParameterBlock
|
||||
*/
|
||||
public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
|
||||
ParameterBlock oldParamBlock = this.paramBlock;
|
||||
this.paramBlock = (ParameterBlock)paramBlock.clone();
|
||||
return oldParamBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the current parameter block.
|
||||
* @return the <code>ParameterBlock</code> of this
|
||||
* <code>RenderableImageOp</code>.
|
||||
* @see #setParameterBlock(ParameterBlock)
|
||||
*/
|
||||
public ParameterBlock getParameterBlock() {
|
||||
return paramBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage instance of this image with width w, and
|
||||
* height h in pixels. The RenderContext is built automatically
|
||||
* with an appropriate usr2dev transform and an area of interest
|
||||
* of the full image. All the rendering hints come from hints
|
||||
* passed in.
|
||||
*
|
||||
* <p> If w == 0, it will be taken to equal
|
||||
* Math.round(h*(getWidth()/getHeight())).
|
||||
* Similarly, if h == 0, it will be taken to equal
|
||||
* Math.round(w*(getHeight()/getWidth())). One of
|
||||
* w or h must be non-zero or else an IllegalArgumentException
|
||||
* will be thrown.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param w the width of rendered image in pixels, or 0.
|
||||
* @param h the height of rendered image in pixels, or 0.
|
||||
* @param hints a RenderingHints object containg hints.
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createScaledRendering(int w, int h,
|
||||
RenderingHints hints) {
|
||||
// DSR -- code to try to get a unit scale
|
||||
double sx = (double)w/getWidth();
|
||||
double sy = (double)h/getHeight();
|
||||
if (Math.abs(sx/sy - 1.0) < 0.01) {
|
||||
sx = sy;
|
||||
}
|
||||
AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
|
||||
RenderContext newRC = new RenderContext(usr2dev, hints);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a RenderedImage instance of this image with a default
|
||||
* width and height in pixels. The RenderContext is built
|
||||
* automatically with an appropriate usr2dev transform and an area
|
||||
* of interest of the full image. All the rendering hints come
|
||||
* from hints passed in. Implementors of this interface must be
|
||||
* sure that there is a defined default width and height.
|
||||
*
|
||||
* @return a RenderedImage containing the rendered data.
|
||||
*/
|
||||
public RenderedImage createDefaultRendering() {
|
||||
AffineTransform usr2dev = new AffineTransform(); // Identity
|
||||
RenderContext newRC = new RenderContext(usr2dev);
|
||||
return createRendering(newRC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage which represents this
|
||||
* RenderableImageOp (including its Renderable sources) rendered
|
||||
* according to the given RenderContext.
|
||||
*
|
||||
* <p> This method supports chaining of either Renderable or
|
||||
* RenderedImage operations. If sources in
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* RenderableImages, then a three step process is followed:
|
||||
*
|
||||
* <ol>
|
||||
* <li> mapRenderContext() is called on the associated CRIF for
|
||||
* each RenderableImage source;
|
||||
* <li> createRendering() is called on each of the RenderableImage sources
|
||||
* using the backwards-mapped RenderContexts obtained in step 1,
|
||||
* resulting in a rendering of each source;
|
||||
* <li> ContextualRenderedImageFactory.create() is called
|
||||
* with a new ParameterBlock containing the parameters of
|
||||
* the RenderableImageOp and the RenderedImages that were created by the
|
||||
* createRendering() calls.
|
||||
* </ol>
|
||||
*
|
||||
* <p> If the elements of the source Vector of
|
||||
* the ParameterBlock used to construct the RenderableImageOp are
|
||||
* instances of RenderedImage, then the CRIF.create() method is
|
||||
* called immediately using the original ParameterBlock.
|
||||
* This provides a basis case for the recursion.
|
||||
*
|
||||
* <p> The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* (from the RenderContext) were used to create the image.
|
||||
* In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param renderContext The RenderContext to use to perform the rendering.
|
||||
* @return a RenderedImage containing the desired output image.
|
||||
*/
|
||||
public RenderedImage createRendering(RenderContext renderContext) {
|
||||
RenderedImage image = null;
|
||||
RenderContext rcOut = null;
|
||||
|
||||
// Clone the original ParameterBlock; if the ParameterBlock
|
||||
// contains RenderableImage sources, they will be replaced by
|
||||
// RenderedImages.
|
||||
ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
|
||||
Vector sources = getRenderableSources();
|
||||
|
||||
try {
|
||||
// This assumes that if there is no renderable source, that there
|
||||
// is a rendered source in paramBlock
|
||||
|
||||
if (sources != null) {
|
||||
Vector renderedSources = new Vector();
|
||||
for (int i = 0; i < sources.size(); i++) {
|
||||
rcOut = myCRIF.mapRenderContext(i, renderContext,
|
||||
paramBlock, this);
|
||||
RenderedImage rdrdImage =
|
||||
((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
|
||||
if (rdrdImage == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add this rendered image to the ParameterBlock's
|
||||
// list of RenderedImages.
|
||||
renderedSources.addElement(rdrdImage);
|
||||
}
|
||||
|
||||
if (renderedSources.size() > 0) {
|
||||
renderedParamBlock.setSources(renderedSources);
|
||||
}
|
||||
}
|
||||
|
||||
return myCRIF.create(renderContext, renderedParamBlock);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
// This should never happen
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Portions Copyright 1998 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.ImageConsumer;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* An adapter class that implements ImageProducer to allow the
|
||||
* asynchronous production of a RenderableImage. The size of the
|
||||
* ImageConsumer is determined by the scale factor of the usr2dev
|
||||
* transform in the RenderContext. If the RenderContext is null, the
|
||||
* default rendering of the RenderableImage is used. This class
|
||||
* implements an asynchronous production that produces the image in
|
||||
* one thread at one resolution. This class may be subclassed to
|
||||
* implement versions that will render the image using several
|
||||
* threads. These threads could render either the same image at
|
||||
* progressively better quality, or different sections of the image at
|
||||
* a single resolution.
|
||||
*/
|
||||
public class RenderableImageProducer implements ImageProducer, Runnable {
|
||||
|
||||
/** The RenderableImage source for the producer. */
|
||||
RenderableImage rdblImage;
|
||||
|
||||
/** The RenderContext to use for producing the image. */
|
||||
RenderContext rc;
|
||||
|
||||
/** A Vector of image consumers. */
|
||||
Vector ics = new Vector();
|
||||
|
||||
/**
|
||||
* Constructs a new RenderableImageProducer from a RenderableImage
|
||||
* and a RenderContext.
|
||||
*
|
||||
* @param rdblImage the RenderableImage to be rendered.
|
||||
* @param rc the RenderContext to use for producing the pixels.
|
||||
*/
|
||||
public RenderableImageProducer(RenderableImage rdblImage,
|
||||
RenderContext rc) {
|
||||
this.rdblImage = rdblImage;
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new RenderContext to use for the next startProduction() call.
|
||||
*
|
||||
* @param rc the new RenderContext.
|
||||
*/
|
||||
public synchronized void setRenderContext(RenderContext rc) {
|
||||
this.rc = rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic an ImageConsumer to be added to the interest list.
|
||||
*/
|
||||
public synchronized void addConsumer(ImageConsumer ic) {
|
||||
if (!ics.contains(ic)) {
|
||||
ics.addElement(ic);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if an ImageConsumer is on the list of consumers
|
||||
* currently interested in data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be checked.
|
||||
* @return true if the ImageConsumer is on the list; false otherwise.
|
||||
*/
|
||||
public synchronized boolean isConsumer(ImageConsumer ic) {
|
||||
return ics.contains(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an ImageConsumer from the list of consumers interested in
|
||||
* data for this image.
|
||||
*
|
||||
* @param ic the ImageConsumer to be removed.
|
||||
*/
|
||||
public synchronized void removeConsumer(ImageConsumer ic) {
|
||||
ics.removeElement(ic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an ImageConsumer to the list of consumers interested in
|
||||
* data for this image, and immediately starts delivery of the
|
||||
* image data through the ImageConsumer interface.
|
||||
*
|
||||
* @param ic the ImageConsumer to be added to the list of consumers.
|
||||
*/
|
||||
public synchronized void startProduction(ImageConsumer ic) {
|
||||
addConsumer(ic);
|
||||
// Need to build a runnable object for the Thread.
|
||||
Thread thread = new Thread(this, "RenderableImageProducer Thread");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests that a given ImageConsumer have the image data delivered
|
||||
* one more time in top-down, left-right order.
|
||||
*
|
||||
* @param ic the ImageConsumer requesting the resend.
|
||||
*/
|
||||
public void requestTopDownLeftRightResend(ImageConsumer ic) {
|
||||
// So far, all pixels are already sent in TDLR order
|
||||
}
|
||||
|
||||
/**
|
||||
* The runnable method for this class. This will produce an image using
|
||||
* the current RenderableImage and RenderContext and send it to all the
|
||||
* ImageConsumer currently registered with this class.
|
||||
*/
|
||||
public void run() {
|
||||
// First get the rendered image
|
||||
RenderedImage rdrdImage;
|
||||
if (rc != null) {
|
||||
rdrdImage = rdblImage.createRendering(rc);
|
||||
} else {
|
||||
rdrdImage = rdblImage.createDefaultRendering();
|
||||
}
|
||||
|
||||
// And its ColorModel
|
||||
ColorModel colorModel = rdrdImage.getColorModel();
|
||||
Raster raster = rdrdImage.getData();
|
||||
SampleModel sampleModel = raster.getSampleModel();
|
||||
DataBuffer dataBuffer = raster.getDataBuffer();
|
||||
|
||||
if (colorModel == null) {
|
||||
colorModel = ColorModel.getRGBdefault();
|
||||
}
|
||||
int minX = raster.getMinX();
|
||||
int minY = raster.getMinY();
|
||||
int width = raster.getWidth();
|
||||
int height = raster.getHeight();
|
||||
|
||||
Enumeration icList;
|
||||
ImageConsumer ic;
|
||||
// Set up the ImageConsumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setDimensions(width,height);
|
||||
ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
|
||||
ImageConsumer.COMPLETESCANLINES |
|
||||
ImageConsumer.SINGLEPASS |
|
||||
ImageConsumer.SINGLEFRAME);
|
||||
}
|
||||
|
||||
// Get RGB pixels from the raster scanline by scanline and
|
||||
// send to consumers.
|
||||
int pix[] = new int[width];
|
||||
int i,j;
|
||||
int numBands = sampleModel.getNumBands();
|
||||
int tmpPixel[] = new int[numBands];
|
||||
for (j = 0; j < height; j++) {
|
||||
for(i = 0; i < width; i++) {
|
||||
sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
|
||||
pix[i] = colorModel.getDataElement(tmpPixel, 0);
|
||||
}
|
||||
// Now send the scanline to the Consumers
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
|
||||
}
|
||||
}
|
||||
|
||||
// Now tell the consumers we're done.
|
||||
icList = ics.elements();
|
||||
while (icList.hasMoreElements()) {
|
||||
ic = (ImageConsumer)icList.nextElement();
|
||||
ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Portions Copyright 1998 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.
|
||||
*/
|
||||
|
||||
/* ********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
*** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
|
||||
*** As an unpublished work pursuant to Title 17 of the United ***
|
||||
*** States Code. All rights reserved. ***
|
||||
**********************************************************************
|
||||
**********************************************************************
|
||||
**********************************************************************/
|
||||
|
||||
package java.awt.image.renderable;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
/**
|
||||
* The RenderedImageFactory interface (often abbreviated RIF) is
|
||||
* intended to be implemented by classes that wish to act as factories
|
||||
* to produce different renderings, for example by executing a series
|
||||
* of BufferedImageOps on a set of sources, depending on a specific
|
||||
* set of parameters, properties, and rendering hints.
|
||||
*/
|
||||
public interface RenderedImageFactory {
|
||||
|
||||
/**
|
||||
* Creates a RenderedImage representing the results of an imaging
|
||||
* operation (or chain of operations) for a given ParameterBlock and
|
||||
* RenderingHints. The RIF may also query any source images
|
||||
* referenced by the ParameterBlock for their dimensions,
|
||||
* SampleModels, properties, etc., as necessary.
|
||||
*
|
||||
* <p> The create() method can return null if the
|
||||
* RenderedImageFactory is not capable of producing output for the
|
||||
* given set of source images and parameters. For example, if a
|
||||
* RenderedImageFactory is only capable of performing a 3x3
|
||||
* convolution on single-banded image data, and the source image has
|
||||
* multiple bands or the convolution Kernel is 5x5, null should be
|
||||
* returned.
|
||||
*
|
||||
* <p> Hints should be taken into account, but can be ignored.
|
||||
* The created RenderedImage may have a property identified
|
||||
* by the String HINTS_OBSERVED to indicate which RenderingHints
|
||||
* were used to create the image. In addition any RenderedImages
|
||||
* that are obtained via the getSources() method on the created
|
||||
* RenderedImage may have such a property.
|
||||
*
|
||||
* @param paramBlock a ParameterBlock containing sources and parameters
|
||||
* for the RenderedImage to be created.
|
||||
* @param hints a RenderingHints object containing hints.
|
||||
* @return A RenderedImage containing the desired output.
|
||||
*/
|
||||
RenderedImage create(ParameterBlock paramBlock,
|
||||
RenderingHints hints);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user