Merge jdk7-b29
authorxdono
Thu, 12 Jun 2008 11:46:57 -0700
changeset 337e21f4266466c
parent 336 a0d703b249f0
parent 333 906a396bff74
child 338 0a5b87833562
child 348 3570562846ef
child 367 edf7cd1ec436
Merge
src/solaris/classes/sun/java2d/SurfaceManagerFactory.java
src/windows/classes/sun/java2d/SurfaceManagerFactory.java
test/javax/management/Introspector/LegacyIntrospectorTest.java
     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 +&nbsp;     CIEXYZ
   10.79 +&nbsp;     viewing illuminance: 200 lux
   10.80 +&nbsp;     viewing white point: CIE D50
   10.81 +&nbsp;     media white point: "that of a perfectly reflecting diffuser" -- D50
   10.82 +&nbsp;     media black point: 0 lux or 0 Reflectance
   10.83 +&nbsp;     flare: 1 percent
   10.84 +&nbsp;     surround: 20percent of the media white point
   10.85 +&nbsp;     media description: reflection print (i.e., RLAB, Hunt viewing media)
   10.86 +&nbsp;     note: For developers creating an ICC profile for this conversion
   10.87 +&nbsp;           space, the following is applicable.  Use a simple Von Kries
   10.88 +&nbsp;           white point adaptation folded into the 3X3 matrix parameters
   10.89 +&nbsp;           and fold the flare and surround effects into the three
   10.90 +&nbsp;           one-dimensional lookup tables (assuming one uses the minimal
   10.91 +&nbsp;           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&nbsp;<code>1</code> corresponds to Java&nbsp;2
 12.1862 +     * Platform,&nbsp;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&nbsp;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[]&nbsp;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 +&nbsp;               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 +&nbsp;                         gamma
  13.114 +&nbsp;        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 + * &nbsp;               linearR = redTRC[deviceR]
   14.72 + *
   14.73 + * &nbsp;               linearG = greenTRC[deviceG]
   14.74 + *
   14.75 + * &nbsp;               linearB = blueTRC[deviceB]
   14.76 + *
   14.77 + * &nbsp; _      _       _                                             _   _         _
   14.78 + * &nbsp;[  PCSX  ]     [  redColorantX  greenColorantX  blueColorantX  ] [  linearR  ]
   14.79 + * &nbsp;[        ]     [                                               ] [           ]
   14.80 + * &nbsp;[  PCSY  ]  =  [  redColorantY  greenColorantY  blueColorantY  ] [  linearG  ]
   14.81 + * &nbsp;[        ]     [                                               ] [           ]
   14.82 + * &nbsp;[_ 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 +     * &nbsp;                                         gamma
  14.194 +     * &nbsp;        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,&nbsp;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,&nbsp;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,&nbsp;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,&nbsp;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 +