1.1 --- a/.hgtags Tue Jun 10 16:31:26 2008 -0700
1.2 +++ b/.hgtags Thu Jun 12 11:46:57 2008 -0700
1.3 @@ -2,3 +2,4 @@
1.4 75fca0b0ab83ab1392e615910cea020f66535390 jdk7-b25
1.5 fb57027902e04ecafceae31a605e69b436c23d57 jdk7-b26
1.6 3e599d98875ddf919c8ea11cff9b3a99ba631a9b jdk7-b27
1.7 +02e4c5348592a8d7fc2cba28bc5f8e35c0e17277 jdk7-b28
2.1 --- a/make/common/internal/BinaryPlugs.gmk Tue Jun 10 16:31:26 2008 -0700
2.2 +++ b/make/common/internal/BinaryPlugs.gmk Thu Jun 12 11:46:57 2008 -0700
2.3 @@ -126,44 +126,10 @@
2.4 com/sun/media/sound/SimpleInputDeviceProvider\$$InputDeviceInfo.class \
2.5 com/sun/media/sound/SimpleInputDeviceProvider.class
2.6
2.7 -PLUG_AWT_CLASS_NAMES = \
2.8 -java/awt/color/CMMException.class \
2.9 -java/awt/color/ColorSpace.class \
2.10 -java/awt/color/ICC_ColorSpace.class \
2.11 -java/awt/color/ICC_Profile\$$1.class \
2.12 -java/awt/color/ICC_Profile\$$2.class \
2.13 -java/awt/color/ICC_Profile\$$3.class \
2.14 -java/awt/color/ICC_Profile.class \
2.15 -java/awt/color/ICC_ProfileGray.class \
2.16 -java/awt/color/ICC_ProfileRGB.class \
2.17 -java/awt/image/BandedSampleModel.class \
2.18 -java/awt/image/ColorConvertOp.class \
2.19 -java/awt/image/ComponentSampleModel.class \
2.20 -java/awt/image/DataBuffer\$$1.class \
2.21 -java/awt/image/DataBuffer.class \
2.22 -java/awt/image/DataBufferByte.class \
2.23 -java/awt/image/DataBufferInt.class \
2.24 -java/awt/image/DataBufferShort.class \
2.25 -java/awt/image/DataBufferUShort.class \
2.26 -java/awt/image/MultiPixelPackedSampleModel.class \
2.27 -java/awt/image/Raster.class \
2.28 -java/awt/image/RenderedImage.class \
2.29 -java/awt/image/SampleModel.class \
2.30 -java/awt/image/SinglePixelPackedSampleModel.class \
2.31 -java/awt/image/WritableRaster.class \
2.32 -java/awt/image/WritableRenderedImage.class \
2.33 -java/awt/image/renderable/ContextualRenderedImageFactory.class \
2.34 -java/awt/image/renderable/ParameterBlock.class \
2.35 -java/awt/image/renderable/RenderContext.class \
2.36 -java/awt/image/renderable/RenderableImage.class \
2.37 -java/awt/image/renderable/RenderableImageOp.class \
2.38 -java/awt/image/renderable/RenderableImageProducer.class \
2.39 -java/awt/image/renderable/RenderedImageFactory.class
2.40 -
2.41 # Class list temp files (used by both import and export of plugs)
2.42
2.43 PLUG_TEMPDIR=$(ABS_TEMPDIR)/plugs
2.44 -PLUG_CLASS_AREAS = jmf sound awt
2.45 +PLUG_CLASS_AREAS = jmf sound
2.46 PLUG_CLISTS = $(PLUG_CLASS_AREAS:%=$(PLUG_TEMPDIR)/%.clist)
2.47
2.48 # Create jargs file command
2.49 @@ -186,11 +152,6 @@
2.50 @for i in $(PLUG_SOUND_CLASS_NAMES) ; do \
2.51 $(ECHO) "$$i" >> $@ ; \
2.52 done
2.53 -$(PLUG_TEMPDIR)/awt.clist:
2.54 - @$(prep-target)
2.55 - @for i in $(PLUG_AWT_CLASS_NAMES) ; do \
2.56 - $(ECHO) "$$i" >> $@ ; \
2.57 - done
2.58 $(PLUG_TEMPDIR)/all.clist: $(PLUG_CLISTS)
2.59 @$(prep-target)
2.60 $(CAT) $(PLUG_CLISTS) > $@
2.61 @@ -198,8 +159,6 @@
2.62 $(plug-create-jargs)
2.63 $(PLUG_TEMPDIR)/sound.jargs: $(PLUG_TEMPDIR)/sound.clist
2.64 $(plug-create-jargs)
2.65 -$(PLUG_TEMPDIR)/awt.jargs: $(PLUG_TEMPDIR)/awt.clist
2.66 - $(plug-create-jargs)
2.67 $(PLUG_TEMPDIR)/all.jargs: $(PLUG_TEMPDIR)/all.clist
2.68 $(plug-create-jargs)
2.69
2.70 @@ -235,15 +194,12 @@
2.71 $(call import-binary-plug-classes,$(PLUG_TEMPDIR)/jmf.clist)
2.72 import-binary-plug-sound-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/sound.clist
2.73 $(call import-binary-plug-classes,$(PLUG_TEMPDIR)/sound.clist)
2.74 -import-binary-plug-awt-classes: $(PLUG_IMPORT_JARFILE) $(PLUG_TEMPDIR)/awt.clist
2.75 - $(call import-binary-plug-classes,$(PLUG_TEMPDIR)/awt.clist)
2.76
2.77 # Import all classes from the jar file
2.78
2.79 import-binary-plug-jar: \
2.80 import-binary-plug-jmf-classes \
2.81 - import-binary-plug-sound-classes \
2.82 - import-binary-plug-awt-classes
2.83 + import-binary-plug-sound-classes
2.84
2.85 # Import native libraries
2.86
2.87 @@ -286,7 +242,6 @@
2.88 import-binary-plug-jar \
2.89 import-binary-plug-jmf-classes \
2.90 import-binary-plug-sound-classes \
2.91 - import-binary-plug-awt-classes \
2.92 import-binary-plug-jsound-library
2.93
2.94 else # !OPENJDK
3.1 --- a/make/java/awt/Makefile Tue Jun 10 16:31:26 2008 -0700
3.2 +++ b/make/java/awt/Makefile Thu Jun 12 11:46:57 2008 -0700
3.3 @@ -28,24 +28,12 @@
3.4 PRODUCT = sun
3.5 include $(BUILDDIR)/common/Defs.gmk
3.6
3.7 -# WARNING: Make sure the OPENJDK plugs are up-to-date, see make/common/internal/BinaryPlugs.gmk
3.8
3.9 #
3.10 # Files
3.11 #
3.12 AUTO_FILES_JAVA_DIRS = java/awt sun/awt/geom
3.13
3.14 -#
3.15 -# Specific to OPENJDK
3.16 -#
3.17 -ifdef OPENJDK
3.18 -
3.19 -build: import-binary-plug-awt-classes
3.20 -
3.21 -include $(BUILDDIR)/common/internal/BinaryPlugs.gmk
3.22 -
3.23 -endif
3.24 -
3.25 build: properties cursors
3.26
3.27 #
4.1 --- a/make/sun/cmm/Makefile Tue Jun 10 16:31:26 2008 -0700
4.2 +++ b/make/sun/cmm/Makefile Thu Jun 12 11:46:57 2008 -0700
4.3 @@ -41,12 +41,8 @@
4.4 ICCPROFILE_DEST_DIR = $(LIBDIR)/cmm
4.5
4.6 iccprofiles: $(ICCPROFILE_DEST_DIR)/sRGB.pf $(ICCPROFILE_DEST_DIR)/GRAY.pf \
4.7 - $(ICCPROFILE_DEST_DIR)/CIEXYZ.pf
4.8 -
4.9 -ifndef OPENJDK
4.10 -iccprofiles: $(ICCPROFILE_DEST_DIR)/PYCC.pf \
4.11 - $(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
4.12 -endif
4.13 + $(ICCPROFILE_DEST_DIR)/CIEXYZ.pf $(ICCPROFILE_DEST_DIR)/PYCC.pf \
4.14 + $(ICCPROFILE_DEST_DIR)/LINEAR_RGB.pf
4.15
4.16 $(ICCPROFILE_DEST_DIR)/sRGB.pf: $(ICCPROFILE_SRC_DIR)/sRGB.pf
4.17 $(RM) $(ICCPROFILE_DEST_DIR)/sRGB.pf
5.1 --- a/make/sun/font/FILES_c.gmk Tue Jun 10 16:31:26 2008 -0700
5.2 +++ b/make/sun/font/FILES_c.gmk Thu Jun 12 11:46:57 2008 -0700
5.3 @@ -113,7 +113,9 @@
5.4
5.5
5.6 ifeq ($(PLATFORM),windows)
5.7 -FILES_c_platform = fontpath.c
5.8 +FILES_c_platform = fontpath.c \
5.9 + lcdglyph.c
5.10 +
5.11 FILES_cpp_platform = D3DTextRenderer.cpp
5.12 else
5.13 FILES_c_platform = X11FontScaler.c \
6.1 --- a/make/sun/font/Makefile Tue Jun 10 16:31:26 2008 -0700
6.2 +++ b/make/sun/font/Makefile Thu Jun 12 11:46:57 2008 -0700
6.3 @@ -63,6 +63,7 @@
6.4 java/awt/Font.java \
6.5 java/text/Bidi.java \
6.6 sun/font/FileFont.java \
6.7 + sun/font/FileFontStrike.java \
6.8 sun/font/FontManager.java \
6.9 sun/font/GlyphList.java \
6.10 sun/font/NativeFont.java \
7.1 --- a/src/share/classes/java/awt/Component.java Tue Jun 10 16:31:26 2008 -0700
7.2 +++ b/src/share/classes/java/awt/Component.java Thu Jun 12 11:46:57 2008 -0700
7.3 @@ -3057,10 +3057,24 @@
7.4 // services. Additionally, the request is restricted to
7.5 // the bounds of the component.
7.6 if (parent != null) {
7.7 - int px = this.x + ((x < 0) ? 0 : x);
7.8 - int py = this.y + ((y < 0) ? 0 : y);
7.9 + if (x < 0) {
7.10 + width += x;
7.11 + x = 0;
7.12 + }
7.13 + if (y < 0) {
7.14 + height += y;
7.15 + y = 0;
7.16 + }
7.17 +
7.18 int pwidth = (width > this.width) ? this.width : width;
7.19 int pheight = (height > this.height) ? this.height : height;
7.20 +
7.21 + if (pwidth <= 0 || pheight <= 0) {
7.22 + return;
7.23 + }
7.24 +
7.25 + int px = this.x + x;
7.26 + int py = this.y + y;
7.27 parent.repaint(tm, px, py, pwidth, pheight);
7.28 }
7.29 } else {
8.1 --- a/src/share/classes/java/awt/Font.java Tue Jun 10 16:31:26 2008 -0700
8.2 +++ b/src/share/classes/java/awt/Font.java Thu Jun 12 11:46:57 2008 -0700
8.3 @@ -711,7 +711,7 @@
8.4 EBIDI_EMBEDDING, EJUSTIFICATION,
8.5 EINPUT_METHOD_HIGHLIGHT, EINPUT_METHOD_UNDERLINE,
8.6 ESWAP_COLORS, ENUMERIC_SHAPING, EKERNING,
8.7 - ELIGATURES, ETRACKING);
8.8 + ELIGATURES, ETRACKING, ESUPERSCRIPT);
8.9
8.10 private static final int EXTRA_MASK =
8.11 AttributeValues.getMask(ETRANSFORM, ESUPERSCRIPT, EWIDTH);
8.12 @@ -1970,7 +1970,6 @@
8.13 * in the JDK - and the only likely caller - is in this same class.
8.14 */
8.15 private float getItalicAngle(FontRenderContext frc) {
8.16 - AffineTransform at = (isTransformed()) ? getTransform() : identityTx;
8.17 Object aa, fm;
8.18 if (frc == null) {
8.19 aa = RenderingHints.VALUE_TEXT_ANTIALIAS_OFF;
8.20 @@ -1979,7 +1978,7 @@
8.21 aa = frc.getAntiAliasingHint();
8.22 fm = frc.getFractionalMetricsHint();
8.23 }
8.24 - return getFont2D().getItalicAngle(this, at, aa, fm);
8.25 + return getFont2D().getItalicAngle(this, identityTx, aa, fm);
8.26 }
8.27
8.28 /**
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/src/share/classes/java/awt/color/CMMException.java Thu Jun 12 11:46:57 2008 -0700
9.3 @@ -0,0 +1,57 @@
9.4 +/*
9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
9.6 + *
9.7 + * This code is free software; you can redistribute it and/or modify it
9.8 + * under the terms of the GNU General Public License version 2 only, as
9.9 + * published by the Free Software Foundation. Sun designates this
9.10 + * particular file as subject to the "Classpath" exception as provided
9.11 + * by Sun in the LICENSE file that accompanied this code.
9.12 + *
9.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
9.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9.16 + * version 2 for more details (a copy is included in the LICENSE file that
9.17 + * accompanied this code).
9.18 + *
9.19 + * You should have received a copy of the GNU General Public License version
9.20 + * 2 along with this work; if not, write to the Free Software Foundation,
9.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
9.22 + *
9.23 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
9.24 + * CA 95054 USA or visit www.sun.com if you need additional information or
9.25 + * have any questions.
9.26 + */
9.27 +
9.28 +/*
9.29 + Created by gbp, October 25, 1997
9.30 +
9.31 + *
9.32 + */
9.33 +/**********************************************************************
9.34 + **********************************************************************
9.35 + **********************************************************************
9.36 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
9.37 + *** As an unpublished work pursuant to Title 17 of the United ***
9.38 + *** States Code. All rights reserved. ***
9.39 + **********************************************************************
9.40 + **********************************************************************
9.41 + **********************************************************************/
9.42 +
9.43 +
9.44 +package java.awt.color;
9.45 +
9.46 +
9.47 +/**
9.48 + * This exception is thrown if the native CMM returns an error.
9.49 + */
9.50 +
9.51 +public class CMMException extends java.lang.RuntimeException {
9.52 +
9.53 + /**
9.54 + * Constructs a CMMException with the specified detail message.
9.55 + * @param s the specified detail message
9.56 + */
9.57 + public CMMException (String s) {
9.58 + super (s);
9.59 + }
9.60 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/src/share/classes/java/awt/color/ColorSpace.java Thu Jun 12 11:46:57 2008 -0700
10.3 @@ -0,0 +1,611 @@
10.4 +/*
10.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 + *
10.8 + * This code is free software; you can redistribute it and/or modify it
10.9 + * under the terms of the GNU General Public License version 2 only, as
10.10 + * published by the Free Software Foundation. Sun designates this
10.11 + * particular file as subject to the "Classpath" exception as provided
10.12 + * by Sun in the LICENSE file that accompanied this code.
10.13 + *
10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.17 + * version 2 for more details (a copy is included in the LICENSE file that
10.18 + * accompanied this code).
10.19 + *
10.20 + * You should have received a copy of the GNU General Public License version
10.21 + * 2 along with this work; if not, write to the Free Software Foundation,
10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.23 + *
10.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
10.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
10.26 + * have any questions.
10.27 + */
10.28 +
10.29 +/**********************************************************************
10.30 + **********************************************************************
10.31 + **********************************************************************
10.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
10.33 + *** As an unpublished work pursuant to Title 17 of the United ***
10.34 + *** States Code. All rights reserved. ***
10.35 + **********************************************************************
10.36 + **********************************************************************
10.37 + **********************************************************************/
10.38 +
10.39 +package java.awt.color;
10.40 +
10.41 +import sun.java2d.cmm.PCMM;
10.42 +import sun.java2d.cmm.CMSManager;
10.43 +
10.44 +
10.45 +/**
10.46 + * This abstract class is used to serve as a color space tag to identify the
10.47 + * specific color space of a Color object or, via a ColorModel object,
10.48 + * of an Image, a BufferedImage, or a GraphicsDevice. It contains
10.49 + * methods that transform colors in a specific color space to/from sRGB
10.50 + * and to/from a well-defined CIEXYZ color space.
10.51 + * <p>
10.52 + * For purposes of the methods in this class, colors are represented as
10.53 + * arrays of color components represented as floats in a normalized range
10.54 + * defined by each ColorSpace. For many ColorSpaces (e.g. sRGB), this
10.55 + * range is 0.0 to 1.0. However, some ColorSpaces have components whose
10.56 + * values have a different range. Methods are provided to inquire per
10.57 + * component minimum and maximum normalized values.
10.58 + * <p>
10.59 + * Several variables are defined for purposes of referring to color
10.60 + * space types (e.g. TYPE_RGB, TYPE_XYZ, etc.) and to refer to specific
10.61 + * color spaces (e.g. CS_sRGB and CS_CIEXYZ).
10.62 + * sRGB is a proposed standard RGB color space. For more information,
10.63 + * see <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
10.64 + * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
10.65 + * </A>.
10.66 + * <p>
10.67 + * The purpose of the methods to transform to/from the well-defined
10.68 + * CIEXYZ color space is to support conversions between any two color
10.69 + * spaces at a reasonably high degree of accuracy. It is expected that
10.70 + * particular implementations of subclasses of ColorSpace (e.g.
10.71 + * ICC_ColorSpace) will support high performance conversion based on
10.72 + * underlying platform color management systems.
10.73 + * <p>
10.74 + * The CS_CIEXYZ space used by the toCIEXYZ/fromCIEXYZ methods can be
10.75 + * described as follows:
10.76 +<pre>
10.77 +
10.78 + CIEXYZ
10.79 + viewing illuminance: 200 lux
10.80 + viewing white point: CIE D50
10.81 + media white point: "that of a perfectly reflecting diffuser" -- D50
10.82 + media black point: 0 lux or 0 Reflectance
10.83 + flare: 1 percent
10.84 + surround: 20percent of the media white point
10.85 + media description: reflection print (i.e., RLAB, Hunt viewing media)
10.86 + note: For developers creating an ICC profile for this conversion
10.87 + space, the following is applicable. Use a simple Von Kries
10.88 + white point adaptation folded into the 3X3 matrix parameters
10.89 + and fold the flare and surround effects into the three
10.90 + one-dimensional lookup tables (assuming one uses the minimal
10.91 + model for monitors).
10.92 +
10.93 +</pre>
10.94 + *
10.95 + * <p>
10.96 + * @see ICC_ColorSpace
10.97 + */
10.98 +
10.99 +
10.100 +
10.101 +public abstract class ColorSpace implements java.io.Serializable {
10.102 +
10.103 + static final long serialVersionUID = -409452704308689724L;
10.104 +
10.105 + private int type;
10.106 + private int numComponents;
10.107 + private transient String [] compName = null;
10.108 +
10.109 + // Cache of singletons for the predefined color spaces.
10.110 + private static ColorSpace sRGBspace;
10.111 + private static ColorSpace XYZspace;
10.112 + private static ColorSpace PYCCspace;
10.113 + private static ColorSpace GRAYspace;
10.114 + private static ColorSpace LINEAR_RGBspace;
10.115 +
10.116 + /**
10.117 + * Any of the family of XYZ color spaces.
10.118 + */
10.119 + public static final int TYPE_XYZ = 0;
10.120 +
10.121 + /**
10.122 + * Any of the family of Lab color spaces.
10.123 + */
10.124 + public static final int TYPE_Lab = 1;
10.125 +
10.126 + /**
10.127 + * Any of the family of Luv color spaces.
10.128 + */
10.129 + public static final int TYPE_Luv = 2;
10.130 +
10.131 + /**
10.132 + * Any of the family of YCbCr color spaces.
10.133 + */
10.134 + public static final int TYPE_YCbCr = 3;
10.135 +
10.136 + /**
10.137 + * Any of the family of Yxy color spaces.
10.138 + */
10.139 + public static final int TYPE_Yxy = 4;
10.140 +
10.141 + /**
10.142 + * Any of the family of RGB color spaces.
10.143 + */
10.144 + public static final int TYPE_RGB = 5;
10.145 +
10.146 + /**
10.147 + * Any of the family of GRAY color spaces.
10.148 + */
10.149 + public static final int TYPE_GRAY = 6;
10.150 +
10.151 + /**
10.152 + * Any of the family of HSV color spaces.
10.153 + */
10.154 + public static final int TYPE_HSV = 7;
10.155 +
10.156 + /**
10.157 + * Any of the family of HLS color spaces.
10.158 + */
10.159 + public static final int TYPE_HLS = 8;
10.160 +
10.161 + /**
10.162 + * Any of the family of CMYK color spaces.
10.163 + */
10.164 + public static final int TYPE_CMYK = 9;
10.165 +
10.166 + /**
10.167 + * Any of the family of CMY color spaces.
10.168 + */
10.169 + public static final int TYPE_CMY = 11;
10.170 +
10.171 + /**
10.172 + * Generic 2 component color spaces.
10.173 + */
10.174 + public static final int TYPE_2CLR = 12;
10.175 +
10.176 + /**
10.177 + * Generic 3 component color spaces.
10.178 + */
10.179 + public static final int TYPE_3CLR = 13;
10.180 +
10.181 + /**
10.182 + * Generic 4 component color spaces.
10.183 + */
10.184 + public static final int TYPE_4CLR = 14;
10.185 +
10.186 + /**
10.187 + * Generic 5 component color spaces.
10.188 + */
10.189 + public static final int TYPE_5CLR = 15;
10.190 +
10.191 + /**
10.192 + * Generic 6 component color spaces.
10.193 + */
10.194 + public static final int TYPE_6CLR = 16;
10.195 +
10.196 + /**
10.197 + * Generic 7 component color spaces.
10.198 + */
10.199 + public static final int TYPE_7CLR = 17;
10.200 +
10.201 + /**
10.202 + * Generic 8 component color spaces.
10.203 + */
10.204 + public static final int TYPE_8CLR = 18;
10.205 +
10.206 + /**
10.207 + * Generic 9 component color spaces.
10.208 + */
10.209 + public static final int TYPE_9CLR = 19;
10.210 +
10.211 + /**
10.212 + * Generic 10 component color spaces.
10.213 + */
10.214 + public static final int TYPE_ACLR = 20;
10.215 +
10.216 + /**
10.217 + * Generic 11 component color spaces.
10.218 + */
10.219 + public static final int TYPE_BCLR = 21;
10.220 +
10.221 + /**
10.222 + * Generic 12 component color spaces.
10.223 + */
10.224 + public static final int TYPE_CCLR = 22;
10.225 +
10.226 + /**
10.227 + * Generic 13 component color spaces.
10.228 + */
10.229 + public static final int TYPE_DCLR = 23;
10.230 +
10.231 + /**
10.232 + * Generic 14 component color spaces.
10.233 + */
10.234 + public static final int TYPE_ECLR = 24;
10.235 +
10.236 + /**
10.237 + * Generic 15 component color spaces.
10.238 + */
10.239 + public static final int TYPE_FCLR = 25;
10.240 +
10.241 + /**
10.242 + * The sRGB color space defined at
10.243 + * <A href="http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html">
10.244 + * http://www.w3.org/pub/WWW/Graphics/Color/sRGB.html
10.245 + * </A>.
10.246 + */
10.247 + public static final int CS_sRGB = 1000;
10.248 +
10.249 + /**
10.250 + * A built-in linear RGB color space. This space is based on the
10.251 + * same RGB primaries as CS_sRGB, but has a linear tone reproduction curve.
10.252 + */
10.253 + public static final int CS_LINEAR_RGB = 1004;
10.254 +
10.255 + /**
10.256 + * The CIEXYZ conversion color space defined above.
10.257 + */
10.258 + public static final int CS_CIEXYZ = 1001;
10.259 +
10.260 + /**
10.261 + * The Photo YCC conversion color space.
10.262 + */
10.263 + public static final int CS_PYCC = 1002;
10.264 +
10.265 + /**
10.266 + * The built-in linear gray scale color space.
10.267 + */
10.268 + public static final int CS_GRAY = 1003;
10.269 +
10.270 +
10.271 + /**
10.272 + * Constructs a ColorSpace object given a color space type
10.273 + * and the number of components.
10.274 + * @param type one of the <CODE>ColorSpace</CODE> type constants
10.275 + * @param numcomponents the number of components in the color space
10.276 + */
10.277 + protected ColorSpace (int type, int numcomponents) {
10.278 + this.type = type;
10.279 + this.numComponents = numcomponents;
10.280 + }
10.281 +
10.282 +
10.283 + /**
10.284 + * Returns a ColorSpace representing one of the specific
10.285 + * predefined color spaces.
10.286 + * @param colorspace a specific color space identified by one of
10.287 + * the predefined class constants (e.g. CS_sRGB, CS_LINEAR_RGB,
10.288 + * CS_CIEXYZ, CS_GRAY, or CS_PYCC)
10.289 + * @return the requested <CODE>ColorSpace</CODE> object
10.290 + */
10.291 + // NOTE: This method may be called by privileged threads.
10.292 + // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
10.293 + public static ColorSpace getInstance (int colorspace)
10.294 + {
10.295 + ColorSpace theColorSpace;
10.296 +
10.297 + switch (colorspace) {
10.298 + case CS_sRGB:
10.299 + synchronized(ColorSpace.class) {
10.300 + if (sRGBspace == null) {
10.301 + ICC_Profile theProfile = ICC_Profile.getInstance (CS_sRGB);
10.302 + sRGBspace = new ICC_ColorSpace (theProfile);
10.303 + }
10.304 +
10.305 + theColorSpace = sRGBspace;
10.306 + }
10.307 + break;
10.308 +
10.309 + case CS_CIEXYZ:
10.310 + synchronized(ColorSpace.class) {
10.311 + if (XYZspace == null) {
10.312 + ICC_Profile theProfile =
10.313 + ICC_Profile.getInstance (CS_CIEXYZ);
10.314 + XYZspace = new ICC_ColorSpace (theProfile);
10.315 + }
10.316 +
10.317 + theColorSpace = XYZspace;
10.318 + }
10.319 + break;
10.320 +
10.321 + case CS_PYCC:
10.322 + synchronized(ColorSpace.class) {
10.323 + if (PYCCspace == null) {
10.324 + ICC_Profile theProfile = ICC_Profile.getInstance (CS_PYCC);
10.325 + PYCCspace = new ICC_ColorSpace (theProfile);
10.326 + }
10.327 +
10.328 + theColorSpace = PYCCspace;
10.329 + }
10.330 + break;
10.331 +
10.332 +
10.333 + case CS_GRAY:
10.334 + synchronized(ColorSpace.class) {
10.335 + if (GRAYspace == null) {
10.336 + ICC_Profile theProfile = ICC_Profile.getInstance (CS_GRAY);
10.337 + GRAYspace = new ICC_ColorSpace (theProfile);
10.338 + /* to allow access from java.awt.ColorModel */
10.339 + CMSManager.GRAYspace = GRAYspace;
10.340 + }
10.341 +
10.342 + theColorSpace = GRAYspace;
10.343 + }
10.344 + break;
10.345 +
10.346 +
10.347 + case CS_LINEAR_RGB:
10.348 + synchronized(ColorSpace.class) {
10.349 + if (LINEAR_RGBspace == null) {
10.350 + ICC_Profile theProfile =
10.351 + ICC_Profile.getInstance(CS_LINEAR_RGB);
10.352 + LINEAR_RGBspace = new ICC_ColorSpace (theProfile);
10.353 + /* to allow access from java.awt.ColorModel */
10.354 + CMSManager.LINEAR_RGBspace = LINEAR_RGBspace;
10.355 + }
10.356 +
10.357 + theColorSpace = LINEAR_RGBspace;
10.358 + }
10.359 + break;
10.360 +
10.361 +
10.362 + default:
10.363 + throw new IllegalArgumentException ("Unknown color space");
10.364 + }
10.365 +
10.366 + return theColorSpace;
10.367 + }
10.368 +
10.369 +
10.370 + /**
10.371 + * Returns true if the ColorSpace is CS_sRGB.
10.372 + * @return <CODE>true</CODE> if this is a <CODE>CS_sRGB</CODE> color
10.373 + * space, <code>false</code> if it is not
10.374 + */
10.375 + public boolean isCS_sRGB () {
10.376 + /* REMIND - make sure we know sRGBspace exists already */
10.377 + return (this == sRGBspace);
10.378 + }
10.379 +
10.380 + /**
10.381 + * Transforms a color value assumed to be in this ColorSpace
10.382 + * into a value in the default CS_sRGB color space.
10.383 + * <p>
10.384 + * This method transforms color values using algorithms designed
10.385 + * to produce the best perceptual match between input and output
10.386 + * colors. In order to do colorimetric conversion of color values,
10.387 + * you should use the <code>toCIEXYZ</code>
10.388 + * method of this color space to first convert from the input
10.389 + * color space to the CS_CIEXYZ color space, and then use the
10.390 + * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
10.391 + * convert from CS_CIEXYZ to the output color space.
10.392 + * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
10.393 + * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
10.394 + * <p>
10.395 + * @param colorvalue a float array with length of at least the number
10.396 + * of components in this ColorSpace
10.397 + * @return a float array of length 3
10.398 + * @throws ArrayIndexOutOfBoundsException if array length is not
10.399 + * at least the number of components in this ColorSpace
10.400 + */
10.401 + public abstract float[] toRGB(float[] colorvalue);
10.402 +
10.403 +
10.404 + /**
10.405 + * Transforms a color value assumed to be in the default CS_sRGB
10.406 + * color space into this ColorSpace.
10.407 + * <p>
10.408 + * This method transforms color values using algorithms designed
10.409 + * to produce the best perceptual match between input and output
10.410 + * colors. In order to do colorimetric conversion of color values,
10.411 + * you should use the <code>toCIEXYZ</code>
10.412 + * method of the CS_sRGB color space to first convert from the input
10.413 + * color space to the CS_CIEXYZ color space, and then use the
10.414 + * <code>fromCIEXYZ</code> method of this color space to
10.415 + * convert from CS_CIEXYZ to the output color space.
10.416 + * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
10.417 + * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
10.418 + * <p>
10.419 + * @param rgbvalue a float array with length of at least 3
10.420 + * @return a float array with length equal to the number of
10.421 + * components in this ColorSpace
10.422 + * @throws ArrayIndexOutOfBoundsException if array length is not
10.423 + * at least 3
10.424 + */
10.425 + public abstract float[] fromRGB(float[] rgbvalue);
10.426 +
10.427 +
10.428 + /**
10.429 + * Transforms a color value assumed to be in this ColorSpace
10.430 + * into the CS_CIEXYZ conversion color space.
10.431 + * <p>
10.432 + * This method transforms color values using relative colorimetry,
10.433 + * as defined by the International Color Consortium standard. This
10.434 + * means that the XYZ values returned by this method are represented
10.435 + * relative to the D50 white point of the CS_CIEXYZ color space.
10.436 + * This representation is useful in a two-step color conversion
10.437 + * process in which colors are transformed from an input color
10.438 + * space to CS_CIEXYZ and then to an output color space. This
10.439 + * representation is not the same as the XYZ values that would
10.440 + * be measured from the given color value by a colorimeter.
10.441 + * A further transformation is necessary to compute the XYZ values
10.442 + * that would be measured using current CIE recommended practices.
10.443 + * See the {@link ICC_ColorSpace#toCIEXYZ(float[]) toCIEXYZ} method of
10.444 + * <code>ICC_ColorSpace</code> for further information.
10.445 + * <p>
10.446 + * @param colorvalue a float array with length of at least the number
10.447 + * of components in this ColorSpace
10.448 + * @return a float array of length 3
10.449 + * @throws ArrayIndexOutOfBoundsException if array length is not
10.450 + * at least the number of components in this ColorSpace.
10.451 + */
10.452 + public abstract float[] toCIEXYZ(float[] colorvalue);
10.453 +
10.454 +
10.455 + /**
10.456 + * Transforms a color value assumed to be in the CS_CIEXYZ conversion
10.457 + * color space into this ColorSpace.
10.458 + * <p>
10.459 + * This method transforms color values using relative colorimetry,
10.460 + * as defined by the International Color Consortium standard. This
10.461 + * means that the XYZ argument values taken by this method are represented
10.462 + * relative to the D50 white point of the CS_CIEXYZ color space.
10.463 + * This representation is useful in a two-step color conversion
10.464 + * process in which colors are transformed from an input color
10.465 + * space to CS_CIEXYZ and then to an output color space. The color
10.466 + * values returned by this method are not those that would produce
10.467 + * the XYZ value passed to the method when measured by a colorimeter.
10.468 + * If you have XYZ values corresponding to measurements made using
10.469 + * current CIE recommended practices, they must be converted to D50
10.470 + * relative values before being passed to this method.
10.471 + * See the {@link ICC_ColorSpace#fromCIEXYZ(float[]) fromCIEXYZ} method of
10.472 + * <code>ICC_ColorSpace</code> for further information.
10.473 + * <p>
10.474 + * @param colorvalue a float array with length of at least 3
10.475 + * @return a float array with length equal to the number of
10.476 + * components in this ColorSpace
10.477 + * @throws ArrayIndexOutOfBoundsException if array length is not
10.478 + * at least 3
10.479 + */
10.480 + public abstract float[] fromCIEXYZ(float[] colorvalue);
10.481 +
10.482 + /**
10.483 + * Returns the color space type of this ColorSpace (for example
10.484 + * TYPE_RGB, TYPE_XYZ, ...). The type defines the
10.485 + * number of components of the color space and the interpretation,
10.486 + * e.g. TYPE_RGB identifies a color space with three components - red,
10.487 + * green, and blue. It does not define the particular color
10.488 + * characteristics of the space, e.g. the chromaticities of the
10.489 + * primaries.
10.490 + *
10.491 + * @return the type constant that represents the type of this
10.492 + * <CODE>ColorSpace</CODE>
10.493 + */
10.494 + public int getType() {
10.495 + return type;
10.496 + }
10.497 +
10.498 + /**
10.499 + * Returns the number of components of this ColorSpace.
10.500 + * @return The number of components in this <CODE>ColorSpace</CODE>.
10.501 + */
10.502 + public int getNumComponents() {
10.503 + return numComponents;
10.504 + }
10.505 +
10.506 + /**
10.507 + * Returns the name of the component given the component index.
10.508 + *
10.509 + * @param idx the component index
10.510 + * @return the name of the component at the specified index
10.511 + * @throws IllegalArgumentException if <code>idx</code> is
10.512 + * less than 0 or greater than numComponents - 1
10.513 + */
10.514 + public String getName (int idx) {
10.515 + /* REMIND - handle common cases here */
10.516 + if ((idx < 0) || (idx > numComponents - 1)) {
10.517 + throw new IllegalArgumentException(
10.518 + "Component index out of range: " + idx);
10.519 + }
10.520 +
10.521 + if (compName == null) {
10.522 + switch (type) {
10.523 + case ColorSpace.TYPE_XYZ:
10.524 + compName = new String[] {"X", "Y", "Z"};
10.525 + break;
10.526 + case ColorSpace.TYPE_Lab:
10.527 + compName = new String[] {"L", "a", "b"};
10.528 + break;
10.529 + case ColorSpace.TYPE_Luv:
10.530 + compName = new String[] {"L", "u", "v"};
10.531 + break;
10.532 + case ColorSpace.TYPE_YCbCr:
10.533 + compName = new String[] {"Y", "Cb", "Cr"};
10.534 + break;
10.535 + case ColorSpace.TYPE_Yxy:
10.536 + compName = new String[] {"Y", "x", "y"};
10.537 + break;
10.538 + case ColorSpace.TYPE_RGB:
10.539 + compName = new String[] {"Red", "Green", "Blue"};
10.540 + break;
10.541 + case ColorSpace.TYPE_GRAY:
10.542 + compName = new String[] {"Gray"};
10.543 + break;
10.544 + case ColorSpace.TYPE_HSV:
10.545 + compName = new String[] {"Hue", "Saturation", "Value"};
10.546 + break;
10.547 + case ColorSpace.TYPE_HLS:
10.548 + compName = new String[] {"Hue", "Lightness",
10.549 + "Saturation"};
10.550 + break;
10.551 + case ColorSpace.TYPE_CMYK:
10.552 + compName = new String[] {"Cyan", "Magenta", "Yellow",
10.553 + "Black"};
10.554 + break;
10.555 + case ColorSpace.TYPE_CMY:
10.556 + compName = new String[] {"Cyan", "Magenta", "Yellow"};
10.557 + break;
10.558 + default:
10.559 + String [] tmp = new String[numComponents];
10.560 + for (int i = 0; i < tmp.length; i++) {
10.561 + tmp[i] = "Unnamed color component(" + i + ")";
10.562 + }
10.563 + compName = tmp;
10.564 + }
10.565 + }
10.566 + return compName[idx];
10.567 + }
10.568 +
10.569 + /**
10.570 + * Returns the minimum normalized color component value for the
10.571 + * specified component. The default implementation in this abstract
10.572 + * class returns 0.0 for all components. Subclasses should override
10.573 + * this method if necessary.
10.574 + *
10.575 + * @param component the component index
10.576 + * @return the minimum normalized component value
10.577 + * @throws IllegalArgumentException if component is less than 0 or
10.578 + * greater than numComponents - 1
10.579 + * @since 1.4
10.580 + */
10.581 + public float getMinValue(int component) {
10.582 + if ((component < 0) || (component > numComponents - 1)) {
10.583 + throw new IllegalArgumentException(
10.584 + "Component index out of range: " + component);
10.585 + }
10.586 + return 0.0f;
10.587 + }
10.588 +
10.589 + /**
10.590 + * Returns the maximum normalized color component value for the
10.591 + * specified component. The default implementation in this abstract
10.592 + * class returns 1.0 for all components. Subclasses should override
10.593 + * this method if necessary.
10.594 + *
10.595 + * @param component the component index
10.596 + * @return the maximum normalized component value
10.597 + * @throws IllegalArgumentException if component is less than 0 or
10.598 + * greater than numComponents - 1
10.599 + * @since 1.4
10.600 + */
10.601 + public float getMaxValue(int component) {
10.602 + if ((component < 0) || (component > numComponents - 1)) {
10.603 + throw new IllegalArgumentException(
10.604 + "Component index out of range: " + component);
10.605 + }
10.606 + return 1.0f;
10.607 + }
10.608 +
10.609 + /* Returns true if cspace is the XYZspace.
10.610 + */
10.611 + static boolean isCS_CIEXYZ(ColorSpace cspace) {
10.612 + return (cspace == XYZspace);
10.613 + }
10.614 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/src/share/classes/java/awt/color/ICC_ColorSpace.java Thu Jun 12 11:46:57 2008 -0700
11.3 @@ -0,0 +1,616 @@
11.4 +/*
11.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 + *
11.8 + * This code is free software; you can redistribute it and/or modify it
11.9 + * under the terms of the GNU General Public License version 2 only, as
11.10 + * published by the Free Software Foundation. Sun designates this
11.11 + * particular file as subject to the "Classpath" exception as provided
11.12 + * by Sun in the LICENSE file that accompanied this code.
11.13 + *
11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 + * version 2 for more details (a copy is included in the LICENSE file that
11.18 + * accompanied this code).
11.19 + *
11.20 + * You should have received a copy of the GNU General Public License version
11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 + *
11.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
11.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
11.26 + * have any questions.
11.27 + */
11.28 +
11.29 +/**********************************************************************
11.30 + **********************************************************************
11.31 + **********************************************************************
11.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
11.33 + *** As an unpublished work pursuant to Title 17 of the United ***
11.34 + *** States Code. All rights reserved. ***
11.35 + **********************************************************************
11.36 + **********************************************************************
11.37 + **********************************************************************/
11.38 +
11.39 +package java.awt.color;
11.40 +
11.41 +import sun.java2d.cmm.ColorTransform;
11.42 +import sun.java2d.cmm.CMSManager;
11.43 +import sun.java2d.cmm.PCMM;
11.44 +
11.45 +
11.46 +/**
11.47 + *
11.48 + * The ICC_ColorSpace class is an implementation of the abstract
11.49 + * ColorSpace class. This representation of
11.50 + * device independent and device dependent color spaces is based on the
11.51 + * International Color Consortium Specification ICC.1:2001-12, File Format for
11.52 + * Color Profiles (see <A href="http://www.color.org">http://www.color.org</A>).
11.53 + * <p>
11.54 + * Typically, a Color or ColorModel would be associated with an ICC
11.55 + * Profile which is either an input, display, or output profile (see
11.56 + * the ICC specification). There are other types of ICC Profiles, e.g.
11.57 + * abstract profiles, device link profiles, and named color profiles,
11.58 + * which do not contain information appropriate for representing the color
11.59 + * space of a color, image, or device (see ICC_Profile).
11.60 + * Attempting to create an ICC_ColorSpace object from an inappropriate ICC
11.61 + * Profile is an error.
11.62 + * <p>
11.63 + * ICC Profiles represent transformations from the color space of
11.64 + * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
11.65 + * Profiles of interest for tagging images or colors have a
11.66 + * PCS which is one of the device independent
11.67 + * spaces (one CIEXYZ space and two CIELab spaces) defined in the
11.68 + * ICC Profile Format Specification. Most profiles of interest
11.69 + * either have invertible transformations or explicitly specify
11.70 + * transformations going both directions. Should an ICC_ColorSpace
11.71 + * object be used in a way requiring a conversion from PCS to
11.72 + * the profile's native space and there is inadequate data to
11.73 + * correctly perform the conversion, the ICC_ColorSpace object will
11.74 + * produce output in the specified type of color space (e.g. TYPE_RGB,
11.75 + * TYPE_CMYK, etc.), but the specific color values of the output data
11.76 + * will be undefined.
11.77 + * <p>
11.78 + * The details of this class are not important for simple applets,
11.79 + * which draw in a default color space or manipulate and display
11.80 + * imported images with a known color space. At most, such applets
11.81 + * would need to get one of the default color spaces via
11.82 + * ColorSpace.getInstance().
11.83 + * <p>
11.84 + * @see ColorSpace
11.85 + * @see ICC_Profile
11.86 + */
11.87 +
11.88 +
11.89 +
11.90 +public class ICC_ColorSpace extends ColorSpace {
11.91 +
11.92 + static final long serialVersionUID = 3455889114070431483L;
11.93 +
11.94 + private ICC_Profile thisProfile;
11.95 + private float[] minVal;
11.96 + private float[] maxVal;
11.97 + private float[] diffMinMax;
11.98 + private float[] invDiffMinMax;
11.99 + private boolean needScaleInit = true;
11.100 +
11.101 + // {to,from}{RGB,CIEXYZ} methods create and cache these when needed
11.102 + private transient ColorTransform this2srgb;
11.103 + private transient ColorTransform srgb2this;
11.104 + private transient ColorTransform this2xyz;
11.105 + private transient ColorTransform xyz2this;
11.106 +
11.107 +
11.108 + /**
11.109 + * Constructs a new ICC_ColorSpace from an ICC_Profile object.
11.110 + * @param profile the specified ICC_Profile object
11.111 + * @exception IllegalArgumentException if profile is inappropriate for
11.112 + * representing a ColorSpace.
11.113 + */
11.114 + public ICC_ColorSpace (ICC_Profile profile) {
11.115 + super (profile.getColorSpaceType(), profile.getNumComponents());
11.116 +
11.117 + int profileClass = profile.getProfileClass();
11.118 +
11.119 + /* REMIND - is NAMEDCOLOR OK? */
11.120 + if ((profileClass != ICC_Profile.CLASS_INPUT) &&
11.121 + (profileClass != ICC_Profile.CLASS_DISPLAY) &&
11.122 + (profileClass != ICC_Profile.CLASS_OUTPUT) &&
11.123 + (profileClass != ICC_Profile.CLASS_COLORSPACECONVERSION) &&
11.124 + (profileClass != ICC_Profile.CLASS_NAMEDCOLOR) &&
11.125 + (profileClass != ICC_Profile.CLASS_ABSTRACT)) {
11.126 + throw new IllegalArgumentException("Invalid profile type");
11.127 + }
11.128 +
11.129 + thisProfile = profile;
11.130 + setMinMax();
11.131 + }
11.132 +
11.133 + /**
11.134 + * Returns the ICC_Profile for this ICC_ColorSpace.
11.135 + * @return the ICC_Profile for this ICC_ColorSpace.
11.136 + */
11.137 + public ICC_Profile getProfile() {
11.138 + return thisProfile;
11.139 + }
11.140 +
11.141 + /**
11.142 + * Transforms a color value assumed to be in this ColorSpace
11.143 + * into a value in the default CS_sRGB color space.
11.144 + * <p>
11.145 + * This method transforms color values using algorithms designed
11.146 + * to produce the best perceptual match between input and output
11.147 + * colors. In order to do colorimetric conversion of color values,
11.148 + * you should use the <code>toCIEXYZ</code>
11.149 + * method of this color space to first convert from the input
11.150 + * color space to the CS_CIEXYZ color space, and then use the
11.151 + * <code>fromCIEXYZ</code> method of the CS_sRGB color space to
11.152 + * convert from CS_CIEXYZ to the output color space.
11.153 + * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
11.154 + * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
11.155 + * <p>
11.156 + * @param colorvalue a float array with length of at least the number
11.157 + * of components in this ColorSpace.
11.158 + * @return a float array of length 3.
11.159 + * @throws ArrayIndexOutOfBoundsException if array length is not
11.160 + * at least the number of components in this ColorSpace.
11.161 + */
11.162 + public float[] toRGB (float[] colorvalue) {
11.163 +
11.164 + if (this2srgb == null) {
11.165 + ColorTransform[] transformList = new ColorTransform [2];
11.166 + ICC_ColorSpace srgbCS =
11.167 + (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
11.168 + PCMM mdl = CMSManager.getModule();
11.169 + transformList[0] = mdl.createTransform(
11.170 + thisProfile, ColorTransform.Any, ColorTransform.In);
11.171 + transformList[1] = mdl.createTransform(
11.172 + srgbCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
11.173 + this2srgb = mdl.createTransform(transformList);
11.174 + if (needScaleInit) {
11.175 + setComponentScaling();
11.176 + }
11.177 + }
11.178 +
11.179 + int nc = this.getNumComponents();
11.180 + short tmp[] = new short[nc];
11.181 + for (int i = 0; i < nc; i++) {
11.182 + tmp[i] = (short)
11.183 + ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
11.184 + }
11.185 + tmp = this2srgb.colorConvert(tmp, null);
11.186 + float[] result = new float [3];
11.187 + for (int i = 0; i < 3; i++) {
11.188 + result[i] = ((float) (tmp[i] & 0xffff)) / 65535.0f;
11.189 + }
11.190 + return result;
11.191 + }
11.192 +
11.193 + /**
11.194 + * Transforms a color value assumed to be in the default CS_sRGB
11.195 + * color space into this ColorSpace.
11.196 + * <p>
11.197 + * This method transforms color values using algorithms designed
11.198 + * to produce the best perceptual match between input and output
11.199 + * colors. In order to do colorimetric conversion of color values,
11.200 + * you should use the <code>toCIEXYZ</code>
11.201 + * method of the CS_sRGB color space to first convert from the input
11.202 + * color space to the CS_CIEXYZ color space, and then use the
11.203 + * <code>fromCIEXYZ</code> method of this color space to
11.204 + * convert from CS_CIEXYZ to the output color space.
11.205 + * See {@link #toCIEXYZ(float[]) toCIEXYZ} and
11.206 + * {@link #fromCIEXYZ(float[]) fromCIEXYZ} for further information.
11.207 + * <p>
11.208 + * @param rgbvalue a float array with length of at least 3.
11.209 + * @return a float array with length equal to the number of
11.210 + * components in this ColorSpace.
11.211 + * @throws ArrayIndexOutOfBoundsException if array length is not
11.212 + * at least 3.
11.213 + */
11.214 + public float[] fromRGB(float[] rgbvalue) {
11.215 +
11.216 + if (srgb2this == null) {
11.217 + ColorTransform[] transformList = new ColorTransform [2];
11.218 + ICC_ColorSpace srgbCS =
11.219 + (ICC_ColorSpace) ColorSpace.getInstance (CS_sRGB);
11.220 + PCMM mdl = CMSManager.getModule();
11.221 + transformList[0] = mdl.createTransform(
11.222 + srgbCS.getProfile(), ColorTransform.Any, ColorTransform.In);
11.223 + transformList[1] = mdl.createTransform(
11.224 + thisProfile, ColorTransform.Any, ColorTransform.Out);
11.225 + srgb2this = mdl.createTransform(transformList);
11.226 + if (needScaleInit) {
11.227 + setComponentScaling();
11.228 + }
11.229 + }
11.230 +
11.231 + short tmp[] = new short[3];
11.232 + for (int i = 0; i < 3; i++) {
11.233 + tmp[i] = (short) ((rgbvalue[i] * 65535.0f) + 0.5f);
11.234 + }
11.235 + tmp = srgb2this.colorConvert(tmp, null);
11.236 + int nc = this.getNumComponents();
11.237 + float[] result = new float [nc];
11.238 + for (int i = 0; i < nc; i++) {
11.239 + result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
11.240 + diffMinMax[i] + minVal[i];
11.241 + }
11.242 + return result;
11.243 + }
11.244 +
11.245 +
11.246 + /**
11.247 + * Transforms a color value assumed to be in this ColorSpace
11.248 + * into the CS_CIEXYZ conversion color space.
11.249 + * <p>
11.250 + * This method transforms color values using relative colorimetry,
11.251 + * as defined by the ICC Specification. This
11.252 + * means that the XYZ values returned by this method are represented
11.253 + * relative to the D50 white point of the CS_CIEXYZ color space.
11.254 + * This representation is useful in a two-step color conversion
11.255 + * process in which colors are transformed from an input color
11.256 + * space to CS_CIEXYZ and then to an output color space. This
11.257 + * representation is not the same as the XYZ values that would
11.258 + * be measured from the given color value by a colorimeter.
11.259 + * A further transformation is necessary to compute the XYZ values
11.260 + * that would be measured using current CIE recommended practices.
11.261 + * The paragraphs below explain this in more detail.
11.262 + * <p>
11.263 + * The ICC standard uses a device independent color space (DICS) as the
11.264 + * mechanism for converting color from one device to another device. In
11.265 + * this architecture, colors are converted from the source device's color
11.266 + * space to the ICC DICS and then from the ICC DICS to the destination
11.267 + * device's color space. The ICC standard defines device profiles which
11.268 + * contain transforms which will convert between a device's color space
11.269 + * and the ICC DICS. The overall conversion of colors from a source
11.270 + * device to colors of a destination device is done by connecting the
11.271 + * device-to-DICS transform of the profile for the source device to the
11.272 + * DICS-to-device transform of the profile for the destination device.
11.273 + * For this reason, the ICC DICS is commonly referred to as the profile
11.274 + * connection space (PCS). The color space used in the methods
11.275 + * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
11.276 + * Specification. This is also the color space represented by
11.277 + * ColorSpace.CS_CIEXYZ.
11.278 + * <p>
11.279 + * The XYZ values of a color are often represented as relative to some
11.280 + * white point, so the actual meaning of the XYZ values cannot be known
11.281 + * without knowing the white point of those values. This is known as
11.282 + * relative colorimetry. The PCS uses a white point of D50, so the XYZ
11.283 + * values of the PCS are relative to D50. For example, white in the PCS
11.284 + * will have the XYZ values of D50, which is defined to be X=.9642,
11.285 + * Y=1.000, and Z=0.8249. This white point is commonly used for graphic
11.286 + * arts applications, but others are often used in other applications.
11.287 + * <p>
11.288 + * To quantify the color characteristics of a device such as a printer
11.289 + * or monitor, measurements of XYZ values for particular device colors
11.290 + * are typically made. For purposes of this discussion, the term
11.291 + * device XYZ values is used to mean the XYZ values that would be
11.292 + * measured from device colors using current CIE recommended practices.
11.293 + * <p>
11.294 + * Converting between device XYZ values and the PCS XYZ values returned
11.295 + * by this method corresponds to converting between the device's color
11.296 + * space, as represented by CIE colorimetric values, and the PCS. There
11.297 + * are many factors involved in this process, some of which are quite
11.298 + * subtle. The most important, however, is the adjustment made to account
11.299 + * for differences between the device's white point and the white point of
11.300 + * the PCS. There are many techniques for doing this and it is the
11.301 + * subject of much current research and controversy. Some commonly used
11.302 + * methods are XYZ scaling, the von Kries transform, and the Bradford
11.303 + * transform. The proper method to use depends upon each particular
11.304 + * application.
11.305 + * <p>
11.306 + * The simplest method is XYZ scaling. In this method each device XYZ
11.307 + * value is converted to a PCS XYZ value by multiplying it by the ratio
11.308 + * of the PCS white point (D50) to the device white point.
11.309 + * <pre>
11.310 + *
11.311 + * Xd, Yd, Zd are the device XYZ values
11.312 + * Xdw, Ydw, Zdw are the device XYZ white point values
11.313 + * Xp, Yp, Zp are the PCS XYZ values
11.314 + * Xd50, Yd50, Zd50 are the PCS XYZ white point values
11.315 + *
11.316 + * Xp = Xd * (Xd50 / Xdw)
11.317 + * Yp = Yd * (Yd50 / Ydw)
11.318 + * Zp = Zd * (Zd50 / Zdw)
11.319 + *
11.320 + * </pre>
11.321 + * <p>
11.322 + * Conversion from the PCS to the device would be done by inverting these
11.323 + * equations:
11.324 + * <pre>
11.325 + *
11.326 + * Xd = Xp * (Xdw / Xd50)
11.327 + * Yd = Yp * (Ydw / Yd50)
11.328 + * Zd = Zp * (Zdw / Zd50)
11.329 + *
11.330 + * </pre>
11.331 + * <p>
11.332 + * Note that the media white point tag in an ICC profile is not the same
11.333 + * as the device white point. The media white point tag is expressed in
11.334 + * PCS values and is used to represent the difference between the XYZ of
11.335 + * device illuminant and the XYZ of the device media when measured under
11.336 + * that illuminant. The device white point is expressed as the device
11.337 + * XYZ values corresponding to white displayed on the device. For
11.338 + * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
11.339 + * will result in a measured device XYZ value of D65. This will not
11.340 + * be the same as the media white point tag XYZ value in the ICC
11.341 + * profile for an sRGB device.
11.342 + * <p>
11.343 + * @param colorvalue a float array with length of at least the number
11.344 + * of components in this ColorSpace.
11.345 + * @return a float array of length 3.
11.346 + * @throws ArrayIndexOutOfBoundsException if array length is not
11.347 + * at least the number of components in this ColorSpace.
11.348 + */
11.349 + public float[] toCIEXYZ(float[] colorvalue) {
11.350 +
11.351 + if (this2xyz == null) {
11.352 + ColorTransform[] transformList = new ColorTransform [2];
11.353 + ICC_ColorSpace xyzCS =
11.354 + (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
11.355 + PCMM mdl = CMSManager.getModule();
11.356 + try {
11.357 + transformList[0] = mdl.createTransform(
11.358 + thisProfile, ICC_Profile.icRelativeColorimetric,
11.359 + ColorTransform.In);
11.360 + } catch (CMMException e) {
11.361 + transformList[0] = mdl.createTransform(
11.362 + thisProfile, ColorTransform.Any, ColorTransform.In);
11.363 + }
11.364 + transformList[1] = mdl.createTransform(
11.365 + xyzCS.getProfile(), ColorTransform.Any, ColorTransform.Out);
11.366 + this2xyz = mdl.createTransform (transformList);
11.367 + if (needScaleInit) {
11.368 + setComponentScaling();
11.369 + }
11.370 + }
11.371 +
11.372 + int nc = this.getNumComponents();
11.373 + short tmp[] = new short[nc];
11.374 + for (int i = 0; i < nc; i++) {
11.375 + tmp[i] = (short)
11.376 + ((colorvalue[i] - minVal[i]) * invDiffMinMax[i] + 0.5f);
11.377 + }
11.378 + tmp = this2xyz.colorConvert(tmp, null);
11.379 + float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
11.380 + // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
11.381 + float[] result = new float [3];
11.382 + for (int i = 0; i < 3; i++) {
11.383 + result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) * ALMOST_TWO;
11.384 + }
11.385 + return result;
11.386 + }
11.387 +
11.388 +
11.389 + /**
11.390 + * Transforms a color value assumed to be in the CS_CIEXYZ conversion
11.391 + * color space into this ColorSpace.
11.392 + * <p>
11.393 + * This method transforms color values using relative colorimetry,
11.394 + * as defined by the ICC Specification. This
11.395 + * means that the XYZ argument values taken by this method are represented
11.396 + * relative to the D50 white point of the CS_CIEXYZ color space.
11.397 + * This representation is useful in a two-step color conversion
11.398 + * process in which colors are transformed from an input color
11.399 + * space to CS_CIEXYZ and then to an output color space. The color
11.400 + * values returned by this method are not those that would produce
11.401 + * the XYZ value passed to the method when measured by a colorimeter.
11.402 + * If you have XYZ values corresponding to measurements made using
11.403 + * current CIE recommended practices, they must be converted to D50
11.404 + * relative values before being passed to this method.
11.405 + * The paragraphs below explain this in more detail.
11.406 + * <p>
11.407 + * The ICC standard uses a device independent color space (DICS) as the
11.408 + * mechanism for converting color from one device to another device. In
11.409 + * this architecture, colors are converted from the source device's color
11.410 + * space to the ICC DICS and then from the ICC DICS to the destination
11.411 + * device's color space. The ICC standard defines device profiles which
11.412 + * contain transforms which will convert between a device's color space
11.413 + * and the ICC DICS. The overall conversion of colors from a source
11.414 + * device to colors of a destination device is done by connecting the
11.415 + * device-to-DICS transform of the profile for the source device to the
11.416 + * DICS-to-device transform of the profile for the destination device.
11.417 + * For this reason, the ICC DICS is commonly referred to as the profile
11.418 + * connection space (PCS). The color space used in the methods
11.419 + * toCIEXYZ and fromCIEXYZ is the CIEXYZ PCS defined by the ICC
11.420 + * Specification. This is also the color space represented by
11.421 + * ColorSpace.CS_CIEXYZ.
11.422 + * <p>
11.423 + * The XYZ values of a color are often represented as relative to some
11.424 + * white point, so the actual meaning of the XYZ values cannot be known
11.425 + * without knowing the white point of those values. This is known as
11.426 + * relative colorimetry. The PCS uses a white point of D50, so the XYZ
11.427 + * values of the PCS are relative to D50. For example, white in the PCS
11.428 + * will have the XYZ values of D50, which is defined to be X=.9642,
11.429 + * Y=1.000, and Z=0.8249. This white point is commonly used for graphic
11.430 + * arts applications, but others are often used in other applications.
11.431 + * <p>
11.432 + * To quantify the color characteristics of a device such as a printer
11.433 + * or monitor, measurements of XYZ values for particular device colors
11.434 + * are typically made. For purposes of this discussion, the term
11.435 + * device XYZ values is used to mean the XYZ values that would be
11.436 + * measured from device colors using current CIE recommended practices.
11.437 + * <p>
11.438 + * Converting between device XYZ values and the PCS XYZ values taken as
11.439 + * arguments by this method corresponds to converting between the device's
11.440 + * color space, as represented by CIE colorimetric values, and the PCS.
11.441 + * There are many factors involved in this process, some of which are quite
11.442 + * subtle. The most important, however, is the adjustment made to account
11.443 + * for differences between the device's white point and the white point of
11.444 + * the PCS. There are many techniques for doing this and it is the
11.445 + * subject of much current research and controversy. Some commonly used
11.446 + * methods are XYZ scaling, the von Kries transform, and the Bradford
11.447 + * transform. The proper method to use depends upon each particular
11.448 + * application.
11.449 + * <p>
11.450 + * The simplest method is XYZ scaling. In this method each device XYZ
11.451 + * value is converted to a PCS XYZ value by multiplying it by the ratio
11.452 + * of the PCS white point (D50) to the device white point.
11.453 + * <pre>
11.454 + *
11.455 + * Xd, Yd, Zd are the device XYZ values
11.456 + * Xdw, Ydw, Zdw are the device XYZ white point values
11.457 + * Xp, Yp, Zp are the PCS XYZ values
11.458 + * Xd50, Yd50, Zd50 are the PCS XYZ white point values
11.459 + *
11.460 + * Xp = Xd * (Xd50 / Xdw)
11.461 + * Yp = Yd * (Yd50 / Ydw)
11.462 + * Zp = Zd * (Zd50 / Zdw)
11.463 + *
11.464 + * </pre>
11.465 + * <p>
11.466 + * Conversion from the PCS to the device would be done by inverting these
11.467 + * equations:
11.468 + * <pre>
11.469 + *
11.470 + * Xd = Xp * (Xdw / Xd50)
11.471 + * Yd = Yp * (Ydw / Yd50)
11.472 + * Zd = Zp * (Zdw / Zd50)
11.473 + *
11.474 + * </pre>
11.475 + * <p>
11.476 + * Note that the media white point tag in an ICC profile is not the same
11.477 + * as the device white point. The media white point tag is expressed in
11.478 + * PCS values and is used to represent the difference between the XYZ of
11.479 + * device illuminant and the XYZ of the device media when measured under
11.480 + * that illuminant. The device white point is expressed as the device
11.481 + * XYZ values corresponding to white displayed on the device. For
11.482 + * example, displaying the RGB color (1.0, 1.0, 1.0) on an sRGB device
11.483 + * will result in a measured device XYZ value of D65. This will not
11.484 + * be the same as the media white point tag XYZ value in the ICC
11.485 + * profile for an sRGB device.
11.486 + * <p>
11.487 + * <p>
11.488 + * @param colorvalue a float array with length of at least 3.
11.489 + * @return a float array with length equal to the number of
11.490 + * components in this ColorSpace.
11.491 + * @throws ArrayIndexOutOfBoundsException if array length is not
11.492 + * at least 3.
11.493 + */
11.494 + public float[] fromCIEXYZ(float[] colorvalue) {
11.495 +
11.496 + if (xyz2this == null) {
11.497 + ColorTransform[] transformList = new ColorTransform [2];
11.498 + ICC_ColorSpace xyzCS =
11.499 + (ICC_ColorSpace) ColorSpace.getInstance (CS_CIEXYZ);
11.500 + PCMM mdl = CMSManager.getModule();
11.501 + transformList[0] = mdl.createTransform (
11.502 + xyzCS.getProfile(), ColorTransform.Any, ColorTransform.In);
11.503 + try {
11.504 + transformList[1] = mdl.createTransform(
11.505 + thisProfile, ICC_Profile.icRelativeColorimetric,
11.506 + ColorTransform.Out);
11.507 + } catch (CMMException e) {
11.508 + transformList[1] = CMSManager.getModule().createTransform(
11.509 + thisProfile, ColorTransform.Any, ColorTransform.Out);
11.510 + }
11.511 + xyz2this = mdl.createTransform(transformList);
11.512 + if (needScaleInit) {
11.513 + setComponentScaling();
11.514 + }
11.515 + }
11.516 +
11.517 + short tmp[] = new short[3];
11.518 + float ALMOST_TWO = 1.0f + (32767.0f / 32768.0f);
11.519 + float factor = 65535.0f / ALMOST_TWO;
11.520 + // For CIEXYZ, min = 0.0, max = ALMOST_TWO for all components
11.521 + for (int i = 0; i < 3; i++) {
11.522 + tmp[i] = (short) ((colorvalue[i] * factor) + 0.5f);
11.523 + }
11.524 + tmp = xyz2this.colorConvert(tmp, null);
11.525 + int nc = this.getNumComponents();
11.526 + float[] result = new float [nc];
11.527 + for (int i = 0; i < nc; i++) {
11.528 + result[i] = (((float) (tmp[i] & 0xffff)) / 65535.0f) *
11.529 + diffMinMax[i] + minVal[i];
11.530 + }
11.531 + return result;
11.532 + }
11.533 +
11.534 + /**
11.535 + * Returns the minimum normalized color component value for the
11.536 + * specified component. For TYPE_XYZ spaces, this method returns
11.537 + * minimum values of 0.0 for all components. For TYPE_Lab spaces,
11.538 + * this method returns 0.0 for L and -128.0 for a and b components.
11.539 + * This is consistent with the encoding of the XYZ and Lab Profile
11.540 + * Connection Spaces in the ICC specification. For all other types, this
11.541 + * method returns 0.0 for all components. When using an ICC_ColorSpace
11.542 + * with a profile that requires different minimum component values,
11.543 + * it is necessary to subclass this class and override this method.
11.544 + * @param component The component index.
11.545 + * @return The minimum normalized component value.
11.546 + * @throws IllegalArgumentException if component is less than 0 or
11.547 + * greater than numComponents - 1.
11.548 + * @since 1.4
11.549 + */
11.550 + public float getMinValue(int component) {
11.551 + if ((component < 0) || (component > this.getNumComponents() - 1)) {
11.552 + throw new IllegalArgumentException(
11.553 + "Component index out of range: + component");
11.554 + }
11.555 + return minVal[component];
11.556 + }
11.557 +
11.558 + /**
11.559 + * Returns the maximum normalized color component value for the
11.560 + * specified component. For TYPE_XYZ spaces, this method returns
11.561 + * maximum values of 1.0 + (32767.0 / 32768.0) for all components.
11.562 + * For TYPE_Lab spaces,
11.563 + * this method returns 100.0 for L and 127.0 for a and b components.
11.564 + * This is consistent with the encoding of the XYZ and Lab Profile
11.565 + * Connection Spaces in the ICC specification. For all other types, this
11.566 + * method returns 1.0 for all components. When using an ICC_ColorSpace
11.567 + * with a profile that requires different maximum component values,
11.568 + * it is necessary to subclass this class and override this method.
11.569 + * @param component The component index.
11.570 + * @return The maximum normalized component value.
11.571 + * @throws IllegalArgumentException if component is less than 0 or
11.572 + * greater than numComponents - 1.
11.573 + * @since 1.4
11.574 + */
11.575 + public float getMaxValue(int component) {
11.576 + if ((component < 0) || (component > this.getNumComponents() - 1)) {
11.577 + throw new IllegalArgumentException(
11.578 + "Component index out of range: + component");
11.579 + }
11.580 + return maxVal[component];
11.581 + }
11.582 +
11.583 + private void setMinMax() {
11.584 + int nc = this.getNumComponents();
11.585 + int type = this.getType();
11.586 + minVal = new float[nc];
11.587 + maxVal = new float[nc];
11.588 + if (type == ColorSpace.TYPE_Lab) {
11.589 + minVal[0] = 0.0f; // L
11.590 + maxVal[0] = 100.0f;
11.591 + minVal[1] = -128.0f; // a
11.592 + maxVal[1] = 127.0f;
11.593 + minVal[2] = -128.0f; // b
11.594 + maxVal[2] = 127.0f;
11.595 + } else if (type == ColorSpace.TYPE_XYZ) {
11.596 + minVal[0] = minVal[1] = minVal[2] = 0.0f; // X, Y, Z
11.597 + maxVal[0] = maxVal[1] = maxVal[2] = 1.0f + (32767.0f/ 32768.0f);
11.598 + } else {
11.599 + for (int i = 0; i < nc; i++) {
11.600 + minVal[i] = 0.0f;
11.601 + maxVal[i] = 1.0f;
11.602 + }
11.603 + }
11.604 + }
11.605 +
11.606 + private void setComponentScaling() {
11.607 + int nc = this.getNumComponents();
11.608 + diffMinMax = new float[nc];
11.609 + invDiffMinMax = new float[nc];
11.610 + for (int i = 0; i < nc; i++) {
11.611 + minVal[i] = this.getMinValue(i); // in case getMinVal is overridden
11.612 + maxVal[i] = this.getMaxValue(i); // in case getMaxVal is overridden
11.613 + diffMinMax[i] = maxVal[i] - minVal[i];
11.614 + invDiffMinMax[i] = 65535.0f / diffMinMax[i];
11.615 + }
11.616 + needScaleInit = false;
11.617 + }
11.618 +
11.619 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/src/share/classes/java/awt/color/ICC_Profile.java Thu Jun 12 11:46:57 2008 -0700
12.3 @@ -0,0 +1,2003 @@
12.4 +/*
12.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 + *
12.8 + * This code is free software; you can redistribute it and/or modify it
12.9 + * under the terms of the GNU General Public License version 2 only, as
12.10 + * published by the Free Software Foundation. Sun designates this
12.11 + * particular file as subject to the "Classpath" exception as provided
12.12 + * by Sun in the LICENSE file that accompanied this code.
12.13 + *
12.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
12.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 + * version 2 for more details (a copy is included in the LICENSE file that
12.18 + * accompanied this code).
12.19 + *
12.20 + * You should have received a copy of the GNU General Public License version
12.21 + * 2 along with this work; if not, write to the Free Software Foundation,
12.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 + *
12.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
12.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
12.26 + * have any questions.
12.27 + */
12.28 +
12.29 +/**********************************************************************
12.30 + **********************************************************************
12.31 + **********************************************************************
12.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
12.33 + *** As an unpublished work pursuant to Title 17 of the United ***
12.34 + *** States Code. All rights reserved. ***
12.35 + **********************************************************************
12.36 + **********************************************************************
12.37 + **********************************************************************/
12.38 +
12.39 +package java.awt.color;
12.40 +
12.41 +import sun.java2d.cmm.PCMM;
12.42 +import sun.java2d.cmm.CMSManager;
12.43 +import sun.java2d.cmm.ProfileDeferralMgr;
12.44 +import sun.java2d.cmm.ProfileDeferralInfo;
12.45 +import sun.java2d.cmm.ProfileActivator;
12.46 +
12.47 +import java.io.File;
12.48 +import java.io.FileInputStream;
12.49 +import java.io.FileNotFoundException;
12.50 +import java.io.FileOutputStream;
12.51 +import java.io.IOException;
12.52 +import java.io.InputStream;
12.53 +import java.io.ObjectInputStream;
12.54 +import java.io.ObjectOutputStream;
12.55 +import java.io.ObjectStreamException;
12.56 +import java.io.OutputStream;
12.57 +import java.io.Serializable;
12.58 +
12.59 +import java.util.StringTokenizer;
12.60 +
12.61 +import java.security.AccessController;
12.62 +import java.security.PrivilegedAction;
12.63 +
12.64 +/**
12.65 + * A representation of color profile data for device independent and
12.66 + * device dependent color spaces based on the International Color
12.67 + * Consortium Specification ICC.1:2001-12, File Format for Color Profiles,
12.68 + * (see <A href="http://www.color.org"> http://www.color.org</A>).
12.69 + * <p>
12.70 + * An ICC_ColorSpace object can be constructed from an appropriate
12.71 + * ICC_Profile.
12.72 + * Typically, an ICC_ColorSpace would be associated with an ICC
12.73 + * Profile which is either an input, display, or output profile (see
12.74 + * the ICC specification). There are also device link, abstract,
12.75 + * color space conversion, and named color profiles. These are less
12.76 + * useful for tagging a color or image, but are useful for other
12.77 + * purposes (in particular device link profiles can provide improved
12.78 + * performance for converting from one device's color space to
12.79 + * another's).
12.80 + * <p>
12.81 + * ICC Profiles represent transformations from the color space of
12.82 + * the profile (e.g. a monitor) to a Profile Connection Space (PCS).
12.83 + * Profiles of interest for tagging images or colors have a PCS
12.84 + * which is one of the two specific device independent
12.85 + * spaces (one CIEXYZ space and one CIELab space) defined in the
12.86 + * ICC Profile Format Specification. Most profiles of interest
12.87 + * either have invertible transformations or explicitly specify
12.88 + * transformations going both directions.
12.89 + * <p>
12.90 + * @see ICC_ColorSpace
12.91 + */
12.92 +
12.93 +
12.94 +public class ICC_Profile implements Serializable {
12.95 +
12.96 + private static final long serialVersionUID = -3938515861990936766L;
12.97 +
12.98 + transient long ID;
12.99 +
12.100 + private transient ProfileDeferralInfo deferralInfo;
12.101 + private transient ProfileActivator profileActivator;
12.102 +
12.103 + // Registry of singleton profile objects for specific color spaces
12.104 + // defined in the ColorSpace class (e.g. CS_sRGB), see
12.105 + // getInstance(int cspace) factory method.
12.106 + private static ICC_Profile sRGBprofile;
12.107 + private static ICC_Profile XYZprofile;
12.108 + private static ICC_Profile PYCCprofile;
12.109 + private static ICC_Profile GRAYprofile;
12.110 + private static ICC_Profile LINEAR_RGBprofile;
12.111 +
12.112 +
12.113 + /**
12.114 + * Profile class is input.
12.115 + */
12.116 + public static final int CLASS_INPUT = 0;
12.117 +
12.118 + /**
12.119 + * Profile class is display.
12.120 + */
12.121 + public static final int CLASS_DISPLAY = 1;
12.122 +
12.123 + /**
12.124 + * Profile class is output.
12.125 + */
12.126 + public static final int CLASS_OUTPUT = 2;
12.127 +
12.128 + /**
12.129 + * Profile class is device link.
12.130 + */
12.131 + public static final int CLASS_DEVICELINK = 3;
12.132 +
12.133 + /**
12.134 + * Profile class is color space conversion.
12.135 + */
12.136 + public static final int CLASS_COLORSPACECONVERSION = 4;
12.137 +
12.138 + /**
12.139 + * Profile class is abstract.
12.140 + */
12.141 + public static final int CLASS_ABSTRACT = 5;
12.142 +
12.143 + /**
12.144 + * Profile class is named color.
12.145 + */
12.146 + public static final int CLASS_NAMEDCOLOR = 6;
12.147 +
12.148 +
12.149 + /**
12.150 + * ICC Profile Color Space Type Signature: 'XYZ '.
12.151 + */
12.152 + public static final int icSigXYZData = 0x58595A20; /* 'XYZ ' */
12.153 +
12.154 + /**
12.155 + * ICC Profile Color Space Type Signature: 'Lab '.
12.156 + */
12.157 + public static final int icSigLabData = 0x4C616220; /* 'Lab ' */
12.158 +
12.159 + /**
12.160 + * ICC Profile Color Space Type Signature: 'Luv '.
12.161 + */
12.162 + public static final int icSigLuvData = 0x4C757620; /* 'Luv ' */
12.163 +
12.164 + /**
12.165 + * ICC Profile Color Space Type Signature: 'YCbr'.
12.166 + */
12.167 + public static final int icSigYCbCrData = 0x59436272; /* 'YCbr' */
12.168 +
12.169 + /**
12.170 + * ICC Profile Color Space Type Signature: 'Yxy '.
12.171 + */
12.172 + public static final int icSigYxyData = 0x59787920; /* 'Yxy ' */
12.173 +
12.174 + /**
12.175 + * ICC Profile Color Space Type Signature: 'RGB '.
12.176 + */
12.177 + public static final int icSigRgbData = 0x52474220; /* 'RGB ' */
12.178 +
12.179 + /**
12.180 + * ICC Profile Color Space Type Signature: 'GRAY'.
12.181 + */
12.182 + public static final int icSigGrayData = 0x47524159; /* 'GRAY' */
12.183 +
12.184 + /**
12.185 + * ICC Profile Color Space Type Signature: 'HSV'.
12.186 + */
12.187 + public static final int icSigHsvData = 0x48535620; /* 'HSV ' */
12.188 +
12.189 + /**
12.190 + * ICC Profile Color Space Type Signature: 'HLS'.
12.191 + */
12.192 + public static final int icSigHlsData = 0x484C5320; /* 'HLS ' */
12.193 +
12.194 + /**
12.195 + * ICC Profile Color Space Type Signature: 'CMYK'.
12.196 + */
12.197 + public static final int icSigCmykData = 0x434D594B; /* 'CMYK' */
12.198 +
12.199 + /**
12.200 + * ICC Profile Color Space Type Signature: 'CMY '.
12.201 + */
12.202 + public static final int icSigCmyData = 0x434D5920; /* 'CMY ' */
12.203 +
12.204 + /**
12.205 + * ICC Profile Color Space Type Signature: '2CLR'.
12.206 + */
12.207 + public static final int icSigSpace2CLR = 0x32434C52; /* '2CLR' */
12.208 +
12.209 + /**
12.210 + * ICC Profile Color Space Type Signature: '3CLR'.
12.211 + */
12.212 + public static final int icSigSpace3CLR = 0x33434C52; /* '3CLR' */
12.213 +
12.214 + /**
12.215 + * ICC Profile Color Space Type Signature: '4CLR'.
12.216 + */
12.217 + public static final int icSigSpace4CLR = 0x34434C52; /* '4CLR' */
12.218 +
12.219 + /**
12.220 + * ICC Profile Color Space Type Signature: '5CLR'.
12.221 + */
12.222 + public static final int icSigSpace5CLR = 0x35434C52; /* '5CLR' */
12.223 +
12.224 + /**
12.225 + * ICC Profile Color Space Type Signature: '6CLR'.
12.226 + */
12.227 + public static final int icSigSpace6CLR = 0x36434C52; /* '6CLR' */
12.228 +
12.229 + /**
12.230 + * ICC Profile Color Space Type Signature: '7CLR'.
12.231 + */
12.232 + public static final int icSigSpace7CLR = 0x37434C52; /* '7CLR' */
12.233 +
12.234 + /**
12.235 + * ICC Profile Color Space Type Signature: '8CLR'.
12.236 + */
12.237 + public static final int icSigSpace8CLR = 0x38434C52; /* '8CLR' */
12.238 +
12.239 + /**
12.240 + * ICC Profile Color Space Type Signature: '9CLR'.
12.241 + */
12.242 + public static final int icSigSpace9CLR = 0x39434C52; /* '9CLR' */
12.243 +
12.244 + /**
12.245 + * ICC Profile Color Space Type Signature: 'ACLR'.
12.246 + */
12.247 + public static final int icSigSpaceACLR = 0x41434C52; /* 'ACLR' */
12.248 +
12.249 + /**
12.250 + * ICC Profile Color Space Type Signature: 'BCLR'.
12.251 + */
12.252 + public static final int icSigSpaceBCLR = 0x42434C52; /* 'BCLR' */
12.253 +
12.254 + /**
12.255 + * ICC Profile Color Space Type Signature: 'CCLR'.
12.256 + */
12.257 + public static final int icSigSpaceCCLR = 0x43434C52; /* 'CCLR' */
12.258 +
12.259 + /**
12.260 + * ICC Profile Color Space Type Signature: 'DCLR'.
12.261 + */
12.262 + public static final int icSigSpaceDCLR = 0x44434C52; /* 'DCLR' */
12.263 +
12.264 + /**
12.265 + * ICC Profile Color Space Type Signature: 'ECLR'.
12.266 + */
12.267 + public static final int icSigSpaceECLR = 0x45434C52; /* 'ECLR' */
12.268 +
12.269 + /**
12.270 + * ICC Profile Color Space Type Signature: 'FCLR'.
12.271 + */
12.272 + public static final int icSigSpaceFCLR = 0x46434C52; /* 'FCLR' */
12.273 +
12.274 +
12.275 + /**
12.276 + * ICC Profile Class Signature: 'scnr'.
12.277 + */
12.278 + public static final int icSigInputClass = 0x73636E72; /* 'scnr' */
12.279 +
12.280 + /**
12.281 + * ICC Profile Class Signature: 'mntr'.
12.282 + */
12.283 + public static final int icSigDisplayClass = 0x6D6E7472; /* 'mntr' */
12.284 +
12.285 + /**
12.286 + * ICC Profile Class Signature: 'prtr'.
12.287 + */
12.288 + public static final int icSigOutputClass = 0x70727472; /* 'prtr' */
12.289 +
12.290 + /**
12.291 + * ICC Profile Class Signature: 'link'.
12.292 + */
12.293 + public static final int icSigLinkClass = 0x6C696E6B; /* 'link' */
12.294 +
12.295 + /**
12.296 + * ICC Profile Class Signature: 'abst'.
12.297 + */
12.298 + public static final int icSigAbstractClass = 0x61627374; /* 'abst' */
12.299 +
12.300 + /**
12.301 + * ICC Profile Class Signature: 'spac'.
12.302 + */
12.303 + public static final int icSigColorSpaceClass = 0x73706163; /* 'spac' */
12.304 +
12.305 + /**
12.306 + * ICC Profile Class Signature: 'nmcl'.
12.307 + */
12.308 + public static final int icSigNamedColorClass = 0x6e6d636c; /* 'nmcl' */
12.309 +
12.310 +
12.311 + /**
12.312 + * ICC Profile Rendering Intent: Perceptual.
12.313 + */
12.314 + public static final int icPerceptual = 0;
12.315 +
12.316 + /**
12.317 + * ICC Profile Rendering Intent: RelativeColorimetric.
12.318 + */
12.319 + public static final int icRelativeColorimetric = 1;
12.320 +
12.321 + /**
12.322 + * ICC Profile Rendering Intent: Media-RelativeColorimetric.
12.323 + * @since 1.5
12.324 + */
12.325 + public static final int icMediaRelativeColorimetric = 1;
12.326 +
12.327 + /**
12.328 + * ICC Profile Rendering Intent: Saturation.
12.329 + */
12.330 + public static final int icSaturation = 2;
12.331 +
12.332 + /**
12.333 + * ICC Profile Rendering Intent: AbsoluteColorimetric.
12.334 + */
12.335 + public static final int icAbsoluteColorimetric = 3;
12.336 +
12.337 + /**
12.338 + * ICC Profile Rendering Intent: ICC-AbsoluteColorimetric.
12.339 + * @since 1.5
12.340 + */
12.341 + public static final int icICCAbsoluteColorimetric = 3;
12.342 +
12.343 +
12.344 + /**
12.345 + * ICC Profile Tag Signature: 'head' - special.
12.346 + */
12.347 + public static final int icSigHead = 0x68656164; /* 'head' - special */
12.348 +
12.349 + /**
12.350 + * ICC Profile Tag Signature: 'A2B0'.
12.351 + */
12.352 + public static final int icSigAToB0Tag = 0x41324230; /* 'A2B0' */
12.353 +
12.354 + /**
12.355 + * ICC Profile Tag Signature: 'A2B1'.
12.356 + */
12.357 + public static final int icSigAToB1Tag = 0x41324231; /* 'A2B1' */
12.358 +
12.359 + /**
12.360 + * ICC Profile Tag Signature: 'A2B2'.
12.361 + */
12.362 + public static final int icSigAToB2Tag = 0x41324232; /* 'A2B2' */
12.363 +
12.364 + /**
12.365 + * ICC Profile Tag Signature: 'bXYZ'.
12.366 + */
12.367 + public static final int icSigBlueColorantTag = 0x6258595A; /* 'bXYZ' */
12.368 +
12.369 + /**
12.370 + * ICC Profile Tag Signature: 'bXYZ'.
12.371 + * @since 1.5
12.372 + */
12.373 + public static final int icSigBlueMatrixColumnTag = 0x6258595A; /* 'bXYZ' */
12.374 +
12.375 + /**
12.376 + * ICC Profile Tag Signature: 'bTRC'.
12.377 + */
12.378 + public static final int icSigBlueTRCTag = 0x62545243; /* 'bTRC' */
12.379 +
12.380 + /**
12.381 + * ICC Profile Tag Signature: 'B2A0'.
12.382 + */
12.383 + public static final int icSigBToA0Tag = 0x42324130; /* 'B2A0' */
12.384 +
12.385 + /**
12.386 + * ICC Profile Tag Signature: 'B2A1'.
12.387 + */
12.388 + public static final int icSigBToA1Tag = 0x42324131; /* 'B2A1' */
12.389 +
12.390 + /**
12.391 + * ICC Profile Tag Signature: 'B2A2'.
12.392 + */
12.393 + public static final int icSigBToA2Tag = 0x42324132; /* 'B2A2' */
12.394 +
12.395 + /**
12.396 + * ICC Profile Tag Signature: 'calt'.
12.397 + */
12.398 + public static final int icSigCalibrationDateTimeTag = 0x63616C74;
12.399 + /* 'calt' */
12.400 +
12.401 + /**
12.402 + * ICC Profile Tag Signature: 'targ'.
12.403 + */
12.404 + public static final int icSigCharTargetTag = 0x74617267; /* 'targ' */
12.405 +
12.406 + /**
12.407 + * ICC Profile Tag Signature: 'cprt'.
12.408 + */
12.409 + public static final int icSigCopyrightTag = 0x63707274; /* 'cprt' */
12.410 +
12.411 + /**
12.412 + * ICC Profile Tag Signature: 'crdi'.
12.413 + */
12.414 + public static final int icSigCrdInfoTag = 0x63726469; /* 'crdi' */
12.415 +
12.416 + /**
12.417 + * ICC Profile Tag Signature: 'dmnd'.
12.418 + */
12.419 + public static final int icSigDeviceMfgDescTag = 0x646D6E64; /* 'dmnd' */
12.420 +
12.421 + /**
12.422 + * ICC Profile Tag Signature: 'dmdd'.
12.423 + */
12.424 + public static final int icSigDeviceModelDescTag = 0x646D6464; /* 'dmdd' */
12.425 +
12.426 + /**
12.427 + * ICC Profile Tag Signature: 'devs'.
12.428 + */
12.429 + public static final int icSigDeviceSettingsTag = 0x64657673; /* 'devs' */
12.430 +
12.431 + /**
12.432 + * ICC Profile Tag Signature: 'gamt'.
12.433 + */
12.434 + public static final int icSigGamutTag = 0x67616D74; /* 'gamt' */
12.435 +
12.436 + /**
12.437 + * ICC Profile Tag Signature: 'kTRC'.
12.438 + */
12.439 + public static final int icSigGrayTRCTag = 0x6b545243; /* 'kTRC' */
12.440 +
12.441 + /**
12.442 + * ICC Profile Tag Signature: 'gXYZ'.
12.443 + */
12.444 + public static final int icSigGreenColorantTag = 0x6758595A; /* 'gXYZ' */
12.445 +
12.446 + /**
12.447 + * ICC Profile Tag Signature: 'gXYZ'.
12.448 + * @since 1.5
12.449 + */
12.450 + public static final int icSigGreenMatrixColumnTag = 0x6758595A;/* 'gXYZ' */
12.451 +
12.452 + /**
12.453 + * ICC Profile Tag Signature: 'gTRC'.
12.454 + */
12.455 + public static final int icSigGreenTRCTag = 0x67545243; /* 'gTRC' */
12.456 +
12.457 + /**
12.458 + * ICC Profile Tag Signature: 'lumi'.
12.459 + */
12.460 + public static final int icSigLuminanceTag = 0x6C756d69; /* 'lumi' */
12.461 +
12.462 + /**
12.463 + * ICC Profile Tag Signature: 'meas'.
12.464 + */
12.465 + public static final int icSigMeasurementTag = 0x6D656173; /* 'meas' */
12.466 +
12.467 + /**
12.468 + * ICC Profile Tag Signature: 'bkpt'.
12.469 + */
12.470 + public static final int icSigMediaBlackPointTag = 0x626B7074; /* 'bkpt' */
12.471 +
12.472 + /**
12.473 + * ICC Profile Tag Signature: 'wtpt'.
12.474 + */
12.475 + public static final int icSigMediaWhitePointTag = 0x77747074; /* 'wtpt' */
12.476 +
12.477 + /**
12.478 + * ICC Profile Tag Signature: 'ncl2'.
12.479 + */
12.480 + public static final int icSigNamedColor2Tag = 0x6E636C32; /* 'ncl2' */
12.481 +
12.482 + /**
12.483 + * ICC Profile Tag Signature: 'resp'.
12.484 + */
12.485 + public static final int icSigOutputResponseTag = 0x72657370; /* 'resp' */
12.486 +
12.487 + /**
12.488 + * ICC Profile Tag Signature: 'pre0'.
12.489 + */
12.490 + public static final int icSigPreview0Tag = 0x70726530; /* 'pre0' */
12.491 +
12.492 + /**
12.493 + * ICC Profile Tag Signature: 'pre1'.
12.494 + */
12.495 + public static final int icSigPreview1Tag = 0x70726531; /* 'pre1' */
12.496 +
12.497 + /**
12.498 + * ICC Profile Tag Signature: 'pre2'.
12.499 + */
12.500 + public static final int icSigPreview2Tag = 0x70726532; /* 'pre2' */
12.501 +
12.502 + /**
12.503 + * ICC Profile Tag Signature: 'desc'.
12.504 + */
12.505 + public static final int icSigProfileDescriptionTag = 0x64657363;
12.506 + /* 'desc' */
12.507 +
12.508 + /**
12.509 + * ICC Profile Tag Signature: 'pseq'.
12.510 + */
12.511 + public static final int icSigProfileSequenceDescTag = 0x70736571;
12.512 + /* 'pseq' */
12.513 +
12.514 + /**
12.515 + * ICC Profile Tag Signature: 'psd0'.
12.516 + */
12.517 + public static final int icSigPs2CRD0Tag = 0x70736430; /* 'psd0' */
12.518 +
12.519 + /**
12.520 + * ICC Profile Tag Signature: 'psd1'.
12.521 + */
12.522 + public static final int icSigPs2CRD1Tag = 0x70736431; /* 'psd1' */
12.523 +
12.524 + /**
12.525 + * ICC Profile Tag Signature: 'psd2'.
12.526 + */
12.527 + public static final int icSigPs2CRD2Tag = 0x70736432; /* 'psd2' */
12.528 +
12.529 + /**
12.530 + * ICC Profile Tag Signature: 'psd3'.
12.531 + */
12.532 + public static final int icSigPs2CRD3Tag = 0x70736433; /* 'psd3' */
12.533 +
12.534 + /**
12.535 + * ICC Profile Tag Signature: 'ps2s'.
12.536 + */
12.537 + public static final int icSigPs2CSATag = 0x70733273; /* 'ps2s' */
12.538 +
12.539 + /**
12.540 + * ICC Profile Tag Signature: 'ps2i'.
12.541 + */
12.542 + public static final int icSigPs2RenderingIntentTag = 0x70733269;
12.543 + /* 'ps2i' */
12.544 +
12.545 + /**
12.546 + * ICC Profile Tag Signature: 'rXYZ'.
12.547 + */
12.548 + public static final int icSigRedColorantTag = 0x7258595A; /* 'rXYZ' */
12.549 +
12.550 + /**
12.551 + * ICC Profile Tag Signature: 'rXYZ'.
12.552 + * @since 1.5
12.553 + */
12.554 + public static final int icSigRedMatrixColumnTag = 0x7258595A; /* 'rXYZ' */
12.555 +
12.556 + /**
12.557 + * ICC Profile Tag Signature: 'rTRC'.
12.558 + */
12.559 + public static final int icSigRedTRCTag = 0x72545243; /* 'rTRC' */
12.560 +
12.561 + /**
12.562 + * ICC Profile Tag Signature: 'scrd'.
12.563 + */
12.564 + public static final int icSigScreeningDescTag = 0x73637264; /* 'scrd' */
12.565 +
12.566 + /**
12.567 + * ICC Profile Tag Signature: 'scrn'.
12.568 + */
12.569 + public static final int icSigScreeningTag = 0x7363726E; /* 'scrn' */
12.570 +
12.571 + /**
12.572 + * ICC Profile Tag Signature: 'tech'.
12.573 + */
12.574 + public static final int icSigTechnologyTag = 0x74656368; /* 'tech' */
12.575 +
12.576 + /**
12.577 + * ICC Profile Tag Signature: 'bfd '.
12.578 + */
12.579 + public static final int icSigUcrBgTag = 0x62666420; /* 'bfd ' */
12.580 +
12.581 + /**
12.582 + * ICC Profile Tag Signature: 'vued'.
12.583 + */
12.584 + public static final int icSigViewingCondDescTag = 0x76756564; /* 'vued' */
12.585 +
12.586 + /**
12.587 + * ICC Profile Tag Signature: 'view'.
12.588 + */
12.589 + public static final int icSigViewingConditionsTag = 0x76696577;/* 'view' */
12.590 +
12.591 + /**
12.592 + * ICC Profile Tag Signature: 'chrm'.
12.593 + */
12.594 + public static final int icSigChromaticityTag = 0x6368726d; /* 'chrm' */
12.595 +
12.596 + /**
12.597 + * ICC Profile Tag Signature: 'chad'.
12.598 + * @since 1.5
12.599 + */
12.600 + public static final int icSigChromaticAdaptationTag = 0x63686164;/* 'chad' */
12.601 +
12.602 + /**
12.603 + * ICC Profile Tag Signature: 'clro'.
12.604 + * @since 1.5
12.605 + */
12.606 + public static final int icSigColorantOrderTag = 0x636C726F; /* 'clro' */
12.607 +
12.608 + /**
12.609 + * ICC Profile Tag Signature: 'clrt'.
12.610 + * @since 1.5
12.611 + */
12.612 + public static final int icSigColorantTableTag = 0x636C7274; /* 'clrt' */
12.613 +
12.614 +
12.615 + /**
12.616 + * ICC Profile Header Location: profile size in bytes.
12.617 + */
12.618 + public static final int icHdrSize = 0; /* Profile size in bytes */
12.619 +
12.620 + /**
12.621 + * ICC Profile Header Location: CMM for this profile.
12.622 + */
12.623 + public static final int icHdrCmmId = 4; /* CMM for this profile */
12.624 +
12.625 + /**
12.626 + * ICC Profile Header Location: format version number.
12.627 + */
12.628 + public static final int icHdrVersion = 8; /* Format version number */
12.629 +
12.630 + /**
12.631 + * ICC Profile Header Location: type of profile.
12.632 + */
12.633 + public static final int icHdrDeviceClass = 12; /* Type of profile */
12.634 +
12.635 + /**
12.636 + * ICC Profile Header Location: color space of data.
12.637 + */
12.638 + public static final int icHdrColorSpace = 16; /* Color space of data */
12.639 +
12.640 + /**
12.641 + * ICC Profile Header Location: PCS - XYZ or Lab only.
12.642 + */
12.643 + public static final int icHdrPcs = 20; /* PCS - XYZ or Lab only */
12.644 +
12.645 + /**
12.646 + * ICC Profile Header Location: date profile was created.
12.647 + */
12.648 + public static final int icHdrDate = 24; /* Date profile was created */
12.649 +
12.650 + /**
12.651 + * ICC Profile Header Location: icMagicNumber.
12.652 + */
12.653 + public static final int icHdrMagic = 36; /* icMagicNumber */
12.654 +
12.655 + /**
12.656 + * ICC Profile Header Location: primary platform.
12.657 + */
12.658 + public static final int icHdrPlatform = 40; /* Primary Platform */
12.659 +
12.660 + /**
12.661 + * ICC Profile Header Location: various bit settings.
12.662 + */
12.663 + public static final int icHdrFlags = 44; /* Various bit settings */
12.664 +
12.665 + /**
12.666 + * ICC Profile Header Location: device manufacturer.
12.667 + */
12.668 + public static final int icHdrManufacturer = 48; /* Device manufacturer */
12.669 +
12.670 + /**
12.671 + * ICC Profile Header Location: device model number.
12.672 + */
12.673 + public static final int icHdrModel = 52; /* Device model number */
12.674 +
12.675 + /**
12.676 + * ICC Profile Header Location: device attributes.
12.677 + */
12.678 + public static final int icHdrAttributes = 56; /* Device attributes */
12.679 +
12.680 + /**
12.681 + * ICC Profile Header Location: rendering intent.
12.682 + */
12.683 + public static final int icHdrRenderingIntent = 64; /* Rendering intent */
12.684 +
12.685 + /**
12.686 + * ICC Profile Header Location: profile illuminant.
12.687 + */
12.688 + public static final int icHdrIlluminant = 68; /* Profile illuminant */
12.689 +
12.690 + /**
12.691 + * ICC Profile Header Location: profile creator.
12.692 + */
12.693 + public static final int icHdrCreator = 80; /* Profile creator */
12.694 +
12.695 + /**
12.696 + * ICC Profile Header Location: profile's ID.
12.697 + * @since 1.5
12.698 + */
12.699 + public static final int icHdrProfileID = 84; /* Profile's ID */
12.700 +
12.701 +
12.702 + /**
12.703 + * ICC Profile Constant: tag type signaturE.
12.704 + */
12.705 + public static final int icTagType = 0; /* tag type signature */
12.706 +
12.707 + /**
12.708 + * ICC Profile Constant: reserved.
12.709 + */
12.710 + public static final int icTagReserved = 4; /* reserved */
12.711 +
12.712 + /**
12.713 + * ICC Profile Constant: curveType count.
12.714 + */
12.715 + public static final int icCurveCount = 8; /* curveType count */
12.716 +
12.717 + /**
12.718 + * ICC Profile Constant: curveType data.
12.719 + */
12.720 + public static final int icCurveData = 12; /* curveType data */
12.721 +
12.722 + /**
12.723 + * ICC Profile Constant: XYZNumber X.
12.724 + */
12.725 + public static final int icXYZNumberX = 8; /* XYZNumber X */
12.726 +
12.727 +
12.728 + /**
12.729 + * Constructs an ICC_Profile object with a given ID.
12.730 + */
12.731 + ICC_Profile(long ID) {
12.732 + this.ID = ID;
12.733 + }
12.734 +
12.735 +
12.736 + /**
12.737 + * Constructs an ICC_Profile object whose loading will be deferred.
12.738 + * The ID will be 0 until the profile is loaded.
12.739 + */
12.740 + ICC_Profile(ProfileDeferralInfo pdi) {
12.741 + this.deferralInfo = pdi;
12.742 + this.profileActivator = new ProfileActivator() {
12.743 + public void activate() {
12.744 + activateDeferredProfile();
12.745 + }
12.746 + };
12.747 + ProfileDeferralMgr.registerDeferral(this.profileActivator);
12.748 + }
12.749 +
12.750 +
12.751 + /**
12.752 + * Frees the resources associated with an ICC_Profile object.
12.753 + */
12.754 + protected void finalize () {
12.755 + if (ID != 0) {
12.756 + CMSManager.getModule().freeProfile(ID);
12.757 + } else if (profileActivator != null) {
12.758 + ProfileDeferralMgr.unregisterDeferral(profileActivator);
12.759 + }
12.760 + }
12.761 +
12.762 +
12.763 + /**
12.764 + * Constructs an ICC_Profile object corresponding to the data in
12.765 + * a byte array. Throws an IllegalArgumentException if the data
12.766 + * does not correspond to a valid ICC Profile.
12.767 + * @param data the specified ICC Profile data
12.768 + * @return an <code>ICC_Profile</code> object corresponding to
12.769 + * the data in the specified <code>data</code> array.
12.770 + */
12.771 + public static ICC_Profile getInstance(byte[] data) {
12.772 + ICC_Profile thisProfile;
12.773 +
12.774 + long theID;
12.775 +
12.776 + if (ProfileDeferralMgr.deferring) {
12.777 + ProfileDeferralMgr.activateProfiles();
12.778 + }
12.779 +
12.780 + try {
12.781 + theID = CMSManager.getModule().loadProfile(data);
12.782 + } catch (CMMException c) {
12.783 + throw new IllegalArgumentException("Invalid ICC Profile Data");
12.784 + }
12.785 +
12.786 + try {
12.787 + if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) &&
12.788 + (getData (theID, icSigMediaWhitePointTag) != null) &&
12.789 + (getData (theID, icSigGrayTRCTag) != null)) {
12.790 + thisProfile = new ICC_ProfileGray (theID);
12.791 + }
12.792 + else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) &&
12.793 + (getData (theID, icSigMediaWhitePointTag) != null) &&
12.794 + (getData (theID, icSigRedColorantTag) != null) &&
12.795 + (getData (theID, icSigGreenColorantTag) != null) &&
12.796 + (getData (theID, icSigBlueColorantTag) != null) &&
12.797 + (getData (theID, icSigRedTRCTag) != null) &&
12.798 + (getData (theID, icSigGreenTRCTag) != null) &&
12.799 + (getData (theID, icSigBlueTRCTag) != null)) {
12.800 + thisProfile = new ICC_ProfileRGB (theID);
12.801 + }
12.802 + else {
12.803 + thisProfile = new ICC_Profile (theID);
12.804 + }
12.805 + } catch (CMMException c) {
12.806 + thisProfile = new ICC_Profile (theID);
12.807 + }
12.808 + return thisProfile;
12.809 + }
12.810 +
12.811 +
12.812 +
12.813 + /**
12.814 + * Constructs an ICC_Profile corresponding to one of the specific color
12.815 + * spaces defined by the ColorSpace class (for example CS_sRGB).
12.816 + * Throws an IllegalArgumentException if cspace is not one of the
12.817 + * defined color spaces.
12.818 + *
12.819 + * @param cspace the type of color space to create a profile for.
12.820 + * The specified type is one of the color
12.821 + * space constants defined in the <CODE>ColorSpace</CODE> class.
12.822 + *
12.823 + * @return an <code>ICC_Profile</code> object corresponding to
12.824 + * the specified <code>ColorSpace</code> type.
12.825 + * @exception IllegalArgumentException If <CODE>cspace</CODE> is not
12.826 + * one of the predefined color space types.
12.827 + */
12.828 + public static ICC_Profile getInstance (int cspace) {
12.829 + ICC_Profile thisProfile = null;
12.830 + String fileName;
12.831 +
12.832 + switch (cspace) {
12.833 + case ColorSpace.CS_sRGB:
12.834 + synchronized(ICC_Profile.class) {
12.835 + if (sRGBprofile == null) {
12.836 + try {
12.837 + /*
12.838 + * Deferral is only used for standard profiles.
12.839 + * Enabling the appropriate access privileges is handled
12.840 + * at a lower level.
12.841 + */
12.842 + sRGBprofile = getDeferredInstance(
12.843 + new ProfileDeferralInfo("sRGB.pf",
12.844 + ColorSpace.TYPE_RGB,
12.845 + 3, CLASS_DISPLAY));
12.846 + } catch (IOException e) {
12.847 + throw new IllegalArgumentException(
12.848 + "Can't load standard profile: sRGB.pf");
12.849 + }
12.850 + }
12.851 + thisProfile = sRGBprofile;
12.852 + }
12.853 +
12.854 + break;
12.855 +
12.856 + case ColorSpace.CS_CIEXYZ:
12.857 + synchronized(ICC_Profile.class) {
12.858 + if (XYZprofile == null) {
12.859 + XYZprofile = getStandardProfile("CIEXYZ.pf");
12.860 + }
12.861 + thisProfile = XYZprofile;
12.862 + }
12.863 +
12.864 + break;
12.865 +
12.866 + case ColorSpace.CS_PYCC:
12.867 + synchronized(ICC_Profile.class) {
12.868 + if (PYCCprofile == null) {
12.869 + PYCCprofile = getStandardProfile("PYCC.pf");
12.870 + }
12.871 + thisProfile = PYCCprofile;
12.872 + }
12.873 +
12.874 + break;
12.875 +
12.876 + case ColorSpace.CS_GRAY:
12.877 + synchronized(ICC_Profile.class) {
12.878 + if (GRAYprofile == null) {
12.879 + GRAYprofile = getStandardProfile("GRAY.pf");
12.880 + }
12.881 + thisProfile = GRAYprofile;
12.882 + }
12.883 +
12.884 + break;
12.885 +
12.886 + case ColorSpace.CS_LINEAR_RGB:
12.887 + synchronized(ICC_Profile.class) {
12.888 + if (LINEAR_RGBprofile == null) {
12.889 + LINEAR_RGBprofile = getStandardProfile("LINEAR_RGB.pf");
12.890 + }
12.891 + thisProfile = LINEAR_RGBprofile;
12.892 + }
12.893 +
12.894 + break;
12.895 +
12.896 + default:
12.897 + throw new IllegalArgumentException("Unknown color space");
12.898 + }
12.899 +
12.900 + return thisProfile;
12.901 + }
12.902 +
12.903 + /* This asserts system privileges, so is used only for the
12.904 + * standard profiles.
12.905 + */
12.906 + private static ICC_Profile getStandardProfile(final String name) {
12.907 +
12.908 + return (ICC_Profile) AccessController.doPrivileged(
12.909 + new PrivilegedAction() {
12.910 + public Object run() {
12.911 + ICC_Profile p = null;
12.912 + try {
12.913 + p = getInstance (name);
12.914 + } catch (IOException ex) {
12.915 + throw new IllegalArgumentException(
12.916 + "Can't load standard profile: " + name);
12.917 + }
12.918 + return p;
12.919 + }
12.920 + });
12.921 + }
12.922 +
12.923 + /**
12.924 + * Constructs an ICC_Profile corresponding to the data in a file.
12.925 + * fileName may be an absolute or a relative file specification.
12.926 + * Relative file names are looked for in several places: first, relative
12.927 + * to any directories specified by the java.iccprofile.path property;
12.928 + * second, relative to any directories specified by the java.class.path
12.929 + * property; finally, in a directory used to store profiles always
12.930 + * available, such as the profile for sRGB. Built-in profiles use .pf as
12.931 + * the file name extension for profiles, e.g. sRGB.pf.
12.932 + * This method throws an IOException if the specified file cannot be
12.933 + * opened or if an I/O error occurs while reading the file. It throws
12.934 + * an IllegalArgumentException if the file does not contain valid ICC
12.935 + * Profile data.
12.936 + * @param fileName The file that contains the data for the profile.
12.937 + *
12.938 + * @return an <code>ICC_Profile</code> object corresponding to
12.939 + * the data in the specified file.
12.940 + * @exception IOException If the specified file cannot be opened or
12.941 + * an I/O error occurs while reading the file.
12.942 + *
12.943 + * @exception IllegalArgumentException If the file does not
12.944 + * contain valid ICC Profile data.
12.945 + *
12.946 + * @exception SecurityException If a security manager is installed
12.947 + * and it does not permit read access to the given file.
12.948 + */
12.949 + public static ICC_Profile getInstance(String fileName) throws IOException {
12.950 + ICC_Profile thisProfile;
12.951 + FileInputStream fis;
12.952 +
12.953 + SecurityManager security = System.getSecurityManager();
12.954 + if (security != null) {
12.955 + security.checkRead(fileName);
12.956 + }
12.957 +
12.958 + if ((fis = openProfile(fileName)) == null) {
12.959 + throw new IOException("Cannot open file " + fileName);
12.960 + }
12.961 +
12.962 + thisProfile = getInstance(fis);
12.963 +
12.964 + fis.close(); /* close the file */
12.965 +
12.966 + return thisProfile;
12.967 + }
12.968 +
12.969 +
12.970 + /**
12.971 + * Constructs an ICC_Profile corresponding to the data in an InputStream.
12.972 + * This method throws an IllegalArgumentException if the stream does not
12.973 + * contain valid ICC Profile data. It throws an IOException if an I/O
12.974 + * error occurs while reading the stream.
12.975 + * @param s The input stream from which to read the profile data.
12.976 + *
12.977 + * @return an <CODE>ICC_Profile</CODE> object corresponding to the
12.978 + * data in the specified <code>InputStream</code>.
12.979 + *
12.980 + * @exception IOException If an I/O error occurs while reading the stream.
12.981 + *
12.982 + * @exception IllegalArgumentException If the stream does not
12.983 + * contain valid ICC Profile data.
12.984 + */
12.985 + public static ICC_Profile getInstance(InputStream s) throws IOException {
12.986 + byte profileData[];
12.987 +
12.988 + if (s instanceof ProfileDeferralInfo) {
12.989 + /* hack to detect profiles whose loading can be deferred */
12.990 + return getDeferredInstance((ProfileDeferralInfo) s);
12.991 + }
12.992 +
12.993 + if ((profileData = getProfileDataFromStream(s)) == null) {
12.994 + throw new IllegalArgumentException("Invalid ICC Profile Data");
12.995 + }
12.996 +
12.997 + return getInstance(profileData);
12.998 + }
12.999 +
12.1000 +
12.1001 + static byte[] getProfileDataFromStream(InputStream s) throws IOException {
12.1002 + byte profileData[];
12.1003 + int profileSize;
12.1004 +
12.1005 + byte header[] = new byte[128];
12.1006 + int bytestoread = 128;
12.1007 + int bytesread = 0;
12.1008 + int n;
12.1009 +
12.1010 + while (bytestoread != 0) {
12.1011 + if ((n = s.read(header, bytesread, bytestoread)) < 0) {
12.1012 + return null;
12.1013 + }
12.1014 + bytesread += n;
12.1015 + bytestoread -= n;
12.1016 + }
12.1017 + if (header[36] != 0x61 || header[37] != 0x63 ||
12.1018 + header[38] != 0x73 || header[39] != 0x70) {
12.1019 + return null; /* not a valid profile */
12.1020 + }
12.1021 + profileSize = ((header[0] & 0xff) << 24) |
12.1022 + ((header[1] & 0xff) << 16) |
12.1023 + ((header[2] & 0xff) << 8) |
12.1024 + (header[3] & 0xff);
12.1025 + profileData = new byte[profileSize];
12.1026 + System.arraycopy(header, 0, profileData, 0, 128);
12.1027 + bytestoread = profileSize - 128;
12.1028 + bytesread = 128;
12.1029 + while (bytestoread != 0) {
12.1030 + if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
12.1031 + return null;
12.1032 + }
12.1033 + bytesread += n;
12.1034 + bytestoread -= n;
12.1035 + }
12.1036 +
12.1037 + return profileData;
12.1038 + }
12.1039 +
12.1040 +
12.1041 + /**
12.1042 + * Constructs an ICC_Profile for which the actual loading of the
12.1043 + * profile data from a file and the initialization of the CMM should
12.1044 + * be deferred as long as possible.
12.1045 + * Deferral is only used for standard profiles.
12.1046 + * If deferring is disabled, then getStandardProfile() ensures
12.1047 + * that all of the appropriate access privileges are granted
12.1048 + * when loading this profile.
12.1049 + * If deferring is enabled, then the deferred activation
12.1050 + * code will take care of access privileges.
12.1051 + * @see activateDeferredProfile()
12.1052 + */
12.1053 + static ICC_Profile getDeferredInstance(ProfileDeferralInfo pdi)
12.1054 + throws IOException {
12.1055 +
12.1056 + if (!ProfileDeferralMgr.deferring) {
12.1057 + return getStandardProfile(pdi.filename);
12.1058 + }
12.1059 + if (pdi.colorSpaceType == ColorSpace.TYPE_RGB) {
12.1060 + return new ICC_ProfileRGB(pdi);
12.1061 + } else if (pdi.colorSpaceType == ColorSpace.TYPE_GRAY) {
12.1062 + return new ICC_ProfileGray(pdi);
12.1063 + } else {
12.1064 + return new ICC_Profile(pdi);
12.1065 + }
12.1066 + }
12.1067 +
12.1068 +
12.1069 + void activateDeferredProfile() {
12.1070 + byte profileData[];
12.1071 + FileInputStream fis;
12.1072 + String fileName = deferralInfo.filename;
12.1073 +
12.1074 + profileActivator = null;
12.1075 + deferralInfo = null;
12.1076 + if ((fis = openProfile(fileName)) == null) {
12.1077 + throw new IllegalArgumentException("Cannot open file " + fileName);
12.1078 + }
12.1079 + try {
12.1080 + profileData = getProfileDataFromStream(fis);
12.1081 + fis.close(); /* close the file */
12.1082 + }
12.1083 + catch (IOException e) {
12.1084 + throw new IllegalArgumentException("Invalid ICC Profile Data" +
12.1085 + fileName);
12.1086 + }
12.1087 + if (profileData == null) {
12.1088 + throw new IllegalArgumentException("Invalid ICC Profile Data" +
12.1089 + fileName);
12.1090 + }
12.1091 + try {
12.1092 + ID = CMSManager.getModule().loadProfile(profileData);
12.1093 + } catch (CMMException c) {
12.1094 + throw new IllegalArgumentException("Invalid ICC Profile Data" +
12.1095 + fileName);
12.1096 + }
12.1097 + }
12.1098 +
12.1099 +
12.1100 + /**
12.1101 + * Returns profile major version.
12.1102 + * @return The major version of the profile.
12.1103 + */
12.1104 + public int getMajorVersion() {
12.1105 + byte[] theHeader;
12.1106 +
12.1107 + theHeader = getData(icSigHead); /* getData will activate deferred
12.1108 + profiles if necessary */
12.1109 +
12.1110 + return (int) theHeader[8];
12.1111 + }
12.1112 +
12.1113 + /**
12.1114 + * Returns profile minor version.
12.1115 + * @return The minor version of the profile.
12.1116 + */
12.1117 + public int getMinorVersion() {
12.1118 + byte[] theHeader;
12.1119 +
12.1120 + theHeader = getData(icSigHead); /* getData will activate deferred
12.1121 + profiles if necessary */
12.1122 +
12.1123 + return (int) theHeader[9];
12.1124 + }
12.1125 +
12.1126 + /**
12.1127 + * Returns the profile class.
12.1128 + * @return One of the predefined profile class constants.
12.1129 + */
12.1130 + public int getProfileClass() {
12.1131 + byte[] theHeader;
12.1132 + int theClassSig, theClass;
12.1133 +
12.1134 + if (deferralInfo != null) {
12.1135 + return deferralInfo.profileClass; /* Need to have this info for
12.1136 + ICC_ColorSpace without
12.1137 + causing a deferred profile
12.1138 + to be loaded */
12.1139 + }
12.1140 +
12.1141 + theHeader = getData(icSigHead);
12.1142 +
12.1143 + theClassSig = intFromBigEndian (theHeader, icHdrDeviceClass);
12.1144 +
12.1145 + switch (theClassSig) {
12.1146 + case icSigInputClass:
12.1147 + theClass = CLASS_INPUT;
12.1148 + break;
12.1149 +
12.1150 + case icSigDisplayClass:
12.1151 + theClass = CLASS_DISPLAY;
12.1152 + break;
12.1153 +
12.1154 + case icSigOutputClass:
12.1155 + theClass = CLASS_OUTPUT;
12.1156 + break;
12.1157 +
12.1158 + case icSigLinkClass:
12.1159 + theClass = CLASS_DEVICELINK;
12.1160 + break;
12.1161 +
12.1162 + case icSigColorSpaceClass:
12.1163 + theClass = CLASS_COLORSPACECONVERSION;
12.1164 + break;
12.1165 +
12.1166 + case icSigAbstractClass:
12.1167 + theClass = CLASS_ABSTRACT;
12.1168 + break;
12.1169 +
12.1170 + case icSigNamedColorClass:
12.1171 + theClass = CLASS_NAMEDCOLOR;
12.1172 + break;
12.1173 +
12.1174 + default:
12.1175 + throw new IllegalArgumentException("Unknown profile class");
12.1176 + }
12.1177 +
12.1178 + return theClass;
12.1179 + }
12.1180 +
12.1181 + /**
12.1182 + * Returns the color space type. Returns one of the color space type
12.1183 + * constants defined by the ColorSpace class. This is the
12.1184 + * "input" color space of the profile. The type defines the
12.1185 + * number of components of the color space and the interpretation,
12.1186 + * e.g. TYPE_RGB identifies a color space with three components - red,
12.1187 + * green, and blue. It does not define the particular color
12.1188 + * characteristics of the space, e.g. the chromaticities of the
12.1189 + * primaries.
12.1190 + * @return One of the color space type constants defined in the
12.1191 + * <CODE>ColorSpace</CODE> class.
12.1192 + */
12.1193 + public int getColorSpaceType() {
12.1194 + if (deferralInfo != null) {
12.1195 + return deferralInfo.colorSpaceType; /* Need to have this info for
12.1196 + ICC_ColorSpace without
12.1197 + causing a deferred profile
12.1198 + to be loaded */
12.1199 + }
12.1200 + return getColorSpaceType(ID);
12.1201 + }
12.1202 +
12.1203 + static int getColorSpaceType(long profileID) {
12.1204 + byte[] theHeader;
12.1205 + int theColorSpaceSig, theColorSpace;
12.1206 +
12.1207 + theHeader = getData(profileID, icSigHead);
12.1208 + theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace);
12.1209 + theColorSpace = iccCStoJCS (theColorSpaceSig);
12.1210 + return theColorSpace;
12.1211 + }
12.1212 +
12.1213 + /**
12.1214 + * Returns the color space type of the Profile Connection Space (PCS).
12.1215 + * Returns one of the color space type constants defined by the
12.1216 + * ColorSpace class. This is the "output" color space of the
12.1217 + * profile. For an input, display, or output profile useful
12.1218 + * for tagging colors or images, this will be either TYPE_XYZ or
12.1219 + * TYPE_Lab and should be interpreted as the corresponding specific
12.1220 + * color space defined in the ICC specification. For a device
12.1221 + * link profile, this could be any of the color space type constants.
12.1222 + * @return One of the color space type constants defined in the
12.1223 + * <CODE>ColorSpace</CODE> class.
12.1224 + */
12.1225 + public int getPCSType() {
12.1226 + if (ProfileDeferralMgr.deferring) {
12.1227 + ProfileDeferralMgr.activateProfiles();
12.1228 + }
12.1229 + return getPCSType(ID);
12.1230 + }
12.1231 +
12.1232 +
12.1233 + static int getPCSType(long profileID) {
12.1234 + byte[] theHeader;
12.1235 + int thePCSSig, thePCS;
12.1236 +
12.1237 + theHeader = getData(profileID, icSigHead);
12.1238 + thePCSSig = intFromBigEndian(theHeader, icHdrPcs);
12.1239 + thePCS = iccCStoJCS(thePCSSig);
12.1240 + return thePCS;
12.1241 + }
12.1242 +
12.1243 +
12.1244 + /**
12.1245 + * Write this ICC_Profile to a file.
12.1246 + *
12.1247 + * @param fileName The file to write the profile data to.
12.1248 + *
12.1249 + * @exception IOException If the file cannot be opened for writing
12.1250 + * or an I/O error occurs while writing to the file.
12.1251 + */
12.1252 + public void write(String fileName) throws IOException {
12.1253 + FileOutputStream outputFile;
12.1254 + byte profileData[];
12.1255 +
12.1256 + profileData = getData(); /* this will activate deferred
12.1257 + profiles if necessary */
12.1258 + outputFile = new FileOutputStream(fileName);
12.1259 + outputFile.write(profileData);
12.1260 + outputFile.close ();
12.1261 + }
12.1262 +
12.1263 +
12.1264 + /**
12.1265 + * Write this ICC_Profile to an OutputStream.
12.1266 + *
12.1267 + * @param s The stream to write the profile data to.
12.1268 + *
12.1269 + * @exception IOException If an I/O error occurs while writing to the
12.1270 + * stream.
12.1271 + */
12.1272 + public void write(OutputStream s) throws IOException {
12.1273 + byte profileData[];
12.1274 +
12.1275 + profileData = getData(); /* this will activate deferred
12.1276 + profiles if necessary */
12.1277 + s.write(profileData);
12.1278 + }
12.1279 +
12.1280 +
12.1281 + /**
12.1282 + * Returns a byte array corresponding to the data of this ICC_Profile.
12.1283 + * @return A byte array that contains the profile data.
12.1284 + * @see #setData(int, byte[])
12.1285 + */
12.1286 + public byte[] getData() {
12.1287 + int profileSize;
12.1288 + byte[] profileData;
12.1289 +
12.1290 + if (ProfileDeferralMgr.deferring) {
12.1291 + ProfileDeferralMgr.activateProfiles();
12.1292 + }
12.1293 +
12.1294 + PCMM mdl = CMSManager.getModule();
12.1295 +
12.1296 + /* get the number of bytes needed for this profile */
12.1297 + profileSize = mdl.getProfileSize(ID);
12.1298 +
12.1299 + profileData = new byte [profileSize];
12.1300 +
12.1301 + /* get the data for the profile */
12.1302 + mdl.getProfileData(ID, profileData);
12.1303 +
12.1304 + return profileData;
12.1305 + }
12.1306 +
12.1307 +
12.1308 + /**
12.1309 + * Returns a particular tagged data element from the profile as
12.1310 + * a byte array. Elements are identified by signatures
12.1311 + * as defined in the ICC specification. The signature
12.1312 + * icSigHead can be used to get the header. This method is useful
12.1313 + * for advanced applets or applications which need to access
12.1314 + * profile data directly.
12.1315 + *
12.1316 + * @param tagSignature The ICC tag signature for the data element you
12.1317 + * want to get.
12.1318 + *
12.1319 + * @return A byte array that contains the tagged data element. Returns
12.1320 + * <code>null</code> if the specified tag doesn't exist.
12.1321 + * @see #setData(int, byte[])
12.1322 + */
12.1323 + public byte[] getData(int tagSignature) {
12.1324 +
12.1325 + if (ProfileDeferralMgr.deferring) {
12.1326 + ProfileDeferralMgr.activateProfiles();
12.1327 + }
12.1328 +
12.1329 + return getData(ID, tagSignature);
12.1330 + }
12.1331 +
12.1332 +
12.1333 + static byte[] getData(long profileID, int tagSignature) {
12.1334 + int tagSize;
12.1335 + byte[] tagData;
12.1336 +
12.1337 + try {
12.1338 + PCMM mdl = CMSManager.getModule();
12.1339 +
12.1340 + /* get the number of bytes needed for this tag */
12.1341 + tagSize = mdl.getTagSize(profileID, tagSignature);
12.1342 +
12.1343 + tagData = new byte[tagSize]; /* get an array for the tag */
12.1344 +
12.1345 + /* get the tag's data */
12.1346 + mdl.getTagData(profileID, tagSignature, tagData);
12.1347 + } catch(CMMException c) {
12.1348 + tagData = null;
12.1349 + }
12.1350 +
12.1351 + return tagData;
12.1352 + }
12.1353 +
12.1354 + /**
12.1355 + * Sets a particular tagged data element in the profile from
12.1356 + * a byte array. This method is useful
12.1357 + * for advanced applets or applications which need to access
12.1358 + * profile data directly.
12.1359 + *
12.1360 + * @param tagSignature The ICC tag signature for the data element
12.1361 + * you want to set.
12.1362 + * @param tagData the data to set for the specified tag signature
12.1363 + * @see #getData
12.1364 + */
12.1365 + public void setData(int tagSignature, byte[] tagData) {
12.1366 +
12.1367 + if (ProfileDeferralMgr.deferring) {
12.1368 + ProfileDeferralMgr.activateProfiles();
12.1369 + }
12.1370 +
12.1371 + CMSManager.getModule().setTagData(ID, tagSignature, tagData);
12.1372 + }
12.1373 +
12.1374 + /**
12.1375 + * Sets the rendering intent of the profile.
12.1376 + * This is used to select the proper transform from a profile that
12.1377 + * has multiple transforms.
12.1378 + */
12.1379 + void setRenderingIntent(int renderingIntent) {
12.1380 + byte[] theHeader = getData(icSigHead);/* getData will activate deferred
12.1381 + profiles if necessary */
12.1382 + intToBigEndian (renderingIntent, theHeader, icHdrRenderingIntent);
12.1383 + /* set the rendering intent */
12.1384 + setData (icSigHead, theHeader);
12.1385 + }
12.1386 +
12.1387 +
12.1388 + /**
12.1389 + * Returns the rendering intent of the profile.
12.1390 + * This is used to select the proper transform from a profile that
12.1391 + * has multiple transforms. It is typically set in a source profile
12.1392 + * to select a transform from an output profile.
12.1393 + */
12.1394 + int getRenderingIntent() {
12.1395 + byte[] theHeader = getData(icSigHead);/* getData will activate deferred
12.1396 + profiles if necessary */
12.1397 +
12.1398 + int renderingIntent = intFromBigEndian(theHeader, icHdrRenderingIntent);
12.1399 + /* set the rendering intent */
12.1400 + return renderingIntent;
12.1401 + }
12.1402 +
12.1403 +
12.1404 + /**
12.1405 + * Returns the number of color components in the "input" color
12.1406 + * space of this profile. For example if the color space type
12.1407 + * of this profile is TYPE_RGB, then this method will return 3.
12.1408 + *
12.1409 + * @return The number of color components in the profile's input
12.1410 + * color space.
12.1411 + *
12.1412 + * @throws ProfileDataException if color space is in the profile
12.1413 + * is invalid
12.1414 + */
12.1415 + public int getNumComponents() {
12.1416 + byte[] theHeader;
12.1417 + int theColorSpaceSig, theNumComponents;
12.1418 +
12.1419 + if (deferralInfo != null) {
12.1420 + return deferralInfo.numComponents; /* Need to have this info for
12.1421 + ICC_ColorSpace without
12.1422 + causing a deferred profile
12.1423 + to be loaded */
12.1424 + }
12.1425 + theHeader = getData(icSigHead);
12.1426 +
12.1427 + theColorSpaceSig = intFromBigEndian (theHeader, icHdrColorSpace);
12.1428 +
12.1429 + switch (theColorSpaceSig) {
12.1430 + case icSigGrayData:
12.1431 + theNumComponents = 1;
12.1432 + break;
12.1433 +
12.1434 + case icSigSpace2CLR:
12.1435 + theNumComponents = 2;
12.1436 + break;
12.1437 +
12.1438 + case icSigXYZData:
12.1439 + case icSigLabData:
12.1440 + case icSigLuvData:
12.1441 + case icSigYCbCrData:
12.1442 + case icSigYxyData:
12.1443 + case icSigRgbData:
12.1444 + case icSigHsvData:
12.1445 + case icSigHlsData:
12.1446 + case icSigCmyData:
12.1447 + case icSigSpace3CLR:
12.1448 + theNumComponents = 3;
12.1449 + break;
12.1450 +
12.1451 + case icSigCmykData:
12.1452 + case icSigSpace4CLR:
12.1453 + theNumComponents = 4;
12.1454 + break;
12.1455 +
12.1456 + case icSigSpace5CLR:
12.1457 + theNumComponents = 5;
12.1458 + break;
12.1459 +
12.1460 + case icSigSpace6CLR:
12.1461 + theNumComponents = 6;
12.1462 + break;
12.1463 +
12.1464 + case icSigSpace7CLR:
12.1465 + theNumComponents = 7;
12.1466 + break;
12.1467 +
12.1468 + case icSigSpace8CLR:
12.1469 + theNumComponents = 8;
12.1470 + break;
12.1471 +
12.1472 + case icSigSpace9CLR:
12.1473 + theNumComponents = 9;
12.1474 + break;
12.1475 +
12.1476 + case icSigSpaceACLR:
12.1477 + theNumComponents = 10;
12.1478 + break;
12.1479 +
12.1480 + case icSigSpaceBCLR:
12.1481 + theNumComponents = 11;
12.1482 + break;
12.1483 +
12.1484 + case icSigSpaceCCLR:
12.1485 + theNumComponents = 12;
12.1486 + break;
12.1487 +
12.1488 + case icSigSpaceDCLR:
12.1489 + theNumComponents = 13;
12.1490 + break;
12.1491 +
12.1492 + case icSigSpaceECLR:
12.1493 + theNumComponents = 14;
12.1494 + break;
12.1495 +
12.1496 + case icSigSpaceFCLR:
12.1497 + theNumComponents = 15;
12.1498 + break;
12.1499 +
12.1500 + default:
12.1501 + throw new ProfileDataException ("invalid ICC color space");
12.1502 + }
12.1503 +
12.1504 + return theNumComponents;
12.1505 + }
12.1506 +
12.1507 +
12.1508 + /**
12.1509 + * Returns a float array of length 3 containing the X, Y, and Z
12.1510 + * components of the mediaWhitePointTag in the ICC profile.
12.1511 + */
12.1512 + float[] getMediaWhitePoint() {
12.1513 + return getXYZTag(icSigMediaWhitePointTag);
12.1514 + /* get the media white point tag */
12.1515 + }
12.1516 +
12.1517 +
12.1518 + /**
12.1519 + * Returns a float array of length 3 containing the X, Y, and Z
12.1520 + * components encoded in an XYZType tag.
12.1521 + */
12.1522 + float[] getXYZTag(int theTagSignature) {
12.1523 + byte[] theData;
12.1524 + float[] theXYZNumber;
12.1525 + int i1, i2, theS15Fixed16;
12.1526 +
12.1527 + theData = getData(theTagSignature); /* get the tag data */
12.1528 + /* getData will activate deferred
12.1529 + profiles if necessary */
12.1530 +
12.1531 + theXYZNumber = new float [3]; /* array to return */
12.1532 +
12.1533 + /* convert s15Fixed16Number to float */
12.1534 + for (i1 = 0, i2 = icXYZNumberX; i1 < 3; i1++, i2 += 4) {
12.1535 + theS15Fixed16 = intFromBigEndian(theData, i2);
12.1536 + theXYZNumber [i1] = ((float) theS15Fixed16) / 65536.0f;
12.1537 + }
12.1538 + return theXYZNumber;
12.1539 + }
12.1540 +
12.1541 +
12.1542 + /**
12.1543 + * Returns a gamma value representing a tone reproduction
12.1544 + * curve (TRC). If the profile represents the TRC as a table rather
12.1545 + * than a single gamma value, then an exception is thrown. In this
12.1546 + * case the actual table can be obtained via getTRC().
12.1547 + * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
12.1548 + * icSigGreenTRCTag, or icSigBlueTRCTag.
12.1549 + * @return the gamma value as a float.
12.1550 + * @exception ProfileDataException if the profile does not specify
12.1551 + * the TRC as a single gamma value.
12.1552 + */
12.1553 + float getGamma(int theTagSignature) {
12.1554 + byte[] theTRCData;
12.1555 + float theGamma;
12.1556 + int theU8Fixed8;
12.1557 +
12.1558 + theTRCData = getData(theTagSignature); /* get the TRC */
12.1559 + /* getData will activate deferred
12.1560 + profiles if necessary */
12.1561 +
12.1562 + if (intFromBigEndian (theTRCData, icCurveCount) != 1) {
12.1563 + throw new ProfileDataException ("TRC is not a gamma");
12.1564 + }
12.1565 +
12.1566 + /* convert u8Fixed8 to float */
12.1567 + theU8Fixed8 = (shortFromBigEndian(theTRCData, icCurveData)) & 0xffff;
12.1568 +
12.1569 + theGamma = ((float) theU8Fixed8) / 256.0f;
12.1570 +
12.1571 + return theGamma;
12.1572 + }
12.1573 +
12.1574 +
12.1575 + /**
12.1576 + * Returns the TRC as an array of shorts. If the profile has
12.1577 + * specified the TRC as linear (gamma = 1.0) or as a simple gamma
12.1578 + * value, this method throws an exception, and the getGamma() method
12.1579 + * should be used to get the gamma value. Otherwise the short array
12.1580 + * returned here represents a lookup table where the input Gray value
12.1581 + * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
12.1582 + * to array index 0 and value 1.0 maps to array index length-1.
12.1583 + * Interpolation may be used to generate output values for
12.1584 + * input values which do not map exactly to an index in the
12.1585 + * array. Output values also map linearly to the range [0.0, 1.0].
12.1586 + * Value 0.0 is represented by an array value of 0x0000 and
12.1587 + * value 1.0 by 0xFFFF, i.e. the values are really unsigned
12.1588 + * short values, although they are returned in a short array.
12.1589 + * theTagSignature should be one of icSigGrayTRCTag, icSigRedTRCTag,
12.1590 + * icSigGreenTRCTag, or icSigBlueTRCTag.
12.1591 + * @return a short array representing the TRC.
12.1592 + * @exception ProfileDataException if the profile does not specify
12.1593 + * the TRC as a table.
12.1594 + */
12.1595 + short[] getTRC(int theTagSignature) {
12.1596 + byte[] theTRCData;
12.1597 + short[] theTRC;
12.1598 + int i1, i2, nElements, theU8Fixed8;
12.1599 +
12.1600 + theTRCData = getData(theTagSignature); /* get the TRC */
12.1601 + /* getData will activate deferred
12.1602 + profiles if necessary */
12.1603 +
12.1604 + nElements = intFromBigEndian(theTRCData, icCurveCount);
12.1605 +
12.1606 + if (nElements == 1) {
12.1607 + throw new ProfileDataException("TRC is not a table");
12.1608 + }
12.1609 +
12.1610 + /* make the short array */
12.1611 + theTRC = new short [nElements];
12.1612 +
12.1613 + for (i1 = 0, i2 = icCurveData; i1 < nElements; i1++, i2 += 2) {
12.1614 + theTRC[i1] = shortFromBigEndian(theTRCData, i2);
12.1615 + }
12.1616 +
12.1617 + return theTRC;
12.1618 + }
12.1619 +
12.1620 +
12.1621 + /* convert an ICC color space signature into a Java color space type */
12.1622 + static int iccCStoJCS(int theColorSpaceSig) {
12.1623 + int theColorSpace;
12.1624 +
12.1625 + switch (theColorSpaceSig) {
12.1626 + case icSigXYZData:
12.1627 + theColorSpace = ColorSpace.TYPE_XYZ;
12.1628 + break;
12.1629 +
12.1630 + case icSigLabData:
12.1631 + theColorSpace = ColorSpace.TYPE_Lab;
12.1632 + break;
12.1633 +
12.1634 + case icSigLuvData:
12.1635 + theColorSpace = ColorSpace.TYPE_Luv;
12.1636 + break;
12.1637 +
12.1638 + case icSigYCbCrData:
12.1639 + theColorSpace = ColorSpace.TYPE_YCbCr;
12.1640 + break;
12.1641 +
12.1642 + case icSigYxyData:
12.1643 + theColorSpace = ColorSpace.TYPE_Yxy;
12.1644 + break;
12.1645 +
12.1646 + case icSigRgbData:
12.1647 + theColorSpace = ColorSpace.TYPE_RGB;
12.1648 + break;
12.1649 +
12.1650 + case icSigGrayData:
12.1651 + theColorSpace = ColorSpace.TYPE_GRAY;
12.1652 + break;
12.1653 +
12.1654 + case icSigHsvData:
12.1655 + theColorSpace = ColorSpace.TYPE_HSV;
12.1656 + break;
12.1657 +
12.1658 + case icSigHlsData:
12.1659 + theColorSpace = ColorSpace.TYPE_HLS;
12.1660 + break;
12.1661 +
12.1662 + case icSigCmykData:
12.1663 + theColorSpace = ColorSpace.TYPE_CMYK;
12.1664 + break;
12.1665 +
12.1666 + case icSigCmyData:
12.1667 + theColorSpace = ColorSpace.TYPE_CMY;
12.1668 + break;
12.1669 +
12.1670 + case icSigSpace2CLR:
12.1671 + theColorSpace = ColorSpace.TYPE_2CLR;
12.1672 + break;
12.1673 +
12.1674 + case icSigSpace3CLR:
12.1675 + theColorSpace = ColorSpace.TYPE_3CLR;
12.1676 + break;
12.1677 +
12.1678 + case icSigSpace4CLR:
12.1679 + theColorSpace = ColorSpace.TYPE_4CLR;
12.1680 + break;
12.1681 +
12.1682 + case icSigSpace5CLR:
12.1683 + theColorSpace = ColorSpace.TYPE_5CLR;
12.1684 + break;
12.1685 +
12.1686 + case icSigSpace6CLR:
12.1687 + theColorSpace = ColorSpace.TYPE_6CLR;
12.1688 + break;
12.1689 +
12.1690 + case icSigSpace7CLR:
12.1691 + theColorSpace = ColorSpace.TYPE_7CLR;
12.1692 + break;
12.1693 +
12.1694 + case icSigSpace8CLR:
12.1695 + theColorSpace = ColorSpace.TYPE_8CLR;
12.1696 + break;
12.1697 +
12.1698 + case icSigSpace9CLR:
12.1699 + theColorSpace = ColorSpace.TYPE_9CLR;
12.1700 + break;
12.1701 +
12.1702 + case icSigSpaceACLR:
12.1703 + theColorSpace = ColorSpace.TYPE_ACLR;
12.1704 + break;
12.1705 +
12.1706 + case icSigSpaceBCLR:
12.1707 + theColorSpace = ColorSpace.TYPE_BCLR;
12.1708 + break;
12.1709 +
12.1710 + case icSigSpaceCCLR:
12.1711 + theColorSpace = ColorSpace.TYPE_CCLR;
12.1712 + break;
12.1713 +
12.1714 + case icSigSpaceDCLR:
12.1715 + theColorSpace = ColorSpace.TYPE_DCLR;
12.1716 + break;
12.1717 +
12.1718 + case icSigSpaceECLR:
12.1719 + theColorSpace = ColorSpace.TYPE_ECLR;
12.1720 + break;
12.1721 +
12.1722 + case icSigSpaceFCLR:
12.1723 + theColorSpace = ColorSpace.TYPE_FCLR;
12.1724 + break;
12.1725 +
12.1726 + default:
12.1727 + throw new IllegalArgumentException ("Unknown color space");
12.1728 + }
12.1729 +
12.1730 + return theColorSpace;
12.1731 + }
12.1732 +
12.1733 +
12.1734 + static int intFromBigEndian(byte[] array, int index) {
12.1735 + return (((array[index] & 0xff) << 24) |
12.1736 + ((array[index+1] & 0xff) << 16) |
12.1737 + ((array[index+2] & 0xff) << 8) |
12.1738 + (array[index+3] & 0xff));
12.1739 + }
12.1740 +
12.1741 +
12.1742 + static void intToBigEndian(int value, byte[] array, int index) {
12.1743 + array[index] = (byte) (value >> 24);
12.1744 + array[index+1] = (byte) (value >> 16);
12.1745 + array[index+2] = (byte) (value >> 8);
12.1746 + array[index+3] = (byte) (value);
12.1747 + }
12.1748 +
12.1749 +
12.1750 + static short shortFromBigEndian(byte[] array, int index) {
12.1751 + return (short) (((array[index] & 0xff) << 8) |
12.1752 + (array[index+1] & 0xff));
12.1753 + }
12.1754 +
12.1755 +
12.1756 + static void shortToBigEndian(short value, byte[] array, int index) {
12.1757 + array[index] = (byte) (value >> 8);
12.1758 + array[index+1] = (byte) (value);
12.1759 + }
12.1760 +
12.1761 +
12.1762 + /*
12.1763 + * fileName may be an absolute or a relative file specification.
12.1764 + * Relative file names are looked for in several places: first, relative
12.1765 + * to any directories specified by the java.iccprofile.path property;
12.1766 + * second, relative to any directories specified by the java.class.path
12.1767 + * property; finally, in a directory used to store profiles always
12.1768 + * available, such as a profile for sRGB. Built-in profiles use .pf as
12.1769 + * the file name extension for profiles, e.g. sRGB.pf.
12.1770 + */
12.1771 + private static FileInputStream openProfile(final String fileName) {
12.1772 + return (FileInputStream)java.security.AccessController.doPrivileged(
12.1773 + new java.security.PrivilegedAction() {
12.1774 + public Object run() {
12.1775 + return privilegedOpenProfile(fileName);
12.1776 + }
12.1777 + });
12.1778 + }
12.1779 +
12.1780 + /*
12.1781 + * this version is called from doPrivileged in privilegedOpenProfile.
12.1782 + * the whole method is privileged!
12.1783 + */
12.1784 + private static FileInputStream privilegedOpenProfile(String fileName) {
12.1785 + FileInputStream fis = null;
12.1786 + String path, dir, fullPath;
12.1787 +
12.1788 + File f = new File(fileName); /* try absolute file name */
12.1789 +
12.1790 + if ((!f.isFile()) &&
12.1791 + ((path = System.getProperty("java.iccprofile.path")) != null)){
12.1792 + /* try relative to java.iccprofile.path */
12.1793 + StringTokenizer st =
12.1794 + new StringTokenizer(path, File.pathSeparator);
12.1795 + while (st.hasMoreTokens() && (!f.isFile())) {
12.1796 + dir = st.nextToken();
12.1797 + fullPath = dir + File.separatorChar + fileName;
12.1798 + f = new File(fullPath);
12.1799 + }
12.1800 + }
12.1801 +
12.1802 + if ((!f.isFile()) &&
12.1803 + ((path = System.getProperty("java.class.path")) != null)) {
12.1804 + /* try relative to java.class.path */
12.1805 + StringTokenizer st =
12.1806 + new StringTokenizer(path, File.pathSeparator);
12.1807 + while (st.hasMoreTokens() && (!f.isFile())) {
12.1808 + dir = st.nextToken();
12.1809 + fullPath = dir + File.separatorChar + fileName;
12.1810 + f = new File(fullPath);
12.1811 + }
12.1812 + }
12.1813 +
12.1814 + if (!f.isFile()) { /* try the directory of built-in profiles */
12.1815 + dir = System.getProperty("java.home") +
12.1816 + File.separatorChar + "lib" + File.separatorChar + "cmm";
12.1817 + fullPath = dir + File.separatorChar + fileName;
12.1818 + f = new File(fullPath);
12.1819 + }
12.1820 +
12.1821 + if (f.isFile()) {
12.1822 + try {
12.1823 + fis = new FileInputStream(f);
12.1824 + } catch (FileNotFoundException e) {
12.1825 + }
12.1826 + }
12.1827 + return fis;
12.1828 + }
12.1829 +
12.1830 +
12.1831 + /*
12.1832 + * Serialization support.
12.1833 + *
12.1834 + * Directly deserialized profiles are useless since they are not
12.1835 + * registered with CMM. We don't allow constructor to be called
12.1836 + * directly and instead have clients to call one of getInstance
12.1837 + * factory methods that will register the profile with CMM. For
12.1838 + * deserialization we implement readResolve method that will
12.1839 + * resolve the bogus deserialized profile object with one obtained
12.1840 + * with getInstance as well.
12.1841 + *
12.1842 + * There're two primary factory methods for construction of ICC
12.1843 + * profiles: getInstance(int cspace) and getInstance(byte[] data).
12.1844 + * This implementation of ICC_Profile uses the former to return a
12.1845 + * cached singleton profile object, other implementations will
12.1846 + * likely use this technique too. To preserve the singleton
12.1847 + * pattern across serialization we serialize cached singleton
12.1848 + * profiles in such a way that deserializing VM could call
12.1849 + * getInstance(int cspace) method that will resolve deserialized
12.1850 + * object into the corresponding singleton as well.
12.1851 + *
12.1852 + * Since the singletons are private to ICC_Profile the readResolve
12.1853 + * method have to be `protected' instead of `private' so that
12.1854 + * singletons that are instances of subclasses of ICC_Profile
12.1855 + * could be correctly deserialized.
12.1856 + */
12.1857 +
12.1858 +
12.1859 + /**
12.1860 + * Version of the format of additional serialized data in the
12.1861 + * stream. Version <code>1</code> corresponds to Java 2
12.1862 + * Platform, v1.3.
12.1863 + * @since 1.3
12.1864 + * @serial
12.1865 + */
12.1866 + private int iccProfileSerializedDataVersion = 1;
12.1867 +
12.1868 +
12.1869 + /**
12.1870 + * Writes default serializable fields to the stream. Writes a
12.1871 + * string and an array of bytes to the stream as additional data.
12.1872 + *
12.1873 + * @param s stream used for serialization.
12.1874 + * @throws IOException
12.1875 + * thrown by <code>ObjectInputStream</code>.
12.1876 + * @serialData
12.1877 + * The <code>String</code> is the name of one of
12.1878 + * <code>CS_<var>*</var></code> constants defined in the
12.1879 + * {@link ColorSpace} class if the profile object is a profile
12.1880 + * for a predefined color space (for example
12.1881 + * <code>"CS_sRGB"</code>). The string is <code>null</code>
12.1882 + * otherwise.
12.1883 + * <p>
12.1884 + * The <code>byte[]</code> array is the profile data for the
12.1885 + * profile. For predefined color spaces <code>null</code> is
12.1886 + * written instead of the profile data. If in the future
12.1887 + * versions of Java API new predefined color spaces will be
12.1888 + * added, future versions of this class may choose to write
12.1889 + * for new predefined color spaces not only the color space
12.1890 + * name, but the profile data as well so that older versions
12.1891 + * could still deserialize the object.
12.1892 + */
12.1893 + private void writeObject(ObjectOutputStream s)
12.1894 + throws IOException
12.1895 + {
12.1896 + s.defaultWriteObject();
12.1897 +
12.1898 + String csName = null;
12.1899 + if (this == sRGBprofile) {
12.1900 + csName = "CS_sRGB";
12.1901 + } else if (this == XYZprofile) {
12.1902 + csName = "CS_CIEXYZ";
12.1903 + } else if (this == PYCCprofile) {
12.1904 + csName = "CS_PYCC";
12.1905 + } else if (this == GRAYprofile) {
12.1906 + csName = "CS_GRAY";
12.1907 + } else if (this == LINEAR_RGBprofile) {
12.1908 + csName = "CS_LINEAR_RGB";
12.1909 + }
12.1910 +
12.1911 + // Future versions may choose to write profile data for new
12.1912 + // predefined color spaces as well, if any will be introduced,
12.1913 + // so that old versions that don't recognize the new CS name
12.1914 + // may fall back to constructing profile from the data.
12.1915 + byte[] data = null;
12.1916 + if (csName == null) {
12.1917 + // getData will activate deferred profile if necessary
12.1918 + data = getData();
12.1919 + }
12.1920 +
12.1921 + s.writeObject(csName);
12.1922 + s.writeObject(data);
12.1923 + }
12.1924 +
12.1925 + // Temporary storage used by readObject to store resolved profile
12.1926 + // (obtained with getInstance) for readResolve to return.
12.1927 + private transient ICC_Profile resolvedDeserializedProfile;
12.1928 +
12.1929 + /**
12.1930 + * Reads default serializable fields from the stream. Reads from
12.1931 + * the stream a string and an array of bytes as additional data.
12.1932 + *
12.1933 + * @param s stream used for deserialization.
12.1934 + * @throws IOException
12.1935 + * thrown by <code>ObjectInputStream</code>.
12.1936 + * @throws ClassNotFoundException
12.1937 + * thrown by <code>ObjectInputStream</code>.
12.1938 + * @serialData
12.1939 + * The <code>String</code> is the name of one of
12.1940 + * <code>CS_<var>*</var></code> constants defined in the
12.1941 + * {@link ColorSpace} class if the profile object is a profile
12.1942 + * for a predefined color space (for example
12.1943 + * <code>"CS_sRGB"</code>). The string is <code>null</code>
12.1944 + * otherwise.
12.1945 + * <p>
12.1946 + * The <code>byte[]</code> array is the profile data for the
12.1947 + * profile. It will usually be <code>null</code> for the
12.1948 + * predefined profiles.
12.1949 + * <p>
12.1950 + * If the string is recognized as a constant name for
12.1951 + * predefined color space the object will be resolved into
12.1952 + * profile obtained with
12.1953 + * <code>getInstance(int cspace)</code> and the profile
12.1954 + * data are ignored. Otherwise the object will be resolved
12.1955 + * into profile obtained with
12.1956 + * <code>getInstance(byte[] data)</code>.
12.1957 + * @see #readResolve()
12.1958 + * @see #getInstance(int)
12.1959 + * @see #getInstance(byte[])
12.1960 + */
12.1961 + private void readObject(ObjectInputStream s)
12.1962 + throws IOException, ClassNotFoundException
12.1963 + {
12.1964 + s.defaultReadObject();
12.1965 +
12.1966 + String csName = (String)s.readObject();
12.1967 + byte[] data = (byte[])s.readObject();
12.1968 +
12.1969 + int cspace = 0; // ColorSpace.CS_* constant if known
12.1970 + boolean isKnownPredefinedCS = false;
12.1971 + if (csName != null) {
12.1972 + isKnownPredefinedCS = true;
12.1973 + if (csName.equals("CS_sRGB")) {
12.1974 + cspace = ColorSpace.CS_sRGB;
12.1975 + } else if (csName.equals("CS_CIEXYZ")) {
12.1976 + cspace = ColorSpace.CS_CIEXYZ;
12.1977 + } else if (csName.equals("CS_PYCC")) {
12.1978 + cspace = ColorSpace.CS_PYCC;
12.1979 + } else if (csName.equals("CS_GRAY")) {
12.1980 + cspace = ColorSpace.CS_GRAY;
12.1981 + } else if (csName.equals("CS_LINEAR_RGB")) {
12.1982 + cspace = ColorSpace.CS_LINEAR_RGB;
12.1983 + } else {
12.1984 + isKnownPredefinedCS = false;
12.1985 + }
12.1986 + }
12.1987 +
12.1988 + if (isKnownPredefinedCS) {
12.1989 + resolvedDeserializedProfile = getInstance(cspace);
12.1990 + } else {
12.1991 + resolvedDeserializedProfile = getInstance(data);
12.1992 + }
12.1993 + }
12.1994 +
12.1995 + /**
12.1996 + * Resolves instances being deserialized into instances registered
12.1997 + * with CMM.
12.1998 + * @return ICC_Profile object for profile registered with CMM.
12.1999 + * @throws ObjectStreamException
12.2000 + * never thrown, but mandated by the serialization spec.
12.2001 + * @since 1.3
12.2002 + */
12.2003 + protected Object readResolve() throws ObjectStreamException {
12.2004 + return resolvedDeserializedProfile;
12.2005 + }
12.2006 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/src/share/classes/java/awt/color/ICC_ProfileGray.java Thu Jun 12 11:46:57 2008 -0700
13.3 @@ -0,0 +1,150 @@
13.4 +/*
13.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 + *
13.8 + * This code is free software; you can redistribute it and/or modify it
13.9 + * under the terms of the GNU General Public License version 2 only, as
13.10 + * published by the Free Software Foundation. Sun designates this
13.11 + * particular file as subject to the "Classpath" exception as provided
13.12 + * by Sun in the LICENSE file that accompanied this code.
13.13 + *
13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 + * version 2 for more details (a copy is included in the LICENSE file that
13.18 + * accompanied this code).
13.19 + *
13.20 + * You should have received a copy of the GNU General Public License version
13.21 + * 2 along with this work; if not, write to the Free Software Foundation,
13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 + *
13.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
13.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
13.26 + * have any questions.
13.27 + */
13.28 +
13.29 +/**********************************************************************
13.30 + **********************************************************************
13.31 + **********************************************************************
13.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
13.33 + *** As an unpublished work pursuant to Title 17 of the United ***
13.34 + *** States Code. All rights reserved. ***
13.35 + **********************************************************************
13.36 + **********************************************************************
13.37 + **********************************************************************/
13.38 +
13.39 +package java.awt.color;
13.40 +
13.41 +import java.awt.image.LookupTable;
13.42 +import sun.java2d.cmm.ProfileDeferralInfo;
13.43 +
13.44 +/**
13.45 + *
13.46 + * A subclass of the ICC_Profile class which represents profiles
13.47 + * which meet the following criteria: the color space type of the
13.48 + * profile is TYPE_GRAY and the profile includes the grayTRCTag and
13.49 + * mediaWhitePointTag tags. Examples of this kind of profile are
13.50 + * monochrome input profiles, monochrome display profiles, and
13.51 + * monochrome output profiles. The getInstance methods in the
13.52 + * ICC_Profile class will
13.53 + * return an ICC_ProfileGray object when the above conditions are
13.54 + * met. The advantage of this class is that it provides a lookup
13.55 + * table that Java or native methods may be able to use directly to
13.56 + * optimize color conversion in some cases.
13.57 + * <p>
13.58 + * To transform from a GRAY device profile color space to the CIEXYZ Profile
13.59 + * Connection Space, the device gray component is transformed by
13.60 + * a lookup through the tone reproduction curve (TRC). The result is
13.61 + * treated as the achromatic component of the PCS.
13.62 +<pre>
13.63 +
13.64 + PCSY = grayTRC[deviceGray]
13.65 +
13.66 +</pre>
13.67 + * The inverse transform is done by converting the PCS Y components to
13.68 + * device Gray via the inverse of the grayTRC.
13.69 + * <p>
13.70 + */
13.71 +
13.72 +
13.73 +
13.74 +public class ICC_ProfileGray
13.75 +extends ICC_Profile {
13.76 +
13.77 + static final long serialVersionUID = -1124721290732002649L;
13.78 +
13.79 + /**
13.80 + * Constructs a new ICC_ProfileGray from a CMM ID.
13.81 + */
13.82 + ICC_ProfileGray(long ID) {
13.83 + super(ID);
13.84 + }
13.85 +
13.86 + /**
13.87 + * Constructs a new ICC_ProfileGray from a ProfileDeferralInfo object.
13.88 + */
13.89 + ICC_ProfileGray(ProfileDeferralInfo pdi) {
13.90 + super(pdi);
13.91 + }
13.92 +
13.93 +
13.94 + /**
13.95 + * Returns a float array of length 3 containing the X, Y, and Z
13.96 + * components of the mediaWhitePointTag in the ICC profile.
13.97 + * @return an array containing the components of the
13.98 + * mediaWhitePointTag in the ICC profile.
13.99 + */
13.100 + public float[] getMediaWhitePoint() {
13.101 + return super.getMediaWhitePoint();
13.102 + }
13.103 +
13.104 +
13.105 + /**
13.106 + * Returns a gamma value representing the tone reproduction
13.107 + * curve (TRC). If the profile represents the TRC as a table rather
13.108 + * than a single gamma value, then an exception is thrown. In this
13.109 + * case the actual table can be obtained via getTRC(). When
13.110 + * using a gamma value, the PCS Y component is computed as follows:
13.111 +<pre>
13.112 +
13.113 + gamma
13.114 + PCSY = deviceGray
13.115 +
13.116 +</pre>
13.117 + * @return the gamma value as a float.
13.118 + * @exception ProfileDataException if the profile does not specify
13.119 + * the TRC as a single gamma value.
13.120 + */
13.121 + public float getGamma() {
13.122 + float theGamma;
13.123 +
13.124 + theGamma = super.getGamma(ICC_Profile.icSigGrayTRCTag);
13.125 + return theGamma;
13.126 + }
13.127 +
13.128 + /**
13.129 + * Returns the TRC as an array of shorts. If the profile has
13.130 + * specified the TRC as linear (gamma = 1.0) or as a simple gamma
13.131 + * value, this method throws an exception, and the getGamma() method
13.132 + * should be used to get the gamma value. Otherwise the short array
13.133 + * returned here represents a lookup table where the input Gray value
13.134 + * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
13.135 + * to array index 0 and value 1.0 maps to array index length-1.
13.136 + * Interpolation may be used to generate output values for
13.137 + * input values which do not map exactly to an index in the
13.138 + * array. Output values also map linearly to the range [0.0, 1.0].
13.139 + * Value 0.0 is represented by an array value of 0x0000 and
13.140 + * value 1.0 by 0xFFFF, i.e. the values are really unsigned
13.141 + * short values, although they are returned in a short array.
13.142 + * @return a short array representing the TRC.
13.143 + * @exception ProfileDataException if the profile does not specify
13.144 + * the TRC as a table.
13.145 + */
13.146 + public short[] getTRC() {
13.147 + short[] theTRC;
13.148 +
13.149 + theTRC = super.getTRC(ICC_Profile.icSigGrayTRCTag);
13.150 + return theTRC;
13.151 + }
13.152 +
13.153 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/src/share/classes/java/awt/color/ICC_ProfileRGB.java Thu Jun 12 11:46:57 2008 -0700
14.3 @@ -0,0 +1,282 @@
14.4 +/*
14.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 + *
14.8 + * This code is free software; you can redistribute it and/or modify it
14.9 + * under the terms of the GNU General Public License version 2 only, as
14.10 + * published by the Free Software Foundation. Sun designates this
14.11 + * particular file as subject to the "Classpath" exception as provided
14.12 + * by Sun in the LICENSE file that accompanied this code.
14.13 + *
14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 + * version 2 for more details (a copy is included in the LICENSE file that
14.18 + * accompanied this code).
14.19 + *
14.20 + * You should have received a copy of the GNU General Public License version
14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 + *
14.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
14.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
14.26 + * have any questions.
14.27 + */
14.28 +
14.29 +/**********************************************************************
14.30 + **********************************************************************
14.31 + **********************************************************************
14.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
14.33 + *** As an unpublished work pursuant to Title 17 of the United ***
14.34 + *** States Code. All rights reserved. ***
14.35 + **********************************************************************
14.36 + **********************************************************************
14.37 + **********************************************************************/
14.38 +
14.39 +package java.awt.color;
14.40 +
14.41 +import java.awt.image.LookupTable;
14.42 +import sun.java2d.cmm.ProfileDeferralInfo;
14.43 +
14.44 +/**
14.45 + *
14.46 + * The ICC_ProfileRGB class is a subclass of the ICC_Profile class
14.47 + * that represents profiles which meet the following criteria:
14.48 + * <ul>
14.49 + * <li>The profile's color space type is RGB.</li>
14.50 + * <li>The profile includes the <code>redColorantTag</code>,
14.51 + * <code>greenColorantTag</code>, <code>blueColorantTag</code>,
14.52 + * <code>redTRCTag</code>, <code>greenTRCTag</code>,
14.53 + * <code>blueTRCTag</code>, and <code>mediaWhitePointTag</code> tags.</li>
14.54 + * </ul>
14.55 + * The <code>ICC_Profile</code> <code>getInstance</code> method will
14.56 + * return an <code>ICC_ProfileRGB</code> object when these conditions are met.
14.57 + * Three-component, matrix-based input profiles and RGB display profiles are
14.58 + * examples of this type of profile.
14.59 + * <p>
14.60 + * This profile class provides color transform matrices and lookup tables
14.61 + * that Java or native methods can use directly to
14.62 + * optimize color conversion in some cases.
14.63 + * <p>
14.64 + * To transform from a device profile color space to the CIEXYZ Profile
14.65 + * Connection Space, each device color component is first linearized by
14.66 + * a lookup through the corresponding tone reproduction curve (TRC).
14.67 + * The resulting linear RGB components are converted to the CIEXYZ PCS
14.68 + * using a a 3x3 matrix constructed from the RGB colorants.
14.69 + * <pre>
14.70 + *
14.71 + * linearR = redTRC[deviceR]
14.72 + *
14.73 + * linearG = greenTRC[deviceG]
14.74 + *
14.75 + * linearB = blueTRC[deviceB]
14.76 + *
14.77 + * _ _ _ _ _ _
14.78 + * [ PCSX ] [ redColorantX greenColorantX blueColorantX ] [ linearR ]
14.79 + * [ ] [ ] [ ]
14.80 + * [ PCSY ] = [ redColorantY greenColorantY blueColorantY ] [ linearG ]
14.81 + * [ ] [ ] [ ]
14.82 + * [_ PCSZ _] [_ redColorantZ greenColorantZ blueColorantZ _] [_ linearB _]
14.83 + *
14.84 + * </pre>
14.85 + * The inverse transform is performed by converting PCS XYZ components to linear
14.86 + * RGB components through the inverse of the above 3x3 matrix, and then converting
14.87 + * linear RGB to device RGB through inverses of the TRCs.
14.88 + * <p>
14.89 + */
14.90 +
14.91 +
14.92 +
14.93 +public class ICC_ProfileRGB
14.94 +extends ICC_Profile {
14.95 +
14.96 + static final long serialVersionUID = 8505067385152579334L;
14.97 +
14.98 + /**
14.99 + * Used to get a gamma value or TRC for the red component.
14.100 + */
14.101 + public static final int REDCOMPONENT = 0;
14.102 +
14.103 + /**
14.104 + * Used to get a gamma value or TRC for the green component.
14.105 + */
14.106 + public static final int GREENCOMPONENT = 1;
14.107 +
14.108 + /**
14.109 + * Used to get a gamma value or TRC for the blue component.
14.110 + */
14.111 + public static final int BLUECOMPONENT = 2;
14.112 +
14.113 +
14.114 + /**
14.115 + * Constructs an new <code>ICC_ProfileRGB</code> from a CMM ID.
14.116 + *
14.117 + * @param ID The CMM ID for the profile.
14.118 + *
14.119 + */
14.120 + ICC_ProfileRGB(long ID) {
14.121 + super(ID);
14.122 + }
14.123 +
14.124 + /**
14.125 + * Constructs a new <code>ICC_ProfileRGB</code> from a
14.126 + * ProfileDeferralInfo object.
14.127 + *
14.128 + * @param pdi
14.129 + */
14.130 + ICC_ProfileRGB(ProfileDeferralInfo pdi) {
14.131 + super(pdi);
14.132 + }
14.133 +
14.134 +
14.135 + /**
14.136 + * Returns an array that contains the components of the profile's
14.137 + * <CODE>mediaWhitePointTag</CODE>.
14.138 + *
14.139 + * @return A 3-element <CODE>float</CODE> array containing the x, y,
14.140 + * and z components of the profile's <CODE>mediaWhitePointTag</CODE>.
14.141 + */
14.142 + public float[] getMediaWhitePoint() {
14.143 + return super.getMediaWhitePoint();
14.144 + }
14.145 +
14.146 +
14.147 + /**
14.148 + * Returns a 3x3 <CODE>float</CODE> matrix constructed from the
14.149 + * X, Y, and Z components of the profile's <CODE>redColorantTag</CODE>,
14.150 + * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
14.151 + * <p>
14.152 + * This matrix can be used for color transforms in the forward
14.153 + * direction of the profile--from the profile color space
14.154 + * to the CIEXYZ PCS.
14.155 + *
14.156 + * @return A 3x3 <CODE>float</CODE> array that contains the x, y, and z
14.157 + * components of the profile's <CODE>redColorantTag</CODE>,
14.158 + * <CODE>greenColorantTag</CODE>, and <CODE>blueColorantTag</CODE>.
14.159 + */
14.160 + public float[][] getMatrix() {
14.161 + float[][] theMatrix = new float[3][3];
14.162 + float[] tmpMatrix;
14.163 +
14.164 + tmpMatrix = getXYZTag(ICC_Profile.icSigRedColorantTag);
14.165 + theMatrix[0][0] = tmpMatrix[0];
14.166 + theMatrix[1][0] = tmpMatrix[1];
14.167 + theMatrix[2][0] = tmpMatrix[2];
14.168 + tmpMatrix = getXYZTag(ICC_Profile.icSigGreenColorantTag);
14.169 + theMatrix[0][1] = tmpMatrix[0];
14.170 + theMatrix[1][1] = tmpMatrix[1];
14.171 + theMatrix[2][1] = tmpMatrix[2];
14.172 + tmpMatrix = getXYZTag(ICC_Profile.icSigBlueColorantTag);
14.173 + theMatrix[0][2] = tmpMatrix[0];
14.174 + theMatrix[1][2] = tmpMatrix[1];
14.175 + theMatrix[2][2] = tmpMatrix[2];
14.176 + return theMatrix;
14.177 + }
14.178 +
14.179 + /**
14.180 + * Returns a gamma value representing the tone reproduction curve
14.181 + * (TRC) for a particular component. The component parameter
14.182 + * must be one of REDCOMPONENT, GREENCOMPONENT, or BLUECOMPONENT.
14.183 + * <p>
14.184 + * If the profile
14.185 + * represents the TRC for the corresponding component
14.186 + * as a table rather than a single gamma value, an
14.187 + * exception is thrown. In this case the actual table
14.188 + * can be obtained through the {@link #getTRC(int)} method.
14.189 + * When using a gamma value,
14.190 + * the linear component (R, G, or B) is computed as follows:
14.191 + * <pre>
14.192 + *
14.193 + * gamma
14.194 + * linearComponent = deviceComponent
14.195 + *
14.196 + *</pre>
14.197 + * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
14.198 + * represents the component whose TRC you want to retrieve
14.199 + * @return the gamma value as a float.
14.200 + * @exception ProfileDataException if the profile does not specify
14.201 + * the corresponding TRC as a single gamma value.
14.202 + */
14.203 + public float getGamma(int component) {
14.204 + float theGamma;
14.205 + int theSignature;
14.206 +
14.207 + switch (component) {
14.208 + case REDCOMPONENT:
14.209 + theSignature = ICC_Profile.icSigRedTRCTag;
14.210 + break;
14.211 +
14.212 + case GREENCOMPONENT:
14.213 + theSignature = ICC_Profile.icSigGreenTRCTag;
14.214 + break;
14.215 +
14.216 + case BLUECOMPONENT:
14.217 + theSignature = ICC_Profile.icSigBlueTRCTag;
14.218 + break;
14.219 +
14.220 + default:
14.221 + throw new IllegalArgumentException("Must be Red, Green, or Blue");
14.222 + }
14.223 +
14.224 + theGamma = super.getGamma(theSignature);
14.225 +
14.226 + return theGamma;
14.227 + }
14.228 +
14.229 + /**
14.230 + * Returns the TRC for a particular component as an array.
14.231 + * Component must be <code>REDCOMPONENT</code>,
14.232 + * <code>GREENCOMPONENT</code>, or <code>BLUECOMPONENT</code>.
14.233 + * Otherwise the returned array
14.234 + * represents a lookup table where the input component value
14.235 + * is conceptually in the range [0.0, 1.0]. Value 0.0 maps
14.236 + * to array index 0 and value 1.0 maps to array index length-1.
14.237 + * Interpolation might be used to generate output values for
14.238 + * input values that do not map exactly to an index in the
14.239 + * array. Output values also map linearly to the range [0.0, 1.0].
14.240 + * Value 0.0 is represented by an array value of 0x0000 and
14.241 + * value 1.0 by 0xFFFF. In other words, the values are really unsigned
14.242 + * <code>short</code> values even though they are returned in a
14.243 + * <code>short</code> array.
14.244 + *
14.245 + * If the profile has specified the corresponding TRC
14.246 + * as linear (gamma = 1.0) or as a simple gamma value, this method
14.247 + * throws an exception. In this case, the {@link #getGamma(int)}
14.248 + * method should be used to get the gamma value.
14.249 + *
14.250 + * @param component The <CODE>ICC_ProfileRGB</CODE> constant that
14.251 + * represents the component whose TRC you want to retrieve:
14.252 + * <CODE>REDCOMPONENT</CODE>, <CODE>GREENCOMPONENT</CODE>, or
14.253 + * <CODE>BLUECOMPONENT</CODE>.
14.254 + *
14.255 + * @return a short array representing the TRC.
14.256 + * @exception ProfileDataException if the profile does not specify
14.257 + * the corresponding TRC as a table.
14.258 + */
14.259 + public short[] getTRC(int component) {
14.260 + short[] theTRC;
14.261 + int theSignature;
14.262 +
14.263 + switch (component) {
14.264 + case REDCOMPONENT:
14.265 + theSignature = ICC_Profile.icSigRedTRCTag;
14.266 + break;
14.267 +
14.268 + case GREENCOMPONENT:
14.269 + theSignature = ICC_Profile.icSigGreenTRCTag;
14.270 + break;
14.271 +
14.272 + case BLUECOMPONENT:
14.273 + theSignature = ICC_Profile.icSigBlueTRCTag;
14.274 + break;
14.275 +
14.276 + default:
14.277 + throw new IllegalArgumentException("Must be Red, Green, or Blue");
14.278 + }
14.279 +
14.280 + theTRC = super.getTRC(theSignature);
14.281 +
14.282 + return theTRC;
14.283 + }
14.284 +
14.285 +}
15.1 --- a/src/share/classes/java/awt/dnd/DragSourceContext.java Tue Jun 10 16:31:26 2008 -0700
15.2 +++ b/src/share/classes/java/awt/dnd/DragSourceContext.java Thu Jun 12 11:46:57 2008 -0700
15.3 @@ -1,5 +1,5 @@
15.4 /*
15.5 - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
15.6 + * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.8 *
15.9 * This code is free software; you can redistribute it and/or modify it
15.10 @@ -485,7 +485,6 @@
15.11
15.12 Cursor c = null;
15.13
15.14 - targetAct = DnDConstants.ACTION_NONE;
15.15 switch (status) {
15.16 case ENTER:
15.17 case OVER:
15.18 @@ -507,6 +506,10 @@
15.19 else
15.20 c = DragSource.DefaultCopyDrop;
15.21 }
15.22 + break;
15.23 + default:
15.24 + targetAct = DnDConstants.ACTION_NONE;
15.25 +
15.26 }
15.27
15.28 setCursorImpl(c);
16.1 --- a/src/share/classes/java/awt/font/OpenType.java Tue Jun 10 16:31:26 2008 -0700
16.2 +++ b/src/share/classes/java/awt/font/OpenType.java Thu Jun 12 11:46:57 2008 -0700
16.3 @@ -31,9 +31,9 @@
16.4 * <i>sfnt</i> tables from the font. A particular
16.5 * <code>Font</code> object can implement this interface.
16.6 * <p>
16.7 - * For more information on TrueType fonts, see the
16.8 - * Apple TrueType Reference Manual
16.9 - * ( <a href="http://fonts.apple.com/TTRefMan/index.html">http://fonts.apple.com/TTRefMan/index.html</a> ).
16.10 + * For more information on TrueType and OpenType fonts, see the
16.11 + * OpenType specification.
16.12 + * ( <a href=http://www.microsoft.com/typography/otspec/">http://www.microsoft.com/typography/otspec/l</a> ).
16.13 */
16.14 public interface OpenType {
16.15
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/src/share/classes/java/awt/image/BandedSampleModel.java Thu Jun 12 11:46:57 2008 -0700
17.3 @@ -0,0 +1,839 @@
17.4 +/*
17.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
17.7 + *
17.8 + * This code is free software; you can redistribute it and/or modify it
17.9 + * under the terms of the GNU General Public License version 2 only, as
17.10 + * published by the Free Software Foundation. Sun designates this
17.11 + * particular file as subject to the "Classpath" exception as provided
17.12 + * by Sun in the LICENSE file that accompanied this code.
17.13 + *
17.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
17.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17.17 + * version 2 for more details (a copy is included in the LICENSE file that
17.18 + * accompanied this code).
17.19 + *
17.20 + * You should have received a copy of the GNU General Public License version
17.21 + * 2 along with this work; if not, write to the Free Software Foundation,
17.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17.23 + *
17.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
17.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
17.26 + * have any questions.
17.27 + */
17.28 +
17.29 +/* ****************************************************************
17.30 + ******************************************************************
17.31 + ******************************************************************
17.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
17.33 + *** As an unpublished work pursuant to Title 17 of the United
17.34 + *** States Code. All rights reserved.
17.35 + ******************************************************************
17.36 + ******************************************************************
17.37 + ******************************************************************/
17.38 +
17.39 +package java.awt.image;
17.40 +
17.41 +/**
17.42 + * This class represents image data which is stored in a band interleaved
17.43 + * fashion and for
17.44 + * which each sample of a pixel occupies one data element of the DataBuffer.
17.45 + * It subclasses ComponentSampleModel but provides a more efficent
17.46 + * implementation for accessing band interleaved image data than is provided
17.47 + * by ComponentSampleModel. This class should typically be used when working
17.48 + * with images which store sample data for each band in a different bank of the
17.49 + * DataBuffer. Accessor methods are provided so that image data can be
17.50 + * manipulated directly. Pixel stride is the number of
17.51 + * data array elements between two samples for the same band on the same
17.52 + * scanline. The pixel stride for a BandedSampleModel is one.
17.53 + * Scanline stride is the number of data array elements between
17.54 + * a given sample and the corresponding sample in the same column of the next
17.55 + * scanline. Band offsets denote the number
17.56 + * of data array elements from the first data array element of the bank
17.57 + * of the DataBuffer holding each band to the first sample of the band.
17.58 + * The bands are numbered from 0 to N-1.
17.59 + * Bank indices denote the correspondence between a bank of the data buffer
17.60 + * and a band of image data. This class supports
17.61 + * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
17.62 + * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
17.63 + * {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
17.64 + * {@link DataBuffer#TYPE_INT TYPE_INT},
17.65 + * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT}, and
17.66 + * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE} datatypes
17.67 + */
17.68 +
17.69 +
17.70 +public final class BandedSampleModel extends ComponentSampleModel
17.71 +{
17.72 +
17.73 + /**
17.74 + * Constructs a BandedSampleModel with the specified parameters.
17.75 + * The pixel stride will be one data element. The scanline stride
17.76 + * will be the same as the width. Each band will be stored in
17.77 + * a separate bank and all band offsets will be zero.
17.78 + * @param dataType The data type for storing samples.
17.79 + * @param w The width (in pixels) of the region of
17.80 + * image data described.
17.81 + * @param h The height (in pixels) of the region of image
17.82 + * data described.
17.83 + * @param numBands The number of bands for the image data.
17.84 + * @throws IllegalArgumentException if <code>dataType</code> is not
17.85 + * one of the supported data types
17.86 + */
17.87 + public BandedSampleModel(int dataType, int w, int h, int numBands) {
17.88 + super(dataType, w, h, 1, w,
17.89 + BandedSampleModel.createIndicesArray(numBands),
17.90 + BandedSampleModel.createOffsetArray(numBands));
17.91 + }
17.92 +
17.93 + /**
17.94 + * Constructs a BandedSampleModel with the specified parameters.
17.95 + * The number of bands will be inferred from the lengths of the
17.96 + * bandOffsets bankIndices arrays, which must be equal. The pixel
17.97 + * stride will be one data element.
17.98 + * @param dataType The data type for storing samples.
17.99 + * @param w The width (in pixels) of the region of
17.100 + * image data described.
17.101 + * @param h The height (in pixels) of the region of
17.102 + * image data described.
17.103 + * @param scanlineStride The line stride of the of the image data.
17.104 + * @param bankIndices The bank index for each band.
17.105 + * @param bandOffsets The band offset for each band.
17.106 + * @throws IllegalArgumentException if <code>dataType</code> is not
17.107 + * one of the supported data types
17.108 + */
17.109 + public BandedSampleModel(int dataType,
17.110 + int w, int h,
17.111 + int scanlineStride,
17.112 + int bankIndices[],
17.113 + int bandOffsets[]) {
17.114 +
17.115 + super(dataType, w, h, 1,scanlineStride, bankIndices, bandOffsets);
17.116 + }
17.117 +
17.118 + /**
17.119 + * Creates a new BandedSampleModel with the specified
17.120 + * width and height. The new BandedSampleModel will have the same
17.121 + * number of bands, storage data type, and bank indices
17.122 + * as this BandedSampleModel. The band offsets will be compressed
17.123 + * such that the offset between bands will be w*pixelStride and
17.124 + * the minimum of all of the band offsets is zero.
17.125 + * @param w the width of the resulting <code>BandedSampleModel</code>
17.126 + * @param h the height of the resulting <code>BandedSampleModel</code>
17.127 + * @return a new <code>BandedSampleModel</code> with the specified
17.128 + * width and height.
17.129 + * @throws IllegalArgumentException if <code>w</code> or
17.130 + * <code>h</code> equals either
17.131 + * <code>Integer.MAX_VALUE</code> or
17.132 + * <code>Integer.MIN_VALUE</code>
17.133 + * @throws IllegalArgumentException if <code>dataType</code> is not
17.134 + * one of the supported data types
17.135 + */
17.136 + public SampleModel createCompatibleSampleModel(int w, int h) {
17.137 + int[] bandOffs;
17.138 +
17.139 + if (numBanks == 1) {
17.140 + bandOffs = orderBands(bandOffsets, w*h);
17.141 + }
17.142 + else {
17.143 + bandOffs = new int[bandOffsets.length];
17.144 + }
17.145 +
17.146 + SampleModel sampleModel =
17.147 + new BandedSampleModel(dataType, w, h, w, bankIndices, bandOffs);
17.148 + return sampleModel;
17.149 + }
17.150 +
17.151 + /**
17.152 + * Creates a new BandedSampleModel with a subset of the bands of this
17.153 + * BandedSampleModel. The new BandedSampleModel can be
17.154 + * used with any DataBuffer that the existing BandedSampleModel
17.155 + * can be used with. The new BandedSampleModel/DataBuffer
17.156 + * combination will represent an image with a subset of the bands
17.157 + * of the original BandedSampleModel/DataBuffer combination.
17.158 + * @throws RasterFormatException if the number of bands is greater than
17.159 + * the number of banks in this sample model.
17.160 + * @throws IllegalArgumentException if <code>dataType</code> is not
17.161 + * one of the supported data types
17.162 + */
17.163 + public SampleModel createSubsetSampleModel(int bands[]) {
17.164 + if (bands.length > bankIndices.length)
17.165 + throw new RasterFormatException("There are only " +
17.166 + bankIndices.length +
17.167 + " bands");
17.168 + int newBankIndices[] = new int[bands.length];
17.169 + int newBandOffsets[] = new int[bands.length];
17.170 +
17.171 + for (int i=0; i<bands.length; i++) {
17.172 + newBankIndices[i] = bankIndices[bands[i]];
17.173 + newBandOffsets[i] = bandOffsets[bands[i]];
17.174 + }
17.175 +
17.176 + return new BandedSampleModel(this.dataType, width, height,
17.177 + this.scanlineStride,
17.178 + newBankIndices, newBandOffsets);
17.179 + }
17.180 +
17.181 + /**
17.182 + * Creates a DataBuffer that corresponds to this BandedSampleModel,
17.183 + * The DataBuffer's data type, number of banks, and size
17.184 + * will be consistent with this BandedSampleModel.
17.185 + * @throws IllegalArgumentException if <code>dataType</code> is not
17.186 + * one of the supported types.
17.187 + */
17.188 + public DataBuffer createDataBuffer() {
17.189 + DataBuffer dataBuffer = null;
17.190 +
17.191 + int size = scanlineStride * height;
17.192 + switch (dataType) {
17.193 + case DataBuffer.TYPE_BYTE:
17.194 + dataBuffer = new DataBufferByte(size, numBanks);
17.195 + break;
17.196 + case DataBuffer.TYPE_USHORT:
17.197 + dataBuffer = new DataBufferUShort(size, numBanks);
17.198 + break;
17.199 + case DataBuffer.TYPE_SHORT:
17.200 + dataBuffer = new DataBufferShort(size, numBanks);
17.201 + break;
17.202 + case DataBuffer.TYPE_INT:
17.203 + dataBuffer = new DataBufferInt(size, numBanks);
17.204 + break;
17.205 + case DataBuffer.TYPE_FLOAT:
17.206 + dataBuffer = new DataBufferFloat(size, numBanks);
17.207 + break;
17.208 + case DataBuffer.TYPE_DOUBLE:
17.209 + dataBuffer = new DataBufferDouble(size, numBanks);
17.210 + break;
17.211 + default:
17.212 + throw new IllegalArgumentException("dataType is not one " +
17.213 + "of the supported types.");
17.214 + }
17.215 +
17.216 + return dataBuffer;
17.217 + }
17.218 +
17.219 +
17.220 + /**
17.221 + * Returns data for a single pixel in a primitive array of type
17.222 + * TransferType. For a BandedSampleModel, this will be the same
17.223 + * as the data type, and samples will be returned one per array
17.224 + * element. Generally, obj
17.225 + * should be passed in as null, so that the Object will be created
17.226 + * automatically and will be of the right primitive data type.
17.227 + * <p>
17.228 + * The following code illustrates transferring data for one pixel from
17.229 + * DataBuffer <code>db1</code>, whose storage layout is described by
17.230 + * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
17.231 + * whose storage layout is described by
17.232 + * BandedSampleModel <code>bsm2</code>.
17.233 + * The transfer will generally be more efficient than using
17.234 + * getPixel/setPixel.
17.235 + * <pre>
17.236 + * BandedSampleModel bsm1, bsm2;
17.237 + * DataBufferInt db1, db2;
17.238 + * bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
17.239 + * db2);
17.240 + * </pre>
17.241 + * Using getDataElements/setDataElements to transfer between two
17.242 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
17.243 + * the same number of bands, corresponding bands have the same number of
17.244 + * bits per sample, and the TransferTypes are the same.
17.245 + * <p>
17.246 + * If obj is non-null, it should be a primitive array of type TransferType.
17.247 + * Otherwise, a ClassCastException is thrown. An
17.248 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.249 + * not in bounds, or if obj is non-null and is not large enough to hold
17.250 + * the pixel data.
17.251 + * @param x The X coordinate of the pixel location
17.252 + * @param y The Y coordinate of the pixel location
17.253 + * @param obj If non-null, a primitive array in which to return
17.254 + * the pixel data.
17.255 + * @param data The DataBuffer containing the image data.
17.256 + * @return the data for the specified pixel.
17.257 + * @see #setDataElements(int, int, Object, DataBuffer)
17.258 + */
17.259 + public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
17.260 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.261 + throw new ArrayIndexOutOfBoundsException
17.262 + ("Coordinate out of bounds!");
17.263 + }
17.264 + int type = getTransferType();
17.265 + int numDataElems = getNumDataElements();
17.266 + int pixelOffset = y*scanlineStride + x;
17.267 +
17.268 + switch(type) {
17.269 +
17.270 + case DataBuffer.TYPE_BYTE:
17.271 +
17.272 + byte[] bdata;
17.273 +
17.274 + if (obj == null) {
17.275 + bdata = new byte[numDataElems];
17.276 + } else {
17.277 + bdata = (byte[])obj;
17.278 + }
17.279 +
17.280 + for (int i=0; i<numDataElems; i++) {
17.281 + bdata[i] = (byte)data.getElem(bankIndices[i],
17.282 + pixelOffset + bandOffsets[i]);
17.283 + }
17.284 +
17.285 + obj = (Object)bdata;
17.286 + break;
17.287 +
17.288 + case DataBuffer.TYPE_USHORT:
17.289 + case DataBuffer.TYPE_SHORT:
17.290 +
17.291 + short[] sdata;
17.292 +
17.293 + if (obj == null) {
17.294 + sdata = new short[numDataElems];
17.295 + } else {
17.296 + sdata = (short[])obj;
17.297 + }
17.298 +
17.299 + for (int i=0; i<numDataElems; i++) {
17.300 + sdata[i] = (short)data.getElem(bankIndices[i],
17.301 + pixelOffset + bandOffsets[i]);
17.302 + }
17.303 +
17.304 + obj = (Object)sdata;
17.305 + break;
17.306 +
17.307 + case DataBuffer.TYPE_INT:
17.308 +
17.309 + int[] idata;
17.310 +
17.311 + if (obj == null) {
17.312 + idata = new int[numDataElems];
17.313 + } else {
17.314 + idata = (int[])obj;
17.315 + }
17.316 +
17.317 + for (int i=0; i<numDataElems; i++) {
17.318 + idata[i] = data.getElem(bankIndices[i],
17.319 + pixelOffset + bandOffsets[i]);
17.320 + }
17.321 +
17.322 + obj = (Object)idata;
17.323 + break;
17.324 +
17.325 + case DataBuffer.TYPE_FLOAT:
17.326 +
17.327 + float[] fdata;
17.328 +
17.329 + if (obj == null) {
17.330 + fdata = new float[numDataElems];
17.331 + } else {
17.332 + fdata = (float[])obj;
17.333 + }
17.334 +
17.335 + for (int i=0; i<numDataElems; i++) {
17.336 + fdata[i] = data.getElemFloat(bankIndices[i],
17.337 + pixelOffset + bandOffsets[i]);
17.338 + }
17.339 +
17.340 + obj = (Object)fdata;
17.341 + break;
17.342 +
17.343 + case DataBuffer.TYPE_DOUBLE:
17.344 +
17.345 + double[] ddata;
17.346 +
17.347 + if (obj == null) {
17.348 + ddata = new double[numDataElems];
17.349 + } else {
17.350 + ddata = (double[])obj;
17.351 + }
17.352 +
17.353 + for (int i=0; i<numDataElems; i++) {
17.354 + ddata[i] = data.getElemDouble(bankIndices[i],
17.355 + pixelOffset + bandOffsets[i]);
17.356 + }
17.357 +
17.358 + obj = (Object)ddata;
17.359 + break;
17.360 + }
17.361 +
17.362 + return obj;
17.363 + }
17.364 +
17.365 + /**
17.366 + * Returns all samples for the specified pixel in an int array.
17.367 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.368 + * not in bounds.
17.369 + * @param x The X coordinate of the pixel location
17.370 + * @param y The Y coordinate of the pixel location
17.371 + * @param iArray If non-null, returns the samples in this array
17.372 + * @param data The DataBuffer containing the image data
17.373 + * @return the samples for the specified pixel.
17.374 + * @see #setPixel(int, int, int[], DataBuffer)
17.375 + */
17.376 + public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
17.377 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.378 + throw new ArrayIndexOutOfBoundsException
17.379 + ("Coordinate out of bounds!");
17.380 + }
17.381 +
17.382 + int[] pixels;
17.383 +
17.384 + if (iArray != null) {
17.385 + pixels = iArray;
17.386 + } else {
17.387 + pixels = new int [numBands];
17.388 + }
17.389 +
17.390 + int pixelOffset = y*scanlineStride + x;
17.391 + for (int i=0; i<numBands; i++) {
17.392 + pixels[i] = data.getElem(bankIndices[i],
17.393 + pixelOffset + bandOffsets[i]);
17.394 + }
17.395 + return pixels;
17.396 + }
17.397 +
17.398 + /**
17.399 + * Returns all samples for the specified rectangle of pixels in
17.400 + * an int array, one sample per data array element.
17.401 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.402 + * not in bounds.
17.403 + * @param x The X coordinate of the upper left pixel location
17.404 + * @param y The Y coordinate of the upper left pixel location
17.405 + * @param w The width of the pixel rectangle
17.406 + * @param h The height of the pixel rectangle
17.407 + * @param iArray If non-null, returns the samples in this array
17.408 + * @param data The DataBuffer containing the image data
17.409 + * @return the samples for the pixels within the specified region.
17.410 + * @see #setPixels(int, int, int, int, int[], DataBuffer)
17.411 + */
17.412 + public int[] getPixels(int x, int y, int w, int h,
17.413 + int iArray[], DataBuffer data) {
17.414 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
17.415 + throw new ArrayIndexOutOfBoundsException
17.416 + ("Coordinate out of bounds!");
17.417 + }
17.418 + int[] pixels;
17.419 +
17.420 + if (iArray != null) {
17.421 + pixels = iArray;
17.422 + } else {
17.423 + pixels = new int[w*h*numBands];
17.424 + }
17.425 +
17.426 + for (int k = 0; k < numBands; k++) {
17.427 + int lineOffset = y*scanlineStride + x + bandOffsets[k];
17.428 + int srcOffset = k;
17.429 + int bank = bankIndices[k];
17.430 +
17.431 + for (int i = 0; i < h; i++) {
17.432 + int pixelOffset = lineOffset;
17.433 + for (int j = 0; j < w; j++) {
17.434 + pixels[srcOffset] = data.getElem(bank, pixelOffset++);
17.435 + srcOffset += numBands;
17.436 + }
17.437 + lineOffset += scanlineStride;
17.438 + }
17.439 + }
17.440 + return pixels;
17.441 + }
17.442 +
17.443 + /**
17.444 + * Returns as int the sample in a specified band for the pixel
17.445 + * located at (x,y).
17.446 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.447 + * not in bounds.
17.448 + * @param x The X coordinate of the pixel location
17.449 + * @param y The Y coordinate of the pixel location
17.450 + * @param b The band to return
17.451 + * @param data The DataBuffer containing the image data
17.452 + * @return the sample in the specified band for the specified pixel.
17.453 + * @see #setSample(int, int, int, int, DataBuffer)
17.454 + */
17.455 + public int getSample(int x, int y, int b, DataBuffer data) {
17.456 + // Bounds check for 'b' will be performed automatically
17.457 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.458 + throw new ArrayIndexOutOfBoundsException
17.459 + ("Coordinate out of bounds!");
17.460 + }
17.461 + int sample =
17.462 + data.getElem(bankIndices[b],
17.463 + y*scanlineStride + x + bandOffsets[b]);
17.464 + return sample;
17.465 + }
17.466 +
17.467 + /**
17.468 + * Returns the sample in a specified band
17.469 + * for the pixel located at (x,y) as a float.
17.470 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.471 + * not in bounds.
17.472 + * @param x The X coordinate of the pixel location
17.473 + * @param y The Y coordinate of the pixel location
17.474 + * @param b The band to return
17.475 + * @param data The DataBuffer containing the image data
17.476 + * @return a float value that represents the sample in the specified
17.477 + * band for the specified pixel.
17.478 + */
17.479 + public float getSampleFloat(int x, int y, int b, DataBuffer data) {
17.480 + // Bounds check for 'b' will be performed automatically
17.481 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.482 + throw new ArrayIndexOutOfBoundsException
17.483 + ("Coordinate out of bounds!");
17.484 + }
17.485 +
17.486 + float sample = data.getElemFloat(bankIndices[b],
17.487 + y*scanlineStride + x + bandOffsets[b]);
17.488 + return sample;
17.489 + }
17.490 +
17.491 + /**
17.492 + * Returns the sample in a specified band
17.493 + * for a pixel located at (x,y) as a double.
17.494 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.495 + * not in bounds.
17.496 + * @param x The X coordinate of the pixel location
17.497 + * @param y The Y coordinate of the pixel location
17.498 + * @param b The band to return
17.499 + * @param data The DataBuffer containing the image data
17.500 + * @return a double value that represents the sample in the specified
17.501 + * band for the specified pixel.
17.502 + */
17.503 + public double getSampleDouble(int x, int y, int b, DataBuffer data) {
17.504 + // Bounds check for 'b' will be performed automatically
17.505 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.506 + throw new ArrayIndexOutOfBoundsException
17.507 + ("Coordinate out of bounds!");
17.508 + }
17.509 +
17.510 + double sample = data.getElemDouble(bankIndices[b],
17.511 + y*scanlineStride + x + bandOffsets[b]);
17.512 + return sample;
17.513 + }
17.514 +
17.515 + /**
17.516 + * Returns the samples in a specified band for the specified rectangle
17.517 + * of pixels in an int array, one sample per data array element.
17.518 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.519 + * not in bounds.
17.520 + * @param x The X coordinate of the upper left pixel location
17.521 + * @param y The Y coordinate of the upper left pixel location
17.522 + * @param w The width of the pixel rectangle
17.523 + * @param h The height of the pixel rectangle
17.524 + * @param b The band to return
17.525 + * @param iArray If non-null, returns the samples in this array
17.526 + * @param data The DataBuffer containing the image data
17.527 + * @return the samples in the specified band for the pixels within
17.528 + * the specified region.
17.529 + * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
17.530 + */
17.531 + public int[] getSamples(int x, int y, int w, int h, int b,
17.532 + int iArray[], DataBuffer data) {
17.533 + // Bounds check for 'b' will be performed automatically
17.534 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
17.535 + throw new ArrayIndexOutOfBoundsException
17.536 + ("Coordinate out of bounds!");
17.537 + }
17.538 + int samples[];
17.539 + if (iArray != null) {
17.540 + samples = iArray;
17.541 + } else {
17.542 + samples = new int [w*h];
17.543 + }
17.544 +
17.545 + int lineOffset = y*scanlineStride + x + bandOffsets[b];
17.546 + int srcOffset = 0;
17.547 + int bank = bankIndices[b];
17.548 +
17.549 + for (int i = 0; i < h; i++) {
17.550 + int sampleOffset = lineOffset;
17.551 + for (int j = 0; j < w; j++) {
17.552 + samples[srcOffset++] = data.getElem(bank, sampleOffset++);
17.553 + }
17.554 + lineOffset += scanlineStride;
17.555 + }
17.556 + return samples;
17.557 + }
17.558 +
17.559 + /**
17.560 + * Sets the data for a single pixel in the specified DataBuffer from a
17.561 + * primitive array of type TransferType. For a BandedSampleModel,
17.562 + * this will be the same as the data type, and samples are transferred
17.563 + * one per array element.
17.564 + * <p>
17.565 + * The following code illustrates transferring data for one pixel from
17.566 + * DataBuffer <code>db1</code>, whose storage layout is described by
17.567 + * BandedSampleModel <code>bsm1</code>, to DataBuffer <code>db2</code>,
17.568 + * whose storage layout is described by
17.569 + * BandedSampleModel <code>bsm2</code>.
17.570 + * The transfer will generally be more efficient than using
17.571 + * getPixel/setPixel.
17.572 + * <pre>
17.573 + * BandedSampleModel bsm1, bsm2;
17.574 + * DataBufferInt db1, db2;
17.575 + * bsm2.setDataElements(x, y, bsm1.getDataElements(x, y, null, db1),
17.576 + * db2);
17.577 + * </pre>
17.578 + * Using getDataElements/setDataElements to transfer between two
17.579 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
17.580 + * the same number of bands, corresponding bands have the same number of
17.581 + * bits per sample, and the TransferTypes are the same.
17.582 + * <p>
17.583 + * obj must be a primitive array of type TransferType. Otherwise,
17.584 + * a ClassCastException is thrown. An
17.585 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.586 + * not in bounds, or if obj is not large enough to hold the pixel data.
17.587 + * @param x The X coordinate of the pixel location
17.588 + * @param y The Y coordinate of the pixel location
17.589 + * @param obj If non-null, returns the primitive array in this
17.590 + * object
17.591 + * @param data The DataBuffer containing the image data
17.592 + * @see #getDataElements(int, int, Object, DataBuffer)
17.593 + */
17.594 + public void setDataElements(int x, int y, Object obj, DataBuffer data) {
17.595 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.596 + throw new ArrayIndexOutOfBoundsException
17.597 + ("Coordinate out of bounds!");
17.598 + }
17.599 + int type = getTransferType();
17.600 + int numDataElems = getNumDataElements();
17.601 + int pixelOffset = y*scanlineStride + x;
17.602 +
17.603 + switch(type) {
17.604 +
17.605 + case DataBuffer.TYPE_BYTE:
17.606 +
17.607 + byte[] barray = (byte[])obj;
17.608 +
17.609 + for (int i=0; i<numDataElems; i++) {
17.610 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
17.611 + barray[i] & 0xff);
17.612 + }
17.613 + break;
17.614 +
17.615 + case DataBuffer.TYPE_USHORT:
17.616 + case DataBuffer.TYPE_SHORT:
17.617 +
17.618 + short[] sarray = (short[])obj;
17.619 +
17.620 + for (int i=0; i<numDataElems; i++) {
17.621 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
17.622 + sarray[i] & 0xffff);
17.623 + }
17.624 + break;
17.625 +
17.626 + case DataBuffer.TYPE_INT:
17.627 +
17.628 + int[] iarray = (int[])obj;
17.629 +
17.630 + for (int i=0; i<numDataElems; i++) {
17.631 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
17.632 + iarray[i]);
17.633 + }
17.634 + break;
17.635 +
17.636 + case DataBuffer.TYPE_FLOAT:
17.637 +
17.638 + float[] farray = (float[])obj;
17.639 +
17.640 + for (int i=0; i<numDataElems; i++) {
17.641 + data.setElemFloat(bankIndices[i], pixelOffset + bandOffsets[i],
17.642 + farray[i]);
17.643 + }
17.644 + break;
17.645 +
17.646 + case DataBuffer.TYPE_DOUBLE:
17.647 +
17.648 + double[] darray = (double[])obj;
17.649 +
17.650 + for (int i=0; i<numDataElems; i++) {
17.651 + data.setElemDouble(bankIndices[i], pixelOffset + bandOffsets[i],
17.652 + darray[i]);
17.653 + }
17.654 + break;
17.655 +
17.656 + }
17.657 + }
17.658 +
17.659 + /**
17.660 + * Sets a pixel in the DataBuffer using an int array of samples for input.
17.661 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.662 + * not in bounds.
17.663 + * @param x The X coordinate of the pixel location
17.664 + * @param y The Y coordinate of the pixel location
17.665 + * @param iArray The input samples in an int array
17.666 + * @param data The DataBuffer containing the image data
17.667 + * @see #getPixel(int, int, int[], DataBuffer)
17.668 + */
17.669 + public void setPixel(int x, int y, int iArray[], DataBuffer data) {
17.670 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.671 + throw new ArrayIndexOutOfBoundsException
17.672 + ("Coordinate out of bounds!");
17.673 + }
17.674 + int pixelOffset = y*scanlineStride + x;
17.675 + for (int i=0; i<numBands; i++) {
17.676 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
17.677 + iArray[i]);
17.678 + }
17.679 + }
17.680 +
17.681 + /**
17.682 + * Sets all samples for a rectangle of pixels from an int array containing
17.683 + * one sample per array element.
17.684 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.685 + * not in bounds.
17.686 + * @param x The X coordinate of the upper left pixel location
17.687 + * @param y The Y coordinate of the upper left pixel location
17.688 + * @param w The width of the pixel rectangle
17.689 + * @param h The height of the pixel rectangle
17.690 + * @param iArray The input samples in an int array
17.691 + * @param data The DataBuffer containing the image data
17.692 + * @see #getPixels(int, int, int, int, int[], DataBuffer)
17.693 + */
17.694 + public void setPixels(int x, int y, int w, int h,
17.695 + int iArray[], DataBuffer data) {
17.696 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
17.697 + throw new ArrayIndexOutOfBoundsException
17.698 + ("Coordinate out of bounds!");
17.699 + }
17.700 +
17.701 + for (int k = 0; k < numBands; k++) {
17.702 + int lineOffset = y*scanlineStride + x + bandOffsets[k];
17.703 + int srcOffset = k;
17.704 + int bank = bankIndices[k];
17.705 +
17.706 + for (int i = 0; i < h; i++) {
17.707 + int pixelOffset = lineOffset;
17.708 + for (int j = 0; j < w; j++) {
17.709 + data.setElem(bank, pixelOffset++, iArray[srcOffset]);
17.710 + srcOffset += numBands;
17.711 + }
17.712 + lineOffset += scanlineStride;
17.713 + }
17.714 + }
17.715 + }
17.716 +
17.717 + /**
17.718 + * Sets a sample in the specified band for the pixel located at (x,y)
17.719 + * in the DataBuffer using an int for input.
17.720 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.721 + * not in bounds.
17.722 + * @param x The X coordinate of the pixel location
17.723 + * @param y The Y coordinate of the pixel location
17.724 + * @param b The band to set
17.725 + * @param s The input sample as an int
17.726 + * @param data The DataBuffer containing the image data
17.727 + * @see #getSample(int, int, int, DataBuffer)
17.728 + */
17.729 + public void setSample(int x, int y, int b, int s,
17.730 + DataBuffer data) {
17.731 + // Bounds check for 'b' will be performed automatically
17.732 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.733 + throw new ArrayIndexOutOfBoundsException
17.734 + ("Coordinate out of bounds!");
17.735 + }
17.736 + data.setElem(bankIndices[b],
17.737 + y*scanlineStride + x + bandOffsets[b], s);
17.738 + }
17.739 +
17.740 + /**
17.741 + * Sets a sample in the specified band for the pixel located at (x,y)
17.742 + * in the DataBuffer using a float for input.
17.743 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.744 + * not in bounds.
17.745 + * @param x The X coordinate of the pixel location
17.746 + * @param y The Y coordinate of the pixel location
17.747 + * @param b The band to set
17.748 + * @param s The input sample as a float
17.749 + * @param data The DataBuffer containing the image data
17.750 + * @see #getSample(int, int, int, DataBuffer)
17.751 + */
17.752 + public void setSample(int x, int y, int b,
17.753 + float s ,
17.754 + DataBuffer data) {
17.755 + // Bounds check for 'b' will be performed automatically
17.756 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.757 + throw new ArrayIndexOutOfBoundsException
17.758 + ("Coordinate out of bounds!");
17.759 + }
17.760 + data.setElemFloat(bankIndices[b],
17.761 + y*scanlineStride + x + bandOffsets[b], s);
17.762 + }
17.763 +
17.764 + /**
17.765 + * Sets a sample in the specified band for the pixel located at (x,y)
17.766 + * in the DataBuffer using a double for input.
17.767 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.768 + * not in bounds.
17.769 + * @param x The X coordinate of the pixel location
17.770 + * @param y The Y coordinate of the pixel location
17.771 + * @param b The band to set
17.772 + * @param s The input sample as a double
17.773 + * @param data The DataBuffer containing the image data
17.774 + * @see #getSample(int, int, int, DataBuffer)
17.775 + */
17.776 + public void setSample(int x, int y, int b,
17.777 + double s,
17.778 + DataBuffer data) {
17.779 + // Bounds check for 'b' will be performed automatically
17.780 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
17.781 + throw new ArrayIndexOutOfBoundsException
17.782 + ("Coordinate out of bounds!");
17.783 + }
17.784 + data.setElemDouble(bankIndices[b],
17.785 + y*scanlineStride + x + bandOffsets[b], s);
17.786 + }
17.787 +
17.788 + /**
17.789 + * Sets the samples in the specified band for the specified rectangle
17.790 + * of pixels from an int array containing one sample per data array element.
17.791 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
17.792 + * not in bounds.
17.793 + * @param x The X coordinate of the upper left pixel location
17.794 + * @param y The Y coordinate of the upper left pixel location
17.795 + * @param w The width of the pixel rectangle
17.796 + * @param h The height of the pixel rectangle
17.797 + * @param b The band to set
17.798 + * @param iArray The input sample array
17.799 + * @param data The DataBuffer containing the image data
17.800 + * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
17.801 + */
17.802 + public void setSamples(int x, int y, int w, int h, int b,
17.803 + int iArray[], DataBuffer data) {
17.804 + // Bounds check for 'b' will be performed automatically
17.805 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
17.806 + throw new ArrayIndexOutOfBoundsException
17.807 + ("Coordinate out of bounds!");
17.808 + }
17.809 + int lineOffset = y*scanlineStride + x + bandOffsets[b];
17.810 + int srcOffset = 0;
17.811 + int bank = bankIndices[b];
17.812 +
17.813 + for (int i = 0; i < h; i++) {
17.814 + int sampleOffset = lineOffset;
17.815 + for (int j = 0; j < w; j++) {
17.816 + data.setElem(bank, sampleOffset++, iArray[srcOffset++]);
17.817 + }
17.818 + lineOffset += scanlineStride;
17.819 + }
17.820 + }
17.821 +
17.822 + private static int[] createOffsetArray(int numBands) {
17.823 + int[] bandOffsets = new int[numBands];
17.824 + for (int i=0; i < numBands; i++) {
17.825 + bandOffsets[i] = 0;
17.826 + }
17.827 + return bandOffsets;
17.828 + }
17.829 +
17.830 + private static int[] createIndicesArray(int numBands) {
17.831 + int[] bankIndices = new int[numBands];
17.832 + for (int i=0; i < numBands; i++) {
17.833 + bankIndices[i] = i;
17.834 + }
17.835 + return bankIndices;
17.836 + }
17.837 +
17.838 + // Differentiate hash code from other ComponentSampleModel subclasses
17.839 + public int hashCode() {
17.840 + return super.hashCode() ^ 0x2;
17.841 + }
17.842 +}
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/src/share/classes/java/awt/image/ColorConvertOp.java Thu Jun 12 11:46:57 2008 -0700
18.3 @@ -0,0 +1,1109 @@
18.4 +/*
18.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
18.7 + *
18.8 + * This code is free software; you can redistribute it and/or modify it
18.9 + * under the terms of the GNU General Public License version 2 only, as
18.10 + * published by the Free Software Foundation. Sun designates this
18.11 + * particular file as subject to the "Classpath" exception as provided
18.12 + * by Sun in the LICENSE file that accompanied this code.
18.13 + *
18.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
18.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18.17 + * version 2 for more details (a copy is included in the LICENSE file that
18.18 + * accompanied this code).
18.19 + *
18.20 + * You should have received a copy of the GNU General Public License version
18.21 + * 2 along with this work; if not, write to the Free Software Foundation,
18.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18.23 + *
18.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
18.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
18.26 + * have any questions.
18.27 + */
18.28 +
18.29 +/**********************************************************************
18.30 + **********************************************************************
18.31 + **********************************************************************
18.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
18.33 + *** As an unpublished work pursuant to Title 17 of the United ***
18.34 + *** States Code. All rights reserved. ***
18.35 + **********************************************************************
18.36 + **********************************************************************
18.37 + **********************************************************************/
18.38 +
18.39 +package java.awt.image;
18.40 +
18.41 +import java.awt.Point;
18.42 +import java.awt.Graphics2D;
18.43 +import java.awt.color.*;
18.44 +import sun.java2d.cmm.ColorTransform;
18.45 +import sun.java2d.cmm.CMSManager;
18.46 +import sun.java2d.cmm.ProfileDeferralMgr;
18.47 +import sun.java2d.cmm.PCMM;
18.48 +import java.awt.geom.Rectangle2D;
18.49 +import java.awt.geom.Point2D;
18.50 +import java.awt.RenderingHints;
18.51 +
18.52 +/**
18.53 + * This class performs a pixel-by-pixel color conversion of the data in
18.54 + * the source image. The resulting color values are scaled to the precision
18.55 + * of the destination image. Color conversion can be specified
18.56 + * via an array of ColorSpace objects or an array of ICC_Profile objects.
18.57 + * <p>
18.58 + * If the source is a BufferedImage with premultiplied alpha, the
18.59 + * color components are divided by the alpha component before color conversion.
18.60 + * If the destination is a BufferedImage with premultiplied alpha, the
18.61 + * color components are multiplied by the alpha component after conversion.
18.62 + * Rasters are treated as having no alpha channel, i.e. all bands are
18.63 + * color bands.
18.64 + * <p>
18.65 + * If a RenderingHints object is specified in the constructor, the
18.66 + * color rendering hint and the dithering hint may be used to control
18.67 + * color conversion.
18.68 + * <p>
18.69 + * Note that Source and Destination may be the same object.
18.70 + * <p>
18.71 + * @see java.awt.RenderingHints#KEY_COLOR_RENDERING
18.72 + * @see java.awt.RenderingHints#KEY_DITHERING
18.73 + */
18.74 +public class ColorConvertOp implements BufferedImageOp, RasterOp {
18.75 + ICC_Profile[] profileList;
18.76 + ColorSpace[] CSList;
18.77 + ColorTransform thisTransform, thisRasterTransform;
18.78 + ICC_Profile thisSrcProfile, thisDestProfile;
18.79 + RenderingHints hints;
18.80 + boolean gotProfiles;
18.81 + float[] srcMinVals, srcMaxVals, dstMinVals, dstMaxVals;
18.82 +
18.83 + /* the class initializer */
18.84 + static {
18.85 + if (ProfileDeferralMgr.deferring) {
18.86 + ProfileDeferralMgr.activateProfiles();
18.87 + }
18.88 + }
18.89 +
18.90 + /**
18.91 + * Constructs a new ColorConvertOp which will convert
18.92 + * from a source color space to a destination color space.
18.93 + * The RenderingHints argument may be null.
18.94 + * This Op can be used only with BufferedImages, and will convert
18.95 + * directly from the ColorSpace of the source image to that of the
18.96 + * destination. The destination argument of the filter method
18.97 + * cannot be specified as null.
18.98 + * @param hints the <code>RenderingHints</code> object used to control
18.99 + * the color conversion, or <code>null</code>
18.100 + */
18.101 + public ColorConvertOp (RenderingHints hints)
18.102 + {
18.103 + profileList = new ICC_Profile [0]; /* 0 length list */
18.104 + this.hints = hints;
18.105 + }
18.106 +
18.107 + /**
18.108 + * Constructs a new ColorConvertOp from a ColorSpace object.
18.109 + * The RenderingHints argument may be null. This
18.110 + * Op can be used only with BufferedImages, and is primarily useful
18.111 + * when the {@link #filter(BufferedImage, BufferedImage) filter}
18.112 + * method is invoked with a destination argument of null.
18.113 + * In that case, the ColorSpace defines the destination color space
18.114 + * for the destination created by the filter method. Otherwise, the
18.115 + * ColorSpace defines an intermediate space to which the source is
18.116 + * converted before being converted to the destination space.
18.117 + * @param cspace defines the destination <code>ColorSpace</code> or an
18.118 + * intermediate <code>ColorSpace</code>
18.119 + * @param hints the <code>RenderingHints</code> object used to control
18.120 + * the color conversion, or <code>null</code>
18.121 + * @throws NullPointerException if cspace is null
18.122 + */
18.123 + public ColorConvertOp (ColorSpace cspace, RenderingHints hints)
18.124 + {
18.125 + if (cspace == null) {
18.126 + throw new NullPointerException("ColorSpace cannot be null");
18.127 + }
18.128 + if (cspace instanceof ICC_ColorSpace) {
18.129 + profileList = new ICC_Profile [1]; /* 1 profile in the list */
18.130 +
18.131 + profileList [0] = ((ICC_ColorSpace) cspace).getProfile();
18.132 + }
18.133 + else {
18.134 + CSList = new ColorSpace[1]; /* non-ICC case: 1 ColorSpace in list */
18.135 + CSList[0] = cspace;
18.136 + }
18.137 + this.hints = hints;
18.138 + }
18.139 +
18.140 +
18.141 + /**
18.142 + * Constructs a new ColorConvertOp from two ColorSpace objects.
18.143 + * The RenderingHints argument may be null.
18.144 + * This Op is primarily useful for calling the filter method on
18.145 + * Rasters, in which case the two ColorSpaces define the operation
18.146 + * to be performed on the Rasters. In that case, the number of bands
18.147 + * in the source Raster must match the number of components in
18.148 + * srcCspace, and the number of bands in the destination Raster
18.149 + * must match the number of components in dstCspace. For BufferedImages,
18.150 + * the two ColorSpaces define intermediate spaces through which the
18.151 + * source is converted before being converted to the destination space.
18.152 + * @param srcCspace the source <code>ColorSpace</code>
18.153 + * @param dstCspace the destination <code>ColorSpace</code>
18.154 + * @param hints the <code>RenderingHints</code> object used to control
18.155 + * the color conversion, or <code>null</code>
18.156 + * @throws NullPointerException if either srcCspace or dstCspace is null
18.157 + */
18.158 + public ColorConvertOp(ColorSpace srcCspace, ColorSpace dstCspace,
18.159 + RenderingHints hints)
18.160 + {
18.161 + if ((srcCspace == null) || (dstCspace == null)) {
18.162 + throw new NullPointerException("ColorSpaces cannot be null");
18.163 + }
18.164 + if ((srcCspace instanceof ICC_ColorSpace) &&
18.165 + (dstCspace instanceof ICC_ColorSpace)) {
18.166 + profileList = new ICC_Profile [2]; /* 2 profiles in the list */
18.167 +
18.168 + profileList [0] = ((ICC_ColorSpace) srcCspace).getProfile();
18.169 + profileList [1] = ((ICC_ColorSpace) dstCspace).getProfile();
18.170 +
18.171 + getMinMaxValsFromColorSpaces(srcCspace, dstCspace);
18.172 + } else {
18.173 + /* non-ICC case: 2 ColorSpaces in list */
18.174 + CSList = new ColorSpace[2];
18.175 + CSList[0] = srcCspace;
18.176 + CSList[1] = dstCspace;
18.177 + }
18.178 + this.hints = hints;
18.179 + }
18.180 +
18.181 +
18.182 + /**
18.183 + * Constructs a new ColorConvertOp from an array of ICC_Profiles.
18.184 + * The RenderingHints argument may be null.
18.185 + * The sequence of profiles may include profiles that represent color
18.186 + * spaces, profiles that represent effects, etc. If the whole sequence
18.187 + * does not represent a well-defined color conversion, an exception is
18.188 + * thrown.
18.189 + * <p>For BufferedImages, if the ColorSpace
18.190 + * of the source BufferedImage does not match the requirements of the
18.191 + * first profile in the array,
18.192 + * the first conversion is to an appropriate ColorSpace.
18.193 + * If the requirements of the last profile in the array are not met
18.194 + * by the ColorSpace of the destination BufferedImage,
18.195 + * the last conversion is to the destination's ColorSpace.
18.196 + * <p>For Rasters, the number of bands in the source Raster must match
18.197 + * the requirements of the first profile in the array, and the
18.198 + * number of bands in the destination Raster must match the requirements
18.199 + * of the last profile in the array. The array must have at least two
18.200 + * elements or calling the filter method for Rasters will throw an
18.201 + * IllegalArgumentException.
18.202 + * @param profiles the array of <code>ICC_Profile</code> objects
18.203 + * @param hints the <code>RenderingHints</code> object used to control
18.204 + * the color conversion, or <code>null</code>
18.205 + * @exception IllegalArgumentException when the profile sequence does not
18.206 + * specify a well-defined color conversion
18.207 + * @exception NullPointerException if profiles is null
18.208 + */
18.209 + public ColorConvertOp (ICC_Profile[] profiles, RenderingHints hints)
18.210 + {
18.211 + if (profiles == null) {
18.212 + throw new NullPointerException("Profiles cannot be null");
18.213 + }
18.214 + gotProfiles = true;
18.215 + profileList = new ICC_Profile[profiles.length];
18.216 + for (int i1 = 0; i1 < profiles.length; i1++) {
18.217 + profileList[i1] = profiles[i1];
18.218 + }
18.219 + this.hints = hints;
18.220 + }
18.221 +
18.222 +
18.223 + /**
18.224 + * Returns the array of ICC_Profiles used to construct this ColorConvertOp.
18.225 + * Returns null if the ColorConvertOp was not constructed from such an
18.226 + * array.
18.227 + * @return the array of <code>ICC_Profile</code> objects of this
18.228 + * <code>ColorConvertOp</code>, or <code>null</code> if this
18.229 + * <code>ColorConvertOp</code> was not constructed with an
18.230 + * array of <code>ICC_Profile</code> objects.
18.231 + */
18.232 + public final ICC_Profile[] getICC_Profiles() {
18.233 + if (gotProfiles) {
18.234 + ICC_Profile[] profiles = new ICC_Profile[profileList.length];
18.235 + for (int i1 = 0; i1 < profileList.length; i1++) {
18.236 + profiles[i1] = profileList[i1];
18.237 + }
18.238 + return profiles;
18.239 + }
18.240 + return null;
18.241 + }
18.242 +
18.243 + /**
18.244 + * ColorConverts the source BufferedImage.
18.245 + * If the destination image is null,
18.246 + * a BufferedImage will be created with an appropriate ColorModel.
18.247 + * @param src the source <code>BufferedImage</code> to be converted
18.248 + * @param dest the destination <code>BufferedImage</code>,
18.249 + * or <code>null</code>
18.250 + * @return <code>dest</code> color converted from <code>src</code>
18.251 + * or a new, converted <code>BufferedImage</code>
18.252 + * if <code>dest</code> is <code>null</code>
18.253 + * @exception IllegalArgumentException if dest is null and this op was
18.254 + * constructed using the constructor which takes only a
18.255 + * RenderingHints argument, since the operation is ill defined.
18.256 + */
18.257 + public final BufferedImage filter(BufferedImage src, BufferedImage dest) {
18.258 + ColorSpace srcColorSpace, destColorSpace;
18.259 + BufferedImage savdest = null;
18.260 +
18.261 + if (src.getColorModel() instanceof IndexColorModel) {
18.262 + IndexColorModel icm = (IndexColorModel) src.getColorModel();
18.263 + src = icm.convertToIntDiscrete(src.getRaster(), true);
18.264 + }
18.265 + srcColorSpace = src.getColorModel().getColorSpace();
18.266 + if (dest != null) {
18.267 + if (dest.getColorModel() instanceof IndexColorModel) {
18.268 + savdest = dest;
18.269 + dest = null;
18.270 + destColorSpace = null;
18.271 + } else {
18.272 + destColorSpace = dest.getColorModel().getColorSpace();
18.273 + }
18.274 + } else {
18.275 + destColorSpace = null;
18.276 + }
18.277 +
18.278 + if ((CSList != null) ||
18.279 + (!(srcColorSpace instanceof ICC_ColorSpace)) ||
18.280 + ((dest != null) &&
18.281 + (!(destColorSpace instanceof ICC_ColorSpace)))) {
18.282 + /* non-ICC case */
18.283 + dest = nonICCBIFilter(src, srcColorSpace, dest, destColorSpace);
18.284 + } else {
18.285 + dest = ICCBIFilter(src, srcColorSpace, dest, destColorSpace);
18.286 + }
18.287 +
18.288 + if (savdest != null) {
18.289 + Graphics2D big = savdest.createGraphics();
18.290 + try {
18.291 + big.drawImage(dest, 0, 0, null);
18.292 + } finally {
18.293 + big.dispose();
18.294 + }
18.295 + return savdest;
18.296 + } else {
18.297 + return dest;
18.298 + }
18.299 + }
18.300 +
18.301 + private final BufferedImage ICCBIFilter(BufferedImage src,
18.302 + ColorSpace srcColorSpace,
18.303 + BufferedImage dest,
18.304 + ColorSpace destColorSpace) {
18.305 + int nProfiles = profileList.length;
18.306 + ICC_Profile srcProfile = null, destProfile = null;
18.307 +
18.308 + srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();
18.309 +
18.310 + if (dest == null) { /* last profile in the list defines
18.311 + the output color space */
18.312 + if (nProfiles == 0) {
18.313 + throw new IllegalArgumentException(
18.314 + "Destination ColorSpace is undefined");
18.315 + }
18.316 + destProfile = profileList [nProfiles - 1];
18.317 + dest = createCompatibleDestImage(src, null);
18.318 + }
18.319 + else {
18.320 + if (src.getHeight() != dest.getHeight() ||
18.321 + src.getWidth() != dest.getWidth()) {
18.322 + throw new IllegalArgumentException(
18.323 + "Width or height of BufferedImages do not match");
18.324 + }
18.325 + destProfile = ((ICC_ColorSpace) destColorSpace).getProfile();
18.326 + }
18.327 +
18.328 + /* Checking if all profiles in the transform sequence are the same.
18.329 + * If so, performing just copying the data.
18.330 + */
18.331 + if (srcProfile == destProfile) {
18.332 + boolean noTrans = true;
18.333 + for (int i = 0; i < nProfiles; i++) {
18.334 + if (srcProfile != profileList[i]) {
18.335 + noTrans = false;
18.336 + break;
18.337 + }
18.338 + }
18.339 + if (noTrans) {
18.340 + Graphics2D g = dest.createGraphics();
18.341 + try {
18.342 + g.drawImage(src, 0, 0, null);
18.343 + } finally {
18.344 + g.dispose();
18.345 + }
18.346 +
18.347 + return dest;
18.348 + }
18.349 + }
18.350 +
18.351 + /* make a new transform if needed */
18.352 + if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
18.353 + (thisDestProfile != destProfile) ) {
18.354 + updateBITransform(srcProfile, destProfile);
18.355 + }
18.356 +
18.357 + /* color convert the image */
18.358 + thisTransform.colorConvert(src, dest);
18.359 +
18.360 + return dest;
18.361 + }
18.362 +
18.363 + private void updateBITransform(ICC_Profile srcProfile,
18.364 + ICC_Profile destProfile) {
18.365 + ICC_Profile[] theProfiles;
18.366 + int i1, nProfiles, nTransforms, whichTrans, renderState;
18.367 + ColorTransform[] theTransforms;
18.368 + boolean useSrc = false, useDest = false;
18.369 +
18.370 + nProfiles = profileList.length;
18.371 + nTransforms = nProfiles;
18.372 + if ((nProfiles == 0) || (srcProfile != profileList[0])) {
18.373 + nTransforms += 1;
18.374 + useSrc = true;
18.375 + }
18.376 + if ((nProfiles == 0) || (destProfile != profileList[nProfiles - 1]) ||
18.377 + (nTransforms < 2)) {
18.378 + nTransforms += 1;
18.379 + useDest = true;
18.380 + }
18.381 +
18.382 + /* make the profile list */
18.383 + theProfiles = new ICC_Profile[nTransforms]; /* the list of profiles
18.384 + for this Op */
18.385 +
18.386 + int idx = 0;
18.387 + if (useSrc) {
18.388 + /* insert source as first profile */
18.389 + theProfiles[idx++] = srcProfile;
18.390 + }
18.391 +
18.392 + for (i1 = 0; i1 < nProfiles; i1++) {
18.393 + /* insert profiles defined in this Op */
18.394 + theProfiles[idx++] = profileList [i1];
18.395 + }
18.396 +
18.397 + if (useDest) {
18.398 + /* insert dest as last profile */
18.399 + theProfiles[idx] = destProfile;
18.400 + }
18.401 +
18.402 + /* make the transform list */
18.403 + theTransforms = new ColorTransform [nTransforms];
18.404 +
18.405 + /* initialize transform get loop */
18.406 + if (theProfiles[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
18.407 + /* if first profile is a printer
18.408 + render as colorimetric */
18.409 + renderState = ICC_Profile.icRelativeColorimetric;
18.410 + }
18.411 + else {
18.412 + renderState = ICC_Profile.icPerceptual; /* render any other
18.413 + class perceptually */
18.414 + }
18.415 +
18.416 + whichTrans = ColorTransform.In;
18.417 +
18.418 + PCMM mdl = CMSManager.getModule();
18.419 +
18.420 + /* get the transforms from each profile */
18.421 + for (i1 = 0; i1 < nTransforms; i1++) {
18.422 + if (i1 == nTransforms -1) { /* last profile? */
18.423 + whichTrans = ColorTransform.Out; /* get output transform */
18.424 + }
18.425 + else { /* check for abstract profile */
18.426 + if ((whichTrans == ColorTransform.Simulation) &&
18.427 + (theProfiles[i1].getProfileClass () ==
18.428 + ICC_Profile.CLASS_ABSTRACT)) {
18.429 + renderState = ICC_Profile.icPerceptual;
18.430 + whichTrans = ColorTransform.In;
18.431 + }
18.432 + }
18.433 +
18.434 + theTransforms[i1] = mdl.createTransform (
18.435 + theProfiles[i1], renderState, whichTrans);
18.436 +
18.437 + /* get this profile's rendering intent to select transform
18.438 + from next profile */
18.439 + renderState = getRenderingIntent(theProfiles[i1]);
18.440 +
18.441 + /* "middle" profiles use simulation transform */
18.442 + whichTrans = ColorTransform.Simulation;
18.443 + }
18.444 +
18.445 + /* make the net transform */
18.446 + thisTransform = mdl.createTransform(theTransforms);
18.447 +
18.448 + /* update corresponding source and dest profiles */
18.449 + thisSrcProfile = srcProfile;
18.450 + thisDestProfile = destProfile;
18.451 + }
18.452 +
18.453 + /**
18.454 + * ColorConverts the image data in the source Raster.
18.455 + * If the destination Raster is null, a new Raster will be created.
18.456 + * The number of bands in the source and destination Rasters must
18.457 + * meet the requirements explained above. The constructor used to
18.458 + * create this ColorConvertOp must have provided enough information
18.459 + * to define both source and destination color spaces. See above.
18.460 + * Otherwise, an exception is thrown.
18.461 + * @param src the source <code>Raster</code> to be converted
18.462 + * @param dest the destination <code>WritableRaster</code>,
18.463 + * or <code>null</code>
18.464 + * @return <code>dest</code> color converted from <code>src</code>
18.465 + * or a new, converted <code>WritableRaster</code>
18.466 + * if <code>dest</code> is <code>null</code>
18.467 + * @exception IllegalArgumentException if the number of source or
18.468 + * destination bands is incorrect, the source or destination
18.469 + * color spaces are undefined, or this op was constructed
18.470 + * with one of the constructors that applies only to
18.471 + * operations on BufferedImages.
18.472 + */
18.473 + public final WritableRaster filter (Raster src, WritableRaster dest) {
18.474 +
18.475 + if (CSList != null) {
18.476 + /* non-ICC case */
18.477 + return nonICCRasterFilter(src, dest);
18.478 + }
18.479 + int nProfiles = profileList.length;
18.480 + if (nProfiles < 2) {
18.481 + throw new IllegalArgumentException(
18.482 + "Source or Destination ColorSpace is undefined");
18.483 + }
18.484 + if (src.getNumBands() != profileList[0].getNumComponents()) {
18.485 + throw new IllegalArgumentException(
18.486 + "Numbers of source Raster bands and source color space " +
18.487 + "components do not match");
18.488 + }
18.489 + if (dest == null) {
18.490 + dest = createCompatibleDestRaster(src);
18.491 + }
18.492 + else {
18.493 + if (src.getHeight() != dest.getHeight() ||
18.494 + src.getWidth() != dest.getWidth()) {
18.495 + throw new IllegalArgumentException(
18.496 + "Width or height of Rasters do not match");
18.497 + }
18.498 + if (dest.getNumBands() !=
18.499 + profileList[nProfiles-1].getNumComponents()) {
18.500 + throw new IllegalArgumentException(
18.501 + "Numbers of destination Raster bands and destination " +
18.502 + "color space components do not match");
18.503 + }
18.504 + }
18.505 +
18.506 + /* make a new transform if needed */
18.507 + if (thisRasterTransform == null) {
18.508 + int i1, whichTrans, renderState;
18.509 + ColorTransform[] theTransforms;
18.510 +
18.511 + /* make the transform list */
18.512 + theTransforms = new ColorTransform [nProfiles];
18.513 +
18.514 + /* initialize transform get loop */
18.515 + if (profileList[0].getProfileClass() == ICC_Profile.CLASS_OUTPUT) {
18.516 + /* if first profile is a printer
18.517 + render as colorimetric */
18.518 + renderState = ICC_Profile.icRelativeColorimetric;
18.519 + }
18.520 + else {
18.521 + renderState = ICC_Profile.icPerceptual; /* render any other
18.522 + class perceptually */
18.523 + }
18.524 +
18.525 + whichTrans = ColorTransform.In;
18.526 +
18.527 + PCMM mdl = CMSManager.getModule();
18.528 +
18.529 + /* get the transforms from each profile */
18.530 + for (i1 = 0; i1 < nProfiles; i1++) {
18.531 + if (i1 == nProfiles -1) { /* last profile? */
18.532 + whichTrans = ColorTransform.Out; /* get output transform */
18.533 + }
18.534 + else { /* check for abstract profile */
18.535 + if ((whichTrans == ColorTransform.Simulation) &&
18.536 + (profileList[i1].getProfileClass () ==
18.537 + ICC_Profile.CLASS_ABSTRACT)) {
18.538 + renderState = ICC_Profile.icPerceptual;
18.539 + whichTrans = ColorTransform.In;
18.540 + }
18.541 + }
18.542 +
18.543 + theTransforms[i1] = mdl.createTransform (
18.544 + profileList[i1], renderState, whichTrans);
18.545 +
18.546 + /* get this profile's rendering intent to select transform
18.547 + from next profile */
18.548 + renderState = getRenderingIntent(profileList[i1]);
18.549 +
18.550 + /* "middle" profiles use simulation transform */
18.551 + whichTrans = ColorTransform.Simulation;
18.552 + }
18.553 +
18.554 + /* make the net transform */
18.555 + thisRasterTransform = mdl.createTransform(theTransforms);
18.556 + }
18.557 +
18.558 + int srcTransferType = src.getTransferType();
18.559 + int dstTransferType = dest.getTransferType();
18.560 + if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
18.561 + (srcTransferType == DataBuffer.TYPE_DOUBLE) ||
18.562 + (dstTransferType == DataBuffer.TYPE_FLOAT) ||
18.563 + (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
18.564 + if (srcMinVals == null) {
18.565 + getMinMaxValsFromProfiles(profileList[0],
18.566 + profileList[nProfiles-1]);
18.567 + }
18.568 + /* color convert the raster */
18.569 + thisRasterTransform.colorConvert(src, dest,
18.570 + srcMinVals, srcMaxVals,
18.571 + dstMinVals, dstMaxVals);
18.572 + } else {
18.573 + /* color convert the raster */
18.574 + thisRasterTransform.colorConvert(src, dest);
18.575 + }
18.576 +
18.577 +
18.578 + return dest;
18.579 + }
18.580 +
18.581 + /**
18.582 + * Returns the bounding box of the destination, given this source.
18.583 + * Note that this will be the same as the the bounding box of the
18.584 + * source.
18.585 + * @param src the source <code>BufferedImage</code>
18.586 + * @return a <code>Rectangle2D</code> that is the bounding box
18.587 + * of the destination, given the specified <code>src</code>
18.588 + */
18.589 + public final Rectangle2D getBounds2D (BufferedImage src) {
18.590 + return getBounds2D(src.getRaster());
18.591 + }
18.592 +
18.593 + /**
18.594 + * Returns the bounding box of the destination, given this source.
18.595 + * Note that this will be the same as the the bounding box of the
18.596 + * source.
18.597 + * @param src the source <code>Raster</code>
18.598 + * @return a <code>Rectangle2D</code> that is the bounding box
18.599 + * of the destination, given the specified <code>src</code>
18.600 + */
18.601 + public final Rectangle2D getBounds2D (Raster src) {
18.602 + /* return new Rectangle (src.getXOffset(),
18.603 + src.getYOffset(),
18.604 + src.getWidth(), src.getHeight()); */
18.605 + return src.getBounds();
18.606 + }
18.607 +
18.608 + /**
18.609 + * Creates a zeroed destination image with the correct size and number of
18.610 + * bands, given this source.
18.611 + * @param src Source image for the filter operation.
18.612 + * @param destCM ColorModel of the destination. If null, an
18.613 + * appropriate ColorModel will be used.
18.614 + * @return a <code>BufferedImage</code> with the correct size and
18.615 + * number of bands from the specified <code>src</code>.
18.616 + * @throws IllegalArgumentException if <code>destCM</code> is
18.617 + * <code>null</code> and this <code>ColorConvertOp</code> was
18.618 + * created without any <code>ICC_Profile</code> or
18.619 + * <code>ColorSpace</code> defined for the destination
18.620 + */
18.621 + public BufferedImage createCompatibleDestImage (BufferedImage src,
18.622 + ColorModel destCM) {
18.623 + ColorSpace cs = null;;
18.624 + if (destCM == null) {
18.625 + if (CSList == null) {
18.626 + /* ICC case */
18.627 + int nProfiles = profileList.length;
18.628 + if (nProfiles == 0) {
18.629 + throw new IllegalArgumentException(
18.630 + "Destination ColorSpace is undefined");
18.631 + }
18.632 + ICC_Profile destProfile = profileList[nProfiles - 1];
18.633 + cs = new ICC_ColorSpace(destProfile);
18.634 + } else {
18.635 + /* non-ICC case */
18.636 + int nSpaces = CSList.length;
18.637 + cs = CSList[nSpaces - 1];
18.638 + }
18.639 + }
18.640 + return createCompatibleDestImage(src, destCM, cs);
18.641 + }
18.642 +
18.643 + private BufferedImage createCompatibleDestImage(BufferedImage src,
18.644 + ColorModel destCM,
18.645 + ColorSpace destCS) {
18.646 + BufferedImage image;
18.647 + if (destCM == null) {
18.648 + ColorModel srcCM = src.getColorModel();
18.649 + int nbands = destCS.getNumComponents();
18.650 + boolean hasAlpha = srcCM.hasAlpha();
18.651 + if (hasAlpha) {
18.652 + nbands += 1;
18.653 + }
18.654 + int[] nbits = new int[nbands];
18.655 + for (int i = 0; i < nbands; i++) {
18.656 + nbits[i] = 8;
18.657 + }
18.658 + destCM = new ComponentColorModel(destCS, nbits, hasAlpha,
18.659 + srcCM.isAlphaPremultiplied(),
18.660 + srcCM.getTransparency(),
18.661 + DataBuffer.TYPE_BYTE);
18.662 + }
18.663 + int w = src.getWidth();
18.664 + int h = src.getHeight();
18.665 + image = new BufferedImage(destCM,
18.666 + destCM.createCompatibleWritableRaster(w, h),
18.667 + destCM.isAlphaPremultiplied(), null);
18.668 + return image;
18.669 + }
18.670 +
18.671 +
18.672 + /**
18.673 + * Creates a zeroed destination Raster with the correct size and number of
18.674 + * bands, given this source.
18.675 + * @param src the specified <code>Raster</code>
18.676 + * @return a <code>WritableRaster</code> with the correct size and number
18.677 + * of bands from the specified <code>src</code>
18.678 + * @throws IllegalArgumentException if this <code>ColorConvertOp</code>
18.679 + * was created without sufficient information to define the
18.680 + * <code>dst</code> and <code>src</code> color spaces
18.681 + */
18.682 + public WritableRaster createCompatibleDestRaster (Raster src) {
18.683 + int ncomponents;
18.684 +
18.685 + if (CSList != null) {
18.686 + /* non-ICC case */
18.687 + if (CSList.length != 2) {
18.688 + throw new IllegalArgumentException(
18.689 + "Destination ColorSpace is undefined");
18.690 + }
18.691 + ncomponents = CSList[1].getNumComponents();
18.692 + } else {
18.693 + /* ICC case */
18.694 + int nProfiles = profileList.length;
18.695 + if (nProfiles < 2) {
18.696 + throw new IllegalArgumentException(
18.697 + "Destination ColorSpace is undefined");
18.698 + }
18.699 + ncomponents = profileList[nProfiles-1].getNumComponents();
18.700 + }
18.701 +
18.702 + WritableRaster dest =
18.703 + Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
18.704 + src.getWidth(),
18.705 + src.getHeight(),
18.706 + ncomponents,
18.707 + new Point(src.getMinX(), src.getMinY()));
18.708 + return dest;
18.709 + }
18.710 +
18.711 + /**
18.712 + * Returns the location of the destination point given a
18.713 + * point in the source. If <code>dstPt</code> is non-null,
18.714 + * it will be used to hold the return value. Note that
18.715 + * for this class, the destination point will be the same
18.716 + * as the source point.
18.717 + * @param srcPt the specified source <code>Point2D</code>
18.718 + * @param dstPt the destination <code>Point2D</code>
18.719 + * @return <code>dstPt</code> after setting its location to be
18.720 + * the same as <code>srcPt</code>
18.721 + */
18.722 + public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) {
18.723 + if (dstPt == null) {
18.724 + dstPt = new Point2D.Float();
18.725 + }
18.726 + dstPt.setLocation(srcPt.getX(), srcPt.getY());
18.727 +
18.728 + return dstPt;
18.729 + }
18.730 +
18.731 +
18.732 + /**
18.733 + * Returns the RenderingIntent from the specified ICC Profile.
18.734 + */
18.735 + private int getRenderingIntent (ICC_Profile profile) {
18.736 + byte[] header = profile.getData(ICC_Profile.icSigHead);
18.737 + int index = ICC_Profile.icHdrRenderingIntent;
18.738 + return (((header[index] & 0xff) << 24) |
18.739 + ((header[index+1] & 0xff) << 16) |
18.740 + ((header[index+2] & 0xff) << 8) |
18.741 + (header[index+3] & 0xff));
18.742 + }
18.743 +
18.744 + /**
18.745 + * Returns the rendering hints used by this op.
18.746 + * @return the <code>RenderingHints</code> object of this
18.747 + * <code>ColorConvertOp</code>
18.748 + */
18.749 + public final RenderingHints getRenderingHints() {
18.750 + return hints;
18.751 + }
18.752 +
18.753 + private final BufferedImage nonICCBIFilter(BufferedImage src,
18.754 + ColorSpace srcColorSpace,
18.755 + BufferedImage dst,
18.756 + ColorSpace dstColorSpace) {
18.757 +
18.758 + int w = src.getWidth();
18.759 + int h = src.getHeight();
18.760 + ICC_ColorSpace ciespace =
18.761 + (ICC_ColorSpace) ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
18.762 + if (dst == null) {
18.763 + dst = createCompatibleDestImage(src, null);
18.764 + dstColorSpace = dst.getColorModel().getColorSpace();
18.765 + } else {
18.766 + if ((h != dst.getHeight()) || (w != dst.getWidth())) {
18.767 + throw new IllegalArgumentException(
18.768 + "Width or height of BufferedImages do not match");
18.769 + }
18.770 + }
18.771 + Raster srcRas = src.getRaster();
18.772 + WritableRaster dstRas = dst.getRaster();
18.773 + ColorModel srcCM = src.getColorModel();
18.774 + ColorModel dstCM = dst.getColorModel();
18.775 + int srcNumComp = srcCM.getNumColorComponents();
18.776 + int dstNumComp = dstCM.getNumColorComponents();
18.777 + boolean dstHasAlpha = dstCM.hasAlpha();
18.778 + boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
18.779 + ColorSpace[] list;
18.780 + if ((CSList == null) && (profileList.length != 0)) {
18.781 + /* possible non-ICC src, some profiles, possible non-ICC dst */
18.782 + boolean nonICCSrc, nonICCDst;
18.783 + ICC_Profile srcProfile, dstProfile;
18.784 + if (!(srcColorSpace instanceof ICC_ColorSpace)) {
18.785 + nonICCSrc = true;
18.786 + srcProfile = ciespace.getProfile();
18.787 + } else {
18.788 + nonICCSrc = false;
18.789 + srcProfile = ((ICC_ColorSpace) srcColorSpace).getProfile();
18.790 + }
18.791 + if (!(dstColorSpace instanceof ICC_ColorSpace)) {
18.792 + nonICCDst = true;
18.793 + dstProfile = ciespace.getProfile();
18.794 + } else {
18.795 + nonICCDst = false;
18.796 + dstProfile = ((ICC_ColorSpace) dstColorSpace).getProfile();
18.797 + }
18.798 + /* make a new transform if needed */
18.799 + if ((thisTransform == null) || (thisSrcProfile != srcProfile) ||
18.800 + (thisDestProfile != dstProfile) ) {
18.801 + updateBITransform(srcProfile, dstProfile);
18.802 + }
18.803 + // process per scanline
18.804 + float maxNum = 65535.0f; // use 16-bit precision in CMM
18.805 + ColorSpace cs;
18.806 + int iccSrcNumComp;
18.807 + if (nonICCSrc) {
18.808 + cs = ciespace;
18.809 + iccSrcNumComp = 3;
18.810 + } else {
18.811 + cs = srcColorSpace;
18.812 + iccSrcNumComp = srcNumComp;
18.813 + }
18.814 + float[] srcMinVal = new float[iccSrcNumComp];
18.815 + float[] srcInvDiffMinMax = new float[iccSrcNumComp];
18.816 + for (int i = 0; i < srcNumComp; i++) {
18.817 + srcMinVal[i] = cs.getMinValue(i);
18.818 + srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
18.819 + }
18.820 + int iccDstNumComp;
18.821 + if (nonICCDst) {
18.822 + cs = ciespace;
18.823 + iccDstNumComp = 3;
18.824 + } else {
18.825 + cs = dstColorSpace;
18.826 + iccDstNumComp = dstNumComp;
18.827 + }
18.828 + float[] dstMinVal = new float[iccDstNumComp];
18.829 + float[] dstDiffMinMax = new float[iccDstNumComp];
18.830 + for (int i = 0; i < dstNumComp; i++) {
18.831 + dstMinVal[i] = cs.getMinValue(i);
18.832 + dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
18.833 + }
18.834 + float[] dstColor;
18.835 + if (dstHasAlpha) {
18.836 + int size = ((dstNumComp + 1) > 3) ? (dstNumComp + 1) : 3;
18.837 + dstColor = new float[size];
18.838 + } else {
18.839 + int size = (dstNumComp > 3) ? dstNumComp : 3;
18.840 + dstColor = new float[size];
18.841 + }
18.842 + short[] srcLine = new short[w * iccSrcNumComp];
18.843 + short[] dstLine = new short[w * iccDstNumComp];
18.844 + Object pixel;
18.845 + float[] color;
18.846 + float[] alpha = null;
18.847 + if (needSrcAlpha) {
18.848 + alpha = new float[w];
18.849 + }
18.850 + int idx;
18.851 + // process each scanline
18.852 + for (int y = 0; y < h; y++) {
18.853 + // convert src scanline
18.854 + pixel = null;
18.855 + color = null;
18.856 + idx = 0;
18.857 + for (int x = 0; x < w; x++) {
18.858 + pixel = srcRas.getDataElements(x, y, pixel);
18.859 + color = srcCM.getNormalizedComponents(pixel, color, 0);
18.860 + if (needSrcAlpha) {
18.861 + alpha[x] = color[srcNumComp];
18.862 + }
18.863 + if (nonICCSrc) {
18.864 + color = srcColorSpace.toCIEXYZ(color);
18.865 + }
18.866 + for (int i = 0; i < iccSrcNumComp; i++) {
18.867 + srcLine[idx++] = (short)
18.868 + ((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
18.869 + 0.5f);
18.870 + }
18.871 + }
18.872 + // color convert srcLine to dstLine
18.873 + thisTransform.colorConvert(srcLine, dstLine);
18.874 + // convert dst scanline
18.875 + pixel = null;
18.876 + idx = 0;
18.877 + for (int x = 0; x < w; x++) {
18.878 + for (int i = 0; i < iccDstNumComp; i++) {
18.879 + dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
18.880 + dstDiffMinMax[i] + dstMinVal[i];
18.881 + }
18.882 + if (nonICCDst) {
18.883 + color = srcColorSpace.fromCIEXYZ(dstColor);
18.884 + for (int i = 0; i < dstNumComp; i++) {
18.885 + dstColor[i] = color[i];
18.886 + }
18.887 + }
18.888 + if (needSrcAlpha) {
18.889 + dstColor[dstNumComp] = alpha[x];
18.890 + } else if (dstHasAlpha) {
18.891 + dstColor[dstNumComp] = 1.0f;
18.892 + }
18.893 + pixel = dstCM.getDataElements(dstColor, 0, pixel);
18.894 + dstRas.setDataElements(x, y, pixel);
18.895 + }
18.896 + }
18.897 + } else {
18.898 + /* possible non-ICC src, possible CSList, possible non-ICC dst */
18.899 + // process per pixel
18.900 + int numCS;
18.901 + if (CSList == null) {
18.902 + numCS = 0;
18.903 + } else {
18.904 + numCS = CSList.length;
18.905 + }
18.906 + float[] dstColor;
18.907 + if (dstHasAlpha) {
18.908 + dstColor = new float[dstNumComp + 1];
18.909 + } else {
18.910 + dstColor = new float[dstNumComp];
18.911 + }
18.912 + Object spixel = null;
18.913 + Object dpixel = null;
18.914 + float[] color = null;
18.915 + float[] tmpColor;
18.916 + // process each pixel
18.917 + for (int y = 0; y < h; y++) {
18.918 + for (int x = 0; x < w; x++) {
18.919 + spixel = srcRas.getDataElements(x, y, spixel);
18.920 + color = srcCM.getNormalizedComponents(spixel, color, 0);
18.921 + tmpColor = srcColorSpace.toCIEXYZ(color);
18.922 + for (int i = 0; i < numCS; i++) {
18.923 + tmpColor = CSList[i].fromCIEXYZ(tmpColor);
18.924 + tmpColor = CSList[i].toCIEXYZ(tmpColor);
18.925 + }
18.926 + tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
18.927 + for (int i = 0; i < dstNumComp; i++) {
18.928 + dstColor[i] = tmpColor[i];
18.929 + }
18.930 + if (needSrcAlpha) {
18.931 + dstColor[dstNumComp] = color[srcNumComp];
18.932 + } else if (dstHasAlpha) {
18.933 + dstColor[dstNumComp] = 1.0f;
18.934 + }
18.935 + dpixel = dstCM.getDataElements(dstColor, 0, dpixel);
18.936 + dstRas.setDataElements(x, y, dpixel);
18.937 +
18.938 + }
18.939 + }
18.940 + }
18.941 +
18.942 + return dst;
18.943 + }
18.944 +
18.945 + /* color convert a Raster - handles byte, ushort, int, short, float,
18.946 + or double transferTypes */
18.947 + private final WritableRaster nonICCRasterFilter(Raster src,
18.948 + WritableRaster dst) {
18.949 +
18.950 + if (CSList.length != 2) {
18.951 + throw new IllegalArgumentException(
18.952 + "Destination ColorSpace is undefined");
18.953 + }
18.954 + if (src.getNumBands() != CSList[0].getNumComponents()) {
18.955 + throw new IllegalArgumentException(
18.956 + "Numbers of source Raster bands and source color space " +
18.957 + "components do not match");
18.958 + }
18.959 + if (dst == null) {
18.960 + dst = createCompatibleDestRaster(src);
18.961 + } else {
18.962 + if (src.getHeight() != dst.getHeight() ||
18.963 + src.getWidth() != dst.getWidth()) {
18.964 + throw new IllegalArgumentException(
18.965 + "Width or height of Rasters do not match");
18.966 + }
18.967 + if (dst.getNumBands() != CSList[1].getNumComponents()) {
18.968 + throw new IllegalArgumentException(
18.969 + "Numbers of destination Raster bands and destination " +
18.970 + "color space components do not match");
18.971 + }
18.972 + }
18.973 +
18.974 + if (srcMinVals == null) {
18.975 + getMinMaxValsFromColorSpaces(CSList[0], CSList[1]);
18.976 + }
18.977 +
18.978 + SampleModel srcSM = src.getSampleModel();
18.979 + SampleModel dstSM = dst.getSampleModel();
18.980 + boolean srcIsFloat, dstIsFloat;
18.981 + int srcTransferType = src.getTransferType();
18.982 + int dstTransferType = dst.getTransferType();
18.983 + if ((srcTransferType == DataBuffer.TYPE_FLOAT) ||
18.984 + (srcTransferType == DataBuffer.TYPE_DOUBLE)) {
18.985 + srcIsFloat = true;
18.986 + } else {
18.987 + srcIsFloat = false;
18.988 + }
18.989 + if ((dstTransferType == DataBuffer.TYPE_FLOAT) ||
18.990 + (dstTransferType == DataBuffer.TYPE_DOUBLE)) {
18.991 + dstIsFloat = true;
18.992 + } else {
18.993 + dstIsFloat = false;
18.994 + }
18.995 + int w = src.getWidth();
18.996 + int h = src.getHeight();
18.997 + int srcNumBands = src.getNumBands();
18.998 + int dstNumBands = dst.getNumBands();
18.999 + float[] srcScaleFactor = null;
18.1000 + float[] dstScaleFactor = null;
18.1001 + if (!srcIsFloat) {
18.1002 + srcScaleFactor = new float[srcNumBands];
18.1003 + for (int i = 0; i < srcNumBands; i++) {
18.1004 + if (srcTransferType == DataBuffer.TYPE_SHORT) {
18.1005 + srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
18.1006 + 32767.0f;
18.1007 + } else {
18.1008 + srcScaleFactor[i] = (srcMaxVals[i] - srcMinVals[i]) /
18.1009 + ((float) ((1 << srcSM.getSampleSize(i)) - 1));
18.1010 + }
18.1011 + }
18.1012 + }
18.1013 + if (!dstIsFloat) {
18.1014 + dstScaleFactor = new float[dstNumBands];
18.1015 + for (int i = 0; i < dstNumBands; i++) {
18.1016 + if (dstTransferType == DataBuffer.TYPE_SHORT) {
18.1017 + dstScaleFactor[i] = 32767.0f /
18.1018 + (dstMaxVals[i] - dstMinVals[i]);
18.1019 + } else {
18.1020 + dstScaleFactor[i] =
18.1021 + ((float) ((1 << dstSM.getSampleSize(i)) - 1)) /
18.1022 + (dstMaxVals[i] - dstMinVals[i]);
18.1023 + }
18.1024 + }
18.1025 + }
18.1026 + int ys = src.getMinY();
18.1027 + int yd = dst.getMinY();
18.1028 + int xs, xd;
18.1029 + float sample;
18.1030 + float[] color = new float[srcNumBands];
18.1031 + float[] tmpColor;
18.1032 + ColorSpace srcColorSpace = CSList[0];
18.1033 + ColorSpace dstColorSpace = CSList[1];
18.1034 + // process each pixel
18.1035 + for (int y = 0; y < h; y++, ys++, yd++) {
18.1036 + // get src scanline
18.1037 + xs = src.getMinX();
18.1038 + xd = dst.getMinX();
18.1039 + for (int x = 0; x < w; x++, xs++, xd++) {
18.1040 + for (int i = 0; i < srcNumBands; i++) {
18.1041 + sample = src.getSampleFloat(xs, ys, i);
18.1042 + if (!srcIsFloat) {
18.1043 + sample = sample * srcScaleFactor[i] + srcMinVals[i];
18.1044 + }
18.1045 + color[i] = sample;
18.1046 + }
18.1047 + tmpColor = srcColorSpace.toCIEXYZ(color);
18.1048 + tmpColor = dstColorSpace.fromCIEXYZ(tmpColor);
18.1049 + for (int i = 0; i < dstNumBands; i++) {
18.1050 + sample = tmpColor[i];
18.1051 + if (!dstIsFloat) {
18.1052 + sample = (sample - dstMinVals[i]) * dstScaleFactor[i];
18.1053 + }
18.1054 + dst.setSample(xd, yd, i, sample);
18.1055 + }
18.1056 + }
18.1057 + }
18.1058 + return dst;
18.1059 + }
18.1060 +
18.1061 + private void getMinMaxValsFromProfiles(ICC_Profile srcProfile,
18.1062 + ICC_Profile dstProfile) {
18.1063 + int type = srcProfile.getColorSpaceType();
18.1064 + int nc = srcProfile.getNumComponents();
18.1065 + srcMinVals = new float[nc];
18.1066 + srcMaxVals = new float[nc];
18.1067 + setMinMax(type, nc, srcMinVals, srcMaxVals);
18.1068 + type = dstProfile.getColorSpaceType();
18.1069 + nc = dstProfile.getNumComponents();
18.1070 + dstMinVals = new float[nc];
18.1071 + dstMaxVals = new float[nc];
18.1072 + setMinMax(type, nc, dstMinVals, dstMaxVals);
18.1073 + }
18.1074 +
18.1075 + private void setMinMax(int type, int nc, float[] minVals, float[] maxVals) {
18.1076 + if (type == ColorSpace.TYPE_Lab) {
18.1077 + minVals[0] = 0.0f; // L
18.1078 + maxVals[0] = 100.0f;
18.1079 + minVals[1] = -128.0f; // a
18.1080 + maxVals[1] = 127.0f;
18.1081 + minVals[2] = -128.0f; // b
18.1082 + maxVals[2] = 127.0f;
18.1083 + } else if (type == ColorSpace.TYPE_XYZ) {
18.1084 + minVals[0] = minVals[1] = minVals[2] = 0.0f; // X, Y, Z
18.1085 + maxVals[0] = maxVals[1] = maxVals[2] = 1.0f + (32767.0f/ 32768.0f);
18.1086 + } else {
18.1087 + for (int i = 0; i < nc; i++) {
18.1088 + minVals[i] = 0.0f;
18.1089 + maxVals[i] = 1.0f;
18.1090 + }
18.1091 + }
18.1092 + }
18.1093 +
18.1094 + private void getMinMaxValsFromColorSpaces(ColorSpace srcCspace,
18.1095 + ColorSpace dstCspace) {
18.1096 + int nc = srcCspace.getNumComponents();
18.1097 + srcMinVals = new float[nc];
18.1098 + srcMaxVals = new float[nc];
18.1099 + for (int i = 0; i < nc; i++) {
18.1100 + srcMinVals[i] = srcCspace.getMinValue(i);
18.1101 + srcMaxVals[i] = srcCspace.getMaxValue(i);
18.1102 + }
18.1103 + nc = dstCspace.getNumComponents();
18.1104 + dstMinVals = new float[nc];
18.1105 + dstMaxVals = new float[nc];
18.1106 + for (int i = 0; i < nc; i++) {
18.1107 + dstMinVals[i] = dstCspace.getMinValue(i);
18.1108 + dstMaxVals[i] = dstCspace.getMaxValue(i);
18.1109 + }
18.1110 + }
18.1111 +
18.1112 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/src/share/classes/java/awt/image/ComponentSampleModel.java Thu Jun 12 11:46:57 2008 -0700
19.3 @@ -0,0 +1,1202 @@
19.4 +/*
19.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
19.7 + *
19.8 + * This code is free software; you can redistribute it and/or modify it
19.9 + * under the terms of the GNU General Public License version 2 only, as
19.10 + * published by the Free Software Foundation. Sun designates this
19.11 + * particular file as subject to the "Classpath" exception as provided
19.12 + * by Sun in the LICENSE file that accompanied this code.
19.13 + *
19.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
19.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19.17 + * version 2 for more details (a copy is included in the LICENSE file that
19.18 + * accompanied this code).
19.19 + *
19.20 + * You should have received a copy of the GNU General Public License version
19.21 + * 2 along with this work; if not, write to the Free Software Foundation,
19.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19.23 + *
19.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
19.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
19.26 + * have any questions.
19.27 + */
19.28 +
19.29 +/* ****************************************************************
19.30 + ******************************************************************
19.31 + ******************************************************************
19.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
19.33 + *** As an unpublished work pursuant to Title 17 of the United
19.34 + *** States Code. All rights reserved.
19.35 + ******************************************************************
19.36 + ******************************************************************
19.37 + ******************************************************************/
19.38 +
19.39 +package java.awt.image;
19.40 +
19.41 +import java.util.Arrays;
19.42 +
19.43 +/**
19.44 + * This class represents image data which is stored such that each sample
19.45 + * of a pixel occupies one data element of the DataBuffer. It stores the
19.46 + * N samples which make up a pixel in N separate data array elements.
19.47 + * Different bands may be in different banks of the DataBuffer.
19.48 + * Accessor methods are provided so that image data can be manipulated
19.49 + * directly. This class can support different kinds of interleaving, e.g.
19.50 + * band interleaving, scanline interleaving, and pixel interleaving.
19.51 + * Pixel stride is the number of data array elements between two samples
19.52 + * for the same band on the same scanline. Scanline stride is the number
19.53 + * of data array elements between a given sample and the corresponding sample
19.54 + * in the same column of the next scanline. Band offsets denote the number
19.55 + * of data array elements from the first data array element of the bank
19.56 + * of the DataBuffer holding each band to the first sample of the band.
19.57 + * The bands are numbered from 0 to N-1. This class can represent image
19.58 + * data for which each sample is an unsigned integral number which can be
19.59 + * stored in 8, 16, or 32 bits (using <code>DataBuffer.TYPE_BYTE</code>,
19.60 + * <code>DataBuffer.TYPE_USHORT</code>, or <code>DataBuffer.TYPE_INT</code>,
19.61 + * respectively), data for which each sample is a signed integral number
19.62 + * which can be stored in 16 bits (using <code>DataBuffer.TYPE_SHORT</code>),
19.63 + * or data for which each sample is a signed float or double quantity
19.64 + * (using <code>DataBuffer.TYPE_FLOAT</code> or
19.65 + * <code>DataBuffer.TYPE_DOUBLE</code>, respectively).
19.66 + * All samples of a given ComponentSampleModel
19.67 + * are stored with the same precision. All strides and offsets must be
19.68 + * non-negative. This class supports
19.69 + * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
19.70 + * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
19.71 + * {@link DataBuffer#TYPE_SHORT TYPE_SHORT},
19.72 + * {@link DataBuffer#TYPE_INT TYPE_INT},
19.73 + * {@link DataBuffer#TYPE_FLOAT TYPE_FLOAT},
19.74 + * {@link DataBuffer#TYPE_DOUBLE TYPE_DOUBLE},
19.75 + * @see java.awt.image.PixelInterleavedSampleModel
19.76 + * @see java.awt.image.BandedSampleModel
19.77 + */
19.78 +
19.79 +public class ComponentSampleModel extends SampleModel
19.80 +{
19.81 + /** Offsets for all bands in data array elements. */
19.82 + protected int bandOffsets[];
19.83 +
19.84 + /** Index for each bank storing a band of image data. */
19.85 + protected int[] bankIndices;
19.86 +
19.87 + /**
19.88 + * The number of bands in this
19.89 + * <code>ComponentSampleModel</code>.
19.90 + */
19.91 + protected int numBands = 1;
19.92 +
19.93 + /**
19.94 + * The number of banks in this
19.95 + * <code>ComponentSampleModel</code>.
19.96 + */
19.97 + protected int numBanks = 1;
19.98 +
19.99 + /**
19.100 + * Line stride (in data array elements) of the region of image
19.101 + * data described by this ComponentSampleModel.
19.102 + */
19.103 + protected int scanlineStride;
19.104 +
19.105 + /** Pixel stride (in data array elements) of the region of image
19.106 + * data described by this ComponentSampleModel.
19.107 + */
19.108 + protected int pixelStride;
19.109 +
19.110 + static private native void initIDs();
19.111 + static {
19.112 + ColorModel.loadLibraries();
19.113 + initIDs();
19.114 + }
19.115 +
19.116 + /**
19.117 + * Constructs a ComponentSampleModel with the specified parameters.
19.118 + * The number of bands will be given by the length of the bandOffsets array.
19.119 + * All bands will be stored in the first bank of the DataBuffer.
19.120 + * @param dataType the data type for storing samples
19.121 + * @param w the width (in pixels) of the region of
19.122 + * image data described
19.123 + * @param h the height (in pixels) of the region of
19.124 + * image data described
19.125 + * @param pixelStride the pixel stride of the region of image
19.126 + * data described
19.127 + * @param scanlineStride the line stride of the region of image
19.128 + * data described
19.129 + * @param bandOffsets the offsets of all bands
19.130 + * @throws IllegalArgumentException if <code>w</code> or
19.131 + * <code>h</code> is not greater than 0
19.132 + * @throws IllegalArgumentException if <code>pixelStride</code>
19.133 + * is less than 0
19.134 + * @throws IllegalArgumentException if <code>scanlineStride</code>
19.135 + * is less than 0
19.136 + * @throws IllegalArgumentException if <code>numBands</code>
19.137 + * is less than 1
19.138 + * @throws IllegalArgumentException if the product of <code>w</code>
19.139 + * and <code>h</code> is greater than
19.140 + * <code>Integer.MAX_VALUE</code>
19.141 + * @throws IllegalArgumentException if <code>dataType</code> is not
19.142 + * one of the supported data types
19.143 + */
19.144 + public ComponentSampleModel(int dataType,
19.145 + int w, int h,
19.146 + int pixelStride,
19.147 + int scanlineStride,
19.148 + int bandOffsets[]) {
19.149 + super(dataType, w, h, bandOffsets.length);
19.150 + this.dataType = dataType;
19.151 + this.pixelStride = pixelStride;
19.152 + this.scanlineStride = scanlineStride;
19.153 + this.bandOffsets = (int[])bandOffsets.clone();
19.154 + numBands = bandOffsets.length;
19.155 + if (pixelStride < 0) {
19.156 + throw new IllegalArgumentException("Pixel stride must be >= 0");
19.157 + }
19.158 + // TODO - bug 4296691 - remove this check
19.159 + if (scanlineStride < 0) {
19.160 + throw new IllegalArgumentException("Scanline stride must be >= 0");
19.161 + }
19.162 + if (numBands < 1) {
19.163 + throw new IllegalArgumentException("Must have at least one band.");
19.164 + }
19.165 + if ((dataType < DataBuffer.TYPE_BYTE) ||
19.166 + (dataType > DataBuffer.TYPE_DOUBLE)) {
19.167 + throw new IllegalArgumentException("Unsupported dataType.");
19.168 + }
19.169 + bankIndices = new int[numBands];
19.170 + for (int i=0; i<numBands; i++) {
19.171 + bankIndices[i] = 0;
19.172 + }
19.173 + }
19.174 +
19.175 +
19.176 + /**
19.177 + * Constructs a ComponentSampleModel with the specified parameters.
19.178 + * The number of bands will be given by the length of the bandOffsets array.
19.179 + * Different bands may be stored in different banks of the DataBuffer.
19.180 + *
19.181 + * @param dataType the data type for storing samples
19.182 + * @param w the width (in pixels) of the region of
19.183 + * image data described
19.184 + * @param h the height (in pixels) of the region of
19.185 + * image data described
19.186 + * @param pixelStride the pixel stride of the region of image
19.187 + * data described
19.188 + * @param scanlineStride The line stride of the region of image
19.189 + * data described
19.190 + * @param bankIndices the bank indices of all bands
19.191 + * @param bandOffsets the band offsets of all bands
19.192 + * @throws IllegalArgumentException if <code>w</code> or
19.193 + * <code>h</code> is not greater than 0
19.194 + * @throws IllegalArgumentException if <code>pixelStride</code>
19.195 + * is less than 0
19.196 + * @throws IllegalArgumentException if <code>scanlineStride</code>
19.197 + * is less than 0
19.198 + * @throws IllegalArgumentException if the length of
19.199 + * <code>bankIndices</code> does not equal the length of
19.200 + * <code>bankOffsets</code>
19.201 + * @throws IllegalArgumentException if any of the bank indices
19.202 + * of <code>bandIndices</code> is less than 0
19.203 + * @throws IllegalArgumentException if <code>dataType</code> is not
19.204 + * one of the supported data types
19.205 + */
19.206 + public ComponentSampleModel(int dataType,
19.207 + int w, int h,
19.208 + int pixelStride,
19.209 + int scanlineStride,
19.210 + int bankIndices[],
19.211 + int bandOffsets[]) {
19.212 + super(dataType, w, h, bandOffsets.length);
19.213 + this.dataType = dataType;
19.214 + this.pixelStride = pixelStride;
19.215 + this.scanlineStride = scanlineStride;
19.216 + this.bandOffsets = (int[])bandOffsets.clone();
19.217 + this.bankIndices = (int[]) bankIndices.clone();
19.218 + if (pixelStride < 0) {
19.219 + throw new IllegalArgumentException("Pixel stride must be >= 0");
19.220 + }
19.221 + // TODO - bug 4296691 - remove this check
19.222 + if (scanlineStride < 0) {
19.223 + throw new IllegalArgumentException("Scanline stride must be >= 0");
19.224 + }
19.225 + if ((dataType < DataBuffer.TYPE_BYTE) ||
19.226 + (dataType > DataBuffer.TYPE_DOUBLE)) {
19.227 + throw new IllegalArgumentException("Unsupported dataType.");
19.228 + }
19.229 + int maxBank = bankIndices[0];
19.230 + if (maxBank < 0) {
19.231 + throw new IllegalArgumentException("Index of bank 0 is less than "+
19.232 + "0 ("+maxBank+")");
19.233 + }
19.234 + for (int i=1; i < bankIndices.length; i++) {
19.235 + if (bankIndices[i] > maxBank) {
19.236 + maxBank = bankIndices[i];
19.237 + }
19.238 + else if (bankIndices[i] < 0) {
19.239 + throw new IllegalArgumentException("Index of bank "+i+
19.240 + " is less than 0 ("+
19.241 + maxBank+")");
19.242 + }
19.243 + }
19.244 + numBanks = maxBank+1;
19.245 + numBands = bandOffsets.length;
19.246 + if (bandOffsets.length != bankIndices.length) {
19.247 + throw new IllegalArgumentException("Length of bandOffsets must "+
19.248 + "equal length of bankIndices.");
19.249 + }
19.250 + }
19.251 +
19.252 + /**
19.253 + * Returns the size of the data buffer (in data elements) needed
19.254 + * for a data buffer that matches this ComponentSampleModel.
19.255 + */
19.256 + private long getBufferSize() {
19.257 + int maxBandOff=bandOffsets[0];
19.258 + for (int i=1; i<bandOffsets.length; i++)
19.259 + maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
19.260 +
19.261 + long size = 0;
19.262 + if (maxBandOff >= 0)
19.263 + size += maxBandOff+1;
19.264 + if (pixelStride > 0)
19.265 + size += pixelStride * (width-1);
19.266 + if (scanlineStride > 0)
19.267 + size += scanlineStride*(height-1);
19.268 + return size;
19.269 + }
19.270 +
19.271 + /**
19.272 + * Preserves band ordering with new step factor...
19.273 + */
19.274 + int []orderBands(int orig[], int step) {
19.275 + int map[] = new int[orig.length];
19.276 + int ret[] = new int[orig.length];
19.277 +
19.278 + for (int i=0; i<map.length; i++) map[i] = i;
19.279 +
19.280 + for (int i = 0; i < ret.length; i++) {
19.281 + int index = i;
19.282 + for (int j = i+1; j < ret.length; j++) {
19.283 + if (orig[map[index]] > orig[map[j]]) {
19.284 + index = j;
19.285 + }
19.286 + }
19.287 + ret[map[index]] = i*step;
19.288 + map[index] = map[i];
19.289 + }
19.290 + return ret;
19.291 + }
19.292 +
19.293 + /**
19.294 + * Creates a new <code>ComponentSampleModel</code> with the specified
19.295 + * width and height. The new <code>SampleModel</code> will have the same
19.296 + * number of bands, storage data type, interleaving scheme, and
19.297 + * pixel stride as this <code>SampleModel</code>.
19.298 + * @param w the width of the resulting <code>SampleModel</code>
19.299 + * @param h the height of the resulting <code>SampleModel</code>
19.300 + * @return a new <code>ComponentSampleModel</code> with the specified size
19.301 + * @throws IllegalArgumentException if <code>w</code> or
19.302 + * <code>h</code> is not greater than 0
19.303 + */
19.304 + public SampleModel createCompatibleSampleModel(int w, int h) {
19.305 + SampleModel ret=null;
19.306 + long size;
19.307 + int minBandOff=bandOffsets[0];
19.308 + int maxBandOff=bandOffsets[0];
19.309 + for (int i=1; i<bandOffsets.length; i++) {
19.310 + minBandOff = Math.min(minBandOff,bandOffsets[i]);
19.311 + maxBandOff = Math.max(maxBandOff,bandOffsets[i]);
19.312 + }
19.313 + maxBandOff -= minBandOff;
19.314 +
19.315 + int bands = bandOffsets.length;
19.316 + int bandOff[];
19.317 + int pStride = Math.abs(pixelStride);
19.318 + int lStride = Math.abs(scanlineStride);
19.319 + int bStride = Math.abs(maxBandOff);
19.320 +
19.321 + if (pStride > lStride) {
19.322 + if (pStride > bStride) {
19.323 + if (lStride > bStride) { // pix > line > band
19.324 + bandOff = new int[bandOffsets.length];
19.325 + for (int i=0; i<bands; i++)
19.326 + bandOff[i] = bandOffsets[i]-minBandOff;
19.327 + lStride = bStride+1;
19.328 + pStride = lStride*h;
19.329 + } else { // pix > band > line
19.330 + bandOff = orderBands(bandOffsets,lStride*h);
19.331 + pStride = bands*lStride*h;
19.332 + }
19.333 + } else { // band > pix > line
19.334 + pStride = lStride*h;
19.335 + bandOff = orderBands(bandOffsets,pStride*w);
19.336 + }
19.337 + } else {
19.338 + if (pStride > bStride) { // line > pix > band
19.339 + bandOff = new int[bandOffsets.length];
19.340 + for (int i=0; i<bands; i++)
19.341 + bandOff[i] = bandOffsets[i]-minBandOff;
19.342 + pStride = bStride+1;
19.343 + lStride = pStride*w;
19.344 + } else {
19.345 + if (lStride > bStride) { // line > band > pix
19.346 + bandOff = orderBands(bandOffsets,pStride*w);
19.347 + lStride = bands*pStride*w;
19.348 + } else { // band > line > pix
19.349 + lStride = pStride*w;
19.350 + bandOff = orderBands(bandOffsets,lStride*h);
19.351 + }
19.352 + }
19.353 + }
19.354 +
19.355 + // make sure we make room for negative offsets...
19.356 + int base = 0;
19.357 + if (scanlineStride < 0) {
19.358 + base += lStride*h;
19.359 + lStride *= -1;
19.360 + }
19.361 + if (pixelStride < 0) {
19.362 + base += pStride*w;
19.363 + pStride *= -1;
19.364 + }
19.365 +
19.366 + for (int i=0; i<bands; i++)
19.367 + bandOff[i] += base;
19.368 + return new ComponentSampleModel(dataType, w, h, pStride,
19.369 + lStride, bankIndices, bandOff);
19.370 + }
19.371 +
19.372 + /**
19.373 + * Creates a new ComponentSampleModel with a subset of the bands
19.374 + * of this ComponentSampleModel. The new ComponentSampleModel can be
19.375 + * used with any DataBuffer that the existing ComponentSampleModel
19.376 + * can be used with. The new ComponentSampleModel/DataBuffer
19.377 + * combination will represent an image with a subset of the bands
19.378 + * of the original ComponentSampleModel/DataBuffer combination.
19.379 + * @param bands a subset of bands from this
19.380 + * <code>ComponentSampleModel</code>
19.381 + * @return a <code>ComponentSampleModel</code> created with a subset
19.382 + * of bands from this <code>ComponentSampleModel</code>.
19.383 + */
19.384 + public SampleModel createSubsetSampleModel(int bands[]) {
19.385 + if (bands.length > bankIndices.length)
19.386 + throw new RasterFormatException("There are only " +
19.387 + bankIndices.length +
19.388 + " bands");
19.389 + int newBankIndices[] = new int[bands.length];
19.390 + int newBandOffsets[] = new int[bands.length];
19.391 +
19.392 + for (int i=0; i<bands.length; i++) {
19.393 + newBankIndices[i] = bankIndices[bands[i]];
19.394 + newBandOffsets[i] = bandOffsets[bands[i]];
19.395 + }
19.396 +
19.397 + return new ComponentSampleModel(this.dataType, width, height,
19.398 + this.pixelStride,
19.399 + this.scanlineStride,
19.400 + newBankIndices, newBandOffsets);
19.401 + }
19.402 +
19.403 + /**
19.404 + * Creates a <code>DataBuffer</code> that corresponds to this
19.405 + * <code>ComponentSampleModel</code>.
19.406 + * The <code>DataBuffer</code> object's data type, number of banks,
19.407 + * and size are be consistent with this <code>ComponentSampleModel</code>.
19.408 + * @return a <code>DataBuffer</code> whose data type, number of banks
19.409 + * and size are consistent with this
19.410 + * <code>ComponentSampleModel</code>.
19.411 + */
19.412 + public DataBuffer createDataBuffer() {
19.413 + DataBuffer dataBuffer = null;
19.414 +
19.415 + int size = (int)getBufferSize();
19.416 + switch (dataType) {
19.417 + case DataBuffer.TYPE_BYTE:
19.418 + dataBuffer = new DataBufferByte(size, numBanks);
19.419 + break;
19.420 + case DataBuffer.TYPE_USHORT:
19.421 + dataBuffer = new DataBufferUShort(size, numBanks);
19.422 + break;
19.423 + case DataBuffer.TYPE_SHORT:
19.424 + dataBuffer = new DataBufferShort(size, numBanks);
19.425 + break;
19.426 + case DataBuffer.TYPE_INT:
19.427 + dataBuffer = new DataBufferInt(size, numBanks);
19.428 + break;
19.429 + case DataBuffer.TYPE_FLOAT:
19.430 + dataBuffer = new DataBufferFloat(size, numBanks);
19.431 + break;
19.432 + case DataBuffer.TYPE_DOUBLE:
19.433 + dataBuffer = new DataBufferDouble(size, numBanks);
19.434 + break;
19.435 + }
19.436 +
19.437 + return dataBuffer;
19.438 + }
19.439 +
19.440 +
19.441 + /** Gets the offset for the first band of pixel (x,y).
19.442 + * A sample of the first band can be retrieved from a
19.443 + * <code>DataBuffer</code>
19.444 + * <code>data</code> with a <code>ComponentSampleModel</code>
19.445 + * <code>csm</code> as
19.446 + * <pre>
19.447 + * data.getElem(csm.getOffset(x, y));
19.448 + * </pre>
19.449 + * @param x the X location of the pixel
19.450 + * @param y the Y location of the pixel
19.451 + * @return the offset for the first band of the specified pixel.
19.452 + */
19.453 + public int getOffset(int x, int y) {
19.454 + int offset = y*scanlineStride + x*pixelStride + bandOffsets[0];
19.455 + return offset;
19.456 + }
19.457 +
19.458 + /** Gets the offset for band b of pixel (x,y).
19.459 + * A sample of band <code>b</code> can be retrieved from a
19.460 + * <code>DataBuffer</code> <code>data</code>
19.461 + * with a <code>ComponentSampleModel</code> <code>csm</code> as
19.462 + * <pre>
19.463 + * data.getElem(csm.getOffset(x, y, b));
19.464 + * </pre>
19.465 + * @param x the X location of the specified pixel
19.466 + * @param y the Y location of the specified pixel
19.467 + * @param b the specified band
19.468 + * @return the offset for the specified band of the specified pixel.
19.469 + */
19.470 + public int getOffset(int x, int y, int b) {
19.471 + int offset = y*scanlineStride + x*pixelStride + bandOffsets[b];
19.472 + return offset;
19.473 + }
19.474 +
19.475 + /** Returns the number of bits per sample for all bands.
19.476 + * @return an array containing the number of bits per sample
19.477 + * for all bands, where each element in the array
19.478 + * represents a band.
19.479 + */
19.480 + public final int[] getSampleSize() {
19.481 + int sampleSize[] = new int [numBands];
19.482 + int sizeInBits = getSampleSize(0);
19.483 +
19.484 + for (int i=0; i<numBands; i++)
19.485 + sampleSize[i] = sizeInBits;
19.486 +
19.487 + return sampleSize;
19.488 + }
19.489 +
19.490 + /** Returns the number of bits per sample for the specified band.
19.491 + * @param band the specified band
19.492 + * @return the number of bits per sample for the specified band.
19.493 + */
19.494 + public final int getSampleSize(int band) {
19.495 + return DataBuffer.getDataTypeSize(dataType);
19.496 + }
19.497 +
19.498 + /** Returns the bank indices for all bands.
19.499 + * @return the bank indices for all bands.
19.500 + */
19.501 + public final int [] getBankIndices() {
19.502 + return (int[]) bankIndices.clone();
19.503 + }
19.504 +
19.505 + /** Returns the band offset for all bands.
19.506 + * @return the band offsets for all bands.
19.507 + */
19.508 + public final int [] getBandOffsets() {
19.509 + return (int[])bandOffsets.clone();
19.510 + }
19.511 +
19.512 + /** Returns the scanline stride of this ComponentSampleModel.
19.513 + * @return the scanline stride of this <code>ComponentSampleModel</code>.
19.514 + */
19.515 + public final int getScanlineStride() {
19.516 + return scanlineStride;
19.517 + }
19.518 +
19.519 + /** Returns the pixel stride of this ComponentSampleModel.
19.520 + * @return the pixel stride of this <code>ComponentSampleModel</code>.
19.521 + */
19.522 + public final int getPixelStride() {
19.523 + return pixelStride;
19.524 + }
19.525 +
19.526 + /**
19.527 + * Returns the number of data elements needed to transfer a pixel
19.528 + * with the
19.529 + * {@link #getDataElements(int, int, Object, DataBuffer) } and
19.530 + * {@link #setDataElements(int, int, Object, DataBuffer) }
19.531 + * methods.
19.532 + * For a <code>ComponentSampleModel</code>, this is identical to the
19.533 + * number of bands.
19.534 + * @return the number of data elements needed to transfer a pixel with
19.535 + * the <code>getDataElements</code> and
19.536 + * <code>setDataElements</code> methods.
19.537 + * @see java.awt.image.SampleModel#getNumDataElements
19.538 + * @see #getNumBands
19.539 + */
19.540 + public final int getNumDataElements() {
19.541 + return getNumBands();
19.542 + }
19.543 +
19.544 + /**
19.545 + * Returns data for a single pixel in a primitive array of type
19.546 + * <code>TransferType</code>. For a <code>ComponentSampleModel</code>,
19.547 + * this is the same as the data type, and samples are returned
19.548 + * one per array element. Generally, <code>obj</code> should
19.549 + * be passed in as <code>null</code>, so that the <code>Object</code>
19.550 + * is created automatically and is the right primitive data type.
19.551 + * <p>
19.552 + * The following code illustrates transferring data for one pixel from
19.553 + * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
19.554 + * described by <code>ComponentSampleModel</code> <code>csm1</code>,
19.555 + * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
19.556 + * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
19.557 + * The transfer is usually more efficient than using
19.558 + * <code>getPixel</code> and <code>setPixel</code>.
19.559 + * <pre>
19.560 + * ComponentSampleModel csm1, csm2;
19.561 + * DataBufferInt db1, db2;
19.562 + * csm2.setDataElements(x, y,
19.563 + * csm1.getDataElements(x, y, null, db1), db2);
19.564 + * </pre>
19.565 + *
19.566 + * Using <code>getDataElements</code> and <code>setDataElements</code>
19.567 + * to transfer between two <code>DataBuffer/SampleModel</code>
19.568 + * pairs is legitimate if the <code>SampleModel</code> objects have
19.569 + * the same number of bands, corresponding bands have the same number of
19.570 + * bits per sample, and the <code>TransferType</code>s are the same.
19.571 + * <p>
19.572 + * If <code>obj</code> is not <code>null</code>, it should be a
19.573 + * primitive array of type <code>TransferType</code>.
19.574 + * Otherwise, a <code>ClassCastException</code> is thrown. An
19.575 + * <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
19.576 + * coordinates are not in bounds, or if <code>obj</code> is not
19.577 + * <code>null</code> and is not large enough to hold
19.578 + * the pixel data.
19.579 + *
19.580 + * @param x the X coordinate of the pixel location
19.581 + * @param y the Y coordinate of the pixel location
19.582 + * @param obj if non-<code>null</code>, a primitive array
19.583 + * in which to return the pixel data
19.584 + * @param data the <code>DataBuffer</code> containing the image data
19.585 + * @return the data of the specified pixel
19.586 + * @see #setDataElements(int, int, Object, DataBuffer)
19.587 + *
19.588 + * @throws NullPointerException if data is null.
19.589 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
19.590 + * not in bounds, or if obj is too small to hold the ouput.
19.591 + */
19.592 + public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
19.593 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.594 + throw new ArrayIndexOutOfBoundsException
19.595 + ("Coordinate out of bounds!");
19.596 + }
19.597 +
19.598 + int type = getTransferType();
19.599 + int numDataElems = getNumDataElements();
19.600 + int pixelOffset = y*scanlineStride + x*pixelStride;
19.601 +
19.602 + switch(type) {
19.603 +
19.604 + case DataBuffer.TYPE_BYTE:
19.605 +
19.606 + byte[] bdata;
19.607 +
19.608 + if (obj == null)
19.609 + bdata = new byte[numDataElems];
19.610 + else
19.611 + bdata = (byte[])obj;
19.612 +
19.613 + for (int i=0; i<numDataElems; i++) {
19.614 + bdata[i] = (byte)data.getElem(bankIndices[i],
19.615 + pixelOffset + bandOffsets[i]);
19.616 + }
19.617 +
19.618 + obj = (Object)bdata;
19.619 + break;
19.620 +
19.621 + case DataBuffer.TYPE_USHORT:
19.622 + case DataBuffer.TYPE_SHORT:
19.623 +
19.624 + short[] sdata;
19.625 +
19.626 + if (obj == null)
19.627 + sdata = new short[numDataElems];
19.628 + else
19.629 + sdata = (short[])obj;
19.630 +
19.631 + for (int i=0; i<numDataElems; i++) {
19.632 + sdata[i] = (short)data.getElem(bankIndices[i],
19.633 + pixelOffset + bandOffsets[i]);
19.634 + }
19.635 +
19.636 + obj = (Object)sdata;
19.637 + break;
19.638 +
19.639 + case DataBuffer.TYPE_INT:
19.640 +
19.641 + int[] idata;
19.642 +
19.643 + if (obj == null)
19.644 + idata = new int[numDataElems];
19.645 + else
19.646 + idata = (int[])obj;
19.647 +
19.648 + for (int i=0; i<numDataElems; i++) {
19.649 + idata[i] = data.getElem(bankIndices[i],
19.650 + pixelOffset + bandOffsets[i]);
19.651 + }
19.652 +
19.653 + obj = (Object)idata;
19.654 + break;
19.655 +
19.656 + case DataBuffer.TYPE_FLOAT:
19.657 +
19.658 + float[] fdata;
19.659 +
19.660 + if (obj == null)
19.661 + fdata = new float[numDataElems];
19.662 + else
19.663 + fdata = (float[])obj;
19.664 +
19.665 + for (int i=0; i<numDataElems; i++) {
19.666 + fdata[i] = data.getElemFloat(bankIndices[i],
19.667 + pixelOffset + bandOffsets[i]);
19.668 + }
19.669 +
19.670 + obj = (Object)fdata;
19.671 + break;
19.672 +
19.673 + case DataBuffer.TYPE_DOUBLE:
19.674 +
19.675 + double[] ddata;
19.676 +
19.677 + if (obj == null)
19.678 + ddata = new double[numDataElems];
19.679 + else
19.680 + ddata = (double[])obj;
19.681 +
19.682 + for (int i=0; i<numDataElems; i++) {
19.683 + ddata[i] = data.getElemDouble(bankIndices[i],
19.684 + pixelOffset + bandOffsets[i]);
19.685 + }
19.686 +
19.687 + obj = (Object)ddata;
19.688 + break;
19.689 + }
19.690 +
19.691 + return obj;
19.692 + }
19.693 +
19.694 + /**
19.695 + * Returns all samples for the specified pixel in an int array,
19.696 + * one sample per array element.
19.697 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.698 + * the coordinates are not in bounds.
19.699 + * @param x the X coordinate of the pixel location
19.700 + * @param y the Y coordinate of the pixel location
19.701 + * @param iArray If non-null, returns the samples in this array
19.702 + * @param data The DataBuffer containing the image data
19.703 + * @return the samples of the specified pixel.
19.704 + * @see #setPixel(int, int, int[], DataBuffer)
19.705 + *
19.706 + * @throws NullPointerException if data is null.
19.707 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
19.708 + * not in bounds, or if iArray is too small to hold the output.
19.709 + */
19.710 + public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
19.711 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.712 + throw new ArrayIndexOutOfBoundsException
19.713 + ("Coordinate out of bounds!");
19.714 + }
19.715 + int pixels[];
19.716 + if (iArray != null) {
19.717 + pixels = iArray;
19.718 + } else {
19.719 + pixels = new int [numBands];
19.720 + }
19.721 + int pixelOffset = y*scanlineStride + x*pixelStride;
19.722 + for (int i=0; i<numBands; i++) {
19.723 + pixels[i] = data.getElem(bankIndices[i],
19.724 + pixelOffset + bandOffsets[i]);
19.725 + }
19.726 + return pixels;
19.727 + }
19.728 +
19.729 + /**
19.730 + * Returns all samples for the specified rectangle of pixels in
19.731 + * an int array, one sample per array element.
19.732 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.733 + * the coordinates are not in bounds.
19.734 + * @param x The X coordinate of the upper left pixel location
19.735 + * @param y The Y coordinate of the upper left pixel location
19.736 + * @param w The width of the pixel rectangle
19.737 + * @param h The height of the pixel rectangle
19.738 + * @param iArray If non-null, returns the samples in this array
19.739 + * @param data The DataBuffer containing the image data
19.740 + * @return the samples of the pixels within the specified region.
19.741 + * @see #setPixels(int, int, int, int, int[], DataBuffer)
19.742 + */
19.743 + public int[] getPixels(int x, int y, int w, int h,
19.744 + int iArray[], DataBuffer data) {
19.745 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
19.746 + throw new ArrayIndexOutOfBoundsException
19.747 + ("Coordinate out of bounds!");
19.748 + }
19.749 + int pixels[];
19.750 + if (iArray != null) {
19.751 + pixels = iArray;
19.752 + } else {
19.753 + pixels = new int [w*h*numBands];
19.754 + }
19.755 + int lineOffset = y*scanlineStride + x*pixelStride;
19.756 + int srcOffset = 0;
19.757 +
19.758 + for (int i = 0; i < h; i++) {
19.759 + int pixelOffset = lineOffset;
19.760 + for (int j = 0; j < w; j++) {
19.761 + for (int k=0; k < numBands; k++) {
19.762 + pixels[srcOffset++] =
19.763 + data.getElem(bankIndices[k], pixelOffset + bandOffsets[k]);
19.764 + }
19.765 + pixelOffset += pixelStride;
19.766 + }
19.767 + lineOffset += scanlineStride;
19.768 + }
19.769 + return pixels;
19.770 + }
19.771 +
19.772 + /**
19.773 + * Returns as int the sample in a specified band for the pixel
19.774 + * located at (x,y).
19.775 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.776 + * the coordinates are not in bounds.
19.777 + * @param x the X coordinate of the pixel location
19.778 + * @param y the Y coordinate of the pixel location
19.779 + * @param b the band to return
19.780 + * @param data the <code>DataBuffer</code> containing the image data
19.781 + * @return the sample in a specified band for the specified pixel
19.782 + * @see #setSample(int, int, int, int, DataBuffer)
19.783 + */
19.784 + public int getSample(int x, int y, int b, DataBuffer data) {
19.785 + // Bounds check for 'b' will be performed automatically
19.786 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.787 + throw new ArrayIndexOutOfBoundsException
19.788 + ("Coordinate out of bounds!");
19.789 + }
19.790 + int sample = data.getElem(bankIndices[b],
19.791 + y*scanlineStride + x*pixelStride +
19.792 + bandOffsets[b]);
19.793 + return sample;
19.794 + }
19.795 +
19.796 + /**
19.797 + * Returns the sample in a specified band
19.798 + * for the pixel located at (x,y) as a float.
19.799 + * An <code>ArrayIndexOutOfBoundsException</code> might be
19.800 + * thrown if the coordinates are not in bounds.
19.801 + * @param x The X coordinate of the pixel location
19.802 + * @param y The Y coordinate of the pixel location
19.803 + * @param b The band to return
19.804 + * @param data The DataBuffer containing the image data
19.805 + * @return a float value representing the sample in the specified
19.806 + * band for the specified pixel.
19.807 + */
19.808 + public float getSampleFloat(int x, int y, int b, DataBuffer data) {
19.809 + // Bounds check for 'b' will be performed automatically
19.810 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.811 + throw new ArrayIndexOutOfBoundsException
19.812 + ("Coordinate out of bounds!");
19.813 + }
19.814 +
19.815 + float sample = data.getElemFloat(bankIndices[b],
19.816 + y*scanlineStride + x*pixelStride +
19.817 + bandOffsets[b]);
19.818 + return sample;
19.819 + }
19.820 +
19.821 + /**
19.822 + * Returns the sample in a specified band
19.823 + * for a pixel located at (x,y) as a double.
19.824 + * An <code>ArrayIndexOutOfBoundsException</code> might be
19.825 + * thrown if the coordinates are not in bounds.
19.826 + * @param x The X coordinate of the pixel location
19.827 + * @param y The Y coordinate of the pixel location
19.828 + * @param b The band to return
19.829 + * @param data The DataBuffer containing the image data
19.830 + * @return a double value representing the sample in the specified
19.831 + * band for the specified pixel.
19.832 + */
19.833 + public double getSampleDouble(int x, int y, int b, DataBuffer data) {
19.834 + // Bounds check for 'b' will be performed automatically
19.835 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.836 + throw new ArrayIndexOutOfBoundsException
19.837 + ("Coordinate out of bounds!");
19.838 + }
19.839 +
19.840 + double sample = data.getElemDouble(bankIndices[b],
19.841 + y*scanlineStride + x*pixelStride +
19.842 + bandOffsets[b]);
19.843 + return sample;
19.844 + }
19.845 +
19.846 + /**
19.847 + * Returns the samples in a specified band for the specified rectangle
19.848 + * of pixels in an int array, one sample per data array element.
19.849 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.850 + * the coordinates are not in bounds.
19.851 + * @param x The X coordinate of the upper left pixel location
19.852 + * @param y The Y coordinate of the upper left pixel location
19.853 + * @param w the width of the pixel rectangle
19.854 + * @param h the height of the pixel rectangle
19.855 + * @param b the band to return
19.856 + * @param iArray if non-<code>null</code>, returns the samples
19.857 + * in this array
19.858 + * @param data the <code>DataBuffer</code> containing the image data
19.859 + * @return the samples in the specified band of the specified pixel
19.860 + * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
19.861 + */
19.862 + public int[] getSamples(int x, int y, int w, int h, int b,
19.863 + int iArray[], DataBuffer data) {
19.864 + // Bounds check for 'b' will be performed automatically
19.865 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
19.866 + throw new ArrayIndexOutOfBoundsException
19.867 + ("Coordinate out of bounds!");
19.868 + }
19.869 + int samples[];
19.870 + if (iArray != null) {
19.871 + samples = iArray;
19.872 + } else {
19.873 + samples = new int [w*h];
19.874 + }
19.875 + int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
19.876 + int srcOffset = 0;
19.877 +
19.878 + for (int i = 0; i < h; i++) {
19.879 + int sampleOffset = lineOffset;
19.880 + for (int j = 0; j < w; j++) {
19.881 + samples[srcOffset++] = data.getElem(bankIndices[b],
19.882 + sampleOffset);
19.883 + sampleOffset += pixelStride;
19.884 + }
19.885 + lineOffset += scanlineStride;
19.886 + }
19.887 + return samples;
19.888 + }
19.889 +
19.890 + /**
19.891 + * Sets the data for a single pixel in the specified
19.892 + * <code>DataBuffer</code> from a primitive array of type
19.893 + * <code>TransferType</code>. For a <code>ComponentSampleModel</code>,
19.894 + * this is the same as the data type, and samples are transferred
19.895 + * one per array element.
19.896 + * <p>
19.897 + * The following code illustrates transferring data for one pixel from
19.898 + * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
19.899 + * described by <code>ComponentSampleModel</code> <code>csm1</code>,
19.900 + * to <code>DataBuffer</code> <code>db2</code>, whose storage layout
19.901 + * is described by <code>ComponentSampleModel</code> <code>csm2</code>.
19.902 + * The transfer is usually more efficient than using
19.903 + * <code>getPixel</code> and <code>setPixel</code>.
19.904 + * <pre>
19.905 + * ComponentSampleModel csm1, csm2;
19.906 + * DataBufferInt db1, db2;
19.907 + * csm2.setDataElements(x, y, csm1.getDataElements(x, y, null, db1),
19.908 + * db2);
19.909 + * </pre>
19.910 + * Using <code>getDataElements</code> and <code>setDataElements</code>
19.911 + * to transfer between two <code>DataBuffer/SampleModel</code> pairs
19.912 + * is legitimate if the <code>SampleModel</code> objects have
19.913 + * the same number of bands, corresponding bands have the same number of
19.914 + * bits per sample, and the <code>TransferType</code>s are the same.
19.915 + * <p>
19.916 + * A <code>ClassCastException</code> is thrown if <code>obj</code> is not
19.917 + * a primitive array of type <code>TransferType</code>.
19.918 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.919 + * the coordinates are not in bounds, or if <code>obj</code> is not large
19.920 + * enough to hold the pixel data.
19.921 + * @param x the X coordinate of the pixel location
19.922 + * @param y the Y coordinate of the pixel location
19.923 + * @param obj a primitive array containing pixel data
19.924 + * @param data the DataBuffer containing the image data
19.925 + * @see #getDataElements(int, int, Object, DataBuffer)
19.926 + */
19.927 + public void setDataElements(int x, int y, Object obj, DataBuffer data) {
19.928 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.929 + throw new ArrayIndexOutOfBoundsException
19.930 + ("Coordinate out of bounds!");
19.931 + }
19.932 +
19.933 + int type = getTransferType();
19.934 + int numDataElems = getNumDataElements();
19.935 + int pixelOffset = y*scanlineStride + x*pixelStride;
19.936 +
19.937 + switch(type) {
19.938 +
19.939 + case DataBuffer.TYPE_BYTE:
19.940 +
19.941 + byte[] barray = (byte[])obj;
19.942 +
19.943 + for (int i=0; i<numDataElems; i++) {
19.944 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
19.945 + ((int)barray[i])&0xff);
19.946 + }
19.947 + break;
19.948 +
19.949 + case DataBuffer.TYPE_USHORT:
19.950 + case DataBuffer.TYPE_SHORT:
19.951 +
19.952 + short[] sarray = (short[])obj;
19.953 +
19.954 + for (int i=0; i<numDataElems; i++) {
19.955 + data.setElem(bankIndices[i], pixelOffset + bandOffsets[i],
19.956 + ((int)sarray[i])&0xffff);
19.957 + }
19.958 + break;
19.959 +
19.960 + case DataBuffer.TYPE_INT:
19.961 +
19.962 + int[] iarray = (int[])obj;
19.963 +
19.964 + for (int i=0; i<numDataElems; i++) {
19.965 + data.setElem(bankIndices[i],
19.966 + pixelOffset + bandOffsets[i], iarray[i]);
19.967 + }
19.968 + break;
19.969 +
19.970 + case DataBuffer.TYPE_FLOAT:
19.971 +
19.972 + float[] farray = (float[])obj;
19.973 +
19.974 + for (int i=0; i<numDataElems; i++) {
19.975 + data.setElemFloat(bankIndices[i],
19.976 + pixelOffset + bandOffsets[i], farray[i]);
19.977 + }
19.978 + break;
19.979 +
19.980 + case DataBuffer.TYPE_DOUBLE:
19.981 +
19.982 + double[] darray = (double[])obj;
19.983 +
19.984 + for (int i=0; i<numDataElems; i++) {
19.985 + data.setElemDouble(bankIndices[i],
19.986 + pixelOffset + bandOffsets[i], darray[i]);
19.987 + }
19.988 + break;
19.989 +
19.990 + }
19.991 + }
19.992 +
19.993 + /**
19.994 + * Sets a pixel in the <code>DataBuffer</code> using an int array of
19.995 + * samples for input. An <code>ArrayIndexOutOfBoundsException</code>
19.996 + * might be thrown if the coordinates are
19.997 + * not in bounds.
19.998 + * @param x The X coordinate of the pixel location
19.999 + * @param y The Y coordinate of the pixel location
19.1000 + * @param iArray The input samples in an int array
19.1001 + * @param data The DataBuffer containing the image data
19.1002 + * @see #getPixel(int, int, int[], DataBuffer)
19.1003 + */
19.1004 + public void setPixel(int x, int y, int iArray[], DataBuffer data) {
19.1005 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.1006 + throw new ArrayIndexOutOfBoundsException
19.1007 + ("Coordinate out of bounds!");
19.1008 + }
19.1009 + int pixelOffset = y*scanlineStride + x*pixelStride;
19.1010 + for (int i=0; i<numBands; i++) {
19.1011 + data.setElem(bankIndices[i],
19.1012 + pixelOffset + bandOffsets[i],iArray[i]);
19.1013 + }
19.1014 + }
19.1015 +
19.1016 + /**
19.1017 + * Sets all samples for a rectangle of pixels from an int array containing
19.1018 + * one sample per array element.
19.1019 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
19.1020 + * coordinates are not in bounds.
19.1021 + * @param x The X coordinate of the upper left pixel location
19.1022 + * @param y The Y coordinate of the upper left pixel location
19.1023 + * @param w The width of the pixel rectangle
19.1024 + * @param h The height of the pixel rectangle
19.1025 + * @param iArray The input samples in an int array
19.1026 + * @param data The DataBuffer containing the image data
19.1027 + * @see #getPixels(int, int, int, int, int[], DataBuffer)
19.1028 + */
19.1029 + public void setPixels(int x, int y, int w, int h,
19.1030 + int iArray[], DataBuffer data) {
19.1031 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
19.1032 + throw new ArrayIndexOutOfBoundsException
19.1033 + ("Coordinate out of bounds!");
19.1034 + }
19.1035 +
19.1036 + int lineOffset = y*scanlineStride + x*pixelStride;
19.1037 + int srcOffset = 0;
19.1038 +
19.1039 + for (int i = 0; i < h; i++) {
19.1040 + int pixelOffset = lineOffset;
19.1041 + for (int j = 0; j < w; j++) {
19.1042 + for (int k=0; k < numBands; k++) {
19.1043 + data.setElem(bankIndices[k], pixelOffset + bandOffsets[k],
19.1044 + iArray[srcOffset++]);
19.1045 + }
19.1046 + pixelOffset += pixelStride;
19.1047 + }
19.1048 + lineOffset += scanlineStride;
19.1049 + }
19.1050 + }
19.1051 +
19.1052 + /**
19.1053 + * Sets a sample in the specified band for the pixel located at (x,y)
19.1054 + * in the <code>DataBuffer</code> using an int for input.
19.1055 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
19.1056 + * coordinates are not in bounds.
19.1057 + * @param x The X coordinate of the pixel location
19.1058 + * @param y The Y coordinate of the pixel location
19.1059 + * @param b the band to set
19.1060 + * @param s the input sample as an int
19.1061 + * @param data the DataBuffer containing the image data
19.1062 + * @see #getSample(int, int, int, DataBuffer)
19.1063 + */
19.1064 + public void setSample(int x, int y, int b, int s,
19.1065 + DataBuffer data) {
19.1066 + // Bounds check for 'b' will be performed automatically
19.1067 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.1068 + throw new ArrayIndexOutOfBoundsException
19.1069 + ("Coordinate out of bounds!");
19.1070 + }
19.1071 + data.setElem(bankIndices[b],
19.1072 + y*scanlineStride + x*pixelStride + bandOffsets[b], s);
19.1073 + }
19.1074 +
19.1075 + /**
19.1076 + * Sets a sample in the specified band for the pixel located at (x,y)
19.1077 + * in the <code>DataBuffer</code> using a float for input.
19.1078 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.1079 + * the coordinates are not in bounds.
19.1080 + * @param x The X coordinate of the pixel location
19.1081 + * @param y The Y coordinate of the pixel location
19.1082 + * @param b The band to set
19.1083 + * @param s The input sample as a float
19.1084 + * @param data The DataBuffer containing the image data
19.1085 + * @see #getSample(int, int, int, DataBuffer)
19.1086 + */
19.1087 + public void setSample(int x, int y, int b,
19.1088 + float s ,
19.1089 + DataBuffer data) {
19.1090 + // Bounds check for 'b' will be performed automatically
19.1091 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.1092 + throw new ArrayIndexOutOfBoundsException
19.1093 + ("Coordinate out of bounds!");
19.1094 + }
19.1095 + data.setElemFloat(bankIndices[b],
19.1096 + y*scanlineStride + x*pixelStride + bandOffsets[b],
19.1097 + s);
19.1098 + }
19.1099 +
19.1100 + /**
19.1101 + * Sets a sample in the specified band for the pixel located at (x,y)
19.1102 + * in the <code>DataBuffer</code> using a double for input.
19.1103 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if
19.1104 + * the coordinates are not in bounds.
19.1105 + * @param x The X coordinate of the pixel location
19.1106 + * @param y The Y coordinate of the pixel location
19.1107 + * @param b The band to set
19.1108 + * @param s The input sample as a double
19.1109 + * @param data The DataBuffer containing the image data
19.1110 + * @see #getSample(int, int, int, DataBuffer)
19.1111 + */
19.1112 + public void setSample(int x, int y, int b,
19.1113 + double s,
19.1114 + DataBuffer data) {
19.1115 + // Bounds check for 'b' will be performed automatically
19.1116 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
19.1117 + throw new ArrayIndexOutOfBoundsException
19.1118 + ("Coordinate out of bounds!");
19.1119 + }
19.1120 + data.setElemDouble(bankIndices[b],
19.1121 + y*scanlineStride + x*pixelStride + bandOffsets[b],
19.1122 + s);
19.1123 + }
19.1124 +
19.1125 + /**
19.1126 + * Sets the samples in the specified band for the specified rectangle
19.1127 + * of pixels from an int array containing one sample per data array element.
19.1128 + * An <code>ArrayIndexOutOfBoundsException</code> might be thrown if the
19.1129 + * coordinates are not in bounds.
19.1130 + * @param x The X coordinate of the upper left pixel location
19.1131 + * @param y The Y coordinate of the upper left pixel location
19.1132 + * @param w The width of the pixel rectangle
19.1133 + * @param h The height of the pixel rectangle
19.1134 + * @param b The band to set
19.1135 + * @param iArray The input samples in an int array
19.1136 + * @param data The DataBuffer containing the image data
19.1137 + * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
19.1138 + */
19.1139 + public void setSamples(int x, int y, int w, int h, int b,
19.1140 + int iArray[], DataBuffer data) {
19.1141 + // Bounds check for 'b' will be performed automatically
19.1142 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
19.1143 + throw new ArrayIndexOutOfBoundsException
19.1144 + ("Coordinate out of bounds!");
19.1145 + }
19.1146 + int lineOffset = y*scanlineStride + x*pixelStride + bandOffsets[b];
19.1147 + int srcOffset = 0;
19.1148 +
19.1149 + for (int i = 0; i < h; i++) {
19.1150 + int sampleOffset = lineOffset;
19.1151 + for (int j = 0; j < w; j++) {
19.1152 + data.setElem(bankIndices[b], sampleOffset, iArray[srcOffset++]);
19.1153 + sampleOffset += pixelStride;
19.1154 + }
19.1155 + lineOffset += scanlineStride;
19.1156 + }
19.1157 + }
19.1158 +
19.1159 + public boolean equals(Object o) {
19.1160 + if ((o == null) || !(o instanceof ComponentSampleModel)) {
19.1161 + return false;
19.1162 + }
19.1163 +
19.1164 + ComponentSampleModel that = (ComponentSampleModel)o;
19.1165 + return this.width == that.width &&
19.1166 + this.height == that.height &&
19.1167 + this.numBands == that.numBands &&
19.1168 + this.dataType == that.dataType &&
19.1169 + Arrays.equals(this.bandOffsets, that.bandOffsets) &&
19.1170 + Arrays.equals(this.bankIndices, that.bankIndices) &&
19.1171 + this.numBands == that.numBands &&
19.1172 + this.numBanks == that.numBanks &&
19.1173 + this.scanlineStride == that.scanlineStride &&
19.1174 + this.pixelStride == that.pixelStride;
19.1175 + }
19.1176 +
19.1177 + // If we implement equals() we must also implement hashCode
19.1178 + public int hashCode() {
19.1179 + int hash = 0;
19.1180 + hash = width;
19.1181 + hash <<= 8;
19.1182 + hash ^= height;
19.1183 + hash <<= 8;
19.1184 + hash ^= numBands;
19.1185 + hash <<= 8;
19.1186 + hash ^= dataType;
19.1187 + hash <<= 8;
19.1188 + for (int i = 0; i < bandOffsets.length; i++) {
19.1189 + hash ^= bandOffsets[i];
19.1190 + hash <<= 8;
19.1191 + }
19.1192 + for (int i = 0; i < bankIndices.length; i++) {
19.1193 + hash ^= bankIndices[i];
19.1194 + hash <<= 8;
19.1195 + }
19.1196 + hash ^= numBands;
19.1197 + hash <<= 8;
19.1198 + hash ^= numBanks;
19.1199 + hash <<= 8;
19.1200 + hash ^= scanlineStride;
19.1201 + hash <<= 8;
19.1202 + hash ^= pixelStride;
19.1203 + return hash;
19.1204 + }
19.1205 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/src/share/classes/java/awt/image/DataBuffer.java Thu Jun 12 11:46:57 2008 -0700
20.3 @@ -0,0 +1,535 @@
20.4 +/*
20.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
20.7 + *
20.8 + * This code is free software; you can redistribute it and/or modify it
20.9 + * under the terms of the GNU General Public License version 2 only, as
20.10 + * published by the Free Software Foundation. Sun designates this
20.11 + * particular file as subject to the "Classpath" exception as provided
20.12 + * by Sun in the LICENSE file that accompanied this code.
20.13 + *
20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20.17 + * version 2 for more details (a copy is included in the LICENSE file that
20.18 + * accompanied this code).
20.19 + *
20.20 + * You should have received a copy of the GNU General Public License version
20.21 + * 2 along with this work; if not, write to the Free Software Foundation,
20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20.23 + *
20.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
20.26 + * have any questions.
20.27 + */
20.28 +
20.29 +/* ****************************************************************
20.30 + ******************************************************************
20.31 + ******************************************************************
20.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
20.33 + *** As an unpublished work pursuant to Title 17 of the United
20.34 + *** States Code. All rights reserved.
20.35 + ******************************************************************
20.36 + ******************************************************************
20.37 + ******************************************************************/
20.38 +
20.39 +package java.awt.image;
20.40 +
20.41 +import sun.java2d.StateTrackable.State;
20.42 +import static sun.java2d.StateTrackable.State.*;
20.43 +import sun.java2d.StateTrackableDelegate;
20.44 +
20.45 +import sun.awt.image.SunWritableRaster;
20.46 +
20.47 +/**
20.48 + * This class exists to wrap one or more data arrays. Each data array in
20.49 + * the DataBuffer is referred to as a bank. Accessor methods for getting
20.50 + * and setting elements of the DataBuffer's banks exist with and without
20.51 + * a bank specifier. The methods without a bank specifier use the default 0th
20.52 + * bank. The DataBuffer can optionally take an offset per bank, so that
20.53 + * data in an existing array can be used even if the interesting data
20.54 + * doesn't start at array location zero. Getting or setting the 0th
20.55 + * element of a bank, uses the (0+offset)th element of the array. The
20.56 + * size field specifies how much of the data array is available for
20.57 + * use. Size + offset for a given bank should never be greater
20.58 + * than the length of the associated data array. The data type of
20.59 + * a data buffer indicates the type of the data array(s) and may also
20.60 + * indicate additional semantics, e.g. storing unsigned 8-bit data
20.61 + * in elements of a byte array. The data type may be TYPE_UNDEFINED
20.62 + * or one of the types defined below. Other types may be added in
20.63 + * the future. Generally, an object of class DataBuffer will be cast down
20.64 + * to one of its data type specific subclasses to access data type specific
20.65 + * methods for improved performance. Currently, the Java 2D(tm) API
20.66 + * image classes use TYPE_BYTE, TYPE_USHORT, TYPE_INT, TYPE_SHORT,
20.67 + * TYPE_FLOAT, and TYPE_DOUBLE DataBuffers to store image data.
20.68 + * @see java.awt.image.Raster
20.69 + * @see java.awt.image.SampleModel
20.70 + */
20.71 +public abstract class DataBuffer {
20.72 +
20.73 + /** Tag for unsigned byte data. */
20.74 + public static final int TYPE_BYTE = 0;
20.75 +
20.76 + /** Tag for unsigned short data. */
20.77 + public static final int TYPE_USHORT = 1;
20.78 +
20.79 + /** Tag for signed short data. Placeholder for future use. */
20.80 + public static final int TYPE_SHORT = 2;
20.81 +
20.82 + /** Tag for int data. */
20.83 + public static final int TYPE_INT = 3;
20.84 +
20.85 + /** Tag for float data. Placeholder for future use. */
20.86 + public static final int TYPE_FLOAT = 4;
20.87 +
20.88 + /** Tag for double data. Placeholder for future use. */
20.89 + public static final int TYPE_DOUBLE = 5;
20.90 +
20.91 + /** Tag for undefined data. */
20.92 + public static final int TYPE_UNDEFINED = 32;
20.93 +
20.94 + /** The data type of this DataBuffer. */
20.95 + protected int dataType;
20.96 +
20.97 + /** The number of banks in this DataBuffer. */
20.98 + protected int banks;
20.99 +
20.100 + /** Offset into default (first) bank from which to get the first element. */
20.101 + protected int offset;
20.102 +
20.103 + /** Usable size of all banks. */
20.104 + protected int size;
20.105 +
20.106 + /** Offsets into all banks. */
20.107 + protected int offsets[];
20.108 +
20.109 + /* The current StateTrackable state. */
20.110 + StateTrackableDelegate theTrackable;
20.111 +
20.112 + /** Size of the data types indexed by DataType tags defined above. */
20.113 + private static final int dataTypeSize[] = {8,16,16,32,32,64};
20.114 +
20.115 + /** Returns the size (in bits) of the data type, given a datatype tag.
20.116 + * @param type the value of one of the defined datatype tags
20.117 + * @return the size of the data type
20.118 + * @throws IllegalArgumentException if <code>type</code> is less than
20.119 + * zero or greater than {@link #TYPE_DOUBLE}
20.120 + */
20.121 + public static int getDataTypeSize(int type) {
20.122 + if (type < TYPE_BYTE || type > TYPE_DOUBLE) {
20.123 + throw new IllegalArgumentException("Unknown data type "+type);
20.124 + }
20.125 + return dataTypeSize[type];
20.126 + }
20.127 +
20.128 + /**
20.129 + * Constructs a DataBuffer containing one bank of the specified
20.130 + * data type and size.
20.131 + *
20.132 + * @param dataType the data type of this <code>DataBuffer</code>
20.133 + * @param size the size of the banks
20.134 + */
20.135 + protected DataBuffer(int dataType, int size) {
20.136 + this(UNTRACKABLE, dataType, size);
20.137 + }
20.138 +
20.139 + /**
20.140 + * Constructs a DataBuffer containing one bank of the specified
20.141 + * data type and size with the indicated initial {@link State State}.
20.142 + *
20.143 + * @param initialState the initial {@link State State} state of the data
20.144 + * @param dataType the data type of this <code>DataBuffer</code>
20.145 + * @param size the size of the banks
20.146 + * @since 1.7
20.147 + */
20.148 + DataBuffer(State initialState,
20.149 + int dataType, int size)
20.150 + {
20.151 + this.theTrackable = StateTrackableDelegate.createInstance(initialState);
20.152 + this.dataType = dataType;
20.153 + this.banks = 1;
20.154 + this.size = size;
20.155 + this.offset = 0;
20.156 + this.offsets = new int[1]; // init to 0 by new
20.157 + }
20.158 +
20.159 + /**
20.160 + * Constructs a DataBuffer containing the specified number of
20.161 + * banks. Each bank has the specified size and an offset of 0.
20.162 + *
20.163 + * @param dataType the data type of this <code>DataBuffer</code>
20.164 + * @param size the size of the banks
20.165 + * @param numBanks the number of banks in this
20.166 + * <code>DataBuffer</code>
20.167 + */
20.168 + protected DataBuffer(int dataType, int size, int numBanks) {
20.169 + this(UNTRACKABLE, dataType, size, numBanks);
20.170 + }
20.171 +
20.172 + /**
20.173 + * Constructs a DataBuffer containing the specified number of
20.174 + * banks with the indicated initial {@link State State}.
20.175 + * Each bank has the specified size and an offset of 0.
20.176 + *
20.177 + * @param initialState the initial {@link State State} state of the data
20.178 + * @param dataType the data type of this <code>DataBuffer</code>
20.179 + * @param size the size of the banks
20.180 + * @param numBanks the number of banks in this
20.181 + * <code>DataBuffer</code>
20.182 + * @since 1.7
20.183 + */
20.184 + DataBuffer(State initialState,
20.185 + int dataType, int size, int numBanks)
20.186 + {
20.187 + this.theTrackable = StateTrackableDelegate.createInstance(initialState);
20.188 + this.dataType = dataType;
20.189 + this.banks = numBanks;
20.190 + this.size = size;
20.191 + this.offset = 0;
20.192 + this.offsets = new int[banks]; // init to 0 by new
20.193 + }
20.194 +
20.195 + /**
20.196 + * Constructs a DataBuffer that contains the specified number
20.197 + * of banks. Each bank has the specified datatype, size and offset.
20.198 + *
20.199 + * @param dataType the data type of this <code>DataBuffer</code>
20.200 + * @param size the size of the banks
20.201 + * @param numBanks the number of banks in this
20.202 + * <code>DataBuffer</code>
20.203 + * @param offset the offset for each bank
20.204 + */
20.205 + protected DataBuffer(int dataType, int size, int numBanks, int offset) {
20.206 + this(UNTRACKABLE, dataType, size, numBanks, offset);
20.207 + }
20.208 +
20.209 + /**
20.210 + * Constructs a DataBuffer that contains the specified number
20.211 + * of banks with the indicated initial {@link State State}.
20.212 + * Each bank has the specified datatype, size and offset.
20.213 + *
20.214 + * @param initialState the initial {@link State State} state of the data
20.215 + * @param dataType the data type of this <code>DataBuffer</code>
20.216 + * @param size the size of the banks
20.217 + * @param numBanks the number of banks in this
20.218 + * <code>DataBuffer</code>
20.219 + * @param offset the offset for each bank
20.220 + * @since 1.7
20.221 + */
20.222 + DataBuffer(State initialState,
20.223 + int dataType, int size, int numBanks, int offset)
20.224 + {
20.225 + this.theTrackable = StateTrackableDelegate.createInstance(initialState);
20.226 + this.dataType = dataType;
20.227 + this.banks = numBanks;
20.228 + this.size = size;
20.229 + this.offset = offset;
20.230 + this.offsets = new int[numBanks];
20.231 + for (int i = 0; i < numBanks; i++) {
20.232 + this.offsets[i] = offset;
20.233 + }
20.234 + }
20.235 +
20.236 + /**
20.237 + * Constructs a DataBuffer which contains the specified number
20.238 + * of banks. Each bank has the specified datatype and size. The
20.239 + * offset for each bank is specified by its respective entry in
20.240 + * the offsets array.
20.241 + *
20.242 + * @param dataType the data type of this <code>DataBuffer</code>
20.243 + * @param size the size of the banks
20.244 + * @param numBanks the number of banks in this
20.245 + * <code>DataBuffer</code>
20.246 + * @param offsets an array containing an offset for each bank.
20.247 + * @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
20.248 + * does not equal the length of <code>offsets</code>
20.249 + */
20.250 + protected DataBuffer(int dataType, int size, int numBanks, int offsets[]) {
20.251 + this(UNTRACKABLE, dataType, size, numBanks, offsets);
20.252 + }
20.253 +
20.254 + /**
20.255 + * Constructs a DataBuffer which contains the specified number
20.256 + * of banks with the indicated initial {@link State State}.
20.257 + * Each bank has the specified datatype and size. The
20.258 + * offset for each bank is specified by its respective entry in
20.259 + * the offsets array.
20.260 + *
20.261 + * @param initialState the initial {@link State State} state of the data
20.262 + * @param dataType the data type of this <code>DataBuffer</code>
20.263 + * @param size the size of the banks
20.264 + * @param numBanks the number of banks in this
20.265 + * <code>DataBuffer</code>
20.266 + * @param offsets an array containing an offset for each bank.
20.267 + * @throws ArrayIndexOutOfBoundsException if <code>numBanks</code>
20.268 + * does not equal the length of <code>offsets</code>
20.269 + * @since 1.7
20.270 + */
20.271 + DataBuffer(State initialState,
20.272 + int dataType, int size, int numBanks, int offsets[])
20.273 + {
20.274 + if (numBanks != offsets.length) {
20.275 + throw new ArrayIndexOutOfBoundsException("Number of banks" +
20.276 + " does not match number of bank offsets");
20.277 + }
20.278 + this.theTrackable = StateTrackableDelegate.createInstance(initialState);
20.279 + this.dataType = dataType;
20.280 + this.banks = numBanks;
20.281 + this.size = size;
20.282 + this.offset = offsets[0];
20.283 + this.offsets = (int[])offsets.clone();
20.284 + }
20.285 +
20.286 + /** Returns the data type of this DataBuffer.
20.287 + * @return the data type of this <code>DataBuffer</code>.
20.288 + */
20.289 + public int getDataType() {
20.290 + return dataType;
20.291 + }
20.292 +
20.293 + /** Returns the size (in array elements) of all banks.
20.294 + * @return the size of all banks.
20.295 + */
20.296 + public int getSize() {
20.297 + return size;
20.298 + }
20.299 +
20.300 + /** Returns the offset of the default bank in array elements.
20.301 + * @return the offset of the default bank.
20.302 + */
20.303 + public int getOffset() {
20.304 + return offset;
20.305 + }
20.306 +
20.307 + /** Returns the offsets (in array elements) of all the banks.
20.308 + * @return the offsets of all banks.
20.309 + */
20.310 + public int[] getOffsets() {
20.311 + return (int[])offsets.clone();
20.312 + }
20.313 +
20.314 + /** Returns the number of banks in this DataBuffer.
20.315 + * @return the number of banks.
20.316 + */
20.317 + public int getNumBanks() {
20.318 + return banks;
20.319 + }
20.320 +
20.321 + /**
20.322 + * Returns the requested data array element from the first (default) bank
20.323 + * as an integer.
20.324 + * @param i the index of the requested data array element
20.325 + * @return the data array element at the specified index.
20.326 + * @see #setElem(int, int)
20.327 + * @see #setElem(int, int, int)
20.328 + */
20.329 + public int getElem(int i) {
20.330 + return getElem(0,i);
20.331 + }
20.332 +
20.333 + /**
20.334 + * Returns the requested data array element from the specified bank
20.335 + * as an integer.
20.336 + * @param bank the specified bank
20.337 + * @param i the index of the requested data array element
20.338 + * @return the data array element at the specified index from the
20.339 + * specified bank at the specified index.
20.340 + * @see #setElem(int, int)
20.341 + * @see #setElem(int, int, int)
20.342 + */
20.343 + public abstract int getElem(int bank, int i);
20.344 +
20.345 + /**
20.346 + * Sets the requested data array element in the first (default) bank
20.347 + * from the given integer.
20.348 + * @param i the specified index into the data array
20.349 + * @param val the data to set the element at the specified index in
20.350 + * the data array
20.351 + * @see #getElem(int)
20.352 + * @see #getElem(int, int)
20.353 + */
20.354 + public void setElem(int i, int val) {
20.355 + setElem(0,i,val);
20.356 + }
20.357 +
20.358 + /**
20.359 + * Sets the requested data array element in the specified bank
20.360 + * from the given integer.
20.361 + * @param bank the specified bank
20.362 + * @param i the specified index into the data array
20.363 + * @param val the data to set the element in the specified bank
20.364 + * at the specified index in the data array
20.365 + * @see #getElem(int)
20.366 + * @see #getElem(int, int)
20.367 + */
20.368 + public abstract void setElem(int bank, int i, int val);
20.369 +
20.370 + /**
20.371 + * Returns the requested data array element from the first (default) bank
20.372 + * as a float. The implementation in this class is to cast getElem(i)
20.373 + * to a float. Subclasses may override this method if another
20.374 + * implementation is needed.
20.375 + * @param i the index of the requested data array element
20.376 + * @return a float value representing the data array element at the
20.377 + * specified index.
20.378 + * @see #setElemFloat(int, float)
20.379 + * @see #setElemFloat(int, int, float)
20.380 + */
20.381 + public float getElemFloat(int i) {
20.382 + return (float)getElem(i);
20.383 + }
20.384 +
20.385 + /**
20.386 + * Returns the requested data array element from the specified bank
20.387 + * as a float. The implementation in this class is to cast
20.388 + * {@link #getElem(int, int)}
20.389 + * to a float. Subclasses can override this method if another
20.390 + * implementation is needed.
20.391 + * @param bank the specified bank
20.392 + * @param i the index of the requested data array element
20.393 + * @return a float value representing the data array element from the
20.394 + * specified bank at the specified index.
20.395 + * @see #setElemFloat(int, float)
20.396 + * @see #setElemFloat(int, int, float)
20.397 + */
20.398 + public float getElemFloat(int bank, int i) {
20.399 + return (float)getElem(bank,i);
20.400 + }
20.401 +
20.402 + /**
20.403 + * Sets the requested data array element in the first (default) bank
20.404 + * from the given float. The implementation in this class is to cast
20.405 + * val to an int and call {@link #setElem(int, int)}. Subclasses
20.406 + * can override this method if another implementation is needed.
20.407 + * @param i the specified index
20.408 + * @param val the value to set the element at the specified index in
20.409 + * the data array
20.410 + * @see #getElemFloat(int)
20.411 + * @see #getElemFloat(int, int)
20.412 + */
20.413 + public void setElemFloat(int i, float val) {
20.414 + setElem(i,(int)val);
20.415 + }
20.416 +
20.417 + /**
20.418 + * Sets the requested data array element in the specified bank
20.419 + * from the given float. The implementation in this class is to cast
20.420 + * val to an int and call {@link #setElem(int, int)}. Subclasses can
20.421 + * override this method if another implementation is needed.
20.422 + * @param bank the specified bank
20.423 + * @param i the specified index
20.424 + * @param val the value to set the element in the specified bank at
20.425 + * the specified index in the data array
20.426 + * @see #getElemFloat(int)
20.427 + * @see #getElemFloat(int, int)
20.428 + */
20.429 + public void setElemFloat(int bank, int i, float val) {
20.430 + setElem(bank,i,(int)val);
20.431 + }
20.432 +
20.433 + /**
20.434 + * Returns the requested data array element from the first (default) bank
20.435 + * as a double. The implementation in this class is to cast
20.436 + * {@link #getElem(int)}
20.437 + * to a double. Subclasses can override this method if another
20.438 + * implementation is needed.
20.439 + * @param i the specified index
20.440 + * @return a double value representing the element at the specified
20.441 + * index in the data array.
20.442 + * @see #setElemDouble(int, double)
20.443 + * @see #setElemDouble(int, int, double)
20.444 + */
20.445 + public double getElemDouble(int i) {
20.446 + return (double)getElem(i);
20.447 + }
20.448 +
20.449 + /**
20.450 + * Returns the requested data array element from the specified bank as
20.451 + * a double. The implementation in this class is to cast getElem(bank, i)
20.452 + * to a double. Subclasses may override this method if another
20.453 + * implementation is needed.
20.454 + * @param bank the specified bank
20.455 + * @param i the specified index
20.456 + * @return a double value representing the element from the specified
20.457 + * bank at the specified index in the data array.
20.458 + * @see #setElemDouble(int, double)
20.459 + * @see #setElemDouble(int, int, double)
20.460 + */
20.461 + public double getElemDouble(int bank, int i) {
20.462 + return (double)getElem(bank,i);
20.463 + }
20.464 +
20.465 + /**
20.466 + * Sets the requested data array element in the first (default) bank
20.467 + * from the given double. The implementation in this class is to cast
20.468 + * val to an int and call {@link #setElem(int, int)}. Subclasses can
20.469 + * override this method if another implementation is needed.
20.470 + * @param i the specified index
20.471 + * @param val the value to set the element at the specified index
20.472 + * in the data array
20.473 + * @see #getElemDouble(int)
20.474 + * @see #getElemDouble(int, int)
20.475 + */
20.476 + public void setElemDouble(int i, double val) {
20.477 + setElem(i,(int)val);
20.478 + }
20.479 +
20.480 + /**
20.481 + * Sets the requested data array element in the specified bank
20.482 + * from the given double. The implementation in this class is to cast
20.483 + * val to an int and call {@link #setElem(int, int)}. Subclasses can
20.484 + * override this method if another implementation is needed.
20.485 + * @param bank the specified bank
20.486 + * @param i the specified index
20.487 + * @param val the value to set the element in the specified bank
20.488 + * at the specified index of the data array
20.489 + * @see #getElemDouble(int)
20.490 + * @see #getElemDouble(int, int)
20.491 + */
20.492 + public void setElemDouble(int bank, int i, double val) {
20.493 + setElem(bank,i,(int)val);
20.494 + }
20.495 +
20.496 + static int[] toIntArray(Object obj) {
20.497 + if (obj instanceof int[]) {
20.498 + return (int[])obj;
20.499 + } else if (obj == null) {
20.500 + return null;
20.501 + } else if (obj instanceof short[]) {
20.502 + short sdata[] = (short[])obj;
20.503 + int idata[] = new int[sdata.length];
20.504 + for (int i = 0; i < sdata.length; i++) {
20.505 + idata[i] = (int)sdata[i] & 0xffff;
20.506 + }
20.507 + return idata;
20.508 + } else if (obj instanceof byte[]) {
20.509 + byte bdata[] = (byte[])obj;
20.510 + int idata[] = new int[bdata.length];
20.511 + for (int i = 0; i < bdata.length; i++) {
20.512 + idata[i] = 0xff & (int)bdata[i];
20.513 + }
20.514 + return idata;
20.515 + }
20.516 + return null;
20.517 + }
20.518 +
20.519 + static {
20.520 + SunWritableRaster.setDataStealer(new SunWritableRaster.DataStealer() {
20.521 + public byte[] getData(DataBufferByte dbb, int bank) {
20.522 + return dbb.bankdata[bank];
20.523 + }
20.524 +
20.525 + public short[] getData(DataBufferUShort dbus, int bank) {
20.526 + return dbus.bankdata[bank];
20.527 + }
20.528 +
20.529 + public int[] getData(DataBufferInt dbi, int bank) {
20.530 + return dbi.bankdata[bank];
20.531 + }
20.532 +
20.533 + public StateTrackableDelegate getTrackable(DataBuffer db) {
20.534 + return db.theTrackable;
20.535 + }
20.536 + });
20.537 + }
20.538 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/src/share/classes/java/awt/image/DataBufferByte.java Thu Jun 12 11:46:57 2008 -0700
21.3 @@ -0,0 +1,286 @@
21.4 +/*
21.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
21.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
21.7 + *
21.8 + * This code is free software; you can redistribute it and/or modify it
21.9 + * under the terms of the GNU General Public License version 2 only, as
21.10 + * published by the Free Software Foundation. Sun designates this
21.11 + * particular file as subject to the "Classpath" exception as provided
21.12 + * by Sun in the LICENSE file that accompanied this code.
21.13 + *
21.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
21.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21.17 + * version 2 for more details (a copy is included in the LICENSE file that
21.18 + * accompanied this code).
21.19 + *
21.20 + * You should have received a copy of the GNU General Public License version
21.21 + * 2 along with this work; if not, write to the Free Software Foundation,
21.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21.23 + *
21.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
21.26 + * have any questions.
21.27 + */
21.28 +
21.29 +/* ****************************************************************
21.30 + ******************************************************************
21.31 + ******************************************************************
21.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
21.33 + *** As an unpublished work pursuant to Title 17 of the United
21.34 + *** States Code. All rights reserved.
21.35 + ******************************************************************
21.36 + ******************************************************************
21.37 + ******************************************************************/
21.38 +
21.39 +package java.awt.image;
21.40 +
21.41 +import static sun.java2d.StateTrackable.State.*;
21.42 +
21.43 +/**
21.44 + * This class extends <CODE>DataBuffer</CODE> and stores data internally as bytes.
21.45 + * Values stored in the byte array(s) of this <CODE>DataBuffer</CODE> are treated as
21.46 + * unsigned values.
21.47 + * <p>
21.48 + * <a name="optimizations">
21.49 + * Note that some implementations may function more efficiently
21.50 + * if they can maintain control over how the data for an image is
21.51 + * stored.
21.52 + * For example, optimizations such as caching an image in video
21.53 + * memory require that the implementation track all modifications
21.54 + * to that data.
21.55 + * Other implementations may operate better if they can store the
21.56 + * data in locations other than a Java array.
21.57 + * To maintain optimum compatibility with various optimizations
21.58 + * it is best to avoid constructors and methods which expose the
21.59 + * underlying storage as a Java array, as noted below in the
21.60 + * documentation for those methods.
21.61 + * </a>
21.62 + */
21.63 +public final class DataBufferByte extends DataBuffer
21.64 +{
21.65 + /** The default data bank. */
21.66 + byte data[];
21.67 +
21.68 + /** All data banks */
21.69 + byte bankdata[][];
21.70 +
21.71 + /**
21.72 + * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank and the
21.73 + * specified size.
21.74 + *
21.75 + * @param size The size of the <CODE>DataBuffer</CODE>.
21.76 + */
21.77 + public DataBufferByte(int size) {
21.78 + super(STABLE, TYPE_BYTE, size);
21.79 + data = new byte[size];
21.80 + bankdata = new byte[1][];
21.81 + bankdata[0] = data;
21.82 + }
21.83 +
21.84 + /**
21.85 + * Constructs a byte based <CODE>DataBuffer</CODE> with the specified number of
21.86 + * banks all of which are the specified size.
21.87 + *
21.88 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
21.89 + * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
21.90 + */
21.91 + public DataBufferByte(int size, int numBanks) {
21.92 + super(STABLE, TYPE_BYTE, size, numBanks);
21.93 + bankdata = new byte[numBanks][];
21.94 + for (int i= 0; i < numBanks; i++) {
21.95 + bankdata[i] = new byte[size];
21.96 + }
21.97 + data = bankdata[0];
21.98 + }
21.99 +
21.100 + /**
21.101 + * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
21.102 + * specified array.
21.103 + * Only the first <CODE>size</CODE> elements should be used by accessors of
21.104 + * this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
21.105 + * hold <CODE>size</CODE> elements.
21.106 + * <p>
21.107 + * Note that {@code DataBuffer} objects created by this constructor
21.108 + * may be incompatible with <a href="#optimizations">performance
21.109 + * optimizations</a> used by some implementations (such as caching
21.110 + * an associated image in video memory).
21.111 + *
21.112 + * @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
21.113 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
21.114 + */
21.115 + public DataBufferByte(byte dataArray[], int size) {
21.116 + super(UNTRACKABLE, TYPE_BYTE, size);
21.117 + data = dataArray;
21.118 + bankdata = new byte[1][];
21.119 + bankdata[0] = data;
21.120 + }
21.121 +
21.122 + /**
21.123 + * Constructs a byte-based <CODE>DataBuffer</CODE> with a single bank using the
21.124 + * specified array, size, and offset. <CODE>dataArray</CODE> must have at least
21.125 + * <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
21.126 + * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
21.127 + * should be used by accessors of this <CODE>DataBuffer</CODE>.
21.128 + * <p>
21.129 + * Note that {@code DataBuffer} objects created by this constructor
21.130 + * may be incompatible with <a href="#optimizations">performance
21.131 + * optimizations</a> used by some implementations (such as caching
21.132 + * an associated image in video memory).
21.133 + *
21.134 + * @param dataArray The byte array for the <CODE>DataBuffer</CODE>.
21.135 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
21.136 + * @param offset The offset into the <CODE>dataArray</CODE>. <CODE>dataArray</CODE>
21.137 + * must have at least <CODE>offset</CODE> + <CODE>size</CODE> elements.
21.138 + */
21.139 + public DataBufferByte(byte dataArray[], int size, int offset){
21.140 + super(UNTRACKABLE, TYPE_BYTE, size, 1, offset);
21.141 + data = dataArray;
21.142 + bankdata = new byte[1][];
21.143 + bankdata[0] = data;
21.144 + }
21.145 +
21.146 + /**
21.147 + * Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays.
21.148 + * The number of banks is equal to <CODE>dataArray.length</CODE>.
21.149 + * Only the first <CODE>size</CODE> elements of each array should be used by
21.150 + * accessors of this <CODE>DataBuffer</CODE>.
21.151 + * <p>
21.152 + * Note that {@code DataBuffer} objects created by this constructor
21.153 + * may be incompatible with <a href="#optimizations">performance
21.154 + * optimizations</a> used by some implementations (such as caching
21.155 + * an associated image in video memory).
21.156 + *
21.157 + * @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
21.158 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
21.159 + */
21.160 + public DataBufferByte(byte dataArray[][], int size) {
21.161 + super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length);
21.162 + bankdata = (byte[][]) dataArray.clone();
21.163 + data = bankdata[0];
21.164 + }
21.165 +
21.166 + /**
21.167 + * Constructs a byte-based <CODE>DataBuffer</CODE> with the specified arrays, size,
21.168 + * and offsets.
21.169 + * The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
21.170 + * be at least as large as <CODE>size</CODE> + the corresponding <CODE>offset</CODE>.
21.171 + * There must be an entry in the <CODE>offset</CODE> array for each <CODE>dataArray</CODE>
21.172 + * entry. For each bank, only elements <CODE>offset</CODE> through
21.173 + * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be used by accessors of this
21.174 + * <CODE>DataBuffer</CODE>.
21.175 + * <p>
21.176 + * Note that {@code DataBuffer} objects created by this constructor
21.177 + * may be incompatible with <a href="#optimizations">performance
21.178 + * optimizations</a> used by some implementations (such as caching
21.179 + * an associated image in video memory).
21.180 + *
21.181 + * @param dataArray The byte arrays for the <CODE>DataBuffer</CODE>.
21.182 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
21.183 + * @param offsets The offsets into each array.
21.184 + */
21.185 + public DataBufferByte(byte dataArray[][], int size, int offsets[]) {
21.186 + super(UNTRACKABLE, TYPE_BYTE, size, dataArray.length, offsets);
21.187 + bankdata = (byte[][]) dataArray.clone();
21.188 + data = bankdata[0];
21.189 + }
21.190 +
21.191 + /**
21.192 + * Returns the default (first) byte data array.
21.193 + * <p>
21.194 + * Note that calling this method may cause this {@code DataBuffer}
21.195 + * object to be incompatible with <a href="#optimizations">performance
21.196 + * optimizations</a> used by some implementations (such as caching
21.197 + * an associated image in video memory).
21.198 + *
21.199 + * @return The first byte data array.
21.200 + */
21.201 + public byte[] getData() {
21.202 + theTrackable.setUntrackable();
21.203 + return data;
21.204 + }
21.205 +
21.206 + /**
21.207 + * Returns the data array for the specified bank.
21.208 + * <p>
21.209 + * Note that calling this method may cause this {@code DataBuffer}
21.210 + * object to be incompatible with <a href="#optimizations">performance
21.211 + * optimizations</a> used by some implementations (such as caching
21.212 + * an associated image in video memory).
21.213 + *
21.214 + * @param bank The bank whose data array you want to get.
21.215 + * @return The data array for the specified bank.
21.216 + */
21.217 + public byte[] getData(int bank) {
21.218 + theTrackable.setUntrackable();
21.219 + return bankdata[bank];
21.220 + }
21.221 +
21.222 + /**
21.223 + * Returns the data arrays for all banks.
21.224 + * <p>
21.225 + * Note that calling this method may cause this {@code DataBuffer}
21.226 + * object to be incompatible with <a href="#optimizations">performance
21.227 + * optimizations</a> used by some implementations (such as caching
21.228 + * an associated image in video memory).
21.229 + *
21.230 + * @return All of the data arrays.
21.231 + */
21.232 + public byte[][] getBankData() {
21.233 + theTrackable.setUntrackable();
21.234 + return (byte[][]) bankdata.clone();
21.235 + }
21.236 +
21.237 + /**
21.238 + * Returns the requested data array element from the first (default) bank.
21.239 + *
21.240 + * @param i The data array element you want to get.
21.241 + * @return The requested data array element as an integer.
21.242 + * @see #setElem(int, int)
21.243 + * @see #setElem(int, int, int)
21.244 + */
21.245 + public int getElem(int i) {
21.246 + return (int)(data[i+offset]) & 0xff;
21.247 + }
21.248 +
21.249 + /**
21.250 + * Returns the requested data array element from the specified bank.
21.251 + *
21.252 + * @param bank The bank from which you want to get a data array element.
21.253 + * @param i The data array element you want to get.
21.254 + * @return The requested data array element as an integer.
21.255 + * @see #setElem(int, int)
21.256 + * @see #setElem(int, int, int)
21.257 + */
21.258 + public int getElem(int bank, int i) {
21.259 + return (int)(bankdata[bank][i+offsets[bank]]) & 0xff;
21.260 + }
21.261 +
21.262 + /**
21.263 + * Sets the requested data array element in the first (default) bank
21.264 + * to the specified value.
21.265 + *
21.266 + * @param i The data array element you want to set.
21.267 + * @param val The integer value to which you want to set the data array element.
21.268 + * @see #getElem(int)
21.269 + * @see #getElem(int, int)
21.270 + */
21.271 + public void setElem(int i, int val) {
21.272 + data[i+offset] = (byte)val;
21.273 + theTrackable.markDirty();
21.274 + }
21.275 +
21.276 + /**
21.277 + * Sets the requested data array element in the specified bank
21.278 + * from the given integer.
21.279 + * @param bank The bank in which you want to set the data array element.
21.280 + * @param i The data array element you want to set.
21.281 + * @param val The integer value to which you want to set the specified data array element.
21.282 + * @see #getElem(int)
21.283 + * @see #getElem(int, int)
21.284 + */
21.285 + public void setElem(int bank, int i, int val) {
21.286 + bankdata[bank][i+offsets[bank]] = (byte)val;
21.287 + theTrackable.markDirty();
21.288 + }
21.289 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/src/share/classes/java/awt/image/DataBufferInt.java Thu Jun 12 11:46:57 2008 -0700
22.3 @@ -0,0 +1,284 @@
22.4 +/*
22.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
22.7 + *
22.8 + * This code is free software; you can redistribute it and/or modify it
22.9 + * under the terms of the GNU General Public License version 2 only, as
22.10 + * published by the Free Software Foundation. Sun designates this
22.11 + * particular file as subject to the "Classpath" exception as provided
22.12 + * by Sun in the LICENSE file that accompanied this code.
22.13 + *
22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22.17 + * version 2 for more details (a copy is included in the LICENSE file that
22.18 + * accompanied this code).
22.19 + *
22.20 + * You should have received a copy of the GNU General Public License version
22.21 + * 2 along with this work; if not, write to the Free Software Foundation,
22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22.23 + *
22.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
22.26 + * have any questions.
22.27 + */
22.28 +
22.29 +/* ****************************************************************
22.30 + ******************************************************************
22.31 + ******************************************************************
22.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
22.33 + *** As an unpublished work pursuant to Title 17 of the United
22.34 + *** States Code. All rights reserved.
22.35 + ******************************************************************
22.36 + ******************************************************************
22.37 + ******************************************************************/
22.38 +
22.39 +package java.awt.image;
22.40 +
22.41 +import static sun.java2d.StateTrackable.State.*;
22.42 +
22.43 +/**
22.44 + * This class extends <CODE>DataBuffer</CODE> and stores data internally
22.45 + * as integers.
22.46 + * <p>
22.47 + * <a name="optimizations">
22.48 + * Note that some implementations may function more efficiently
22.49 + * if they can maintain control over how the data for an image is
22.50 + * stored.
22.51 + * For example, optimizations such as caching an image in video
22.52 + * memory require that the implementation track all modifications
22.53 + * to that data.
22.54 + * Other implementations may operate better if they can store the
22.55 + * data in locations other than a Java array.
22.56 + * To maintain optimum compatibility with various optimizations
22.57 + * it is best to avoid constructors and methods which expose the
22.58 + * underlying storage as a Java array as noted below in the
22.59 + * documentation for those methods.
22.60 + * </a>
22.61 + */
22.62 +public final class DataBufferInt extends DataBuffer
22.63 +{
22.64 + /** The default data bank. */
22.65 + int data[];
22.66 +
22.67 + /** All data banks */
22.68 + int bankdata[][];
22.69 +
22.70 + /**
22.71 + * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank
22.72 + * and the specified size.
22.73 + *
22.74 + * @param size The size of the <CODE>DataBuffer</CODE>.
22.75 + */
22.76 + public DataBufferInt(int size) {
22.77 + super(STABLE, TYPE_INT, size);
22.78 + data = new int[size];
22.79 + bankdata = new int[1][];
22.80 + bankdata[0] = data;
22.81 + }
22.82 +
22.83 + /**
22.84 + * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified number of
22.85 + * banks, all of which are the specified size.
22.86 + *
22.87 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
22.88 + * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
22.89 + */
22.90 + public DataBufferInt(int size, int numBanks) {
22.91 + super(STABLE, TYPE_INT, size, numBanks);
22.92 + bankdata = new int[numBanks][];
22.93 + for (int i= 0; i < numBanks; i++) {
22.94 + bankdata[i] = new int[size];
22.95 + }
22.96 + data = bankdata[0];
22.97 + }
22.98 +
22.99 + /**
22.100 + * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
22.101 + * specified array.
22.102 + * Only the first <CODE>size</CODE> elements should be used by accessors of
22.103 + * this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
22.104 + * hold <CODE>size</CODE> elements.
22.105 + * <p>
22.106 + * Note that {@code DataBuffer} objects created by this constructor
22.107 + * may be incompatible with <a href="#optimizations">performance
22.108 + * optimizations</a> used by some implementations (such as caching
22.109 + * an associated image in video memory).
22.110 + *
22.111 + * @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
22.112 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
22.113 + */
22.114 + public DataBufferInt(int dataArray[], int size) {
22.115 + super(UNTRACKABLE, TYPE_INT, size);
22.116 + data = dataArray;
22.117 + bankdata = new int[1][];
22.118 + bankdata[0] = data;
22.119 + }
22.120 +
22.121 + /**
22.122 + * Constructs an integer-based <CODE>DataBuffer</CODE> with a single bank using the
22.123 + * specified array, size, and offset. <CODE>dataArray</CODE> must have at least
22.124 + * <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
22.125 + * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
22.126 + * should be used by accessors of this <CODE>DataBuffer</CODE>.
22.127 + * <p>
22.128 + * Note that {@code DataBuffer} objects created by this constructor
22.129 + * may be incompatible with <a href="#optimizations">performance
22.130 + * optimizations</a> used by some implementations (such as caching
22.131 + * an associated image in video memory).
22.132 + *
22.133 + * @param dataArray The integer array for the <CODE>DataBuffer</CODE>.
22.134 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
22.135 + * @param offset The offset into the <CODE>dataArray</CODE>.
22.136 + */
22.137 + public DataBufferInt(int dataArray[], int size, int offset) {
22.138 + super(UNTRACKABLE, TYPE_INT, size, 1, offset);
22.139 + data = dataArray;
22.140 + bankdata = new int[1][];
22.141 + bankdata[0] = data;
22.142 + }
22.143 +
22.144 + /**
22.145 + * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays.
22.146 + * The number of banks will be equal to <CODE>dataArray.length</CODE>.
22.147 + * Only the first <CODE>size</CODE> elements of each array should be used by
22.148 + * accessors of this <CODE>DataBuffer</CODE>.
22.149 + * <p>
22.150 + * Note that {@code DataBuffer} objects created by this constructor
22.151 + * may be incompatible with <a href="#optimizations">performance
22.152 + * optimizations</a> used by some implementations (such as caching
22.153 + * an associated image in video memory).
22.154 + *
22.155 + * @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
22.156 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
22.157 + */
22.158 + public DataBufferInt(int dataArray[][], int size) {
22.159 + super(UNTRACKABLE, TYPE_INT, size, dataArray.length);
22.160 + bankdata = (int [][]) dataArray.clone();
22.161 + data = bankdata[0];
22.162 + }
22.163 +
22.164 + /**
22.165 + * Constructs an integer-based <CODE>DataBuffer</CODE> with the specified arrays, size,
22.166 + * and offsets.
22.167 + * The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
22.168 + * be at least as large as <CODE>size</CODE> + the corresponding offset. There must
22.169 + * be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
22.170 + * bank, only elements <CODE>offset</CODE> through
22.171 + * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
22.172 + * used by accessors of this <CODE>DataBuffer</CODE>.
22.173 + * <p>
22.174 + * Note that {@code DataBuffer} objects created by this constructor
22.175 + * may be incompatible with <a href="#optimizations">performance
22.176 + * optimizations</a> used by some implementations (such as caching
22.177 + * an associated image in video memory).
22.178 + *
22.179 + * @param dataArray The integer arrays for the <CODE>DataBuffer</CODE>.
22.180 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
22.181 + * @param offsets The offsets into each array.
22.182 + */
22.183 + public DataBufferInt(int dataArray[][], int size, int offsets[]) {
22.184 + super(UNTRACKABLE, TYPE_INT, size, dataArray.length, offsets);
22.185 + bankdata = (int [][]) dataArray.clone();
22.186 + data = bankdata[0];
22.187 + }
22.188 +
22.189 + /**
22.190 + * Returns the default (first) int data array in <CODE>DataBuffer</CODE>.
22.191 + * <p>
22.192 + * Note that calling this method may cause this {@code DataBuffer}
22.193 + * object to be incompatible with <a href="#optimizations">performance
22.194 + * optimizations</a> used by some implementations (such as caching
22.195 + * an associated image in video memory).
22.196 + *
22.197 + * @return The first integer data array.
22.198 + */
22.199 + public int[] getData() {
22.200 + theTrackable.setUntrackable();
22.201 + return data;
22.202 + }
22.203 +
22.204 + /**
22.205 + * Returns the data array for the specified bank.
22.206 + * <p>
22.207 + * Note that calling this method may cause this {@code DataBuffer}
22.208 + * object to be incompatible with <a href="#optimizations">performance
22.209 + * optimizations</a> used by some implementations (such as caching
22.210 + * an associated image in video memory).
22.211 + *
22.212 + * @param bank The bank whose data array you want to get.
22.213 + * @return The data array for the specified bank.
22.214 + */
22.215 + public int[] getData(int bank) {
22.216 + theTrackable.setUntrackable();
22.217 + return bankdata[bank];
22.218 + }
22.219 +
22.220 + /**
22.221 + * Returns the data arrays for all banks.
22.222 + * <p>
22.223 + * Note that calling this method may cause this {@code DataBuffer}
22.224 + * object to be incompatible with <a href="#optimizations">performance
22.225 + * optimizations</a> used by some implementations (such as caching
22.226 + * an associated image in video memory).
22.227 + *
22.228 + * @return All of the data arrays.
22.229 + */
22.230 + public int[][] getBankData() {
22.231 + theTrackable.setUntrackable();
22.232 + return (int [][]) bankdata.clone();
22.233 + }
22.234 +
22.235 + /**
22.236 + * Returns the requested data array element from the first (default) bank.
22.237 + *
22.238 + * @param i The data array element you want to get.
22.239 + * @return The requested data array element as an integer.
22.240 + * @see #setElem(int, int)
22.241 + * @see #setElem(int, int, int)
22.242 + */
22.243 + public int getElem(int i) {
22.244 + return data[i+offset];
22.245 + }
22.246 +
22.247 + /**
22.248 + * Returns the requested data array element from the specified bank.
22.249 + *
22.250 + * @param bank The bank from which you want to get a data array element.
22.251 + * @param i The data array element you want to get.
22.252 + * @return The requested data array element as an integer.
22.253 + * @see #setElem(int, int)
22.254 + * @see #setElem(int, int, int)
22.255 + */
22.256 + public int getElem(int bank, int i) {
22.257 + return bankdata[bank][i+offsets[bank]];
22.258 + }
22.259 +
22.260 + /**
22.261 + * Sets the requested data array element in the first (default) bank
22.262 + * to the specified value.
22.263 + *
22.264 + * @param i The data array element you want to set.
22.265 + * @param val The integer value to which you want to set the data array element.
22.266 + * @see #getElem(int)
22.267 + * @see #getElem(int, int)
22.268 + */
22.269 + public void setElem(int i, int val) {
22.270 + data[i+offset] = val;
22.271 + theTrackable.markDirty();
22.272 + }
22.273 +
22.274 + /**
22.275 + * Sets the requested data array element in the specified bank
22.276 + * to the integer value <CODE>i</CODE>.
22.277 + * @param bank The bank in which you want to set the data array element.
22.278 + * @param i The data array element you want to set.
22.279 + * @param val The integer value to which you want to set the specified data array element.
22.280 + * @see #getElem(int)
22.281 + * @see #getElem(int, int)
22.282 + */
22.283 + public void setElem(int bank, int i, int val) {
22.284 + bankdata[bank][i+offsets[bank]] = (int)val;
22.285 + theTrackable.markDirty();
22.286 + }
22.287 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/src/share/classes/java/awt/image/DataBufferShort.java Thu Jun 12 11:46:57 2008 -0700
23.3 @@ -0,0 +1,283 @@
23.4 +/*
23.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
23.7 + *
23.8 + * This code is free software; you can redistribute it and/or modify it
23.9 + * under the terms of the GNU General Public License version 2 only, as
23.10 + * published by the Free Software Foundation. Sun designates this
23.11 + * particular file as subject to the "Classpath" exception as provided
23.12 + * by Sun in the LICENSE file that accompanied this code.
23.13 + *
23.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
23.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23.17 + * version 2 for more details (a copy is included in the LICENSE file that
23.18 + * accompanied this code).
23.19 + *
23.20 + * You should have received a copy of the GNU General Public License version
23.21 + * 2 along with this work; if not, write to the Free Software Foundation,
23.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23.23 + *
23.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
23.26 + * have any questions.
23.27 + */
23.28 +
23.29 +/* ****************************************************************
23.30 + ******************************************************************
23.31 + ******************************************************************
23.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
23.33 + *** As an unpublished work pursuant to Title 17 of the United
23.34 + *** States Code. All rights reserved.
23.35 + ******************************************************************
23.36 + ******************************************************************
23.37 + ******************************************************************/
23.38 +
23.39 +package java.awt.image;
23.40 +
23.41 +import static sun.java2d.StateTrackable.State.*;
23.42 +
23.43 +/**
23.44 + * This class extends <CODE>DataBuffer</CODE> and stores data internally as shorts.
23.45 + * <p>
23.46 + * <a name="optimizations">
23.47 + * Note that some implementations may function more efficiently
23.48 + * if they can maintain control over how the data for an image is
23.49 + * stored.
23.50 + * For example, optimizations such as caching an image in video
23.51 + * memory require that the implementation track all modifications
23.52 + * to that data.
23.53 + * Other implementations may operate better if they can store the
23.54 + * data in locations other than a Java array.
23.55 + * To maintain optimum compatibility with various optimizations
23.56 + * it is best to avoid constructors and methods which expose the
23.57 + * underlying storage as a Java array as noted below in the
23.58 + * documentation for those methods.
23.59 + * </a>
23.60 + */
23.61 +public final class DataBufferShort extends DataBuffer
23.62 +{
23.63 + /** The default data bank. */
23.64 + short data[];
23.65 +
23.66 + /** All data banks */
23.67 + short bankdata[][];
23.68 +
23.69 + /**
23.70 + * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank and the
23.71 + * specified size.
23.72 + *
23.73 + * @param size The size of the <CODE>DataBuffer</CODE>.
23.74 + */
23.75 + public DataBufferShort(int size) {
23.76 + super(STABLE, TYPE_SHORT,size);
23.77 + data = new short[size];
23.78 + bankdata = new short[1][];
23.79 + bankdata[0] = data;
23.80 + }
23.81 +
23.82 + /**
23.83 + * Constructs a short-based <CODE>DataBuffer</CODE> with the specified number of
23.84 + * banks all of which are the specified size.
23.85 + *
23.86 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
23.87 + * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
23.88 + */
23.89 + public DataBufferShort(int size, int numBanks) {
23.90 + super(STABLE, TYPE_SHORT,size,numBanks);
23.91 + bankdata = new short[numBanks][];
23.92 + for (int i= 0; i < numBanks; i++) {
23.93 + bankdata[i] = new short[size];
23.94 + }
23.95 + data = bankdata[0];
23.96 + }
23.97 +
23.98 + /**
23.99 + * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
23.100 + * specified array.
23.101 + * Only the first <CODE>size</CODE> elements should be used by accessors of
23.102 + * this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
23.103 + * hold <CODE>size</CODE> elements.
23.104 + * <p>
23.105 + * Note that {@code DataBuffer} objects created by this constructor
23.106 + * may be incompatible with <a href="#optimizations">performance
23.107 + * optimizations</a> used by some implementations (such as caching
23.108 + * an associated image in video memory).
23.109 + *
23.110 + * @param dataArray The short array for the <CODE>DataBuffer</CODE>.
23.111 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
23.112 + */
23.113 + public DataBufferShort(short dataArray[], int size) {
23.114 + super(UNTRACKABLE, TYPE_SHORT, size);
23.115 + data = dataArray;
23.116 + bankdata = new short[1][];
23.117 + bankdata[0] = data;
23.118 + }
23.119 +
23.120 + /**
23.121 + * Constructs a short-based <CODE>DataBuffer</CODE> with a single bank using the
23.122 + * specified array, size, and offset. <CODE>dataArray</CODE> must have at least
23.123 + * <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements <CODE>offset</CODE>
23.124 + * through <CODE>offset</CODE> + <CODE>size</CODE> - 1
23.125 + * should be used by accessors of this <CODE>DataBuffer</CODE>.
23.126 + * <p>
23.127 + * Note that {@code DataBuffer} objects created by this constructor
23.128 + * may be incompatible with <a href="#optimizations">performance
23.129 + * optimizations</a> used by some implementations (such as caching
23.130 + * an associated image in video memory).
23.131 + *
23.132 + * @param dataArray The short array for the <CODE>DataBuffer</CODE>.
23.133 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
23.134 + * @param offset The offset into the <CODE>dataArray</CODE>.
23.135 + */
23.136 + public DataBufferShort(short dataArray[], int size, int offset) {
23.137 + super(UNTRACKABLE, TYPE_SHORT, size, 1, offset);
23.138 + data = dataArray;
23.139 + bankdata = new short[1][];
23.140 + bankdata[0] = data;
23.141 + }
23.142 +
23.143 + /**
23.144 + * Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays.
23.145 + * The number of banks will be equal to <CODE>dataArray.length</CODE>.
23.146 + * Only the first <CODE>size</CODE> elements of each array should be used by
23.147 + * accessors of this <CODE>DataBuffer</CODE>.
23.148 + * <p>
23.149 + * Note that {@code DataBuffer} objects created by this constructor
23.150 + * may be incompatible with <a href="#optimizations">performance
23.151 + * optimizations</a> used by some implementations (such as caching
23.152 + * an associated image in video memory).
23.153 + *
23.154 + * @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
23.155 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
23.156 + */
23.157 + public DataBufferShort(short dataArray[][], int size) {
23.158 + super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length);
23.159 + bankdata = (short[][]) dataArray.clone();
23.160 + data = bankdata[0];
23.161 + }
23.162 +
23.163 + /**
23.164 + * Constructs a short-based <CODE>DataBuffer</CODE> with the specified arrays, size,
23.165 + * and offsets.
23.166 + * The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
23.167 + * be at least as large as <CODE>size</CODE> + the corresponding offset. There must
23.168 + * be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
23.169 + * bank, only elements <CODE>offset</CODE> through
23.170 + * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
23.171 + * used by accessors of this <CODE>DataBuffer</CODE>.
23.172 + * <p>
23.173 + * Note that {@code DataBuffer} objects created by this constructor
23.174 + * may be incompatible with <a href="#optimizations">performance
23.175 + * optimizations</a> used by some implementations (such as caching
23.176 + * an associated image in video memory).
23.177 + *
23.178 + * @param dataArray The short arrays for the <CODE>DataBuffer</CODE>.
23.179 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
23.180 + * @param offsets The offsets into each array.
23.181 + */
23.182 + public DataBufferShort(short dataArray[][], int size, int offsets[]) {
23.183 + super(UNTRACKABLE, TYPE_SHORT, size, dataArray.length, offsets);
23.184 + bankdata = (short[][]) dataArray.clone();
23.185 + data = bankdata[0];
23.186 + }
23.187 +
23.188 + /**
23.189 + * Returns the default (first) byte data array.
23.190 + * <p>
23.191 + * Note that calling this method may cause this {@code DataBuffer}
23.192 + * object to be incompatible with <a href="#optimizations">performance
23.193 + * optimizations</a> used by some implementations (such as caching
23.194 + * an associated image in video memory).
23.195 + *
23.196 + * @return The first short data array.
23.197 + */
23.198 + public short[] getData() {
23.199 + theTrackable.setUntrackable();
23.200 + return data;
23.201 + }
23.202 +
23.203 + /**
23.204 + * Returns the data array for the specified bank.
23.205 + * <p>
23.206 + * Note that calling this method may cause this {@code DataBuffer}
23.207 + * object to be incompatible with <a href="#optimizations">performance
23.208 + * optimizations</a> used by some implementations (such as caching
23.209 + * an associated image in video memory).
23.210 + *
23.211 + * @param bank The bank whose data array you want to get.
23.212 + * @return The data array for the specified bank.
23.213 + */
23.214 + public short[] getData(int bank) {
23.215 + theTrackable.setUntrackable();
23.216 + return bankdata[bank];
23.217 + }
23.218 +
23.219 + /**
23.220 + * Returns the data arrays for all banks.
23.221 + * <p>
23.222 + * Note that calling this method may cause this {@code DataBuffer}
23.223 + * object to be incompatible with <a href="#optimizations">performance
23.224 + * optimizations</a> used by some implementations (such as caching
23.225 + * an associated image in video memory).
23.226 + *
23.227 + * @return All of the data arrays.
23.228 + */
23.229 + public short[][] getBankData() {
23.230 + theTrackable.setUntrackable();
23.231 + return (short[][]) bankdata.clone();
23.232 + }
23.233 +
23.234 + /**
23.235 + * Returns the requested data array element from the first (default) bank.
23.236 + *
23.237 + * @param i The data array element you want to get.
23.238 + * @return The requested data array element as an integer.
23.239 + * @see #setElem(int, int)
23.240 + * @see #setElem(int, int, int)
23.241 + */
23.242 + public int getElem(int i) {
23.243 + return (int)(data[i+offset]);
23.244 + }
23.245 +
23.246 + /**
23.247 + * Returns the requested data array element from the specified bank.
23.248 + *
23.249 + * @param bank The bank from which you want to get a data array element.
23.250 + * @param i The data array element you want to get.
23.251 + * @return The requested data array element as an integer.
23.252 + * @see #setElem(int, int)
23.253 + * @see #setElem(int, int, int)
23.254 + */
23.255 + public int getElem(int bank, int i) {
23.256 + return (int)(bankdata[bank][i+offsets[bank]]);
23.257 + }
23.258 +
23.259 + /**
23.260 + * Sets the requested data array element in the first (default) bank
23.261 + * to the specified value.
23.262 + *
23.263 + * @param i The data array element you want to set.
23.264 + * @param val The integer value to which you want to set the data array element.
23.265 + * @see #getElem(int)
23.266 + * @see #getElem(int, int)
23.267 + */
23.268 + public void setElem(int i, int val) {
23.269 + data[i+offset] = (short)val;
23.270 + theTrackable.markDirty();
23.271 + }
23.272 +
23.273 + /**
23.274 + * Sets the requested data array element in the specified bank
23.275 + * from the given integer.
23.276 + * @param bank The bank in which you want to set the data array element.
23.277 + * @param i The data array element you want to set.
23.278 + * @param val The integer value to which you want to set the specified data array element.
23.279 + * @see #getElem(int)
23.280 + * @see #getElem(int, int)
23.281 + */
23.282 + public void setElem(int bank, int i, int val) {
23.283 + bankdata[bank][i+offsets[bank]] = (short)val;
23.284 + theTrackable.markDirty();
23.285 + }
23.286 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/src/share/classes/java/awt/image/DataBufferUShort.java Thu Jun 12 11:46:57 2008 -0700
24.3 @@ -0,0 +1,318 @@
24.4 +/*
24.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
24.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
24.7 + *
24.8 + * This code is free software; you can redistribute it and/or modify it
24.9 + * under the terms of the GNU General Public License version 2 only, as
24.10 + * published by the Free Software Foundation. Sun designates this
24.11 + * particular file as subject to the "Classpath" exception as provided
24.12 + * by Sun in the LICENSE file that accompanied this code.
24.13 + *
24.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
24.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
24.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24.17 + * version 2 for more details (a copy is included in the LICENSE file that
24.18 + * accompanied this code).
24.19 + *
24.20 + * You should have received a copy of the GNU General Public License version
24.21 + * 2 along with this work; if not, write to the Free Software Foundation,
24.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24.23 + *
24.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
24.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
24.26 + * have any questions.
24.27 + */
24.28 +
24.29 +/* ****************************************************************
24.30 + ******************************************************************
24.31 + ******************************************************************
24.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
24.33 + *** As an unpublished work pursuant to Title 17 of the United
24.34 + *** States Code. All rights reserved.
24.35 + ******************************************************************
24.36 + ******************************************************************
24.37 + ******************************************************************/
24.38 +
24.39 +package java.awt.image;
24.40 +
24.41 +import static sun.java2d.StateTrackable.State.*;
24.42 +
24.43 +/**
24.44 + * This class extends <CODE>DataBuffer</CODE> and stores data internally as
24.45 + * shorts. Values stored in the short array(s) of this <CODE>DataBuffer</CODE>
24.46 + * are treated as unsigned values.
24.47 + * <p>
24.48 + * <a name="optimizations">
24.49 + * Note that some implementations may function more efficiently
24.50 + * if they can maintain control over how the data for an image is
24.51 + * stored.
24.52 + * For example, optimizations such as caching an image in video
24.53 + * memory require that the implementation track all modifications
24.54 + * to that data.
24.55 + * Other implementations may operate better if they can store the
24.56 + * data in locations other than a Java array.
24.57 + * To maintain optimum compatibility with various optimizations
24.58 + * it is best to avoid constructors and methods which expose the
24.59 + * underlying storage as a Java array as noted below in the
24.60 + * documentation for those methods.
24.61 + * </a>
24.62 + */
24.63 +public final class DataBufferUShort extends DataBuffer
24.64 +{
24.65 + /** The default data bank. */
24.66 + short data[];
24.67 +
24.68 + /** All data banks */
24.69 + short bankdata[][];
24.70 +
24.71 + /**
24.72 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank and the
24.73 + * specified size.
24.74 + *
24.75 + * @param size The size of the <CODE>DataBuffer</CODE>.
24.76 + */
24.77 + public DataBufferUShort(int size) {
24.78 + super(STABLE, TYPE_USHORT, size);
24.79 + data = new short[size];
24.80 + bankdata = new short[1][];
24.81 + bankdata[0] = data;
24.82 + }
24.83 +
24.84 + /**
24.85 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified number of
24.86 + * banks, all of which are the specified size.
24.87 + *
24.88 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
24.89 + * @param numBanks The number of banks in the a<CODE>DataBuffer</CODE>.
24.90 + */
24.91 + public DataBufferUShort(int size, int numBanks) {
24.92 + super(STABLE, TYPE_USHORT, size, numBanks);
24.93 + bankdata = new short[numBanks][];
24.94 + for (int i= 0; i < numBanks; i++) {
24.95 + bankdata[i] = new short[size];
24.96 + }
24.97 + data = bankdata[0];
24.98 + }
24.99 +
24.100 + /**
24.101 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
24.102 + * using the specified array.
24.103 + * Only the first <CODE>size</CODE> elements should be used by accessors of
24.104 + * this <CODE>DataBuffer</CODE>. <CODE>dataArray</CODE> must be large enough to
24.105 + * hold <CODE>size</CODE> elements.
24.106 + * <p>
24.107 + * Note that {@code DataBuffer} objects created by this constructor
24.108 + * may be incompatible with <a href="#optimizations">performance
24.109 + * optimizations</a> used by some implementations (such as caching
24.110 + * an associated image in video memory).
24.111 + *
24.112 + * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
24.113 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
24.114 + */
24.115 + public DataBufferUShort(short dataArray[], int size) {
24.116 + super(UNTRACKABLE, TYPE_USHORT, size);
24.117 + if (dataArray == null) {
24.118 + throw new NullPointerException("dataArray is null");
24.119 + }
24.120 + data = dataArray;
24.121 + bankdata = new short[1][];
24.122 + bankdata[0] = data;
24.123 + }
24.124 +
24.125 + /**
24.126 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with a single bank
24.127 + * using the specified array, size, and offset. <CODE>dataArray</CODE> must have at
24.128 + * least <CODE>offset</CODE> + <CODE>size</CODE> elements. Only elements
24.129 + * <CODE>offset</CODE> through <CODE>offset</CODE> + <CODE>size</CODE> - 1 should
24.130 + * be used by accessors of this <CODE>DataBuffer</CODE>.
24.131 + * <p>
24.132 + * Note that {@code DataBuffer} objects created by this constructor
24.133 + * may be incompatible with <a href="#optimizations">performance
24.134 + * optimizations</a> used by some implementations (such as caching
24.135 + * an associated image in video memory).
24.136 + *
24.137 + * @param dataArray The unsigned-short array for the <CODE>DataBuffer</CODE>.
24.138 + * @param size The size of the <CODE>DataBuffer</CODE> bank.
24.139 + * @param offset The offset into the <CODE>dataArray</CODE>.
24.140 + */
24.141 + public DataBufferUShort(short dataArray[], int size, int offset) {
24.142 + super(UNTRACKABLE, TYPE_USHORT, size, 1, offset);
24.143 + if (dataArray == null) {
24.144 + throw new NullPointerException("dataArray is null");
24.145 + }
24.146 + if ((size+offset) > dataArray.length) {
24.147 + throw new IllegalArgumentException("Length of dataArray is less "+
24.148 + " than size+offset.");
24.149 + }
24.150 + data = dataArray;
24.151 + bankdata = new short[1][];
24.152 + bankdata[0] = data;
24.153 + }
24.154 +
24.155 + /**
24.156 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with the specified arrays.
24.157 + * The number of banks will be equal to <CODE>dataArray.length</CODE>.
24.158 + * Only the first <CODE>size</CODE> elements of each array should be used by
24.159 + * accessors of this <CODE>DataBuffer</CODE>.
24.160 + * <p>
24.161 + * Note that {@code DataBuffer} objects created by this constructor
24.162 + * may be incompatible with <a href="#optimizations">performance
24.163 + * optimizations</a> used by some implementations (such as caching
24.164 + * an associated image in video memory).
24.165 + *
24.166 + * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
24.167 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
24.168 + */
24.169 + public DataBufferUShort(short dataArray[][], int size) {
24.170 + super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length);
24.171 + if (dataArray == null) {
24.172 + throw new NullPointerException("dataArray is null");
24.173 + }
24.174 + for (int i=0; i < dataArray.length; i++) {
24.175 + if (dataArray[i] == null) {
24.176 + throw new NullPointerException("dataArray["+i+"] is null");
24.177 + }
24.178 + }
24.179 +
24.180 + bankdata = (short[][]) dataArray.clone();
24.181 + data = bankdata[0];
24.182 + }
24.183 +
24.184 + /**
24.185 + * Constructs an unsigned-short based <CODE>DataBuffer</CODE> with specified arrays,
24.186 + * size, and offsets.
24.187 + * The number of banks is equal to <CODE>dataArray.length</CODE>. Each array must
24.188 + * be at least as large as <CODE>size</CODE> + the corresponding offset. There must
24.189 + * be an entry in the offset array for each <CODE>dataArray</CODE> entry. For each
24.190 + * bank, only elements <CODE>offset</CODE> through
24.191 + * <CODE>offset</CODE> + <CODE>size</CODE> - 1 should be
24.192 + * used by accessors of this <CODE>DataBuffer</CODE>.
24.193 + * <p>
24.194 + * Note that {@code DataBuffer} objects created by this constructor
24.195 + * may be incompatible with <a href="#optimizations">performance
24.196 + * optimizations</a> used by some implementations (such as caching
24.197 + * an associated image in video memory).
24.198 + *
24.199 + * @param dataArray The unsigned-short arrays for the <CODE>DataBuffer</CODE>.
24.200 + * @param size The size of the banks in the <CODE>DataBuffer</CODE>.
24.201 + * @param offsets The offsets into each array.
24.202 + */
24.203 + public DataBufferUShort(short dataArray[][], int size, int offsets[]) {
24.204 + super(UNTRACKABLE, TYPE_USHORT, size, dataArray.length, offsets);
24.205 + if (dataArray == null) {
24.206 + throw new NullPointerException("dataArray is null");
24.207 + }
24.208 + for (int i=0; i < dataArray.length; i++) {
24.209 + if (dataArray[i] == null) {
24.210 + throw new NullPointerException("dataArray["+i+"] is null");
24.211 + }
24.212 + if ((size+offsets[i]) > dataArray[i].length) {
24.213 + throw new IllegalArgumentException("Length of dataArray["+i+
24.214 + "] is less than size+"+
24.215 + "offsets["+i+"].");
24.216 + }
24.217 +
24.218 + }
24.219 + bankdata = (short[][]) dataArray.clone();
24.220 + data = bankdata[0];
24.221 + }
24.222 +
24.223 + /**
24.224 + * Returns the default (first) unsigned-short data array.
24.225 + * <p>
24.226 + * Note that calling this method may cause this {@code DataBuffer}
24.227 + * object to be incompatible with <a href="#optimizations">performance
24.228 + * optimizations</a> used by some implementations (such as caching
24.229 + * an associated image in video memory).
24.230 + *
24.231 + * @return The first unsigned-short data array.
24.232 + */
24.233 + public short[] getData() {
24.234 + theTrackable.setUntrackable();
24.235 + return data;
24.236 + }
24.237 +
24.238 + /**
24.239 + * Returns the data array for the specified bank.
24.240 + * <p>
24.241 + * Note that calling this method may cause this {@code DataBuffer}
24.242 + * object to be incompatible with <a href="#optimizations">performance
24.243 + * optimizations</a> used by some implementations (such as caching
24.244 + * an associated image in video memory).
24.245 + *
24.246 + * @param bank The bank whose data array you want to get.
24.247 + * @return The data array for the specified bank.
24.248 + */
24.249 + public short[] getData(int bank) {
24.250 + theTrackable.setUntrackable();
24.251 + return bankdata[bank];
24.252 + }
24.253 +
24.254 + /**
24.255 + * Returns the data arrays for all banks.
24.256 + * <p>
24.257 + * Note that calling this method may cause this {@code DataBuffer}
24.258 + * object to be incompatible with <a href="#optimizations">performance
24.259 + * optimizations</a> used by some implementations (such as caching
24.260 + * an associated image in video memory).
24.261 + *
24.262 + * @return All of the data arrays.
24.263 + */
24.264 + public short[][] getBankData() {
24.265 + theTrackable.setUntrackable();
24.266 + return (short[][]) bankdata.clone();
24.267 + }
24.268 +
24.269 + /**
24.270 + * Returns the requested data array element from the first (default) bank.
24.271 + *
24.272 + * @param i The data array element you want to get.
24.273 + * @return The requested data array element as an integer.
24.274 + * @see #setElem(int, int)
24.275 + * @see #setElem(int, int, int)
24.276 + */
24.277 + public int getElem(int i) {
24.278 + return (int)(data[i+offset]&0xffff);
24.279 + }
24.280 +
24.281 + /**
24.282 + * Returns the requested data array element from the specified bank.
24.283 + *
24.284 + * @param bank The bank from which you want to get a data array element.
24.285 + * @param i The data array element you want to get.
24.286 + * @return The requested data array element as an integer.
24.287 + * @see #setElem(int, int)
24.288 + * @see #setElem(int, int, int)
24.289 + */
24.290 + public int getElem(int bank, int i) {
24.291 + return (int)(bankdata[bank][i+offsets[bank]]&0xffff);
24.292 + }
24.293 +
24.294 + /**
24.295 + * Sets the requested data array element in the first (default) bank
24.296 + * to the specified value.
24.297 + *
24.298 + * @param i The data array element you want to set.
24.299 + * @param val The integer value to which you want to set the data array element.
24.300 + * @see #getElem(int)
24.301 + * @see #getElem(int, int)
24.302 + */
24.303 + public void setElem(int i, int val) {
24.304 + data[i+offset] = (short)(val&0xffff);
24.305 + theTrackable.markDirty();
24.306 + }
24.307 +
24.308 + /**
24.309 + * Sets the requested data array element in the specified bank
24.310 + * from the given integer.
24.311 + * @param bank The bank in which you want to set the data array element.
24.312 + * @param i The data array element you want to set.
24.313 + * @param val The integer value to which you want to set the specified data array element.
24.314 + * @see #getElem(int)
24.315 + * @see #getElem(int, int)
24.316 + */
24.317 + public void setElem(int bank, int i, int val) {
24.318 + bankdata[bank][i+offsets[bank]] = (short)(val&0xffff);
24.319 + theTrackable.markDirty();
24.320 + }
24.321 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/src/share/classes/java/awt/image/MultiPixelPackedSampleModel.java Thu Jun 12 11:46:57 2008 -0700
25.3 @@ -0,0 +1,699 @@
25.4 +/*
25.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
25.7 + *
25.8 + * This code is free software; you can redistribute it and/or modify it
25.9 + * under the terms of the GNU General Public License version 2 only, as
25.10 + * published by the Free Software Foundation. Sun designates this
25.11 + * particular file as subject to the "Classpath" exception as provided
25.12 + * by Sun in the LICENSE file that accompanied this code.
25.13 + *
25.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
25.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25.17 + * version 2 for more details (a copy is included in the LICENSE file that
25.18 + * accompanied this code).
25.19 + *
25.20 + * You should have received a copy of the GNU General Public License version
25.21 + * 2 along with this work; if not, write to the Free Software Foundation,
25.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25.23 + *
25.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
25.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
25.26 + * have any questions.
25.27 + */
25.28 +
25.29 +/* ****************************************************************
25.30 + ******************************************************************
25.31 + ******************************************************************
25.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
25.33 + *** As an unpublished work pursuant to Title 17 of the United
25.34 + *** States Code. All rights reserved.
25.35 + ******************************************************************
25.36 + ******************************************************************
25.37 + ******************************************************************/
25.38 +
25.39 +package java.awt.image;
25.40 +
25.41 +/**
25.42 + * The <code>MultiPixelPackedSampleModel</code> class represents
25.43 + * one-banded images and can pack multiple one-sample
25.44 + * pixels into one data element. Pixels are not allowed to span data elements.
25.45 + * The data type can be DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
25.46 + * or DataBuffer.TYPE_INT. Each pixel must be a power of 2 number of bits
25.47 + * and a power of 2 number of pixels must fit exactly in one data element.
25.48 + * Pixel bit stride is equal to the number of bits per pixel. Scanline
25.49 + * stride is in data elements and the last several data elements might be
25.50 + * padded with unused pixels. Data bit offset is the offset in bits from
25.51 + * the beginning of the {@link DataBuffer} to the first pixel and must be
25.52 + * a multiple of pixel bit stride.
25.53 + * <p>
25.54 + * The following code illustrates extracting the bits for pixel
25.55 + * <code>x, y</code> from <code>DataBuffer</code> <code>data</code>
25.56 + * and storing the pixel data in data elements of type
25.57 + * <code>dataType</code>:
25.58 + * <pre>
25.59 + * int dataElementSize = DataBuffer.getDataTypeSize(dataType);
25.60 + * int bitnum = dataBitOffset + x*pixelBitStride;
25.61 + * int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
25.62 + * int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.63 + * - pixelBitStride;
25.64 + * int pixel = (element >> shift) & ((1 << pixelBitStride) - 1);
25.65 + * </pre>
25.66 + */
25.67 +
25.68 +public class MultiPixelPackedSampleModel extends SampleModel
25.69 +{
25.70 + /** The number of bits from one pixel to the next. */
25.71 + int pixelBitStride;
25.72 +
25.73 + /** Bitmask that extracts the rightmost pixel of a data element. */
25.74 + int bitMask;
25.75 +
25.76 + /**
25.77 + * The number of pixels that fit in a data element. Also used
25.78 + * as the number of bits per pixel.
25.79 + */
25.80 + int pixelsPerDataElement;
25.81 +
25.82 + /** The size of a data element in bits. */
25.83 + int dataElementSize;
25.84 +
25.85 + /** The bit offset into the data array where the first pixel begins.
25.86 + */
25.87 + int dataBitOffset;
25.88 +
25.89 + /** ScanlineStride of the data buffer described in data array elements. */
25.90 + int scanlineStride;
25.91 +
25.92 + /**
25.93 + * Constructs a <code>MultiPixelPackedSampleModel</code> with the
25.94 + * specified data type, width, height and number of bits per pixel.
25.95 + * @param dataType the data type for storing samples
25.96 + * @param w the width, in pixels, of the region of
25.97 + * image data described
25.98 + * @param h the height, in pixels, of the region of
25.99 + * image data described
25.100 + * @param numberOfBits the number of bits per pixel
25.101 + * @throws IllegalArgumentException if <code>dataType</code> is not
25.102 + * either <code>DataBuffer.TYPE_BYTE</code>,
25.103 + * <code>DataBuffer.TYPE_USHORT</code>, or
25.104 + * <code>DataBuffer.TYPE_INT</code>
25.105 + */
25.106 + public MultiPixelPackedSampleModel(int dataType,
25.107 + int w,
25.108 + int h,
25.109 + int numberOfBits) {
25.110 + this(dataType,w,h,
25.111 + numberOfBits,
25.112 + (w*numberOfBits+DataBuffer.getDataTypeSize(dataType)-1)/
25.113 + DataBuffer.getDataTypeSize(dataType),
25.114 + 0);
25.115 + if (dataType != DataBuffer.TYPE_BYTE &&
25.116 + dataType != DataBuffer.TYPE_USHORT &&
25.117 + dataType != DataBuffer.TYPE_INT) {
25.118 + throw new IllegalArgumentException("Unsupported data type "+
25.119 + dataType);
25.120 + }
25.121 + }
25.122 +
25.123 + /**
25.124 + * Constructs a <code>MultiPixelPackedSampleModel</code> with
25.125 + * specified data type, width, height, number of bits per pixel,
25.126 + * scanline stride and data bit offset.
25.127 + * @param dataType the data type for storing samples
25.128 + * @param w the width, in pixels, of the region of
25.129 + * image data described
25.130 + * @param h the height, in pixels, of the region of
25.131 + * image data described
25.132 + * @param numberOfBits the number of bits per pixel
25.133 + * @param scanlineStride the line stride of the image data
25.134 + * @param dataBitOffset the data bit offset for the region of image
25.135 + * data described
25.136 + * @exception RasterFormatException if the number of bits per pixel
25.137 + * is not a power of 2 or if a power of 2 number of
25.138 + * pixels do not fit in one data element.
25.139 + * @throws IllegalArgumentException if <code>w</code> or
25.140 + * <code>h</code> is not greater than 0
25.141 + * @throws IllegalArgumentException if <code>dataType</code> is not
25.142 + * either <code>DataBuffer.TYPE_BYTE</code>,
25.143 + * <code>DataBuffer.TYPE_USHORT</code>, or
25.144 + * <code>DataBuffer.TYPE_INT</code>
25.145 + */
25.146 + public MultiPixelPackedSampleModel(int dataType, int w, int h,
25.147 + int numberOfBits,
25.148 + int scanlineStride,
25.149 + int dataBitOffset) {
25.150 + super(dataType, w, h, 1);
25.151 + if (dataType != DataBuffer.TYPE_BYTE &&
25.152 + dataType != DataBuffer.TYPE_USHORT &&
25.153 + dataType != DataBuffer.TYPE_INT) {
25.154 + throw new IllegalArgumentException("Unsupported data type "+
25.155 + dataType);
25.156 + }
25.157 + this.dataType = dataType;
25.158 + this.pixelBitStride = numberOfBits;
25.159 + this.scanlineStride = scanlineStride;
25.160 + this.dataBitOffset = dataBitOffset;
25.161 + this.dataElementSize = DataBuffer.getDataTypeSize(dataType);
25.162 + this.pixelsPerDataElement = dataElementSize/numberOfBits;
25.163 + if (pixelsPerDataElement*numberOfBits != dataElementSize) {
25.164 + throw new RasterFormatException("MultiPixelPackedSampleModel " +
25.165 + "does not allow pixels to " +
25.166 + "span data element boundaries");
25.167 + }
25.168 + this.bitMask = (1 << numberOfBits) - 1;
25.169 + }
25.170 +
25.171 +
25.172 + /**
25.173 + * Creates a new <code>MultiPixelPackedSampleModel</code> with the
25.174 + * specified width and height. The new
25.175 + * <code>MultiPixelPackedSampleModel</code> has the
25.176 + * same storage data type and number of bits per pixel as this
25.177 + * <code>MultiPixelPackedSampleModel</code>.
25.178 + * @param w the specified width
25.179 + * @param h the specified height
25.180 + * @return a {@link SampleModel} with the specified width and height
25.181 + * and with the same storage data type and number of bits per pixel
25.182 + * as this <code>MultiPixelPackedSampleModel</code>.
25.183 + * @throws IllegalArgumentException if <code>w</code> or
25.184 + * <code>h</code> is not greater than 0
25.185 + */
25.186 + public SampleModel createCompatibleSampleModel(int w, int h) {
25.187 + SampleModel sampleModel =
25.188 + new MultiPixelPackedSampleModel(dataType, w, h, pixelBitStride);
25.189 + return sampleModel;
25.190 + }
25.191 +
25.192 + /**
25.193 + * Creates a <code>DataBuffer</code> that corresponds to this
25.194 + * <code>MultiPixelPackedSampleModel</code>. The
25.195 + * <code>DataBuffer</code> object's data type and size
25.196 + * is consistent with this <code>MultiPixelPackedSampleModel</code>.
25.197 + * The <code>DataBuffer</code> has a single bank.
25.198 + * @return a <code>DataBuffer</code> with the same data type and
25.199 + * size as this <code>MultiPixelPackedSampleModel</code>.
25.200 + */
25.201 + public DataBuffer createDataBuffer() {
25.202 + DataBuffer dataBuffer = null;
25.203 +
25.204 + int size = (int)scanlineStride*height;
25.205 + switch (dataType) {
25.206 + case DataBuffer.TYPE_BYTE:
25.207 + dataBuffer = new DataBufferByte(size+(dataBitOffset+7)/8);
25.208 + break;
25.209 + case DataBuffer.TYPE_USHORT:
25.210 + dataBuffer = new DataBufferUShort(size+(dataBitOffset+15)/16);
25.211 + break;
25.212 + case DataBuffer.TYPE_INT:
25.213 + dataBuffer = new DataBufferInt(size+(dataBitOffset+31)/32);
25.214 + break;
25.215 + }
25.216 + return dataBuffer;
25.217 + }
25.218 +
25.219 + /**
25.220 + * Returns the number of data elements needed to transfer one pixel
25.221 + * via the {@link #getDataElements} and {@link #setDataElements}
25.222 + * methods. For a <code>MultiPixelPackedSampleModel</code>, this is
25.223 + * one.
25.224 + * @return the number of data elements.
25.225 + */
25.226 + public int getNumDataElements() {
25.227 + return 1;
25.228 + }
25.229 +
25.230 + /**
25.231 + * Returns the number of bits per sample for all bands.
25.232 + * @return the number of bits per sample.
25.233 + */
25.234 + public int[] getSampleSize() {
25.235 + int sampleSize[] = {pixelBitStride};
25.236 + return sampleSize;
25.237 + }
25.238 +
25.239 + /**
25.240 + * Returns the number of bits per sample for the specified band.
25.241 + * @param band the specified band
25.242 + * @return the number of bits per sample for the specified band.
25.243 + */
25.244 + public int getSampleSize(int band) {
25.245 + return pixelBitStride;
25.246 + }
25.247 +
25.248 + /**
25.249 + * Returns the offset of pixel (x, y) in data array elements.
25.250 + * @param x the X coordinate of the specified pixel
25.251 + * @param y the Y coordinate of the specified pixel
25.252 + * @return the offset of the specified pixel.
25.253 + */
25.254 + public int getOffset(int x, int y) {
25.255 + int offset = y * scanlineStride;
25.256 + offset += (x*pixelBitStride+dataBitOffset)/dataElementSize;
25.257 + return offset;
25.258 + }
25.259 +
25.260 + /**
25.261 + * Returns the offset, in bits, into the data element in which it is
25.262 + * stored for the <code>x</code>th pixel of a scanline.
25.263 + * This offset is the same for all scanlines.
25.264 + * @param x the specified pixel
25.265 + * @return the bit offset of the specified pixel.
25.266 + */
25.267 + public int getBitOffset(int x){
25.268 + return (x*pixelBitStride+dataBitOffset)%dataElementSize;
25.269 + }
25.270 +
25.271 + /**
25.272 + * Returns the scanline stride.
25.273 + * @return the scanline stride of this
25.274 + * <code>MultiPixelPackedSampleModel</code>.
25.275 + */
25.276 + public int getScanlineStride() {
25.277 + return scanlineStride;
25.278 + }
25.279 +
25.280 + /**
25.281 + * Returns the pixel bit stride in bits. This value is the same as
25.282 + * the number of bits per pixel.
25.283 + * @return the <code>pixelBitStride</code> of this
25.284 + * <code>MultiPixelPackedSampleModel</code>.
25.285 + */
25.286 + public int getPixelBitStride() {
25.287 + return pixelBitStride;
25.288 + }
25.289 +
25.290 + /**
25.291 + * Returns the data bit offset in bits.
25.292 + * @return the <code>dataBitOffset</code> of this
25.293 + * <code>MultiPixelPackedSampleModel</code>.
25.294 + */
25.295 + public int getDataBitOffset() {
25.296 + return dataBitOffset;
25.297 + }
25.298 +
25.299 + /**
25.300 + * Returns the TransferType used to transfer pixels by way of the
25.301 + * <code>getDataElements</code> and <code>setDataElements</code>
25.302 + * methods. The TransferType might or might not be the same as the
25.303 + * storage DataType. The TransferType is one of
25.304 + * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
25.305 + * or DataBuffer.TYPE_INT.
25.306 + * @return the transfertype.
25.307 + */
25.308 + public int getTransferType() {
25.309 + if (pixelBitStride > 16)
25.310 + return DataBuffer.TYPE_INT;
25.311 + else if (pixelBitStride > 8)
25.312 + return DataBuffer.TYPE_USHORT;
25.313 + else
25.314 + return DataBuffer.TYPE_BYTE;
25.315 + }
25.316 +
25.317 + /**
25.318 + * Creates a new <code>MultiPixelPackedSampleModel</code> with a
25.319 + * subset of the bands of this
25.320 + * <code>MultiPixelPackedSampleModel</code>. Since a
25.321 + * <code>MultiPixelPackedSampleModel</code> only has one band, the
25.322 + * bands argument must have a length of one and indicate the zeroth
25.323 + * band.
25.324 + * @param bands the specified bands
25.325 + * @return a new <code>SampleModel</code> with a subset of bands of
25.326 + * this <code>MultiPixelPackedSampleModel</code>.
25.327 + * @exception RasterFormatException if the number of bands requested
25.328 + * is not one.
25.329 + * @throws IllegalArgumentException if <code>w</code> or
25.330 + * <code>h</code> is not greater than 0
25.331 + */
25.332 + public SampleModel createSubsetSampleModel(int bands[]) {
25.333 + if (bands != null) {
25.334 + if (bands.length != 1)
25.335 + throw new RasterFormatException("MultiPixelPackedSampleModel has "
25.336 + + "only one band.");
25.337 + }
25.338 + SampleModel sm = createCompatibleSampleModel(width, height);
25.339 + return sm;
25.340 + }
25.341 +
25.342 + /**
25.343 + * Returns as <code>int</code> the sample in a specified band for the
25.344 + * pixel located at (x, y). An
25.345 + * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
25.346 + * coordinates are not in bounds.
25.347 + * @param x the X coordinate of the specified pixel
25.348 + * @param y the Y coordinate of the specified pixel
25.349 + * @param b the band to return, which is assumed to be 0
25.350 + * @param data the <code>DataBuffer</code> containing the image
25.351 + * data
25.352 + * @return the specified band containing the sample of the specified
25.353 + * pixel.
25.354 + * @exception ArrayIndexOutOfBoundException if the specified
25.355 + * coordinates are not in bounds.
25.356 + * @see #setSample(int, int, int, int, DataBuffer)
25.357 + */
25.358 + public int getSample(int x, int y, int b, DataBuffer data) {
25.359 + // 'b' must be 0
25.360 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
25.361 + (b != 0)) {
25.362 + throw new ArrayIndexOutOfBoundsException
25.363 + ("Coordinate out of bounds!");
25.364 + }
25.365 + int bitnum = dataBitOffset + x*pixelBitStride;
25.366 + int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
25.367 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.368 + - pixelBitStride;
25.369 + return (element >> shift) & bitMask;
25.370 + }
25.371 +
25.372 + /**
25.373 + * Sets a sample in the specified band for the pixel located at
25.374 + * (x, y) in the <code>DataBuffer</code> using an
25.375 + * <code>int</code> for input.
25.376 + * An <code>ArrayIndexOutOfBoundsException</code> is thrown if the
25.377 + * coordinates are not in bounds.
25.378 + * @param x the X coordinate of the specified pixel
25.379 + * @param y the Y coordinate of the specified pixel
25.380 + * @param b the band to return, which is assumed to be 0
25.381 + * @param s the input sample as an <code>int</code>
25.382 + * @param data the <code>DataBuffer</code> where image data is stored
25.383 + * @exception ArrayIndexOutOfBoundsException if the coordinates are
25.384 + * not in bounds.
25.385 + * @see #getSample(int, int, int, DataBuffer)
25.386 + */
25.387 + public void setSample(int x, int y, int b, int s,
25.388 + DataBuffer data) {
25.389 + // 'b' must be 0
25.390 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height) ||
25.391 + (b != 0)) {
25.392 + throw new ArrayIndexOutOfBoundsException
25.393 + ("Coordinate out of bounds!");
25.394 + }
25.395 + int bitnum = dataBitOffset + x * pixelBitStride;
25.396 + int index = y * scanlineStride + (bitnum / dataElementSize);
25.397 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.398 + - pixelBitStride;
25.399 + int element = data.getElem(index);
25.400 + element &= ~(bitMask << shift);
25.401 + element |= (s & bitMask) << shift;
25.402 + data.setElem(index,element);
25.403 + }
25.404 +
25.405 + /**
25.406 + * Returns data for a single pixel in a primitive array of type
25.407 + * TransferType. For a <code>MultiPixelPackedSampleModel</code>,
25.408 + * the array has one element, and the type is the smallest of
25.409 + * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
25.410 + * that can hold a single pixel. Generally, <code>obj</code>
25.411 + * should be passed in as <code>null</code>, so that the
25.412 + * <code>Object</code> is created automatically and is the
25.413 + * correct primitive data type.
25.414 + * <p>
25.415 + * The following code illustrates transferring data for one pixel from
25.416 + * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
25.417 + * described by <code>MultiPixelPackedSampleModel</code>
25.418 + * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
25.419 + * whose storage layout is described by
25.420 + * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
25.421 + * The transfer is generally more efficient than using
25.422 + * <code>getPixel</code> or <code>setPixel</code>.
25.423 + * <pre>
25.424 + * MultiPixelPackedSampleModel mppsm1, mppsm2;
25.425 + * DataBufferInt db1, db2;
25.426 + * mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
25.427 + * db1), db2);
25.428 + * </pre>
25.429 + * Using <code>getDataElements</code> or <code>setDataElements</code>
25.430 + * to transfer between two <code>DataBuffer/SampleModel</code> pairs
25.431 + * is legitimate if the <code>SampleModels</code> have the same number
25.432 + * of bands, corresponding bands have the same number of
25.433 + * bits per sample, and the TransferTypes are the same.
25.434 + * <p>
25.435 + * If <code>obj</code> is not <code>null</code>, it should be a
25.436 + * primitive array of type TransferType. Otherwise, a
25.437 + * <code>ClassCastException</code> is thrown. An
25.438 + * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
25.439 + * coordinates are not in bounds, or if <code>obj</code> is not
25.440 + * <code>null</code> and is not large enough to hold the pixel data.
25.441 + * @param x the X coordinate of the specified pixel
25.442 + * @param y the Y coordinate of the specified pixel
25.443 + * @param obj a primitive array in which to return the pixel data or
25.444 + * <code>null</code>.
25.445 + * @param data the <code>DataBuffer</code> containing the image data.
25.446 + * @return an <code>Object</code> containing data for the specified
25.447 + * pixel.
25.448 + * @exception ClassCastException if <code>obj</code> is not a
25.449 + * primitive array of type TransferType or is not <code>null</code>
25.450 + * @exception ArrayIndexOutOfBoundsException if the coordinates are
25.451 + * not in bounds, or if <code>obj</code> is not <code>null</code> or
25.452 + * not large enough to hold the pixel data
25.453 + * @see #setDataElements(int, int, Object, DataBuffer)
25.454 + */
25.455 + public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
25.456 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
25.457 + throw new ArrayIndexOutOfBoundsException
25.458 + ("Coordinate out of bounds!");
25.459 + }
25.460 +
25.461 + int type = getTransferType();
25.462 + int bitnum = dataBitOffset + x*pixelBitStride;
25.463 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.464 + - pixelBitStride;
25.465 + int element = 0;
25.466 +
25.467 + switch(type) {
25.468 +
25.469 + case DataBuffer.TYPE_BYTE:
25.470 +
25.471 + byte[] bdata;
25.472 +
25.473 + if (obj == null)
25.474 + bdata = new byte[1];
25.475 + else
25.476 + bdata = (byte[])obj;
25.477 +
25.478 + element = data.getElem(y*scanlineStride +
25.479 + bitnum/dataElementSize);
25.480 + bdata[0] = (byte)((element >> shift) & bitMask);
25.481 +
25.482 + obj = (Object)bdata;
25.483 + break;
25.484 +
25.485 + case DataBuffer.TYPE_USHORT:
25.486 +
25.487 + short[] sdata;
25.488 +
25.489 + if (obj == null)
25.490 + sdata = new short[1];
25.491 + else
25.492 + sdata = (short[])obj;
25.493 +
25.494 + element = data.getElem(y*scanlineStride +
25.495 + bitnum/dataElementSize);
25.496 + sdata[0] = (short)((element >> shift) & bitMask);
25.497 +
25.498 + obj = (Object)sdata;
25.499 + break;
25.500 +
25.501 + case DataBuffer.TYPE_INT:
25.502 +
25.503 + int[] idata;
25.504 +
25.505 + if (obj == null)
25.506 + idata = new int[1];
25.507 + else
25.508 + idata = (int[])obj;
25.509 +
25.510 + element = data.getElem(y*scanlineStride +
25.511 + bitnum/dataElementSize);
25.512 + idata[0] = (element >> shift) & bitMask;
25.513 +
25.514 + obj = (Object)idata;
25.515 + break;
25.516 + }
25.517 +
25.518 + return obj;
25.519 + }
25.520 +
25.521 + /**
25.522 + * Returns the specified single band pixel in the first element
25.523 + * of an <code>int</code> array.
25.524 + * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
25.525 + * coordinates are not in bounds.
25.526 + * @param x the X coordinate of the specified pixel
25.527 + * @param y the Y coordinate of the specified pixel
25.528 + * @param iArray the array containing the pixel to be returned or
25.529 + * <code>null</code>
25.530 + * @param data the <code>DataBuffer</code> where image data is stored
25.531 + * @return an array containing the specified pixel.
25.532 + * @exception ArrayIndexOutOfBoundsException if the coordinates
25.533 + * are not in bounds
25.534 + * @see #setPixel(int, int, int[], DataBuffer)
25.535 + */
25.536 + public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
25.537 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
25.538 + throw new ArrayIndexOutOfBoundsException
25.539 + ("Coordinate out of bounds!");
25.540 + }
25.541 + int pixels[];
25.542 + if (iArray != null) {
25.543 + pixels = iArray;
25.544 + } else {
25.545 + pixels = new int [numBands];
25.546 + }
25.547 + int bitnum = dataBitOffset + x*pixelBitStride;
25.548 + int element = data.getElem(y*scanlineStride + bitnum/dataElementSize);
25.549 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.550 + - pixelBitStride;
25.551 + pixels[0] = (element >> shift) & bitMask;
25.552 + return pixels;
25.553 + }
25.554 +
25.555 + /**
25.556 + * Sets the data for a single pixel in the specified
25.557 + * <code>DataBuffer</code> from a primitive array of type
25.558 + * TransferType. For a <code>MultiPixelPackedSampleModel</code>,
25.559 + * only the first element of the array holds valid data,
25.560 + * and the type must be the smallest of
25.561 + * DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, or DataBuffer.TYPE_INT
25.562 + * that can hold a single pixel.
25.563 + * <p>
25.564 + * The following code illustrates transferring data for one pixel from
25.565 + * <code>DataBuffer</code> <code>db1</code>, whose storage layout is
25.566 + * described by <code>MultiPixelPackedSampleModel</code>
25.567 + * <code>mppsm1</code>, to <code>DataBuffer</code> <code>db2</code>,
25.568 + * whose storage layout is described by
25.569 + * <code>MultiPixelPackedSampleModel</code> <code>mppsm2</code>.
25.570 + * The transfer is generally more efficient than using
25.571 + * <code>getPixel</code> or <code>setPixel</code>.
25.572 + * <pre>
25.573 + * MultiPixelPackedSampleModel mppsm1, mppsm2;
25.574 + * DataBufferInt db1, db2;
25.575 + * mppsm2.setDataElements(x, y, mppsm1.getDataElements(x, y, null,
25.576 + * db1), db2);
25.577 + * </pre>
25.578 + * Using <code>getDataElements</code> or <code>setDataElements</code> to
25.579 + * transfer between two <code>DataBuffer/SampleModel</code> pairs is
25.580 + * legitimate if the <code>SampleModel</code> objects have
25.581 + * the same number of bands, corresponding bands have the same number of
25.582 + * bits per sample, and the TransferTypes are the same.
25.583 + * <p>
25.584 + * <code>obj</code> must be a primitive array of type TransferType.
25.585 + * Otherwise, a <code>ClassCastException</code> is thrown. An
25.586 + * <code>ArrayIndexOutOfBoundsException</code> is thrown if the
25.587 + * coordinates are not in bounds, or if <code>obj</code> is not large
25.588 + * enough to hold the pixel data.
25.589 + * @param x the X coordinate of the pixel location
25.590 + * @param y the Y coordinate of the pixel location
25.591 + * @param obj a primitive array containing pixel data
25.592 + * @param data the <code>DataBuffer</code> containing the image data
25.593 + * @see #getDataElements(int, int, Object, DataBuffer)
25.594 + */
25.595 + public void setDataElements(int x, int y, Object obj, DataBuffer data) {
25.596 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
25.597 + throw new ArrayIndexOutOfBoundsException
25.598 + ("Coordinate out of bounds!");
25.599 + }
25.600 +
25.601 + int type = getTransferType();
25.602 + int bitnum = dataBitOffset + x * pixelBitStride;
25.603 + int index = y * scanlineStride + (bitnum / dataElementSize);
25.604 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.605 + - pixelBitStride;
25.606 + int element = data.getElem(index);
25.607 + element &= ~(bitMask << shift);
25.608 +
25.609 + switch(type) {
25.610 +
25.611 + case DataBuffer.TYPE_BYTE:
25.612 +
25.613 + byte[] barray = (byte[])obj;
25.614 + element |= ( ((int)(barray[0])&0xff) & bitMask) << shift;
25.615 + data.setElem(index, element);
25.616 + break;
25.617 +
25.618 + case DataBuffer.TYPE_USHORT:
25.619 +
25.620 + short[] sarray = (short[])obj;
25.621 + element |= ( ((int)(sarray[0])&0xffff) & bitMask) << shift;
25.622 + data.setElem(index, element);
25.623 + break;
25.624 +
25.625 + case DataBuffer.TYPE_INT:
25.626 +
25.627 + int[] iarray = (int[])obj;
25.628 + element |= (iarray[0] & bitMask) << shift;
25.629 + data.setElem(index, element);
25.630 + break;
25.631 + }
25.632 + }
25.633 +
25.634 + /**
25.635 + * Sets a pixel in the <code>DataBuffer</code> using an
25.636 + * <code>int</code> array for input.
25.637 + * <code>ArrayIndexOutOfBoundsException</code> is thrown if
25.638 + * the coordinates are not in bounds.
25.639 + * @param x the X coordinate of the pixel location
25.640 + * @param y the Y coordinate of the pixel location
25.641 + * @param iArray the input pixel in an <code>int</code> array
25.642 + * @param data the <code>DataBuffer</code> containing the image data
25.643 + * @see #getPixel(int, int, int[], DataBuffer)
25.644 + */
25.645 + public void setPixel(int x, int y, int[] iArray, DataBuffer data) {
25.646 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
25.647 + throw new ArrayIndexOutOfBoundsException
25.648 + ("Coordinate out of bounds!");
25.649 + }
25.650 + int bitnum = dataBitOffset + x * pixelBitStride;
25.651 + int index = y * scanlineStride + (bitnum / dataElementSize);
25.652 + int shift = dataElementSize - (bitnum & (dataElementSize-1))
25.653 + - pixelBitStride;
25.654 + int element = data.getElem(index);
25.655 + element &= ~(bitMask << shift);
25.656 + element |= (iArray[0] & bitMask) << shift;
25.657 + data.setElem(index,element);
25.658 + }
25.659 +
25.660 + public boolean equals(Object o) {
25.661 + if ((o == null) || !(o instanceof MultiPixelPackedSampleModel)) {
25.662 + return false;
25.663 + }
25.664 +
25.665 + MultiPixelPackedSampleModel that = (MultiPixelPackedSampleModel)o;
25.666 + return this.width == that.width &&
25.667 + this.height == that.height &&
25.668 + this.numBands == that.numBands &&
25.669 + this.dataType == that.dataType &&
25.670 + this.pixelBitStride == that.pixelBitStride &&
25.671 + this.bitMask == that.bitMask &&
25.672 + this.pixelsPerDataElement == that.pixelsPerDataElement &&
25.673 + this.dataElementSize == that.dataElementSize &&
25.674 + this.dataBitOffset == that.dataBitOffset &&
25.675 + this.scanlineStride == that.scanlineStride;
25.676 + }
25.677 +
25.678 + // If we implement equals() we must also implement hashCode
25.679 + public int hashCode() {
25.680 + int hash = 0;
25.681 + hash = width;
25.682 + hash <<= 8;
25.683 + hash ^= height;
25.684 + hash <<= 8;
25.685 + hash ^= numBands;
25.686 + hash <<= 8;
25.687 + hash ^= dataType;
25.688 + hash <<= 8;
25.689 + hash ^= pixelBitStride;
25.690 + hash <<= 8;
25.691 + hash ^= bitMask;
25.692 + hash <<= 8;
25.693 + hash ^= pixelsPerDataElement;
25.694 + hash <<= 8;
25.695 + hash ^= dataElementSize;
25.696 + hash <<= 8;
25.697 + hash ^= dataBitOffset;
25.698 + hash <<= 8;
25.699 + hash ^= scanlineStride;
25.700 + return hash;
25.701 + }
25.702 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/src/share/classes/java/awt/image/Raster.java Thu Jun 12 11:46:57 2008 -0700
26.3 @@ -0,0 +1,1777 @@
26.4 +/*
26.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
26.7 + *
26.8 + * This code is free software; you can redistribute it and/or modify it
26.9 + * under the terms of the GNU General Public License version 2 only, as
26.10 + * published by the Free Software Foundation. Sun designates this
26.11 + * particular file as subject to the "Classpath" exception as provided
26.12 + * by Sun in the LICENSE file that accompanied this code.
26.13 + *
26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26.17 + * version 2 for more details (a copy is included in the LICENSE file that
26.18 + * accompanied this code).
26.19 + *
26.20 + * You should have received a copy of the GNU General Public License version
26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26.23 + *
26.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
26.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
26.26 + * have any questions.
26.27 + */
26.28 +
26.29 +/* ****************************************************************
26.30 + ******************************************************************
26.31 + ******************************************************************
26.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
26.33 + *** As an unpublished work pursuant to Title 17 of the United
26.34 + *** States Code. All rights reserved.
26.35 + ******************************************************************
26.36 + ******************************************************************
26.37 + ******************************************************************/
26.38 +
26.39 +
26.40 +package java.awt.image;
26.41 +import java.awt.Rectangle;
26.42 +import java.awt.Point;
26.43 +
26.44 +import sun.awt.image.ByteInterleavedRaster;
26.45 +import sun.awt.image.ShortInterleavedRaster;
26.46 +import sun.awt.image.IntegerInterleavedRaster;
26.47 +import sun.awt.image.ByteBandedRaster;
26.48 +import sun.awt.image.ShortBandedRaster;
26.49 +import sun.awt.image.BytePackedRaster;
26.50 +import sun.awt.image.SunWritableRaster;
26.51 +
26.52 +/**
26.53 + * A class representing a rectangular array of pixels. A Raster
26.54 + * encapsulates a DataBuffer that stores the sample values and a
26.55 + * SampleModel that describes how to locate a given sample value in a
26.56 + * DataBuffer.
26.57 + * <p>
26.58 + * A Raster defines values for pixels occupying a particular
26.59 + * rectangular area of the plane, not necessarily including (0, 0).
26.60 + * The rectangle, known as the Raster's bounding rectangle and
26.61 + * available by means of the getBounds method, is defined by minX,
26.62 + * minY, width, and height values. The minX and minY values define
26.63 + * the coordinate of the upper left corner of the Raster. References
26.64 + * to pixels outside of the bounding rectangle may result in an
26.65 + * exception being thrown, or may result in references to unintended
26.66 + * elements of the Raster's associated DataBuffer. It is the user's
26.67 + * responsibility to avoid accessing such pixels.
26.68 + * <p>
26.69 + * A SampleModel describes how samples of a Raster
26.70 + * are stored in the primitive array elements of a DataBuffer.
26.71 + * Samples may be stored one per data element, as in a
26.72 + * PixelInterleavedSampleModel or BandedSampleModel, or packed several to
26.73 + * an element, as in a SinglePixelPackedSampleModel or
26.74 + * MultiPixelPackedSampleModel. The SampleModel is also
26.75 + * controls whether samples are sign extended, allowing unsigned
26.76 + * data to be stored in signed Java data types such as byte, short, and
26.77 + * int.
26.78 + * <p>
26.79 + * Although a Raster may live anywhere in the plane, a SampleModel
26.80 + * makes use of a simple coordinate system that starts at (0, 0). A
26.81 + * Raster therefore contains a translation factor that allows pixel
26.82 + * locations to be mapped between the Raster's coordinate system and
26.83 + * that of the SampleModel. The translation from the SampleModel
26.84 + * coordinate system to that of the Raster may be obtained by the
26.85 + * getSampleModelTranslateX and getSampleModelTranslateY methods.
26.86 + * <p>
26.87 + * A Raster may share a DataBuffer with another Raster either by
26.88 + * explicit construction or by the use of the createChild and
26.89 + * createTranslatedChild methods. Rasters created by these methods
26.90 + * can return a reference to the Raster they were created from by
26.91 + * means of the getParent method. For a Raster that was not
26.92 + * constructed by means of a call to createTranslatedChild or
26.93 + * createChild, getParent will return null.
26.94 + * <p>
26.95 + * The createTranslatedChild method returns a new Raster that
26.96 + * shares all of the data of the current Raster, but occupies a
26.97 + * bounding rectangle of the same width and height but with a
26.98 + * different starting point. For example, if the parent Raster
26.99 + * occupied the region (10, 10) to (100, 100), and the translated
26.100 + * Raster was defined to start at (50, 50), then pixel (20, 20) of the
26.101 + * parent and pixel (60, 60) of the child occupy the same location in
26.102 + * the DataBuffer shared by the two Rasters. In the first case, (-10,
26.103 + * -10) should be added to a pixel coordinate to obtain the
26.104 + * corresponding SampleModel coordinate, and in the second case (-50,
26.105 + * -50) should be added.
26.106 + * <p>
26.107 + * The translation between a parent and child Raster may be
26.108 + * determined by subtracting the child's sampleModelTranslateX and
26.109 + * sampleModelTranslateY values from those of the parent.
26.110 + * <p>
26.111 + * The createChild method may be used to create a new Raster
26.112 + * occupying only a subset of its parent's bounding rectangle
26.113 + * (with the same or a translated coordinate system) or
26.114 + * with a subset of the bands of its parent.
26.115 + * <p>
26.116 + * All constructors are protected. The correct way to create a
26.117 + * Raster is to use one of the static create methods defined in this
26.118 + * class. These methods create instances of Raster that use the
26.119 + * standard Interleaved, Banded, and Packed SampleModels and that may
26.120 + * be processed more efficiently than a Raster created by combining
26.121 + * an externally generated SampleModel and DataBuffer.
26.122 + * @see java.awt.image.DataBuffer
26.123 + * @see java.awt.image.SampleModel
26.124 + * @see java.awt.image.PixelInterleavedSampleModel
26.125 + * @see java.awt.image.BandedSampleModel
26.126 + * @see java.awt.image.SinglePixelPackedSampleModel
26.127 + * @see java.awt.image.MultiPixelPackedSampleModel
26.128 + */
26.129 +public class Raster {
26.130 +
26.131 + /**
26.132 + * The SampleModel that describes how pixels from this Raster
26.133 + * are stored in the DataBuffer.
26.134 + */
26.135 + protected SampleModel sampleModel;
26.136 +
26.137 + /** The DataBuffer that stores the image data. */
26.138 + protected DataBuffer dataBuffer;
26.139 +
26.140 + /** The X coordinate of the upper-left pixel of this Raster. */
26.141 + protected int minX;
26.142 +
26.143 + /** The Y coordinate of the upper-left pixel of this Raster. */
26.144 + protected int minY;
26.145 +
26.146 + /** The width of this Raster. */
26.147 + protected int width;
26.148 +
26.149 + /** The height of this Raster. */
26.150 + protected int height;
26.151 +
26.152 + /**
26.153 + * The X translation from the coordinate space of the
26.154 + * Raster's SampleModel to that of the Raster.
26.155 + */
26.156 + protected int sampleModelTranslateX;
26.157 +
26.158 + /**
26.159 + * The Y translation from the coordinate space of the
26.160 + * Raster's SampleModel to that of the Raster.
26.161 + */
26.162 + protected int sampleModelTranslateY;
26.163 +
26.164 + /** The number of bands in the Raster. */
26.165 + protected int numBands;
26.166 +
26.167 + /** The number of DataBuffer data elements per pixel. */
26.168 + protected int numDataElements;
26.169 +
26.170 + /** The parent of this Raster, or null. */
26.171 + protected Raster parent;
26.172 +
26.173 + static private native void initIDs();
26.174 + static {
26.175 + ColorModel.loadLibraries();
26.176 + initIDs();
26.177 + }
26.178 +
26.179 + /**
26.180 + * Creates a Raster based on a PixelInterleavedSampleModel with the
26.181 + * specified data type, width, height, and number of bands.
26.182 + *
26.183 + * <p> The upper left corner of the Raster is given by the
26.184 + * location argument. If location is null, (0, 0) will be used.
26.185 + * The dataType parameter should be one of the enumerated values
26.186 + * defined in the DataBuffer class.
26.187 + *
26.188 + * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
26.189 + * Rasters are not supported. To create a 1-band Raster of type
26.190 + * <code>DataBuffer.TYPE_INT</code>, use
26.191 + * Raster.createPackedRaster().
26.192 + * <p> The only dataTypes supported currently are TYPE_BYTE
26.193 + * and TYPE_USHORT.
26.194 + * @param dataType the data type for storing samples
26.195 + * @param w the width in pixels of the image data
26.196 + * @param h the height in pixels of the image data
26.197 + * @param bands the number of bands
26.198 + * @param location the upper-left corner of the <code>Raster</code>
26.199 + * @return a WritableRaster object with the specified data type,
26.200 + * width, height and number of bands.
26.201 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.202 + * is less than or equal to zero, or computing either
26.203 + * <code>location.x + w</code> or
26.204 + * <code>location.y + h</code> results in integer
26.205 + * overflow
26.206 + */
26.207 + public static WritableRaster createInterleavedRaster(int dataType,
26.208 + int w, int h,
26.209 + int bands,
26.210 + Point location) {
26.211 + int[] bandOffsets = new int[bands];
26.212 + for (int i = 0; i < bands; i++) {
26.213 + bandOffsets[i] = i;
26.214 + }
26.215 + return createInterleavedRaster(dataType, w, h, w*bands, bands,
26.216 + bandOffsets, location);
26.217 + }
26.218 +
26.219 + /**
26.220 + * Creates a Raster based on a PixelInterleavedSampleModel with the
26.221 + * specified data type, width, height, scanline stride, pixel
26.222 + * stride, and band offsets. The number of bands is inferred from
26.223 + * bandOffsets.length.
26.224 + *
26.225 + * <p> The upper left corner of the Raster is given by the
26.226 + * location argument. If location is null, (0, 0) will be used.
26.227 + * The dataType parameter should be one of the enumerated values
26.228 + * defined in the DataBuffer class.
26.229 + *
26.230 + * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
26.231 + * Rasters are not supported. To create a 1-band Raster of type
26.232 + * <code>DataBuffer.TYPE_INT</code>, use
26.233 + * Raster.createPackedRaster().
26.234 + * <p> The only dataTypes supported currently are TYPE_BYTE
26.235 + * and TYPE_USHORT.
26.236 + * @param dataType the data type for storing samples
26.237 + * @param w the width in pixels of the image data
26.238 + * @param h the height in pixels of the image data
26.239 + * @param scanlineStride the line stride of the image data
26.240 + * @param pixelStride the pixel stride of the image data
26.241 + * @param bandOffsets the offsets of all bands
26.242 + * @param location the upper-left corner of the <code>Raster</code>
26.243 + * @return a WritableRaster object with the specified data type,
26.244 + * width, height, scanline stride, pixel stride and band
26.245 + * offsets.
26.246 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.247 + * is less than or equal to zero, or computing either
26.248 + * <code>location.x + w</code> or
26.249 + * <code>location.y + h</code> results in integer
26.250 + * overflow
26.251 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.252 + * one of the supported data types, which are
26.253 + * <code>DataBuffer.TYPE_BYTE</code>, or
26.254 + * <code>DataBuffer.TYPE_USHORT</code>.
26.255 + */
26.256 + public static WritableRaster createInterleavedRaster(int dataType,
26.257 + int w, int h,
26.258 + int scanlineStride,
26.259 + int pixelStride,
26.260 + int bandOffsets[],
26.261 + Point location) {
26.262 + DataBuffer d;
26.263 + int bands = bandOffsets.length;
26.264 +
26.265 + int maxBandOff = bandOffsets[0];
26.266 + for (int i=1; i < bands; i++) {
26.267 + if (bandOffsets[i] > maxBandOff) {
26.268 + maxBandOff = bandOffsets[i];
26.269 + }
26.270 + }
26.271 + int size = maxBandOff + scanlineStride*(h-1) + pixelStride*(w-1) + 1;
26.272 + switch(dataType) {
26.273 + case DataBuffer.TYPE_BYTE:
26.274 + d = new DataBufferByte(size);
26.275 + break;
26.276 +
26.277 + case DataBuffer.TYPE_USHORT:
26.278 + d = new DataBufferUShort(size);
26.279 + break;
26.280 +
26.281 + default:
26.282 + throw new IllegalArgumentException("Unsupported data type " +
26.283 + dataType);
26.284 + }
26.285 +
26.286 + return createInterleavedRaster(d, w, h, scanlineStride,
26.287 + pixelStride, bandOffsets, location);
26.288 + }
26.289 +
26.290 + /**
26.291 + * Creates a Raster based on a BandedSampleModel with the
26.292 + * specified data type, width, height, and number of bands.
26.293 + *
26.294 + * <p> The upper left corner of the Raster is given by the
26.295 + * location argument. If location is null, (0, 0) will be used.
26.296 + * The dataType parameter should be one of the enumerated values
26.297 + * defined in the DataBuffer class.
26.298 + *
26.299 + * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
26.300 + * and TYPE_INT.
26.301 + * @param dataType the data type for storing samples
26.302 + * @param w the width in pixels of the image data
26.303 + * @param h the height in pixels of the image data
26.304 + * @param bands the number of bands
26.305 + * @param location the upper-left corner of the <code>Raster</code>
26.306 + * @return a WritableRaster object with the specified data type,
26.307 + * width, height and number of bands.
26.308 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.309 + * is less than or equal to zero, or computing either
26.310 + * <code>location.x + w</code> or
26.311 + * <code>location.y + h</code> results in integer
26.312 + * overflow
26.313 + * @throws ArrayIndexOutOfBoundsException if <code>bands</code>
26.314 + * is less than 1
26.315 + */
26.316 + public static WritableRaster createBandedRaster(int dataType,
26.317 + int w, int h,
26.318 + int bands,
26.319 + Point location) {
26.320 + if (bands < 1) {
26.321 + throw new ArrayIndexOutOfBoundsException("Number of bands ("+
26.322 + bands+") must"+
26.323 + " be greater than 0");
26.324 + }
26.325 + int[] bankIndices = new int[bands];
26.326 + int[] bandOffsets = new int[bands];
26.327 + for (int i = 0; i < bands; i++) {
26.328 + bankIndices[i] = i;
26.329 + bandOffsets[i] = 0;
26.330 + }
26.331 +
26.332 + return createBandedRaster(dataType, w, h, w,
26.333 + bankIndices, bandOffsets,
26.334 + location);
26.335 + }
26.336 +
26.337 + /**
26.338 + * Creates a Raster based on a BandedSampleModel with the
26.339 + * specified data type, width, height, scanline stride, bank
26.340 + * indices and band offsets. The number of bands is inferred from
26.341 + * bankIndices.length and bandOffsets.length, which must be the
26.342 + * same.
26.343 + *
26.344 + * <p> The upper left corner of the Raster is given by the
26.345 + * location argument. The dataType parameter should be one of the
26.346 + * enumerated values defined in the DataBuffer class.
26.347 + *
26.348 + * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
26.349 + * and TYPE_INT.
26.350 + * @param dataType the data type for storing samples
26.351 + * @param w the width in pixels of the image data
26.352 + * @param h the height in pixels of the image data
26.353 + * @param scanlineStride the line stride of the image data
26.354 + * @param bankIndices the bank indices for each band
26.355 + * @param bandOffsets the offsets of all bands
26.356 + * @param location the upper-left corner of the <code>Raster</code>
26.357 + * @return a WritableRaster object with the specified data type,
26.358 + * width, height, scanline stride, bank indices and band
26.359 + * offsets.
26.360 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.361 + * is less than or equal to zero, or computing either
26.362 + * <code>location.x + w</code> or
26.363 + * <code>location.y + h</code> results in integer
26.364 + * overflow
26.365 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.366 + * one of the supported data types, which are
26.367 + * <code>DataBuffer.TYPE_BYTE</code>,
26.368 + * <code>DataBuffer.TYPE_USHORT</code>
26.369 + * or <code>DataBuffer.TYPE_INT</code>
26.370 + * @throws ArrayIndexOutOfBoundsException if <code>bankIndices</code>
26.371 + * or <code>bandOffsets</code> is <code>null</code>
26.372 + */
26.373 + public static WritableRaster createBandedRaster(int dataType,
26.374 + int w, int h,
26.375 + int scanlineStride,
26.376 + int bankIndices[],
26.377 + int bandOffsets[],
26.378 + Point location) {
26.379 + DataBuffer d;
26.380 + int bands = bandOffsets.length;
26.381 +
26.382 + if (bankIndices == null) {
26.383 + throw new
26.384 + ArrayIndexOutOfBoundsException("Bank indices array is null");
26.385 + }
26.386 + if (bandOffsets == null) {
26.387 + throw new
26.388 + ArrayIndexOutOfBoundsException("Band offsets array is null");
26.389 + }
26.390 +
26.391 + // Figure out the #banks and the largest band offset
26.392 + int maxBank = bankIndices[0];
26.393 + int maxBandOff = bandOffsets[0];
26.394 + for (int i = 1; i < bands; i++) {
26.395 + if (bankIndices[i] > maxBank) {
26.396 + maxBank = bankIndices[i];
26.397 + }
26.398 + if (bandOffsets[i] > maxBandOff) {
26.399 + maxBandOff = bandOffsets[i];
26.400 + }
26.401 + }
26.402 + int banks = maxBank + 1;
26.403 + int size = maxBandOff + scanlineStride*(h-1) + (w-1) + 1;
26.404 +
26.405 + switch(dataType) {
26.406 + case DataBuffer.TYPE_BYTE:
26.407 + d = new DataBufferByte(size, banks);
26.408 + break;
26.409 +
26.410 + case DataBuffer.TYPE_USHORT:
26.411 + d = new DataBufferUShort(size, banks);
26.412 + break;
26.413 +
26.414 + case DataBuffer.TYPE_INT:
26.415 + d = new DataBufferInt(size, banks);
26.416 + break;
26.417 +
26.418 + default:
26.419 + throw new IllegalArgumentException("Unsupported data type " +
26.420 + dataType);
26.421 + }
26.422 +
26.423 + return createBandedRaster(d, w, h, scanlineStride,
26.424 + bankIndices, bandOffsets, location);
26.425 + }
26.426 +
26.427 + /**
26.428 + * Creates a Raster based on a SinglePixelPackedSampleModel with
26.429 + * the specified data type, width, height, and band masks.
26.430 + * The number of bands is inferred from bandMasks.length.
26.431 + *
26.432 + * <p> The upper left corner of the Raster is given by the
26.433 + * location argument. If location is null, (0, 0) will be used.
26.434 + * The dataType parameter should be one of the enumerated values
26.435 + * defined in the DataBuffer class.
26.436 + *
26.437 + * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
26.438 + * and TYPE_INT.
26.439 + * @param dataType the data type for storing samples
26.440 + * @param w the width in pixels of the image data
26.441 + * @param h the height in pixels of the image data
26.442 + * @param bandMasks an array containing an entry for each band
26.443 + * @param location the upper-left corner of the <code>Raster</code>
26.444 + * @return a WritableRaster object with the specified data type,
26.445 + * width, height, and band masks.
26.446 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.447 + * is less than or equal to zero, or computing either
26.448 + * <code>location.x + w</code> or
26.449 + * <code>location.y + h</code> results in integer
26.450 + * overflow
26.451 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.452 + * one of the supported data types, which are
26.453 + * <code>DataBuffer.TYPE_BYTE</code>,
26.454 + * <code>DataBuffer.TYPE_USHORT</code>
26.455 + * or <code>DataBuffer.TYPE_INT</code>
26.456 + */
26.457 + public static WritableRaster createPackedRaster(int dataType,
26.458 + int w, int h,
26.459 + int bandMasks[],
26.460 + Point location) {
26.461 + DataBuffer d;
26.462 +
26.463 + switch(dataType) {
26.464 + case DataBuffer.TYPE_BYTE:
26.465 + d = new DataBufferByte(w*h);
26.466 + break;
26.467 +
26.468 + case DataBuffer.TYPE_USHORT:
26.469 + d = new DataBufferUShort(w*h);
26.470 + break;
26.471 +
26.472 + case DataBuffer.TYPE_INT:
26.473 + d = new DataBufferInt(w*h);
26.474 + break;
26.475 +
26.476 + default:
26.477 + throw new IllegalArgumentException("Unsupported data type " +
26.478 + dataType);
26.479 + }
26.480 +
26.481 + return createPackedRaster(d, w, h, w, bandMasks, location);
26.482 + }
26.483 +
26.484 + /**
26.485 + * Creates a Raster based on a packed SampleModel with the
26.486 + * specified data type, width, height, number of bands, and bits
26.487 + * per band. If the number of bands is one, the SampleModel will
26.488 + * be a MultiPixelPackedSampleModel.
26.489 + *
26.490 + * <p> If the number of bands is more than one, the SampleModel
26.491 + * will be a SinglePixelPackedSampleModel, with each band having
26.492 + * bitsPerBand bits. In either case, the requirements on dataType
26.493 + * and bitsPerBand imposed by the corresponding SampleModel must
26.494 + * be met.
26.495 + *
26.496 + * <p> The upper left corner of the Raster is given by the
26.497 + * location argument. If location is null, (0, 0) will be used.
26.498 + * The dataType parameter should be one of the enumerated values
26.499 + * defined in the DataBuffer class.
26.500 + *
26.501 + * <p> The only dataTypes supported currently are TYPE_BYTE, TYPE_USHORT,
26.502 + * and TYPE_INT.
26.503 + * @param dataType the data type for storing samples
26.504 + * @param w the width in pixels of the image data
26.505 + * @param h the height in pixels of the image data
26.506 + * @param bands the number of bands
26.507 + * @param bitsPerBand the number of bits per band
26.508 + * @param location the upper-left corner of the <code>Raster</code>
26.509 + * @return a WritableRaster object with the specified data type,
26.510 + * width, height, number of bands, and bits per band.
26.511 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.512 + * is less than or equal to zero, or computing either
26.513 + * <code>location.x + w</code> or
26.514 + * <code>location.y + h</code> results in integer
26.515 + * overflow
26.516 + * @throws IllegalArgumentException if the product of
26.517 + * <code>bitsPerBand</code> and <code>bands</code> is
26.518 + * greater than the number of bits held by
26.519 + * <code>dataType</code>
26.520 + * @throws IllegalArgumentException if <code>bitsPerBand</code> or
26.521 + * <code>bands</code> is not greater than zero
26.522 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.523 + * one of the supported data types, which are
26.524 + * <code>DataBuffer.TYPE_BYTE</code>,
26.525 + * <code>DataBuffer.TYPE_USHORT</code>
26.526 + * or <code>DataBuffer.TYPE_INT</code>
26.527 + */
26.528 + public static WritableRaster createPackedRaster(int dataType,
26.529 + int w, int h,
26.530 + int bands,
26.531 + int bitsPerBand,
26.532 + Point location) {
26.533 + DataBuffer d;
26.534 +
26.535 + if (bands <= 0) {
26.536 + throw new IllegalArgumentException("Number of bands ("+bands+
26.537 + ") must be greater than 0");
26.538 + }
26.539 +
26.540 + if (bitsPerBand <= 0) {
26.541 + throw new IllegalArgumentException("Bits per band ("+bitsPerBand+
26.542 + ") must be greater than 0");
26.543 + }
26.544 +
26.545 + if (bands != 1) {
26.546 + int[] masks = new int[bands];
26.547 + int mask = (1 << bitsPerBand) - 1;
26.548 + int shift = (bands-1)*bitsPerBand;
26.549 +
26.550 + /* Make sure the total mask size will fit in the data type */
26.551 + if (shift+bitsPerBand > DataBuffer.getDataTypeSize(dataType)) {
26.552 + throw new IllegalArgumentException("bitsPerBand("+
26.553 + bitsPerBand+") * bands is "+
26.554 + " greater than data type "+
26.555 + "size.");
26.556 + }
26.557 + switch(dataType) {
26.558 + case DataBuffer.TYPE_BYTE:
26.559 + case DataBuffer.TYPE_USHORT:
26.560 + case DataBuffer.TYPE_INT:
26.561 + break;
26.562 + default:
26.563 + throw new IllegalArgumentException("Unsupported data type " +
26.564 + dataType);
26.565 + }
26.566 +
26.567 + for (int i = 0; i < bands; i++) {
26.568 + masks[i] = mask << shift;
26.569 + shift = shift - bitsPerBand;
26.570 + }
26.571 +
26.572 + return createPackedRaster(dataType, w, h, masks, location);
26.573 + }
26.574 + else {
26.575 + double fw = w;
26.576 + switch(dataType) {
26.577 + case DataBuffer.TYPE_BYTE:
26.578 + d = new DataBufferByte((int)(Math.ceil(fw/(8/bitsPerBand)))*h);
26.579 + break;
26.580 +
26.581 + case DataBuffer.TYPE_USHORT:
26.582 + d = new DataBufferUShort((int)(Math.ceil(fw/(16/bitsPerBand)))*h);
26.583 + break;
26.584 +
26.585 + case DataBuffer.TYPE_INT:
26.586 + d = new DataBufferInt((int)(Math.ceil(fw/(32/bitsPerBand)))*h);
26.587 + break;
26.588 +
26.589 + default:
26.590 + throw new IllegalArgumentException("Unsupported data type " +
26.591 + dataType);
26.592 + }
26.593 +
26.594 + return createPackedRaster(d, w, h, bitsPerBand, location);
26.595 + }
26.596 + }
26.597 +
26.598 + /**
26.599 + * Creates a Raster based on a PixelInterleavedSampleModel with the
26.600 + * specified DataBuffer, width, height, scanline stride, pixel
26.601 + * stride, and band offsets. The number of bands is inferred from
26.602 + * bandOffsets.length. The upper left corner of the Raster
26.603 + * is given by the location argument. If location is null, (0, 0)
26.604 + * will be used.
26.605 + * <p> Note that interleaved <code>DataBuffer.TYPE_INT</code>
26.606 + * Rasters are not supported. To create a 1-band Raster of type
26.607 + * <code>DataBuffer.TYPE_INT</code>, use
26.608 + * Raster.createPackedRaster().
26.609 + * @param dataBuffer the <code>DataBuffer</code> that contains the
26.610 + * image data
26.611 + * @param w the width in pixels of the image data
26.612 + * @param h the height in pixels of the image data
26.613 + * @param scanlineStride the line stride of the image data
26.614 + * @param pixelStride the pixel stride of the image data
26.615 + * @param bandOffsets the offsets of all bands
26.616 + * @param location the upper-left corner of the <code>Raster</code>
26.617 + * @return a WritableRaster object with the specified
26.618 + * <code>DataBuffer</code>, width, height, scanline stride,
26.619 + * pixel stride and band offsets.
26.620 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.621 + * is less than or equal to zero, or computing either
26.622 + * <code>location.x + w</code> or
26.623 + * <code>location.y + h</code> results in integer
26.624 + * overflow
26.625 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.626 + * one of the supported data types, which are
26.627 + * <code>DataBuffer.TYPE_BYTE</code>,
26.628 + * <code>DataBuffer.TYPE_USHORT</code>
26.629 + * @throws RasterFormatException if <code>dataBuffer</code> has more
26.630 + * than one bank.
26.631 + * @throws NullPointerException if <code>dataBuffer</code> is null
26.632 + */
26.633 + public static WritableRaster createInterleavedRaster(DataBuffer dataBuffer,
26.634 + int w, int h,
26.635 + int scanlineStride,
26.636 + int pixelStride,
26.637 + int bandOffsets[],
26.638 + Point location) {
26.639 + if (dataBuffer == null) {
26.640 + throw new NullPointerException("DataBuffer cannot be null");
26.641 + }
26.642 + if (location == null) {
26.643 + location = new Point(0, 0);
26.644 + }
26.645 + int dataType = dataBuffer.getDataType();
26.646 +
26.647 + PixelInterleavedSampleModel csm =
26.648 + new PixelInterleavedSampleModel(dataType, w, h,
26.649 + pixelStride,
26.650 + scanlineStride,
26.651 + bandOffsets);
26.652 + switch(dataType) {
26.653 + case DataBuffer.TYPE_BYTE:
26.654 + return new ByteInterleavedRaster(csm, dataBuffer, location);
26.655 +
26.656 + case DataBuffer.TYPE_USHORT:
26.657 + return new ShortInterleavedRaster(csm, dataBuffer, location);
26.658 +
26.659 + default:
26.660 + throw new IllegalArgumentException("Unsupported data type " +
26.661 + dataType);
26.662 + }
26.663 + }
26.664 +
26.665 + /**
26.666 + * Creates a Raster based on a BandedSampleModel with the
26.667 + * specified DataBuffer, width, height, scanline stride, bank
26.668 + * indices, and band offsets. The number of bands is inferred
26.669 + * from bankIndices.length and bandOffsets.length, which must be
26.670 + * the same. The upper left corner of the Raster is given by the
26.671 + * location argument. If location is null, (0, 0) will be used.
26.672 + * @param dataBuffer the <code>DataBuffer</code> that contains the
26.673 + * image data
26.674 + * @param w the width in pixels of the image data
26.675 + * @param h the height in pixels of the image data
26.676 + * @param scanlineStride the line stride of the image data
26.677 + * @param bankIndices the bank indices for each band
26.678 + * @param bandOffsets the offsets of all bands
26.679 + * @param location the upper-left corner of the <code>Raster</code>
26.680 + * @return a WritableRaster object with the specified
26.681 + * <code>DataBuffer</code>, width, height, scanline stride,
26.682 + * bank indices and band offsets.
26.683 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.684 + * is less than or equal to zero, or computing either
26.685 + * <code>location.x + w</code> or
26.686 + * <code>location.y + h</code> results in integer
26.687 + * overflow
26.688 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.689 + * one of the supported data types, which are
26.690 + * <code>DataBuffer.TYPE_BYTE</code>,
26.691 + * <code>DataBuffer.TYPE_USHORT</code>
26.692 + * or <code>DataBuffer.TYPE_INT</code>
26.693 + * @throws NullPointerException if <code>dataBuffer</code> is null
26.694 + */
26.695 + public static WritableRaster createBandedRaster(DataBuffer dataBuffer,
26.696 + int w, int h,
26.697 + int scanlineStride,
26.698 + int bankIndices[],
26.699 + int bandOffsets[],
26.700 + Point location) {
26.701 + if (dataBuffer == null) {
26.702 + throw new NullPointerException("DataBuffer cannot be null");
26.703 + }
26.704 + if (location == null) {
26.705 + location = new Point(0,0);
26.706 + }
26.707 + int dataType = dataBuffer.getDataType();
26.708 +
26.709 + int bands = bankIndices.length;
26.710 + if (bandOffsets.length != bands) {
26.711 + throw new IllegalArgumentException(
26.712 + "bankIndices.length != bandOffsets.length");
26.713 + }
26.714 +
26.715 + BandedSampleModel bsm =
26.716 + new BandedSampleModel(dataType, w, h,
26.717 + scanlineStride,
26.718 + bankIndices, bandOffsets);
26.719 +
26.720 + switch(dataType) {
26.721 + case DataBuffer.TYPE_BYTE:
26.722 + return new ByteBandedRaster(bsm, dataBuffer, location);
26.723 +
26.724 + case DataBuffer.TYPE_USHORT:
26.725 + return new ShortBandedRaster(bsm, dataBuffer, location);
26.726 +
26.727 + case DataBuffer.TYPE_INT:
26.728 + return new SunWritableRaster(bsm, dataBuffer, location);
26.729 +
26.730 + default:
26.731 + throw new IllegalArgumentException("Unsupported data type " +
26.732 + dataType);
26.733 + }
26.734 + }
26.735 +
26.736 + /**
26.737 + * Creates a Raster based on a SinglePixelPackedSampleModel with
26.738 + * the specified DataBuffer, width, height, scanline stride, and
26.739 + * band masks. The number of bands is inferred from bandMasks.length.
26.740 + * The upper left corner of the Raster is given by
26.741 + * the location argument. If location is null, (0, 0) will be used.
26.742 + * @param dataBuffer the <code>DataBuffer</code> that contains the
26.743 + * image data
26.744 + * @param w the width in pixels of the image data
26.745 + * @param h the height in pixels of the image data
26.746 + * @param scanlineStride the line stride of the image data
26.747 + * @param bandMasks an array containing an entry for each band
26.748 + * @param location the upper-left corner of the <code>Raster</code>
26.749 + * @return a WritableRaster object with the specified
26.750 + * <code>DataBuffer</code>, width, height, scanline stride,
26.751 + * and band masks.
26.752 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.753 + * is less than or equal to zero, or computing either
26.754 + * <code>location.x + w</code> or
26.755 + * <code>location.y + h</code> results in integer
26.756 + * overflow
26.757 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.758 + * one of the supported data types, which are
26.759 + * <code>DataBuffer.TYPE_BYTE</code>,
26.760 + * <code>DataBuffer.TYPE_USHORT</code>
26.761 + * or <code>DataBuffer.TYPE_INT</code>
26.762 + * @throws RasterFormatException if <code>dataBuffer</code> has more
26.763 + * than one bank.
26.764 + * @throws NullPointerException if <code>dataBuffer</code> is null
26.765 + */
26.766 + public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
26.767 + int w, int h,
26.768 + int scanlineStride,
26.769 + int bandMasks[],
26.770 + Point location) {
26.771 + if (dataBuffer == null) {
26.772 + throw new NullPointerException("DataBuffer cannot be null");
26.773 + }
26.774 + if (location == null) {
26.775 + location = new Point(0,0);
26.776 + }
26.777 + int dataType = dataBuffer.getDataType();
26.778 +
26.779 + SinglePixelPackedSampleModel sppsm =
26.780 + new SinglePixelPackedSampleModel(dataType, w, h, scanlineStride,
26.781 + bandMasks);
26.782 +
26.783 + switch(dataType) {
26.784 + case DataBuffer.TYPE_BYTE:
26.785 + return new ByteInterleavedRaster(sppsm, dataBuffer, location);
26.786 +
26.787 + case DataBuffer.TYPE_USHORT:
26.788 + return new ShortInterleavedRaster(sppsm, dataBuffer, location);
26.789 +
26.790 + case DataBuffer.TYPE_INT:
26.791 + return new IntegerInterleavedRaster(sppsm, dataBuffer, location);
26.792 +
26.793 + default:
26.794 + throw new IllegalArgumentException("Unsupported data type " +
26.795 + dataType);
26.796 + }
26.797 + }
26.798 +
26.799 + /**
26.800 + * Creates a Raster based on a MultiPixelPackedSampleModel with the
26.801 + * specified DataBuffer, width, height, and bits per pixel. The upper
26.802 + * left corner of the Raster is given by the location argument. If
26.803 + * location is null, (0, 0) will be used.
26.804 + * @param dataBuffer the <code>DataBuffer</code> that contains the
26.805 + * image data
26.806 + * @param w the width in pixels of the image data
26.807 + * @param h the height in pixels of the image data
26.808 + * @param bitsPerPixel the number of bits for each pixel
26.809 + * @param location the upper-left corner of the <code>Raster</code>
26.810 + * @return a WritableRaster object with the specified
26.811 + * <code>DataBuffer</code>, width, height, and
26.812 + * bits per pixel.
26.813 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.814 + * is less than or equal to zero, or computing either
26.815 + * <code>location.x + w</code> or
26.816 + * <code>location.y + h</code> results in integer
26.817 + * overflow
26.818 + * @throws IllegalArgumentException if <code>dataType</code> is not
26.819 + * one of the supported data types, which are
26.820 + * <code>DataBuffer.TYPE_BYTE</code>,
26.821 + * <code>DataBuffer.TYPE_USHORT</code>
26.822 + * or <code>DataBuffer.TYPE_INT</code>
26.823 + * @throws RasterFormatException if <code>dataBuffer</code> has more
26.824 + * than one bank.
26.825 + * @throws NullPointerException if <code>dataBuffer</code> is null
26.826 + */
26.827 + public static WritableRaster createPackedRaster(DataBuffer dataBuffer,
26.828 + int w, int h,
26.829 + int bitsPerPixel,
26.830 + Point location) {
26.831 + if (dataBuffer == null) {
26.832 + throw new NullPointerException("DataBuffer cannot be null");
26.833 + }
26.834 + if (location == null) {
26.835 + location = new Point(0,0);
26.836 + }
26.837 + int dataType = dataBuffer.getDataType();
26.838 +
26.839 + if (dataType != DataBuffer.TYPE_BYTE &&
26.840 + dataType != DataBuffer.TYPE_USHORT &&
26.841 + dataType != DataBuffer.TYPE_INT) {
26.842 + throw new IllegalArgumentException("Unsupported data type " +
26.843 + dataType);
26.844 + }
26.845 +
26.846 + if (dataBuffer.getNumBanks() != 1) {
26.847 + throw new
26.848 + RasterFormatException("DataBuffer for packed Rasters"+
26.849 + " must only have 1 bank.");
26.850 + }
26.851 +
26.852 + MultiPixelPackedSampleModel mppsm =
26.853 + new MultiPixelPackedSampleModel(dataType, w, h, bitsPerPixel);
26.854 +
26.855 + if (dataType == DataBuffer.TYPE_BYTE &&
26.856 + (bitsPerPixel == 1 || bitsPerPixel == 2 || bitsPerPixel == 4)) {
26.857 + return new BytePackedRaster(mppsm, dataBuffer, location);
26.858 + } else {
26.859 + return new SunWritableRaster(mppsm, dataBuffer, location);
26.860 + }
26.861 + }
26.862 +
26.863 +
26.864 + /**
26.865 + * Creates a Raster with the specified SampleModel and DataBuffer.
26.866 + * The upper left corner of the Raster is given by the location argument.
26.867 + * If location is null, (0, 0) will be used.
26.868 + * @param sm the specified <code>SampleModel</code>
26.869 + * @param db the specified <code>DataBuffer</code>
26.870 + * @param location the upper-left corner of the <code>Raster</code>
26.871 + * @return a <code>Raster</code> with the specified
26.872 + * <code>SampleModel</code>, <code>DataBuffer</code>, and
26.873 + * location.
26.874 + * @throws RasterFormatException if computing either
26.875 + * <code>location.x + sm.getWidth()</code> or
26.876 + * <code>location.y + sm.getHeight()</code> results in integer
26.877 + * overflow
26.878 + * @throws RasterFormatException if <code>db</code> has more
26.879 + * than one bank and <code>sm</code> is a
26.880 + * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
26.881 + * or MultiPixelPackedSampleModel.
26.882 + * @throws NullPointerException if either SampleModel or DataBuffer is
26.883 + * null
26.884 + */
26.885 + public static Raster createRaster(SampleModel sm,
26.886 + DataBuffer db,
26.887 + Point location) {
26.888 + if ((sm == null) || (db == null)) {
26.889 + throw new NullPointerException("SampleModel and DataBuffer cannot be null");
26.890 + }
26.891 +
26.892 + if (location == null) {
26.893 + location = new Point(0,0);
26.894 + }
26.895 + int dataType = sm.getDataType();
26.896 +
26.897 + if (sm instanceof PixelInterleavedSampleModel) {
26.898 + switch(dataType) {
26.899 + case DataBuffer.TYPE_BYTE:
26.900 + return new ByteInterleavedRaster(sm, db, location);
26.901 +
26.902 + case DataBuffer.TYPE_USHORT:
26.903 + return new ShortInterleavedRaster(sm, db, location);
26.904 + }
26.905 + } else if (sm instanceof SinglePixelPackedSampleModel) {
26.906 + switch(dataType) {
26.907 + case DataBuffer.TYPE_BYTE:
26.908 + return new ByteInterleavedRaster(sm, db, location);
26.909 +
26.910 + case DataBuffer.TYPE_USHORT:
26.911 + return new ShortInterleavedRaster(sm, db, location);
26.912 +
26.913 + case DataBuffer.TYPE_INT:
26.914 + return new IntegerInterleavedRaster(sm, db, location);
26.915 + }
26.916 + } else if (sm instanceof MultiPixelPackedSampleModel &&
26.917 + dataType == DataBuffer.TYPE_BYTE &&
26.918 + sm.getSampleSize(0) < 8) {
26.919 + return new BytePackedRaster(sm, db, location);
26.920 + }
26.921 +
26.922 + // we couldn't do anything special - do the generic thing
26.923 +
26.924 + return new Raster(sm,db,location);
26.925 + }
26.926 +
26.927 + /**
26.928 + * Creates a WritableRaster with the specified SampleModel.
26.929 + * The upper left corner of the Raster is given by the location argument.
26.930 + * If location is null, (0, 0) will be used.
26.931 + * @param sm the specified <code>SampleModel</code>
26.932 + * @param location the upper-left corner of the
26.933 + * <code>WritableRaster</code>
26.934 + * @return a <code>WritableRaster</code> with the specified
26.935 + * <code>SampleModel</code> and location.
26.936 + * @throws RasterFormatException if computing either
26.937 + * <code>location.x + sm.getWidth()</code> or
26.938 + * <code>location.y + sm.getHeight()</code> results in integer
26.939 + * overflow
26.940 + */
26.941 + public static WritableRaster createWritableRaster(SampleModel sm,
26.942 + Point location) {
26.943 + if (location == null) {
26.944 + location = new Point(0,0);
26.945 + }
26.946 +
26.947 + return createWritableRaster(sm, sm.createDataBuffer(), location);
26.948 + }
26.949 +
26.950 + /**
26.951 + * Creates a WritableRaster with the specified SampleModel and DataBuffer.
26.952 + * The upper left corner of the Raster is given by the location argument.
26.953 + * If location is null, (0, 0) will be used.
26.954 + * @param sm the specified <code>SampleModel</code>
26.955 + * @param db the specified <code>DataBuffer</code>
26.956 + * @param location the upper-left corner of the
26.957 + * <code>WritableRaster</code>
26.958 + * @return a <code>WritableRaster</code> with the specified
26.959 + * <code>SampleModel</code>, <code>DataBuffer</code>, and
26.960 + * location.
26.961 + * @throws RasterFormatException if computing either
26.962 + * <code>location.x + sm.getWidth()</code> or
26.963 + * <code>location.y + sm.getHeight()</code> results in integer
26.964 + * overflow
26.965 + * @throws RasterFormatException if <code>db</code> has more
26.966 + * than one bank and <code>sm</code> is a
26.967 + * PixelInterleavedSampleModel, SinglePixelPackedSampleModel,
26.968 + * or MultiPixelPackedSampleModel.
26.969 + * @throws NullPointerException if either SampleModel or DataBuffer is null
26.970 + */
26.971 + public static WritableRaster createWritableRaster(SampleModel sm,
26.972 + DataBuffer db,
26.973 + Point location) {
26.974 + if ((sm == null) || (db == null)) {
26.975 + throw new NullPointerException("SampleModel and DataBuffer cannot be null");
26.976 + }
26.977 + if (location == null) {
26.978 + location = new Point(0,0);
26.979 + }
26.980 +
26.981 + int dataType = sm.getDataType();
26.982 +
26.983 + if (sm instanceof PixelInterleavedSampleModel) {
26.984 + switch(dataType) {
26.985 + case DataBuffer.TYPE_BYTE:
26.986 + return new ByteInterleavedRaster(sm, db, location);
26.987 +
26.988 + case DataBuffer.TYPE_USHORT:
26.989 + return new ShortInterleavedRaster(sm, db, location);
26.990 + }
26.991 + } else if (sm instanceof SinglePixelPackedSampleModel) {
26.992 + switch(dataType) {
26.993 + case DataBuffer.TYPE_BYTE:
26.994 + return new ByteInterleavedRaster(sm, db, location);
26.995 +
26.996 + case DataBuffer.TYPE_USHORT:
26.997 + return new ShortInterleavedRaster(sm, db, location);
26.998 +
26.999 + case DataBuffer.TYPE_INT:
26.1000 + return new IntegerInterleavedRaster(sm, db, location);
26.1001 + }
26.1002 + } else if (sm instanceof MultiPixelPackedSampleModel &&
26.1003 + dataType == DataBuffer.TYPE_BYTE &&
26.1004 + sm.getSampleSize(0) < 8) {
26.1005 + return new BytePackedRaster(sm, db, location);
26.1006 + }
26.1007 +
26.1008 + // we couldn't do anything special - do the generic thing
26.1009 +
26.1010 + return new SunWritableRaster(sm,db,location);
26.1011 + }
26.1012 +
26.1013 + /**
26.1014 + * Constructs a Raster with the given SampleModel. The Raster's
26.1015 + * upper left corner is origin and it is the same size as the
26.1016 + * SampleModel. A DataBuffer large enough to describe the
26.1017 + * Raster is automatically created.
26.1018 + * @param sampleModel The SampleModel that specifies the layout
26.1019 + * @param origin The Point that specified the origin
26.1020 + * @throws RasterFormatException if computing either
26.1021 + * <code>origin.x + sampleModel.getWidth()</code> or
26.1022 + * <code>origin.y + sampleModel.getHeight()</code> results in
26.1023 + * integer overflow
26.1024 + * @throws NullPointerException either <code>sampleModel</code> or
26.1025 + * <code>origin</code> is null
26.1026 + */
26.1027 + protected Raster(SampleModel sampleModel,
26.1028 + Point origin) {
26.1029 + this(sampleModel,
26.1030 + sampleModel.createDataBuffer(),
26.1031 + new Rectangle(origin.x,
26.1032 + origin.y,
26.1033 + sampleModel.getWidth(),
26.1034 + sampleModel.getHeight()),
26.1035 + origin,
26.1036 + null);
26.1037 + }
26.1038 +
26.1039 + /**
26.1040 + * Constructs a Raster with the given SampleModel and DataBuffer.
26.1041 + * The Raster's upper left corner is origin and it is the same size
26.1042 + * as the SampleModel. The DataBuffer is not initialized and must
26.1043 + * be compatible with SampleModel.
26.1044 + * @param sampleModel The SampleModel that specifies the layout
26.1045 + * @param dataBuffer The DataBuffer that contains the image data
26.1046 + * @param origin The Point that specifies the origin
26.1047 + * @throws RasterFormatException if computing either
26.1048 + * <code>origin.x + sampleModel.getWidth()</code> or
26.1049 + * <code>origin.y + sampleModel.getHeight()</code> results in
26.1050 + * integer overflow
26.1051 + * @throws NullPointerException either <code>sampleModel</code> or
26.1052 + * <code>origin</code> is null
26.1053 + */
26.1054 + protected Raster(SampleModel sampleModel,
26.1055 + DataBuffer dataBuffer,
26.1056 + Point origin) {
26.1057 + this(sampleModel,
26.1058 + dataBuffer,
26.1059 + new Rectangle(origin.x,
26.1060 + origin.y,
26.1061 + sampleModel.getWidth(),
26.1062 + sampleModel.getHeight()),
26.1063 + origin,
26.1064 + null);
26.1065 + }
26.1066 +
26.1067 + /**
26.1068 + * Constructs a Raster with the given SampleModel, DataBuffer, and
26.1069 + * parent. aRegion specifies the bounding rectangle of the new
26.1070 + * Raster. When translated into the base Raster's coordinate
26.1071 + * system, aRegion must be contained by the base Raster.
26.1072 + * (The base Raster is the Raster's ancestor which has no parent.)
26.1073 + * sampleModelTranslate specifies the sampleModelTranslateX and
26.1074 + * sampleModelTranslateY values of the new Raster.
26.1075 + *
26.1076 + * Note that this constructor should generally be called by other
26.1077 + * constructors or create methods, it should not be used directly.
26.1078 + * @param sampleModel The SampleModel that specifies the layout
26.1079 + * @param dataBuffer The DataBuffer that contains the image data
26.1080 + * @param aRegion The Rectangle that specifies the image area
26.1081 + * @param sampleModelTranslate The Point that specifies the translation
26.1082 + * from SampleModel to Raster coordinates
26.1083 + * @param parent The parent (if any) of this raster
26.1084 + * @throws NullPointerException if any of <code>sampleModel</code>,
26.1085 + * <code>dataBuffer</code>, <code>aRegion</code> or
26.1086 + * <code>sampleModelTranslate</code> is null
26.1087 + * @throws RasterFormatException if <code>aRegion</code> has width
26.1088 + * or height less than or equal to zero, or computing either
26.1089 + * <code>aRegion.x + aRegion.width</code> or
26.1090 + * <code>aRegion.y + aRegion.height</code> results in integer
26.1091 + * overflow
26.1092 + */
26.1093 + protected Raster(SampleModel sampleModel,
26.1094 + DataBuffer dataBuffer,
26.1095 + Rectangle aRegion,
26.1096 + Point sampleModelTranslate,
26.1097 + Raster parent) {
26.1098 +
26.1099 + if ((sampleModel == null) || (dataBuffer == null) ||
26.1100 + (aRegion == null) || (sampleModelTranslate == null)) {
26.1101 + throw new NullPointerException("SampleModel, dataBuffer, aRegion and " +
26.1102 + "sampleModelTranslate cannot be null");
26.1103 + }
26.1104 + this.sampleModel = sampleModel;
26.1105 + this.dataBuffer = dataBuffer;
26.1106 + minX = aRegion.x;
26.1107 + minY = aRegion.y;
26.1108 + width = aRegion.width;
26.1109 + height = aRegion.height;
26.1110 + if (width <= 0 || height <= 0) {
26.1111 + throw new RasterFormatException("negative or zero " +
26.1112 + ((width <= 0) ? "width" : "height"));
26.1113 + }
26.1114 + if ((minX + width) < minX) {
26.1115 + throw new RasterFormatException(
26.1116 + "overflow condition for X coordinates of Raster");
26.1117 + }
26.1118 + if ((minY + height) < minY) {
26.1119 + throw new RasterFormatException(
26.1120 + "overflow condition for Y coordinates of Raster");
26.1121 + }
26.1122 +
26.1123 + sampleModelTranslateX = sampleModelTranslate.x;
26.1124 + sampleModelTranslateY = sampleModelTranslate.y;
26.1125 +
26.1126 + numBands = sampleModel.getNumBands();
26.1127 + numDataElements = sampleModel.getNumDataElements();
26.1128 + this.parent = parent;
26.1129 + }
26.1130 +
26.1131 +
26.1132 + /**
26.1133 + * Returns the parent Raster (if any) of this Raster or null.
26.1134 + * @return the parent Raster or <code>null</code>.
26.1135 + */
26.1136 + public Raster getParent() {
26.1137 + return parent;
26.1138 + }
26.1139 +
26.1140 + /**
26.1141 + * Returns the X translation from the coordinate system of the
26.1142 + * SampleModel to that of the Raster. To convert a pixel's X
26.1143 + * coordinate from the Raster coordinate system to the SampleModel
26.1144 + * coordinate system, this value must be subtracted.
26.1145 + * @return the X translation from the coordinate space of the
26.1146 + * Raster's SampleModel to that of the Raster.
26.1147 + */
26.1148 + final public int getSampleModelTranslateX() {
26.1149 + return sampleModelTranslateX;
26.1150 + }
26.1151 +
26.1152 + /**
26.1153 + * Returns the Y translation from the coordinate system of the
26.1154 + * SampleModel to that of the Raster. To convert a pixel's Y
26.1155 + * coordinate from the Raster coordinate system to the SampleModel
26.1156 + * coordinate system, this value must be subtracted.
26.1157 + * @return the Y translation from the coordinate space of the
26.1158 + * Raster's SampleModel to that of the Raster.
26.1159 + */
26.1160 + final public int getSampleModelTranslateY() {
26.1161 + return sampleModelTranslateY;
26.1162 + }
26.1163 +
26.1164 + /**
26.1165 + * Create a compatible WritableRaster the same size as this Raster with
26.1166 + * the same SampleModel and a new initialized DataBuffer.
26.1167 + * @return a compatible <code>WritableRaster</code> with the same sample
26.1168 + * model and a new data buffer.
26.1169 + */
26.1170 + public WritableRaster createCompatibleWritableRaster() {
26.1171 + return new SunWritableRaster(sampleModel, new Point(0,0));
26.1172 + }
26.1173 +
26.1174 + /**
26.1175 + * Create a compatible WritableRaster with the specified size, a new
26.1176 + * SampleModel, and a new initialized DataBuffer.
26.1177 + * @param w the specified width of the new <code>WritableRaster</code>
26.1178 + * @param h the specified height of the new <code>WritableRaster</code>
26.1179 + * @return a compatible <code>WritableRaster</code> with the specified
26.1180 + * size and a new sample model and data buffer.
26.1181 + * @exception RasterFormatException if the width or height is less than
26.1182 + * or equal to zero.
26.1183 + */
26.1184 + public WritableRaster createCompatibleWritableRaster(int w, int h) {
26.1185 + if (w <= 0 || h <=0) {
26.1186 + throw new RasterFormatException("negative " +
26.1187 + ((w <= 0) ? "width" : "height"));
26.1188 + }
26.1189 +
26.1190 + SampleModel sm = sampleModel.createCompatibleSampleModel(w,h);
26.1191 +
26.1192 + return new SunWritableRaster(sm, new Point(0,0));
26.1193 + }
26.1194 +
26.1195 + /**
26.1196 + * Create a compatible WritableRaster with location (minX, minY)
26.1197 + * and size (width, height) specified by rect, a
26.1198 + * new SampleModel, and a new initialized DataBuffer.
26.1199 + * @param rect a <code>Rectangle</code> that specifies the size and
26.1200 + * location of the <code>WritableRaster</code>
26.1201 + * @return a compatible <code>WritableRaster</code> with the specified
26.1202 + * size and location and a new sample model and data buffer.
26.1203 + * @throws RasterFormatException if <code>rect</code> has width
26.1204 + * or height less than or equal to zero, or computing either
26.1205 + * <code>rect.x + rect.width</code> or
26.1206 + * <code>rect.y + rect.height</code> results in integer
26.1207 + * overflow
26.1208 + * @throws NullPointerException if <code>rect</code> is null
26.1209 + */
26.1210 + public WritableRaster createCompatibleWritableRaster(Rectangle rect) {
26.1211 + if (rect == null) {
26.1212 + throw new NullPointerException("Rect cannot be null");
26.1213 + }
26.1214 + return createCompatibleWritableRaster(rect.x, rect.y,
26.1215 + rect.width, rect.height);
26.1216 + }
26.1217 +
26.1218 + /**
26.1219 + * Create a compatible WritableRaster with the specified
26.1220 + * location (minX, minY) and size (width, height), a
26.1221 + * new SampleModel, and a new initialized DataBuffer.
26.1222 + * @param x the X coordinate of the upper-left corner of
26.1223 + * the <code>WritableRaster</code>
26.1224 + * @param y the Y coordinate of the upper-left corner of
26.1225 + * the <code>WritableRaster</code>
26.1226 + * @param w the specified width of the <code>WritableRaster</code>
26.1227 + * @param h the specified height of the <code>WritableRaster</code>
26.1228 + * @return a compatible <code>WritableRaster</code> with the specified
26.1229 + * size and location and a new sample model and data buffer.
26.1230 + * @throws RasterFormatException if <code>w</code> or <code>h</code>
26.1231 + * is less than or equal to zero, or computing either
26.1232 + * <code>x + w</code> or
26.1233 + * <code>y + h</code> results in integer
26.1234 + * overflow
26.1235 + */
26.1236 + public WritableRaster createCompatibleWritableRaster(int x, int y,
26.1237 + int w, int h) {
26.1238 + WritableRaster ret = createCompatibleWritableRaster(w, h);
26.1239 + return ret.createWritableChild(0,0,w,h,x,y,null);
26.1240 + }
26.1241 +
26.1242 + /**
26.1243 + * Create a Raster with the same size, SampleModel and DataBuffer
26.1244 + * as this one, but with a different location. The new Raster
26.1245 + * will possess a reference to the current Raster, accessible
26.1246 + * through its getParent() method.
26.1247 + *
26.1248 + * @param childMinX the X coordinate of the upper-left
26.1249 + * corner of the new <code>Raster</code>
26.1250 + * @param childMinY the Y coordinate of the upper-left
26.1251 + * corner of the new <code>Raster</code>
26.1252 + * @return a new <code>Raster</code> with the same size, SampleModel,
26.1253 + * and DataBuffer as this <code>Raster</code>, but with the
26.1254 + * specified location.
26.1255 + * @throws RasterFormatException if computing either
26.1256 + * <code>childMinX + this.getWidth()</code> or
26.1257 + * <code>childMinY + this.getHeight()</code> results in integer
26.1258 + * overflow
26.1259 + */
26.1260 + public Raster createTranslatedChild(int childMinX, int childMinY) {
26.1261 + return createChild(minX,minY,width,height,
26.1262 + childMinX,childMinY,null);
26.1263 + }
26.1264 +
26.1265 + /**
26.1266 + * Returns a new Raster which shares all or part of this Raster's
26.1267 + * DataBuffer. The new Raster will possess a reference to the
26.1268 + * current Raster, accessible through its getParent() method.
26.1269 + *
26.1270 + * <p> The parentX, parentY, width and height parameters
26.1271 + * form a Rectangle in this Raster's coordinate space,
26.1272 + * indicating the area of pixels to be shared. An error will
26.1273 + * be thrown if this Rectangle is not contained with the bounds
26.1274 + * of the current Raster.
26.1275 + *
26.1276 + * <p> The new Raster may additionally be translated to a
26.1277 + * different coordinate system for the plane than that used by the current
26.1278 + * Raster. The childMinX and childMinY parameters give the new
26.1279 + * (x, y) coordinate of the upper-left pixel of the returned
26.1280 + * Raster; the coordinate (childMinX, childMinY) in the new Raster
26.1281 + * will map to the same pixel as the coordinate (parentX, parentY)
26.1282 + * in the current Raster.
26.1283 + *
26.1284 + * <p> The new Raster may be defined to contain only a subset of
26.1285 + * the bands of the current Raster, possibly reordered, by means
26.1286 + * of the bandList parameter. If bandList is null, it is taken to
26.1287 + * include all of the bands of the current Raster in their current
26.1288 + * order.
26.1289 + *
26.1290 + * <p> To create a new Raster that contains a subregion of the current
26.1291 + * Raster, but shares its coordinate system and bands,
26.1292 + * this method should be called with childMinX equal to parentX,
26.1293 + * childMinY equal to parentY, and bandList equal to null.
26.1294 + *
26.1295 + * @param parentX The X coordinate of the upper-left corner
26.1296 + * in this Raster's coordinates
26.1297 + * @param parentY The Y coordinate of the upper-left corner
26.1298 + * in this Raster's coordinates
26.1299 + * @param width Width of the region starting at (parentX, parentY)
26.1300 + * @param height Height of the region starting at (parentX, parentY).
26.1301 + * @param childMinX The X coordinate of the upper-left corner
26.1302 + * of the returned Raster
26.1303 + * @param childMinY The Y coordinate of the upper-left corner
26.1304 + * of the returned Raster
26.1305 + * @param bandList Array of band indices, or null to use all bands
26.1306 + * @return a new <code>Raster</code>.
26.1307 + * @exception RasterFormatException if the specified subregion is outside
26.1308 + * of the raster bounds.
26.1309 + * @throws RasterFormatException if <code>width</code> or
26.1310 + * <code>height</code>
26.1311 + * is less than or equal to zero, or computing any of
26.1312 + * <code>parentX + width</code>, <code>parentY + height</code>,
26.1313 + * <code>childMinX + width</code>, or
26.1314 + * <code>childMinY + height</code> results in integer
26.1315 + * overflow
26.1316 + */
26.1317 + public Raster createChild(int parentX, int parentY,
26.1318 + int width, int height,
26.1319 + int childMinX, int childMinY,
26.1320 + int bandList[]) {
26.1321 + if (parentX < this.minX) {
26.1322 + throw new RasterFormatException("parentX lies outside raster");
26.1323 + }
26.1324 + if (parentY < this.minY) {
26.1325 + throw new RasterFormatException("parentY lies outside raster");
26.1326 + }
26.1327 + if ((parentX + width < parentX) ||
26.1328 + (parentX + width > this.width + this.minX)) {
26.1329 + throw new RasterFormatException("(parentX + width) is outside raster");
26.1330 + }
26.1331 + if ((parentY + height < parentY) ||
26.1332 + (parentY + height > this.height + this.minY)) {
26.1333 + throw new RasterFormatException("(parentY + height) is outside raster");
26.1334 + }
26.1335 +
26.1336 + SampleModel subSampleModel;
26.1337 + // Note: the SampleModel for the child Raster should have the same
26.1338 + // width and height as that for the parent, since it represents
26.1339 + // the physical layout of the pixel data. The child Raster's width
26.1340 + // and height represent a "virtual" view of the pixel data, so
26.1341 + // they may be different than those of the SampleModel.
26.1342 + if (bandList == null) {
26.1343 + subSampleModel = sampleModel;
26.1344 + } else {
26.1345 + subSampleModel = sampleModel.createSubsetSampleModel(bandList);
26.1346 + }
26.1347 +
26.1348 + int deltaX = childMinX - parentX;
26.1349 + int deltaY = childMinY - parentY;
26.1350 +
26.1351 + return new Raster(subSampleModel, getDataBuffer(),
26.1352 + new Rectangle(childMinX, childMinY, width, height),
26.1353 + new Point(sampleModelTranslateX + deltaX,
26.1354 + sampleModelTranslateY + deltaY), this);
26.1355 + }
26.1356 +
26.1357 + /**
26.1358 + * Returns the bounding Rectangle of this Raster. This function returns
26.1359 + * the same information as getMinX/MinY/Width/Height.
26.1360 + * @return the bounding box of this <code>Raster</code>.
26.1361 + */
26.1362 + public Rectangle getBounds() {
26.1363 + return new Rectangle(minX, minY, width, height);
26.1364 + }
26.1365 +
26.1366 + /** Returns the minimum valid X coordinate of the Raster.
26.1367 + * @return the minimum x coordinate of this <code>Raster</code>.
26.1368 + */
26.1369 + final public int getMinX() {
26.1370 + return minX;
26.1371 + }
26.1372 +
26.1373 + /** Returns the minimum valid Y coordinate of the Raster.
26.1374 + * @return the minimum y coordinate of this <code>Raster</code>.
26.1375 + */
26.1376 + final public int getMinY() {
26.1377 + return minY;
26.1378 + }
26.1379 +
26.1380 + /** Returns the width in pixels of the Raster.
26.1381 + * @return the width of this <code>Raster</code>.
26.1382 + */
26.1383 + final public int getWidth() {
26.1384 + return width;
26.1385 + }
26.1386 +
26.1387 + /** Returns the height in pixels of the Raster.
26.1388 + * @return the height of this <code>Raster</code>.
26.1389 + */
26.1390 + final public int getHeight() {
26.1391 + return height;
26.1392 + }
26.1393 +
26.1394 + /** Returns the number of bands (samples per pixel) in this Raster.
26.1395 + * @return the number of bands of this <code>Raster</code>.
26.1396 + */
26.1397 + final public int getNumBands() {
26.1398 + return numBands;
26.1399 + }
26.1400 +
26.1401 + /**
26.1402 + * Returns the number of data elements needed to transfer one pixel
26.1403 + * via the getDataElements and setDataElements methods. When pixels
26.1404 + * are transferred via these methods, they may be transferred in a
26.1405 + * packed or unpacked format, depending on the implementation of the
26.1406 + * underlying SampleModel. Using these methods, pixels are transferred
26.1407 + * as an array of getNumDataElements() elements of a primitive type given
26.1408 + * by getTransferType(). The TransferType may or may not be the same
26.1409 + * as the storage data type of the DataBuffer.
26.1410 + * @return the number of data elements.
26.1411 + */
26.1412 + final public int getNumDataElements() {
26.1413 + return sampleModel.getNumDataElements();
26.1414 + }
26.1415 +
26.1416 + /**
26.1417 + * Returns the TransferType used to transfer pixels via the
26.1418 + * getDataElements and setDataElements methods. When pixels
26.1419 + * are transferred via these methods, they may be transferred in a
26.1420 + * packed or unpacked format, depending on the implementation of the
26.1421 + * underlying SampleModel. Using these methods, pixels are transferred
26.1422 + * as an array of getNumDataElements() elements of a primitive type given
26.1423 + * by getTransferType(). The TransferType may or may not be the same
26.1424 + * as the storage data type of the DataBuffer. The TransferType will
26.1425 + * be one of the types defined in DataBuffer.
26.1426 + * @return this transfer type.
26.1427 + */
26.1428 + final public int getTransferType() {
26.1429 + return sampleModel.getTransferType();
26.1430 + }
26.1431 +
26.1432 + /** Returns the DataBuffer associated with this Raster.
26.1433 + * @return the <code>DataBuffer</code> of this <code>Raster</code>.
26.1434 + */
26.1435 + public DataBuffer getDataBuffer() {
26.1436 + return dataBuffer;
26.1437 + }
26.1438 +
26.1439 + /** Returns the SampleModel that describes the layout of the image data.
26.1440 + * @return the <code>SampleModel</code> of this <code>Raster</code>.
26.1441 + */
26.1442 + public SampleModel getSampleModel() {
26.1443 + return sampleModel;
26.1444 + }
26.1445 +
26.1446 + /**
26.1447 + * Returns data for a single pixel in a primitive array of type
26.1448 + * TransferType. For image data supported by the Java 2D(tm) API,
26.1449 + * this will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
26.1450 + * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
26.1451 + * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
26.1452 + * thus increasing efficiency for data transfers.
26.1453 + * An ArrayIndexOutOfBoundsException may be thrown
26.1454 + * if the coordinates are not in bounds. However, explicit bounds
26.1455 + * checking is not guaranteed.
26.1456 + * A ClassCastException will be thrown if the input object is non null
26.1457 + * and references anything other than an array of TransferType.
26.1458 + * @see java.awt.image.SampleModel#getDataElements(int, int, Object, DataBuffer)
26.1459 + * @param x The X coordinate of the pixel location
26.1460 + * @param y The Y coordinate of the pixel location
26.1461 + * @param outData An object reference to an array of type defined by
26.1462 + * getTransferType() and length getNumDataElements().
26.1463 + * If null, an array of appropriate type and size will be
26.1464 + * allocated
26.1465 + * @return An object reference to an array of type defined by
26.1466 + * getTransferType() with the requested pixel data.
26.1467 + *
26.1468 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1469 + * in bounds, or if outData is too small to hold the output.
26.1470 + */
26.1471 + public Object getDataElements(int x, int y, Object outData) {
26.1472 + return sampleModel.getDataElements(x - sampleModelTranslateX,
26.1473 + y - sampleModelTranslateY,
26.1474 + outData, dataBuffer);
26.1475 + }
26.1476 +
26.1477 + /**
26.1478 + * Returns the pixel data for the specified rectangle of pixels in a
26.1479 + * primitive array of type TransferType.
26.1480 + * For image data supported by the Java 2D API, this
26.1481 + * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
26.1482 + * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
26.1483 + * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
26.1484 + * thus increasing efficiency for data transfers.
26.1485 + * An ArrayIndexOutOfBoundsException may be thrown
26.1486 + * if the coordinates are not in bounds. However, explicit bounds
26.1487 + * checking is not guaranteed.
26.1488 + * A ClassCastException will be thrown if the input object is non null
26.1489 + * and references anything other than an array of TransferType.
26.1490 + * @see java.awt.image.SampleModel#getDataElements(int, int, int, int, Object, DataBuffer)
26.1491 + * @param x The X coordinate of the upper-left pixel location
26.1492 + * @param y The Y coordinate of the upper-left pixel location
26.1493 + * @param w Width of the pixel rectangle
26.1494 + * @param h Height of the pixel rectangle
26.1495 + * @param outData An object reference to an array of type defined by
26.1496 + * getTransferType() and length w*h*getNumDataElements().
26.1497 + * If null, an array of appropriate type and size will be
26.1498 + * allocated.
26.1499 + * @return An object reference to an array of type defined by
26.1500 + * getTransferType() with the requested pixel data.
26.1501 + *
26.1502 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1503 + * in bounds, or if outData is too small to hold the output.
26.1504 + */
26.1505 + public Object getDataElements(int x, int y, int w, int h, Object outData) {
26.1506 + return sampleModel.getDataElements(x - sampleModelTranslateX,
26.1507 + y - sampleModelTranslateY,
26.1508 + w, h, outData, dataBuffer);
26.1509 + }
26.1510 +
26.1511 + /**
26.1512 + * Returns the samples in an array of int for the specified pixel.
26.1513 + * An ArrayIndexOutOfBoundsException may be thrown
26.1514 + * if the coordinates are not in bounds. However, explicit bounds
26.1515 + * checking is not guaranteed.
26.1516 + * @param x The X coordinate of the pixel location
26.1517 + * @param y The Y coordinate of the pixel location
26.1518 + * @param iArray An optionally preallocated int array
26.1519 + * @return the samples for the specified pixel.
26.1520 + *
26.1521 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1522 + * in bounds, or if iArray is too small to hold the output.
26.1523 + */
26.1524 + public int[] getPixel(int x, int y, int iArray[]) {
26.1525 + return sampleModel.getPixel(x - sampleModelTranslateX,
26.1526 + y - sampleModelTranslateY,
26.1527 + iArray, dataBuffer);
26.1528 + }
26.1529 +
26.1530 + /**
26.1531 + * Returns the samples in an array of float for the
26.1532 + * specified pixel.
26.1533 + * An ArrayIndexOutOfBoundsException may be thrown
26.1534 + * if the coordinates are not in bounds. However, explicit bounds
26.1535 + * checking is not guaranteed.
26.1536 + * @param x The X coordinate of the pixel location
26.1537 + * @param y The Y coordinate of the pixel location
26.1538 + * @param fArray An optionally preallocated float array
26.1539 + * @return the samples for the specified pixel.
26.1540 + *
26.1541 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1542 + * in bounds, or if fArray is too small to hold the output.
26.1543 + */
26.1544 + public float[] getPixel(int x, int y, float fArray[]) {
26.1545 + return sampleModel.getPixel(x - sampleModelTranslateX,
26.1546 + y - sampleModelTranslateY,
26.1547 + fArray, dataBuffer);
26.1548 + }
26.1549 +
26.1550 + /**
26.1551 + * Returns the samples in an array of double for the specified pixel.
26.1552 + * An ArrayIndexOutOfBoundsException may be thrown
26.1553 + * if the coordinates are not in bounds. However, explicit bounds
26.1554 + * checking is not guaranteed.
26.1555 + * @param x The X coordinate of the pixel location
26.1556 + * @param y The Y coordinate of the pixel location
26.1557 + * @param dArray An optionally preallocated double array
26.1558 + * @return the samples for the specified pixel.
26.1559 + *
26.1560 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1561 + * in bounds, or if dArray is too small to hold the output.
26.1562 + */
26.1563 + public double[] getPixel(int x, int y, double dArray[]) {
26.1564 + return sampleModel.getPixel(x - sampleModelTranslateX,
26.1565 + y - sampleModelTranslateY,
26.1566 + dArray, dataBuffer);
26.1567 + }
26.1568 +
26.1569 + /**
26.1570 + * Returns an int array containing all samples for a rectangle of pixels,
26.1571 + * one sample per array element.
26.1572 + * An ArrayIndexOutOfBoundsException may be thrown
26.1573 + * if the coordinates are not in bounds. However, explicit bounds
26.1574 + * checking is not guaranteed.
26.1575 + * @param x The X coordinate of the upper-left pixel location
26.1576 + * @param y The Y coordinate of the upper-left pixel location
26.1577 + * @param w Width of the pixel rectangle
26.1578 + * @param h Height of the pixel rectangle
26.1579 + * @param iArray An optionally pre-allocated int array
26.1580 + * @return the samples for the specified rectangle of pixels.
26.1581 + *
26.1582 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1583 + * in bounds, or if iArray is too small to hold the output.
26.1584 + */
26.1585 + public int[] getPixels(int x, int y, int w, int h, int iArray[]) {
26.1586 + return sampleModel.getPixels(x - sampleModelTranslateX,
26.1587 + y - sampleModelTranslateY, w, h,
26.1588 + iArray, dataBuffer);
26.1589 + }
26.1590 +
26.1591 + /**
26.1592 + * Returns a float array containing all samples for a rectangle of pixels,
26.1593 + * one sample per array element.
26.1594 + * An ArrayIndexOutOfBoundsException may be thrown
26.1595 + * if the coordinates are not in bounds. However, explicit bounds
26.1596 + * checking is not guaranteed.
26.1597 + * @param x The X coordinate of the pixel location
26.1598 + * @param y The Y coordinate of the pixel location
26.1599 + * @param w Width of the pixel rectangle
26.1600 + * @param h Height of the pixel rectangle
26.1601 + * @param fArray An optionally pre-allocated float array
26.1602 + * @return the samples for the specified rectangle of pixels.
26.1603 + *
26.1604 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1605 + * in bounds, or if fArray is too small to hold the output.
26.1606 + */
26.1607 + public float[] getPixels(int x, int y, int w, int h,
26.1608 + float fArray[]) {
26.1609 + return sampleModel.getPixels(x - sampleModelTranslateX,
26.1610 + y - sampleModelTranslateY, w, h,
26.1611 + fArray, dataBuffer);
26.1612 + }
26.1613 +
26.1614 + /**
26.1615 + * Returns a double array containing all samples for a rectangle of pixels,
26.1616 + * one sample per array element.
26.1617 + * An ArrayIndexOutOfBoundsException may be thrown
26.1618 + * if the coordinates are not in bounds. However, explicit bounds
26.1619 + * checking is not guaranteed.
26.1620 + * @param x The X coordinate of the upper-left pixel location
26.1621 + * @param y The Y coordinate of the upper-left pixel location
26.1622 + * @param w Width of the pixel rectangle
26.1623 + * @param h Height of the pixel rectangle
26.1624 + * @param dArray An optionally pre-allocated double array
26.1625 + * @return the samples for the specified rectangle of pixels.
26.1626 + *
26.1627 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
26.1628 + * in bounds, or if dArray is too small to hold the output.
26.1629 + */
26.1630 + public double[] getPixels(int x, int y, int w, int h,
26.1631 + double dArray[]) {
26.1632 + return sampleModel.getPixels(x - sampleModelTranslateX,
26.1633 + y - sampleModelTranslateY,
26.1634 + w, h, dArray, dataBuffer);
26.1635 + }
26.1636 +
26.1637 +
26.1638 + /**
26.1639 + * Returns the sample in a specified band for the pixel located
26.1640 + * at (x,y) as an int.
26.1641 + * An ArrayIndexOutOfBoundsException may be thrown
26.1642 + * if the coordinates are not in bounds. However, explicit bounds
26.1643 + * checking is not guaranteed.
26.1644 + * @param x The X coordinate of the pixel location
26.1645 + * @param y The Y coordinate of the pixel location
26.1646 + * @param b The band to return
26.1647 + * @return the sample in the specified band for the pixel at the
26.1648 + * specified coordinate.
26.1649 + *
26.1650 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1651 + * the band index are not in bounds.
26.1652 + */
26.1653 + public int getSample(int x, int y, int b) {
26.1654 + return sampleModel.getSample(x - sampleModelTranslateX,
26.1655 + y - sampleModelTranslateY, b,
26.1656 + dataBuffer);
26.1657 + }
26.1658 +
26.1659 + /**
26.1660 + * Returns the sample in a specified band
26.1661 + * for the pixel located at (x,y) as a float.
26.1662 + * An ArrayIndexOutOfBoundsException may be thrown
26.1663 + * if the coordinates are not in bounds. However, explicit bounds
26.1664 + * checking is not guaranteed.
26.1665 + * @param x The X coordinate of the pixel location
26.1666 + * @param y The Y coordinate of the pixel location
26.1667 + * @param b The band to return
26.1668 + * @return the sample in the specified band for the pixel at the
26.1669 + * specified coordinate.
26.1670 + *
26.1671 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1672 + * the band index are not in bounds.
26.1673 + */
26.1674 + public float getSampleFloat(int x, int y, int b) {
26.1675 + return sampleModel.getSampleFloat(x - sampleModelTranslateX,
26.1676 + y - sampleModelTranslateY, b,
26.1677 + dataBuffer);
26.1678 + }
26.1679 +
26.1680 + /**
26.1681 + * Returns the sample in a specified band
26.1682 + * for a pixel located at (x,y) as a double.
26.1683 + * An ArrayIndexOutOfBoundsException may be thrown
26.1684 + * if the coordinates are not in bounds. However, explicit bounds
26.1685 + * checking is not guaranteed.
26.1686 + * @param x The X coordinate of the pixel location
26.1687 + * @param y The Y coordinate of the pixel location
26.1688 + * @param b The band to return
26.1689 + * @return the sample in the specified band for the pixel at the
26.1690 + * specified coordinate.
26.1691 + *
26.1692 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1693 + * the band index are not in bounds.
26.1694 + */
26.1695 + public double getSampleDouble(int x, int y, int b) {
26.1696 + return sampleModel.getSampleDouble(x - sampleModelTranslateX,
26.1697 + y - sampleModelTranslateY,
26.1698 + b, dataBuffer);
26.1699 + }
26.1700 +
26.1701 + /**
26.1702 + * Returns the samples for a specified band for the specified rectangle
26.1703 + * of pixels in an int array, one sample per array element.
26.1704 + * An ArrayIndexOutOfBoundsException may be thrown
26.1705 + * if the coordinates are not in bounds. However, explicit bounds
26.1706 + * checking is not guaranteed.
26.1707 + * @param x The X coordinate of the upper-left pixel location
26.1708 + * @param y The Y coordinate of the upper-left pixel location
26.1709 + * @param w Width of the pixel rectangle
26.1710 + * @param h Height of the pixel rectangle
26.1711 + * @param b The band to return
26.1712 + * @param iArray An optionally pre-allocated int array
26.1713 + * @return the samples for the specified band for the specified
26.1714 + * rectangle of pixels.
26.1715 + *
26.1716 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1717 + * the band index are not in bounds, or if iArray is too small to
26.1718 + * hold the output.
26.1719 + */
26.1720 + public int[] getSamples(int x, int y, int w, int h, int b,
26.1721 + int iArray[]) {
26.1722 + return sampleModel.getSamples(x - sampleModelTranslateX,
26.1723 + y - sampleModelTranslateY,
26.1724 + w, h, b, iArray,
26.1725 + dataBuffer);
26.1726 + }
26.1727 +
26.1728 + /**
26.1729 + * Returns the samples for a specified band for the specified rectangle
26.1730 + * of pixels in a float array, one sample per array element.
26.1731 + * An ArrayIndexOutOfBoundsException may be thrown
26.1732 + * if the coordinates are not in bounds. However, explicit bounds
26.1733 + * checking is not guaranteed.
26.1734 + * @param x The X coordinate of the upper-left pixel location
26.1735 + * @param y The Y coordinate of the upper-left pixel location
26.1736 + * @param w Width of the pixel rectangle
26.1737 + * @param h Height of the pixel rectangle
26.1738 + * @param b The band to return
26.1739 + * @param fArray An optionally pre-allocated float array
26.1740 + * @return the samples for the specified band for the specified
26.1741 + * rectangle of pixels.
26.1742 + *
26.1743 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1744 + * the band index are not in bounds, or if fArray is too small to
26.1745 + * hold the output.
26.1746 + */
26.1747 + public float[] getSamples(int x, int y, int w, int h, int b,
26.1748 + float fArray[]) {
26.1749 + return sampleModel.getSamples(x - sampleModelTranslateX,
26.1750 + y - sampleModelTranslateY,
26.1751 + w, h, b, fArray, dataBuffer);
26.1752 + }
26.1753 +
26.1754 + /**
26.1755 + * Returns the samples for a specified band for a specified rectangle
26.1756 + * of pixels in a double array, one sample per array element.
26.1757 + * An ArrayIndexOutOfBoundsException may be thrown
26.1758 + * if the coordinates are not in bounds. However, explicit bounds
26.1759 + * checking is not guaranteed.
26.1760 + * @param x The X coordinate of the upper-left pixel location
26.1761 + * @param y The Y coordinate of the upper-left pixel location
26.1762 + * @param w Width of the pixel rectangle
26.1763 + * @param h Height of the pixel rectangle
26.1764 + * @param b The band to return
26.1765 + * @param dArray An optionally pre-allocated double array
26.1766 + * @return the samples for the specified band for the specified
26.1767 + * rectangle of pixels.
26.1768 + *
26.1769 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
26.1770 + * the band index are not in bounds, or if dArray is too small to
26.1771 + * hold the output.
26.1772 + */
26.1773 + public double[] getSamples(int x, int y, int w, int h, int b,
26.1774 + double dArray[]) {
26.1775 + return sampleModel.getSamples(x - sampleModelTranslateX,
26.1776 + y - sampleModelTranslateY,
26.1777 + w, h, b, dArray, dataBuffer);
26.1778 + }
26.1779 +
26.1780 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/src/share/classes/java/awt/image/RenderedImage.java Thu Jun 12 11:46:57 2008 -0700
27.3 @@ -0,0 +1,217 @@
27.4 +/*
27.5 + * Portions Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
27.7 + *
27.8 + * This code is free software; you can redistribute it and/or modify it
27.9 + * under the terms of the GNU General Public License version 2 only, as
27.10 + * published by the Free Software Foundation. Sun designates this
27.11 + * particular file as subject to the "Classpath" exception as provided
27.12 + * by Sun in the LICENSE file that accompanied this code.
27.13 + *
27.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
27.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
27.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27.17 + * version 2 for more details (a copy is included in the LICENSE file that
27.18 + * accompanied this code).
27.19 + *
27.20 + * You should have received a copy of the GNU General Public License version
27.21 + * 2 along with this work; if not, write to the Free Software Foundation,
27.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27.23 + *
27.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
27.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
27.26 + * have any questions.
27.27 + */
27.28 +
27.29 +/* ****************************************************************
27.30 + ******************************************************************
27.31 + ******************************************************************
27.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
27.33 + *** As an unpublished work pursuant to Title 17 of the United
27.34 + *** States Code. All rights reserved.
27.35 + ******************************************************************
27.36 + ******************************************************************
27.37 + ******************************************************************/
27.38 +
27.39 +package java.awt.image;
27.40 +import java.awt.Rectangle;
27.41 +import java.util.Dictionary;
27.42 +import java.util.Vector;
27.43 +
27.44 +/**
27.45 + * RenderedImage is a common interface for objects which contain
27.46 + * or can produce image data in the form of Rasters. The image
27.47 + * data may be stored/produced as a single tile or a regular array
27.48 + * of tiles.
27.49 + */
27.50 +
27.51 +public interface RenderedImage {
27.52 +
27.53 + /**
27.54 + * Returns a vector of RenderedImages that are the immediate sources of
27.55 + * image data for this RenderedImage. This method returns null if
27.56 + * the RenderedImage object has no information about its immediate
27.57 + * sources. It returns an empty Vector if the RenderedImage object has
27.58 + * no immediate sources.
27.59 + * @return a Vector of <code>RenderedImage</code> objects.
27.60 + */
27.61 + Vector<RenderedImage> getSources();
27.62 +
27.63 + /**
27.64 + * Gets a property from the property set of this image. The set of
27.65 + * properties and whether it is immutable is determined by the
27.66 + * implementing class. This method returns
27.67 + * java.awt.Image.UndefinedProperty if the specified property is
27.68 + * not defined for this RenderedImage.
27.69 + * @param name the name of the property
27.70 + * @return the property indicated by the specified name.
27.71 + * @see java.awt.Image#UndefinedProperty
27.72 + */
27.73 + Object getProperty(String name);
27.74 +
27.75 + /**
27.76 + * Returns an array of names recognized by
27.77 + * {@link #getProperty(String) getProperty(String)}
27.78 + * or <code>null</code>, if no property names are recognized.
27.79 + * @return a <code>String</code> array containing all of the
27.80 + * property names that <code>getProperty(String)</code> recognizes;
27.81 + * or <code>null</code> if no property names are recognized.
27.82 + */
27.83 + String[] getPropertyNames();
27.84 +
27.85 + /**
27.86 + * Returns the ColorModel associated with this image. All Rasters
27.87 + * returned from this image will have this as their ColorModel. This
27.88 + * can return null.
27.89 + * @return the <code>ColorModel</code> of this image.
27.90 + */
27.91 + ColorModel getColorModel();
27.92 +
27.93 + /**
27.94 + * Returns the SampleModel associated with this image. All Rasters
27.95 + * returned from this image will have this as their SampleModel.
27.96 + * @return the <code>SampleModel</code> of this image.
27.97 + */
27.98 + SampleModel getSampleModel();
27.99 +
27.100 + /**
27.101 + * Returns the width of the RenderedImage.
27.102 + * @return the width of this <code>RenderedImage</code>.
27.103 + */
27.104 + int getWidth();
27.105 +
27.106 + /**
27.107 + * Returns the height of the RenderedImage.
27.108 + * @return the height of this <code>RenderedImage</code>.
27.109 + */
27.110 + int getHeight();
27.111 +
27.112 + /**
27.113 + * Returns the minimum X coordinate (inclusive) of the RenderedImage.
27.114 + * @return the X coordinate of this <code>RenderedImage</code>.
27.115 + */
27.116 + int getMinX();
27.117 +
27.118 + /**
27.119 + * Returns the minimum Y coordinate (inclusive) of the RenderedImage.
27.120 + * @return the Y coordinate of this <code>RenderedImage</code>.
27.121 + */
27.122 + int getMinY();
27.123 +
27.124 + /**
27.125 + * Returns the number of tiles in the X direction.
27.126 + * @return the number of tiles in the X direction.
27.127 + */
27.128 + int getNumXTiles();
27.129 +
27.130 + /**
27.131 + * Returns the number of tiles in the Y direction.
27.132 + * @return the number of tiles in the Y direction.
27.133 + */
27.134 + int getNumYTiles();
27.135 +
27.136 + /**
27.137 + * Returns the minimum tile index in the X direction.
27.138 + * @return the minimum tile index in the X direction.
27.139 + */
27.140 + int getMinTileX();
27.141 +
27.142 + /**
27.143 + * Returns the minimum tile index in the Y direction.
27.144 + * @return the minimum tile index in the X direction.
27.145 + */
27.146 + int getMinTileY();
27.147 +
27.148 + /**
27.149 + * Returns the tile width in pixels. All tiles must have the same
27.150 + * width.
27.151 + * @return the tile width in pixels.
27.152 + */
27.153 + int getTileWidth();
27.154 +
27.155 + /**
27.156 + * Returns the tile height in pixels. All tiles must have the same
27.157 + * height.
27.158 + * @return the tile height in pixels.
27.159 + */
27.160 + int getTileHeight();
27.161 +
27.162 + /**
27.163 + * Returns the X offset of the tile grid relative to the origin,
27.164 + * i.e., the X coordinate of the upper-left pixel of tile (0, 0).
27.165 + * (Note that tile (0, 0) may not actually exist.)
27.166 + * @return the X offset of the tile grid relative to the origin.
27.167 + */
27.168 + int getTileGridXOffset();
27.169 +
27.170 + /**
27.171 + * Returns the Y offset of the tile grid relative to the origin,
27.172 + * i.e., the Y coordinate of the upper-left pixel of tile (0, 0).
27.173 + * (Note that tile (0, 0) may not actually exist.)
27.174 + * @return the Y offset of the tile grid relative to the origin.
27.175 + */
27.176 + int getTileGridYOffset();
27.177 +
27.178 + /**
27.179 + * Returns tile (tileX, tileY). Note that tileX and tileY are indices
27.180 + * into the tile array, not pixel locations. The Raster that is returned
27.181 + * is live and will be updated if the image is changed.
27.182 + * @param tileX the X index of the requested tile in the tile array
27.183 + * @param tileY the Y index of the requested tile in the tile array
27.184 + * @return the tile given the specified indices.
27.185 + */
27.186 + Raster getTile(int tileX, int tileY);
27.187 +
27.188 + /**
27.189 + * Returns the image as one large tile (for tile based
27.190 + * images this will require fetching the whole image
27.191 + * and copying the image data over). The Raster returned is
27.192 + * a copy of the image data and will not be updated if the image
27.193 + * is changed.
27.194 + * @return the image as one large tile.
27.195 + */
27.196 + Raster getData();
27.197 +
27.198 + /**
27.199 + * Computes and returns an arbitrary region of the RenderedImage.
27.200 + * The Raster returned is a copy of the image data and will not
27.201 + * be updated if the image is changed.
27.202 + * @param rect the region of the RenderedImage to be returned.
27.203 + * @return the region of the <code>RenderedImage</code>
27.204 + * indicated by the specified <code>Rectangle</code>.
27.205 + */
27.206 + Raster getData(Rectangle rect);
27.207 +
27.208 + /**
27.209 + * Computes an arbitrary rectangular region of the RenderedImage
27.210 + * and copies it into a caller-supplied WritableRaster. The region
27.211 + * to be computed is determined from the bounds of the supplied
27.212 + * WritableRaster. The supplied WritableRaster must have a
27.213 + * SampleModel that is compatible with this image. If raster is null,
27.214 + * an appropriate WritableRaster is created.
27.215 + * @param raster a WritableRaster to hold the returned portion of the
27.216 + * image, or null.
27.217 + * @return a reference to the supplied or created WritableRaster.
27.218 + */
27.219 + WritableRaster copyData(WritableRaster raster);
27.220 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/src/share/classes/java/awt/image/SampleModel.java Thu Jun 12 11:46:57 2008 -0700
28.3 @@ -0,0 +1,1393 @@
28.4 +/*
28.5 + * Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
28.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
28.7 + *
28.8 + * This code is free software; you can redistribute it and/or modify it
28.9 + * under the terms of the GNU General Public License version 2 only, as
28.10 + * published by the Free Software Foundation. Sun designates this
28.11 + * particular file as subject to the "Classpath" exception as provided
28.12 + * by Sun in the LICENSE file that accompanied this code.
28.13 + *
28.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
28.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
28.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28.17 + * version 2 for more details (a copy is included in the LICENSE file that
28.18 + * accompanied this code).
28.19 + *
28.20 + * You should have received a copy of the GNU General Public License version
28.21 + * 2 along with this work; if not, write to the Free Software Foundation,
28.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28.23 + *
28.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
28.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
28.26 + * have any questions.
28.27 + */
28.28 +
28.29 +/* ****************************************************************
28.30 + ******************************************************************
28.31 + ******************************************************************
28.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
28.33 + *** As an unpublished work pursuant to Title 17 of the United
28.34 + *** States Code. All rights reserved.
28.35 + ******************************************************************
28.36 + ******************************************************************
28.37 + ******************************************************************/
28.38 +
28.39 +package java.awt.image;
28.40 +
28.41 +/**
28.42 + * This abstract class defines an interface for extracting samples of pixels
28.43 + * in an image. All image data is expressed as a collection of pixels.
28.44 + * Each pixel consists of a number of samples. A sample is a datum
28.45 + * for one band of an image and a band consists of all samples of a
28.46 + * particular type in an image. For example, a pixel might contain
28.47 + * three samples representing its red, green and blue components.
28.48 + * There are three bands in the image containing this pixel. One band
28.49 + * consists of all the red samples from all pixels in the
28.50 + * image. The second band consists of all the green samples and
28.51 + * the remaining band consists of all of the blue samples. The pixel
28.52 + * can be stored in various formats. For example, all samples from
28.53 + * a particular band can be stored contiguously or all samples from a
28.54 + * single pixel can be stored contiguously.
28.55 + * <p>
28.56 + * Subclasses of SampleModel specify the types of samples they can
28.57 + * represent (e.g. unsigned 8-bit byte, signed 16-bit short, etc.)
28.58 + * and may specify how the samples are organized in memory.
28.59 + * In the Java 2D(tm) API, built-in image processing operators may
28.60 + * not operate on all possible sample types, but generally will work
28.61 + * for unsigned integral samples of 16 bits or less. Some operators
28.62 + * support a wider variety of sample types.
28.63 + * <p>
28.64 + * A collection of pixels is represented as a Raster, which consists of
28.65 + * a DataBuffer and a SampleModel. The SampleModel allows access to
28.66 + * samples in the DataBuffer and may provide low-level information that
28.67 + * a programmer can use to directly manipulate samples and pixels in the
28.68 + * DataBuffer.
28.69 + * <p>
28.70 + * This class is generally a fall back method for dealing with
28.71 + * images. More efficient code will cast the SampleModel to the
28.72 + * appropriate subclass and extract the information needed to directly
28.73 + * manipulate pixels in the DataBuffer.
28.74 + *
28.75 + * @see java.awt.image.DataBuffer
28.76 + * @see java.awt.image.Raster
28.77 + * @see java.awt.image.ComponentSampleModel
28.78 + * @see java.awt.image.PixelInterleavedSampleModel
28.79 + * @see java.awt.image.BandedSampleModel
28.80 + * @see java.awt.image.MultiPixelPackedSampleModel
28.81 + * @see java.awt.image.SinglePixelPackedSampleModel
28.82 + */
28.83 +
28.84 +public abstract class SampleModel
28.85 +{
28.86 +
28.87 + /** Width in pixels of the region of image data that this SampleModel
28.88 + * describes.
28.89 + */
28.90 + protected int width;
28.91 +
28.92 + /** Height in pixels of the region of image data that this SampleModel
28.93 + * describes.
28.94 + */
28.95 + protected int height;
28.96 +
28.97 + /** Number of bands of the image data that this SampleModel describes. */
28.98 + protected int numBands;
28.99 +
28.100 + /** Data type of the DataBuffer storing the pixel data.
28.101 + * @see java.awt.image.DataBuffer
28.102 + */
28.103 + protected int dataType;
28.104 +
28.105 + static private native void initIDs();
28.106 + static {
28.107 + ColorModel.loadLibraries();
28.108 + initIDs();
28.109 + }
28.110 +
28.111 + /**
28.112 + * Constructs a SampleModel with the specified parameters.
28.113 + * @param dataType The data type of the DataBuffer storing the pixel data.
28.114 + * @param w The width (in pixels) of the region of image data.
28.115 + * @param h The height (in pixels) of the region of image data.
28.116 + * @param numBands The number of bands of the image data.
28.117 + * @throws IllegalArgumentException if <code>w</code> or <code>h</code>
28.118 + * is not greater than 0
28.119 + * @throws IllegalArgumentException if the product of <code>w</code>
28.120 + * and <code>h</code> is greater than
28.121 + * <code>Integer.MAX_VALUE</code>
28.122 + * @throws IllegalArgumentException if <code>dataType</code> is not
28.123 + * one of the supported data types
28.124 + */
28.125 + public SampleModel(int dataType, int w, int h, int numBands)
28.126 + {
28.127 + float size = (float)w*h;
28.128 + if (w <= 0 || h <= 0) {
28.129 + throw new IllegalArgumentException("Width ("+w+") and height ("+
28.130 + h+") must be > 0");
28.131 + }
28.132 + if (size >= Integer.MAX_VALUE) {
28.133 + throw new IllegalArgumentException("Dimensions (width="+w+
28.134 + " height="+h+") are too large");
28.135 + }
28.136 +
28.137 + if (dataType < DataBuffer.TYPE_BYTE ||
28.138 + (dataType > DataBuffer.TYPE_DOUBLE &&
28.139 + dataType != DataBuffer.TYPE_UNDEFINED))
28.140 + {
28.141 + throw new IllegalArgumentException("Unsupported dataType: "+
28.142 + dataType);
28.143 + }
28.144 +
28.145 + if (numBands <= 0) {
28.146 + throw new IllegalArgumentException("Number of bands must be > 0");
28.147 + }
28.148 +
28.149 + this.dataType = dataType;
28.150 + this.width = w;
28.151 + this.height = h;
28.152 + this.numBands = numBands;
28.153 + }
28.154 +
28.155 + /** Returns the width in pixels.
28.156 + * @return the width in pixels of the region of image data
28.157 + * that this <code>SampleModel</code> describes.
28.158 + */
28.159 + final public int getWidth() {
28.160 + return width;
28.161 + }
28.162 +
28.163 + /** Returns the height in pixels.
28.164 + * @return the height in pixels of the region of image data
28.165 + * that this <code>SampleModel</code> describes.
28.166 + */
28.167 + final public int getHeight() {
28.168 + return height;
28.169 + }
28.170 +
28.171 + /** Returns the total number of bands of image data.
28.172 + * @return the number of bands of image data that this
28.173 + * <code>SampleModel</code> describes.
28.174 + */
28.175 + final public int getNumBands() {
28.176 + return numBands;
28.177 + }
28.178 +
28.179 + /** Returns the number of data elements needed to transfer a pixel
28.180 + * via the getDataElements and setDataElements methods. When pixels
28.181 + * are transferred via these methods, they may be transferred in a
28.182 + * packed or unpacked format, depending on the implementation of the
28.183 + * SampleModel. Using these methods, pixels are transferred as an
28.184 + * array of getNumDataElements() elements of a primitive type given
28.185 + * by getTransferType(). The TransferType may or may not be the same
28.186 + * as the storage DataType.
28.187 + * @return the number of data elements.
28.188 + * @see #getDataElements(int, int, Object, DataBuffer)
28.189 + * @see #getDataElements(int, int, int, int, Object, DataBuffer)
28.190 + * @see #setDataElements(int, int, Object, DataBuffer)
28.191 + * @see #setDataElements(int, int, int, int, Object, DataBuffer)
28.192 + * @see #getTransferType
28.193 + */
28.194 + public abstract int getNumDataElements();
28.195 +
28.196 + /** Returns the data type of the DataBuffer storing the pixel data.
28.197 + * @return the data type.
28.198 + */
28.199 + final public int getDataType() {
28.200 + return dataType;
28.201 + }
28.202 +
28.203 + /** Returns the TransferType used to transfer pixels via the
28.204 + * getDataElements and setDataElements methods. When pixels
28.205 + * are transferred via these methods, they may be transferred in a
28.206 + * packed or unpacked format, depending on the implementation of the
28.207 + * SampleModel. Using these methods, pixels are transferred as an
28.208 + * array of getNumDataElements() elements of a primitive type given
28.209 + * by getTransferType(). The TransferType may or may not be the same
28.210 + * as the storage DataType. The TransferType will be one of the types
28.211 + * defined in DataBuffer.
28.212 + * @return the transfer type.
28.213 + * @see #getDataElements(int, int, Object, DataBuffer)
28.214 + * @see #getDataElements(int, int, int, int, Object, DataBuffer)
28.215 + * @see #setDataElements(int, int, Object, DataBuffer)
28.216 + * @see #setDataElements(int, int, int, int, Object, DataBuffer)
28.217 + * @see #getNumDataElements
28.218 + * @see java.awt.image.DataBuffer
28.219 + */
28.220 + public int getTransferType() {
28.221 + return dataType;
28.222 + }
28.223 +
28.224 + /**
28.225 + * Returns the samples for a specified pixel in an int array,
28.226 + * one sample per array element.
28.227 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.228 + * not in bounds.
28.229 + * @param x The X coordinate of the pixel location
28.230 + * @param y The Y coordinate of the pixel location
28.231 + * @param iArray If non-null, returns the samples in this array
28.232 + * @param data The DataBuffer containing the image data
28.233 + * @return the samples for the specified pixel.
28.234 + * @see #setPixel(int, int, int[], DataBuffer)
28.235 + *
28.236 + * @throws NullPointerException if data is null.
28.237 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.238 + * not in bounds, or if iArray is too small to hold the output.
28.239 + */
28.240 + public int[] getPixel(int x, int y, int iArray[], DataBuffer data) {
28.241 +
28.242 + int pixels[];
28.243 +
28.244 + if (iArray != null)
28.245 + pixels = iArray;
28.246 + else
28.247 + pixels = new int[numBands];
28.248 +
28.249 + for (int i=0; i<numBands; i++) {
28.250 + pixels[i] = getSample(x, y, i, data);
28.251 + }
28.252 +
28.253 + return pixels;
28.254 + }
28.255 +
28.256 + /**
28.257 + * Returns data for a single pixel in a primitive array of type
28.258 + * TransferType. For image data supported by the Java 2D API, this
28.259 + * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
28.260 + * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
28.261 + * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
28.262 + * thus increasing efficiency for data transfers. Generally, obj
28.263 + * should be passed in as null, so that the Object will be created
28.264 + * automatically and will be of the right primitive data type.
28.265 + * <p>
28.266 + * The following code illustrates transferring data for one pixel from
28.267 + * DataBuffer <code>db1</code>, whose storage layout is described by
28.268 + * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
28.269 + * storage layout is described by SampleModel <code>sm2</code>.
28.270 + * The transfer will generally be more efficient than using
28.271 + * getPixel/setPixel.
28.272 + * <pre>
28.273 + * SampleModel sm1, sm2;
28.274 + * DataBuffer db1, db2;
28.275 + * sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1), db2);
28.276 + * </pre>
28.277 + * Using getDataElements/setDataElements to transfer between two
28.278 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
28.279 + * the same number of bands, corresponding bands have the same number of
28.280 + * bits per sample, and the TransferTypes are the same.
28.281 + * <p>
28.282 + * If obj is non-null, it should be a primitive array of type TransferType.
28.283 + * Otherwise, a ClassCastException is thrown. An
28.284 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.285 + * not in bounds, or if obj is non-null and is not large enough to hold
28.286 + * the pixel data.
28.287 + * @param x The X coordinate of the pixel location.
28.288 + * @param y The Y coordinate of the pixel location.
28.289 + * @param obj If non-null, a primitive array in which to return
28.290 + * the pixel data.
28.291 + * @param data The DataBuffer containing the image data.
28.292 + * @return the data elements for the specified pixel.
28.293 + * @see #getNumDataElements
28.294 + * @see #getTransferType
28.295 + * @see java.awt.image.DataBuffer
28.296 + * @see #setDataElements(int, int, Object, DataBuffer)
28.297 + *
28.298 + * @throws NullPointerException if data is null.
28.299 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.300 + * not in bounds, or if obj is too small to hold the output.
28.301 + */
28.302 + public abstract Object getDataElements(int x, int y,
28.303 + Object obj, DataBuffer data);
28.304 +
28.305 + /**
28.306 + * Returns the pixel data for the specified rectangle of pixels in a
28.307 + * primitive array of type TransferType.
28.308 + * For image data supported by the Java 2D API, this
28.309 + * will be one of DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT,
28.310 + * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT,
28.311 + * or DataBuffer.TYPE_DOUBLE. Data may be returned in a packed format,
28.312 + * thus increasing efficiency for data transfers. Generally, obj
28.313 + * should be passed in as null, so that the Object will be created
28.314 + * automatically and will be of the right primitive data type.
28.315 + * <p>
28.316 + * The following code illustrates transferring data for a rectangular
28.317 + * region of pixels from
28.318 + * DataBuffer <code>db1</code>, whose storage layout is described by
28.319 + * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
28.320 + * storage layout is described by SampleModel <code>sm2</code>.
28.321 + * The transfer will generally be more efficient than using
28.322 + * getPixels/setPixels.
28.323 + * <pre>
28.324 + * SampleModel sm1, sm2;
28.325 + * DataBuffer db1, db2;
28.326 + * sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w,
28.327 + * h, null, db1), db2);
28.328 + * </pre>
28.329 + * Using getDataElements/setDataElements to transfer between two
28.330 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
28.331 + * the same number of bands, corresponding bands have the same number of
28.332 + * bits per sample, and the TransferTypes are the same.
28.333 + * <p>
28.334 + * If obj is non-null, it should be a primitive array of type TransferType.
28.335 + * Otherwise, a ClassCastException is thrown. An
28.336 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.337 + * not in bounds, or if obj is non-null and is not large enough to hold
28.338 + * the pixel data.
28.339 + * @param x The minimum X coordinate of the pixel rectangle.
28.340 + * @param y The minimum Y coordinate of the pixel rectangle.
28.341 + * @param w The width of the pixel rectangle.
28.342 + * @param h The height of the pixel rectangle.
28.343 + * @param obj If non-null, a primitive array in which to return
28.344 + * the pixel data.
28.345 + * @param data The DataBuffer containing the image data.
28.346 + * @return the data elements for the specified region of pixels.
28.347 + * @see #getNumDataElements
28.348 + * @see #getTransferType
28.349 + * @see #setDataElements(int, int, int, int, Object, DataBuffer)
28.350 + * @see java.awt.image.DataBuffer
28.351 + *
28.352 + * @throws NullPointerException if data is null.
28.353 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.354 + * not in bounds, or if obj is too small to hold the output.
28.355 + */
28.356 + public Object getDataElements(int x, int y, int w, int h,
28.357 + Object obj, DataBuffer data) {
28.358 +
28.359 + int type = getTransferType();
28.360 + int numDataElems = getNumDataElements();
28.361 + int cnt = 0;
28.362 + Object o = null;
28.363 +
28.364 + switch(type) {
28.365 +
28.366 + case DataBuffer.TYPE_BYTE:
28.367 +
28.368 + byte[] btemp;
28.369 + byte[] bdata;
28.370 +
28.371 + if (obj == null)
28.372 + bdata = new byte[numDataElems*w*h];
28.373 + else
28.374 + bdata = (byte[])obj;
28.375 +
28.376 + for (int i=y; i<y+h; i++) {
28.377 + for (int j=x; j<x+w; j++) {
28.378 + o = getDataElements(j, i, o, data);
28.379 + btemp = (byte[])o;
28.380 + for (int k=0; k<numDataElems; k++) {
28.381 + bdata[cnt++] = btemp[k];
28.382 + }
28.383 + }
28.384 + }
28.385 + obj = (Object)bdata;
28.386 + break;
28.387 +
28.388 + case DataBuffer.TYPE_USHORT:
28.389 + case DataBuffer.TYPE_SHORT:
28.390 +
28.391 + short[] sdata;
28.392 + short[] stemp;
28.393 +
28.394 + if (obj == null)
28.395 + sdata = new short[numDataElems*w*h];
28.396 + else
28.397 + sdata = (short[])obj;
28.398 +
28.399 + for (int i=y; i<y+h; i++) {
28.400 + for (int j=x; j<x+w; j++) {
28.401 + o = getDataElements(j, i, o, data);
28.402 + stemp = (short[])o;
28.403 + for (int k=0; k<numDataElems; k++) {
28.404 + sdata[cnt++] = stemp[k];
28.405 + }
28.406 + }
28.407 + }
28.408 +
28.409 + obj = (Object)sdata;
28.410 + break;
28.411 +
28.412 + case DataBuffer.TYPE_INT:
28.413 +
28.414 + int[] idata;
28.415 + int[] itemp;
28.416 +
28.417 + if (obj == null)
28.418 + idata = new int[numDataElems*w*h];
28.419 + else
28.420 + idata = (int[])obj;
28.421 +
28.422 + for (int i=y; i<y+h; i++) {
28.423 + for (int j=x; j<x+w; j++) {
28.424 + o = getDataElements(j, i, o, data);
28.425 + itemp = (int[])o;
28.426 + for (int k=0; k<numDataElems; k++) {
28.427 + idata[cnt++] = itemp[k];
28.428 + }
28.429 + }
28.430 + }
28.431 +
28.432 + obj = (Object)idata;
28.433 + break;
28.434 +
28.435 + case DataBuffer.TYPE_FLOAT:
28.436 +
28.437 + float[] fdata;
28.438 + float[] ftemp;
28.439 +
28.440 + if (obj == null)
28.441 + fdata = new float[numDataElems*w*h];
28.442 + else
28.443 + fdata = (float[])obj;
28.444 +
28.445 + for (int i=y; i<y+h; i++) {
28.446 + for (int j=x; j<x+w; j++) {
28.447 + o = getDataElements(j, i, o, data);
28.448 + ftemp = (float[])o;
28.449 + for (int k=0; k<numDataElems; k++) {
28.450 + fdata[cnt++] = ftemp[k];
28.451 + }
28.452 + }
28.453 + }
28.454 +
28.455 + obj = (Object)fdata;
28.456 + break;
28.457 +
28.458 + case DataBuffer.TYPE_DOUBLE:
28.459 +
28.460 + double[] ddata;
28.461 + double[] dtemp;
28.462 +
28.463 + if (obj == null)
28.464 + ddata = new double[numDataElems*w*h];
28.465 + else
28.466 + ddata = (double[])obj;
28.467 +
28.468 + for (int i=y; i<y+h; i++) {
28.469 + for (int j=x; j<x+w; j++) {
28.470 + o = getDataElements(j, i, o, data);
28.471 + dtemp = (double[])o;
28.472 + for (int k=0; k<numDataElems; k++) {
28.473 + ddata[cnt++] = dtemp[k];
28.474 + }
28.475 + }
28.476 + }
28.477 +
28.478 + obj = (Object)ddata;
28.479 + break;
28.480 + }
28.481 +
28.482 + return obj;
28.483 + }
28.484 +
28.485 + /**
28.486 + * Sets the data for a single pixel in the specified DataBuffer from a
28.487 + * primitive array of type TransferType. For image data supported by
28.488 + * the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
28.489 + * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
28.490 + * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
28.491 + * may be in a packed format, thus increasing efficiency for data
28.492 + * transfers.
28.493 + * <p>
28.494 + * The following code illustrates transferring data for one pixel from
28.495 + * DataBuffer <code>db1</code>, whose storage layout is described by
28.496 + * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
28.497 + * storage layout is described by SampleModel <code>sm2</code>.
28.498 + * The transfer will generally be more efficient than using
28.499 + * getPixel/setPixel.
28.500 + * <pre>
28.501 + * SampleModel sm1, sm2;
28.502 + * DataBuffer db1, db2;
28.503 + * sm2.setDataElements(x, y, sm1.getDataElements(x, y, null, db1),
28.504 + * db2);
28.505 + * </pre>
28.506 + * Using getDataElements/setDataElements to transfer between two
28.507 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
28.508 + * the same number of bands, corresponding bands have the same number of
28.509 + * bits per sample, and the TransferTypes are the same.
28.510 + * <p>
28.511 + * obj must be a primitive array of type TransferType. Otherwise,
28.512 + * a ClassCastException is thrown. An
28.513 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.514 + * not in bounds, or if obj is not large enough to hold the pixel data.
28.515 + * @param x The X coordinate of the pixel location.
28.516 + * @param y The Y coordinate of the pixel location.
28.517 + * @param obj A primitive array containing pixel data.
28.518 + * @param data The DataBuffer containing the image data.
28.519 + * @see #getNumDataElements
28.520 + * @see #getTransferType
28.521 + * @see #getDataElements(int, int, Object, DataBuffer)
28.522 + * @see java.awt.image.DataBuffer
28.523 + *
28.524 + * @throws NullPointerException if data is null.
28.525 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.526 + * not in bounds, or if obj is too small to hold the input.
28.527 + */
28.528 + public abstract void setDataElements(int x, int y,
28.529 + Object obj, DataBuffer data);
28.530 +
28.531 + /**
28.532 + * Sets the data for a rectangle of pixels in the specified DataBuffer
28.533 + * from a primitive array of type TransferType. For image data supported
28.534 + * by the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
28.535 + * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
28.536 + * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
28.537 + * may be in a packed format, thus increasing efficiency for data
28.538 + * transfers.
28.539 + * <p>
28.540 + * The following code illustrates transferring data for a rectangular
28.541 + * region of pixels from
28.542 + * DataBuffer <code>db1</code>, whose storage layout is described by
28.543 + * SampleModel <code>sm1</code>, to DataBuffer <code>db2</code>, whose
28.544 + * storage layout is described by SampleModel <code>sm2</code>.
28.545 + * The transfer will generally be more efficient than using
28.546 + * getPixels/setPixels.
28.547 + * <pre>
28.548 + * SampleModel sm1, sm2;
28.549 + * DataBuffer db1, db2;
28.550 + * sm2.setDataElements(x, y, w, h, sm1.getDataElements(x, y, w, h,
28.551 + * null, db1), db2);
28.552 + * </pre>
28.553 + * Using getDataElements/setDataElements to transfer between two
28.554 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
28.555 + * the same number of bands, corresponding bands have the same number of
28.556 + * bits per sample, and the TransferTypes are the same.
28.557 + * <p>
28.558 + * obj must be a primitive array of type TransferType. Otherwise,
28.559 + * a ClassCastException is thrown. An
28.560 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.561 + * not in bounds, or if obj is not large enough to hold the pixel data.
28.562 + * @param x The minimum X coordinate of the pixel rectangle.
28.563 + * @param y The minimum Y coordinate of the pixel rectangle.
28.564 + * @param w The width of the pixel rectangle.
28.565 + * @param h The height of the pixel rectangle.
28.566 + * @param obj A primitive array containing pixel data.
28.567 + * @param data The DataBuffer containing the image data.
28.568 + * @see #getNumDataElements
28.569 + * @see #getTransferType
28.570 + * @see #getDataElements(int, int, int, int, Object, DataBuffer)
28.571 + * @see java.awt.image.DataBuffer
28.572 + *
28.573 + * @throws NullPointerException if data is null.
28.574 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.575 + * not in bounds, or if obj is too small to hold the input.
28.576 + */
28.577 + public void setDataElements(int x, int y, int w, int h,
28.578 + Object obj, DataBuffer data) {
28.579 +
28.580 + int cnt = 0;
28.581 + Object o = null;
28.582 + int type = getTransferType();
28.583 + int numDataElems = getNumDataElements();
28.584 +
28.585 + switch(type) {
28.586 +
28.587 + case DataBuffer.TYPE_BYTE:
28.588 +
28.589 + byte[] barray = (byte[])obj;
28.590 + byte[] btemp = new byte[numDataElems];
28.591 +
28.592 + for (int i=y; i<y+h; i++) {
28.593 + for (int j=x; j<x+w; j++) {
28.594 + for (int k=0; k<numDataElems; k++) {
28.595 + btemp[k] = barray[cnt++];
28.596 + }
28.597 +
28.598 + setDataElements(j, i, btemp, data);
28.599 + }
28.600 + }
28.601 + break;
28.602 +
28.603 + case DataBuffer.TYPE_USHORT:
28.604 + case DataBuffer.TYPE_SHORT:
28.605 +
28.606 + short[] sarray = (short[])obj;
28.607 + short[] stemp = new short[numDataElems];
28.608 +
28.609 + for (int i=y; i<y+h; i++) {
28.610 + for (int j=x; j<x+w; j++) {
28.611 + for (int k=0; k<numDataElems; k++) {
28.612 + stemp[k] = sarray[cnt++];
28.613 + }
28.614 +
28.615 + setDataElements(j, i, stemp, data);
28.616 + }
28.617 + }
28.618 + break;
28.619 +
28.620 + case DataBuffer.TYPE_INT:
28.621 +
28.622 + int[] iArray = (int[])obj;
28.623 + int[] itemp = new int[numDataElems];
28.624 +
28.625 + for (int i=y; i<y+h; i++) {
28.626 + for (int j=x; j<x+w; j++) {
28.627 + for (int k=0; k<numDataElems; k++) {
28.628 + itemp[k] = iArray[cnt++];
28.629 + }
28.630 +
28.631 + setDataElements(j, i, itemp, data);
28.632 + }
28.633 + }
28.634 + break;
28.635 +
28.636 + case DataBuffer.TYPE_FLOAT:
28.637 +
28.638 + float[] fArray = (float[])obj;
28.639 + float[] ftemp = new float[numDataElems];
28.640 +
28.641 + for (int i=y; i<y+h; i++) {
28.642 + for (int j=x; j<x+w; j++) {
28.643 + for (int k=0; k<numDataElems; k++) {
28.644 + ftemp[k] = fArray[cnt++];
28.645 + }
28.646 +
28.647 + setDataElements(j, i, ftemp, data);
28.648 + }
28.649 + }
28.650 + break;
28.651 +
28.652 + case DataBuffer.TYPE_DOUBLE:
28.653 +
28.654 + double[] dArray = (double[])obj;
28.655 + double[] dtemp = new double[numDataElems];
28.656 +
28.657 + for (int i=y; i<y+h; i++) {
28.658 + for (int j=x; j<x+w; j++) {
28.659 + for (int k=0; k<numDataElems; k++) {
28.660 + dtemp[k] = dArray[cnt++];
28.661 + }
28.662 +
28.663 + setDataElements(j, i, dtemp, data);
28.664 + }
28.665 + }
28.666 + break;
28.667 + }
28.668 +
28.669 + }
28.670 +
28.671 + /**
28.672 + * Returns the samples for the specified pixel in an array of float.
28.673 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.674 + * not in bounds.
28.675 + * @param x The X coordinate of the pixel location.
28.676 + * @param y The Y coordinate of the pixel location.
28.677 + * @param fArray If non-null, returns the samples in this array.
28.678 + * @param data The DataBuffer containing the image data.
28.679 + * @return the samples for the specified pixel.
28.680 + * @see #setPixel(int, int, float[], DataBuffer)
28.681 + *
28.682 + * @throws NullPointerException if data is null.
28.683 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.684 + * not in bounds, or if fArray is too small to hold the output.
28.685 + */
28.686 + public float[] getPixel(int x, int y, float fArray[],
28.687 + DataBuffer data) {
28.688 +
28.689 + float pixels[];
28.690 +
28.691 + if (fArray != null)
28.692 + pixels = fArray;
28.693 + else
28.694 + pixels = new float[numBands];
28.695 +
28.696 + for (int i=0; i<numBands; i++)
28.697 + pixels[i] = getSampleFloat(x, y, i, data);
28.698 +
28.699 + return pixels;
28.700 + }
28.701 +
28.702 + /**
28.703 + * Returns the samples for the specified pixel in an array of double.
28.704 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.705 + * not in bounds.
28.706 + * @param x The X coordinate of the pixel location.
28.707 + * @param y The Y coordinate of the pixel location.
28.708 + * @param dArray If non-null, returns the samples in this array.
28.709 + * @param data The DataBuffer containing the image data.
28.710 + * @return the samples for the specified pixel.
28.711 + * @see #setPixel(int, int, double[], DataBuffer)
28.712 + *
28.713 + * @throws NullPointerException if data is null.
28.714 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.715 + * not in bounds, or if dArray is too small to hold the output.
28.716 + */
28.717 + public double[] getPixel(int x, int y, double dArray[],
28.718 + DataBuffer data) {
28.719 +
28.720 + double pixels[];
28.721 +
28.722 + if(dArray != null)
28.723 + pixels = dArray;
28.724 + else
28.725 + pixels = new double[numBands];
28.726 +
28.727 + for (int i=0; i<numBands; i++)
28.728 + pixels[i] = getSampleDouble(x, y, i, data);
28.729 +
28.730 + return pixels;
28.731 + }
28.732 +
28.733 + /**
28.734 + * Returns all samples for a rectangle of pixels in an
28.735 + * int array, one sample per array element.
28.736 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.737 + * not in bounds.
28.738 + * @param x The X coordinate of the upper left pixel location.
28.739 + * @param y The Y coordinate of the upper left pixel location.
28.740 + * @param w The width of the pixel rectangle.
28.741 + * @param h The height of the pixel rectangle.
28.742 + * @param iArray If non-null, returns the samples in this array.
28.743 + * @param data The DataBuffer containing the image data.
28.744 + * @return the samples for the specified region of pixels.
28.745 + * @see #setPixels(int, int, int, int, int[], DataBuffer)
28.746 + *
28.747 + * @throws NullPointerException if data is null.
28.748 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.749 + * not in bounds, or if iArray is too small to hold the output.
28.750 + */
28.751 + public int[] getPixels(int x, int y, int w, int h,
28.752 + int iArray[], DataBuffer data) {
28.753 +
28.754 + int pixels[];
28.755 + int Offset=0;
28.756 +
28.757 + if (iArray != null)
28.758 + pixels = iArray;
28.759 + else
28.760 + pixels = new int[numBands * w * h];
28.761 +
28.762 + for (int i=y; i<(h+y); i++) {
28.763 + for (int j=x; j<(w+x); j++) {
28.764 + for(int k=0; k<numBands; k++) {
28.765 + pixels[Offset++] = getSample(j, i, k, data);
28.766 + }
28.767 + }
28.768 + }
28.769 +
28.770 + return pixels;
28.771 + }
28.772 +
28.773 + /**
28.774 + * Returns all samples for a rectangle of pixels in a float
28.775 + * array, one sample per array element.
28.776 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.777 + * not in bounds.
28.778 + * @param x The X coordinate of the upper left pixel location.
28.779 + * @param y The Y coordinate of the upper left pixel location.
28.780 + * @param w The width of the pixel rectangle.
28.781 + * @param h The height of the pixel rectangle.
28.782 + * @param fArray If non-null, returns the samples in this array.
28.783 + * @param data The DataBuffer containing the image data.
28.784 + * @return the samples for the specified region of pixels.
28.785 + * @see #setPixels(int, int, int, int, float[], DataBuffer)
28.786 + *
28.787 + * @throws NullPointerException if data is null.
28.788 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.789 + * not in bounds, or if fArray is too small to hold the output.
28.790 + */
28.791 + public float[] getPixels(int x, int y, int w, int h,
28.792 + float fArray[], DataBuffer data) {
28.793 +
28.794 + float pixels[];
28.795 + int Offset = 0;
28.796 +
28.797 + if (fArray != null)
28.798 + pixels = fArray;
28.799 + else
28.800 + pixels = new float[numBands * w * h];
28.801 +
28.802 + for (int i=y; i<(h+y); i++) {
28.803 + for(int j=x; j<(w+x); j++) {
28.804 + for(int k=0; k<numBands; k++) {
28.805 + pixels[Offset++] = getSampleFloat(j, i, k, data);
28.806 + }
28.807 + }
28.808 + }
28.809 +
28.810 + return pixels;
28.811 + }
28.812 +
28.813 + /**
28.814 + * Returns all samples for a rectangle of pixels in a double
28.815 + * array, one sample per array element.
28.816 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.817 + * not in bounds.
28.818 + * @param x The X coordinate of the upper left pixel location.
28.819 + * @param y The Y coordinate of the upper left pixel location.
28.820 + * @param w The width of the pixel rectangle.
28.821 + * @param h The height of the pixel rectangle.
28.822 + * @param dArray If non-null, returns the samples in this array.
28.823 + * @param data The DataBuffer containing the image data.
28.824 + * @return the samples for the specified region of pixels.
28.825 + * @see #setPixels(int, int, int, int, double[], DataBuffer)
28.826 + *
28.827 + * @throws NullPointerException if data is null.
28.828 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.829 + * not in bounds, or if dArray is too small to hold the output.
28.830 + */
28.831 + public double[] getPixels(int x, int y, int w, int h,
28.832 + double dArray[], DataBuffer data) {
28.833 + double pixels[];
28.834 + int Offset = 0;
28.835 +
28.836 + if (dArray != null)
28.837 + pixels = dArray;
28.838 + else
28.839 + pixels = new double[numBands * w * h];
28.840 +
28.841 + // Fix 4217412
28.842 + for (int i=y; i<(h+y); i++) {
28.843 + for (int j=x; j<(w+x); j++) {
28.844 + for (int k=0; k<numBands; k++) {
28.845 + pixels[Offset++] = getSampleDouble(j, i, k, data);
28.846 + }
28.847 + }
28.848 + }
28.849 +
28.850 + return pixels;
28.851 + }
28.852 +
28.853 +
28.854 + /**
28.855 + * Returns the sample in a specified band for the pixel located
28.856 + * at (x,y) as an int.
28.857 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.858 + * not in bounds.
28.859 + * @param x The X coordinate of the pixel location.
28.860 + * @param y The Y coordinate of the pixel location.
28.861 + * @param b The band to return.
28.862 + * @param data The DataBuffer containing the image data.
28.863 + * @return the sample in a specified band for the specified pixel.
28.864 + * @see #setSample(int, int, int, int, DataBuffer)
28.865 + *
28.866 + * @throws NullPointerException if data is null.
28.867 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.868 + * the band index are not in bounds.
28.869 + */
28.870 + public abstract int getSample(int x, int y, int b, DataBuffer data);
28.871 +
28.872 +
28.873 + /**
28.874 + * Returns the sample in a specified band
28.875 + * for the pixel located at (x,y) as a float.
28.876 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.877 + * not in bounds.
28.878 + * @param x The X coordinate of the pixel location.
28.879 + * @param y The Y coordinate of the pixel location.
28.880 + * @param b The band to return.
28.881 + * @param data The DataBuffer containing the image data.
28.882 + * @return the sample in a specified band for the specified pixel.
28.883 + *
28.884 + * @throws NullPointerException if data is null.
28.885 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.886 + * the band index are not in bounds.
28.887 + */
28.888 + public float getSampleFloat(int x, int y, int b, DataBuffer data) {
28.889 +
28.890 + float sample;
28.891 + sample = (float) getSample(x, y, b, data);
28.892 + return sample;
28.893 + }
28.894 +
28.895 + /**
28.896 + * Returns the sample in a specified band
28.897 + * for a pixel located at (x,y) as a double.
28.898 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.899 + * not in bounds.
28.900 + * @param x The X coordinate of the pixel location.
28.901 + * @param y The Y coordinate of the pixel location.
28.902 + * @param b The band to return.
28.903 + * @param data The DataBuffer containing the image data.
28.904 + * @return the sample in a specified band for the specified pixel.
28.905 + *
28.906 + * @throws NullPointerException if data is null.
28.907 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.908 + * the band index are not in bounds.
28.909 + */
28.910 + public double getSampleDouble(int x, int y, int b, DataBuffer data) {
28.911 +
28.912 + double sample;
28.913 +
28.914 + sample = (double) getSample(x, y, b, data);
28.915 + return sample;
28.916 + }
28.917 +
28.918 + /**
28.919 + * Returns the samples for a specified band for the specified rectangle
28.920 + * of pixels in an int array, one sample per array element.
28.921 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.922 + * not in bounds.
28.923 + * @param x The X coordinate of the upper left pixel location.
28.924 + * @param y The Y coordinate of the upper left pixel location.
28.925 + * @param w The width of the pixel rectangle.
28.926 + * @param h The height of the pixel rectangle.
28.927 + * @param b The band to return.
28.928 + * @param iArray If non-null, returns the samples in this array.
28.929 + * @param data The DataBuffer containing the image data.
28.930 + * @return the samples for the specified band for the specified region
28.931 + * of pixels.
28.932 + * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
28.933 + *
28.934 + * @throws NullPointerException if data is null.
28.935 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.936 + * the band index are not in bounds, or if iArray is too small to
28.937 + * hold the output.
28.938 + */
28.939 + public int[] getSamples(int x, int y, int w, int h, int b,
28.940 + int iArray[], DataBuffer data) {
28.941 + int pixels[];
28.942 + int Offset=0;
28.943 +
28.944 + if (iArray != null)
28.945 + pixels = iArray;
28.946 + else
28.947 + pixels = new int[w * h];
28.948 +
28.949 + for(int i=y; i<(h+y); i++) {
28.950 + for (int j=x; j<(w+x); j++) {
28.951 + pixels[Offset++] = getSample(j, i, b, data);
28.952 + }
28.953 + }
28.954 +
28.955 + return pixels;
28.956 + }
28.957 +
28.958 + /**
28.959 + * Returns the samples for a specified band for the specified rectangle
28.960 + * of pixels in a float array, one sample per array element.
28.961 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.962 + * not in bounds.
28.963 + * @param x The X coordinate of the upper left pixel location.
28.964 + * @param y The Y coordinate of the upper left pixel location.
28.965 + * @param w The width of the pixel rectangle.
28.966 + * @param h The height of the pixel rectangle.
28.967 + * @param b The band to return.
28.968 + * @param fArray If non-null, returns the samples in this array.
28.969 + * @param data The DataBuffer containing the image data.
28.970 + * @return the samples for the specified band for the specified region
28.971 + * of pixels.
28.972 + * @see #setSamples(int, int, int, int, int, float[], DataBuffer)
28.973 + *
28.974 + * @throws NullPointerException if data is null.
28.975 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.976 + * the band index are not in bounds, or if fArray is too small to
28.977 + * hold the output.
28.978 + */
28.979 + public float[] getSamples(int x, int y, int w, int h,
28.980 + int b, float fArray[],
28.981 + DataBuffer data) {
28.982 + float pixels[];
28.983 + int Offset=0;
28.984 +
28.985 + if (fArray != null)
28.986 + pixels = fArray;
28.987 + else
28.988 + pixels = new float[w * h];
28.989 +
28.990 + for (int i=y; i<(h+y); i++) {
28.991 + for (int j=x; j<(w+x); j++) {
28.992 + pixels[Offset++] = getSampleFloat(j, i, b, data);
28.993 + }
28.994 + }
28.995 +
28.996 + return pixels;
28.997 + }
28.998 +
28.999 + /**
28.1000 + * Returns the samples for a specified band for a specified rectangle
28.1001 + * of pixels in a double array, one sample per array element.
28.1002 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1003 + * not in bounds.
28.1004 + * @param x The X coordinate of the upper left pixel location.
28.1005 + * @param y The Y coordinate of the upper left pixel location.
28.1006 + * @param w The width of the pixel rectangle.
28.1007 + * @param h The height of the pixel rectangle.
28.1008 + * @param b The band to return.
28.1009 + * @param dArray If non-null, returns the samples in this array.
28.1010 + * @param data The DataBuffer containing the image data.
28.1011 + * @return the samples for the specified band for the specified region
28.1012 + * of pixels.
28.1013 + * @see #setSamples(int, int, int, int, int, double[], DataBuffer)
28.1014 + *
28.1015 + * @throws NullPointerException if data is null.
28.1016 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1017 + * the band index are not in bounds, or if dArray is too small to
28.1018 + * hold the output.
28.1019 + */
28.1020 + public double[] getSamples(int x, int y, int w, int h,
28.1021 + int b, double dArray[],
28.1022 + DataBuffer data) {
28.1023 + double pixels[];
28.1024 + int Offset=0;
28.1025 +
28.1026 + if (dArray != null)
28.1027 + pixels = dArray;
28.1028 + else
28.1029 + pixels = new double[w * h];
28.1030 +
28.1031 + for (int i=y; i<(y+h); i++) {
28.1032 + for (int j=x; j<(x+w); j++) {
28.1033 + pixels[Offset++] = getSampleDouble(j, i, b, data);
28.1034 + }
28.1035 + }
28.1036 +
28.1037 + return pixels;
28.1038 + }
28.1039 +
28.1040 + /**
28.1041 + * Sets a pixel in the DataBuffer using an int array of samples for input.
28.1042 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1043 + * not in bounds.
28.1044 + * @param x The X coordinate of the pixel location.
28.1045 + * @param y The Y coordinate of the pixel location.
28.1046 + * @param iArray The input samples in an int array.
28.1047 + * @param data The DataBuffer containing the image data.
28.1048 + * @see #getPixel(int, int, int[], DataBuffer)
28.1049 + *
28.1050 + * @throws NullPointerException if iArray or data is null.
28.1051 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1052 + * not in bounds, or if iArray is too small to hold the input.
28.1053 + */
28.1054 + public void setPixel(int x, int y, int iArray[], DataBuffer data) {
28.1055 +
28.1056 + for (int i=0; i<numBands; i++)
28.1057 + setSample(x, y, i, iArray[i], data);
28.1058 + }
28.1059 +
28.1060 + /**
28.1061 + * Sets a pixel in the DataBuffer using a float array of samples for input.
28.1062 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1063 + * not in bounds.
28.1064 + * @param x The X coordinate of the pixel location.
28.1065 + * @param y The Y coordinate of the pixel location.
28.1066 + * @param fArray The input samples in a float array.
28.1067 + * @param data The DataBuffer containing the image data.
28.1068 + * @see #getPixel(int, int, float[], DataBuffer)
28.1069 + *
28.1070 + * @throws NullPointerException if fArray or data is null.
28.1071 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1072 + * not in bounds, or if fArray is too small to hold the input.
28.1073 + */
28.1074 + public void setPixel(int x, int y, float fArray[], DataBuffer data) {
28.1075 +
28.1076 + for (int i=0; i<numBands; i++)
28.1077 + setSample(x, y, i, fArray[i], data);
28.1078 + }
28.1079 +
28.1080 + /**
28.1081 + * Sets a pixel in the DataBuffer using a double array of samples
28.1082 + * for input.
28.1083 + * @param x The X coordinate of the pixel location.
28.1084 + * @param y The Y coordinate of the pixel location.
28.1085 + * @param dArray The input samples in a double array.
28.1086 + * @param data The DataBuffer containing the image data.
28.1087 + * @see #getPixel(int, int, double[], DataBuffer)
28.1088 + *
28.1089 + * @throws NullPointerException if dArray or data is null.
28.1090 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1091 + * not in bounds, or if fArray is too small to hold the input.
28.1092 + */
28.1093 + public void setPixel(int x, int y, double dArray[], DataBuffer data) {
28.1094 +
28.1095 + for (int i=0; i<numBands; i++)
28.1096 + setSample(x, y, i, dArray[i], data);
28.1097 + }
28.1098 +
28.1099 + /**
28.1100 + * Sets all samples for a rectangle of pixels from an int array containing
28.1101 + * one sample per array element.
28.1102 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1103 + * not in bounds.
28.1104 + * @param x The X coordinate of the upper left pixel location.
28.1105 + * @param y The Y coordinate of the upper left pixel location.
28.1106 + * @param w The width of the pixel rectangle.
28.1107 + * @param h The height of the pixel rectangle.
28.1108 + * @param iArray The input samples in an int array.
28.1109 + * @param data The DataBuffer containing the image data.
28.1110 + * @see #getPixels(int, int, int, int, int[], DataBuffer)
28.1111 + *
28.1112 + * @throws NullPointerException if iArray or data is null.
28.1113 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1114 + * not in bounds, or if iArray is too small to hold the input.
28.1115 + */
28.1116 + public void setPixels(int x, int y, int w, int h,
28.1117 + int iArray[], DataBuffer data) {
28.1118 + int Offset=0;
28.1119 +
28.1120 + for (int i=y; i<(y+h); i++) {
28.1121 + for (int j=x; j<(x+w); j++) {
28.1122 + for (int k=0; k<numBands; k++) {
28.1123 + setSample(j, i, k, iArray[Offset++], data);
28.1124 + }
28.1125 + }
28.1126 + }
28.1127 + }
28.1128 +
28.1129 + /**
28.1130 + * Sets all samples for a rectangle of pixels from a float array containing
28.1131 + * one sample per array element.
28.1132 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1133 + * not in bounds.
28.1134 + * @param x The X coordinate of the upper left pixel location.
28.1135 + * @param y The Y coordinate of the upper left pixel location.
28.1136 + * @param w The width of the pixel rectangle.
28.1137 + * @param h The height of the pixel rectangle.
28.1138 + * @param fArray The input samples in a float array.
28.1139 + * @param data The DataBuffer containing the image data.
28.1140 + * @see #getPixels(int, int, int, int, float[], DataBuffer)
28.1141 + *
28.1142 + * @throws NullPointerException if fArray or data is null.
28.1143 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1144 + * not in bounds, or if fArray is too small to hold the input.
28.1145 + */
28.1146 + public void setPixels(int x, int y, int w, int h,
28.1147 + float fArray[], DataBuffer data) {
28.1148 + int Offset=0;
28.1149 +
28.1150 + for (int i=y; i<(y+h); i++) {
28.1151 + for (int j=x; j<(x+w); j++) {
28.1152 + for(int k=0; k<numBands; k++) {
28.1153 + setSample(j, i, k, fArray[Offset++], data);
28.1154 + }
28.1155 + }
28.1156 + }
28.1157 + }
28.1158 +
28.1159 + /**
28.1160 + * Sets all samples for a rectangle of pixels from a double array
28.1161 + * containing one sample per array element.
28.1162 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1163 + * not in bounds.
28.1164 + * @param x The X coordinate of the upper left pixel location.
28.1165 + * @param y The Y coordinate of the upper left pixel location.
28.1166 + * @param w The width of the pixel rectangle.
28.1167 + * @param h The height of the pixel rectangle.
28.1168 + * @param dArray The input samples in a double array.
28.1169 + * @param data The DataBuffer containing the image data.
28.1170 + * @see #getPixels(int, int, int, int, double[], DataBuffer)
28.1171 + *
28.1172 + * @throws NullPointerException if dArray or data is null.
28.1173 + * @throws ArrayIndexOutOfBoundsException if the coordinates are
28.1174 + * not in bounds, or if dArray is too small to hold the input.
28.1175 + */
28.1176 + public void setPixels(int x, int y, int w, int h,
28.1177 + double dArray[], DataBuffer data) {
28.1178 + int Offset=0;
28.1179 +
28.1180 + for (int i=y; i<(y+h); i++) {
28.1181 + for (int j=x; j<(x+w); j++) {
28.1182 + for (int k=0; k<numBands; k++) {
28.1183 + setSample(j, i, k, dArray[Offset++], data);
28.1184 + }
28.1185 + }
28.1186 + }
28.1187 + }
28.1188 +
28.1189 + /**
28.1190 + * Sets a sample in the specified band for the pixel located at (x,y)
28.1191 + * in the DataBuffer using an int for input.
28.1192 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1193 + * not in bounds.
28.1194 + * @param x The X coordinate of the pixel location.
28.1195 + * @param y The Y coordinate of the pixel location.
28.1196 + * @param b The band to set.
28.1197 + * @param s The input sample as an int.
28.1198 + * @param data The DataBuffer containing the image data.
28.1199 + * @see #getSample(int, int, int, DataBuffer)
28.1200 + *
28.1201 + * @throws NullPointerException if data is null.
28.1202 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1203 + * the band index are not in bounds.
28.1204 + */
28.1205 + public abstract void setSample(int x, int y, int b,
28.1206 + int s,
28.1207 + DataBuffer data);
28.1208 +
28.1209 + /**
28.1210 + * Sets a sample in the specified band for the pixel located at (x,y)
28.1211 + * in the DataBuffer using a float for input.
28.1212 + * The default implementation of this method casts the input
28.1213 + * float sample to an int and then calls the
28.1214 + * <code>setSample(int, int, int, DataBuffer)</code> method using
28.1215 + * that int value.
28.1216 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1217 + * not in bounds.
28.1218 + * @param x The X coordinate of the pixel location.
28.1219 + * @param y The Y coordinate of the pixel location.
28.1220 + * @param b The band to set.
28.1221 + * @param s The input sample as a float.
28.1222 + * @param data The DataBuffer containing the image data.
28.1223 + * @see #getSample(int, int, int, DataBuffer)
28.1224 + *
28.1225 + * @throws NullPointerException if data is null.
28.1226 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1227 + * the band index are not in bounds.
28.1228 + */
28.1229 + public void setSample(int x, int y, int b,
28.1230 + float s ,
28.1231 + DataBuffer data) {
28.1232 + int sample = (int)s;
28.1233 +
28.1234 + setSample(x, y, b, sample, data);
28.1235 + }
28.1236 +
28.1237 + /**
28.1238 + * Sets a sample in the specified band for the pixel located at (x,y)
28.1239 + * in the DataBuffer using a double for input.
28.1240 + * The default implementation of this method casts the input
28.1241 + * double sample to an int and then calls the
28.1242 + * <code>setSample(int, int, int, DataBuffer)</code> method using
28.1243 + * that int value.
28.1244 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1245 + * not in bounds.
28.1246 + * @param x The X coordinate of the pixel location.
28.1247 + * @param y The Y coordinate of the pixel location.
28.1248 + * @param b The band to set.
28.1249 + * @param s The input sample as a double.
28.1250 + * @param data The DataBuffer containing the image data.
28.1251 + * @see #getSample(int, int, int, DataBuffer)
28.1252 + *
28.1253 + * @throws NullPointerException if data is null.
28.1254 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1255 + * the band index are not in bounds.
28.1256 + */
28.1257 + public void setSample(int x, int y, int b,
28.1258 + double s,
28.1259 + DataBuffer data) {
28.1260 + int sample = (int)s;
28.1261 +
28.1262 + setSample(x, y, b, sample, data);
28.1263 + }
28.1264 +
28.1265 + /**
28.1266 + * Sets the samples in the specified band for the specified rectangle
28.1267 + * of pixels from an int array containing one sample per array element.
28.1268 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1269 + * not in bounds.
28.1270 + * @param x The X coordinate of the upper left pixel location.
28.1271 + * @param y The Y coordinate of the upper left pixel location.
28.1272 + * @param w The width of the pixel rectangle.
28.1273 + * @param h The height of the pixel rectangle.
28.1274 + * @param b The band to set.
28.1275 + * @param iArray The input samples in an int array.
28.1276 + * @param data The DataBuffer containing the image data.
28.1277 + * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
28.1278 + *
28.1279 + * @throws NullPointerException if iArray or data is null.
28.1280 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1281 + * the band index are not in bounds, or if iArray is too small to
28.1282 + * hold the input.
28.1283 + */
28.1284 + public void setSamples(int x, int y, int w, int h, int b,
28.1285 + int iArray[], DataBuffer data) {
28.1286 +
28.1287 + int Offset=0;
28.1288 +
28.1289 + for (int i=y; i<(y+h); i++) {
28.1290 + for (int j=x; j<(x+w); j++) {
28.1291 + setSample(j, i, b, iArray[Offset++], data);
28.1292 + }
28.1293 + }
28.1294 + }
28.1295 +
28.1296 + /**
28.1297 + * Sets the samples in the specified band for the specified rectangle
28.1298 + * of pixels from a float array containing one sample per array element.
28.1299 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1300 + * not in bounds.
28.1301 + * @param x The X coordinate of the upper left pixel location.
28.1302 + * @param y The Y coordinate of the upper left pixel location.
28.1303 + * @param w The width of the pixel rectangle.
28.1304 + * @param h The height of the pixel rectangle.
28.1305 + * @param b The band to set.
28.1306 + * @param fArray The input samples in a float array.
28.1307 + * @param data The DataBuffer containing the image data.
28.1308 + * @see #getSamples(int, int, int, int, int, float[], DataBuffer)
28.1309 + *
28.1310 + * @throws NullPointerException if fArray or data is null.
28.1311 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1312 + * the band index are not in bounds, or if fArray is too small to
28.1313 + * hold the input.
28.1314 + */
28.1315 + public void setSamples(int x, int y, int w, int h, int b,
28.1316 + float fArray[], DataBuffer data) {
28.1317 + int Offset=0;
28.1318 +
28.1319 + for (int i=y; i<(y+h); i++) {
28.1320 + for (int j=x; j<(x+w); j++) {
28.1321 + setSample(j, i, b, fArray[Offset++], data);
28.1322 + }
28.1323 + }
28.1324 + }
28.1325 +
28.1326 + /**
28.1327 + * Sets the samples in the specified band for the specified rectangle
28.1328 + * of pixels from a double array containing one sample per array element.
28.1329 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
28.1330 + * not in bounds.
28.1331 + * @param x The X coordinate of the upper left pixel location.
28.1332 + * @param y The Y coordinate of the upper left pixel location.
28.1333 + * @param w The width of the pixel rectangle.
28.1334 + * @param h The height of the pixel rectangle.
28.1335 + * @param b The band to set.
28.1336 + * @param dArray The input samples in a double array.
28.1337 + * @param data The DataBuffer containing the image data.
28.1338 + * @see #getSamples(int, int, int, int, int, double[], DataBuffer)
28.1339 + *
28.1340 + * @throws NullPointerException if dArray or data is null.
28.1341 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
28.1342 + * the band index are not in bounds, or if dArray is too small to
28.1343 + * hold the input.
28.1344 + */
28.1345 + public void setSamples(int x, int y, int w, int h, int b,
28.1346 + double dArray[], DataBuffer data) {
28.1347 + int Offset=0;
28.1348 +
28.1349 + for (int i=y; i<(y+h); i++) {
28.1350 + for (int j=x; j<(x+w); j++) {
28.1351 + setSample(j, i, b, dArray[Offset++], data);
28.1352 + }
28.1353 + }
28.1354 + }
28.1355 +
28.1356 + /**
28.1357 + * Creates a SampleModel which describes data in this SampleModel's
28.1358 + * format, but with a different width and height.
28.1359 + * @param w the width of the image data
28.1360 + * @param h the height of the image data
28.1361 + * @return a <code>SampleModel</code> describing the same image
28.1362 + * data as this <code>SampleModel</code>, but with a
28.1363 + * different size.
28.1364 + */
28.1365 + public abstract SampleModel createCompatibleSampleModel(int w, int h);
28.1366 +
28.1367 + /**
28.1368 + * Creates a new SampleModel
28.1369 + * with a subset of the bands of this
28.1370 + * SampleModel.
28.1371 + * @param bands the subset of bands of this <code>SampleModel</code>
28.1372 + * @return a <code>SampleModel</code> with a subset of bands of this
28.1373 + * <code>SampleModel</code>.
28.1374 + */
28.1375 + public abstract SampleModel createSubsetSampleModel(int bands[]);
28.1376 +
28.1377 + /**
28.1378 + * Creates a DataBuffer that corresponds to this SampleModel.
28.1379 + * The DataBuffer's width and height will match this SampleModel's.
28.1380 + * @return a <code>DataBuffer</code> corresponding to this
28.1381 + * <code>SampleModel</code>.
28.1382 + */
28.1383 + public abstract DataBuffer createDataBuffer();
28.1384 +
28.1385 + /** Returns the size in bits of samples for all bands.
28.1386 + * @return the size of samples for all bands.
28.1387 + */
28.1388 + public abstract int[] getSampleSize();
28.1389 +
28.1390 + /** Returns the size in bits of samples for the specified band.
28.1391 + * @param band the specified band
28.1392 + * @return the size of the samples of the specified band.
28.1393 + */
28.1394 + public abstract int getSampleSize(int band);
28.1395 +
28.1396 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/src/share/classes/java/awt/image/SinglePixelPackedSampleModel.java Thu Jun 12 11:46:57 2008 -0700
29.3 @@ -0,0 +1,805 @@
29.4 +/*
29.5 + * Portions Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved.
29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29.7 + *
29.8 + * This code is free software; you can redistribute it and/or modify it
29.9 + * under the terms of the GNU General Public License version 2 only, as
29.10 + * published by the Free Software Foundation. Sun designates this
29.11 + * particular file as subject to the "Classpath" exception as provided
29.12 + * by Sun in the LICENSE file that accompanied this code.
29.13 + *
29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29.17 + * version 2 for more details (a copy is included in the LICENSE file that
29.18 + * accompanied this code).
29.19 + *
29.20 + * You should have received a copy of the GNU General Public License version
29.21 + * 2 along with this work; if not, write to the Free Software Foundation,
29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29.23 + *
29.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
29.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
29.26 + * have any questions.
29.27 + */
29.28 +
29.29 +/* ****************************************************************
29.30 + ******************************************************************
29.31 + ******************************************************************
29.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
29.33 + *** As an unpublished work pursuant to Title 17 of the United
29.34 + *** States Code. All rights reserved.
29.35 + ******************************************************************
29.36 + ******************************************************************
29.37 + ******************************************************************/
29.38 +
29.39 +package java.awt.image;
29.40 +
29.41 +import java.util.Arrays;
29.42 +
29.43 +/**
29.44 + * This class represents pixel data packed such that the N samples which make
29.45 + * up a single pixel are stored in a single data array element, and each data
29.46 + * data array element holds samples for only one pixel.
29.47 + * This class supports
29.48 + * {@link DataBuffer#TYPE_BYTE TYPE_BYTE},
29.49 + * {@link DataBuffer#TYPE_USHORT TYPE_USHORT},
29.50 + * {@link DataBuffer#TYPE_INT TYPE_INT} data types.
29.51 + * All data array elements reside
29.52 + * in the first bank of a DataBuffer. Accessor methods are provided so
29.53 + * that the image data can be manipulated directly. Scanline stride is the
29.54 + * number of data array elements between a given sample and the corresponding
29.55 + * sample in the same column of the next scanline. Bit masks are the masks
29.56 + * required to extract the samples representing the bands of the pixel.
29.57 + * Bit offsets are the offsets in bits into the data array
29.58 + * element of the samples representing the bands of the pixel.
29.59 + * <p>
29.60 + * The following code illustrates extracting the bits of the sample
29.61 + * representing band <code>b</code> for pixel <code>x,y</code>
29.62 + * from DataBuffer <code>data</code>:
29.63 + * <pre>
29.64 + * int sample = data.getElem(y * scanlineStride + x);
29.65 + * sample = (sample & bitMasks[b]) >>> bitOffsets[b];
29.66 + * </pre>
29.67 + */
29.68 +
29.69 +public class SinglePixelPackedSampleModel extends SampleModel
29.70 +{
29.71 + /** Bit masks for all bands of the image data. */
29.72 + private int bitMasks[];
29.73 +
29.74 + /** Bit Offsets for all bands of the image data. */
29.75 + private int bitOffsets[];
29.76 +
29.77 + /** Bit sizes for all the bands of the image data. */
29.78 + private int bitSizes[];
29.79 +
29.80 + /** Maximum bit size. */
29.81 + private int maxBitSize;
29.82 +
29.83 + /** Line stride of the region of image data described by this
29.84 + * SinglePixelPackedSampleModel.
29.85 + */
29.86 + private int scanlineStride;
29.87 +
29.88 + private static native void initIDs();
29.89 + static {
29.90 + ColorModel.loadLibraries();
29.91 + initIDs();
29.92 + }
29.93 +
29.94 + /**
29.95 + * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands.
29.96 + * Each sample is stored in a data array element in the position of
29.97 + * its corresponding bit mask. Each bit mask must be contiguous and
29.98 + * masks must not overlap.
29.99 + * @param dataType The data type for storing samples.
29.100 + * @param w The width (in pixels) of the region of the
29.101 + * image data described.
29.102 + * @param h The height (in pixels) of the region of the
29.103 + * image data described.
29.104 + * @param bitMasks The bit masks for all bands.
29.105 + * @throws IllegalArgumentException if <code>dataType</code> is not
29.106 + * either <code>DataBuffer.TYPE_BYTE</code>,
29.107 + * <code>DataBuffer.TYPE_USHORT</code>, or
29.108 + * <code>DataBuffer.TYPE_INT</code>
29.109 + */
29.110 + public SinglePixelPackedSampleModel(int dataType, int w, int h,
29.111 + int bitMasks[]) {
29.112 + this(dataType, w, h, w, bitMasks);
29.113 + if (dataType != DataBuffer.TYPE_BYTE &&
29.114 + dataType != DataBuffer.TYPE_USHORT &&
29.115 + dataType != DataBuffer.TYPE_INT) {
29.116 + throw new IllegalArgumentException("Unsupported data type "+
29.117 + dataType);
29.118 + }
29.119 + }
29.120 +
29.121 + /**
29.122 + * Constructs a SinglePixelPackedSampleModel with bitMasks.length bands
29.123 + * and a scanline stride equal to scanlineStride data array elements.
29.124 + * Each sample is stored in a data array element in the position of
29.125 + * its corresponding bit mask. Each bit mask must be contiguous and
29.126 + * masks must not overlap.
29.127 + * @param dataType The data type for storing samples.
29.128 + * @param w The width (in pixels) of the region of
29.129 + * image data described.
29.130 + * @param h The height (in pixels) of the region of
29.131 + * image data described.
29.132 + * @param scanlineStride The line stride of the image data.
29.133 + * @param bitMasks The bit masks for all bands.
29.134 + * @throws IllegalArgumentException if <code>w</code> or
29.135 + * <code>h</code> is not greater than 0
29.136 + * @throws IllegalArgumentException if any mask in
29.137 + * <code>bitMask</code> is not contiguous
29.138 + * @throws IllegalArgumentException if <code>dataType</code> is not
29.139 + * either <code>DataBuffer.TYPE_BYTE</code>,
29.140 + * <code>DataBuffer.TYPE_USHORT</code>, or
29.141 + * <code>DataBuffer.TYPE_INT</code>
29.142 + */
29.143 + public SinglePixelPackedSampleModel(int dataType, int w, int h,
29.144 + int scanlineStride, int bitMasks[]) {
29.145 + super(dataType, w, h, bitMasks.length);
29.146 + if (dataType != DataBuffer.TYPE_BYTE &&
29.147 + dataType != DataBuffer.TYPE_USHORT &&
29.148 + dataType != DataBuffer.TYPE_INT) {
29.149 + throw new IllegalArgumentException("Unsupported data type "+
29.150 + dataType);
29.151 + }
29.152 + this.dataType = dataType;
29.153 + this.bitMasks = (int[]) bitMasks.clone();
29.154 + this.scanlineStride = scanlineStride;
29.155 +
29.156 + this.bitOffsets = new int[numBands];
29.157 + this.bitSizes = new int[numBands];
29.158 +
29.159 + this.maxBitSize = 0;
29.160 + for (int i=0; i<numBands; i++) {
29.161 + int bitOffset = 0, bitSize = 0, mask;
29.162 + mask = bitMasks[i];
29.163 +
29.164 + if (mask != 0) {
29.165 + while ((mask & 1) == 0) {
29.166 + mask = mask >>> 1;
29.167 + bitOffset++;
29.168 + }
29.169 + while ((mask & 1) == 1) {
29.170 + mask = mask >>> 1;
29.171 + bitSize++;
29.172 + }
29.173 + if (mask != 0) {
29.174 + throw new IllegalArgumentException("Mask "+bitMasks[i]+
29.175 + " must be contiguous");
29.176 + }
29.177 + }
29.178 + bitOffsets[i] = bitOffset;
29.179 + bitSizes[i] = bitSize;
29.180 + if (bitSize > maxBitSize) {
29.181 + maxBitSize = bitSize;
29.182 + }
29.183 + }
29.184 + }
29.185 +
29.186 + /**
29.187 + * Returns the number of data elements needed to transfer one pixel
29.188 + * via the getDataElements and setDataElements methods.
29.189 + * For a SinglePixelPackedSampleModel, this is one.
29.190 + */
29.191 + public int getNumDataElements() {
29.192 + return 1;
29.193 + }
29.194 +
29.195 + /**
29.196 + * Returns the size of the buffer (in data array elements)
29.197 + * needed for a data buffer that matches this
29.198 + * SinglePixelPackedSampleModel.
29.199 + */
29.200 + private long getBufferSize() {
29.201 + long size = scanlineStride * (height-1) + width;
29.202 + return size;
29.203 + }
29.204 +
29.205 + /**
29.206 + * Creates a new SinglePixelPackedSampleModel with the specified
29.207 + * width and height. The new SinglePixelPackedSampleModel will have the
29.208 + * same storage data type and bit masks as this
29.209 + * SinglePixelPackedSampleModel.
29.210 + * @param w the width of the resulting <code>SampleModel</code>
29.211 + * @param h the height of the resulting <code>SampleModel</code>
29.212 + * @return a <code>SinglePixelPackedSampleModel</code> with the
29.213 + * specified width and height.
29.214 + * @throws IllegalArgumentException if <code>w</code> or
29.215 + * <code>h</code> is not greater than 0
29.216 + */
29.217 + public SampleModel createCompatibleSampleModel(int w, int h) {
29.218 + SampleModel sampleModel = new SinglePixelPackedSampleModel(dataType, w, h,
29.219 + bitMasks);
29.220 + return sampleModel;
29.221 + }
29.222 +
29.223 + /**
29.224 + * Creates a DataBuffer that corresponds to this
29.225 + * SinglePixelPackedSampleModel. The DataBuffer's data type and size
29.226 + * will be consistent with this SinglePixelPackedSampleModel. The
29.227 + * DataBuffer will have a single bank.
29.228 + */
29.229 + public DataBuffer createDataBuffer() {
29.230 + DataBuffer dataBuffer = null;
29.231 +
29.232 + int size = (int)getBufferSize();
29.233 + switch (dataType) {
29.234 + case DataBuffer.TYPE_BYTE:
29.235 + dataBuffer = new DataBufferByte(size);
29.236 + break;
29.237 + case DataBuffer.TYPE_USHORT:
29.238 + dataBuffer = new DataBufferUShort(size);
29.239 + break;
29.240 + case DataBuffer.TYPE_INT:
29.241 + dataBuffer = new DataBufferInt(size);
29.242 + break;
29.243 + }
29.244 + return dataBuffer;
29.245 + }
29.246 +
29.247 + /** Returns the number of bits per sample for all bands. */
29.248 + public int[] getSampleSize() {
29.249 + int mask;
29.250 + int sampleSize[] = new int [numBands];
29.251 + for (int i=0; i<numBands; i++) {
29.252 + sampleSize[i] = 0;
29.253 + mask = bitMasks[i] >>> bitOffsets[i];
29.254 + while ((mask & 1) != 0) {
29.255 + sampleSize[i] ++;
29.256 + mask = mask >>> 1;
29.257 + }
29.258 + }
29.259 +
29.260 + return sampleSize;
29.261 + }
29.262 +
29.263 + /** Returns the number of bits per sample for the specified band. */
29.264 + public int getSampleSize(int band) {
29.265 + int sampleSize = 0;
29.266 + int mask = bitMasks[band] >>> bitOffsets[band];
29.267 + while ((mask & 1) != 0) {
29.268 + sampleSize ++;
29.269 + mask = mask >>> 1;
29.270 + }
29.271 +
29.272 + return sampleSize;
29.273 + }
29.274 +
29.275 + /** Returns the offset (in data array elements) of pixel (x,y).
29.276 + * The data element containing pixel <code>x,y</code>
29.277 + * can be retrieved from a DataBuffer <code>data</code> with a
29.278 + * SinglePixelPackedSampleModel <code>sppsm</code> as:
29.279 + * <pre>
29.280 + * data.getElem(sppsm.getOffset(x, y));
29.281 + * </pre>
29.282 + * @param x the X coordinate of the specified pixel
29.283 + * @param y the Y coordinate of the specified pixel
29.284 + * @return the offset of the specified pixel.
29.285 + */
29.286 + public int getOffset(int x, int y) {
29.287 + int offset = y * scanlineStride + x;
29.288 + return offset;
29.289 + }
29.290 +
29.291 + /** Returns the bit offsets into the data array element representing
29.292 + * a pixel for all bands.
29.293 + * @return the bit offsets representing a pixel for all bands.
29.294 + */
29.295 + public int [] getBitOffsets() {
29.296 + return (int[])bitOffsets.clone();
29.297 + }
29.298 +
29.299 + /** Returns the bit masks for all bands.
29.300 + * @return the bit masks for all bands.
29.301 + */
29.302 + public int [] getBitMasks() {
29.303 + return (int[])bitMasks.clone();
29.304 + }
29.305 +
29.306 + /** Returns the scanline stride of this SinglePixelPackedSampleModel.
29.307 + * @return the scanline stride of this
29.308 + * <code>SinglePixelPackedSampleModel</code>.
29.309 + */
29.310 + public int getScanlineStride() {
29.311 + return scanlineStride;
29.312 + }
29.313 +
29.314 + /**
29.315 + * This creates a new SinglePixelPackedSampleModel with a subset of the
29.316 + * bands of this SinglePixelPackedSampleModel. The new
29.317 + * SinglePixelPackedSampleModel can be used with any DataBuffer that the
29.318 + * existing SinglePixelPackedSampleModel can be used with. The new
29.319 + * SinglePixelPackedSampleModel/DataBuffer combination will represent
29.320 + * an image with a subset of the bands of the original
29.321 + * SinglePixelPackedSampleModel/DataBuffer combination.
29.322 + * @exception RasterFormatException if the length of the bands argument is
29.323 + * greater than the number of bands in
29.324 + * the sample model.
29.325 + */
29.326 + public SampleModel createSubsetSampleModel(int bands[]) {
29.327 + if (bands.length > numBands)
29.328 + throw new RasterFormatException("There are only " +
29.329 + numBands +
29.330 + " bands");
29.331 + int newBitMasks[] = new int[bands.length];
29.332 + for (int i=0; i<bands.length; i++)
29.333 + newBitMasks[i] = bitMasks[bands[i]];
29.334 +
29.335 + return new SinglePixelPackedSampleModel(this.dataType, width, height,
29.336 + this.scanlineStride, newBitMasks);
29.337 + }
29.338 +
29.339 + /**
29.340 + * Returns data for a single pixel in a primitive array of type
29.341 + * TransferType. For a SinglePixelPackedSampleModel, the array will
29.342 + * have one element, and the type will be the same as the storage
29.343 + * data type. Generally, obj
29.344 + * should be passed in as null, so that the Object will be created
29.345 + * automatically and will be of the right primitive data type.
29.346 + * <p>
29.347 + * The following code illustrates transferring data for one pixel from
29.348 + * DataBuffer <code>db1</code>, whose storage layout is described by
29.349 + * SinglePixelPackedSampleModel <code>sppsm1</code>, to
29.350 + * DataBuffer <code>db2</code>, whose storage layout is described by
29.351 + * SinglePixelPackedSampleModel <code>sppsm2</code>.
29.352 + * The transfer will generally be more efficient than using
29.353 + * getPixel/setPixel.
29.354 + * <pre>
29.355 + * SinglePixelPackedSampleModel sppsm1, sppsm2;
29.356 + * DataBufferInt db1, db2;
29.357 + * sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
29.358 + * db1), db2);
29.359 + * </pre>
29.360 + * Using getDataElements/setDataElements to transfer between two
29.361 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
29.362 + * the same number of bands, corresponding bands have the same number of
29.363 + * bits per sample, and the TransferTypes are the same.
29.364 + * <p>
29.365 + * If obj is non-null, it should be a primitive array of type TransferType.
29.366 + * Otherwise, a ClassCastException is thrown. An
29.367 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.368 + * not in bounds, or if obj is non-null and is not large enough to hold
29.369 + * the pixel data.
29.370 + * @param x The X coordinate of the pixel location.
29.371 + * @param y The Y coordinate of the pixel location.
29.372 + * @param obj If non-null, a primitive array in which to return
29.373 + * the pixel data.
29.374 + * @param data The DataBuffer containing the image data.
29.375 + * @return the data for the specified pixel.
29.376 + * @see #setDataElements(int, int, Object, DataBuffer)
29.377 + */
29.378 + public Object getDataElements(int x, int y, Object obj, DataBuffer data) {
29.379 + // Bounds check for 'b' will be performed automatically
29.380 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.381 + throw new ArrayIndexOutOfBoundsException
29.382 + ("Coordinate out of bounds!");
29.383 + }
29.384 +
29.385 + int type = getTransferType();
29.386 +
29.387 + switch(type) {
29.388 +
29.389 + case DataBuffer.TYPE_BYTE:
29.390 +
29.391 + byte[] bdata;
29.392 +
29.393 + if (obj == null)
29.394 + bdata = new byte[1];
29.395 + else
29.396 + bdata = (byte[])obj;
29.397 +
29.398 + bdata[0] = (byte)data.getElem(y * scanlineStride + x);
29.399 +
29.400 + obj = (Object)bdata;
29.401 + break;
29.402 +
29.403 + case DataBuffer.TYPE_USHORT:
29.404 +
29.405 + short[] sdata;
29.406 +
29.407 + if (obj == null)
29.408 + sdata = new short[1];
29.409 + else
29.410 + sdata = (short[])obj;
29.411 +
29.412 + sdata[0] = (short)data.getElem(y * scanlineStride + x);
29.413 +
29.414 + obj = (Object)sdata;
29.415 + break;
29.416 +
29.417 + case DataBuffer.TYPE_INT:
29.418 +
29.419 + int[] idata;
29.420 +
29.421 + if (obj == null)
29.422 + idata = new int[1];
29.423 + else
29.424 + idata = (int[])obj;
29.425 +
29.426 + idata[0] = data.getElem(y * scanlineStride + x);
29.427 +
29.428 + obj = (Object)idata;
29.429 + break;
29.430 + }
29.431 +
29.432 + return obj;
29.433 + }
29.434 +
29.435 + /**
29.436 + * Returns all samples in for the specified pixel in an int array.
29.437 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.438 + * not in bounds.
29.439 + * @param x The X coordinate of the pixel location.
29.440 + * @param y The Y coordinate of the pixel location.
29.441 + * @param iArray If non-null, returns the samples in this array
29.442 + * @param data The DataBuffer containing the image data.
29.443 + * @return all samples for the specified pixel.
29.444 + * @see #setPixel(int, int, int[], DataBuffer)
29.445 + */
29.446 + public int [] getPixel(int x, int y, int iArray[], DataBuffer data) {
29.447 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.448 + throw new ArrayIndexOutOfBoundsException
29.449 + ("Coordinate out of bounds!");
29.450 + }
29.451 + int pixels[];
29.452 + if (iArray == null) {
29.453 + pixels = new int [numBands];
29.454 + } else {
29.455 + pixels = iArray;
29.456 + }
29.457 +
29.458 + int value = data.getElem(y * scanlineStride + x);
29.459 + for (int i=0; i<numBands; i++) {
29.460 + pixels[i] = (value & bitMasks[i]) >>> bitOffsets[i];
29.461 + }
29.462 + return pixels;
29.463 + }
29.464 +
29.465 + /**
29.466 + * Returns all samples for the specified rectangle of pixels in
29.467 + * an int array, one sample per array element.
29.468 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.469 + * not in bounds.
29.470 + * @param x The X coordinate of the upper left pixel location.
29.471 + * @param y The Y coordinate of the upper left pixel location.
29.472 + * @param w The width of the pixel rectangle.
29.473 + * @param h The height of the pixel rectangle.
29.474 + * @param iArray If non-null, returns the samples in this array.
29.475 + * @param data The DataBuffer containing the image data.
29.476 + * @return all samples for the specified region of pixels.
29.477 + * @see #setPixels(int, int, int, int, int[], DataBuffer)
29.478 + */
29.479 + public int[] getPixels(int x, int y, int w, int h,
29.480 + int iArray[], DataBuffer data) {
29.481 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
29.482 + throw new ArrayIndexOutOfBoundsException
29.483 + ("Coordinate out of bounds!");
29.484 + }
29.485 + int pixels[];
29.486 + if (iArray != null) {
29.487 + pixels = iArray;
29.488 + } else {
29.489 + pixels = new int [w*h*numBands];
29.490 + }
29.491 + int lineOffset = y*scanlineStride + x;
29.492 + int dstOffset = 0;
29.493 +
29.494 + for (int i = 0; i < h; i++) {
29.495 + for (int j = 0; j < w; j++) {
29.496 + int value = data.getElem(lineOffset+j);
29.497 + for (int k=0; k < numBands; k++) {
29.498 + pixels[dstOffset++] =
29.499 + ((value & bitMasks[k]) >>> bitOffsets[k]);
29.500 + }
29.501 + }
29.502 + lineOffset += scanlineStride;
29.503 + }
29.504 + return pixels;
29.505 + }
29.506 +
29.507 + /**
29.508 + * Returns as int the sample in a specified band for the pixel
29.509 + * located at (x,y).
29.510 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.511 + * not in bounds.
29.512 + * @param x The X coordinate of the pixel location.
29.513 + * @param y The Y coordinate of the pixel location.
29.514 + * @param b The band to return.
29.515 + * @param data The DataBuffer containing the image data.
29.516 + * @return the sample in a specified band for the specified
29.517 + * pixel.
29.518 + * @see #setSample(int, int, int, int, DataBuffer)
29.519 + */
29.520 + public int getSample(int x, int y, int b, DataBuffer data) {
29.521 + // Bounds check for 'b' will be performed automatically
29.522 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.523 + throw new ArrayIndexOutOfBoundsException
29.524 + ("Coordinate out of bounds!");
29.525 + }
29.526 + int sample = data.getElem(y * scanlineStride + x);
29.527 + return ((sample & bitMasks[b]) >>> bitOffsets[b]);
29.528 + }
29.529 +
29.530 + /**
29.531 + * Returns the samples for a specified band for the specified rectangle
29.532 + * of pixels in an int array, one sample per array element.
29.533 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.534 + * not in bounds.
29.535 + * @param x The X coordinate of the upper left pixel location.
29.536 + * @param y The Y coordinate of the upper left pixel location.
29.537 + * @param w The width of the pixel rectangle.
29.538 + * @param h The height of the pixel rectangle.
29.539 + * @param b The band to return.
29.540 + * @param iArray If non-null, returns the samples in this array.
29.541 + * @param data The DataBuffer containing the image data.
29.542 + * @return the samples for the specified band for the specified
29.543 + * region of pixels.
29.544 + * @see #setSamples(int, int, int, int, int, int[], DataBuffer)
29.545 + */
29.546 + public int[] getSamples(int x, int y, int w, int h, int b,
29.547 + int iArray[], DataBuffer data) {
29.548 + // Bounds check for 'b' will be performed automatically
29.549 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
29.550 + throw new ArrayIndexOutOfBoundsException
29.551 + ("Coordinate out of bounds!");
29.552 + }
29.553 + int samples[];
29.554 + if (iArray != null) {
29.555 + samples = iArray;
29.556 + } else {
29.557 + samples = new int [w*h];
29.558 + }
29.559 + int lineOffset = y*scanlineStride + x;
29.560 + int dstOffset = 0;
29.561 +
29.562 + for (int i = 0; i < h; i++) {
29.563 + for (int j = 0; j < w; j++) {
29.564 + int value = data.getElem(lineOffset+j);
29.565 + samples[dstOffset++] =
29.566 + ((value & bitMasks[b]) >>> bitOffsets[b]);
29.567 + }
29.568 + lineOffset += scanlineStride;
29.569 + }
29.570 + return samples;
29.571 + }
29.572 +
29.573 + /**
29.574 + * Sets the data for a single pixel in the specified DataBuffer from a
29.575 + * primitive array of type TransferType. For a
29.576 + * SinglePixelPackedSampleModel, only the first element of the array
29.577 + * will hold valid data, and the type of the array must be the same as
29.578 + * the storage data type of the SinglePixelPackedSampleModel.
29.579 + * <p>
29.580 + * The following code illustrates transferring data for one pixel from
29.581 + * DataBuffer <code>db1</code>, whose storage layout is described by
29.582 + * SinglePixelPackedSampleModel <code>sppsm1</code>,
29.583 + * to DataBuffer <code>db2</code>, whose storage layout is described by
29.584 + * SinglePixelPackedSampleModel <code>sppsm2</code>.
29.585 + * The transfer will generally be more efficient than using
29.586 + * getPixel/setPixel.
29.587 + * <pre>
29.588 + * SinglePixelPackedSampleModel sppsm1, sppsm2;
29.589 + * DataBufferInt db1, db2;
29.590 + * sppsm2.setDataElements(x, y, sppsm1.getDataElements(x, y, null,
29.591 + * db1), db2);
29.592 + * </pre>
29.593 + * Using getDataElements/setDataElements to transfer between two
29.594 + * DataBuffer/SampleModel pairs is legitimate if the SampleModels have
29.595 + * the same number of bands, corresponding bands have the same number of
29.596 + * bits per sample, and the TransferTypes are the same.
29.597 + * <p>
29.598 + * obj must be a primitive array of type TransferType. Otherwise,
29.599 + * a ClassCastException is thrown. An
29.600 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.601 + * not in bounds, or if obj is not large enough to hold the pixel data.
29.602 + * @param x The X coordinate of the pixel location.
29.603 + * @param y The Y coordinate of the pixel location.
29.604 + * @param obj A primitive array containing pixel data.
29.605 + * @param data The DataBuffer containing the image data.
29.606 + * @see #getDataElements(int, int, Object, DataBuffer)
29.607 + */
29.608 + public void setDataElements(int x, int y, Object obj, DataBuffer data) {
29.609 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.610 + throw new ArrayIndexOutOfBoundsException
29.611 + ("Coordinate out of bounds!");
29.612 + }
29.613 +
29.614 + int type = getTransferType();
29.615 +
29.616 + switch(type) {
29.617 +
29.618 + case DataBuffer.TYPE_BYTE:
29.619 +
29.620 + byte[] barray = (byte[])obj;
29.621 + data.setElem(y*scanlineStride+x, ((int)barray[0])&0xff);
29.622 + break;
29.623 +
29.624 + case DataBuffer.TYPE_USHORT:
29.625 +
29.626 + short[] sarray = (short[])obj;
29.627 + data.setElem(y*scanlineStride+x, ((int)sarray[0])&0xffff);
29.628 + break;
29.629 +
29.630 + case DataBuffer.TYPE_INT:
29.631 +
29.632 + int[] iarray = (int[])obj;
29.633 + data.setElem(y*scanlineStride+x, iarray[0]);
29.634 + break;
29.635 + }
29.636 + }
29.637 +
29.638 + /**
29.639 + * Sets a pixel in the DataBuffer using an int array of samples for input.
29.640 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.641 + * not in bounds.
29.642 + * @param x The X coordinate of the pixel location.
29.643 + * @param y The Y coordinate of the pixel location.
29.644 + * @param iArray The input samples in an int array.
29.645 + * @param data The DataBuffer containing the image data.
29.646 + * @see #getPixel(int, int, int[], DataBuffer)
29.647 + */
29.648 + public void setPixel(int x, int y,
29.649 + int iArray[],
29.650 + DataBuffer data) {
29.651 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.652 + throw new ArrayIndexOutOfBoundsException
29.653 + ("Coordinate out of bounds!");
29.654 + }
29.655 + int lineOffset = y * scanlineStride + x;
29.656 + int value = data.getElem(lineOffset);
29.657 + for (int i=0; i < numBands; i++) {
29.658 + value &= ~bitMasks[i];
29.659 + value |= ((iArray[i] << bitOffsets[i]) & bitMasks[i]);
29.660 + }
29.661 + data.setElem(lineOffset, value);
29.662 + }
29.663 +
29.664 + /**
29.665 + * Sets all samples for a rectangle of pixels from an int array containing
29.666 + * one sample per array element.
29.667 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.668 + * not in bounds.
29.669 + * @param x The X coordinate of the upper left pixel location.
29.670 + * @param y The Y coordinate of the upper left pixel location.
29.671 + * @param w The width of the pixel rectangle.
29.672 + * @param h The height of the pixel rectangle.
29.673 + * @param iArray The input samples in an int array.
29.674 + * @param data The DataBuffer containing the image data.
29.675 + * @see #getPixels(int, int, int, int, int[], DataBuffer)
29.676 + */
29.677 + public void setPixels(int x, int y, int w, int h,
29.678 + int iArray[], DataBuffer data) {
29.679 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
29.680 + throw new ArrayIndexOutOfBoundsException
29.681 + ("Coordinate out of bounds!");
29.682 + }
29.683 +
29.684 + int lineOffset = y*scanlineStride + x;
29.685 + int srcOffset = 0;
29.686 +
29.687 + for (int i = 0; i < h; i++) {
29.688 + for (int j = 0; j < w; j++) {
29.689 + int value = data.getElem(lineOffset+j);
29.690 + for (int k=0; k < numBands; k++) {
29.691 + value &= ~bitMasks[k];
29.692 + int srcValue = iArray[srcOffset++];
29.693 + value |= ((srcValue << bitOffsets[k])
29.694 + & bitMasks[k]);
29.695 + }
29.696 + data.setElem(lineOffset+j, value);
29.697 + }
29.698 + lineOffset += scanlineStride;
29.699 + }
29.700 + }
29.701 +
29.702 + /**
29.703 + * Sets a sample in the specified band for the pixel located at (x,y)
29.704 + * in the DataBuffer using an int for input.
29.705 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.706 + * not in bounds.
29.707 + * @param x The X coordinate of the pixel location.
29.708 + * @param y The Y coordinate of the pixel location.
29.709 + * @param b The band to set.
29.710 + * @param s The input sample as an int.
29.711 + * @param data The DataBuffer containing the image data.
29.712 + * @see #getSample(int, int, int, DataBuffer)
29.713 + */
29.714 + public void setSample(int x, int y, int b, int s,
29.715 + DataBuffer data) {
29.716 + // Bounds check for 'b' will be performed automatically
29.717 + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) {
29.718 + throw new ArrayIndexOutOfBoundsException
29.719 + ("Coordinate out of bounds!");
29.720 + }
29.721 + int value = data.getElem(y*scanlineStride + x);
29.722 + value &= ~bitMasks[b];
29.723 + value |= (s << bitOffsets[b]) & bitMasks[b];
29.724 + data.setElem(y*scanlineStride + x,value);
29.725 + }
29.726 +
29.727 + /**
29.728 + * Sets the samples in the specified band for the specified rectangle
29.729 + * of pixels from an int array containing one sample per array element.
29.730 + * ArrayIndexOutOfBoundsException may be thrown if the coordinates are
29.731 + * not in bounds.
29.732 + * @param x The X coordinate of the upper left pixel location.
29.733 + * @param y The Y coordinate of the upper left pixel location.
29.734 + * @param w The width of the pixel rectangle.
29.735 + * @param h The height of the pixel rectangle.
29.736 + * @param b The band to set.
29.737 + * @param iArray The input samples in an int array.
29.738 + * @param data The DataBuffer containing the image data.
29.739 + * @see #getSamples(int, int, int, int, int, int[], DataBuffer)
29.740 + */
29.741 + public void setSamples(int x, int y, int w, int h, int b,
29.742 + int iArray[], DataBuffer data) {
29.743 + // Bounds check for 'b' will be performed automatically
29.744 + if ((x < 0) || (y < 0) || (x + w > width) || (y + h > height)) {
29.745 + throw new ArrayIndexOutOfBoundsException
29.746 + ("Coordinate out of bounds!");
29.747 + }
29.748 + int lineOffset = y*scanlineStride + x;
29.749 + int srcOffset = 0;
29.750 +
29.751 + for (int i = 0; i < h; i++) {
29.752 + for (int j = 0; j < w; j++) {
29.753 + int value = data.getElem(lineOffset+j);
29.754 + value &= ~bitMasks[b];
29.755 + int sample = iArray[srcOffset++];
29.756 + value |= ((int)sample << bitOffsets[b]) & bitMasks[b];
29.757 + data.setElem(lineOffset+j,value);
29.758 + }
29.759 + lineOffset += scanlineStride;
29.760 + }
29.761 + }
29.762 +
29.763 + public boolean equals(Object o) {
29.764 + if ((o == null) || !(o instanceof SinglePixelPackedSampleModel)) {
29.765 + return false;
29.766 + }
29.767 +
29.768 + SinglePixelPackedSampleModel that = (SinglePixelPackedSampleModel)o;
29.769 + return this.width == that.width &&
29.770 + this.height == that.height &&
29.771 + this.numBands == that.numBands &&
29.772 + this.dataType == that.dataType &&
29.773 + Arrays.equals(this.bitMasks, that.bitMasks) &&
29.774 + Arrays.equals(this.bitOffsets, that.bitOffsets) &&
29.775 + Arrays.equals(this.bitSizes, that.bitSizes) &&
29.776 + this.maxBitSize == that.maxBitSize &&
29.777 + this.scanlineStride == that.scanlineStride;
29.778 + }
29.779 +
29.780 + // If we implement equals() we must also implement hashCode
29.781 + public int hashCode() {
29.782 + int hash = 0;
29.783 + hash = width;
29.784 + hash <<= 8;
29.785 + hash ^= height;
29.786 + hash <<= 8;
29.787 + hash ^= numBands;
29.788 + hash <<= 8;
29.789 + hash ^= dataType;
29.790 + hash <<= 8;
29.791 + for (int i = 0; i < bitMasks.length; i++) {
29.792 + hash ^= bitMasks[i];
29.793 + hash <<= 8;
29.794 + }
29.795 + for (int i = 0; i < bitOffsets.length; i++) {
29.796 + hash ^= bitOffsets[i];
29.797 + hash <<= 8;
29.798 + }
29.799 + for (int i = 0; i < bitSizes.length; i++) {
29.800 + hash ^= bitSizes[i];
29.801 + hash <<= 8;
29.802 + }
29.803 + hash ^= maxBitSize;
29.804 + hash <<= 8;
29.805 + hash ^= scanlineStride;
29.806 + return hash;
29.807 + }
29.808 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/src/share/classes/java/awt/image/WritableRaster.java Thu Jun 12 11:46:57 2008 -0700
30.3 @@ -0,0 +1,741 @@
30.4 +/*
30.5 + * Portions Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
30.7 + *
30.8 + * This code is free software; you can redistribute it and/or modify it
30.9 + * under the terms of the GNU General Public License version 2 only, as
30.10 + * published by the Free Software Foundation. Sun designates this
30.11 + * particular file as subject to the "Classpath" exception as provided
30.12 + * by Sun in the LICENSE file that accompanied this code.
30.13 + *
30.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
30.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
30.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30.17 + * version 2 for more details (a copy is included in the LICENSE file that
30.18 + * accompanied this code).
30.19 + *
30.20 + * You should have received a copy of the GNU General Public License version
30.21 + * 2 along with this work; if not, write to the Free Software Foundation,
30.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30.23 + *
30.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
30.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
30.26 + * have any questions.
30.27 + */
30.28 +
30.29 +/* ****************************************************************
30.30 + ******************************************************************
30.31 + ******************************************************************
30.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
30.33 + *** As an unpublished work pursuant to Title 17 of the United
30.34 + *** States Code. All rights reserved.
30.35 + ******************************************************************
30.36 + ******************************************************************
30.37 + ******************************************************************/
30.38 +
30.39 +package java.awt.image;
30.40 +import java.awt.Rectangle;
30.41 +import java.awt.Point;
30.42 +
30.43 +/**
30.44 + * This class extends Raster to provide pixel writing capabilities.
30.45 + * Refer to the class comment for Raster for descriptions of how
30.46 + * a Raster stores pixels.
30.47 + *
30.48 + * <p> The constructors of this class are protected. To instantiate
30.49 + * a WritableRaster, use one of the createWritableRaster factory methods
30.50 + * in the Raster class.
30.51 + */
30.52 +public class WritableRaster extends Raster {
30.53 +
30.54 + /**
30.55 + * Constructs a WritableRaster with the given SampleModel. The
30.56 + * WritableRaster's upper left corner is origin and it is the
30.57 + * same size as the SampleModel. A DataBuffer large enough to
30.58 + * describe the WritableRaster is automatically created.
30.59 + * @param sampleModel The SampleModel that specifies the layout.
30.60 + * @param origin The Point that specifies the origin.
30.61 + * @throws RasterFormatException if computing either
30.62 + * <code>origin.x + sampleModel.getWidth()</code> or
30.63 + * <code>origin.y + sampleModel.getHeight()</code> results
30.64 + * in integer overflow
30.65 + */
30.66 + protected WritableRaster(SampleModel sampleModel,
30.67 + Point origin) {
30.68 + this(sampleModel,
30.69 + sampleModel.createDataBuffer(),
30.70 + new Rectangle(origin.x,
30.71 + origin.y,
30.72 + sampleModel.getWidth(),
30.73 + sampleModel.getHeight()),
30.74 + origin,
30.75 + null);
30.76 + }
30.77 +
30.78 + /**
30.79 + * Constructs a WritableRaster with the given SampleModel and DataBuffer.
30.80 + * The WritableRaster's upper left corner is origin and it is the same
30.81 + * size as the SampleModel. The DataBuffer is not initialized and must
30.82 + * be compatible with SampleModel.
30.83 + * @param sampleModel The SampleModel that specifies the layout.
30.84 + * @param dataBuffer The DataBuffer that contains the image data.
30.85 + * @param origin The Point that specifies the origin.
30.86 + * @throws RasterFormatException if computing either
30.87 + * <code>origin.x + sampleModel.getWidth()</code> or
30.88 + * <code>origin.y + sampleModel.getHeight()</code> results
30.89 + * in integer overflow
30.90 + */
30.91 + protected WritableRaster(SampleModel sampleModel,
30.92 + DataBuffer dataBuffer,
30.93 + Point origin) {
30.94 + this(sampleModel,
30.95 + dataBuffer,
30.96 + new Rectangle(origin.x,
30.97 + origin.y,
30.98 + sampleModel.getWidth(),
30.99 + sampleModel.getHeight()),
30.100 + origin,
30.101 + null);
30.102 + }
30.103 +
30.104 + /**
30.105 + * Constructs a WritableRaster with the given SampleModel, DataBuffer,
30.106 + * and parent. aRegion specifies the bounding rectangle of the new
30.107 + * Raster. When translated into the base Raster's coordinate
30.108 + * system, aRegion must be contained by the base Raster.
30.109 + * (The base Raster is the Raster's ancestor which has no parent.)
30.110 + * sampleModelTranslate specifies the sampleModelTranslateX and
30.111 + * sampleModelTranslateY values of the new Raster.
30.112 + *
30.113 + * Note that this constructor should generally be called by other
30.114 + * constructors or create methods, it should not be used directly.
30.115 + * @param sampleModel The SampleModel that specifies the layout.
30.116 + * @param dataBuffer The DataBuffer that contains the image data.
30.117 + * @param aRegion The Rectangle that specifies the image area.
30.118 + * @param sampleModelTranslate The Point that specifies the translation
30.119 + * from SampleModel to Raster coordinates.
30.120 + * @param parent The parent (if any) of this raster.
30.121 + * @throws RasterFormatException if <code>aRegion</code> has width
30.122 + * or height less than or equal to zero, or computing either
30.123 + * <code>aRegion.x + aRegion.width</code> or
30.124 + * <code>aRegion.y + aRegion.height</code> results in integer
30.125 + * overflow
30.126 + */
30.127 + protected WritableRaster(SampleModel sampleModel,
30.128 + DataBuffer dataBuffer,
30.129 + Rectangle aRegion,
30.130 + Point sampleModelTranslate,
30.131 + WritableRaster parent){
30.132 + super(sampleModel,dataBuffer,aRegion,sampleModelTranslate,parent);
30.133 + }
30.134 +
30.135 + /** Returns the parent WritableRaster (if any) of this WritableRaster,
30.136 + * or else null.
30.137 + * @return the parent of this <code>WritableRaster</code>, or
30.138 + * <code>null</code>.
30.139 + */
30.140 + public WritableRaster getWritableParent() {
30.141 + return (WritableRaster)parent;
30.142 + }
30.143 +
30.144 + /**
30.145 + * Create a WritableRaster with the same size, SampleModel and DataBuffer
30.146 + * as this one, but with a different location. The new WritableRaster
30.147 + * will possess a reference to the current WritableRaster, accessible
30.148 + * through its getParent() and getWritableParent() methods.
30.149 + *
30.150 + * @param childMinX X coord of the upper left corner of the new Raster.
30.151 + * @param childMinY Y coord of the upper left corner of the new Raster.
30.152 + * @return a <code>WritableRaster</code> the same as this one except
30.153 + * for the specified location.
30.154 + * @throws RasterFormatException if computing either
30.155 + * <code>childMinX + this.getWidth()</code> or
30.156 + * <code>childMinY + this.getHeight()</code> results in integer
30.157 + * overflow
30.158 + */
30.159 + public WritableRaster createWritableTranslatedChild(int childMinX,
30.160 + int childMinY) {
30.161 + return createWritableChild(minX,minY,width,height,
30.162 + childMinX,childMinY,null);
30.163 + }
30.164 +
30.165 + /**
30.166 + * Returns a new WritableRaster which shares all or part of this
30.167 + * WritableRaster's DataBuffer. The new WritableRaster will
30.168 + * possess a reference to the current WritableRaster, accessible
30.169 + * through its getParent() and getWritableParent() methods.
30.170 + *
30.171 + * <p> The parentX, parentY, width and height parameters form a
30.172 + * Rectangle in this WritableRaster's coordinate space, indicating
30.173 + * the area of pixels to be shared. An error will be thrown if
30.174 + * this Rectangle is not contained with the bounds of the current
30.175 + * WritableRaster.
30.176 + *
30.177 + * <p> The new WritableRaster may additionally be translated to a
30.178 + * different coordinate system for the plane than that used by the current
30.179 + * WritableRaster. The childMinX and childMinY parameters give
30.180 + * the new (x, y) coordinate of the upper-left pixel of the
30.181 + * returned WritableRaster; the coordinate (childMinX, childMinY)
30.182 + * in the new WritableRaster will map to the same pixel as the
30.183 + * coordinate (parentX, parentY) in the current WritableRaster.
30.184 + *
30.185 + * <p> The new WritableRaster may be defined to contain only a
30.186 + * subset of the bands of the current WritableRaster, possibly
30.187 + * reordered, by means of the bandList parameter. If bandList is
30.188 + * null, it is taken to include all of the bands of the current
30.189 + * WritableRaster in their current order.
30.190 + *
30.191 + * <p> To create a new WritableRaster that contains a subregion of
30.192 + * the current WritableRaster, but shares its coordinate system
30.193 + * and bands, this method should be called with childMinX equal to
30.194 + * parentX, childMinY equal to parentY, and bandList equal to
30.195 + * null.
30.196 + *
30.197 + * @param parentX X coordinate of the upper left corner in this
30.198 + * WritableRaster's coordinates.
30.199 + * @param parentY Y coordinate of the upper left corner in this
30.200 + * WritableRaster's coordinates.
30.201 + * @param w Width of the region starting at (parentX, parentY).
30.202 + * @param h Height of the region starting at (parentX, parentY).
30.203 + * @param childMinX X coordinate of the upper left corner of
30.204 + * the returned WritableRaster.
30.205 + * @param childMinY Y coordinate of the upper left corner of
30.206 + * the returned WritableRaster.
30.207 + * @param bandList Array of band indices, or null to use all bands.
30.208 + * @return a <code>WritableRaster</code> sharing all or part of the
30.209 + * <code>DataBuffer</code> of this <code>WritableRaster</code>.
30.210 + * @exception RasterFormatException if the subregion is outside of the
30.211 + * raster bounds.
30.212 + * @throws RasterFormatException if <code>w</code> or
30.213 + * <code>h</code>
30.214 + * is less than or equal to zero, or computing any of
30.215 + * <code>parentX + w</code>, <code>parentY + h</code>,
30.216 + * <code>childMinX + w</code>, or
30.217 + * <code>childMinY + h</code> results in integer
30.218 + * overflow
30.219 + */
30.220 + public WritableRaster createWritableChild(int parentX, int parentY,
30.221 + int w, int h,
30.222 + int childMinX, int childMinY,
30.223 + int bandList[]) {
30.224 + if (parentX < this.minX) {
30.225 + throw new RasterFormatException("parentX lies outside raster");
30.226 + }
30.227 + if (parentY < this.minY) {
30.228 + throw new RasterFormatException("parentY lies outside raster");
30.229 + }
30.230 + if ((parentX+w < parentX) || (parentX+w > this.width + this.minX)) {
30.231 + throw new RasterFormatException("(parentX + width) is outside raster");
30.232 + }
30.233 + if ((parentY+h < parentY) || (parentY+h > this.height + this.minY)) {
30.234 + throw new RasterFormatException("(parentY + height) is outside raster");
30.235 + }
30.236 +
30.237 + SampleModel sm;
30.238 + // Note: the SampleModel for the child Raster should have the same
30.239 + // width and height as that for the parent, since it represents
30.240 + // the physical layout of the pixel data. The child Raster's width
30.241 + // and height represent a "virtual" view of the pixel data, so
30.242 + // they may be different than those of the SampleModel.
30.243 + if (bandList != null) {
30.244 + sm = sampleModel.createSubsetSampleModel(bandList);
30.245 + }
30.246 + else {
30.247 + sm = sampleModel;
30.248 + }
30.249 +
30.250 + int deltaX = childMinX - parentX;
30.251 + int deltaY = childMinY - parentY;
30.252 +
30.253 + return new WritableRaster(sm,
30.254 + getDataBuffer(),
30.255 + new Rectangle(childMinX,childMinY,
30.256 + w, h),
30.257 + new Point(sampleModelTranslateX+deltaX,
30.258 + sampleModelTranslateY+deltaY),
30.259 + this);
30.260 + }
30.261 +
30.262 + /**
30.263 + * Sets the data for a single pixel from a
30.264 + * primitive array of type TransferType. For image data supported by
30.265 + * the Java 2D(tm) API, this will be one of DataBuffer.TYPE_BYTE,
30.266 + * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
30.267 + * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
30.268 + * may be in a packed format, thus increasing efficiency for data
30.269 + * transfers.
30.270 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.271 + * not in bounds, or if inData is not large enough to hold the pixel data.
30.272 + * However, explicit bounds checking is not guaranteed.
30.273 + * A ClassCastException will be thrown if the input object is not null
30.274 + * and references anything other than an array of TransferType.
30.275 + * @see java.awt.image.SampleModel#setDataElements(int, int, Object, DataBuffer)
30.276 + * @param x The X coordinate of the pixel location.
30.277 + * @param y The Y coordinate of the pixel location.
30.278 + * @param inData An object reference to an array of type defined by
30.279 + * getTransferType() and length getNumDataElements()
30.280 + * containing the pixel data to place at x,y.
30.281 + *
30.282 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.283 + * in bounds, or if inData is too small to hold the input.
30.284 + */
30.285 + public void setDataElements(int x, int y, Object inData) {
30.286 + sampleModel.setDataElements(x-sampleModelTranslateX,
30.287 + y-sampleModelTranslateY,
30.288 + inData, dataBuffer);
30.289 + }
30.290 +
30.291 + /**
30.292 + * Sets the data for a rectangle of pixels from an input Raster.
30.293 + * The input Raster must be compatible with this WritableRaster
30.294 + * in that they must have the same number of bands, corresponding bands
30.295 + * must have the same number of bits per sample, the TransferTypes
30.296 + * and NumDataElements must be the same, and the packing used by
30.297 + * the getDataElements/setDataElements must be identical.
30.298 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.299 + * not in bounds.
30.300 + * However, explicit bounds checking is not guaranteed.
30.301 + * @param x The X coordinate of the pixel location.
30.302 + * @param y The Y coordinate of the pixel location.
30.303 + * @param inRaster Raster containing data to place at x,y.
30.304 + *
30.305 + * @throws NullPointerException if inRaster is null.
30.306 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.307 + * in bounds.
30.308 + */
30.309 + public void setDataElements(int x, int y, Raster inRaster) {
30.310 + int dstOffX = x+inRaster.getMinX();
30.311 + int dstOffY = y+inRaster.getMinY();
30.312 + int width = inRaster.getWidth();
30.313 + int height = inRaster.getHeight();
30.314 + if ((dstOffX < this.minX) || (dstOffY < this.minY) ||
30.315 + (dstOffX + width > this.minX + this.width) ||
30.316 + (dstOffY + height > this.minY + this.height)) {
30.317 + throw new ArrayIndexOutOfBoundsException
30.318 + ("Coordinate out of bounds!");
30.319 + }
30.320 +
30.321 + int srcOffX = inRaster.getMinX();
30.322 + int srcOffY = inRaster.getMinY();
30.323 + Object tdata = null;
30.324 +
30.325 + for (int startY=0; startY < height; startY++) {
30.326 + tdata = inRaster.getDataElements(srcOffX, srcOffY+startY,
30.327 + width, 1, tdata);
30.328 + setDataElements(dstOffX, dstOffY+startY,
30.329 + width, 1, tdata);
30.330 + }
30.331 + }
30.332 +
30.333 + /**
30.334 + * Sets the data for a rectangle of pixels from a
30.335 + * primitive array of type TransferType. For image data supported by
30.336 + * the Java 2D API, this will be one of DataBuffer.TYPE_BYTE,
30.337 + * DataBuffer.TYPE_USHORT, DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT,
30.338 + * DataBuffer.TYPE_FLOAT, or DataBuffer.TYPE_DOUBLE. Data in the array
30.339 + * may be in a packed format, thus increasing efficiency for data
30.340 + * transfers.
30.341 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.342 + * not in bounds, or if inData is not large enough to hold the pixel data.
30.343 + * However, explicit bounds checking is not guaranteed.
30.344 + * A ClassCastException will be thrown if the input object is not null
30.345 + * and references anything other than an array of TransferType.
30.346 + * @see java.awt.image.SampleModel#setDataElements(int, int, int, int, Object, DataBuffer)
30.347 + * @param x The X coordinate of the upper left pixel location.
30.348 + * @param y The Y coordinate of the upper left pixel location.
30.349 + * @param w Width of the pixel rectangle.
30.350 + * @param h Height of the pixel rectangle.
30.351 + * @param inData An object reference to an array of type defined by
30.352 + * getTransferType() and length w*h*getNumDataElements()
30.353 + * containing the pixel data to place between x,y and
30.354 + * x+w-1, y+h-1.
30.355 + *
30.356 + * @throws NullPointerException if inData is null.
30.357 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.358 + * in bounds, or if inData is too small to hold the input.
30.359 + */
30.360 + public void setDataElements(int x, int y, int w, int h, Object inData) {
30.361 + sampleModel.setDataElements(x-sampleModelTranslateX,
30.362 + y-sampleModelTranslateY,
30.363 + w,h,inData,dataBuffer);
30.364 + }
30.365 +
30.366 + /**
30.367 + * Copies pixels from Raster srcRaster to this WritableRaster. Each pixel
30.368 + * in srcRaster is copied to the same x,y address in this raster, unless
30.369 + * the address falls outside the bounds of this raster. srcRaster
30.370 + * must have the same number of bands as this WritableRaster. The
30.371 + * copy is a simple copy of source samples to the corresponding destination
30.372 + * samples.
30.373 + * <p>
30.374 + * If all samples of both source and destination Rasters are of
30.375 + * integral type and less than or equal to 32 bits in size, then calling
30.376 + * this method is equivalent to executing the following code for all
30.377 + * <code>x,y</code> addresses valid in both Rasters.
30.378 + * <pre>
30.379 + * Raster srcRaster;
30.380 + * WritableRaster dstRaster;
30.381 + * for (int b = 0; b < srcRaster.getNumBands(); b++) {
30.382 + * dstRaster.setSample(x, y, b, srcRaster.getSample(x, y, b));
30.383 + * }
30.384 + * </pre>
30.385 + * Thus, when copying an integral type source to an integral type
30.386 + * destination, if the source sample size is greater than the destination
30.387 + * sample size for a particular band, the high order bits of the source
30.388 + * sample are truncated. If the source sample size is less than the
30.389 + * destination size for a particular band, the high order bits of the
30.390 + * destination are zero-extended or sign-extended depending on whether
30.391 + * srcRaster's SampleModel treats the sample as a signed or unsigned
30.392 + * quantity.
30.393 + * <p>
30.394 + * When copying a float or double source to an integral type destination,
30.395 + * each source sample is cast to the destination type. When copying an
30.396 + * integral type source to a float or double destination, the source
30.397 + * is first converted to a 32-bit int (if necessary), using the above
30.398 + * rules for integral types, and then the int is cast to float or
30.399 + * double.
30.400 + * <p>
30.401 + * @param srcRaster The Raster from which to copy pixels.
30.402 + *
30.403 + * @throws NullPointerException if srcRaster is null.
30.404 + */
30.405 + public void setRect(Raster srcRaster) {
30.406 + setRect(0,0,srcRaster);
30.407 + }
30.408 +
30.409 + /**
30.410 + * Copies pixels from Raster srcRaster to this WritableRaster.
30.411 + * For each (x, y) address in srcRaster, the corresponding pixel
30.412 + * is copied to address (x+dx, y+dy) in this WritableRaster,
30.413 + * unless (x+dx, y+dy) falls outside the bounds of this raster.
30.414 + * srcRaster must have the same number of bands as this WritableRaster.
30.415 + * The copy is a simple copy of source samples to the corresponding
30.416 + * destination samples. For details, see
30.417 + * {@link WritableRaster#setRect(Raster)}.
30.418 + *
30.419 + * @param dx The X translation factor from src space to dst space
30.420 + * of the copy.
30.421 + * @param dy The Y translation factor from src space to dst space
30.422 + * of the copy.
30.423 + * @param srcRaster The Raster from which to copy pixels.
30.424 + *
30.425 + * @throws NullPointerException if srcRaster is null.
30.426 + */
30.427 + public void setRect(int dx, int dy, Raster srcRaster) {
30.428 + int width = srcRaster.getWidth();
30.429 + int height = srcRaster.getHeight();
30.430 + int srcOffX = srcRaster.getMinX();
30.431 + int srcOffY = srcRaster.getMinY();
30.432 + int dstOffX = dx+srcOffX;
30.433 + int dstOffY = dy+srcOffY;
30.434 +
30.435 + // Clip to this raster
30.436 + if (dstOffX < this.minX) {
30.437 + int skipX = this.minX - dstOffX;
30.438 + width -= skipX;
30.439 + srcOffX += skipX;
30.440 + dstOffX = this.minX;
30.441 + }
30.442 + if (dstOffY < this.minY) {
30.443 + int skipY = this.minY - dstOffY;
30.444 + height -= skipY;
30.445 + srcOffY += skipY;
30.446 + dstOffY = this.minY;
30.447 + }
30.448 + if (dstOffX+width > this.minX+this.width) {
30.449 + width = this.minX + this.width - dstOffX;
30.450 + }
30.451 + if (dstOffY+height > this.minY+this.height) {
30.452 + height = this.minY + this.height - dstOffY;
30.453 + }
30.454 +
30.455 + if (width <= 0 || height <= 0) {
30.456 + return;
30.457 + }
30.458 +
30.459 + switch (srcRaster.getSampleModel().getDataType()) {
30.460 + case DataBuffer.TYPE_BYTE:
30.461 + case DataBuffer.TYPE_SHORT:
30.462 + case DataBuffer.TYPE_USHORT:
30.463 + case DataBuffer.TYPE_INT:
30.464 + int[] iData = null;
30.465 + for (int startY=0; startY < height; startY++) {
30.466 + // Grab one scanline at a time
30.467 + iData =
30.468 + srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
30.469 + iData);
30.470 + setPixels(dstOffX, dstOffY+startY, width, 1, iData);
30.471 + }
30.472 + break;
30.473 +
30.474 + case DataBuffer.TYPE_FLOAT:
30.475 + float[] fData = null;
30.476 + for (int startY=0; startY < height; startY++) {
30.477 + fData =
30.478 + srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
30.479 + fData);
30.480 + setPixels(dstOffX, dstOffY+startY, width, 1, fData);
30.481 + }
30.482 + break;
30.483 +
30.484 + case DataBuffer.TYPE_DOUBLE:
30.485 + double[] dData = null;
30.486 + for (int startY=0; startY < height; startY++) {
30.487 + // Grab one scanline at a time
30.488 + dData =
30.489 + srcRaster.getPixels(srcOffX, srcOffY+startY, width, 1,
30.490 + dData);
30.491 + setPixels(dstOffX, dstOffY+startY, width, 1, dData);
30.492 + }
30.493 + break;
30.494 + }
30.495 + }
30.496 +
30.497 + /**
30.498 + * Sets a pixel in the DataBuffer using an int array of samples for input.
30.499 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.500 + * not in bounds.
30.501 + * However, explicit bounds checking is not guaranteed.
30.502 + * @param x The X coordinate of the pixel location.
30.503 + * @param y The Y coordinate of the pixel location.
30.504 + * @param iArray The input samples in a int array.
30.505 + *
30.506 + * @throws NullPointerException if iArray is null.
30.507 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.508 + * in bounds, or if iArray is too small to hold the input.
30.509 + */
30.510 + public void setPixel(int x, int y, int iArray[]) {
30.511 + sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.512 + iArray,dataBuffer);
30.513 + }
30.514 +
30.515 + /**
30.516 + * Sets a pixel in the DataBuffer using a float array of samples for input.
30.517 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.518 + * not in bounds.
30.519 + * However, explicit bounds checking is not guaranteed.
30.520 + * @param x The X coordinate of the pixel location.
30.521 + * @param y The Y coordinate of the pixel location.
30.522 + * @param fArray The input samples in a float array.
30.523 + *
30.524 + * @throws NullPointerException if fArray is null.
30.525 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.526 + * in bounds, or if fArray is too small to hold the input.
30.527 + */
30.528 + public void setPixel(int x, int y, float fArray[]) {
30.529 + sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.530 + fArray,dataBuffer);
30.531 + }
30.532 +
30.533 + /**
30.534 + * Sets a pixel in the DataBuffer using a double array of samples for input.
30.535 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.536 + * not in bounds.
30.537 + * However, explicit bounds checking is not guaranteed.
30.538 + * @param x The X coordinate of the pixel location.
30.539 + * @param y The Y coordinate of the pixel location.
30.540 + * @param dArray The input samples in a double array.
30.541 + *
30.542 + * @throws NullPointerException if dArray is null.
30.543 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.544 + * in bounds, or if dArray is too small to hold the input.
30.545 + */
30.546 + public void setPixel(int x, int y, double dArray[]) {
30.547 + sampleModel.setPixel(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.548 + dArray,dataBuffer);
30.549 + }
30.550 +
30.551 + /**
30.552 + * Sets all samples for a rectangle of pixels from an int array containing
30.553 + * one sample per array element.
30.554 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.555 + * not in bounds.
30.556 + * However, explicit bounds checking is not guaranteed.
30.557 + * @param x The X coordinate of the upper left pixel location.
30.558 + * @param y The Y coordinate of the upper left pixel location.
30.559 + * @param w Width of the pixel rectangle.
30.560 + * @param h Height of the pixel rectangle.
30.561 + * @param iArray The input int pixel array.
30.562 + *
30.563 + * @throws NullPointerException if iArray is null.
30.564 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.565 + * in bounds, or if iArray is too small to hold the input.
30.566 + */
30.567 + public void setPixels(int x, int y, int w, int h, int iArray[]) {
30.568 + sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.569 + w,h,iArray,dataBuffer);
30.570 + }
30.571 +
30.572 + /**
30.573 + * Sets all samples for a rectangle of pixels from a float array containing
30.574 + * one sample per array element.
30.575 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.576 + * not in bounds.
30.577 + * However, explicit bounds checking is not guaranteed.
30.578 + * @param x The X coordinate of the upper left pixel location.
30.579 + * @param y The Y coordinate of the upper left pixel location.
30.580 + * @param w Width of the pixel rectangle.
30.581 + * @param h Height of the pixel rectangle.
30.582 + * @param fArray The input float pixel array.
30.583 + *
30.584 + * @throws NullPointerException if fArray is null.
30.585 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.586 + * in bounds, or if fArray is too small to hold the input.
30.587 + */
30.588 + public void setPixels(int x, int y, int w, int h, float fArray[]) {
30.589 + sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.590 + w,h,fArray,dataBuffer);
30.591 + }
30.592 +
30.593 + /**
30.594 + * Sets all samples for a rectangle of pixels from a double array containing
30.595 + * one sample per array element.
30.596 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.597 + * not in bounds.
30.598 + * However, explicit bounds checking is not guaranteed.
30.599 + * @param x The X coordinate of the upper left pixel location.
30.600 + * @param y The Y coordinate of the upper left pixel location.
30.601 + * @param w Width of the pixel rectangle.
30.602 + * @param h Height of the pixel rectangle.
30.603 + * @param dArray The input double pixel array.
30.604 + *
30.605 + * @throws NullPointerException if dArray is null.
30.606 + * @throws ArrayIndexOutOfBoundsException if the coordinates are not
30.607 + * in bounds, or if dArray is too small to hold the input.
30.608 + */
30.609 + public void setPixels(int x, int y, int w, int h, double dArray[]) {
30.610 + sampleModel.setPixels(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.611 + w,h,dArray,dataBuffer);
30.612 + }
30.613 +
30.614 + /**
30.615 + * Sets a sample in the specified band for the pixel located at (x,y)
30.616 + * in the DataBuffer using an int for input.
30.617 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.618 + * not in bounds.
30.619 + * However, explicit bounds checking is not guaranteed.
30.620 + * @param x The X coordinate of the pixel location.
30.621 + * @param y The Y coordinate of the pixel location.
30.622 + * @param b The band to set.
30.623 + * @param s The input sample.
30.624 + *
30.625 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.626 + * the band index are not in bounds.
30.627 + */
30.628 + public void setSample(int x, int y, int b, int s) {
30.629 + sampleModel.setSample(x-sampleModelTranslateX,
30.630 + y-sampleModelTranslateY, b, s,
30.631 + dataBuffer);
30.632 + }
30.633 +
30.634 + /**
30.635 + * Sets a sample in the specified band for the pixel located at (x,y)
30.636 + * in the DataBuffer using a float for input.
30.637 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.638 + * not in bounds.
30.639 + * However, explicit bounds checking is not guaranteed.
30.640 + * @param x The X coordinate of the pixel location.
30.641 + * @param y The Y coordinate of the pixel location.
30.642 + * @param b The band to set.
30.643 + * @param s The input sample as a float.
30.644 + *
30.645 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.646 + * the band index are not in bounds.
30.647 + */
30.648 + public void setSample(int x, int y, int b, float s){
30.649 + sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.650 + b,s,dataBuffer);
30.651 + }
30.652 +
30.653 + /**
30.654 + * Sets a sample in the specified band for the pixel located at (x,y)
30.655 + * in the DataBuffer using a double for input.
30.656 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.657 + * not in bounds.
30.658 + * However, explicit bounds checking is not guaranteed.
30.659 + * @param x The X coordinate of the pixel location.
30.660 + * @param y The Y coordinate of the pixel location.
30.661 + * @param b The band to set.
30.662 + * @param s The input sample as a double.
30.663 + *
30.664 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.665 + * the band index are not in bounds.
30.666 + */
30.667 + public void setSample(int x, int y, int b, double s){
30.668 + sampleModel.setSample(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.669 + b,s,dataBuffer);
30.670 + }
30.671 +
30.672 + /**
30.673 + * Sets the samples in the specified band for the specified rectangle
30.674 + * of pixels from an int array containing one sample per array element.
30.675 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.676 + * not in bounds.
30.677 + * However, explicit bounds checking is not guaranteed.
30.678 + * @param x The X coordinate of the upper left pixel location.
30.679 + * @param y The Y coordinate of the upper left pixel location.
30.680 + * @param w Width of the pixel rectangle.
30.681 + * @param h Height of the pixel rectangle.
30.682 + * @param b The band to set.
30.683 + * @param iArray The input int sample array.
30.684 + *
30.685 + * @throws NullPointerException if iArray is null.
30.686 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.687 + * the band index are not in bounds, or if iArray is too small to
30.688 + * hold the input.
30.689 + */
30.690 + public void setSamples(int x, int y, int w, int h, int b,
30.691 + int iArray[]) {
30.692 + sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.693 + w,h,b,iArray,dataBuffer);
30.694 + }
30.695 +
30.696 + /**
30.697 + * Sets the samples in the specified band for the specified rectangle
30.698 + * of pixels from a float array containing one sample per array element.
30.699 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.700 + * not in bounds.
30.701 + * However, explicit bounds checking is not guaranteed.
30.702 + * @param x The X coordinate of the upper left pixel location.
30.703 + * @param y The Y coordinate of the upper left pixel location.
30.704 + * @param w Width of the pixel rectangle.
30.705 + * @param h Height of the pixel rectangle.
30.706 + * @param b The band to set.
30.707 + * @param fArray The input float sample array.
30.708 + *
30.709 + * @throws NullPointerException if fArray is null.
30.710 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.711 + * the band index are not in bounds, or if fArray is too small to
30.712 + * hold the input.
30.713 + */
30.714 + public void setSamples(int x, int y, int w, int h, int b,
30.715 + float fArray[]) {
30.716 + sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.717 + w,h,b,fArray,dataBuffer);
30.718 + }
30.719 +
30.720 + /**
30.721 + * Sets the samples in the specified band for the specified rectangle
30.722 + * of pixels from a double array containing one sample per array element.
30.723 + * An ArrayIndexOutOfBoundsException may be thrown if the coordinates are
30.724 + * not in bounds.
30.725 + * However, explicit bounds checking is not guaranteed.
30.726 + * @param x The X coordinate of the upper left pixel location.
30.727 + * @param y The Y coordinate of the upper left pixel location.
30.728 + * @param w Width of the pixel rectangle.
30.729 + * @param h Height of the pixel rectangle.
30.730 + * @param b The band to set.
30.731 + * @param dArray The input double sample array.
30.732 + *
30.733 + * @throws NullPointerException if dArray is null.
30.734 + * @throws ArrayIndexOutOfBoundsException if the coordinates or
30.735 + * the band index are not in bounds, or if dArray is too small to
30.736 + * hold the input.
30.737 + */
30.738 + public void setSamples(int x, int y, int w, int h, int b,
30.739 + double dArray[]) {
30.740 + sampleModel.setSamples(x-sampleModelTranslateX,y-sampleModelTranslateY,
30.741 + w,h,b,dArray,dataBuffer);
30.742 + }
30.743 +
30.744 +}
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
31.2 +++ b/src/share/classes/java/awt/image/WritableRenderedImage.java Thu Jun 12 11:46:57 2008 -0700
31.3 @@ -0,0 +1,151 @@
31.4 +/*
31.5 + * Portions Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
31.7 + *
31.8 + * This code is free software; you can redistribute it and/or modify it
31.9 + * under the terms of the GNU General Public License version 2 only, as
31.10 + * published by the Free Software Foundation. Sun designates this
31.11 + * particular file as subject to the "Classpath" exception as provided
31.12 + * by Sun in the LICENSE file that accompanied this code.
31.13 + *
31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
31.17 + * version 2 for more details (a copy is included in the LICENSE file that
31.18 + * accompanied this code).
31.19 + *
31.20 + * You should have received a copy of the GNU General Public License version
31.21 + * 2 along with this work; if not, write to the Free Software Foundation,
31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
31.23 + *
31.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
31.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
31.26 + * have any questions.
31.27 + */
31.28 +
31.29 +/* ****************************************************************
31.30 + ******************************************************************
31.31 + ******************************************************************
31.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997
31.33 + *** As an unpublished work pursuant to Title 17 of the United
31.34 + *** States Code. All rights reserved.
31.35 + ******************************************************************
31.36 + ******************************************************************
31.37 + ******************************************************************/
31.38 +
31.39 +package java.awt.image;
31.40 +import java.awt.Point;
31.41 +
31.42 +/**
31.43 + * WriteableRenderedImage is a common interface for objects which
31.44 + * contain or can produce image data in the form of Rasters and
31.45 + * which can be modified and/or written over. The image
31.46 + * data may be stored/produced as a single tile or a regular array
31.47 + * of tiles.
31.48 + * <p>
31.49 + * WritableRenderedImage provides notification to other interested
31.50 + * objects when a tile is checked out for writing (via the
31.51 + * getWritableTile method) and when the last writer of a particular
31.52 + * tile relinquishes its access (via a call to releaseWritableTile).
31.53 + * Additionally, it allows any caller to determine whether any tiles
31.54 + * are currently checked out (via hasTileWriters), and to obtain a
31.55 + * list of such tiles (via getWritableTileIndices, in the form of a Vector
31.56 + * of Point objects).
31.57 + * <p>
31.58 + * Objects wishing to be notified of changes in tile writability must
31.59 + * implement the TileObserver interface, and are added by a
31.60 + * call to addTileObserver. Multiple calls to
31.61 + * addTileObserver for the same object will result in multiple
31.62 + * notifications. An existing observer may reduce its notifications
31.63 + * by calling removeTileObserver; if the observer had no
31.64 + * notifications the operation is a no-op.
31.65 + * <p>
31.66 + * It is necessary for a WritableRenderedImage to ensure that
31.67 + * notifications occur only when the first writer acquires a tile and
31.68 + * the last writer releases it.
31.69 + *
31.70 + */
31.71 +
31.72 +public interface WritableRenderedImage extends RenderedImage
31.73 +{
31.74 +
31.75 + /**
31.76 + * Adds an observer. If the observer is already present,
31.77 + * it will receive multiple notifications.
31.78 + * @param to the specified <code>TileObserver</code>
31.79 + */
31.80 + public void addTileObserver(TileObserver to);
31.81 +
31.82 + /**
31.83 + * Removes an observer. If the observer was not registered,
31.84 + * nothing happens. If the observer was registered for multiple
31.85 + * notifications, it will now be registered for one fewer.
31.86 + * @param to the specified <code>TileObserver</code>
31.87 + */
31.88 + public void removeTileObserver(TileObserver to);
31.89 +
31.90 + /**
31.91 + * Checks out a tile for writing.
31.92 + *
31.93 + * The WritableRenderedImage is responsible for notifying all
31.94 + * of its TileObservers when a tile goes from having
31.95 + * no writers to having one writer.
31.96 + *
31.97 + * @param tileX the X index of the tile.
31.98 + * @param tileY the Y index of the tile.
31.99 + * @return a writable tile.
31.100 + */
31.101 + public WritableRaster getWritableTile(int tileX, int tileY);
31.102 +
31.103 + /**
31.104 + * Relinquishes the right to write to a tile. If the caller
31.105 + * continues to write to the tile, the results are undefined.
31.106 + * Calls to this method should only appear in matching pairs
31.107 + * with calls to getWritableTile; any other use will lead
31.108 + * to undefined results.
31.109 + *
31.110 + * The WritableRenderedImage is responsible for notifying all of
31.111 + * its TileObservers when a tile goes from having one writer
31.112 + * to having no writers.
31.113 + *
31.114 + * @param tileX the X index of the tile.
31.115 + * @param tileY the Y index of the tile.
31.116 + */
31.117 + public void releaseWritableTile(int tileX, int tileY);
31.118 +
31.119 + /**
31.120 + * Returns whether a tile is currently checked out for writing.
31.121 + *
31.122 + * @param tileX the X index of the tile.
31.123 + * @param tileY the Y index of the tile.
31.124 + * @return <code>true</code> if specified tile is checked out
31.125 + * for writing; <code>false</code> otherwise.
31.126 + */
31.127 + public boolean isTileWritable(int tileX, int tileY);
31.128 +
31.129 + /**
31.130 + * Returns an array of Point objects indicating which tiles
31.131 + * are checked out for writing. Returns null if none are
31.132 + * checked out.
31.133 + * @return an array containing the locations of tiles that are
31.134 + * checked out for writing.
31.135 + */
31.136 + public Point[] getWritableTileIndices();
31.137 +
31.138 + /**
31.139 + * Returns whether any tile is checked out for writing.
31.140 + * Semantically equivalent to (getWritableTileIndices() != null).
31.141 + * @return <code>true</code> if any tiles are checked out for
31.142 + * writing; <code>false</code> otherwise.
31.143 + */
31.144 + public boolean hasTileWriters();
31.145 +
31.146 + /**
31.147 + * Sets a rect of the image to the contents of the Raster r, which is
31.148 + * assumed to be in the same coordinate space as the WritableRenderedImage.
31.149 + * The operation is clipped to the bounds of the WritableRenderedImage.
31.150 + * @param r the specified <code>Raster</code>
31.151 + */
31.152 + public void setData(Raster r);
31.153 +
31.154 +}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/src/share/classes/java/awt/image/renderable/ContextualRenderedImageFactory.java Thu Jun 12 11:46:57 2008 -0700
32.3 @@ -0,0 +1,143 @@
32.4 +/*
32.5 + * Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
32.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
32.7 + *
32.8 + * This code is free software; you can redistribute it and/or modify it
32.9 + * under the terms of the GNU General Public License version 2 only, as
32.10 + * published by the Free Software Foundation. Sun designates this
32.11 + * particular file as subject to the "Classpath" exception as provided
32.12 + * by Sun in the LICENSE file that accompanied this code.
32.13 + *
32.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
32.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
32.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32.17 + * version 2 for more details (a copy is included in the LICENSE file that
32.18 + * accompanied this code).
32.19 + *
32.20 + * You should have received a copy of the GNU General Public License version
32.21 + * 2 along with this work; if not, write to the Free Software Foundation,
32.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
32.23 + *
32.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
32.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
32.26 + * have any questions.
32.27 + */
32.28 +
32.29 +/* ********************************************************************
32.30 + **********************************************************************
32.31 + **********************************************************************
32.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
32.33 + *** As an unpublished work pursuant to Title 17 of the United ***
32.34 + *** States Code. All rights reserved. ***
32.35 + **********************************************************************
32.36 + **********************************************************************
32.37 + **********************************************************************/
32.38 +
32.39 +package java.awt.image.renderable;
32.40 +import java.awt.geom.Rectangle2D;
32.41 +import java.awt.image.RenderedImage;
32.42 +
32.43 +/**
32.44 + * ContextualRenderedImageFactory provides an interface for the
32.45 + * functionality that may differ between instances of
32.46 + * RenderableImageOp. Thus different operations on RenderableImages
32.47 + * may be performed by a single class such as RenderedImageOp through
32.48 + * the use of multiple instances of ContextualRenderedImageFactory.
32.49 + * The name ContextualRenderedImageFactory is commonly shortened to
32.50 + * "CRIF."
32.51 + *
32.52 + * <p> All operations that are to be used in a rendering-independent
32.53 + * chain must implement ContextualRenderedImageFactory.
32.54 + *
32.55 + * <p> Classes that implement this interface must provide a
32.56 + * constructor with no arguments.
32.57 + */
32.58 +public interface ContextualRenderedImageFactory extends RenderedImageFactory {
32.59 +
32.60 + /**
32.61 + * Maps the operation's output RenderContext into a RenderContext
32.62 + * for each of the operation's sources. This is useful for
32.63 + * operations that can be expressed in whole or in part simply as
32.64 + * alterations in the RenderContext, such as an affine mapping, or
32.65 + * operations that wish to obtain lower quality renderings of
32.66 + * their sources in order to save processing effort or
32.67 + * transmission bandwith. Some operations, such as blur, can also
32.68 + * use this mechanism to avoid obtaining sources of higher quality
32.69 + * than necessary.
32.70 + *
32.71 + * @param i the index of the source image.
32.72 + * @param renderContext the RenderContext being applied to the operation.
32.73 + * @param paramBlock a ParameterBlock containing the operation's
32.74 + * sources and parameters.
32.75 + * @param image the RenderableImage being rendered.
32.76 + * @return a <code>RenderContext</code> for
32.77 + * the source at the specified index of the parameters
32.78 + * Vector contained in the specified ParameterBlock.
32.79 + */
32.80 + RenderContext mapRenderContext(int i,
32.81 + RenderContext renderContext,
32.82 + ParameterBlock paramBlock,
32.83 + RenderableImage image);
32.84 +
32.85 + /**
32.86 + * Creates a rendering, given a RenderContext and a ParameterBlock
32.87 + * containing the operation's sources and parameters. The output
32.88 + * is a RenderedImage that takes the RenderContext into account to
32.89 + * determine its dimensions and placement on the image plane.
32.90 + * This method houses the "intelligence" that allows a
32.91 + * rendering-independent operation to adapt to a specific
32.92 + * RenderContext.
32.93 + *
32.94 + * @param renderContext The RenderContext specifying the rendering
32.95 + * @param paramBlock a ParameterBlock containing the operation's
32.96 + * sources and parameters
32.97 + * @return a <code>RenderedImage</code> from the sources and parameters
32.98 + * in the specified ParameterBlock and according to the
32.99 + * rendering instructions in the specified RenderContext.
32.100 + */
32.101 + RenderedImage create(RenderContext renderContext,
32.102 + ParameterBlock paramBlock);
32.103 +
32.104 + /**
32.105 + * Returns the bounding box for the output of the operation,
32.106 + * performed on a given set of sources, in rendering-independent
32.107 + * space. The bounds are returned as a Rectangle2D, that is, an
32.108 + * axis-aligned rectangle with floating-point corner coordinates.
32.109 + *
32.110 + * @param paramBlock a ParameterBlock containing the operation's
32.111 + * sources and parameters.
32.112 + * @return a Rectangle2D specifying the rendering-independent
32.113 + * bounding box of the output.
32.114 + */
32.115 + Rectangle2D getBounds2D(ParameterBlock paramBlock);
32.116 +
32.117 + /**
32.118 + * Gets the appropriate instance of the property specified by the name
32.119 + * parameter. This method must determine which instance of a property to
32.120 + * return when there are multiple sources that each specify the property.
32.121 + *
32.122 + * @param paramBlock a ParameterBlock containing the operation's
32.123 + * sources and parameters.
32.124 + * @param name a String naming the desired property.
32.125 + * @return an object reference to the value of the property requested.
32.126 + */
32.127 + Object getProperty(ParameterBlock paramBlock, String name);
32.128 +
32.129 + /**
32.130 + * Returns a list of names recognized by getProperty.
32.131 + * @return the list of property names.
32.132 + */
32.133 + String[] getPropertyNames();
32.134 +
32.135 + /**
32.136 + * Returns true if successive renderings (that is, calls to
32.137 + * create(RenderContext, ParameterBlock)) with the same arguments
32.138 + * may produce different results. This method may be used to
32.139 + * determine whether an existing rendering may be cached and
32.140 + * reused. It is always safe to return true.
32.141 + * @return <code>true</code> if successive renderings with the
32.142 + * same arguments might produce different results;
32.143 + * <code>false</code> otherwise.
32.144 + */
32.145 + boolean isDynamic();
32.146 +}
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
33.2 +++ b/src/share/classes/java/awt/image/renderable/RenderContext.java Thu Jun 12 11:46:57 2008 -0700
33.3 @@ -0,0 +1,272 @@
33.4 +/*
33.5 + * Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33.7 + *
33.8 + * This code is free software; you can redistribute it and/or modify it
33.9 + * under the terms of the GNU General Public License version 2 only, as
33.10 + * published by the Free Software Foundation. Sun designates this
33.11 + * particular file as subject to the "Classpath" exception as provided
33.12 + * by Sun in the LICENSE file that accompanied this code.
33.13 + *
33.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
33.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33.17 + * version 2 for more details (a copy is included in the LICENSE file that
33.18 + * accompanied this code).
33.19 + *
33.20 + * You should have received a copy of the GNU General Public License version
33.21 + * 2 along with this work; if not, write to the Free Software Foundation,
33.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
33.23 + *
33.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
33.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
33.26 + * have any questions.
33.27 + */
33.28 +
33.29 +/* ********************************************************************
33.30 + **********************************************************************
33.31 + **********************************************************************
33.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
33.33 + *** As an unpublished work pursuant to Title 17 of the United ***
33.34 + *** States Code. All rights reserved. ***
33.35 + **********************************************************************
33.36 + **********************************************************************
33.37 + **********************************************************************/
33.38 +
33.39 +package java.awt.image.renderable;
33.40 +import java.util.*;
33.41 +import java.awt.geom.*;
33.42 +import java.awt.*;
33.43 +import java.awt.image.*;
33.44 +
33.45 +/**
33.46 + * A RenderContext encapsulates the information needed to produce a
33.47 + * specific rendering from a RenderableImage. It contains the area to
33.48 + * be rendered specified in rendering-independent terms, the
33.49 + * resolution at which the rendering is to be performed, and hints
33.50 + * used to control the rendering process.
33.51 + *
33.52 + * <p> Users create RenderContexts and pass them to the
33.53 + * RenderableImage via the createRendering method. Most of the methods of
33.54 + * RenderContexts are not meant to be used directly by applications,
33.55 + * but by the RenderableImage and operator classes to which it is
33.56 + * passed.
33.57 + *
33.58 + * <p> The AffineTransform parameter passed into and out of this class
33.59 + * are cloned. The RenderingHints and Shape parameters are not
33.60 + * necessarily cloneable and are therefore only reference copied.
33.61 + * Altering RenderingHints or Shape instances that are in use by
33.62 + * instances of RenderContext may have undesired side effects.
33.63 + */
33.64 +public class RenderContext implements Cloneable {
33.65 +
33.66 + /** Table of hints. May be null. */
33.67 + RenderingHints hints;
33.68 +
33.69 + /** Transform to convert user coordinates to device coordinates. */
33.70 + AffineTransform usr2dev;
33.71 +
33.72 + /** The area of interest. May be null. */
33.73 + Shape aoi;
33.74 +
33.75 + // Various constructors that allow different levels of
33.76 + // specificity. If the Shape is missing the whole renderable area
33.77 + // is assumed. If hints is missing no hints are assumed.
33.78 +
33.79 + /**
33.80 + * Constructs a RenderContext with a given transform.
33.81 + * The area of interest is supplied as a Shape,
33.82 + * and the rendering hints are supplied as a RenderingHints object.
33.83 + *
33.84 + * @param usr2dev an AffineTransform.
33.85 + * @param aoi a Shape representing the area of interest.
33.86 + * @param hints a RenderingHints object containing rendering hints.
33.87 + */
33.88 + public RenderContext(AffineTransform usr2dev,
33.89 + Shape aoi,
33.90 + RenderingHints hints) {
33.91 + this.hints = hints;
33.92 + this.aoi = aoi;
33.93 + this.usr2dev = (AffineTransform)usr2dev.clone();
33.94 + }
33.95 +
33.96 + /**
33.97 + * Constructs a RenderContext with a given transform.
33.98 + * The area of interest is taken to be the entire renderable area.
33.99 + * No rendering hints are used.
33.100 + *
33.101 + * @param usr2dev an AffineTransform.
33.102 + */
33.103 + public RenderContext(AffineTransform usr2dev) {
33.104 + this(usr2dev, null, null);
33.105 + }
33.106 +
33.107 + /**
33.108 + * Constructs a RenderContext with a given transform and rendering hints.
33.109 + * The area of interest is taken to be the entire renderable area.
33.110 + *
33.111 + * @param usr2dev an AffineTransform.
33.112 + * @param hints a RenderingHints object containing rendering hints.
33.113 + */
33.114 + public RenderContext(AffineTransform usr2dev, RenderingHints hints) {
33.115 + this(usr2dev, null, hints);
33.116 + }
33.117 +
33.118 + /**
33.119 + * Constructs a RenderContext with a given transform and area of interest.
33.120 + * The area of interest is supplied as a Shape.
33.121 + * No rendering hints are used.
33.122 + *
33.123 + * @param usr2dev an AffineTransform.
33.124 + * @param aoi a Shape representing the area of interest.
33.125 + */
33.126 + public RenderContext(AffineTransform usr2dev, Shape aoi) {
33.127 + this(usr2dev, aoi, null);
33.128 + }
33.129 +
33.130 + /**
33.131 + * Gets the rendering hints of this <code>RenderContext</code>.
33.132 + * @return a <code>RenderingHints</code> object that represents
33.133 + * the rendering hints of this <code>RenderContext</code>.
33.134 + * @see #setRenderingHints(RenderingHints)
33.135 + */
33.136 + public RenderingHints getRenderingHints() {
33.137 + return hints;
33.138 + }
33.139 +
33.140 + /**
33.141 + * Sets the rendering hints of this <code>RenderContext</code>.
33.142 + * @param hints a <code>RenderingHints</code> object that represents
33.143 + * the rendering hints to assign to this <code>RenderContext</code>.
33.144 + * @see #getRenderingHints
33.145 + */
33.146 + public void setRenderingHints(RenderingHints hints) {
33.147 + this.hints = hints;
33.148 + }
33.149 +
33.150 + /**
33.151 + * Sets the current user-to-device AffineTransform contained
33.152 + * in the RenderContext to a given transform.
33.153 + *
33.154 + * @param newTransform the new AffineTransform.
33.155 + * @see #getTransform
33.156 + */
33.157 + public void setTransform(AffineTransform newTransform) {
33.158 + usr2dev = (AffineTransform)newTransform.clone();
33.159 + }
33.160 +
33.161 + /**
33.162 + * Modifies the current user-to-device transform by prepending another
33.163 + * transform. In matrix notation the operation is:
33.164 + * <pre>
33.165 + * [this] = [modTransform] x [this]
33.166 + * </pre>
33.167 + *
33.168 + * @param modTransform the AffineTransform to prepend to the
33.169 + * current usr2dev transform.
33.170 + * @since 1.3
33.171 + */
33.172 + public void preConcatenateTransform(AffineTransform modTransform) {
33.173 + this.preConcetenateTransform(modTransform);
33.174 + }
33.175 +
33.176 + /**
33.177 + * Modifies the current user-to-device transform by prepending another
33.178 + * transform. In matrix notation the operation is:
33.179 + * <pre>
33.180 + * [this] = [modTransform] x [this]
33.181 + * </pre>
33.182 + * This method does the same thing as the preConcatenateTransform
33.183 + * method. It is here for backward compatibility with previous releases
33.184 + * which misspelled the method name.
33.185 + *
33.186 + * @param modTransform the AffineTransform to prepend to the
33.187 + * current usr2dev transform.
33.188 + * @deprecated replaced by
33.189 + * <code>preConcatenateTransform(AffineTransform)</code>.
33.190 + */
33.191 + @Deprecated
33.192 + public void preConcetenateTransform(AffineTransform modTransform) {
33.193 + usr2dev.preConcatenate(modTransform);
33.194 + }
33.195 +
33.196 + /**
33.197 + * Modifies the current user-to-device transform by appending another
33.198 + * transform. In matrix notation the operation is:
33.199 + * <pre>
33.200 + * [this] = [this] x [modTransform]
33.201 + * </pre>
33.202 + *
33.203 + * @param modTransform the AffineTransform to append to the
33.204 + * current usr2dev transform.
33.205 + * @since 1.3
33.206 + */
33.207 + public void concatenateTransform(AffineTransform modTransform) {
33.208 + this.concetenateTransform(modTransform);
33.209 + }
33.210 +
33.211 + /**
33.212 + * Modifies the current user-to-device transform by appending another
33.213 + * transform. In matrix notation the operation is:
33.214 + * <pre>
33.215 + * [this] = [this] x [modTransform]
33.216 + * </pre>
33.217 + * This method does the same thing as the concatenateTransform
33.218 + * method. It is here for backward compatibility with previous releases
33.219 + * which misspelled the method name.
33.220 + *
33.221 + * @param modTransform the AffineTransform to append to the
33.222 + * current usr2dev transform.
33.223 + * @deprecated replaced by
33.224 + * <code>concatenateTransform(AffineTransform)</code>.
33.225 + */
33.226 + @Deprecated
33.227 + public void concetenateTransform(AffineTransform modTransform) {
33.228 + usr2dev.concatenate(modTransform);
33.229 + }
33.230 +
33.231 + /**
33.232 + * Gets the current user-to-device AffineTransform.
33.233 + *
33.234 + * @return a reference to the current AffineTransform.
33.235 + * @see #setTransform(AffineTransform)
33.236 + */
33.237 + public AffineTransform getTransform() {
33.238 + return (AffineTransform)usr2dev.clone();
33.239 + }
33.240 +
33.241 + /**
33.242 + * Sets the current area of interest. The old area is discarded.
33.243 + *
33.244 + * @param newAoi The new area of interest.
33.245 + * @see #getAreaOfInterest
33.246 + */
33.247 + public void setAreaOfInterest(Shape newAoi) {
33.248 + aoi = newAoi;
33.249 + }
33.250 +
33.251 + /**
33.252 + * Gets the ares of interest currently contained in the
33.253 + * RenderContext.
33.254 + *
33.255 + * @return a reference to the area of interest of the RenderContext,
33.256 + * or null if none is specified.
33.257 + * @see #setAreaOfInterest(Shape)
33.258 + */
33.259 + public Shape getAreaOfInterest() {
33.260 + return aoi;
33.261 + }
33.262 +
33.263 + /**
33.264 + * Makes a copy of a RenderContext. The area of interest is copied
33.265 + * by reference. The usr2dev AffineTransform and hints are cloned,
33.266 + * while the area of interest is copied by reference.
33.267 + *
33.268 + * @return the new cloned RenderContext.
33.269 + */
33.270 + public Object clone() {
33.271 + RenderContext newRenderContext = new RenderContext(usr2dev,
33.272 + aoi, hints);
33.273 + return newRenderContext;
33.274 + }
33.275 +}
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
34.2 +++ b/src/share/classes/java/awt/image/renderable/RenderableImage.java Thu Jun 12 11:46:57 2008 -0700
34.3 @@ -0,0 +1,198 @@
34.4 +/*
34.5 + * Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
34.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
34.7 + *
34.8 + * This code is free software; you can redistribute it and/or modify it
34.9 + * under the terms of the GNU General Public License version 2 only, as
34.10 + * published by the Free Software Foundation. Sun designates this
34.11 + * particular file as subject to the "Classpath" exception as provided
34.12 + * by Sun in the LICENSE file that accompanied this code.
34.13 + *
34.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
34.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34.17 + * version 2 for more details (a copy is included in the LICENSE file that
34.18 + * accompanied this code).
34.19 + *
34.20 + * You should have received a copy of the GNU General Public License version
34.21 + * 2 along with this work; if not, write to the Free Software Foundation,
34.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
34.23 + *
34.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
34.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
34.26 + * have any questions.
34.27 + */
34.28 +
34.29 +/* ********************************************************************
34.30 + **********************************************************************
34.31 + **********************************************************************
34.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
34.33 + *** As an unpublished work pursuant to Title 17 of the United ***
34.34 + *** States Code. All rights reserved. ***
34.35 + **********************************************************************
34.36 + **********************************************************************
34.37 + **********************************************************************/
34.38 +
34.39 +package java.awt.image.renderable;
34.40 +import java.util.Vector;
34.41 +import java.awt.RenderingHints;
34.42 +import java.awt.image.*;
34.43 +
34.44 +/**
34.45 + * A RenderableImage is a common interface for rendering-independent
34.46 + * images (a notion which subsumes resolution independence). That is,
34.47 + * images which are described and have operations applied to them
34.48 + * independent of any specific rendering of the image. For example, a
34.49 + * RenderableImage can be rotated and cropped in
34.50 + * resolution-independent terms. Then, it can be rendered for various
34.51 + * specific contexts, such as a draft preview, a high-quality screen
34.52 + * display, or a printer, each in an optimal fashion.
34.53 + *
34.54 + * <p> A RenderedImage is returned from a RenderableImage via the
34.55 + * createRendering() method, which takes a RenderContext. The
34.56 + * RenderContext specifies how the RenderedImage should be
34.57 + * constructed. Note that it is not possible to extract pixels
34.58 + * directly from a RenderableImage.
34.59 + *
34.60 + * <p> The createDefaultRendering() and createScaledRendering() methods are
34.61 + * convenience methods that construct an appropriate RenderContext
34.62 + * internally. All of the rendering methods may return a reference to a
34.63 + * previously produced rendering.
34.64 + */
34.65 +public interface RenderableImage {
34.66 +
34.67 + /**
34.68 + * String constant that can be used to identify a property on
34.69 + * a RenderedImage obtained via the createRendering or
34.70 + * createScaledRendering methods. If such a property exists,
34.71 + * the value of the propoery will be a RenderingHints object
34.72 + * specifying which hints were observed in creating the rendering.
34.73 + */
34.74 + static final String HINTS_OBSERVED = "HINTS_OBSERVED";
34.75 +
34.76 + /**
34.77 + * Returns a vector of RenderableImages that are the sources of
34.78 + * image data for this RenderableImage. Note that this method may
34.79 + * return an empty vector, to indicate that the image has no sources,
34.80 + * or null, to indicate that no information is available.
34.81 + *
34.82 + * @return a (possibly empty) Vector of RenderableImages, or null.
34.83 + */
34.84 + Vector<RenderableImage> getSources();
34.85 +
34.86 + /**
34.87 + * Gets a property from the property set of this image.
34.88 + * If the property name is not recognized, java.awt.Image.UndefinedProperty
34.89 + * will be returned.
34.90 + *
34.91 + * @param name the name of the property to get, as a String.
34.92 + * @return a reference to the property Object, or the value
34.93 + * java.awt.Image.UndefinedProperty.
34.94 + */
34.95 + Object getProperty(String name);
34.96 +
34.97 + /**
34.98 + * Returns a list of names recognized by getProperty.
34.99 + * @return a list of property names.
34.100 + */
34.101 + String[] getPropertyNames();
34.102 +
34.103 + /**
34.104 + * Returns true if successive renderings (that is, calls to
34.105 + * createRendering() or createScaledRendering()) with the same arguments
34.106 + * may produce different results. This method may be used to
34.107 + * determine whether an existing rendering may be cached and
34.108 + * reused. It is always safe to return true.
34.109 + * @return <code>true</code> if successive renderings with the
34.110 + * same arguments might produce different results;
34.111 + * <code>false</code> otherwise.
34.112 + */
34.113 + boolean isDynamic();
34.114 +
34.115 + /**
34.116 + * Gets the width in user coordinate space. By convention, the
34.117 + * usual width of a RenderableImage is equal to the image's aspect
34.118 + * ratio (width divided by height).
34.119 + *
34.120 + * @return the width of the image in user coordinates.
34.121 + */
34.122 + float getWidth();
34.123 +
34.124 + /**
34.125 + * Gets the height in user coordinate space. By convention, the
34.126 + * usual height of a RenderedImage is equal to 1.0F.
34.127 + *
34.128 + * @return the height of the image in user coordinates.
34.129 + */
34.130 + float getHeight();
34.131 +
34.132 + /**
34.133 + * Gets the minimum X coordinate of the rendering-independent image data.
34.134 + * @return the minimum X coordinate of the rendering-independent image
34.135 + * data.
34.136 + */
34.137 + float getMinX();
34.138 +
34.139 + /**
34.140 + * Gets the minimum Y coordinate of the rendering-independent image data.
34.141 + * @return the minimum Y coordinate of the rendering-independent image
34.142 + * data.
34.143 + */
34.144 + float getMinY();
34.145 +
34.146 + /**
34.147 + * Creates a RenderedImage instance of this image with width w, and
34.148 + * height h in pixels. The RenderContext is built automatically
34.149 + * with an appropriate usr2dev transform and an area of interest
34.150 + * of the full image. All the rendering hints come from hints
34.151 + * passed in.
34.152 + *
34.153 + * <p> If w == 0, it will be taken to equal
34.154 + * Math.round(h*(getWidth()/getHeight())).
34.155 + * Similarly, if h == 0, it will be taken to equal
34.156 + * Math.round(w*(getHeight()/getWidth())). One of
34.157 + * w or h must be non-zero or else an IllegalArgumentException
34.158 + * will be thrown.
34.159 + *
34.160 + * <p> The created RenderedImage may have a property identified
34.161 + * by the String HINTS_OBSERVED to indicate which RenderingHints
34.162 + * were used to create the image. In addition any RenderedImages
34.163 + * that are obtained via the getSources() method on the created
34.164 + * RenderedImage may have such a property.
34.165 + *
34.166 + * @param w the width of rendered image in pixels, or 0.
34.167 + * @param h the height of rendered image in pixels, or 0.
34.168 + * @param hints a RenderingHints object containg hints.
34.169 + * @return a RenderedImage containing the rendered data.
34.170 + */
34.171 + RenderedImage createScaledRendering(int w, int h, RenderingHints hints);
34.172 +
34.173 + /**
34.174 + * Returnd a RenderedImage instance of this image with a default
34.175 + * width and height in pixels. The RenderContext is built
34.176 + * automatically with an appropriate usr2dev transform and an area
34.177 + * of interest of the full image. The rendering hints are
34.178 + * empty. createDefaultRendering may make use of a stored
34.179 + * rendering for speed.
34.180 + *
34.181 + * @return a RenderedImage containing the rendered data.
34.182 + */
34.183 + RenderedImage createDefaultRendering();
34.184 +
34.185 + /**
34.186 + * Creates a RenderedImage that represented a rendering of this image
34.187 + * using a given RenderContext. This is the most general way to obtain a
34.188 + * rendering of a RenderableImage.
34.189 + *
34.190 + * <p> The created RenderedImage may have a property identified
34.191 + * by the String HINTS_OBSERVED to indicate which RenderingHints
34.192 + * (from the RenderContext) were used to create the image.
34.193 + * In addition any RenderedImages
34.194 + * that are obtained via the getSources() method on the created
34.195 + * RenderedImage may have such a property.
34.196 + *
34.197 + * @param renderContext the RenderContext to use to produce the rendering.
34.198 + * @return a RenderedImage containing the rendered data.
34.199 + */
34.200 + RenderedImage createRendering(RenderContext renderContext);
34.201 +}
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
35.2 +++ b/src/share/classes/java/awt/image/renderable/RenderableImageOp.java Thu Jun 12 11:46:57 2008 -0700
35.3 @@ -0,0 +1,350 @@
35.4 +/*
35.5 + * Portions Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
35.7 + *
35.8 + * This code is free software; you can redistribute it and/or modify it
35.9 + * under the terms of the GNU General Public License version 2 only, as
35.10 + * published by the Free Software Foundation. Sun designates this
35.11 + * particular file as subject to the "Classpath" exception as provided
35.12 + * by Sun in the LICENSE file that accompanied this code.
35.13 + *
35.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
35.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
35.17 + * version 2 for more details (a copy is included in the LICENSE file that
35.18 + * accompanied this code).
35.19 + *
35.20 + * You should have received a copy of the GNU General Public License version
35.21 + * 2 along with this work; if not, write to the Free Software Foundation,
35.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
35.23 + *
35.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
35.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
35.26 + * have any questions.
35.27 + */
35.28 +
35.29 +/* ********************************************************************
35.30 + **********************************************************************
35.31 + **********************************************************************
35.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
35.33 + *** As an unpublished work pursuant to Title 17 of the United ***
35.34 + *** States Code. All rights reserved. ***
35.35 + **********************************************************************
35.36 + **********************************************************************
35.37 + **********************************************************************/
35.38 +
35.39 +package java.awt.image.renderable;
35.40 +import java.awt.geom.AffineTransform;
35.41 +import java.awt.geom.Rectangle2D;
35.42 +import java.awt.image.RenderedImage;
35.43 +import java.awt.RenderingHints;
35.44 +import java.util.Hashtable;
35.45 +import java.util.Vector;
35.46 +
35.47 +/**
35.48 + * This class handles the renderable aspects of an operation with help
35.49 + * from its associated instance of a ContextualRenderedImageFactory.
35.50 + */
35.51 +public class RenderableImageOp implements RenderableImage {
35.52 +
35.53 + /** A ParameterBlock containing source and parameters. */
35.54 + ParameterBlock paramBlock;
35.55 +
35.56 + /** The associated ContextualRenderedImageFactory. */
35.57 + ContextualRenderedImageFactory myCRIF;
35.58 +
35.59 + /** The bounding box of the results of this RenderableImageOp. */
35.60 + Rectangle2D boundingBox;
35.61 +
35.62 +
35.63 + /**
35.64 + * Constructs a RenderedImageOp given a
35.65 + * ContextualRenderedImageFactory object, and
35.66 + * a ParameterBlock containing RenderableImage sources and other
35.67 + * parameters. Any RenderedImage sources referenced by the
35.68 + * ParameterBlock will be ignored.
35.69 + *
35.70 + * @param CRIF a ContextualRenderedImageFactory object
35.71 + * @param paramBlock a ParameterBlock containing this operation's source
35.72 + * images and other parameters necessary for the operation
35.73 + * to run.
35.74 + */
35.75 + public RenderableImageOp(ContextualRenderedImageFactory CRIF,
35.76 + ParameterBlock paramBlock) {
35.77 + this.myCRIF = CRIF;
35.78 + this.paramBlock = (ParameterBlock) paramBlock.clone();
35.79 + }
35.80 +
35.81 + /**
35.82 + * Returns a vector of RenderableImages that are the sources of
35.83 + * image data for this RenderableImage. Note that this method may
35.84 + * return an empty vector, to indicate that the image has no sources,
35.85 + * or null, to indicate that no information is available.
35.86 + *
35.87 + * @return a (possibly empty) Vector of RenderableImages, or null.
35.88 + */
35.89 + public Vector<RenderableImage> getSources() {
35.90 + return getRenderableSources();
35.91 + }
35.92 +
35.93 + private Vector getRenderableSources() {
35.94 + Vector sources = null;
35.95 +
35.96 + if (paramBlock.getNumSources() > 0) {
35.97 + sources = new Vector();
35.98 + int i = 0;
35.99 + while (i < paramBlock.getNumSources()) {
35.100 + Object o = paramBlock.getSource(i);
35.101 + if (o instanceof RenderableImage) {
35.102 + sources.add((RenderableImage)o);
35.103 + i++;
35.104 + } else {
35.105 + break;
35.106 + }
35.107 + }
35.108 + }
35.109 + return sources;
35.110 + }
35.111 +
35.112 + /**
35.113 + * Gets a property from the property set of this image.
35.114 + * If the property name is not recognized, java.awt.Image.UndefinedProperty
35.115 + * will be returned.
35.116 + *
35.117 + * @param name the name of the property to get, as a String.
35.118 + * @return a reference to the property Object, or the value
35.119 + * java.awt.Image.UndefinedProperty.
35.120 + */
35.121 + public Object getProperty(String name) {
35.122 + return myCRIF.getProperty(paramBlock, name);
35.123 + }
35.124 +
35.125 + /**
35.126 + * Return a list of names recognized by getProperty.
35.127 + * @return a list of property names.
35.128 + */
35.129 + public String[] getPropertyNames() {
35.130 + return myCRIF.getPropertyNames();
35.131 + }
35.132 +
35.133 + /**
35.134 + * Returns true if successive renderings (that is, calls to
35.135 + * createRendering() or createScaledRendering()) with the same arguments
35.136 + * may produce different results. This method may be used to
35.137 + * determine whether an existing rendering may be cached and
35.138 + * reused. The CRIF's isDynamic method will be called.
35.139 + * @return <code>true</code> if successive renderings with the
35.140 + * same arguments might produce different results;
35.141 + * <code>false</code> otherwise.
35.142 + */
35.143 + public boolean isDynamic() {
35.144 + return myCRIF.isDynamic();
35.145 + }
35.146 +
35.147 + /**
35.148 + * Gets the width in user coordinate space. By convention, the
35.149 + * usual width of a RenderableImage is equal to the image's aspect
35.150 + * ratio (width divided by height).
35.151 + *
35.152 + * @return the width of the image in user coordinates.
35.153 + */
35.154 + public float getWidth() {
35.155 + if (boundingBox == null) {
35.156 + boundingBox = myCRIF.getBounds2D(paramBlock);
35.157 + }
35.158 + return (float)boundingBox.getWidth();
35.159 + }
35.160 +
35.161 + /**
35.162 + * Gets the height in user coordinate space. By convention, the
35.163 + * usual height of a RenderedImage is equal to 1.0F.
35.164 + *
35.165 + * @return the height of the image in user coordinates.
35.166 + */
35.167 + public float getHeight() {
35.168 + if (boundingBox == null) {
35.169 + boundingBox = myCRIF.getBounds2D(paramBlock);
35.170 + }
35.171 + return (float)boundingBox.getHeight();
35.172 + }
35.173 +
35.174 + /**
35.175 + * Gets the minimum X coordinate of the rendering-independent image data.
35.176 + */
35.177 + public float getMinX() {
35.178 + if (boundingBox == null) {
35.179 + boundingBox = myCRIF.getBounds2D(paramBlock);
35.180 + }
35.181 + return (float)boundingBox.getMinX();
35.182 + }
35.183 +
35.184 + /**
35.185 + * Gets the minimum Y coordinate of the rendering-independent image data.
35.186 + */
35.187 + public float getMinY() {
35.188 + if (boundingBox == null) {
35.189 + boundingBox = myCRIF.getBounds2D(paramBlock);
35.190 + }
35.191 + return (float)boundingBox.getMinY();
35.192 + }
35.193 +
35.194 + /**
35.195 + * Change the current ParameterBlock of the operation, allowing
35.196 + * editing of image rendering chains. The effects of such a
35.197 + * change will be visible when a new rendering is created from
35.198 + * this RenderableImageOp or any dependent RenderableImageOp.
35.199 + *
35.200 + * @param paramBlock the new ParameterBlock.
35.201 + * @return the old ParameterBlock.
35.202 + * @see #getParameterBlock
35.203 + */
35.204 + public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
35.205 + ParameterBlock oldParamBlock = this.paramBlock;
35.206 + this.paramBlock = (ParameterBlock)paramBlock.clone();
35.207 + return oldParamBlock;
35.208 + }
35.209 +
35.210 + /**
35.211 + * Returns a reference to the current parameter block.
35.212 + * @return the <code>ParameterBlock</code> of this
35.213 + * <code>RenderableImageOp</code>.
35.214 + * @see #setParameterBlock(ParameterBlock)
35.215 + */
35.216 + public ParameterBlock getParameterBlock() {
35.217 + return paramBlock;
35.218 + }
35.219 +
35.220 + /**
35.221 + * Creates a RenderedImage instance of this image with width w, and
35.222 + * height h in pixels. The RenderContext is built automatically
35.223 + * with an appropriate usr2dev transform and an area of interest
35.224 + * of the full image. All the rendering hints come from hints
35.225 + * passed in.
35.226 + *
35.227 + * <p> If w == 0, it will be taken to equal
35.228 + * Math.round(h*(getWidth()/getHeight())).
35.229 + * Similarly, if h == 0, it will be taken to equal
35.230 + * Math.round(w*(getHeight()/getWidth())). One of
35.231 + * w or h must be non-zero or else an IllegalArgumentException
35.232 + * will be thrown.
35.233 + *
35.234 + * <p> The created RenderedImage may have a property identified
35.235 + * by the String HINTS_OBSERVED to indicate which RenderingHints
35.236 + * were used to create the image. In addition any RenderedImages
35.237 + * that are obtained via the getSources() method on the created
35.238 + * RenderedImage may have such a property.
35.239 + *
35.240 + * @param w the width of rendered image in pixels, or 0.
35.241 + * @param h the height of rendered image in pixels, or 0.
35.242 + * @param hints a RenderingHints object containg hints.
35.243 + * @return a RenderedImage containing the rendered data.
35.244 + */
35.245 + public RenderedImage createScaledRendering(int w, int h,
35.246 + RenderingHints hints) {
35.247 + // DSR -- code to try to get a unit scale
35.248 + double sx = (double)w/getWidth();
35.249 + double sy = (double)h/getHeight();
35.250 + if (Math.abs(sx/sy - 1.0) < 0.01) {
35.251 + sx = sy;
35.252 + }
35.253 + AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
35.254 + RenderContext newRC = new RenderContext(usr2dev, hints);
35.255 + return createRendering(newRC);
35.256 + }
35.257 +
35.258 + /**
35.259 + * Gets a RenderedImage instance of this image with a default
35.260 + * width and height in pixels. The RenderContext is built
35.261 + * automatically with an appropriate usr2dev transform and an area
35.262 + * of interest of the full image. All the rendering hints come
35.263 + * from hints passed in. Implementors of this interface must be
35.264 + * sure that there is a defined default width and height.
35.265 + *
35.266 + * @return a RenderedImage containing the rendered data.
35.267 + */
35.268 + public RenderedImage createDefaultRendering() {
35.269 + AffineTransform usr2dev = new AffineTransform(); // Identity
35.270 + RenderContext newRC = new RenderContext(usr2dev);
35.271 + return createRendering(newRC);
35.272 + }
35.273 +
35.274 + /**
35.275 + * Creates a RenderedImage which represents this
35.276 + * RenderableImageOp (including its Renderable sources) rendered
35.277 + * according to the given RenderContext.
35.278 + *
35.279 + * <p> This method supports chaining of either Renderable or
35.280 + * RenderedImage operations. If sources in
35.281 + * the ParameterBlock used to construct the RenderableImageOp are
35.282 + * RenderableImages, then a three step process is followed:
35.283 + *
35.284 + * <ol>
35.285 + * <li> mapRenderContext() is called on the associated CRIF for
35.286 + * each RenderableImage source;
35.287 + * <li> createRendering() is called on each of the RenderableImage sources
35.288 + * using the backwards-mapped RenderContexts obtained in step 1,
35.289 + * resulting in a rendering of each source;
35.290 + * <li> ContextualRenderedImageFactory.create() is called
35.291 + * with a new ParameterBlock containing the parameters of
35.292 + * the RenderableImageOp and the RenderedImages that were created by the
35.293 + * createRendering() calls.
35.294 + * </ol>
35.295 + *
35.296 + * <p> If the elements of the source Vector of
35.297 + * the ParameterBlock used to construct the RenderableImageOp are
35.298 + * instances of RenderedImage, then the CRIF.create() method is
35.299 + * called immediately using the original ParameterBlock.
35.300 + * This provides a basis case for the recursion.
35.301 + *
35.302 + * <p> The created RenderedImage may have a property identified
35.303 + * by the String HINTS_OBSERVED to indicate which RenderingHints
35.304 + * (from the RenderContext) were used to create the image.
35.305 + * In addition any RenderedImages
35.306 + * that are obtained via the getSources() method on the created
35.307 + * RenderedImage may have such a property.
35.308 + *
35.309 + * @param renderContext The RenderContext to use to perform the rendering.
35.310 + * @return a RenderedImage containing the desired output image.
35.311 + */
35.312 + public RenderedImage createRendering(RenderContext renderContext) {
35.313 + RenderedImage image = null;
35.314 + RenderContext rcOut = null;
35.315 +
35.316 + // Clone the original ParameterBlock; if the ParameterBlock
35.317 + // contains RenderableImage sources, they will be replaced by
35.318 + // RenderedImages.
35.319 + ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
35.320 + Vector sources = getRenderableSources();
35.321 +
35.322 + try {
35.323 + // This assumes that if there is no renderable source, that there
35.324 + // is a rendered source in paramBlock
35.325 +
35.326 + if (sources != null) {
35.327 + Vector renderedSources = new Vector();
35.328 + for (int i = 0; i < sources.size(); i++) {
35.329 + rcOut = myCRIF.mapRenderContext(i, renderContext,
35.330 + paramBlock, this);
35.331 + RenderedImage rdrdImage =
35.332 + ((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
35.333 + if (rdrdImage == null) {
35.334 + return null;
35.335 + }
35.336 +
35.337 + // Add this rendered image to the ParameterBlock's
35.338 + // list of RenderedImages.
35.339 + renderedSources.addElement(rdrdImage);
35.340 + }
35.341 +
35.342 + if (renderedSources.size() > 0) {
35.343 + renderedParamBlock.setSources(renderedSources);
35.344 + }
35.345 + }
35.346 +
35.347 + return myCRIF.create(renderContext, renderedParamBlock);
35.348 + } catch (ArrayIndexOutOfBoundsException e) {
35.349 + // This should never happen
35.350 + return null;
35.351 + }
35.352 + }
35.353 +}
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
36.2 +++ b/src/share/classes/java/awt/image/renderable/RenderableImageProducer.java Thu Jun 12 11:46:57 2008 -0700
36.3 @@ -0,0 +1,219 @@
36.4 +/*
36.5 + * Portions Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
36.7 + *
36.8 + * This code is free software; you can redistribute it and/or modify it
36.9 + * under the terms of the GNU General Public License version 2 only, as
36.10 + * published by the Free Software Foundation. Sun designates this
36.11 + * particular file as subject to the "Classpath" exception as provided
36.12 + * by Sun in the LICENSE file that accompanied this code.
36.13 + *
36.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
36.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
36.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36.17 + * version 2 for more details (a copy is included in the LICENSE file that
36.18 + * accompanied this code).
36.19 + *
36.20 + * You should have received a copy of the GNU General Public License version
36.21 + * 2 along with this work; if not, write to the Free Software Foundation,
36.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
36.23 + *
36.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
36.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
36.26 + * have any questions.
36.27 + */
36.28 +
36.29 +/* ********************************************************************
36.30 + **********************************************************************
36.31 + **********************************************************************
36.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
36.33 + *** As an unpublished work pursuant to Title 17 of the United ***
36.34 + *** States Code. All rights reserved. ***
36.35 + **********************************************************************
36.36 + **********************************************************************
36.37 + **********************************************************************/
36.38 +
36.39 +package java.awt.image.renderable;
36.40 +import java.awt.color.ColorSpace;
36.41 +import java.awt.image.ColorModel;
36.42 +import java.awt.image.DataBuffer;
36.43 +import java.awt.image.DirectColorModel;
36.44 +import java.awt.image.ImageConsumer;
36.45 +import java.awt.image.ImageProducer;
36.46 +import java.awt.image.Raster;
36.47 +import java.awt.image.RenderedImage;
36.48 +import java.awt.image.SampleModel;
36.49 +import java.util.Enumeration;
36.50 +import java.util.Vector;
36.51 +
36.52 +/**
36.53 + * An adapter class that implements ImageProducer to allow the
36.54 + * asynchronous production of a RenderableImage. The size of the
36.55 + * ImageConsumer is determined by the scale factor of the usr2dev
36.56 + * transform in the RenderContext. If the RenderContext is null, the
36.57 + * default rendering of the RenderableImage is used. This class
36.58 + * implements an asynchronous production that produces the image in
36.59 + * one thread at one resolution. This class may be subclassed to
36.60 + * implement versions that will render the image using several
36.61 + * threads. These threads could render either the same image at
36.62 + * progressively better quality, or different sections of the image at
36.63 + * a single resolution.
36.64 + */
36.65 +public class RenderableImageProducer implements ImageProducer, Runnable {
36.66 +
36.67 + /** The RenderableImage source for the producer. */
36.68 + RenderableImage rdblImage;
36.69 +
36.70 + /** The RenderContext to use for producing the image. */
36.71 + RenderContext rc;
36.72 +
36.73 + /** A Vector of image consumers. */
36.74 + Vector ics = new Vector();
36.75 +
36.76 + /**
36.77 + * Constructs a new RenderableImageProducer from a RenderableImage
36.78 + * and a RenderContext.
36.79 + *
36.80 + * @param rdblImage the RenderableImage to be rendered.
36.81 + * @param rc the RenderContext to use for producing the pixels.
36.82 + */
36.83 + public RenderableImageProducer(RenderableImage rdblImage,
36.84 + RenderContext rc) {
36.85 + this.rdblImage = rdblImage;
36.86 + this.rc = rc;
36.87 + }
36.88 +
36.89 + /**
36.90 + * Sets a new RenderContext to use for the next startProduction() call.
36.91 + *
36.92 + * @param rc the new RenderContext.
36.93 + */
36.94 + public synchronized void setRenderContext(RenderContext rc) {
36.95 + this.rc = rc;
36.96 + }
36.97 +
36.98 + /**
36.99 + * Adds an ImageConsumer to the list of consumers interested in
36.100 + * data for this image.
36.101 + *
36.102 + * @param ic an ImageConsumer to be added to the interest list.
36.103 + */
36.104 + public synchronized void addConsumer(ImageConsumer ic) {
36.105 + if (!ics.contains(ic)) {
36.106 + ics.addElement(ic);
36.107 + }
36.108 + }
36.109 +
36.110 + /**
36.111 + * Determine if an ImageConsumer is on the list of consumers
36.112 + * currently interested in data for this image.
36.113 + *
36.114 + * @param ic the ImageConsumer to be checked.
36.115 + * @return true if the ImageConsumer is on the list; false otherwise.
36.116 + */
36.117 + public synchronized boolean isConsumer(ImageConsumer ic) {
36.118 + return ics.contains(ic);
36.119 + }
36.120 +
36.121 + /**
36.122 + * Remove an ImageConsumer from the list of consumers interested in
36.123 + * data for this image.
36.124 + *
36.125 + * @param ic the ImageConsumer to be removed.
36.126 + */
36.127 + public synchronized void removeConsumer(ImageConsumer ic) {
36.128 + ics.removeElement(ic);
36.129 + }
36.130 +
36.131 + /**
36.132 + * Adds an ImageConsumer to the list of consumers interested in
36.133 + * data for this image, and immediately starts delivery of the
36.134 + * image data through the ImageConsumer interface.
36.135 + *
36.136 + * @param ic the ImageConsumer to be added to the list of consumers.
36.137 + */
36.138 + public synchronized void startProduction(ImageConsumer ic) {
36.139 + addConsumer(ic);
36.140 + // Need to build a runnable object for the Thread.
36.141 + Thread thread = new Thread(this, "RenderableImageProducer Thread");
36.142 + thread.start();
36.143 + }
36.144 +
36.145 + /**
36.146 + * Requests that a given ImageConsumer have the image data delivered
36.147 + * one more time in top-down, left-right order.
36.148 + *
36.149 + * @param ic the ImageConsumer requesting the resend.
36.150 + */
36.151 + public void requestTopDownLeftRightResend(ImageConsumer ic) {
36.152 + // So far, all pixels are already sent in TDLR order
36.153 + }
36.154 +
36.155 + /**
36.156 + * The runnable method for this class. This will produce an image using
36.157 + * the current RenderableImage and RenderContext and send it to all the
36.158 + * ImageConsumer currently registered with this class.
36.159 + */
36.160 + public void run() {
36.161 + // First get the rendered image
36.162 + RenderedImage rdrdImage;
36.163 + if (rc != null) {
36.164 + rdrdImage = rdblImage.createRendering(rc);
36.165 + } else {
36.166 + rdrdImage = rdblImage.createDefaultRendering();
36.167 + }
36.168 +
36.169 + // And its ColorModel
36.170 + ColorModel colorModel = rdrdImage.getColorModel();
36.171 + Raster raster = rdrdImage.getData();
36.172 + SampleModel sampleModel = raster.getSampleModel();
36.173 + DataBuffer dataBuffer = raster.getDataBuffer();
36.174 +
36.175 + if (colorModel == null) {
36.176 + colorModel = ColorModel.getRGBdefault();
36.177 + }
36.178 + int minX = raster.getMinX();
36.179 + int minY = raster.getMinY();
36.180 + int width = raster.getWidth();
36.181 + int height = raster.getHeight();
36.182 +
36.183 + Enumeration icList;
36.184 + ImageConsumer ic;
36.185 + // Set up the ImageConsumers
36.186 + icList = ics.elements();
36.187 + while (icList.hasMoreElements()) {
36.188 + ic = (ImageConsumer)icList.nextElement();
36.189 + ic.setDimensions(width,height);
36.190 + ic.setHints(ImageConsumer.TOPDOWNLEFTRIGHT |
36.191 + ImageConsumer.COMPLETESCANLINES |
36.192 + ImageConsumer.SINGLEPASS |
36.193 + ImageConsumer.SINGLEFRAME);
36.194 + }
36.195 +
36.196 + // Get RGB pixels from the raster scanline by scanline and
36.197 + // send to consumers.
36.198 + int pix[] = new int[width];
36.199 + int i,j;
36.200 + int numBands = sampleModel.getNumBands();
36.201 + int tmpPixel[] = new int[numBands];
36.202 + for (j = 0; j < height; j++) {
36.203 + for(i = 0; i < width; i++) {
36.204 + sampleModel.getPixel(i, j, tmpPixel, dataBuffer);
36.205 + pix[i] = colorModel.getDataElement(tmpPixel, 0);
36.206 + }
36.207 + // Now send the scanline to the Consumers
36.208 + icList = ics.elements();
36.209 + while (icList.hasMoreElements()) {
36.210 + ic = (ImageConsumer)icList.nextElement();
36.211 + ic.setPixels(0, j, width, 1, colorModel, pix, 0, width);
36.212 + }
36.213 + }
36.214 +
36.215 + // Now tell the consumers we're done.
36.216 + icList = ics.elements();
36.217 + while (icList.hasMoreElements()) {
36.218 + ic = (ImageConsumer)icList.nextElement();
36.219 + ic.imageComplete(ImageConsumer.STATICIMAGEDONE);
36.220 + }
36.221 + }
36.222 +}
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
37.2 +++ b/src/share/classes/java/awt/image/renderable/RenderedImageFactory.java Thu Jun 12 11:46:57 2008 -0700
37.3 @@ -0,0 +1,78 @@
37.4 +/*
37.5 + * Portions Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
37.7 + *
37.8 + * This code is free software; you can redistribute it and/or modify it
37.9 + * under the terms of the GNU General Public License version 2 only, as
37.10 + * published by the Free Software Foundation. Sun designates this
37.11 + * particular file as subject to the "Classpath" exception as provided
37.12 + * by Sun in the LICENSE file that accompanied this code.
37.13 + *
37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
37.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
37.17 + * version 2 for more details (a copy is included in the LICENSE file that
37.18 + * accompanied this code).
37.19 + *
37.20 + * You should have received a copy of the GNU General Public License version
37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
37.23 + *
37.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
37.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
37.26 + * have any questions.
37.27 + */
37.28 +
37.29 +/* ********************************************************************
37.30 + **********************************************************************
37.31 + **********************************************************************
37.32 + *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
37.33 + *** As an unpublished work pursuant to Title 17 of the United ***
37.34 + *** States Code. All rights reserved. ***
37.35 + **********************************************************************
37.36 + **********************************************************************
37.37 + **********************************************************************/
37.38 +
37.39 +package java.awt.image.renderable;
37.40 +import java.awt.image.RenderedImage;
37.41 +import java.awt.RenderingHints;
37.42 +
37.43 +/**
37.44 + * The RenderedImageFactory interface (often abbreviated RIF) is
37.45 + * intended to be implemented by classes that wish to act as factories
37.46 + * to produce different renderings, for example by executing a series
37.47 + * of BufferedImageOps on a set of sources, depending on a specific
37.48 + * set of parameters, properties, and rendering hints.
37.49 + */
37.50 +public interface RenderedImageFactory {
37.51 +
37.52 + /**
37.53 + * Creates a RenderedImage representing the results of an imaging
37.54 + * operation (or chain of operations) for a given ParameterBlock and
37.55 + * RenderingHints. The RIF may also query any source images
37.56 + * referenced by the ParameterBlock for their dimensions,
37.57 + * SampleModels, properties, etc., as necessary.
37.58 + *
37.59 + * <p> The create() method can return null if the
37.60 + * RenderedImageFactory is not capable of producing output for the
37.61 + * given set of source images and parameters. For example, if a
37.62 + * RenderedImageFactory is only capable of performing a 3x3
37.63 + * convolution on single-banded image data, and the source image has
37.64 + * multiple bands or the convolution Kernel is 5x5, null should be
37.65 + * returned.
37.66 + *
37.67 + * <p> Hints should be taken into account, but can be ignored.
37.68 + * The created RenderedImage may have a property identified
37.69 + * by the String HINTS_OBSERVED to indicate which RenderingHints
37.70 + * were used to create the image. In addition any RenderedImages
37.71 + * that are obtained via the getSources() method on the created
37.72 + * RenderedImage may have such a property.
37.73 + *
37.74 + * @param paramBlock a ParameterBlock containing sources and parameters
37.75 + * for the RenderedImage to be created.
37.76 + * @param hints a RenderingHints object containing hints.
37.77 + * @return A RenderedImage containing the desired output.
37.78 + */
37.79 + RenderedImage create(ParameterBlock paramBlock,
37.80 + RenderingHints hints);
37.81 +}
38.1 --- a/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Tue Jun 10 16:31:26 2008 -0700
38.2 +++ b/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java Thu Jun 12 11:46:57 2008 -0700
38.3 @@ -1696,8 +1696,8 @@
38.4 } catch (Exception e) {
38.5 // eat exceptions because interface doesn't have an
38.6 // exception on it
38.7 - if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
38.8 - MODELMBEAN_LOGGER.logp(Level.WARNING,
38.9 + if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
38.10 + MODELMBEAN_LOGGER.logp(Level.FINER,
38.11 RequiredModelMBean.class.getName(),
38.12 "getAttributes(String[])",
38.13 "Failed to get \"" + attrNames[i] + "\": ", e);
38.14 @@ -1857,8 +1857,8 @@
38.15 attrValue.getClass().getName() +
38.16 " received.");
38.17 } catch (ClassNotFoundException x) {
38.18 - if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
38.19 - MODELMBEAN_LOGGER.logp(Level.WARNING,
38.20 + if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
38.21 + MODELMBEAN_LOGGER.logp(Level.FINER,
38.22 RequiredModelMBean.class.getName(),
38.23 "setAttribute(Attribute)","Class " +
38.24 attrType + " for attribute "
38.25 @@ -2224,8 +2224,8 @@
38.26 ntfyObj.getMessage() + " Severity = " +
38.27 (String)ntfyDesc.getFieldValue("severity"));
38.28 } catch (Exception e) {
38.29 - if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
38.30 - MODELMBEAN_LOGGER.logp(Level.WARNING,
38.31 + if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
38.32 + MODELMBEAN_LOGGER.logp(Level.FINE,
38.33 RequiredModelMBean.class.getName(),
38.34 "sendNotification(Notification)",
38.35 "Failed to log " +
38.36 @@ -2618,8 +2618,8 @@
38.37 " Old value = " + oldv +
38.38 " New value = " + newv);
38.39 } catch (Exception e) {
38.40 - if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
38.41 - MODELMBEAN_LOGGER.logp(Level.WARNING,
38.42 + if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
38.43 + MODELMBEAN_LOGGER.logp(Level.FINE,
38.44 RequiredModelMBean.class.getName(),mth,
38.45 "Failed to log " + ntfyObj.getType() +
38.46 " notification: ", e);
38.47 @@ -2644,8 +2644,8 @@
38.48 " Old value = " + oldv +
38.49 " New value = " + newv);
38.50 } catch (Exception e) {
38.51 - if (MODELMBEAN_LOGGER.isLoggable(Level.WARNING)) {
38.52 - MODELMBEAN_LOGGER.logp(Level.WARNING,
38.53 + if (MODELMBEAN_LOGGER.isLoggable(Level.FINE)) {
38.54 + MODELMBEAN_LOGGER.logp(Level.FINE,
38.55 RequiredModelMBean.class.getName(),mth,
38.56 "Failed to log " + ntfyObj.getType() +
38.57 " notification: ", e);
39.1 --- a/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java Tue Jun 10 16:31:26 2008 -0700
39.2 +++ b/src/share/classes/javax/print/attribute/standard/ReferenceUriSchemesSupported.java Thu Jun 12 11:46:57 2008 -0700
39.3 @@ -44,7 +44,7 @@
39.4 * print request's, print job's, or print service's attribute set.
39.5 * <P>
39.6 * The Internet Assigned Numbers Authority maintains the
39.7 - * <A HREF="http://www.isi.edu/in-notes/iana/assignments/url-schemes">official
39.8 + * <A HREF="http://www.iana.org/assignments/uri-schemes.html">official
39.9 * list of URI schemes</A>.
39.10 * <p>
39.11 * Class ReferenceUriSchemesSupported defines enumeration values for widely
40.1 --- a/src/share/classes/sun/awt/image/SunVolatileImage.java Tue Jun 10 16:31:26 2008 -0700
40.2 +++ b/src/share/classes/sun/awt/image/SunVolatileImage.java Thu Jun 12 11:46:57 2008 -0700
40.3 @@ -165,7 +165,8 @@
40.4 {
40.5 return new BufImgVolatileSurfaceManager(this, context);
40.6 }
40.7 - return SurfaceManagerFactory.createVolatileManager(this, context);
40.8 + SurfaceManagerFactory smf = SurfaceManagerFactory.getInstance();
40.9 + return smf.createVolatileManager(this, context);
40.10 }
40.11
40.12 private Color getForeground() {
41.1 --- a/src/share/classes/sun/font/AttributeValues.java Tue Jun 10 16:31:26 2008 -0700
41.2 +++ b/src/share/classes/sun/font/AttributeValues.java Thu Jun 12 11:46:57 2008 -0700
41.3 @@ -887,10 +887,10 @@
41.4
41.5 try {
41.6 AffineTransform rtxi = rtx.createInverse();
41.7 + double dx = tx.getTranslateX();
41.8 + double dy = tx.getTranslateY();
41.9 tx.preConcatenate(rtxi);
41.10 if (andTranslation) {
41.11 - double dx = tx.getTranslateX();
41.12 - double dy = tx.getTranslateY();
41.13 if (dx != 0 || dy != 0) {
41.14 tx.setTransform(tx.getScaleX(), tx.getShearY(),
41.15 tx.getShearX(), tx.getScaleY(), 0, 0);
42.1 --- a/src/share/classes/sun/font/FileFontStrike.java Tue Jun 10 16:31:26 2008 -0700
42.2 +++ b/src/share/classes/sun/font/FileFontStrike.java Thu Jun 12 11:46:57 2008 -0700
42.3 @@ -27,6 +27,7 @@
42.4
42.5 import java.lang.ref.SoftReference;
42.6 import java.awt.Font;
42.7 +import java.awt.GraphicsEnvironment;
42.8 import java.awt.Rectangle;
42.9 import java.awt.geom.AffineTransform;
42.10 import java.awt.geom.GeneralPath;
42.11 @@ -105,6 +106,19 @@
42.12 boolean useNatives;
42.13 NativeStrike[] nativeStrikes;
42.14
42.15 + /* Used only for communication to native layer */
42.16 + private int intPtSize;
42.17 +
42.18 + /* Perform global initialisation needed for Windows native rasterizer */
42.19 + private static native boolean initNative();
42.20 + private static boolean isXPorLater = false;
42.21 + static {
42.22 + if (FontManager.isWindows && !FontManager.useT2K &&
42.23 + !GraphicsEnvironment.isHeadless()) {
42.24 + isXPorLater = initNative();
42.25 + }
42.26 + }
42.27 +
42.28 FileFontStrike(FileFont fileFont, FontStrikeDesc desc) {
42.29 super(fileFont, desc);
42.30 this.fileFont = fileFont;
42.31 @@ -165,7 +179,7 @@
42.32 * should not segment unless there's another reason to do so.
42.33 */
42.34 float ptSize = (float)matrix[3]; // interpreted only when meaningful.
42.35 - int iSize = (int)ptSize;
42.36 + int iSize = intPtSize = (int)ptSize;
42.37 boolean isSimpleTx = (at.getType() & complexTX) == 0;
42.38 segmentedCache =
42.39 (numGlyphs > SEGSIZE << 3) ||
42.40 @@ -189,8 +203,26 @@
42.41 FontManager.deRegisterBadFont(fileFont);
42.42 return;
42.43 }
42.44 -
42.45 - if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
42.46 + /* First, see if native code should be used to create the glyph.
42.47 + * GDI will return the integer metrics, not fractional metrics, which
42.48 + * may be requested for this strike, so we would require here that :
42.49 + * desc.fmHint != INTVAL_FRACTIONALMETRICS_ON
42.50 + * except that the advance returned by GDI is always overwritten by
42.51 + * the JDK rasteriser supplied one (see getGlyphImageFromWindows()).
42.52 + */
42.53 + if (FontManager.isWindows && isXPorLater &&
42.54 + !FontManager.useT2K &&
42.55 + !GraphicsEnvironment.isHeadless() &&
42.56 + !fileFont.useJavaRasterizer &&
42.57 + (desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HRGB ||
42.58 + desc.aaHint == INTVAL_TEXT_ANTIALIAS_LCD_HBGR) &&
42.59 + (matrix[1] == 0.0 && matrix[2] == 0.0 &&
42.60 + matrix[0] == matrix[3] &&
42.61 + matrix[0] >= 3.0 && matrix[0] <= 100.0) &&
42.62 + !((TrueTypeFont)fileFont).useEmbeddedBitmapsForSize(intPtSize)) {
42.63 + useNatives = true;
42.64 + }
42.65 + else if (fileFont.checkUseNatives() && desc.aaHint==0 && !algoStyle) {
42.66 /* Check its a simple scale of a pt size in the range
42.67 * where native bitmaps typically exist (6-36 pts) */
42.68 if (matrix[1] == 0.0 && matrix[2] == 0.0 &&
42.69 @@ -208,7 +240,16 @@
42.70 }
42.71 }
42.72 }
42.73 -
42.74 + if (FontManager.logging && FontManager.isWindows) {
42.75 + FontManager.logger.info
42.76 + ("Strike for " + fileFont + " at size = " + intPtSize +
42.77 + " use natives = " + useNatives +
42.78 + " useJavaRasteriser = " + fileFont.useJavaRasterizer +
42.79 + " AAHint = " + desc.aaHint +
42.80 + " Has Embedded bitmaps = " +
42.81 + ((TrueTypeFont)fileFont).
42.82 + useEmbeddedBitmapsForSize(intPtSize));
42.83 + }
42.84 this.disposer = new FontStrikeDisposer(fileFont, desc, pScalerContext);
42.85
42.86 /* Always get the image and the advance together for smaller sizes
42.87 @@ -217,7 +258,12 @@
42.88 * "maximumSizeForGetImageWithAdvance".
42.89 * This should be no greater than OutlineTextRender.THRESHOLD.
42.90 */
42.91 - getImageWithAdvance = at.getScaleY() <= 48.0;
42.92 + double maxSz = 48.0;
42.93 + getImageWithAdvance =
42.94 + Math.abs(at.getScaleX()) <= maxSz &&
42.95 + Math.abs(at.getScaleY()) <= maxSz &&
42.96 + Math.abs(at.getShearX()) <= maxSz &&
42.97 + Math.abs(at.getShearY()) <= maxSz;
42.98
42.99 /* Some applications request advance frequently during layout.
42.100 * If we are not getting and caching the image with the advance,
42.101 @@ -250,8 +296,50 @@
42.102 return fileFont.getNumGlyphs();
42.103 }
42.104
42.105 + long getGlyphImageFromNative(int glyphCode) {
42.106 + if (FontManager.isWindows) {
42.107 + return getGlyphImageFromWindows(glyphCode);
42.108 + } else {
42.109 + return getGlyphImageFromX11(glyphCode);
42.110 + }
42.111 + }
42.112 +
42.113 + /* There's no global state conflicts, so this method is not
42.114 + * presently synchronized.
42.115 + */
42.116 + private native long _getGlyphImageFromWindows(String family,
42.117 + int style,
42.118 + int size,
42.119 + int glyphCode,
42.120 + boolean fracMetrics);
42.121 +
42.122 + long getGlyphImageFromWindows(int glyphCode) {
42.123 + String family = fileFont.getFamilyName(null);
42.124 + int style = desc.style & Font.BOLD | desc.style & Font.ITALIC
42.125 + | fileFont.getStyle();
42.126 + int size = intPtSize;
42.127 + long ptr = _getGlyphImageFromWindows
42.128 + (family, style, size, glyphCode,
42.129 + desc.fmHint == INTVAL_FRACTIONALMETRICS_ON);
42.130 + if (ptr != 0) {
42.131 + /* Get the advance from the JDK rasterizer. This is mostly
42.132 + * necessary for the fractional metrics case, but there are
42.133 + * also some very small number (<0.25%) of marginal cases where
42.134 + * there is some rounding difference between windows and JDK.
42.135 + * After these are resolved, we can restrict this extra
42.136 + * work to the FM case.
42.137 + */
42.138 + float advance = getGlyphAdvance(glyphCode, false);
42.139 + StrikeCache.unsafe.putFloat(ptr + StrikeCache.xAdvanceOffset,
42.140 + advance);
42.141 + return ptr;
42.142 + } else {
42.143 + return fileFont.getGlyphImage(pScalerContext, glyphCode);
42.144 + }
42.145 + }
42.146 +
42.147 /* Try the native strikes first, then try the fileFont strike */
42.148 - long getGlyphImageFromNative(int glyphCode) {
42.149 + long getGlyphImageFromX11(int glyphCode) {
42.150 long glyphPtr;
42.151 char charCode = fileFont.glyphToCharMap[glyphCode];
42.152 for (int i=0;i<nativeStrikes.length;i++) {
42.153 @@ -271,13 +359,19 @@
42.154 if (glyphCode >= INVISIBLE_GLYPHS) {
42.155 return StrikeCache.invisibleGlyphPtr;
42.156 }
42.157 - long glyphPtr;
42.158 + long glyphPtr = 0L;
42.159 if ((glyphPtr = getCachedGlyphPtr(glyphCode)) != 0L) {
42.160 return glyphPtr;
42.161 } else {
42.162 if (useNatives) {
42.163 glyphPtr = getGlyphImageFromNative(glyphCode);
42.164 - } else {
42.165 + if (glyphPtr == 0L && FontManager.logging) {
42.166 + FontManager.logger.info
42.167 + ("Strike for " + fileFont +
42.168 + " at size = " + intPtSize +
42.169 + " couldn't get native glyph for code = " + glyphCode);
42.170 + }
42.171 + } if (glyphPtr == 0L) {
42.172 glyphPtr = fileFont.getGlyphImage(pScalerContext,
42.173 glyphCode);
42.174 }
42.175 @@ -295,10 +389,10 @@
42.176 } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
42.177 continue;
42.178 } else {
42.179 - long glyphPtr;
42.180 + long glyphPtr = 0L;
42.181 if (useNatives) {
42.182 glyphPtr = getGlyphImageFromNative(glyphCode);
42.183 - } else {
42.184 + } if (glyphPtr == 0L) {
42.185 glyphPtr = fileFont.getGlyphImage(pScalerContext,
42.186 glyphCode);
42.187 }
42.188 @@ -327,10 +421,11 @@
42.189 } else if ((images[i] = getCachedGlyphPtr(glyphCode)) != 0L) {
42.190 continue;
42.191 } else {
42.192 - long glyphPtr;
42.193 + long glyphPtr = 0L;
42.194 if (useNatives) {
42.195 glyphPtr = getGlyphImageFromNative(glyphCode);
42.196 - } else {
42.197 + }
42.198 + if (glyphPtr == 0L) {
42.199 glyphPtr = fileFont.getGlyphImage(pScalerContext,
42.200 glyphCode);
42.201 }
42.202 @@ -454,11 +549,16 @@
42.203 }
42.204 }
42.205
42.206 + float getGlyphAdvance(int glyphCode) {
42.207 + return getGlyphAdvance(glyphCode, true);
42.208 + }
42.209 +
42.210 /* Metrics info is always retrieved. If the GlyphInfo address is non-zero
42.211 * then metrics info there is valid and can just be copied.
42.212 - * This is in user space coordinates.
42.213 + * This is in user space coordinates unless getUserAdv == false.
42.214 + * Device space advance should not be propagated out of this class.
42.215 */
42.216 - float getGlyphAdvance(int glyphCode) {
42.217 + private float getGlyphAdvance(int glyphCode, boolean getUserAdv) {
42.218 float advance;
42.219
42.220 if (glyphCode >= INVISIBLE_GLYPHS) {
42.221 @@ -480,11 +580,11 @@
42.222 }
42.223 }
42.224
42.225 - if (invertDevTx != null) {
42.226 + if (invertDevTx != null || !getUserAdv) {
42.227 /* If there is a device transform need x & y advance to
42.228 * transform back into user space.
42.229 */
42.230 - advance = getGlyphMetrics(glyphCode).x;
42.231 + advance = getGlyphMetrics(glyphCode, getUserAdv).x;
42.232 } else {
42.233 long glyphPtr;
42.234 if (getImageWithAdvance) {
42.235 @@ -620,6 +720,10 @@
42.236 }
42.237
42.238 Point2D.Float getGlyphMetrics(int glyphCode) {
42.239 + return getGlyphMetrics(glyphCode, true);
42.240 + }
42.241 +
42.242 + private Point2D.Float getGlyphMetrics(int glyphCode, boolean getUserAdv) {
42.243 Point2D.Float metrics = new Point2D.Float();
42.244
42.245 // !!! or do we force sgv user glyphs?
42.246 @@ -627,7 +731,7 @@
42.247 return metrics;
42.248 }
42.249 long glyphPtr;
42.250 - if (getImageWithAdvance) {
42.251 + if (getImageWithAdvance && getUserAdv) {
42.252 /* A heuristic optimisation says that for most cases its
42.253 * worthwhile retrieving the image at the same time as the
42.254 * metrics. So here we get the image data even if its not
42.255 @@ -644,9 +748,9 @@
42.256 metrics.y = StrikeCache.unsafe.getFloat
42.257 (glyphPtr + StrikeCache.yAdvanceOffset);
42.258 /* advance is currently in device space, need to convert back
42.259 - * into user space.
42.260 + * into user space, unless getUserAdv == false.
42.261 * This must not include the translation component. */
42.262 - if (invertDevTx != null) {
42.263 + if (invertDevTx != null && getUserAdv) {
42.264 invertDevTx.deltaTransform(metrics, metrics);
42.265 }
42.266 } else {
42.267 @@ -675,9 +779,9 @@
42.268 if (value == null) {
42.269 fileFont.getGlyphMetrics(pScalerContext, glyphCode, metrics);
42.270 /* advance is currently in device space, need to convert back
42.271 - * into user space.
42.272 + * into user space, unless getUserAdv == false.
42.273 */
42.274 - if (invertDevTx != null) {
42.275 + if (invertDevTx != null && getUserAdv) {
42.276 invertDevTx.deltaTransform(metrics, metrics);
42.277 }
42.278 value = new Point2D.Float(metrics.x, metrics.y);
43.1 --- a/src/share/classes/sun/font/Font2D.java Tue Jun 10 16:31:26 2008 -0700
43.2 +++ b/src/share/classes/sun/font/Font2D.java Thu Jun 12 11:46:57 2008 -0700
43.3 @@ -241,6 +241,13 @@
43.4 if (font.isTransformed()) {
43.5 glyphTx.concatenate(font.getTransform());
43.6 }
43.7 + if (glyphTx.getTranslateX() != 0 || glyphTx.getTranslateY() != 0) {
43.8 + glyphTx.setTransform(glyphTx.getScaleX(),
43.9 + glyphTx.getShearY(),
43.10 + glyphTx.getShearX(),
43.11 + glyphTx.getScaleY(),
43.12 + 0.0, 0.0);
43.13 + }
43.14 FontStrikeDesc desc = new FontStrikeDesc(devTx, glyphTx,
43.15 font.getStyle(), aa, fm);
43.16 return getStrike(desc, false);
43.17 @@ -266,6 +273,13 @@
43.18 at.scale(ptSize, ptSize);
43.19 if (font.isTransformed()) {
43.20 at.concatenate(font.getTransform());
43.21 + if (at.getTranslateX() != 0 || at.getTranslateY() != 0) {
43.22 + at.setTransform(at.getScaleX(),
43.23 + at.getShearY(),
43.24 + at.getShearX(),
43.25 + at.getScaleY(),
43.26 + 0.0, 0.0);
43.27 + }
43.28 }
43.29 int aa = FontStrikeDesc.getAAHintIntVal(this, font, frc);
43.30 int fm = FontStrikeDesc.getFMHintIntVal(frc.getFractionalMetricsHint());
44.1 --- a/src/share/classes/sun/font/FontManager.java Tue Jun 10 16:31:26 2008 -0700
44.2 +++ b/src/share/classes/sun/font/FontManager.java Thu Jun 12 11:46:57 2008 -0700
44.3 @@ -93,7 +93,6 @@
44.4 */
44.5 private static final int CHANNELPOOLSIZE = 20;
44.6 private static int lastPoolIndex = 0;
44.7 - private static int poolSize = 0;
44.8 private static FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE];
44.9
44.10 /* Need to implement a simple linked list scheme for fast
44.11 @@ -245,9 +244,11 @@
44.12 osName = System.getProperty("os.name", "unknownOS");
44.13 isSolaris = osName.startsWith("SunOS");
44.14
44.15 + String t2kStr = System.getProperty("sun.java2d.font.scaler");
44.16 + if (t2kStr != null) {
44.17 + useT2K = "t2k".equals(t2kStr);
44.18 + }
44.19 if (isSolaris) {
44.20 - String t2kStr= System.getProperty("sun.java2d.font.scaler");
44.21 - useT2K = "t2k".equals(t2kStr);
44.22 String version = System.getProperty("os.version", "unk");
44.23 isSolaris8 = version.equals("5.8");
44.24 isSolaris9 = version.equals("5.9");
44.25 @@ -283,29 +284,32 @@
44.26 private static native void initIDs();
44.27
44.28 public static void addToPool(FileFont font) {
44.29 - boolean added = false;
44.30 +
44.31 + FileFont fontFileToClose = null;
44.32 + int freeSlot = -1;
44.33 +
44.34 synchronized (fontFileCache) {
44.35 - /* use poolSize to quickly detect if there's any free slots.
44.36 - * This is a performance tweak based on the assumption that
44.37 - * if this is executed at all often, its because there are many
44.38 - * fonts being used and the pool will be full, and we will save
44.39 - * a fruitless iteration
44.40 + /* Avoid duplicate entries in the pool, and don't close() it,
44.41 + * since this method is called only from within open().
44.42 + * Seeing a duplicate is most likely to happen if the thread
44.43 + * was interrupted during a read, forcing perhaps repeated
44.44 + * close and open calls and it eventually it ends up pointing
44.45 + * at the same slot.
44.46 */
44.47 - if (poolSize < CHANNELPOOLSIZE) {
44.48 - for (int i=0; i<CHANNELPOOLSIZE; i++) {
44.49 - if (fontFileCache[i] == null) {
44.50 - fontFileCache[i] = font;
44.51 - poolSize++;
44.52 - added = true;
44.53 - break;
44.54 - }
44.55 + for (int i=0;i<CHANNELPOOLSIZE;i++) {
44.56 + if (fontFileCache[i] == font) {
44.57 + return;
44.58 }
44.59 - assert added;
44.60 + if (fontFileCache[i] == null && freeSlot < 0) {
44.61 + freeSlot = i;
44.62 + }
44.63 + }
44.64 + if (freeSlot >= 0) {
44.65 + fontFileCache[freeSlot] = font;
44.66 + return;
44.67 } else {
44.68 - // is it possible for this to be the same font?
44.69 - assert fontFileCache[lastPoolIndex] != font;
44.70 - /* replace with new font, poolSize is unchanged. */
44.71 - fontFileCache[lastPoolIndex].close();
44.72 + /* replace with new font. */
44.73 + fontFileToClose = fontFileCache[lastPoolIndex];
44.74 fontFileCache[lastPoolIndex] = font;
44.75 /* lastPoolIndex is updated so that the least recently opened
44.76 * file will be closed next.
44.77 @@ -313,6 +317,19 @@
44.78 lastPoolIndex = (lastPoolIndex+1) % CHANNELPOOLSIZE;
44.79 }
44.80 }
44.81 + /* Need to close the font file outside of the synchronized block,
44.82 + * since its possible some other thread is in an open() call on
44.83 + * this font file, and could be holding its lock and the pool lock.
44.84 + * Releasing the pool lock allows that thread to continue, so it can
44.85 + * then release the lock on this font, allowing the close() call
44.86 + * below to proceed.
44.87 + * Also, calling close() is safe because any other thread using
44.88 + * the font we are closing() synchronizes all reading, so we
44.89 + * will not close the file while its in use.
44.90 + */
44.91 + if (fontFileToClose != null) {
44.92 + fontFileToClose.close();
44.93 + }
44.94 }
44.95
44.96 /*
44.97 @@ -334,7 +351,6 @@
44.98 for (int i=0; i<CHANNELPOOLSIZE; i++) {
44.99 if (fontFileCache[i] == font) {
44.100 fontFileCache[i] = null;
44.101 - poolSize--;
44.102 }
44.103 }
44.104 }
45.1 --- a/src/share/classes/sun/font/GlyphLayout.java Tue Jun 10 16:31:26 2008 -0700
45.2 +++ b/src/share/classes/sun/font/GlyphLayout.java Thu Jun 12 11:46:57 2008 -0700
45.3 @@ -85,7 +85,7 @@
45.4 private GVData _gvdata;
45.5
45.6 // cached glyph layout data for reuse
45.7 - private static GlyphLayout cache; // reusable
45.8 + private static volatile GlyphLayout cache; // reusable
45.9
45.10 private LayoutEngineFactory _lef; // set when get is called, unset when done is called
45.11 private TextRecord _textRecord; // the text we're working on, used by iterators
46.1 --- a/src/share/classes/sun/font/TrueTypeFont.java Tue Jun 10 16:31:26 2008 -0700
46.2 +++ b/src/share/classes/sun/font/TrueTypeFont.java Thu Jun 12 11:46:57 2008 -0700
46.3 @@ -893,6 +893,31 @@
46.4 return null;
46.5 }
46.6
46.7 + /* Used to determine if this size has embedded bitmaps, which
46.8 + * for CJK fonts should be used in preference to LCD glyphs.
46.9 + */
46.10 + boolean useEmbeddedBitmapsForSize(int ptSize) {
46.11 + if (!supportsCJK) {
46.12 + return false;
46.13 + }
46.14 + if (getDirectoryEntry(EBLCTag) == null) {
46.15 + return false;
46.16 + }
46.17 + ByteBuffer eblcTable = getTableBuffer(EBLCTag);
46.18 + int numSizes = eblcTable.getInt(4);
46.19 + /* The bitmapSizeTable's start at offset of 8.
46.20 + * Each bitmapSizeTable entry is 48 bytes.
46.21 + * The offset of ppemY in the entry is 45.
46.22 + */
46.23 + for (int i=0;i<numSizes;i++) {
46.24 + int ppemY = eblcTable.get(8+(i*48)+45) &0xff;
46.25 + if (ppemY == ptSize) {
46.26 + return true;
46.27 + }
46.28 + }
46.29 + return false;
46.30 + }
46.31 +
46.32 public String getFullName() {
46.33 return fullName;
46.34 }
47.1 --- a/src/share/classes/sun/font/Type1Font.java Tue Jun 10 16:31:26 2008 -0700
47.2 +++ b/src/share/classes/sun/font/Type1Font.java Thu Jun 12 11:46:57 2008 -0700
47.3 @@ -589,7 +589,7 @@
47.4
47.5 protected synchronized FontScaler getScaler() {
47.6 if (scaler == null) {
47.7 - return FontManager.getScaler(this, 0, false, fileSize);
47.8 + scaler = FontManager.getScaler(this, 0, false, fileSize);
47.9 }
47.10
47.11 return scaler;
48.1 --- a/src/share/classes/sun/java2d/SunGraphics2D.java Tue Jun 10 16:31:26 2008 -0700
48.2 +++ b/src/share/classes/sun/java2d/SunGraphics2D.java Thu Jun 12 11:46:57 2008 -0700
48.3 @@ -2805,6 +2805,9 @@
48.4 }
48.5
48.6 if (font.hasLayoutAttributes()) {
48.7 + if (str.length() == 0) {
48.8 + return;
48.9 + }
48.10 new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
48.11 return;
48.12 }
48.13 @@ -2831,6 +2834,9 @@
48.14 }
48.15
48.16 if (font.hasLayoutAttributes()) {
48.17 + if (str.length() == 0) {
48.18 + return;
48.19 + }
48.20 new TextLayout(str, font, getFontRenderContext()).draw(this, x, y);
48.21 return;
48.22 }
48.23 @@ -2856,6 +2862,9 @@
48.24 if (iterator == null) {
48.25 throw new NullPointerException("AttributedCharacterIterator is null");
48.26 }
48.27 + if (iterator.getBeginIndex() == iterator.getEndIndex()) {
48.28 + return; /* nothing to draw */
48.29 + }
48.30 TextLayout tl = new TextLayout(iterator, getFontRenderContext());
48.31 tl.draw(this, (float) x, (float) y);
48.32 }
48.33 @@ -2865,6 +2874,9 @@
48.34 if (iterator == null) {
48.35 throw new NullPointerException("AttributedCharacterIterator is null");
48.36 }
48.37 + if (iterator.getBeginIndex() == iterator.getEndIndex()) {
48.38 + return; /* nothing to draw */
48.39 + }
48.40 TextLayout tl = new TextLayout(iterator, getFontRenderContext());
48.41 tl.draw(this, x, y);
48.42 }
48.43 @@ -2900,6 +2912,9 @@
48.44 throw new ArrayIndexOutOfBoundsException("bad offset/length");
48.45 }
48.46 if (font.hasLayoutAttributes()) {
48.47 + if (data.length == 0) {
48.48 + return;
48.49 + }
48.50 new TextLayout(new String(data, offset, length),
48.51 font, getFontRenderContext()).draw(this, x, y);
48.52 return;
48.53 @@ -2934,6 +2949,9 @@
48.54 chData[i] = (char)(data[i+offset] & 0xff);
48.55 }
48.56 if (font.hasLayoutAttributes()) {
48.57 + if (data.length == 0) {
48.58 + return;
48.59 + }
48.60 new TextLayout(new String(chData),
48.61 font, getFontRenderContext()).draw(this, x, y);
48.62 return;
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
49.2 +++ b/src/share/classes/sun/java2d/SurfaceManagerFactory.java Thu Jun 12 11:46:57 2008 -0700
49.3 @@ -0,0 +1,91 @@
49.4 +/*
49.5 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
49.7 + *
49.8 + * This code is free software; you can redistribute it and/or modify it
49.9 + * under the terms of the GNU General Public License version 2 only, as
49.10 + * published by the Free Software Foundation. Sun designates this
49.11 + * particular file as subject to the "Classpath" exception as provided
49.12 + * by Sun in the LICENSE file that accompanied this code.
49.13 + *
49.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
49.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49.17 + * version 2 for more details (a copy is included in the LICENSE file that
49.18 + * accompanied this code).
49.19 + *
49.20 + * You should have received a copy of the GNU General Public License version
49.21 + * 2 along with this work; if not, write to the Free Software Foundation,
49.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
49.23 + *
49.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
49.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
49.26 + * have any questions.
49.27 + */
49.28 +
49.29 +package sun.java2d;
49.30 +
49.31 +import sun.awt.image.SunVolatileImage;
49.32 +import sun.awt.image.VolatileSurfaceManager;
49.33 +
49.34 +/**
49.35 + * This factory creates platform specific VolatileSurfaceManager
49.36 + * implementations.
49.37 + *
49.38 + * There are two platform specific SurfaceManagerFactories in OpenJDK,
49.39 + * UnixSurfaceManagerFactory and WindowsSurfaceManagerFactory.
49.40 + * The actually used SurfaceManagerFactory is set by the respective platform
49.41 + * GraphicsEnvironment implementations in the static initializer.
49.42 + */
49.43 +public abstract class SurfaceManagerFactory {
49.44 +
49.45 + /**
49.46 + * The single shared instance.
49.47 + */
49.48 + private static SurfaceManagerFactory instance;
49.49 +
49.50 + /**
49.51 + * Returns the surface manager factory instance. This returns a factory
49.52 + * that has been set by {@link #setInstance(SurfaceManagerFactory)}.
49.53 + *
49.54 + * @return the surface manager factory
49.55 + */
49.56 + public synchronized static SurfaceManagerFactory getInstance() {
49.57 +
49.58 + if (instance == null) {
49.59 + throw new IllegalStateException("No SurfaceManagerFactory set.");
49.60 + }
49.61 + return instance;
49.62 + }
49.63 +
49.64 + /**
49.65 + * Sets the surface manager factory. This may only be called once, and it
49.66 + * may not be set back to {@code null} when the factory is already
49.67 + * instantiated.
49.68 + *
49.69 + * @param factory the factory to set
49.70 + */
49.71 + public synchronized static void setInstance(SurfaceManagerFactory factory) {
49.72 +
49.73 + if (factory == null) {
49.74 + // We don't want to allow setting this to null at any time.
49.75 + throw new IllegalArgumentException("factory must be non-null");
49.76 + }
49.77 +
49.78 + if (instance != null) {
49.79 + // We don't want to re-set the instance at any time.
49.80 + throw new IllegalStateException("The surface manager factory is already initialized");
49.81 + }
49.82 +
49.83 + instance = factory;
49.84 + }
49.85 +
49.86 + /**
49.87 + * Creates a new instance of a VolatileSurfaceManager given any
49.88 + * arbitrary SunVolatileImage. An optional context Object can be supplied
49.89 + * as a way for the caller to pass pipeline-specific context data to
49.90 + * the VolatileSurfaceManager (such as a backbuffer handle, for example).
49.91 + */
49.92 + public abstract VolatileSurfaceManager
49.93 + createVolatileManager(SunVolatileImage image, Object context);
49.94 +}
50.1 --- a/src/share/classes/sun/print/PSPathGraphics.java Tue Jun 10 16:31:26 2008 -0700
50.2 +++ b/src/share/classes/sun/print/PSPathGraphics.java Thu Jun 12 11:46:57 2008 -0700
50.3 @@ -344,8 +344,15 @@
50.4 double devScaleX = devResX / DEFAULT_USER_RES;
50.5 double devScaleY = devResY / DEFAULT_USER_RES;
50.6
50.7 - if (scaleX > devScaleX) scaleX = devScaleX;
50.8 - if (scaleY > devScaleY) scaleY = devScaleY;
50.9 + /* check if rotated or sheared */
50.10 + int transformType = fullTransform.getType();
50.11 + boolean clampScale = ((transformType &
50.12 + (AffineTransform.TYPE_GENERAL_ROTATION |
50.13 + AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
50.14 + if (clampScale) {
50.15 + if (scaleX > devScaleX) scaleX = devScaleX;
50.16 + if (scaleY > devScaleY) scaleY = devScaleY;
50.17 + }
50.18
50.19 /* We do not need to draw anything if either scaling
50.20 * factor is zero.
51.1 --- a/src/share/classes/sun/print/ServiceDialog.java Tue Jun 10 16:31:26 2008 -0700
51.2 +++ b/src/share/classes/sun/print/ServiceDialog.java Thu Jun 12 11:46:57 2008 -0700
51.3 @@ -2149,48 +2149,55 @@
51.4 }
51.5 }
51.6 }
51.7 - }
51.8 - rbPortrait.setEnabled(pSupported);
51.9 - rbLandscape.setEnabled(lSupported);
51.10 - rbRevPortrait.setEnabled(rpSupported);
51.11 - rbRevLandscape.setEnabled(rlSupported);
51.12 -
51.13 - OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
51.14 - if (or == null ||
51.15 - !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
51.16 -
51.17 - or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
51.18 - // need to validate if default is not supported
51.19 - if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
51.20 - or = null;
51.21 - Object values =
51.22 - psCurrent.getSupportedAttributeValues(orCategory,
51.23 - docFlavor,
51.24 - asCurrent);
51.25 - if (values instanceof OrientationRequested[]) {
51.26 - OrientationRequested[] orValues =
51.27 +
51.28 + rbPortrait.setEnabled(pSupported);
51.29 + rbLandscape.setEnabled(lSupported);
51.30 + rbRevPortrait.setEnabled(rpSupported);
51.31 + rbRevLandscape.setEnabled(rlSupported);
51.32 +
51.33 + OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
51.34 + if (or == null ||
51.35 + !psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
51.36 +
51.37 + or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
51.38 + // need to validate if default is not supported
51.39 + if (!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
51.40 + or = null;
51.41 + values =
51.42 + psCurrent.getSupportedAttributeValues(orCategory,
51.43 + docFlavor,
51.44 + asCurrent);
51.45 + if (values instanceof OrientationRequested[]) {
51.46 + OrientationRequested[] orValues =
51.47 (OrientationRequested[])values;
51.48 - if (orValues.length > 1) {
51.49 - // get the first in the list
51.50 - or = orValues[0];
51.51 + if (orValues.length > 1) {
51.52 + // get the first in the list
51.53 + or = orValues[0];
51.54 + }
51.55 }
51.56 }
51.57 +
51.58 + if (or == null) {
51.59 + or = OrientationRequested.PORTRAIT;
51.60 + }
51.61 + asCurrent.add(or);
51.62 }
51.63
51.64 - if (or == null) {
51.65 - or = OrientationRequested.PORTRAIT;
51.66 + if (or == OrientationRequested.PORTRAIT) {
51.67 + rbPortrait.setSelected(true);
51.68 + } else if (or == OrientationRequested.LANDSCAPE) {
51.69 + rbLandscape.setSelected(true);
51.70 + } else if (or == OrientationRequested.REVERSE_PORTRAIT) {
51.71 + rbRevPortrait.setSelected(true);
51.72 + } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
51.73 + rbRevLandscape.setSelected(true);
51.74 }
51.75 - asCurrent.add(or);
51.76 - }
51.77 -
51.78 - if (or == OrientationRequested.PORTRAIT) {
51.79 - rbPortrait.setSelected(true);
51.80 - } else if (or == OrientationRequested.LANDSCAPE) {
51.81 - rbLandscape.setSelected(true);
51.82 - } else if (or == OrientationRequested.REVERSE_PORTRAIT) {
51.83 - rbRevPortrait.setSelected(true);
51.84 - } else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
51.85 - rbRevLandscape.setSelected(true);
51.86 + } else {
51.87 + rbPortrait.setEnabled(pSupported);
51.88 + rbLandscape.setEnabled(lSupported);
51.89 + rbRevPortrait.setEnabled(rpSupported);
51.90 + rbRevLandscape.setEnabled(rlSupported);
51.91 +
51.92 }
51.93 }
51.94 }
52.1 --- a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Tue Jun 10 16:31:26 2008 -0700
52.2 +++ b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Thu Jun 12 11:46:57 2008 -0700
52.3 @@ -102,7 +102,7 @@
52.4 */
52.5 public void init(boolean forward) throws CertPathValidatorException {
52.6 if (!forward) {
52.7 - remainingCerts = certs.length;
52.8 + remainingCerts = certs.length + 1;
52.9 } else {
52.10 throw new CertPathValidatorException(
52.11 "Forward checking not supported");
52.12 @@ -131,14 +131,22 @@
52.13
52.14 InputStream in = null;
52.15 OutputStream out = null;
52.16 +
52.17 + // Decrement the certificate counter
52.18 + remainingCerts--;
52.19 +
52.20 try {
52.21 - // Examine OCSP properties
52.22 X509Certificate responderCert = null;
52.23 boolean seekResponderCert = false;
52.24 X500Principal responderSubjectName = null;
52.25 X500Principal responderIssuerName = null;
52.26 BigInteger responderSerialNumber = null;
52.27
52.28 + boolean seekIssuerCert = true;
52.29 + X509CertImpl issuerCertImpl = null;
52.30 + X509CertImpl currCertImpl =
52.31 + X509CertImpl.toImpl((X509Certificate)cert);
52.32 +
52.33 /*
52.34 * OCSP security property values, in the following order:
52.35 * 1. ocsp.responderURL
52.36 @@ -148,6 +156,9 @@
52.37 */
52.38 String[] properties = getOCSPProperties();
52.39
52.40 + // Check whether OCSP is feasible before seeking cert information
52.41 + URL url = getOCSPServerURL(currCertImpl, properties);
52.42 +
52.43 // When responder's subject name is set then the issuer/serial
52.44 // properties are ignored
52.45 if (properties[1] != null) {
52.46 @@ -172,14 +183,9 @@
52.47 seekResponderCert = true;
52.48 }
52.49
52.50 - boolean seekIssuerCert = true;
52.51 - X509CertImpl issuerCertImpl = null;
52.52 - X509CertImpl currCertImpl =
52.53 - X509CertImpl.toImpl((X509Certificate)cert);
52.54 - remainingCerts--;
52.55 -
52.56 - // Set the issuer certificate
52.57 - if (remainingCerts != 0) {
52.58 + // Set the issuer certificate to the next cert in the chain
52.59 + // (unless we're processing the final cert).
52.60 + if (remainingCerts < certs.length) {
52.61 issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
52.62 seekIssuerCert = false; // done
52.63
52.64 @@ -312,7 +318,8 @@
52.65 // Construct an OCSP Request
52.66 OCSPRequest ocspRequest =
52.67 new OCSPRequest(currCertImpl, issuerCertImpl);
52.68 - URL url = getOCSPServerURL(currCertImpl, properties);
52.69 +
52.70 + // Use the URL to the OCSP service that was created earlier
52.71 HttpURLConnection con = (HttpURLConnection)url.openConnection();
52.72 if (DEBUG != null) {
52.73 DEBUG.println("connecting to OCSP service at: " + url);
53.1 Binary file src/share/lib/cmm/lcms/GRAY.pf has changed
54.1 Binary file src/share/lib/cmm/lcms/LINEAR_RGB.pf has changed
55.1 Binary file src/share/lib/cmm/lcms/PYCC.pf has changed
56.1 --- a/src/share/native/sun/font/freetypeScaler.c Tue Jun 10 16:31:26 2008 -0700
56.2 +++ b/src/share/native/sun/font/freetypeScaler.c Thu Jun 12 11:46:57 2008 -0700
56.3 @@ -368,7 +368,7 @@
56.4 //text can not be smaller than 1 point
56.5 ptsz = 1.0;
56.6 }
56.7 - context->ptsz = (((int) ptsz) << 6);
56.8 + context->ptsz = (int)(ptsz * 64);
56.9 context->transform.xx = FloatToFTFixed((float)dmat[0]/ptsz);
56.10 context->transform.yx = -FloatToFTFixed((float)dmat[1]/ptsz);
56.11 context->transform.xy = -FloatToFTFixed((float)dmat[2]/ptsz);
56.12 @@ -779,13 +779,24 @@
56.13 }
56.14
56.15 if (context->fmType == TEXT_FM_ON) {
56.16 - glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
56.17 - glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
56.18 + double advh = FTFixedToFloat(ftglyph->linearHoriAdvance);
56.19 + glyphInfo->advanceX =
56.20 + (float) (advh * FTFixedToFloat(context->transform.xx));
56.21 + glyphInfo->advanceY =
56.22 + (float) (advh * FTFixedToFloat(context->transform.xy));
56.23 } else {
56.24 - glyphInfo->advanceX =
56.25 - (float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
56.26 - glyphInfo->advanceY =
56.27 - (float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
56.28 + if (!ftglyph->advance.y) {
56.29 + glyphInfo->advanceX =
56.30 + (float) ROUND(FT26Dot6ToFloat(ftglyph->advance.x));
56.31 + glyphInfo->advanceY = 0;
56.32 + } else if (!ftglyph->advance.x) {
56.33 + glyphInfo->advanceX = 0;
56.34 + glyphInfo->advanceY =
56.35 + (float) ROUND(FT26Dot6ToFloat(-ftglyph->advance.y));
56.36 + } else {
56.37 + glyphInfo->advanceX = FT26Dot6ToFloat(ftglyph->advance.x);
56.38 + glyphInfo->advanceY = FT26Dot6ToFloat(-ftglyph->advance.y);
56.39 + }
56.40 }
56.41
56.42 if (imageSize == 0) {
56.43 @@ -974,7 +985,7 @@
56.44
56.45 FT_Outline_Translate(&ftglyph->outline,
56.46 FloatToF26Dot6(xpos),
56.47 - FloatToF26Dot6(ypos));
56.48 + -FloatToF26Dot6(ypos));
56.49
56.50 return &ftglyph->outline;
56.51 }
57.1 --- a/src/share/native/sun/java2d/loops/AlphaMacros.h Tue Jun 10 16:31:26 2008 -0700
57.2 +++ b/src/share/native/sun/java2d/loops/AlphaMacros.h Thu Jun 12 11:46:57 2008 -0700
57.3 @@ -416,7 +416,8 @@
57.4 MultiplyAndStore ## STRATEGY ## Comps(res, \
57.5 srcF, res);\
57.6 } \
57.7 - if (!(DST ## IsPremultiplied) && resA && \
57.8 + if (!(DST ## IsOpaque) && \
57.9 + !(DST ## IsPremultiplied) && resA && \
57.10 resA < MaxValFor ## STRATEGY) \
57.11 { \
57.12 DivideAndStore ## STRATEGY ## Comps(res, \
57.13 @@ -475,7 +476,8 @@
57.14 MultiplyAndStore ## STRATEGY ## Comps(res, \
57.15 srcF, res); \
57.16 } \
57.17 - if (!(DST ## IsPremultiplied) && resA && \
57.18 + if (!(DST ## IsOpaque) && \
57.19 + !(DST ## IsPremultiplied) && resA && \
57.20 resA < MaxValFor ## STRATEGY) \
57.21 { \
57.22 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
57.23 @@ -797,7 +799,8 @@
57.24 Store ## STRATEGY ## CompsUsingOp(res, +=, tmp); \
57.25 } \
57.26 } \
57.27 - if (!(TYPE ## IsPremultiplied) && resA && \
57.28 + if (!(TYPE ## IsOpaque) && \
57.29 + !(TYPE ## IsPremultiplied) && resA && \
57.30 resA < MaxValFor ## STRATEGY) \
57.31 { \
57.32 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
57.33 @@ -831,7 +834,8 @@
57.34 Postload ## STRATEGY ## From ## TYPE(pRas, DstPix, res); \
57.35 MultiplyAddAndStore ## STRATEGY ## Comps(res, \
57.36 dstF, res, src); \
57.37 - if (!(TYPE ## IsPremultiplied) && resA && \
57.38 + if (!(TYPE ## IsOpaque) && \
57.39 + !(TYPE ## IsPremultiplied) && resA && \
57.40 resA < MaxValFor ## STRATEGY) \
57.41 { \
57.42 DivideAndStore ## STRATEGY ## Comps(res, res, resA); \
58.1 --- a/src/share/native/sun/java2d/loops/ByteGray.h Tue Jun 10 16:31:26 2008 -0700
58.2 +++ b/src/share/native/sun/java2d/loops/ByteGray.h Thu Jun 12 11:46:57 2008 -0700
58.3 @@ -36,6 +36,8 @@
58.4 typedef jubyte ByteGrayPixelType;
58.5 typedef jubyte ByteGrayDataType;
58.6
58.7 +#define ByteGrayIsOpaque 1
58.8 +
58.9 #define ByteGrayPixelStride 1
58.10 #define ByteGrayBitsPerPixel 8
58.11
59.1 --- a/src/share/native/sun/java2d/loops/FourByteAbgr.h Tue Jun 10 16:31:26 2008 -0700
59.2 +++ b/src/share/native/sun/java2d/loops/FourByteAbgr.h Thu Jun 12 11:46:57 2008 -0700
59.3 @@ -34,6 +34,8 @@
59.4 typedef jint FourByteAbgrPixelType;
59.5 typedef jubyte FourByteAbgrDataType;
59.6
59.7 +#define FourByteAbgrIsOpaque 0
59.8 +
59.9 #define FourByteAbgrPixelStride 4
59.10
59.11 #define DeclareFourByteAbgrLoadVars(PREFIX)
60.1 --- a/src/share/native/sun/java2d/loops/FourByteAbgrPre.h Tue Jun 10 16:31:26 2008 -0700
60.2 +++ b/src/share/native/sun/java2d/loops/FourByteAbgrPre.h Thu Jun 12 11:46:57 2008 -0700
60.3 @@ -34,6 +34,8 @@
60.4 typedef jint FourByteAbgrPrePixelType;
60.5 typedef jubyte FourByteAbgrPreDataType;
60.6
60.7 +#define FourByteAbgrPreIsOpaque 0
60.8 +
60.9 #define FourByteAbgrPrePixelStride 4
60.10
60.11 #define DeclareFourByteAbgrPreLoadVars(PREFIX)
61.1 --- a/src/share/native/sun/java2d/loops/Index12Gray.h Tue Jun 10 16:31:26 2008 -0700
61.2 +++ b/src/share/native/sun/java2d/loops/Index12Gray.h Thu Jun 12 11:46:57 2008 -0700
61.3 @@ -37,6 +37,8 @@
61.4 typedef jushort Index12GrayPixelType;
61.5 typedef jushort Index12GrayDataType;
61.6
61.7 +#define Index12GrayIsOpaque 1
61.8 +
61.9 #define Index12GrayPixelStride 2
61.10 #define Index12GrayBitsPerPixel 12
61.11
62.1 --- a/src/share/native/sun/java2d/loops/Index8Gray.h Tue Jun 10 16:31:26 2008 -0700
62.2 +++ b/src/share/native/sun/java2d/loops/Index8Gray.h Thu Jun 12 11:46:57 2008 -0700
62.3 @@ -37,6 +37,8 @@
62.4 typedef jubyte Index8GrayPixelType;
62.5 typedef jubyte Index8GrayDataType;
62.6
62.7 +#define Index8GrayIsOpaque 1
62.8 +
62.9 #define Index8GrayPixelStride 1
62.10 #define Index8GrayBitsPerPixel 8
62.11
63.1 --- a/src/share/native/sun/java2d/loops/IntArgb.h Tue Jun 10 16:31:26 2008 -0700
63.2 +++ b/src/share/native/sun/java2d/loops/IntArgb.h Thu Jun 12 11:46:57 2008 -0700
63.3 @@ -38,6 +38,8 @@
63.4 typedef jint IntArgbPixelType;
63.5 typedef jint IntArgbDataType;
63.6
63.7 +#define IntArgbIsOpaque 0
63.8 +
63.9 #define IntArgbPixelStride 4
63.10
63.11 #define DeclareIntArgbLoadVars(PREFIX)
64.1 --- a/src/share/native/sun/java2d/loops/IntArgbBm.h Tue Jun 10 16:31:26 2008 -0700
64.2 +++ b/src/share/native/sun/java2d/loops/IntArgbBm.h Thu Jun 12 11:46:57 2008 -0700
64.3 @@ -38,6 +38,8 @@
64.4 typedef jint IntArgbBmPixelType;
64.5 typedef jint IntArgbBmDataType;
64.6
64.7 +#define IntArgbBmIsOpaque 0
64.8 +
64.9 #define IntArgbBmPixelStride 4
64.10
64.11 #define DeclareIntArgbBmLoadVars(PREFIX)
65.1 --- a/src/share/native/sun/java2d/loops/IntArgbPre.h Tue Jun 10 16:31:26 2008 -0700
65.2 +++ b/src/share/native/sun/java2d/loops/IntArgbPre.h Thu Jun 12 11:46:57 2008 -0700
65.3 @@ -36,6 +36,8 @@
65.4 typedef jint IntArgbPrePixelType;
65.5 typedef jint IntArgbPreDataType;
65.6
65.7 +#define IntArgbPreIsOpaque 0
65.8 +
65.9 #define IntArgbPrePixelStride 4
65.10
65.11 #define DeclareIntArgbPreLoadVars(PREFIX)
66.1 --- a/src/share/native/sun/java2d/loops/IntBgr.h Tue Jun 10 16:31:26 2008 -0700
66.2 +++ b/src/share/native/sun/java2d/loops/IntBgr.h Thu Jun 12 11:46:57 2008 -0700
66.3 @@ -38,6 +38,8 @@
66.4 typedef jint IntBgrPixelType;
66.5 typedef jint IntBgrDataType;
66.6
66.7 +#define IntBgrIsOpaque 1
66.8 +
66.9 #define IntBgrPixelStride 4
66.10
66.11 #define DeclareIntBgrLoadVars(PREFIX)
67.1 --- a/src/share/native/sun/java2d/loops/IntRgb.h Tue Jun 10 16:31:26 2008 -0700
67.2 +++ b/src/share/native/sun/java2d/loops/IntRgb.h Thu Jun 12 11:46:57 2008 -0700
67.3 @@ -38,6 +38,8 @@
67.4 typedef jint IntRgbPixelType;
67.5 typedef jint IntRgbDataType;
67.6
67.7 +#define IntRgbIsOpaque 1
67.8 +
67.9 #define IntRgbPixelStride 4
67.10
67.11 #define DeclareIntRgbLoadVars(PREFIX)
68.1 --- a/src/share/native/sun/java2d/loops/IntRgbx.h Tue Jun 10 16:31:26 2008 -0700
68.2 +++ b/src/share/native/sun/java2d/loops/IntRgbx.h Thu Jun 12 11:46:57 2008 -0700
68.3 @@ -36,6 +36,8 @@
68.4 typedef jint IntRgbxPixelType;
68.5 typedef jint IntRgbxDataType;
68.6
68.7 +#define IntRgbxIsOpaque 1
68.8 +
68.9 #define IntRgbxPixelStride 4
68.10
68.11 #define DeclareIntRgbxLoadVars(PREFIX)
69.1 --- a/src/share/native/sun/java2d/loops/LoopMacros.h Tue Jun 10 16:31:26 2008 -0700
69.2 +++ b/src/share/native/sun/java2d/loops/LoopMacros.h Thu Jun 12 11:46:57 2008 -0700
69.3 @@ -1610,8 +1610,12 @@
69.4 MUL8(SRC_PREFIX ## A, mixValSrc); \
69.5 MultMultAddAndStore4ByteArgbComps(dst, mixValDst, dst, \
69.6 mixValSrc, SRC_PREFIX); \
69.7 - Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \
69.8 - dstA, dstR, dstG, dstB); \
69.9 + if (!(DST ## IsOpaque) && \
69.10 + !(DST ## IsPremultiplied) && dstA && dstA < 255) { \
69.11 + DivideAndStore4ByteArgbComps(dst, dst, dstA); \
69.12 + } \
69.13 + Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \
69.14 + PIXEL_INDEX, dst); \
69.15 } else { \
69.16 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \
69.17 FG_PIXEL, PREFIX); \
69.18 @@ -1793,8 +1797,12 @@
69.19 dstR = gammaLut[dstR]; \
69.20 dstG = gammaLut[dstG]; \
69.21 dstB = gammaLut[dstB]; \
69.22 - Store ## DST ## From4ByteArgb(DST_PTR, pix, PIXEL_INDEX, \
69.23 - dstA, dstR, dstG, dstB); \
69.24 + if (!(DST ## IsOpaque) && \
69.25 + !(DST ## IsPremultiplied) && dstA && dstA < 255) { \
69.26 + DivideAndStore4ByteArgbComps(dst, dst, dstA); \
69.27 + } \
69.28 + Store ## DST ## From4ByteArgbComps(DST_PTR, pix, \
69.29 + PIXEL_INDEX, dst); \
69.30 } else { \
69.31 Store ## DST ## PixelData(DST_PTR, PIXEL_INDEX, \
69.32 FG_PIXEL, PREFIX); \
70.1 --- a/src/share/native/sun/java2d/loops/ThreeByteBgr.h Tue Jun 10 16:31:26 2008 -0700
70.2 +++ b/src/share/native/sun/java2d/loops/ThreeByteBgr.h Thu Jun 12 11:46:57 2008 -0700
70.3 @@ -34,6 +34,8 @@
70.4 typedef jint ThreeByteBgrPixelType;
70.5 typedef jubyte ThreeByteBgrDataType;
70.6
70.7 +#define ThreeByteBgrIsOpaque 1
70.8 +
70.9 #define ThreeByteBgrPixelStride 3
70.10
70.11 #define DeclareThreeByteBgrLoadVars(PREFIX)
71.1 --- a/src/share/native/sun/java2d/loops/Ushort4444Argb.h Tue Jun 10 16:31:26 2008 -0700
71.2 +++ b/src/share/native/sun/java2d/loops/Ushort4444Argb.h Thu Jun 12 11:46:57 2008 -0700
71.3 @@ -34,6 +34,8 @@
71.4 typedef jushort Ushort4444ArgbPixelType;
71.5 typedef jushort Ushort4444ArgbDataType;
71.6
71.7 +#define Ushort4444ArgbIsOpaque 0
71.8 +
71.9 #define Ushort4444ArgbPixelStride 2
71.10
71.11 #define DeclareUshort4444ArgbLoadVars(PREFIX)
72.1 --- a/src/share/native/sun/java2d/loops/Ushort555Rgb.h Tue Jun 10 16:31:26 2008 -0700
72.2 +++ b/src/share/native/sun/java2d/loops/Ushort555Rgb.h Thu Jun 12 11:46:57 2008 -0700
72.3 @@ -34,6 +34,8 @@
72.4 typedef jushort Ushort555RgbPixelType;
72.5 typedef jushort Ushort555RgbDataType;
72.6
72.7 +#define Ushort555RgbIsOpaque 1
72.8 +
72.9 #define Ushort555RgbPixelStride 2
72.10
72.11 #define DeclareUshort555RgbLoadVars(PREFIX)
73.1 --- a/src/share/native/sun/java2d/loops/Ushort555Rgbx.h Tue Jun 10 16:31:26 2008 -0700
73.2 +++ b/src/share/native/sun/java2d/loops/Ushort555Rgbx.h Thu Jun 12 11:46:57 2008 -0700
73.3 @@ -34,6 +34,8 @@
73.4 typedef jushort Ushort555RgbxPixelType;
73.5 typedef jushort Ushort555RgbxDataType;
73.6
73.7 +#define Ushort555RgbxIsOpaque 1
73.8 +
73.9 #define Ushort555RgbxPixelStride 2
73.10
73.11 #define DeclareUshort555RgbxLoadVars(PREFIX)
74.1 --- a/src/share/native/sun/java2d/loops/Ushort565Rgb.h Tue Jun 10 16:31:26 2008 -0700
74.2 +++ b/src/share/native/sun/java2d/loops/Ushort565Rgb.h Thu Jun 12 11:46:57 2008 -0700
74.3 @@ -34,6 +34,8 @@
74.4 typedef jushort Ushort565RgbPixelType;
74.5 typedef jushort Ushort565RgbDataType;
74.6
74.7 +#define Ushort565RgbIsOpaque 1
74.8 +
74.9 #define Ushort565RgbPixelStride 2
74.10
74.11 #define DeclareUshort565RgbLoadVars(PREFIX)
75.1 --- a/src/share/native/sun/java2d/loops/UshortGray.h Tue Jun 10 16:31:26 2008 -0700
75.2 +++ b/src/share/native/sun/java2d/loops/UshortGray.h Thu Jun 12 11:46:57 2008 -0700
75.3 @@ -36,6 +36,8 @@
75.4 typedef jushort UshortGrayPixelType;
75.5 typedef jushort UshortGrayDataType;
75.6
75.7 +#define UshortGrayIsOpaque 1
75.8 +
75.9 #define UshortGrayPixelStride 2
75.10 #define UshortGrayBitsPerPixel 16
75.11
76.1 --- a/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Tue Jun 10 16:31:26 2008 -0700
76.2 +++ b/src/solaris/classes/sun/awt/X11GraphicsEnvironment.java Thu Jun 12 11:46:57 2008 -0700
76.3 @@ -48,6 +48,8 @@
76.4 import sun.font.FontManager;
76.5 import sun.font.NativeFont;
76.6 import sun.java2d.SunGraphicsEnvironment;
76.7 +import sun.java2d.SurfaceManagerFactory;
76.8 +import sun.java2d.UnixSurfaceManagerFactory;
76.9
76.10 /**
76.11 * This is an implementation of a GraphicsEnvironment object for the
76.12 @@ -177,6 +179,10 @@
76.13 return null;
76.14 }
76.15 });
76.16 +
76.17 + // Install the correct surface manager factory.
76.18 + SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory());
76.19 +
76.20 }
76.21
76.22 private static boolean glxAvailable;
77.1 --- a/src/solaris/classes/sun/java2d/SurfaceManagerFactory.java Tue Jun 10 16:31:26 2008 -0700
77.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
77.3 @@ -1,65 +0,0 @@
77.4 -/*
77.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
77.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
77.7 - *
77.8 - * This code is free software; you can redistribute it and/or modify it
77.9 - * under the terms of the GNU General Public License version 2 only, as
77.10 - * published by the Free Software Foundation. Sun designates this
77.11 - * particular file as subject to the "Classpath" exception as provided
77.12 - * by Sun in the LICENSE file that accompanied this code.
77.13 - *
77.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
77.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
77.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
77.17 - * version 2 for more details (a copy is included in the LICENSE file that
77.18 - * accompanied this code).
77.19 - *
77.20 - * You should have received a copy of the GNU General Public License version
77.21 - * 2 along with this work; if not, write to the Free Software Foundation,
77.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
77.23 - *
77.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
77.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
77.26 - * have any questions.
77.27 - */
77.28 -
77.29 -package sun.java2d;
77.30 -
77.31 -import java.awt.GraphicsConfiguration;
77.32 -import java.awt.image.BufferedImage;
77.33 -import sun.awt.X11GraphicsConfig;
77.34 -import sun.awt.image.SunVolatileImage;
77.35 -import sun.awt.image.SurfaceManager;
77.36 -import sun.awt.image.VolatileSurfaceManager;
77.37 -import sun.java2d.opengl.GLXGraphicsConfig;
77.38 -import sun.java2d.opengl.GLXVolatileSurfaceManager;
77.39 -import sun.java2d.x11.X11VolatileSurfaceManager;
77.40 -
77.41 -/**
77.42 - * This is a factory class with static methods for creating a
77.43 - * platform-specific instance of a particular SurfaceManager. Each platform
77.44 - * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
77.45 - */
77.46 -public class SurfaceManagerFactory {
77.47 - /**
77.48 - * Creates a new instance of a VolatileSurfaceManager given any
77.49 - * arbitrary SunVolatileImage. An optional context Object can be supplied
77.50 - * as a way for the caller to pass pipeline-specific context data to
77.51 - * the VolatileSurfaceManager (such as a backbuffer handle, for example).
77.52 - *
77.53 - * For Unix platforms, this method returns either an X11- or a GLX-
77.54 - * specific VolatileSurfaceManager based on the GraphicsConfiguration
77.55 - * under which the SunVolatileImage was created.
77.56 - */
77.57 - public static VolatileSurfaceManager
77.58 - createVolatileManager(SunVolatileImage vImg,
77.59 - Object context)
77.60 - {
77.61 - GraphicsConfiguration gc = vImg.getGraphicsConfig();
77.62 - if (gc instanceof GLXGraphicsConfig) {
77.63 - return new GLXVolatileSurfaceManager(vImg, context);
77.64 - } else {
77.65 - return new X11VolatileSurfaceManager(vImg, context);
77.66 - }
77.67 - }
77.68 -}
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
78.2 +++ b/src/solaris/classes/sun/java2d/UnixSurfaceManagerFactory.java Thu Jun 12 11:46:57 2008 -0700
78.3 @@ -0,0 +1,64 @@
78.4 +/*
78.5 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
78.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
78.7 + *
78.8 + * This code is free software; you can redistribute it and/or modify it
78.9 + * under the terms of the GNU General Public License version 2 only, as
78.10 + * published by the Free Software Foundation. Sun designates this
78.11 + * particular file as subject to the "Classpath" exception as provided
78.12 + * by Sun in the LICENSE file that accompanied this code.
78.13 + *
78.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
78.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
78.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
78.17 + * version 2 for more details (a copy is included in the LICENSE file that
78.18 + * accompanied this code).
78.19 + *
78.20 + * You should have received a copy of the GNU General Public License version
78.21 + * 2 along with this work; if not, write to the Free Software Foundation,
78.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
78.23 + *
78.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
78.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
78.26 + * have any questions.
78.27 + */
78.28 +
78.29 +
78.30 +package sun.java2d;
78.31 +
78.32 +import java.awt.GraphicsConfiguration;
78.33 +
78.34 +import sun.awt.image.SunVolatileImage;
78.35 +import sun.awt.image.VolatileSurfaceManager;
78.36 +import sun.java2d.opengl.GLXGraphicsConfig;
78.37 +import sun.java2d.opengl.GLXVolatileSurfaceManager;
78.38 +import sun.java2d.x11.X11VolatileSurfaceManager;
78.39 +
78.40 +/**
78.41 + * The SurfaceManagerFactory that creates VolatileSurfaceManager
78.42 + * implementations for the Unix volatile images.
78.43 + */
78.44 +public class UnixSurfaceManagerFactory extends SurfaceManagerFactory {
78.45 +
78.46 + /**
78.47 + * Creates a new instance of a VolatileSurfaceManager given any
78.48 + * arbitrary SunVolatileImage. An optional context Object can be supplied
78.49 + * as a way for the caller to pass pipeline-specific context data to
78.50 + * the VolatileSurfaceManager (such as a backbuffer handle, for example).
78.51 + *
78.52 + * For Unix platforms, this method returns either an X11- or a GLX-
78.53 + * specific VolatileSurfaceManager based on the GraphicsConfiguration
78.54 + * under which the SunVolatileImage was created.
78.55 + */
78.56 + public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
78.57 + Object context)
78.58 + {
78.59 + GraphicsConfiguration gc = vImg.getGraphicsConfig();
78.60 + if (gc instanceof GLXGraphicsConfig) {
78.61 + return new GLXVolatileSurfaceManager(vImg, context);
78.62 + } else {
78.63 + return new X11VolatileSurfaceManager(vImg, context);
78.64 + }
78.65 + }
78.66 +
78.67 +}
79.1 --- a/src/solaris/classes/sun/print/AttributeClass.java Tue Jun 10 16:31:26 2008 -0700
79.2 +++ b/src/solaris/classes/sun/print/AttributeClass.java Thu Jun 12 11:46:57 2008 -0700
79.3 @@ -32,6 +32,7 @@
79.4 private int nameLen;
79.5 private Object myValue;
79.6
79.7 + public static final int TAG_UNSUPPORTED_VALUE = 0x10;
79.8 public static final int TAG_INT = 0x21;
79.9 public static final int TAG_BOOL = 0x22;
79.10 public static final int TAG_ENUM = 0x23;
80.1 --- a/src/solaris/classes/sun/print/CUPSPrinter.java Tue Jun 10 16:31:26 2008 -0700
80.2 +++ b/src/solaris/classes/sun/print/CUPSPrinter.java Thu Jun 12 11:46:57 2008 -0700
80.3 @@ -333,7 +333,7 @@
80.4 AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
80.5 new AttributeClass("requested-attributes",
80.6 AttributeClass.TAG_KEYWORD,
80.7 - "printer-name")
80.8 + "printer-uri-supported")
80.9 };
80.10
80.11 if (IPPPrintService.writeIPPRequest(os,
80.12 @@ -354,7 +354,7 @@
80.13 ArrayList printerNames = new ArrayList();
80.14 for (int i=0; i< responseMap.length; i++) {
80.15 AttributeClass attribClass = (AttributeClass)
80.16 - responseMap[i].get("printer-name");
80.17 + responseMap[i].get("printer-uri-supported");
80.18
80.19 if (attribClass != null) {
80.20 String nameStr = attribClass.getStringValue();
81.1 --- a/src/solaris/classes/sun/print/IPPPrintService.java Tue Jun 10 16:31:26 2008 -0700
81.2 +++ b/src/solaris/classes/sun/print/IPPPrintService.java Thu Jun 12 11:46:57 2008 -0700
81.3 @@ -335,6 +335,38 @@
81.4 }
81.5
81.6
81.7 + IPPPrintService(String name, String uriStr, boolean isCups) {
81.8 + if ((name == null) || (uriStr == null)){
81.9 + throw new IllegalArgumentException("null uri or printer name");
81.10 + }
81.11 + printer = name;
81.12 + supportedDocFlavors = null;
81.13 + supportedCats = null;
81.14 + mediaSizeNames = null;
81.15 + customMediaSizeNames = null;
81.16 + mediaTrays = null;
81.17 + cps = null;
81.18 + init = false;
81.19 + defaultMediaIndex = -1;
81.20 + try {
81.21 + myURL =
81.22 + new URL(uriStr.replaceFirst("ipp", "http"));
81.23 + } catch (Exception e) {
81.24 + IPPPrintService.debug_println(debugPrefix+
81.25 + " IPPPrintService, myURL="+
81.26 + myURL+" Exception= "+
81.27 + e);
81.28 + }
81.29 +
81.30 + isCupsPrinter = isCups;
81.31 + try {
81.32 + myURI = new URI(uriStr);
81.33 + debug_println(debugPrefix+"IPPPrintService myURI : "+myURI);
81.34 + } catch (java.net.URISyntaxException e) {
81.35 + throw new IllegalArgumentException("invalid uri");
81.36 + }
81.37 + }
81.38 +
81.39
81.40 /*
81.41 * Initialize mediaSizeNames, mediaTrays and other attributes.
81.42 @@ -375,7 +407,7 @@
81.43 return;
81.44 } catch (Exception e) {
81.45 IPPPrintService.debug_println(debugPrefix+
81.46 - " error creating CUPSPrinter");
81.47 + " error creating CUPSPrinter e="+e);
81.48 }
81.49 }
81.50
81.51 @@ -621,17 +653,8 @@
81.52 }
81.53 }
81.54 } else if (category == OrientationRequested.class) {
81.55 - if (flavor == null ||
81.56 - flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
81.57 - flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
81.58 - // Orientation is emulated in Pageable/Printable flavors
81.59 - // so we report the 3 orientations as supported.
81.60 - OrientationRequested []orientSup = new OrientationRequested[3];
81.61 - orientSup[0] = OrientationRequested.PORTRAIT;
81.62 - orientSup[1] = OrientationRequested.LANDSCAPE;
81.63 - orientSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
81.64 - return orientSup;
81.65 - }
81.66 + boolean revPort = false;
81.67 + OrientationRequested[] orientSup = null;
81.68
81.69 AttributeClass attribClass = (getAttMap != null) ?
81.70 (AttributeClass)getAttMap.get("orientation-requested-supported")
81.71 @@ -639,7 +662,7 @@
81.72 if (attribClass != null) {
81.73 int[] orientArray = attribClass.getArrayOfIntValues();
81.74 if ((orientArray != null) && (orientArray.length > 0)) {
81.75 - OrientationRequested[] orientSup =
81.76 + orientSup =
81.77 new OrientationRequested[orientArray.length];
81.78 for (int i=0; i<orientArray.length; i++) {
81.79 switch (orientArray[i]) {
81.80 @@ -657,12 +680,33 @@
81.81 case 6:
81.82 orientSup[i] =
81.83 OrientationRequested.REVERSE_PORTRAIT;
81.84 + revPort = true;
81.85 break;
81.86 }
81.87 }
81.88 - return orientSup;
81.89 }
81.90 }
81.91 + if (flavor == null ||
81.92 + flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
81.93 + flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
81.94 +
81.95 + if (revPort && flavor == null) {
81.96 + OrientationRequested []orSup = new OrientationRequested[4];
81.97 + orSup[0] = OrientationRequested.PORTRAIT;
81.98 + orSup[1] = OrientationRequested.LANDSCAPE;
81.99 + orSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
81.100 + orSup[3] = OrientationRequested.REVERSE_PORTRAIT;
81.101 + return orSup;
81.102 + } else {
81.103 + OrientationRequested []orSup = new OrientationRequested[3];
81.104 + orSup[0] = OrientationRequested.PORTRAIT;
81.105 + orSup[1] = OrientationRequested.LANDSCAPE;
81.106 + orSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
81.107 + return orSup;
81.108 + }
81.109 + } else {
81.110 + return orientSup;
81.111 + }
81.112 } else if (category == PageRanges.class) {
81.113 if (flavor == null ||
81.114 flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
81.115 @@ -795,6 +839,18 @@
81.116
81.117 docList.addAll(Arrays.asList(flavors));
81.118
81.119 + if (isCupsPrinter) {
81.120 + /*
81.121 + Always add Pageable and Printable for CUPS
81.122 + since it uses Filters to convert from Postscript
81.123 + to device printer language.
81.124 + */
81.125 + docList.add(
81.126 + DocFlavor.SERVICE_FORMATTED.PAGEABLE);
81.127 + docList.add(
81.128 + DocFlavor.SERVICE_FORMATTED.PRINTABLE);
81.129 + }
81.130 +
81.131 if (mimeType.equals("text/plain") &&
81.132 addHostEncoding) {
81.133 docList.add(Arrays.asList(textPlainHost));
81.134 @@ -808,11 +864,6 @@
81.135 } else if (mimeType.equals("image/jpeg")) {
81.136 jpgImagesAdded = true;
81.137 } else if (mimeType.indexOf("postscript") != -1) {
81.138 - docList.add(
81.139 - DocFlavor.SERVICE_FORMATTED.PAGEABLE);
81.140 - docList.add(
81.141 - DocFlavor.SERVICE_FORMATTED.PRINTABLE);
81.142 -
81.143 psSupported = true;
81.144 }
81.145 break;
81.146 @@ -829,7 +880,7 @@
81.147 }
81.148
81.149 // check if we need to add image DocFlavors
81.150 - if (psSupported) {
81.151 + if (psSupported || isCupsPrinter) {
81.152 if (!jpgImagesAdded) {
81.153 docList.addAll(Arrays.asList(imageJPG));
81.154 }
81.155 @@ -991,6 +1042,14 @@
81.156 getSupportedAttributeCategories();
81.157 }
81.158
81.159 + // It is safe to assume that Orientation is always supported
81.160 + // and even if CUPS or an IPP device reports it as not,
81.161 + // our renderer can do portrait, landscape and
81.162 + // reverse landscape.
81.163 + if (category == OrientationRequested.class) {
81.164 + return true;
81.165 + }
81.166 +
81.167 for (int i=0;i<supportedCats.length;i++) {
81.168 if (category == supportedCats[i]) {
81.169 return true;
81.170 @@ -1520,10 +1579,7 @@
81.171 if (isCupsPrinter) {
81.172 try {
81.173 urlConnection = getIPPConnection(
81.174 - new URL("http://"+
81.175 - CUPSPrinter.getServer()+":"+
81.176 - CUPSPrinter.getPort()+
81.177 - "/printers/"+printer+".ppd"));
81.178 + new URL(myURL+".ppd"));
81.179
81.180 InputStream is = urlConnection.getInputStream();
81.181 if (is != null) {
81.182 @@ -1539,6 +1595,11 @@
81.183 }
81.184 }
81.185 } catch (java.io.IOException e) {
81.186 + debug_println(" isPostscript, e= "+e);
81.187 + /* if PPD is not found, this may be a raw printer
81.188 + and in this case it is assumed that it is a
81.189 + Postscript printer */
81.190 + // do nothing
81.191 }
81.192 }
81.193 }
81.194 @@ -1602,7 +1663,13 @@
81.195 public static boolean writeIPPRequest(OutputStream os,
81.196 String operCode,
81.197 AttributeClass[] attCl) {
81.198 - OutputStreamWriter osw = new OutputStreamWriter(os);
81.199 + OutputStreamWriter osw;
81.200 + try {
81.201 + osw = new OutputStreamWriter(os, "UTF-8");
81.202 + } catch (java.io.UnsupportedEncodingException exc) {
81.203 + debug_println("UTF-8 not supported? Exception: "+exc);
81.204 + return false;
81.205 + }
81.206 char[] opCode = new char[2];
81.207 opCode[0] = (char)Byte.parseByte(operCode.substring(0,2), 16);
81.208 opCode[1] = (char)Byte.parseByte(operCode.substring(2,4), 16);
81.209 @@ -1690,7 +1757,7 @@
81.210
81.211 // read value tag
81.212 response[0] = ois.readByte();
81.213 - while (response[0] >= AttributeClass.TAG_INT &&
81.214 + while (response[0] >= AttributeClass.TAG_UNSUPPORTED_VALUE &&
81.215 response[0] <= AttributeClass.TAG_MEMBER_ATTRNAME) {
81.216 // read name length
81.217 len = ois.readShort();
81.218 @@ -1710,12 +1777,16 @@
81.219 respList.add(responseMap);
81.220 responseMap = new HashMap();
81.221 }
81.222 - AttributeClass ac =
81.223 - new AttributeClass(attribStr,
81.224 - valTagByte,
81.225 - outArray);
81.226
81.227 - responseMap.put(ac.getName(), ac);
81.228 + // exclude those that are unknown
81.229 + if (valTagByte >= AttributeClass.TAG_INT) {
81.230 + AttributeClass ac =
81.231 + new AttributeClass(attribStr,
81.232 + valTagByte,
81.233 + outArray);
81.234 +
81.235 + responseMap.put(ac.getName(), ac);
81.236 + }
81.237
81.238 outObj = new ByteArrayOutputStream();
81.239 counter = 0; //reset counter
82.1 --- a/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Tue Jun 10 16:31:26 2008 -0700
82.2 +++ b/src/solaris/classes/sun/print/UnixPrintServiceLookup.java Thu Jun 12 11:46:57 2008 -0700
82.3 @@ -196,11 +196,20 @@
82.4
82.5 // refreshes "printServices"
82.6 public synchronized void refreshServices() {
82.7 - String[] printers; /* excludes the default printer */
82.8 + /* excludes the default printer */
82.9 + String[] printers = null; // array of printer names
82.10 + String[] printerURIs = null; //array of printer URIs
82.11
82.12 getDefaultPrintService();
82.13 if (CUPSPrinter.isCupsRunning()) {
82.14 - printers = CUPSPrinter.getAllPrinters();
82.15 + printerURIs = CUPSPrinter.getAllPrinters();
82.16 + if ((printerURIs != null) && (printerURIs.length > 0)) {
82.17 + printers = new String[printerURIs.length];
82.18 + for (int i=0; i<printerURIs.length; i++) {
82.19 + int lastIndex = printerURIs[i].lastIndexOf("/");
82.20 + printers[i] = printerURIs[i].substring(lastIndex+1);
82.21 + }
82.22 + }
82.23 } else {
82.24 if (isSysV()) {
82.25 printers = getAllPrinterNamesSysV();
82.26 @@ -236,12 +245,9 @@
82.27
82.28 if (CUPSPrinter.isCupsRunning()) {
82.29 try {
82.30 - URL serviceURL =
82.31 - new URL("http://"+
82.32 - CUPSPrinter.getServer()+":"+
82.33 - CUPSPrinter.getPort()+"/"+printers[p]);
82.34 - printerList.add(new IPPPrintService( printers[p],
82.35 - serviceURL));
82.36 + printerList.add(new IPPPrintService(printers[p],
82.37 + printerURIs[p],
82.38 + true));
82.39 } catch (Exception e) {
82.40 IPPPrintService.debug_println(debugPrefix+
82.41 " getAllPrinters Exception "+
82.42 @@ -265,12 +271,10 @@
82.43 if (j == printServices.length) { // not found?
82.44 if (CUPSPrinter.isCupsRunning()) {
82.45 try {
82.46 - URL serviceURL =
82.47 - new URL("http://"+
82.48 - CUPSPrinter.getServer()+":"+
82.49 - CUPSPrinter.getPort()+"/"+printers[p]);
82.50 - printerList.add(new IPPPrintService( printers[p],
82.51 - serviceURL));
82.52 + printerList.add(new IPPPrintService(
82.53 + printers[p],
82.54 + printerURIs[p],
82.55 + true));
82.56 } catch (Exception e) {
82.57 IPPPrintService.debug_println(debugPrefix+
82.58 " getAllPrinters Exception "+
83.1 --- a/src/solaris/native/java/net/PlainSocketImpl.c Tue Jun 10 16:31:26 2008 -0700
83.2 +++ b/src/solaris/native/java/net/PlainSocketImpl.c Thu Jun 12 11:46:57 2008 -0700
83.3 @@ -358,15 +358,28 @@
83.4 * See 6343810.
83.5 */
83.6 while (1) {
83.7 - fd_set wr, ex;
83.8 +#ifndef USE_SELECT
83.9 + {
83.10 +fprintf(stdout,"\nNATIVE: fd = %d] ", fd);
83.11 + struct pollfd pfd;
83.12 + pfd.fd = fd;
83.13 + pfd.events = POLLOUT;
83.14
83.15 - FD_ZERO(&wr);
83.16 - FD_SET(fd, &wr);
83.17 - FD_ZERO(&ex);
83.18 - FD_SET(fd, &ex);
83.19 + connect_rv = NET_Poll(&pfd, 1, -1);
83.20 + }
83.21 +#else
83.22 + {
83.23 + fd_set wr, ex;
83.24
83.25 - errno = 0;
83.26 - connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
83.27 + FD_ZERO(&wr);
83.28 + FD_SET(fd, &wr);
83.29 + FD_ZERO(&ex);
83.30 + FD_SET(fd, &ex);
83.31 +
83.32 + connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
83.33 + }
83.34 +#endif
83.35 +
83.36 if (connect_rv == JVM_IO_ERR) {
83.37 if (errno == EINTR) {
83.38 continue;
84.1 --- a/src/solaris/native/sun/awt/awt_GraphicsEnv.c Tue Jun 10 16:31:26 2008 -0700
84.2 +++ b/src/solaris/native/sun/awt/awt_GraphicsEnv.c Thu Jun 12 11:46:57 2008 -0700
84.3 @@ -650,7 +650,7 @@
84.4 if (XineramaQueryScreens != NULL) {
84.5 DTRACE_PRINTLN("calling XineramaQueryScreens func on Linux");
84.6 xinInfo = (*XineramaQueryScreens)(awt_display, &locNumScr);
84.7 - if (xinInfo != NULL) {
84.8 + if (xinInfo != NULL && locNumScr > XScreenCount(awt_display)) {
84.9 int32_t idx;
84.10 DTRACE_PRINTLN("Enabling Xinerama support");
84.11 usingXinerama = True;
84.12 @@ -701,7 +701,8 @@
84.13 if (XineramaSolarisFunc != NULL) {
84.14 DTRACE_PRINTLN("calling XineramaGetInfo func on Solaris");
84.15 if ((*XineramaSolarisFunc)(awt_display, 0, &fbrects[0],
84.16 - &fbhints[0], &locNumScr) != 0)
84.17 + &fbhints[0], &locNumScr) != 0 &&
84.18 + locNumScr > XScreenCount(awt_display))
84.19 {
84.20 DTRACE_PRINTLN("Enabling Xinerama support");
84.21 usingXinerama = True;
84.22 @@ -1626,6 +1627,8 @@
84.23
84.24 #define BIT_DEPTH_MULTI java_awt_DisplayMode_BIT_DEPTH_MULTI
84.25
84.26 +typedef Status
84.27 + (*XRRQueryVersionType) (Display *dpy, int *major_versionp, int *minor_versionp);
84.28 typedef XRRScreenConfiguration*
84.29 (*XRRGetScreenInfoType)(Display *dpy, Drawable root);
84.30 typedef void
84.31 @@ -1650,6 +1653,7 @@
84.32 short rate,
84.33 Time timestamp);
84.34
84.35 +static XRRQueryVersionType awt_XRRQueryVersion;
84.36 static XRRGetScreenInfoType awt_XRRGetScreenInfo;
84.37 static XRRFreeScreenConfigInfoType awt_XRRFreeScreenConfigInfo;
84.38 static XRRConfigRatesType awt_XRRConfigRates;
84.39 @@ -1672,6 +1676,8 @@
84.40 static jboolean
84.41 X11GD_InitXrandrFuncs(JNIEnv *env)
84.42 {
84.43 + int rr_maj_ver = 0, rr_min_ver = 0;
84.44 +
84.45 void *pLibRandR = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_LOCAL);
84.46 if (pLibRandR == NULL) {
84.47 J2dRlsTraceLn(J2D_TRACE_ERROR,
84.48 @@ -1679,6 +1685,41 @@
84.49 return JNI_FALSE;
84.50 }
84.51
84.52 + LOAD_XRANDR_FUNC(XRRQueryVersion);
84.53 +
84.54 + if (!(*awt_XRRQueryVersion)(awt_display, &rr_maj_ver, &rr_min_ver)) {
84.55 + J2dRlsTraceLn(J2D_TRACE_ERROR,
84.56 + "X11GD_InitXrandrFuncs: XRRQueryVersion returned an error status");
84.57 + dlclose(pLibRandR);
84.58 + return JNI_FALSE;
84.59 + }
84.60 +
84.61 + if (usingXinerama) {
84.62 + /*
84.63 + * We can proceed as long as this is RANDR 1.2 or above.
84.64 + * As of Xorg server 1.3 onwards the Xinerama backend may actually be
84.65 + * a fake one provided by RANDR itself. See Java bug 6636469 for info.
84.66 + */
84.67 + if (!(rr_maj_ver > 1 || (rr_maj_ver == 1 && rr_min_ver >= 2))) {
84.68 + J2dRlsTraceLn2(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
84.69 + "Xinerama is active and Xrandr version is %d.%d",
84.70 + rr_maj_ver, rr_min_ver);
84.71 + dlclose(pLibRandR);
84.72 + return JNI_FALSE;
84.73 + }
84.74 +
84.75 + /*
84.76 + * REMIND: Fullscreen mode doesn't work quite right with multi-monitor
84.77 + * setups and RANDR 1.2. So for now we also require a single screen.
84.78 + */
84.79 + if (awt_numScreens > 1 ) {
84.80 + J2dRlsTraceLn(J2D_TRACE_INFO, "X11GD_InitXrandrFuncs: Can't use Xrandr. "
84.81 + "Multiple screens in use");
84.82 + dlclose(pLibRandR);
84.83 + return JNI_FALSE;
84.84 + }
84.85 + }
84.86 +
84.87 LOAD_XRANDR_FUNC(XRRGetScreenInfo);
84.88 LOAD_XRANDR_FUNC(XRRFreeScreenConfigInfo);
84.89 LOAD_XRANDR_FUNC(XRRConfigRates);
84.90 @@ -1814,15 +1855,6 @@
84.91 int opcode = 0, firstEvent = 0, firstError = 0;
84.92 jboolean ret;
84.93
84.94 - if (usingXinerama) {
84.95 - /*
84.96 - * REMIND: we'll just punt if Xinerama is enabled; we can remove this
84.97 - * restriction in the future if we find Xinerama and XRandR playing
84.98 - * well together...
84.99 - */
84.100 - return JNI_FALSE;
84.101 - }
84.102 -
84.103 AWT_LOCK();
84.104 ret = (jboolean)XQueryExtension(awt_display, "RANDR",
84.105 &opcode, &firstEvent, &firstError);
85.1 --- a/src/solaris/native/sun/java2d/loops/vis_FourByteAbgr.c Tue Jun 10 16:31:26 2008 -0700
85.2 +++ b/src/solaris/native/sun/java2d/loops/vis_FourByteAbgr.c Thu Jun 12 11:46:57 2008 -0700
85.3 @@ -1936,6 +1936,7 @@
85.4 for (j = 0; j < height; j++) {
85.5 mlib_u8 *src = (void*)pixels;
85.6 mlib_s32 *dst, *dst_end;
85.7 + mlib_u8 *dst_start;
85.8
85.9 if ((mlib_s32)dstBase & 3) {
85.10 COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32));
85.11 @@ -1943,8 +1944,14 @@
85.12 } else {
85.13 dst = (void*)dstBase;
85.14 }
85.15 + dst_start = (void*)dst;
85.16 dst_end = dst + width;
85.17
85.18 + /* Need to reset the GSR from the values set by the
85.19 + * convert call near the end of this loop.
85.20 + */
85.21 + vis_write_gsr(7 << 0);
85.22 +
85.23 if ((mlib_s32)dst & 7) {
85.24 pix = *src++;
85.25 dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
85.26 @@ -1984,8 +1991,13 @@
85.27 dst++;
85.28 }
85.29
85.30 + ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, dst_start,
85.31 + width, 1,
85.32 + pRasInfo, pRasInfo,
85.33 + pPrim, pCompInfo);
85.34 +
85.35 if ((mlib_s32)dstBase & 3) {
85.36 - COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32));
85.37 + COPY_NA(dst_start, dstBase, width*sizeof(mlib_s32));
85.38 }
85.39
85.40 PTR_ADD(dstBase, scan);
86.1 --- a/src/solaris/native/sun/java2d/loops/vis_FourByteAbgrPre.c Tue Jun 10 16:31:26 2008 -0700
86.2 +++ b/src/solaris/native/sun/java2d/loops/vis_FourByteAbgrPre.c Thu Jun 12 11:46:57 2008 -0700
86.3 @@ -181,6 +181,7 @@
86.4 d_half = vis_to_double_dup((1 << (16 + 6)) | (1 << 6));
86.5
86.6 srcG_f = vis_to_float(argbcolor);
86.7 + ARGB2ABGR_FL(srcG_f);
86.8
86.9 for (glyphCounter = 0; glyphCounter < totalGlyphs; glyphCounter++) {
86.10 const jubyte *pixels;
86.11 @@ -238,8 +239,33 @@
86.12 mlib_u8 *src = (void*)pixels;
86.13 mlib_s32 *dst, *dst_end;
86.14 mlib_u8 *dst8;
86.15 + mlib_u8* dst_start = dstBase;
86.16
86.17 - ADD_SUFF(FourByteAbgrPreToIntArgbConvert)(dstBase, pbuff, width, 1,
86.18 + /*
86.19 + * Typically the inner loop here works on Argb input data, an
86.20 + * Argb color, and produces ArgbPre output data. To use that
86.21 + * standard approach we would need a FourByteAbgrPre to IntArgb
86.22 + * converter for the front end and an IntArgbPre to FourByteAbgrPre
86.23 + * converter for the back end. The converter exists for the
86.24 + * front end, but it is a workaround implementation that uses a 2
86.25 + * stage conversion and an intermediate buffer that is allocated
86.26 + * on every call. The converter for the back end doesn't really
86.27 + * exist, but we could reuse the IntArgb to FourByteAbgr converter
86.28 + * to do the same work - at the cost of swapping the components as
86.29 + * we copy the data back. All of this is more work than we really
86.30 + * need so we use an alternate procedure:
86.31 + * - Copy the data into an int-aligned temporary buffer (if needed)
86.32 + * - Convert the data from FourByteAbgrPre to IntAbgr by using the
86.33 + * IntArgbPre to IntArgb converter in the int-aligned buffer.
86.34 + * - Swap the color data to Abgr so that the inner loop goes from
86.35 + * IntAbgr data to IntAbgrPre data
86.36 + * - Simply copy the IntAbgrPre data back into place.
86.37 + */
86.38 + if (((mlib_s32)dstBase) & 3) {
86.39 + COPY_NA(dstBase, pbuff, width*sizeof(mlib_s32));
86.40 + dst_start = pbuff;
86.41 + }
86.42 + ADD_SUFF(IntArgbPreToIntArgbConvert)(dst_start, pbuff, width, 1,
86.43 pRasInfo, pRasInfo,
86.44 pPrim, pCompInfo);
86.45
86.46 @@ -283,9 +309,7 @@
86.47 dst++;
86.48 }
86.49
86.50 - ADD_SUFF(IntArgbToFourByteAbgrPreConvert)(pbuff, dstBase, width, 1,
86.51 - pRasInfo, pRasInfo,
86.52 - pPrim, pCompInfo);
86.53 + COPY_NA(pbuff, dstBase, width*sizeof(mlib_s32));
86.54
86.55 src = (void*)pixels;
86.56 dst8 = (void*)dstBase;
87.1 --- a/src/solaris/native/sun/java2d/loops/vis_IntArgb.c Tue Jun 10 16:31:26 2008 -0700
87.2 +++ b/src/solaris/native/sun/java2d/loops/vis_IntArgb.c Thu Jun 12 11:46:57 2008 -0700
87.3 @@ -428,6 +428,11 @@
87.4 dst = (void*)dstBase;
87.5 dst_end = dst + width;
87.6
87.7 + /* Clearing the Graphics Status Register is necessary otherwise
87.8 + * left over scale settings affect the pack instructions.
87.9 + */
87.10 + vis_write_gsr(0 << 3);
87.11 +
87.12 if ((mlib_s32)dst & 7) {
87.13 pix = *src++;
87.14 dd = vis_fpadd16(MUL8_VIS(srcG_f, pix), d_half);
87.15 @@ -467,6 +472,9 @@
87.16 dst++;
87.17 }
87.18
87.19 + ADD_SUFF(IntArgbPreToIntArgbConvert)(dstBase, dstBase, width, 1,
87.20 + pRasInfo, pRasInfo,
87.21 + pPrim, pCompInfo);
87.22 PTR_ADD(dstBase, scan);
87.23 pixels += rowBytes;
87.24 }
88.1 --- a/src/solaris/native/sun/java2d/loops/vis_IntArgbPre.c Tue Jun 10 16:31:26 2008 -0700
88.2 +++ b/src/solaris/native/sun/java2d/loops/vis_IntArgbPre.c Thu Jun 12 11:46:57 2008 -0700
88.3 @@ -1193,10 +1193,6 @@
88.4 dst++;
88.5 }
88.6
88.7 - ADD_SUFF(IntArgbToIntArgbPreConvert)(dstBase, dstBase, width, 1,
88.8 - pRasInfo, pRasInfo,
88.9 - pPrim, pCompInfo);
88.10 -
88.11 PTR_ADD(dstBase, scan);
88.12 pixels += rowBytes;
88.13 }
89.1 --- a/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java Tue Jun 10 16:31:26 2008 -0700
89.2 +++ b/src/windows/classes/sun/awt/Win32GraphicsEnvironment.java Thu Jun 12 11:46:57 2008 -0700
89.3 @@ -42,6 +42,8 @@
89.4 import sun.awt.windows.WToolkit;
89.5 import sun.font.FontManager;
89.6 import sun.java2d.SunGraphicsEnvironment;
89.7 +import sun.java2d.SurfaceManagerFactory;
89.8 +import sun.java2d.WindowsSurfaceManagerFactory;
89.9 import sun.java2d.windows.WindowsFlags;
89.10
89.11 /**
89.12 @@ -64,6 +66,9 @@
89.13 WindowsFlags.initFlags();
89.14 initDisplayWrapper();
89.15 eudcFontFileName = getEUDCFontFile();
89.16 +
89.17 + // Install correct surface manager factory.
89.18 + SurfaceManagerFactory.setInstance(new WindowsSurfaceManagerFactory());
89.19 }
89.20
89.21 /**
89.22 @@ -260,6 +265,7 @@
89.23 try {
89.24 while (!found && parser.hasMoreTokens()) {
89.25 String newPath = parser.nextToken();
89.26 + boolean ujr = newPath.equals(jreFontDirName);
89.27 File theFile = new File(newPath, fontFileName);
89.28 if (theFile.canRead()) {
89.29 found = true;
89.30 @@ -267,11 +273,11 @@
89.31 if (defer) {
89.32 FontManager.registerDeferredFont(fontFileName, path,
89.33 nativeNames,
89.34 - fontFormat, true,
89.35 + fontFormat, ujr,
89.36 fontRank);
89.37 } else {
89.38 FontManager.registerFontFile(path, nativeNames,
89.39 - fontFormat, true,
89.40 + fontFormat, ujr,
89.41 fontRank);
89.42 }
89.43 break;
89.44 @@ -296,7 +302,7 @@
89.45 }
89.46
89.47 public static void registerJREFontsForPrinting() {
89.48 - String pathName = null;
89.49 + final String pathName;
89.50 synchronized (Win32GraphicsEnvironment.class) {
89.51 GraphicsEnvironment.getLocalGraphicsEnvironment();
89.52 if (fontsForPrinting == null) {
89.53 @@ -305,15 +311,21 @@
89.54 pathName = fontsForPrinting;
89.55 fontsForPrinting = null;
89.56 }
89.57 - File f1 = new File(pathName);
89.58 - String[] ls = f1.list(new TTFilter());
89.59 - if (ls == null) {
89.60 - return;
89.61 - }
89.62 - for (int i=0; i <ls.length; i++ ) {
89.63 - File fontFile = new File(f1, ls[i]);
89.64 - registerFontWithPlatform(fontFile.getAbsolutePath());
89.65 - }
89.66 + java.security.AccessController.doPrivileged(
89.67 + new java.security.PrivilegedAction() {
89.68 + public Object run() {
89.69 + File f1 = new File(pathName);
89.70 + String[] ls = f1.list(new TTFilter());
89.71 + if (ls == null) {
89.72 + return null;
89.73 + }
89.74 + for (int i=0; i <ls.length; i++ ) {
89.75 + File fontFile = new File(f1, ls[i]);
89.76 + registerFontWithPlatform(fontFile.getAbsolutePath());
89.77 + }
89.78 + return null;
89.79 + }
89.80 + });
89.81 }
89.82
89.83 protected static native void registerFontWithPlatform(String fontName);
90.1 --- a/src/windows/classes/sun/awt/windows/WPathGraphics.java Tue Jun 10 16:31:26 2008 -0700
90.2 +++ b/src/windows/classes/sun/awt/windows/WPathGraphics.java Thu Jun 12 11:46:57 2008 -0700
90.3 @@ -943,8 +943,16 @@
90.4 double devResY = wPrinterJob.getYRes();
90.5 double devScaleX = devResX / DEFAULT_USER_RES;
90.6 double devScaleY = devResY / DEFAULT_USER_RES;
90.7 - if (scaleX > devScaleX) scaleX = devScaleX;
90.8 - if (scaleY > devScaleY) scaleY = devScaleY;
90.9 +
90.10 + /* check if rotated or sheared */
90.11 + int transformType = fullTransform.getType();
90.12 + boolean clampScale = ((transformType &
90.13 + (AffineTransform.TYPE_GENERAL_ROTATION |
90.14 + AffineTransform.TYPE_GENERAL_TRANSFORM)) != 0);
90.15 + if (clampScale) {
90.16 + if (scaleX > devScaleX) scaleX = devScaleX;
90.17 + if (scaleY > devScaleY) scaleY = devScaleY;
90.18 + }
90.19
90.20 /* We do not need to draw anything if either scaling
90.21 * factor is zero.
91.1 --- a/src/windows/classes/sun/java2d/SurfaceManagerFactory.java Tue Jun 10 16:31:26 2008 -0700
91.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
91.3 @@ -1,64 +0,0 @@
91.4 -/*
91.5 - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
91.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
91.7 - *
91.8 - * This code is free software; you can redistribute it and/or modify it
91.9 - * under the terms of the GNU General Public License version 2 only, as
91.10 - * published by the Free Software Foundation. Sun designates this
91.11 - * particular file as subject to the "Classpath" exception as provided
91.12 - * by Sun in the LICENSE file that accompanied this code.
91.13 - *
91.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
91.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
91.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
91.17 - * version 2 for more details (a copy is included in the LICENSE file that
91.18 - * accompanied this code).
91.19 - *
91.20 - * You should have received a copy of the GNU General Public License version
91.21 - * 2 along with this work; if not, write to the Free Software Foundation,
91.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
91.23 - *
91.24 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
91.25 - * CA 95054 USA or visit www.sun.com if you need additional information or
91.26 - * have any questions.
91.27 - */
91.28 -
91.29 -package sun.java2d;
91.30 -
91.31 -import java.awt.GraphicsConfiguration;
91.32 -import java.awt.image.BufferedImage;
91.33 -import sun.awt.image.SunVolatileImage;
91.34 -import sun.awt.image.SurfaceManager;
91.35 -import sun.awt.image.VolatileSurfaceManager;
91.36 -import sun.java2d.opengl.WGLGraphicsConfig;
91.37 -import sun.java2d.opengl.WGLVolatileSurfaceManager;
91.38 -import sun.java2d.windows.WindowsFlags;
91.39 -import sun.java2d.windows.WinVolatileSurfaceManager;
91.40 -
91.41 -/**
91.42 - * This is a factory class with static methods for creating a
91.43 - * platform-specific instance of a particular SurfaceManager. Each platform
91.44 - * (Windows, Unix, etc.) has its own specialized SurfaceManagerFactory.
91.45 - */
91.46 -public class SurfaceManagerFactory {
91.47 - /**
91.48 - * Creates a new instance of a VolatileSurfaceManager given any
91.49 - * arbitrary SunVolatileImage. An optional context Object can be supplied
91.50 - * as a way for the caller to pass pipeline-specific context data to
91.51 - * the VolatileSurfaceManager (such as a backbuffer handle, for example).
91.52 - *
91.53 - * For Windows platforms, this method returns a Windows-specific
91.54 - * VolatileSurfaceManager.
91.55 - */
91.56 - public static VolatileSurfaceManager
91.57 - createVolatileManager(SunVolatileImage vImg,
91.58 - Object context)
91.59 - {
91.60 - GraphicsConfiguration gc = vImg.getGraphicsConfig();
91.61 - if (gc instanceof WGLGraphicsConfig) {
91.62 - return new WGLVolatileSurfaceManager(vImg, context);
91.63 - } else {
91.64 - return new WinVolatileSurfaceManager(vImg, context);
91.65 - }
91.66 - }
91.67 -}
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
92.2 +++ b/src/windows/classes/sun/java2d/WindowsSurfaceManagerFactory.java Thu Jun 12 11:46:57 2008 -0700
92.3 @@ -0,0 +1,64 @@
92.4 +/*
92.5 + * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
92.7 + *
92.8 + * This code is free software; you can redistribute it and/or modify it
92.9 + * under the terms of the GNU General Public License version 2 only, as
92.10 + * published by the Free Software Foundation. Sun designates this
92.11 + * particular file as subject to the "Classpath" exception as provided
92.12 + * by Sun in the LICENSE file that accompanied this code.
92.13 + *
92.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
92.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
92.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
92.17 + * version 2 for more details (a copy is included in the LICENSE file that
92.18 + * accompanied this code).
92.19 + *
92.20 + * You should have received a copy of the GNU General Public License version
92.21 + * 2 along with this work; if not, write to the Free Software Foundation,
92.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
92.23 + *
92.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
92.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
92.26 + * have any questions.
92.27 + */
92.28 +
92.29 +package sun.java2d;
92.30 +
92.31 +import java.awt.GraphicsConfiguration;
92.32 +import java.awt.image.BufferedImage;
92.33 +import sun.awt.image.SunVolatileImage;
92.34 +import sun.awt.image.SurfaceManager;
92.35 +import sun.awt.image.VolatileSurfaceManager;
92.36 +import sun.java2d.opengl.WGLGraphicsConfig;
92.37 +import sun.java2d.opengl.WGLVolatileSurfaceManager;
92.38 +import sun.java2d.windows.WindowsFlags;
92.39 +import sun.java2d.windows.WinVolatileSurfaceManager;
92.40 +
92.41 +/**
92.42 + * The SurfaceManagerFactory that creates VolatileSurfaceManager
92.43 + * implementations for the Windows volatile images.
92.44 + */
92.45 +public class WindowsSurfaceManagerFactory extends SurfaceManagerFactory {
92.46 +
92.47 + /**
92.48 + * Creates a new instance of a VolatileSurfaceManager given any
92.49 + * arbitrary SunVolatileImage. An optional context Object can be supplied
92.50 + * as a way for the caller to pass pipeline-specific context data to
92.51 + * the VolatileSurfaceManager (such as a backbuffer handle, for example).
92.52 + *
92.53 + * For Windows platforms, this method returns a Windows-specific
92.54 + * VolatileSurfaceManager.
92.55 + */
92.56 + public VolatileSurfaceManager createVolatileManager(SunVolatileImage vImg,
92.57 + Object context)
92.58 + {
92.59 + GraphicsConfiguration gc = vImg.getGraphicsConfig();
92.60 + if (gc instanceof WGLGraphicsConfig) {
92.61 + return new WGLVolatileSurfaceManager(vImg, context);
92.62 + } else {
92.63 + return new WinVolatileSurfaceManager(vImg, context);
92.64 + }
92.65 + }
92.66 +
92.67 +}
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
93.2 +++ b/src/windows/native/sun/font/lcdglyph.c Thu Jun 12 11:46:57 2008 -0700
93.3 @@ -0,0 +1,481 @@
93.4 +/*
93.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
93.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
93.7 + *
93.8 + * This code is free software; you can redistribute it and/or modify it
93.9 + * under the terms of the GNU General Public License version 2 only, as
93.10 + * published by the Free Software Foundation. Sun designates this
93.11 + * particular file as subject to the "Classpath" exception as provided
93.12 + * by Sun in the LICENSE file that accompanied this code.
93.13 + *
93.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
93.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
93.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
93.17 + * version 2 for more details (a copy is included in the LICENSE file that
93.18 + * accompanied this code).
93.19 + *
93.20 + * You should have received a copy of the GNU General Public License version
93.21 + * 2 along with this work; if not, write to the Free Software Foundation,
93.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
93.23 + *
93.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
93.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
93.26 + * have any questions.
93.27 + */
93.28 +
93.29 +/*
93.30 + * The function here is used to get a GDI rasterized LCD glyph and place it
93.31 + * into the JDK glyph cache. The benefit is rendering fidelity for the
93.32 + * most common cases, with no impact on the 2D rendering pipelines.
93.33 + *
93.34 + * Requires that the font and graphics are unrotated, and the scale is
93.35 + * a simple one, and the font is a TT font registered with windows.
93.36 + * Those conditions are established by the calling code.
93.37 + *
93.38 + * This code
93.39 + * - Receives the family name, style, and size of the font
93.40 + * and creates a Font object.
93.41 + * - Create a surface from which we can get a DC : must be 16 bit or more.
93.42 + * Ideally we'd be able to specify the depth of this, but in practice we
93.43 + * have to accept it will be the same as the default screen.
93.44 + * - Selects the GDI font on to the device
93.45 + * - Uses GetGlyphOutline to estimate the bounds.
93.46 + * - Creates a DIB on to which to blit the image.
93.47 + * - Creates a GlyphInfo structure and copies the GDI glyph and offsets
93.48 + * into the glyph which is returned.
93.49 + */
93.50 +
93.51 +#include <stdio.h>
93.52 +#include <malloc.h>
93.53 +#include <math.h>
93.54 +#include <windows.h>
93.55 +#include <winuser.h>
93.56 +
93.57 +#include <jni.h>
93.58 +#include <jni_util.h>
93.59 +#include <jlong_md.h>
93.60 +#include <sun_font_FileFontStrike.h>
93.61 +
93.62 +#include "fontscalerdefs.h"
93.63 +
93.64 +/* Some of these are also defined in awtmsg.h but I don't want a dependency
93.65 + * on that here. They are needed here - and in awtmsg.h - until we
93.66 + * move up our build to define WIN32_WINNT >= 0x501 (ie XP), since MS
93.67 + * headers will not define them otherwise.
93.68 + */
93.69 +#ifndef SPI_GETFONTSMOOTHINGTYPE
93.70 +#define SPI_GETFONTSMOOTHINGTYPE 0x200A
93.71 +#endif //SPI_GETFONTSMOOTHINGTYPE
93.72 +
93.73 +#ifndef SPI_GETFONTSMOOTHINGCONTRAST
93.74 +#define SPI_GETFONTSMOOTHINGCONTRAST 0x200C
93.75 +#endif //SPI_GETFONTSMOOTHINGCONTRAST
93.76 +
93.77 +#ifndef SPI_GETFONTSMOOTHINGORIENTATION
93.78 +#define SPI_GETFONTSMOOTHINGORIENTATION 0x2012
93.79 +#endif //SPI_GETFONTSMOOTHINGORIENTATION
93.80 +
93.81 +#ifndef FE_FONTSMOOTHINGORIENTATIONBGR
93.82 +#define FE_FONTSMOOTHINGORIENTATIONBGR 0x0000
93.83 +#endif //FE_FONTSMOOTHINGORIENTATIONBGR
93.84 +
93.85 +#ifndef FE_FONTSMOOTHINGORIENTATIONRGB
93.86 +#define FE_FONTSMOOTHINGORIENTATIONRGB 0x0001
93.87 +#endif //FE_FONTSMOOTHINGORIENTATIONRGB
93.88 +
93.89 +#define MIN_GAMMA 100
93.90 +#define MAX_GAMMA 220
93.91 +#define LCDLUTCOUNT (MAX_GAMMA-MIN_GAMMA+1)
93.92 +
93.93 +static unsigned char* igLUTable[LCDLUTCOUNT];
93.94 +
93.95 +static unsigned char* getIGTable(int gamma) {
93.96 + int i, index;
93.97 + double ig;
93.98 + char *igTable;
93.99 +
93.100 + if (gamma < MIN_GAMMA) {
93.101 + gamma = MIN_GAMMA;
93.102 + } else if (gamma > MAX_GAMMA) {
93.103 + gamma = MAX_GAMMA;
93.104 + }
93.105 +
93.106 + index = gamma - MIN_GAMMA;
93.107 +
93.108 + if (igLUTable[index] != NULL) {
93.109 + return igLUTable[index];
93.110 + }
93.111 + igTable = (unsigned char*)malloc(256);
93.112 + if (igTable == NULL) {
93.113 + return NULL;
93.114 + }
93.115 + igTable[0] = 0;
93.116 + igTable[255] = 255;
93.117 + ig = ((double)gamma)/100.0;
93.118 +
93.119 + for (i=1;i<255;i++) {
93.120 + igTable[i] = (unsigned char)(pow(((double)i)/255.0, ig)*255);
93.121 + }
93.122 + igLUTable[index] = igTable;
93.123 + return igTable;
93.124 +}
93.125 +
93.126 +
93.127 +JNIEXPORT jboolean JNICALL
93.128 + Java_sun_font_FileFontStrike_initNative(JNIEnv *env, jclass unused) {
93.129 +
93.130 + DWORD osVersion = GetVersion();
93.131 + DWORD majorVersion = (DWORD)(LOBYTE(LOWORD(osVersion)));
93.132 + DWORD minorVersion = (DWORD)(HIBYTE(LOWORD(osVersion)));
93.133 +
93.134 + /* Need at least XP which is 5.1 */
93.135 + if (majorVersion < 5 || (majorVersion == 5 && minorVersion < 1)) {
93.136 + return JNI_FALSE;
93.137 + }
93.138 +
93.139 + memset(igLUTable, 0, LCDLUTCOUNT);
93.140 +
93.141 + return JNI_TRUE;
93.142 +}
93.143 +
93.144 +#ifndef CLEARTYPE_QUALITY
93.145 +#define CLEARTYPE_QUALITY 5
93.146 +#endif
93.147 +
93.148 +#ifndef CLEARTYPE_NATURAL_QUALITY
93.149 +#define CLEARTYPE_NATURAL_QUALITY 6
93.150 +#endif
93.151 +
93.152 +#define FREE_AND_RETURN \
93.153 + if (hDesktopDC != 0 && hWnd != 0) { \
93.154 + ReleaseDC(hWnd, hDesktopDC); \
93.155 + }\
93.156 + if (hMemoryDC != 0) { \
93.157 + DeleteObject(hMemoryDC); \
93.158 + } \
93.159 + if (hBitmap != 0) { \
93.160 + DeleteObject(hBitmap); \
93.161 + } \
93.162 + if (dibImage != NULL) { \
93.163 + free(dibImage); \
93.164 + } \
93.165 + if (glyphInfo != NULL) { \
93.166 + free(glyphInfo); \
93.167 + } \
93.168 + return (jlong)0;
93.169 +/* end define */
93.170 +
93.171 +JNIEXPORT jlong JNICALL
93.172 +Java_sun_font_FileFontStrike__1getGlyphImageFromWindows
93.173 +(JNIEnv *env, jobject unused,
93.174 + jstring fontFamily, jint style, jint size, jint glyphCode, jboolean fm) {
93.175 +
93.176 + GLYPHMETRICS glyphMetrics;
93.177 + LOGFONTW lf;
93.178 + BITMAPINFO bmi;
93.179 + TEXTMETRIC textMetric;
93.180 + RECT rect;
93.181 + int bytesWidth, dibBytesWidth, extra, imageSize, dibImageSize;
93.182 + unsigned char* dibImage = NULL, *rowPtr, *pixelPtr, *dibPixPtr, *dibRowPtr;
93.183 + unsigned char r,g,b;
93.184 + unsigned char* igTable;
93.185 + GlyphInfo* glyphInfo = NULL;
93.186 + int nameLen;
93.187 + LPWSTR name;
93.188 + HFONT oldFont, hFont;
93.189 + MAT2 mat2;
93.190 +
93.191 + unsigned short width;
93.192 + unsigned short height;
93.193 + short advanceX;
93.194 + short advanceY;
93.195 + int topLeftX;
93.196 + int topLeftY;
93.197 + int err;
93.198 + int bmWidth, bmHeight;
93.199 + int x, y;
93.200 + HBITMAP hBitmap = NULL, hOrigBM;
93.201 + int gamma, orient;
93.202 +
93.203 + HWND hWnd = NULL;
93.204 + HDC hDesktopDC = NULL;
93.205 + HDC hMemoryDC = NULL;
93.206 +
93.207 + hWnd = GetDesktopWindow();
93.208 + hDesktopDC = GetWindowDC(hWnd);
93.209 + if (hDesktopDC == NULL) {
93.210 + return (jlong)0;
93.211 + }
93.212 + if (GetDeviceCaps(hDesktopDC, BITSPIXEL) < 15) {
93.213 + FREE_AND_RETURN;
93.214 + }
93.215 +
93.216 + hMemoryDC = CreateCompatibleDC(hDesktopDC);
93.217 + if (hMemoryDC == NULL || fontFamily == NULL) {
93.218 + FREE_AND_RETURN;
93.219 + }
93.220 + err = SetMapMode(hMemoryDC, MM_TEXT);
93.221 + if (err == 0) {
93.222 + FREE_AND_RETURN;
93.223 + }
93.224 +
93.225 + memset(&lf, 0, sizeof(LOGFONTW));
93.226 + lf.lfHeight = -size;
93.227 + lf.lfWeight = (style & 1) ? FW_BOLD : FW_NORMAL;
93.228 + lf.lfItalic = (style & 2) ? 0xff : 0;
93.229 + lf.lfCharSet = DEFAULT_CHARSET;
93.230 + lf.lfQuality = CLEARTYPE_QUALITY;
93.231 + lf.lfOutPrecision = OUT_TT_PRECIS;
93.232 + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
93.233 + lf.lfPitchAndFamily = DEFAULT_PITCH;
93.234 +
93.235 + nameLen = (*env)->GetStringLength(env, fontFamily);
93.236 + name = (LPWSTR)alloca((nameLen+1)*2);
93.237 + if (name == NULL) {
93.238 + FREE_AND_RETURN;
93.239 + }
93.240 + (*env)->GetStringRegion(env, fontFamily, 0, nameLen, name);
93.241 + name[nameLen] = '\0';
93.242 +
93.243 + if (nameLen < (sizeof(lf.lfFaceName) / sizeof(lf.lfFaceName[0]))) {
93.244 + wcscpy(lf.lfFaceName, name);
93.245 + } else {
93.246 + FREE_AND_RETURN;
93.247 + }
93.248 +
93.249 + hFont = CreateFontIndirectW(&lf);
93.250 + if (hFont == NULL) {
93.251 + FREE_AND_RETURN;
93.252 + }
93.253 + oldFont = SelectObject(hMemoryDC, hFont);
93.254 +
93.255 + memset(&textMetric, 0, sizeof(TEXTMETRIC));
93.256 + err = GetTextMetrics(hMemoryDC, &textMetric);
93.257 + if (err == 0) {
93.258 + FREE_AND_RETURN;
93.259 + }
93.260 + memset(&glyphMetrics, 0, sizeof(GLYPHMETRICS));
93.261 + memset(&mat2, 0, sizeof(MAT2));
93.262 + mat2.eM11.value = 1; mat2.eM22.value = 1;
93.263 + err = GetGlyphOutline(hMemoryDC, glyphCode,
93.264 + GGO_METRICS|GGO_GLYPH_INDEX,
93.265 + &glyphMetrics,
93.266 + 0, NULL, &mat2);
93.267 + if (err == GDI_ERROR) {
93.268 + /* Probably no such glyph - ie the font wasn't the one we expected. */
93.269 + FREE_AND_RETURN;
93.270 + }
93.271 +
93.272 + width = (unsigned short)glyphMetrics.gmBlackBoxX;
93.273 + height = (unsigned short)glyphMetrics.gmBlackBoxY;
93.274 +
93.275 + /* Don't handle "invisible" glyphs in this code */
93.276 + if (width <= 0 || height == 0) {
93.277 + FREE_AND_RETURN;
93.278 + }
93.279 +
93.280 + advanceX = glyphMetrics.gmCellIncX;
93.281 + advanceY = glyphMetrics.gmCellIncY;
93.282 + topLeftX = glyphMetrics.gmptGlyphOrigin.x;
93.283 + topLeftY = glyphMetrics.gmptGlyphOrigin.y;
93.284 +
93.285 + /* GetGlyphOutline pre-dates cleartype and I'm not sure that it will
93.286 + * account for all pixels touched by the rendering. Need to widen,
93.287 + * and also adjust by one the x position at which it is rendered.
93.288 + * The extra pixels of width are used as follows :
93.289 + * One extra pixel at the left and the right will be needed to absorb
93.290 + * the pixels that will be touched by filtering by GDI to compensate
93.291 + * for colour fringing.
93.292 + * However there seem to be some cases where GDI renders two extra
93.293 + * pixels to the right, so we add one additional pixel to the right,
93.294 + * and in the code that copies this to the image cache we test for
93.295 + * the (rare) cases when this is touched, and if its not reduce the
93.296 + * stated image width for the blitting loops.
93.297 + * For fractional metrics :
93.298 + * One extra pixel at each end to account for sub-pixel positioning used
93.299 + * when fractional metrics is on in LCD mode.
93.300 + * The pixel at the left is needed so the blitting loop can index into
93.301 + * that a byte at a time to more accurately position the glyph.
93.302 + * The pixel at the right is needed so that when such indexing happens,
93.303 + * the blitting still can use the same width.
93.304 + * Consequently the width that is specified for the glyph is one less
93.305 + * than that of the actual image.
93.306 + * Note that in the FM case as a consequence we need to adjust the
93.307 + * position at which GDI renders, and the declared width of the glyph
93.308 + * See the if (fm) {} cases in the code.
93.309 + * For the non-FM case, we not only save 3 bytes per row, but this
93.310 + * prevents apparent glyph overlapping which affects the rendering
93.311 + * performance of accelerated pipelines since it adds additional
93.312 + * read-back requirements.
93.313 + */
93.314 + width+=3;
93.315 + if (fm) {
93.316 + width+=1;
93.317 + }
93.318 + /* DIB scanline must end on a DWORD boundary. We specify 3 bytes per pixel,
93.319 + * so must round up as needed to a multiple of 4 bytes.
93.320 + */
93.321 + dibBytesWidth = bytesWidth = width*3;
93.322 + extra = dibBytesWidth % 4;
93.323 + if (extra != 0) {
93.324 + dibBytesWidth += (4-extra);
93.325 + }
93.326 + /* The glyph cache image must be a multiple of 3 bytes wide. */
93.327 + extra = bytesWidth % 3;
93.328 + if (extra != 0) {
93.329 + bytesWidth += (3-extra);
93.330 + }
93.331 + bmWidth = width;
93.332 + bmHeight = height;
93.333 +
93.334 + /* Must use desktop DC to create a bitmap of that depth */
93.335 + hBitmap = CreateCompatibleBitmap(hDesktopDC, bmWidth, bmHeight);
93.336 + if (hBitmap == NULL) {
93.337 + FREE_AND_RETURN;
93.338 + }
93.339 + hOrigBM = (HBITMAP)SelectObject(hMemoryDC, hBitmap);
93.340 +
93.341 + /* Fill in black */
93.342 + rect.left = 0;
93.343 + rect.top = 0;
93.344 + rect.right = bmWidth;
93.345 + rect.bottom = bmHeight;
93.346 + FillRect(hMemoryDC, (LPRECT)&rect, GetStockObject(BLACK_BRUSH));
93.347 +
93.348 + /* Set text color to white, background to black. */
93.349 + SetBkColor(hMemoryDC, RGB(0,0,0));
93.350 + SetTextColor(hMemoryDC, RGB(255,255,255));
93.351 +
93.352 + /* adjust rendering position */
93.353 + x = -topLeftX+1;
93.354 + if (fm) {
93.355 + x += 1;
93.356 + }
93.357 + y = topLeftY - textMetric.tmAscent;
93.358 + err = ExtTextOutW(hMemoryDC, x, y, ETO_GLYPH_INDEX|ETO_OPAQUE,
93.359 + (LPRECT)&rect, (LPCWSTR)&glyphCode, 1, NULL);
93.360 + if (err == 0) {
93.361 + FREE_AND_RETURN;
93.362 + }
93.363 +
93.364 + /* Now get the image into a DIB.
93.365 + * MS docs for GetDIBits says the compatible bitmap must not be
93.366 + * selected into a DC, so restore the original first.
93.367 + */
93.368 + SelectObject(hMemoryDC, hOrigBM);
93.369 + SelectObject(hMemoryDC, oldFont);
93.370 + DeleteObject(hFont);
93.371 +
93.372 + memset(&bmi, 0, sizeof(BITMAPINFO));
93.373 + bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
93.374 + bmi.bmiHeader.biWidth = width;
93.375 + bmi.bmiHeader.biHeight = -height;
93.376 + bmi.bmiHeader.biPlanes = 1;
93.377 + bmi.bmiHeader.biBitCount = 24;
93.378 + bmi.bmiHeader.biCompression = BI_RGB;
93.379 +
93.380 + dibImageSize = dibBytesWidth*height;
93.381 + dibImage = malloc(dibImageSize);
93.382 + if (dibImage == NULL) {
93.383 + FREE_AND_RETURN;
93.384 + }
93.385 + memset(dibImage, 0, dibImageSize);
93.386 +
93.387 + err = GetDIBits(hMemoryDC, hBitmap, 0, height, dibImage,
93.388 + &bmi, DIB_RGB_COLORS);
93.389 +
93.390 + if (err == 0) { /* GetDIBits failed. */
93.391 + FREE_AND_RETURN;
93.392 + }
93.393 +
93.394 + err = SystemParametersInfo(SPI_GETFONTSMOOTHINGORIENTATION, 0, &orient, 0);
93.395 + if (err == 0) {
93.396 + FREE_AND_RETURN;
93.397 + }
93.398 + err = SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &gamma, 0);
93.399 + if (err == 0) {
93.400 + FREE_AND_RETURN;
93.401 + }
93.402 + igTable = getIGTable(gamma/10);
93.403 + if (igTable == NULL) {
93.404 + FREE_AND_RETURN;
93.405 + }
93.406 +
93.407 + /* Now copy glyph image into a GlyphInfo structure and return it.
93.408 + * NB the xadvance calculated here may be overwritten by the caller.
93.409 + * 1 is subtracted from the bitmap width to get the glyph width, since
93.410 + * that extra "1" was added as padding, so the sub-pixel positioning of
93.411 + * fractional metrics could index into it.
93.412 + */
93.413 + imageSize = bytesWidth*height;
93.414 + glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
93.415 + if (malloc == NULL) {
93.416 + FREE_AND_RETURN;
93.417 + }
93.418 + glyphInfo->cellInfo = NULL;
93.419 + glyphInfo->rowBytes = bytesWidth;
93.420 + glyphInfo->width = width;
93.421 + if (fm) {
93.422 + glyphInfo->width -= 1; // must subtract 1
93.423 + }
93.424 + glyphInfo->height = height;
93.425 + glyphInfo->advanceX = advanceX;
93.426 + glyphInfo->advanceY = advanceY;
93.427 + glyphInfo->topLeftX = (float)(topLeftX-1);
93.428 + if (fm) {
93.429 + glyphInfo->topLeftX -= 1;
93.430 + }
93.431 + glyphInfo->topLeftY = (float)-topLeftY;
93.432 + glyphInfo->image = (unsigned char*)glyphInfo+sizeof(GlyphInfo);
93.433 + memset(glyphInfo->image, 0, imageSize);
93.434 +
93.435 + /* DIB 24bpp data is always stored in BGR order, but we usually
93.436 + * need this in RGB, so we can't just memcpy and need to swap B and R.
93.437 + * Also need to apply inverse gamma adjustment here.
93.438 + * We re-use the variable "extra" to see if the last pixel is touched
93.439 + * at all. If its not we can reduce the glyph image width. This comes
93.440 + * into play in some cases where GDI touches more pixels than accounted
93.441 + * for by increasing width by two pixels over the B&W image. Whilst
93.442 + * the bytes are in the cache, it doesn't affect rendering performance
93.443 + * of the hardware pipelines.
93.444 + */
93.445 + extra = 0;
93.446 + if (fm) {
93.447 + extra = 1; // always need it.
93.448 + }
93.449 + dibRowPtr = dibImage;
93.450 + rowPtr = glyphInfo->image;
93.451 + for (y=0;y<height;y++) {
93.452 + pixelPtr = rowPtr;
93.453 + dibPixPtr = dibRowPtr;
93.454 + for (x=0;x<width;x++) {
93.455 + if (orient == FE_FONTSMOOTHINGORIENTATIONRGB) {
93.456 + b = *dibPixPtr++;
93.457 + g = *dibPixPtr++;
93.458 + r = *dibPixPtr++;
93.459 + } else {
93.460 + r = *dibPixPtr++;
93.461 + g = *dibPixPtr++;
93.462 + b = *dibPixPtr++;
93.463 + }
93.464 + *pixelPtr++ = igTable[r];
93.465 + *pixelPtr++ = igTable[g];
93.466 + *pixelPtr++ = igTable[b];
93.467 + if (!fm && (x==(width-1)) && (r|g|b)) {
93.468 + extra = 1;
93.469 + }
93.470 + }
93.471 + dibRowPtr += dibBytesWidth;
93.472 + rowPtr += bytesWidth;
93.473 + }
93.474 + if (!extra) {
93.475 + glyphInfo->width -= 1;
93.476 + }
93.477 +
93.478 + free(dibImage);
93.479 + ReleaseDC(hWnd, hDesktopDC);
93.480 + DeleteObject(hMemoryDC);
93.481 + DeleteObject(hBitmap);
93.482 +
93.483 + return ptr_to_jlong(glyphInfo);
93.484 +}
94.1 --- a/src/windows/native/sun/windows/awt_Component.cpp Tue Jun 10 16:31:26 2008 -0700
94.2 +++ b/src/windows/native/sun/windows/awt_Component.cpp Thu Jun 12 11:46:57 2008 -0700
94.3 @@ -3464,6 +3464,21 @@
94.4 return java_awt_event_KeyEvent_VK_UNDEFINED;
94.5 }
94.6
94.7 +BOOL AwtComponent::IsNavigationKey(UINT wkey) {
94.8 + switch (wkey) {
94.9 + case VK_END:
94.10 + case VK_PRIOR: // PageUp
94.11 + case VK_NEXT: // PageDown
94.12 + case VK_HOME:
94.13 + case VK_LEFT:
94.14 + case VK_UP:
94.15 + case VK_RIGHT:
94.16 + case VK_DOWN:
94.17 + return TRUE;
94.18 + }
94.19 + return FALSE;
94.20 +}
94.21 +
94.22 // determine if a key is a numpad key (distinguishes the numpad
94.23 // arrow keys from the non-numpad arrow keys, for example).
94.24 BOOL AwtComponent::IsNumPadKey(UINT vkey, BOOL extended)
94.25 @@ -3563,7 +3578,10 @@
94.26 // fix for 4623376,4737679,4501485,4740906,4708221 (4173679/4122715)
94.27 // Here we try to resolve a conflict with ::ToAsciiEx's translating
94.28 // ALT+number key combinations. kdm@sarc.spb.su
94.29 - keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
94.30 + // yan: Do it for navigation keys only, otherwise some AltGr deadkeys fail.
94.31 + if( IsNavigationKey(wkey) ) {
94.32 + keyboardState[VK_MENU] &= ~KEY_STATE_DOWN;
94.33 + }
94.34
94.35 if (ctrlIsDown)
94.36 {
95.1 --- a/src/windows/native/sun/windows/awt_Component.h Tue Jun 10 16:31:26 2008 -0700
95.2 +++ b/src/windows/native/sun/windows/awt_Component.h Thu Jun 12 11:46:57 2008 -0700
95.3 @@ -823,6 +823,7 @@
95.4 private:
95.5 AwtComponent* SearchChild(UINT id);
95.6 void RemoveChild(UINT id) ;
95.7 + static BOOL IsNavigationKey(UINT wkey);
95.8
95.9 ChildListItem* m_childList;
95.10
96.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
96.2 +++ b/test/java/awt/Graphics2D/DrawString/AlphaSurfaceText.java Thu Jun 12 11:46:57 2008 -0700
96.3 @@ -0,0 +1,106 @@
96.4 +/*
96.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
96.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
96.7 + *
96.8 + * This code is free software; you can redistribute it and/or modify it
96.9 + * under the terms of the GNU General Public License version 2 only, as
96.10 + * published by the Free Software Foundation.
96.11 + *
96.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
96.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
96.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
96.15 + * version 2 for more details (a copy is included in the LICENSE file that
96.16 + * accompanied this code).
96.17 + *
96.18 + * You should have received a copy of the GNU General Public License version
96.19 + * 2 along with this work; if not, write to the Free Software Foundation,
96.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
96.21 + *
96.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
96.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
96.24 + * have any questions.
96.25 + */
96.26 +
96.27 +/**
96.28 + * @test
96.29 + * @bug 6679308
96.30 + * @summary test drawing to Alpha surfaces
96.31 + */
96.32 +
96.33 +import java.awt.*;
96.34 +import java.awt.image.*;
96.35 +
96.36 +public class AlphaSurfaceText {
96.37 +
96.38 + int wid=400, hgt=200;
96.39 +
96.40 + public AlphaSurfaceText(int biType, Color c) {
96.41 + BufferedImage opaquebi0 =
96.42 + new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
96.43 + drawText(opaquebi0, c);
96.44 +
96.45 + BufferedImage alphabi = new BufferedImage(wid, hgt, biType);
96.46 + drawText(alphabi, c);
96.47 + BufferedImage opaquebi1 =
96.48 + new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
96.49 + Graphics2D g2d = opaquebi1.createGraphics();
96.50 + g2d.drawImage(alphabi, 0, 0, null);
96.51 + compare(opaquebi0, opaquebi1, biType, c);
96.52 + }
96.53 +
96.54 + private void drawText(BufferedImage bi, Color c) {
96.55 + Graphics2D g = bi.createGraphics();
96.56 + g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
96.57 + RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
96.58 + g.setColor(c);
96.59 + g.setFont(new Font("sansserif", Font.PLAIN, 70));
96.60 + g.drawString("Hello!", 20, 100);
96.61 + g.setFont(new Font("sansserif", Font.PLAIN, 12));
96.62 + g.drawString("Hello!", 20, 130);
96.63 + g.setFont(new Font("sansserif", Font.PLAIN, 10));
96.64 + g.drawString("Hello!", 20, 150);
96.65 + }
96.66 +
96.67 + // Need to allow for minimal rounding error, so allow each component
96.68 + // to differ by 1.
96.69 + void compare(BufferedImage bi0, BufferedImage bi1, int biType, Color c) {
96.70 + for (int x=0; x<wid; x++) {
96.71 + for (int y=0; y<hgt; y++) {
96.72 + int rgb0 = bi0.getRGB(x, y);
96.73 + int rgb1 = bi1.getRGB(x, y);
96.74 + if (rgb0 == rgb1) continue;
96.75 + int r0 = (rgb0 & 0xff0000) >> 16;
96.76 + int r1 = (rgb1 & 0xff0000) >> 16;
96.77 + int rdiff = r0-r1; if (rdiff<0) rdiff = -rdiff;
96.78 + int g0 = (rgb0 & 0x00ff00) >> 8;
96.79 + int g1 = (rgb1 & 0x00ff00) >> 8;
96.80 + int gdiff = g0-g1; if (gdiff<0) gdiff = -gdiff;
96.81 + int b0 = (rgb0 & 0x0000ff);
96.82 + int b1 = (rgb1 & 0x0000ff);
96.83 + int bdiff = b0-b1; if (bdiff<0) bdiff = -bdiff;
96.84 + if (rdiff > 1 || gdiff > 1 || bdiff > 1) {
96.85 + throw new RuntimeException(
96.86 + "Images differ for type "+biType + " col="+c +
96.87 + " at x=" + x + " y="+ y + " " +
96.88 + Integer.toHexString(rgb0) + " vs " +
96.89 + Integer.toHexString(rgb1));
96.90 + }
96.91 + }
96.92 + }
96.93 +
96.94 + }
96.95 + public static void main(String[] args) {
96.96 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.white);
96.97 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.red);
96.98 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB, Color.blue);
96.99 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.white);
96.100 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.red);
96.101 + new AlphaSurfaceText(BufferedImage.TYPE_INT_ARGB_PRE, Color.blue);
96.102 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.white);
96.103 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.red);
96.104 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR, Color.blue);
96.105 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.white);
96.106 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.red);
96.107 + new AlphaSurfaceText(BufferedImage.TYPE_4BYTE_ABGR_PRE, Color.blue);
96.108 + }
96.109 +}
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
97.2 +++ b/test/java/awt/Graphics2D/DrawString/DrawStrSuper.java Thu Jun 12 11:46:57 2008 -0700
97.3 @@ -0,0 +1,151 @@
97.4 +/*
97.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
97.7 + *
97.8 + * This code is free software; you can redistribute it and/or modify it
97.9 + * under the terms of the GNU General Public License version 2 only, as
97.10 + * published by the Free Software Foundation.
97.11 + *
97.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
97.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
97.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
97.15 + * version 2 for more details (a copy is included in the LICENSE file that
97.16 + * accompanied this code).
97.17 + *
97.18 + * You should have received a copy of the GNU General Public License version
97.19 + * 2 along with this work; if not, write to the Free Software Foundation,
97.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
97.21 + *
97.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
97.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
97.24 + * have any questions.
97.25 + */
97.26 +
97.27 +/**
97.28 + * @test
97.29 + * @bug 6684056
97.30 + * @summary Super-scripted text needs to be positioned the same with
97.31 + * drawString and TextLayout.
97.32 + */
97.33 +import java.awt.*;
97.34 +import java.awt.event.*;
97.35 +import java.awt.font.*;
97.36 +import static java.awt.font.TextAttribute.*;
97.37 +import java.awt.geom.AffineTransform;
97.38 +import java.awt.image.BufferedImage;
97.39 +import java.util.HashMap;
97.40 +
97.41 +
97.42 +public class DrawStrSuper extends Component {
97.43 +
97.44 + int angle = 0;
97.45 + static boolean interactive = false;
97.46 +
97.47 + int wid=400, hgt=400;
97.48 + BufferedImage bi = null;
97.49 +
97.50 + void paintImage() {
97.51 +
97.52 + if (bi == null) {
97.53 + bi = new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
97.54 + }
97.55 + Graphics2D g2d = bi.createGraphics();
97.56 + g2d.setColor(Color.white);
97.57 + g2d.fillRect(0, 0, wid, hgt);
97.58 + g2d.translate(200, 200);
97.59 +
97.60 + Font fnt = new Font("Arial", Font.PLAIN, 20);
97.61 + fnt = fnt.deriveFont(60.0f);
97.62 + HashMap attrMap = new HashMap();
97.63 + AffineTransform aff =
97.64 + AffineTransform.getRotateInstance(angle * Math.PI/180.0);
97.65 + attrMap.put(SUPERSCRIPT, SUPERSCRIPT_SUPER);
97.66 + attrMap.put(TRANSFORM, aff);
97.67 + fnt = fnt.deriveFont(attrMap);
97.68 +
97.69 + g2d.setFont(fnt);
97.70 + g2d.setColor(Color.yellow);
97.71 + TextLayout tl = new TextLayout("Text", fnt,g2d.getFontRenderContext());
97.72 + g2d.fill(tl.getBounds());
97.73 +
97.74 + g2d.setColor(Color.black);
97.75 + g2d.drawLine(-3, 0, 3, 0);
97.76 + g2d.drawLine(0, -3, 0, 3);
97.77 +
97.78 + g2d.setColor(Color.blue);
97.79 + g2d.drawString("Text", 0, 0);
97.80 +
97.81 + g2d.setColor(Color.red);
97.82 + tl.draw(g2d,0f,0f);
97.83 +
97.84 + // Test BI: should be no blue
97.85 + int blue = Color.blue.getRGB();
97.86 + for (int px=0;px<wid;px++) {
97.87 + for (int py=0;py<hgt;py++) {
97.88 + int rgb = bi.getRGB(px, py);
97.89 + if (rgb == blue) {
97.90 + throw new RuntimeException
97.91 + ("Unexpected color : " + Integer.toHexString(rgb) +
97.92 + " at x=" + px + " y="+ py);
97.93 + }
97.94 + }
97.95 + }
97.96 + }
97.97 +
97.98 + @Override
97.99 + public void paint(Graphics g) {
97.100 + paintImage();
97.101 + g.drawImage(bi, 0,0, null);
97.102 + }
97.103 +
97.104 +
97.105 + static class Runner extends Thread {
97.106 +
97.107 + DrawStrSuper dss;
97.108 +
97.109 + Runner(DrawStrSuper dss) {
97.110 + this.dss = dss;
97.111 + }
97.112 +
97.113 + public void run() {
97.114 + while (true) {
97.115 + if (!interactive && dss.angle > 360) {
97.116 + return;
97.117 + }
97.118 + try {
97.119 + Thread.sleep(100);
97.120 + } catch (InterruptedException e) {
97.121 + return;
97.122 + }
97.123 +
97.124 + dss.angle += 10;
97.125 + dss.repaint();
97.126 + }
97.127 + }
97.128 + }
97.129 +
97.130 + @Override
97.131 + public Dimension getPreferredSize() {
97.132 + return new Dimension(400, 400);
97.133 + }
97.134 +
97.135 + public static void main(String argv[]) throws InterruptedException {
97.136 + if (argv.length > 0) interactive = true;
97.137 +
97.138 + Frame f = new Frame("Text bounds test");
97.139 + f.addWindowListener(new WindowAdapter() {
97.140 + @Override
97.141 + public void windowClosing(WindowEvent e) {
97.142 + System.exit(0);
97.143 + }
97.144 + });
97.145 + DrawStrSuper dss = new DrawStrSuper();
97.146 + f.add(dss, BorderLayout.CENTER);
97.147 + f.pack();
97.148 + f.setLocationRelativeTo(null);
97.149 + f.setVisible(true);
97.150 + Runner runner = new Runner(dss);
97.151 + runner.start();
97.152 + runner.join();
97.153 + }
97.154 +}
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
98.2 +++ b/test/java/awt/Graphics2D/DrawString/EmptyAttrString.java Thu Jun 12 11:46:57 2008 -0700
98.3 @@ -0,0 +1,58 @@
98.4 +/*
98.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
98.7 + *
98.8 + * This code is free software; you can redistribute it and/or modify it
98.9 + * under the terms of the GNU General Public License version 2 only, as
98.10 + * published by the Free Software Foundation.
98.11 + *
98.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
98.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
98.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
98.15 + * version 2 for more details (a copy is included in the LICENSE file that
98.16 + * accompanied this code).
98.17 + *
98.18 + * You should have received a copy of the GNU General Public License version
98.19 + * 2 along with this work; if not, write to the Free Software Foundation,
98.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
98.21 + *
98.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
98.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
98.24 + * have any questions.
98.25 + */
98.26 +
98.27 +/**
98.28 + * @test
98.29 + * @bug 6699843
98.30 + * @summary IllegalArgumentException when using Graphics.drawString( "", 0, 0 )
98.31 + */
98.32 +
98.33 +import java.awt.*;
98.34 +import java.awt.font.*;
98.35 +import java.awt.image.*;
98.36 +import java.text.*;
98.37 +import java.util.*;
98.38 +
98.39 +public class EmptyAttrString {
98.40 +
98.41 + public static void main(String[] args) {
98.42 + BufferedImage bi =
98.43 + new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
98.44 + Graphics2D g = bi.createGraphics();
98.45 + Font f = new Font( "Dialog", Font.PLAIN, 12 );
98.46 + Map map = new HashMap();
98.47 + map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
98.48 + f = f.deriveFont(map);
98.49 + g.setFont(f);
98.50 + g.drawString("", 50, 50);
98.51 + g.drawString("", 50f, 50f);
98.52 + char[] chs = { } ;
98.53 + g.drawChars(chs, 0, 0, 50, 50);
98.54 + byte[] bytes = { } ;
98.55 + g.drawBytes(bytes, 0, 0, 50, 50);
98.56 + AttributedString astr = new AttributedString("");
98.57 + g.drawString(astr.getIterator(), 50, 50);
98.58 + g.drawString(astr.getIterator(), 50f, 50f);
98.59 + return;
98.60 + }
98.61 +}
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/test/java/awt/Graphics2D/DrawString/RotTransText.java Thu Jun 12 11:46:57 2008 -0700
99.3 @@ -0,0 +1,108 @@
99.4 +/*
99.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
99.7 + *
99.8 + * This code is free software; you can redistribute it and/or modify it
99.9 + * under the terms of the GNU General Public License version 2 only, as
99.10 + * published by the Free Software Foundation.
99.11 + *
99.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
99.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
99.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
99.15 + * version 2 for more details (a copy is included in the LICENSE file that
99.16 + * accompanied this code).
99.17 + *
99.18 + * You should have received a copy of the GNU General Public License version
99.19 + * 2 along with this work; if not, write to the Free Software Foundation,
99.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
99.21 + *
99.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
99.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
99.24 + * have any questions.
99.25 + */
99.26 +
99.27 +/**
99.28 + * @test
99.29 + * @bug 6683472 6687298
99.30 + * @summary Transformed fonts using drawString and TextLayout should be in
99.31 + * the same position.
99.32 + */
99.33 +
99.34 +import java.awt.*;
99.35 +import java.awt.font.*;
99.36 +import java.awt.geom.*;
99.37 +import java.awt.image.*;
99.38 +import java.util.HashMap;
99.39 +
99.40 +public class RotTransText {
99.41 +
99.42 + public static void main(String[] args) {
99.43 +
99.44 + testIt(false);
99.45 + testIt(true);
99.46 +
99.47 + }
99.48 +
99.49 + public static void testIt(boolean fmOn) {
99.50 +
99.51 + int wid=400, hgt=400;
99.52 + BufferedImage bi =
99.53 + new BufferedImage(wid, hgt, BufferedImage.TYPE_INT_RGB);
99.54 +
99.55 + Graphics2D g2d = bi.createGraphics();
99.56 +
99.57 + if (fmOn) {
99.58 + g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
99.59 + RenderingHints.VALUE_FRACTIONALMETRICS_ON);
99.60 + }
99.61 +
99.62 + int x=130, y=130;
99.63 + String s = "Text";
99.64 +
99.65 + int xt=90, yt=50;
99.66 + for (int angle=0;angle<360;angle+=30) {
99.67 +
99.68 + g2d.setColor(Color.white);
99.69 + g2d.fillRect(0, 0, wid, hgt);
99.70 +
99.71 + AffineTransform aff = AffineTransform.getTranslateInstance(50,90);
99.72 + aff.rotate(angle * Math.PI/180.0);
99.73 +
99.74 + Font fnt = new Font("SansSerif", Font.PLAIN, 60);
99.75 + fnt = fnt.deriveFont(Font.PLAIN, aff);
99.76 + g2d.setFont(fnt);
99.77 + g2d.setColor(Color.blue);
99.78 + g2d.drawString(s, x, y);
99.79 +
99.80 + g2d.setColor(Color.red);
99.81 + FontRenderContext frc = g2d.getFontRenderContext();
99.82 + HashMap attrMap = new HashMap();
99.83 + attrMap.put(TextAttribute.STRIKETHROUGH,
99.84 + TextAttribute.STRIKETHROUGH_ON);
99.85 + fnt = fnt.deriveFont(attrMap);
99.86 + TextLayout tl = new TextLayout(s, fnt, frc);
99.87 + tl.draw(g2d, (float)x, (float)y);
99.88 +
99.89 + // Test BI: should be minimal blue relative to red.
99.90 + int redCount = 0;
99.91 + int blueCount = 0;
99.92 + int red = Color.red.getRGB();
99.93 + int blue = Color.blue.getRGB();
99.94 + for (int px=0;px<wid;px++) {
99.95 + for (int py=0;py<hgt;py++) {
99.96 + int rgb = bi.getRGB(px, py);
99.97 + if (rgb == red) {
99.98 + redCount++;
99.99 + } else if (rgb == blue) {
99.100 + blueCount++;
99.101 + }
99.102 + }
99.103 + }
99.104 + if (redCount == 0 || (blueCount/(double)redCount) > 0.1) {
99.105 + throw new
99.106 + RuntimeException("Ratio of blue to red is too great: " +
99.107 + (blueCount/(double)redCount));
99.108 + }
99.109 + }
99.110 + }
99.111 +}
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/test/java/awt/Graphics2D/DrawString/ScaledLCDTextMetrics.java Thu Jun 12 11:46:57 2008 -0700
100.3 @@ -0,0 +1,82 @@
100.4 +/*
100.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
100.7 + *
100.8 + * This code is free software; you can redistribute it and/or modify it
100.9 + * under the terms of the GNU General Public License version 2 only, as
100.10 + * published by the Free Software Foundation.
100.11 + *
100.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
100.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
100.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
100.15 + * version 2 for more details (a copy is included in the LICENSE file that
100.16 + * accompanied this code).
100.17 + *
100.18 + * You should have received a copy of the GNU General Public License version
100.19 + * 2 along with this work; if not, write to the Free Software Foundation,
100.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
100.21 + *
100.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
100.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
100.24 + * have any questions.
100.25 + */
100.26 +
100.27 +/**
100.28 + * @test
100.29 + * @bug 6685312
100.30 + * @summary Check advance of LCD text on a scaled graphics.
100.31 + */
100.32 +
100.33 +import javax.swing.*;
100.34 +import java.awt.*;
100.35 +import static java.awt.RenderingHints.*;
100.36 +
100.37 +public class ScaledLCDTextMetrics extends Component {
100.38 +
100.39 + public static void main(String[] args) {
100.40 + JFrame f = new JFrame();
100.41 + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
100.42 + f.add("Center", new ScaledLCDTextMetrics());
100.43 + f.pack();
100.44 + f.setVisible(true);
100.45 + }
100.46 +
100.47 + public Dimension getPreferredSize() {
100.48 + return new Dimension(200,100);
100.49 + }
100.50 + public void paint(Graphics g) {
100.51 + Graphics2D g2 = (Graphics2D)g;
100.52 +
100.53 + Font f = new Font("Tahoma", Font.PLAIN, 11);
100.54 + g.setFont(f);
100.55 + g.setColor(Color.white);
100.56 + g.fillRect(0,0,400,300);
100.57 + g.setColor(Color.black);
100.58 + g2.setRenderingHint(KEY_TEXT_ANTIALIASING,VALUE_TEXT_ANTIALIAS_LCD_HRGB);
100.59 + String text = "ABCDEFGHIJKLI";
100.60 +
100.61 + FontMetrics fm1 = g2.getFontMetrics();
100.62 + int adv1 = fm1.stringWidth(text);
100.63 + g.drawString(text, 5, 20);
100.64 +
100.65 + g2.scale(2,2);
100.66 +
100.67 + FontMetrics fm2 = g2.getFontMetrics();
100.68 + int adv2 = fm2.stringWidth(text);
100.69 + g.drawString(text, 5, 40);
100.70 +
100.71 + double frac = Math.abs(adv1/(double)adv2);
100.72 +
100.73 + System.out.println("scalex1: " + adv1);
100.74 + System.out.println("scalex2: " + adv2);
100.75 + System.out.println("Fraction : "+ frac);
100.76 +
100.77 + // adv1 will not be exactly the same as adv2, but should differ
100.78 + // only by a fraction.
100.79 +
100.80 + if (frac < 0.8 || frac > 1.2) {
100.81 + throw new RuntimeException("Metrics differ " +
100.82 + "Adv1="+adv1+" Adv2="+adv2+" Fraction="+frac);
100.83 + }
100.84 + }
100.85 +}
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
101.2 +++ b/test/java/awt/font/Rotate/Shear.java Thu Jun 12 11:46:57 2008 -0700
101.3 @@ -0,0 +1,66 @@
101.4 +/*
101.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
101.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
101.7 + *
101.8 + * This code is free software; you can redistribute it and/or modify it
101.9 + * under the terms of the GNU General Public License version 2 only, as
101.10 + * published by the Free Software Foundation.
101.11 + *
101.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
101.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
101.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
101.15 + * version 2 for more details (a copy is included in the LICENSE file that
101.16 + * accompanied this code).
101.17 + *
101.18 + * You should have received a copy of the GNU General Public License version
101.19 + * 2 along with this work; if not, write to the Free Software Foundation,
101.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
101.21 + *
101.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
101.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
101.24 + * have any questions.
101.25 + */
101.26 +
101.27 +/*
101.28 + * @test
101.29 + * @bug 6692979
101.30 + * @summary Verify no crashes with extreme shears.
101.31 + */
101.32 +
101.33 +import javax.swing.*;
101.34 +import java.awt.*;
101.35 +import java.awt.font.*;
101.36 +import java.awt.geom.*;
101.37 +public class Shear extends Component {
101.38 +
101.39 + public static void main(String[] args) {
101.40 + JFrame f = new JFrame();
101.41 + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
101.42 + f.getContentPane().add("Center", new Shear());
101.43 + f.pack();
101.44 + f.setVisible(true);
101.45 + }
101.46 +
101.47 + public Dimension getPreferredSize() {
101.48 + return new Dimension(400,300);
101.49 + }
101.50 +
101.51 + public void paint(Graphics g) {
101.52 + Graphics2D g2 = (Graphics2D)g;
101.53 +
101.54 + g.setColor(Color.white);
101.55 + g.fillRect(0,0,400,300);
101.56 + g.setColor(Color.black);
101.57 + Font origFont = new Font(Font.DIALOG, Font.BOLD, 30);
101.58 + for (int i=0;i<=360;i++) {
101.59 + double sv = i*180.0/Math.PI;
101.60 + AffineTransform tx = AffineTransform.getShearInstance(sv, sv);
101.61 + Font font = origFont.deriveFont(tx);
101.62 + g.setFont(font);
101.63 + GlyphVector gv =
101.64 + font.createGlyphVector(g2.getFontRenderContext(), "JavaFX");
101.65 + //System.out.println(gv.getVisualBounds());
101.66 + g.drawString("JavaFX", 100, 100);
101.67 + }
101.68 + }
101.69 +}
102.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102.2 +++ b/test/java/awt/font/Rotate/TranslatedOutlineTest.java Thu Jun 12 11:46:57 2008 -0700
102.3 @@ -0,0 +1,69 @@
102.4 +/*
102.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
102.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
102.7 + *
102.8 + * This code is free software; you can redistribute it and/or modify it
102.9 + * under the terms of the GNU General Public License version 2 only, as
102.10 + * published by the Free Software Foundation.
102.11 + *
102.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
102.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
102.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
102.15 + * version 2 for more details (a copy is included in the LICENSE file that
102.16 + * accompanied this code).
102.17 + *
102.18 + * You should have received a copy of the GNU General Public License version
102.19 + * 2 along with this work; if not, write to the Free Software Foundation,
102.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
102.21 + *
102.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
102.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
102.24 + * have any questions.
102.25 + */
102.26 +
102.27 +/*
102.28 + * @test TranslatedOutlineTest
102.29 + * @bug 6703377
102.30 + * @summary This test verifies that outline is translated in a correct direction
102.31 + * @run main TranslatedOutlineTest
102.32 + */
102.33 +
102.34 +import java.awt.Color;
102.35 +import java.awt.Graphics2D;
102.36 +import java.awt.RenderingHints;
102.37 +import java.awt.font.FontRenderContext;
102.38 +import java.awt.font.GlyphVector;
102.39 +import java.awt.image.BufferedImage;
102.40 +
102.41 +public class TranslatedOutlineTest {
102.42 + public static void main(String a[]) {
102.43 + /* prepare blank image */
102.44 + BufferedImage bi = new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
102.45 + Graphics2D g2 = (Graphics2D) bi.getGraphics();
102.46 + g2.setColor(Color.WHITE);
102.47 + g2.fillRect(0, 0, 50, 50);
102.48 +
102.49 + /* draw outline somethere in the middle of the image */
102.50 + FontRenderContext frc = new FontRenderContext(null, false, false);
102.51 + g2.setColor(Color.RED);
102.52 + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
102.53 + GlyphVector gv = g2.getFont().createGlyphVector(frc, "test");
102.54 + g2.fill(gv.getOutline(20, 20));
102.55 +
102.56 + /* Check if anything was drawn.
102.57 + * If y direction is not correct then image is still blank and
102.58 + * test will fail.
102.59 + */
102.60 + int bgcolor = Color.WHITE.getRGB();
102.61 + for (int i=0; i<bi.getWidth(); i++) {
102.62 + for(int j=0; j<bi.getHeight(); j++) {
102.63 + if (bi.getRGB(i, j) != bgcolor) {
102.64 + System.out.println("Test passed.");
102.65 + return;
102.66 + }
102.67 + }
102.68 + }
102.69 + throw new RuntimeException("Outline was not detected");
102.70 + }
102.71 +}
102.72 +
103.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
103.2 +++ b/test/java/awt/font/Threads/FontThread.java Thu Jun 12 11:46:57 2008 -0700
103.3 @@ -0,0 +1,89 @@
103.4 +/*
103.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
103.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
103.7 + *
103.8 + * This code is free software; you can redistribute it and/or modify it
103.9 + * under the terms of the GNU General Public License version 2 only, as
103.10 + * published by the Free Software Foundation.
103.11 + *
103.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
103.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
103.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
103.15 + * version 2 for more details (a copy is included in the LICENSE file that
103.16 + * accompanied this code).
103.17 + *
103.18 + * You should have received a copy of the GNU General Public License version
103.19 + * 2 along with this work; if not, write to the Free Software Foundation,
103.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
103.21 + *
103.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
103.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
103.24 + * have any questions.
103.25 + */
103.26 +
103.27 +
103.28 +/* @test
103.29 + * @summary verify thread interruption doesn't affect font file reading.
103.30 + * @bug 6640532
103.31 + */
103.32 +
103.33 +import java.awt.*;
103.34 +
103.35 +public class FontThread extends Thread {
103.36 +
103.37 + String fontName = "Dialog";
103.38 + static FontThread thread1;
103.39 + static FontThread thread2;
103.40 + static FontThread thread3;
103.41 +
103.42 + public static void main(String args[]) throws Exception {
103.43 + thread1 = new FontThread("SansSerif");
103.44 + thread2 = new FontThread("Serif");
103.45 + thread3 = new FontThread("Monospaced");
103.46 + thread1.dometrics(60); // load classes first
103.47 + thread1.start();
103.48 + thread2.start();
103.49 + thread3.start();
103.50 + InterruptThread ithread = new InterruptThread();
103.51 + ithread.setDaemon(true);
103.52 + ithread.start();
103.53 + thread1.join();
103.54 + thread2.join();
103.55 + thread3.join();
103.56 + }
103.57 +
103.58 + FontThread(String font) {
103.59 + super();
103.60 + this.fontName = font;
103.61 + }
103.62 +
103.63 + public void run() {
103.64 + System.out.println("started "+fontName); System.out.flush();
103.65 + dometrics(4000);
103.66 + System.out.println("done "+fontName); System.out.flush();
103.67 + }
103.68 +
103.69 + private void dometrics(int max) {
103.70 + Font f = new Font(fontName, Font.PLAIN, 12);
103.71 + FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(f);
103.72 + for (char i=0;i<max;i++) {
103.73 + if (f.canDisplay(i)) fm.charWidth(i);
103.74 + }
103.75 + }
103.76 +
103.77 + static class InterruptThread extends Thread {
103.78 + public void run() {
103.79 + while (true) {
103.80 + try {
103.81 + Thread.sleep(1);
103.82 + } catch (InterruptedException e) {
103.83 + }
103.84 + thread1.interrupt();
103.85 + thread2.interrupt();
103.86 + thread3.interrupt();
103.87 + }
103.88 + }
103.89 + }
103.90 +}
103.91 +
103.92 +
104.1 --- a/test/javax/management/Introspector/LegacyIntrospectorTest.java Tue Jun 10 16:31:26 2008 -0700
104.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
104.3 @@ -1,75 +0,0 @@
104.4 -/*
104.5 - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
104.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
104.7 - *
104.8 - * This code is free software; you can redistribute it and/or modify it
104.9 - * under the terms of the GNU General Public License version 2 only, as
104.10 - * published by the Free Software Foundation.
104.11 - *
104.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
104.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
104.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
104.15 - * version 2 for more details (a copy is included in the LICENSE file that
104.16 - * accompanied this code).
104.17 - *
104.18 - * You should have received a copy of the GNU General Public License version
104.19 - * 2 along with this work; if not, write to the Free Software Foundation,
104.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
104.21 - *
104.22 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
104.23 - * CA 95054 USA or visit www.sun.com if you need additional information or
104.24 - * have any questions.
104.25 - */
104.26 -
104.27 -/*
104.28 - * @test
104.29 - * @bug 6316460
104.30 - * @summary Test that the legacy com.sun.management.jmx.Introspector
104.31 - * methods work.
104.32 - * @author Eamonn McManus
104.33 - * @run clean LegacyIntrospectorTest
104.34 - * @run build LegacyIntrospectorTest
104.35 - * @run main LegacyIntrospectorTest
104.36 - */
104.37 -
104.38 -import javax.management.*;
104.39 -import com.sun.management.jmx.*;
104.40 -
104.41 -public class LegacyIntrospectorTest {
104.42 - public static interface TestMBean {
104.43 - public int getWhatever();
104.44 - }
104.45 - public static class Test implements TestMBean {
104.46 - public int getWhatever() {return 0;}
104.47 - }
104.48 -
104.49 - @SuppressWarnings("deprecation")
104.50 - public static void main(String[] args) throws Exception {
104.51 - MBeanInfo mbi = Introspector.testCompliance(Test.class);
104.52 - MBeanAttributeInfo mbai = mbi.getAttributes()[0];
104.53 - if (!mbai.getName().equals("Whatever"))
104.54 - throw new Exception("Wrong attribute name: " + mbai.getName());
104.55 - Class c = Introspector.getMBeanInterface(Test.class);
104.56 - if (c != TestMBean.class)
104.57 - throw new Exception("Wrong interface: " + c);
104.58 -
104.59 - MBeanServer mbs1 = new MBeanServerImpl();
104.60 - if (!mbs1.getDefaultDomain().equals("DefaultDomain"))
104.61 - throw new Exception("Wrong default domain: " + mbs1.getDefaultDomain());
104.62 -
104.63 - MBeanServer mbs2 = new MBeanServerImpl("Foo");
104.64 - if (!mbs2.getDefaultDomain().equals("Foo"))
104.65 - throw new Exception("Wrong default domain: " + mbs2.getDefaultDomain());
104.66 -
104.67 - ObjectName delegateName =
104.68 - new ObjectName("JMImplementation:type=MBeanServerDelegate");
104.69 - MBeanInfo delegateInfo = mbs2.getMBeanInfo(delegateName);
104.70 - MBeanInfo refDelegateInfo =
104.71 - MBeanServerFactory.newMBeanServer().getMBeanInfo(delegateName);
104.72 - if (!delegateInfo.equals(refDelegateInfo))
104.73 - throw new Exception("Wrong delegate info from MBeanServerImpl: " +
104.74 - delegateInfo);
104.75 -
104.76 - System.out.println("TEST PASSED");
104.77 - }
104.78 -}
105.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
105.2 +++ b/test/javax/print/PrintSE/PrintSE.java Thu Jun 12 11:46:57 2008 -0700
105.3 @@ -0,0 +1,52 @@
105.4 +/*
105.5 + * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
105.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
105.7 + *
105.8 + * This code is free software; you can redistribute it and/or modify it
105.9 + * under the terms of the GNU General Public License version 2 only, as
105.10 + * published by the Free Software Foundation.
105.11 + *
105.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
105.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
105.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
105.15 + * version 2 for more details (a copy is included in the LICENSE file that
105.16 + * accompanied this code).
105.17 + *
105.18 + * You should have received a copy of the GNU General Public License version
105.19 + * 2 along with this work; if not, write to the Free Software Foundation,
105.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
105.21 + *
105.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
105.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
105.24 + * have any questions.
105.25 + */
105.26 +
105.27 +import java.awt.*;
105.28 +import java.awt.print.*;
105.29 +import javax.print.*;
105.30 +import javax.print.attribute.*;
105.31 +
105.32 +public class PrintSE implements Printable {
105.33 +
105.34 + public static void main(String[] args) throws Exception {
105.35 + GraphicsEnvironment.getLocalGraphicsEnvironment();
105.36 +
105.37 + PrintService service = PrintServiceLookup.lookupDefaultPrintService();
105.38 + if (service == null) {
105.39 + System.out.println("No print service found.");
105.40 + return;
105.41 + }
105.42 + SimpleDoc doc =
105.43 + new SimpleDoc(new PrintSE(),
105.44 + DocFlavor.SERVICE_FORMATTED.PRINTABLE,
105.45 + new HashDocAttributeSet());
105.46 + DocPrintJob job = service.createPrintJob();
105.47 + job.print(doc, new HashPrintRequestAttributeSet());
105.48 + }
105.49 +
105.50 + public int print(Graphics g, PageFormat pf, int pg) {
105.51 + if (pg > 0) return NO_SUCH_PAGE;
105.52 + g.drawString("Test passes.", 100, 100);
105.53 + return PAGE_EXISTS;
105.54 + }
105.55 +}
106.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
106.2 +++ b/test/javax/print/PrintSE/PrintSE.sh Thu Jun 12 11:46:57 2008 -0700
106.3 @@ -0,0 +1,51 @@
106.4 +#!/bin/sh
106.5 +
106.6 +#
106.7 +# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
106.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
106.9 +#
106.10 +# This code is free software; you can redistribute it and/or modify it
106.11 +# under the terms of the GNU General Public License version 2 only, as
106.12 +# published by the Free Software Foundation.
106.13 +#
106.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
106.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
106.16 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
106.17 +# version 2 for more details (a copy is included in the LICENSE file that
106.18 +# accompanied this code).
106.19 +#
106.20 +# You should have received a copy of the GNU General Public License version
106.21 +# 2 along with this work; if not, write to the Free Software Foundation,
106.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
106.23 +#
106.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
106.25 +# CA 95054 USA or visit www.sun.com if you need additional information or
106.26 +# have any questions.
106.27 +#
106.28 +
106.29 +# @test
106.30 +# @bug 6662775
106.31 +# @summary Tests queuePrintJob is sufficient permission.
106.32 +# @run clean PrintSE
106.33 +# @run build PrintSE
106.34 +# @run compile PrintSE.java
106.35 +# @run shell/timeout=300 PrintSE.sh
106.36 +
106.37 +echo -------------------------------------------------------------
106.38 +echo Launching test for `basename $0 .sh`
106.39 +echo -------------------------------------------------------------
106.40 +
106.41 +createJavaPolicyFile()
106.42 +{
106.43 + cat << EOF > ${TESTCLASSES}/print.policy
106.44 +grant {
106.45 + permission java.lang.RuntimePermission "queuePrintJob";
106.46 +};
106.47 +EOF
106.48 +}
106.49 +
106.50 +createJavaPolicyFile
106.51 +
106.52 +${TESTJAVA}/bin/java -Djava.security.manager -Djava.security.policy=${TESTCLASSES}/print.policy -cp ${TESTCLASSES} PrintSE
106.53 +
106.54 +exit $?
107.1 --- a/test/sun/java2d/cmm/ProfileOp/ReadProfileTest.java Tue Jun 10 16:31:26 2008 -0700
107.2 +++ b/test/sun/java2d/cmm/ProfileOp/ReadProfileTest.java Thu Jun 12 11:46:57 2008 -0700
107.3 @@ -23,7 +23,7 @@
107.4
107.5 /**
107.6 * @test
107.7 - * @bug 6476665
107.8 + * @bug 6476665 6523403
107.9 * @summary Verifies reading profiles of the standard color spaces
107.10 * @run main ReadProfileTest
107.11 */
108.1 --- a/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java Tue Jun 10 16:31:26 2008 -0700
108.2 +++ b/test/sun/security/pkcs11/Cipher/TestSymmCiphers.java Thu Jun 12 11:46:57 2008 -0700
108.3 @@ -2,32 +2,22 @@
108.4 * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
108.5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
108.6 *
108.7 - * This code is free software; you can redistribute it and/or modi
108.8 -fy it
108.9 - * under the terms of the GNU General Public License version 2 onl
108.10 -y, as
108.11 + * This code is free software; you can redistribute it and/or modify it
108.12 + * under the terms of the GNU General Public License version 2 only, as
108.13 * published by the Free Software Foundation.
108.14 *
108.15 - * This code is distributed in the hope that it will be useful, bu
108.16 -t WITHOUT
108.17 - * ANY WARRANTY; without even the implied warranty of MERCHANTABIL
108.18 -ITY or
108.19 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public L
108.20 -icense
108.21 - * version 2 for more details (a copy is included in the LICENSE f
108.22 -ile that
108.23 + * This code is distributed in the hope that it will be useful, but WITHOUT
108.24 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
108.25 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
108.26 + * version 2 for more details (a copy is included in the LICENSE file that
108.27 * accompanied this code).
108.28 *
108.29 - * You should have received a copy of the GNU General Public Licen
108.30 -se version
108.31 - * 2 along with this work; if not, write to the Free Software Foun
108.32 -dation,
108.33 + * You should have received a copy of the GNU General Public License version
108.34 + * 2 along with this work; if not, write to the Free Software Foundation,
108.35 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
108.36 *
108.37 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, San
108.38 -ta Clara,
108.39 - * CA 95054 USA or visit www.sun.com if you need additional inform
108.40 -ation or
108.41 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
108.42 + * CA 95054 USA or visit www.sun.com if you need additional information or
108.43 * have any questions.
108.44 */
108.45
109.1 --- a/test/sun/security/tools/keytool/autotest.sh Tue Jun 10 16:31:26 2008 -0700
109.2 +++ b/test/sun/security/tools/keytool/autotest.sh Thu Jun 12 11:46:57 2008 -0700
109.3 @@ -1,5 +1,5 @@
109.4 #
109.5 -# Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
109.6 +# Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
109.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
109.8 #
109.9 # This code is free software; you can redistribute it and/or modify it
109.10 @@ -90,7 +90,8 @@
109.11
109.12 echo | ${TESTJAVA}${FS}bin${FS}java -Dfile -Dnss \
109.13 -Dnss.lib=${NSS}${FS}lib${FS}${PF}${FS}${LIBNAME} \
109.14 - KeyToolTest || exit 12
109.15 + KeyToolTest
109.16 +status=$?
109.17
109.18 rm -f p11-nss.txt
109.19 rm -f cert8.db
109.20 @@ -101,4 +102,5 @@
109.21 rm KeyToolTest.class
109.22 rm TestException.class
109.23
109.24 -exit $?
109.25 +exit $status
109.26 +