[kaffe] CVS kaffe (robilad): Resynced with GNU Classpath: awt fixes

Kaffe CVS cvs-commits at kaffe.org
Fri Jun 10 15:24:52 PDT 2005


PatchSet 6616 
Date: 2005/06/10 22:20:28
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
Resynced with GNU Classpath: awt fixes

Members: 
	ChangeLog:1.4142->1.4143 
	libraries/javalib/java/awt/image/BufferedImage.java:INITIAL->1.10 
	libraries/javalib/java/awt/image/DirectColorModel.java:INITIAL->1.14 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4142 kaffe/ChangeLog:1.4143
--- kaffe/ChangeLog:1.4142	Fri Jun 10 19:51:04 2005
+++ kaffe/ChangeLog	Fri Jun 10 22:20:28 2005
@@ -2,6 +2,17 @@
 
 	Resynced with GNU Classpath.
 
+	2005-05-31  Sven de Marothy  <sven at physto.se>
+
+	* java/awt/image/BufferedImage.java:
+	(ImageProducer): Use Vector instead of HashMap.
+	* java/awt/image/DirectColorModel.java:
+	(getAlpha): Default to 255 (opaque).
+	
+2005-06-10  Dalibor Topic  <robilad at kaffe.org>
+
+	Resynced with GNU Classpath.
+
 	2005-05-30  Roman Kennke  <roman at kennke.org>
 
 	* javax/swing/JTree.java
===================================================================
Checking out kaffe/libraries/javalib/java/awt/image/BufferedImage.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/awt/image/BufferedImage.java,v
VERS: 1.10
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/awt/image/BufferedImage.java	Fri Jun 10 22:24:52 2005
@@ -0,0 +1,693 @@
+/* BufferedImage.java --
+   Copyright (C) 2000, 2002, 2003, 2004  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.ComponentDataBlitOp;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Vector;
+
+/**
+ * A buffered image always starts at coordinates (0, 0).
+ *
+ * The buffered image is not subdivided into multiple tiles. Instead,
+ * the image consists of one large tile (0,0) with the width and
+ * height of the image. This tile is always considered to be checked
+ * out.
+ * 
+ * @author Rolf W. Rasmussen (rolfwr at ii.uib.no)
+ */
+public class BufferedImage extends Image
+  implements WritableRenderedImage
+{
+  public static final int TYPE_CUSTOM         =  0,
+                          TYPE_INT_RGB        =  1,
+                          TYPE_INT_ARGB       =  2,
+                          TYPE_INT_ARGB_PRE   =  3,
+                          TYPE_INT_BGR        =  4,
+                          TYPE_3BYTE_BGR      =  5,
+                          TYPE_4BYTE_ABGR     =  6,
+                          TYPE_4BYTE_ABGR_PRE =  7,
+                          TYPE_USHORT_565_RGB =  8,
+                          TYPE_USHORT_555_RGB =  9,
+                          TYPE_BYTE_GRAY      = 10,
+                          TYPE_USHORT_GRAY    = 11,
+                          TYPE_BYTE_BINARY    = 12,
+                          TYPE_BYTE_INDEXED   = 13;
+  
+  static final int[] bits3 = { 8, 8, 8 };
+  static final int[] bits4 = { 8, 8, 8 };
+  static final int[] bits1byte = { 8 };
+  static final int[] bits1ushort = { 16 };
+  
+  static final int[] masks_int = { 0x00ff0000,
+				   0x0000ff00,
+				   0x000000ff,
+				   DataBuffer.TYPE_INT };
+  static final int[] masks_565 = { 0xf800,
+				   0x07e0,
+				   0x001f,
+				   DataBuffer.TYPE_USHORT};
+  static final int[] masks_555 = { 0x7c00,
+				   0x03e0,
+				   0x001f,
+				   DataBuffer.TYPE_USHORT};
+
+  Vector observers;
+  
+  public BufferedImage(int w, int h, int type)
+  {
+    ColorModel cm = null;
+    
+    boolean alpha = false;
+    boolean premultiplied = false;
+    switch (type)
+      {
+      case TYPE_4BYTE_ABGR_PRE:
+      case TYPE_INT_ARGB_PRE:
+	premultiplied = true;
+	// fall through
+      case TYPE_INT_ARGB:
+      case TYPE_4BYTE_ABGR:
+	alpha = true;
+      }
+	
+    ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+    switch (type)
+      {
+      case TYPE_INT_RGB:
+      case TYPE_INT_ARGB:
+      case TYPE_INT_ARGB_PRE:
+      case TYPE_USHORT_565_RGB:
+      case TYPE_USHORT_555_RGB:
+	int[] masks = null;
+	switch (type)
+	  {
+	  case TYPE_INT_RGB:
+	  case TYPE_INT_ARGB:
+	  case TYPE_INT_ARGB_PRE:
+	    masks = masks_int;
+	    break;
+	  case TYPE_USHORT_565_RGB:
+	    masks = masks_565;
+	    break;
+	  case TYPE_USHORT_555_RGB:
+	    masks = masks_555;
+	    break;
+	  }
+	
+	cm = new DirectColorModel(cs,
+				  32, // 32 bits in an int
+				  masks[0], // r
+				  masks[1], // g
+				  masks[2], // b
+				  alpha ? 0xff000000 : 0,
+				  premultiplied,
+				  masks[3] // data type
+				  );
+	break;
+	
+      case TYPE_INT_BGR:
+	String msg =
+	  "FIXME: Programmer is confused. Why (and how) does a " +
+	  "TYPE_INT_BGR image use ComponentColorModel to store " +
+	  "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
+	  "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
+	throw new UnsupportedOperationException(msg);
+	
+      case TYPE_3BYTE_BGR:
+      case TYPE_4BYTE_ABGR:
+      case TYPE_4BYTE_ABGR_PRE:
+      case TYPE_BYTE_GRAY:
+      case TYPE_USHORT_GRAY:
+	int[] bits = null;
+	int dataType = DataBuffer.TYPE_BYTE;
+	switch (type) {
+	case TYPE_3BYTE_BGR:
+	  bits = bits3;
+	  break;
+	case TYPE_4BYTE_ABGR:
+	case TYPE_4BYTE_ABGR_PRE:
+	  bits = bits4;
+	  break;
+	case TYPE_BYTE_GRAY:
+	  bits = bits1byte;
+	  break;
+	case TYPE_USHORT_GRAY:
+	  bits = bits1ushort;
+	  dataType = DataBuffer.TYPE_USHORT;
+	  break;
+	}
+	cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
+				     alpha ?
+				     Transparency.TRANSLUCENT:
+				     Transparency.OPAQUE,
+				     dataType);
+	break;
+      case TYPE_BYTE_BINARY:
+	byte[] vals = { 0, (byte) 0xff };
+	cm = new IndexColorModel(8, 2, vals, vals, vals);
+	break;
+      case TYPE_BYTE_INDEXED:
+	String msg2 = "type not implemented yet";
+	throw new UnsupportedOperationException(msg2);
+	// FIXME: build color-cube and create color model
+      }
+    
+    init(cm,
+	 cm.createCompatibleWritableRaster(w, h),
+	 premultiplied,
+	 null, // no properties
+	 type
+	 );
+  }
+
+  public BufferedImage(int w, int h, int type,
+		       IndexColorModel indexcolormodel)
+  {
+    if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
+      throw new IllegalArgumentException("type must be binary or indexed");
+
+    init(indexcolormodel,
+	 indexcolormodel.createCompatibleWritableRaster(w, h),
+	 false, // not premultiplied (guess)
+	 null, // no properties
+	 type);
+  }
+
+  public BufferedImage(ColorModel colormodel, 
+		       WritableRaster writableraster,
+		       boolean premultiplied,
+		       Hashtable properties)
+  {
+    init(colormodel, writableraster, premultiplied, properties,
+	 TYPE_CUSTOM);
+    // TODO: perhaps try to identify type?
+  }
+ 
+  WritableRaster raster;
+  ColorModel colorModel;
+  Hashtable properties;
+  boolean isPremultiplied;
+  int type;
+  
+  private void init(ColorModel cm,
+		    WritableRaster writableraster,
+		    boolean premultiplied,
+		    Hashtable properties,
+		    int type)
+  {
+    raster = writableraster;
+    colorModel = cm;
+    this.properties = properties;
+    isPremultiplied = premultiplied;
+    this.type = type;
+  }
+    
+  //public void addTileObserver(TileObserver tileobserver) {}
+  
+  public void coerceData(boolean premultiplied)
+  {
+    colorModel = colorModel.coerceData(raster, premultiplied);
+  }
+
+  public WritableRaster copyData(WritableRaster dest)
+  {
+    if (dest == null)
+      dest = raster.createCompatibleWritableRaster(getMinX(), getMinY(),
+                                                   getWidth(),getHeight());
+
+    int x = dest.getMinX();
+    int y = dest.getMinY();
+    int w = dest.getWidth();
+    int h = dest.getHeight();
+    
+    // create a src child that has the right bounds...
+    WritableRaster src =
+      raster.createWritableChild(x, y, w, h, x, y,
+				 null  // same bands
+				 );
+    if (src.getSampleModel () instanceof ComponentSampleModel
+        && dest.getSampleModel () instanceof ComponentSampleModel)
+      // Refer to ComponentDataBlitOp for optimized data blitting:
+      ComponentDataBlitOp.INSTANCE.filter(src, dest);
+    else
+      {
+        // slower path
+        int samples[] = src.getPixels (x, y, w, h, (int [])null);
+        dest.setPixels (x, y, w, h, samples);
+      }
+    return dest;
+  }
+
+  public Graphics2D createGraphics()
+  {
+    GraphicsEnvironment env;
+    env = GraphicsEnvironment.getLocalGraphicsEnvironment ();
+    return env.createGraphics (this);
+  }
+
+  public void flush() {
+  }
+  
+  public WritableRaster getAlphaRaster()
+  {
+    return colorModel.getAlphaRaster(raster);
+  }
+  
+  public ColorModel getColorModel()
+  {
+    return colorModel;
+  }
+  
+  public Raster getData()
+  {
+    return copyData(null);
+    /* TODO: this might be optimized by returning the same
+       raster (not writable) as long as image data doesn't change. */
+  }
+
+  public Raster getData(Rectangle rectangle)
+  {
+    WritableRaster dest =
+      raster.createCompatibleWritableRaster(rectangle);
+    return copyData(dest);
+  }
+  
+  public Graphics getGraphics()
+  {
+    return createGraphics();
+  }
+
+  public int getHeight()
+  {
+    return raster.getHeight();
+  }
+  
+  public int getHeight(ImageObserver imageobserver)
+  {
+    return getHeight();
+  }
+    
+  public int getMinTileX()
+  {
+    return 0;
+  }
+  
+  public int getMinTileY()
+  {
+    return 0;
+  }
+
+  public int getMinX()
+  {
+    return 0; 
+  }
+
+  public int getMinY() 
+  {
+    return 0;
+  }
+  
+  public int getNumXTiles()
+  {
+    return 1;
+  }
+
+  public int getNumYTiles()
+  {
+	return 1;
+  }
+
+  public Object getProperty(String string)
+  {
+    if (properties == null)
+      return null;
+    return properties.get(string);
+  }
+
+  public Object getProperty(String string, ImageObserver imageobserver)
+  {
+    return getProperty(string);
+  }
+
+  
+  public String[] getPropertyNames()
+  {
+    // FIXME: implement
+    return null;
+  }
+
+  public int getRGB(int x, int y)
+  {
+    Object rgbElem = raster.getDataElements(x, y,
+					    null // create as needed
+					    );
+    return colorModel.getRGB(rgbElem);
+  }
+    
+  public int[] getRGB(int startX, int startY, int w, int h,
+		      int[] rgbArray,
+		      int offset, int scanlineStride)
+  {
+    if (rgbArray == null)
+    {
+      /*
+	000000000000000000
+	00000[#######-----   [ = start
+	-----########-----   ] = end
+	-----#######]00000
+	000000000000000000  */
+      int size = (h-1)*scanlineStride + w;
+      rgbArray = new int[size];
+    }
+	
+    int endX = startX + w;
+    int endY = startY + h;
+    
+    /* *TODO*:
+       Opportunity for optimization by examining color models...
+       
+       Perhaps wrap the rgbArray up in a WritableRaster with packed
+       sRGB color model and perform optimized rendering into the
+       array. */
+
+    Object rgbElem = null;
+    for (int y=startY; y<endY; y++)
+      {
+	int xoffset = offset;
+	for (int x=startX; x<endX; x++)
+	  {
+	    int rgb;
+	    rgbElem = raster.getDataElements(x, y, rgbElem);
+	    rgb = colorModel.getRGB(rgbElem);
+	    rgbArray[xoffset++] = rgb;
+	  }
+	offset += scanlineStride;
+      }
+    return rgbArray;
+  }
+
+  public WritableRaster getRaster()
+  {
+    return raster;
+  }
+  
+  public SampleModel getSampleModel()
+  {
+    return raster.getSampleModel();
+  }
+    
+  public ImageProducer getSource()
+  {
+    return new ImageProducer() {
+        
+	Vector consumers = new Vector();
+
+        public void addConsumer(ImageConsumer ic)
+        {
+	  if(!consumers.contains(ic))
+	    consumers.add(ic);
+        }
+
+        public boolean isConsumer(ImageConsumer ic)
+        {
+          return consumers.contains(ic);
+        }
+
+        public void removeConsumer(ImageConsumer ic)
+        {
+	  consumers.remove(ic);
+        }
+
+        public void startProduction(ImageConsumer ic)
+        {
+          int x = 0;
+          int y = 0;
+          int width = getWidth();
+          int height = getHeight();
+          int stride = width;
+          int offset = 0;
+          int[] pixels = getRGB(x, y, 
+                                width, height, 
+                                (int[])null, offset, stride);
+          ColorModel model = getColorModel();
+
+          consumers.add(ic);
+
+	  for(int i=0;i<consumers.size();i++)
+            {
+              ImageConsumer c = (ImageConsumer) consumers.elementAt(i);
+              c.setHints(ImageConsumer.SINGLEPASS);
+              c.setDimensions(getWidth(), getHeight());
+              c.setPixels(x, y, width, height, model, pixels, offset, stride);
+              c.imageComplete(ImageConsumer.STATICIMAGEDONE);
+            }
+        }
+
+        public void requestTopDownLeftRightResend(ImageConsumer ic)
+        {
+          startProduction(ic);
+        }
+
+      };
+  }
+  
+  public Vector getSources()
+  {
+    return null;
+  }
+  
+  public BufferedImage getSubimage(int x, int y, int w, int h)
+  {
+    WritableRaster subRaster = 
+      getRaster().createWritableChild(x, y, w, h, 0, 0, null);
+    
+    return new BufferedImage(getColorModel(),
+			     subRaster,
+			     isPremultiplied,
+			     properties);
+  }
+
+  public Raster getTile(int tileX, int tileY)
+  {
+    return getWritableTile(tileX, tileY);
+  }
+    
+  public int getTileGridXOffset()
+  {
+    return 0; // according to javadocs
+  }
+
+  public int getTileGridYOffset()
+  {
+    return 0; // according to javadocs
+  }
+
+  public int getTileHeight()
+  {
+    return getHeight(); // image is one big tile
+  }
+
+  public int getTileWidth()
+  {
+    return getWidth(); // image is one big tile
+  }
+
+  public int getType()
+  {
+    return type;
+  }
+
+  public int getWidth()
+  {
+    return raster.getWidth();
+  }
+
+  public int getWidth(ImageObserver imageobserver)
+  {
+    return getWidth();
+  }
+
+  public WritableRaster getWritableTile(int tileX, int tileY)
+  {
+    isTileWritable(tileX, tileY);  // for exception
+    return raster;
+  }
+
+  private static final Point[] tileIndices = { new Point() };
+    
+  public Point[] getWritableTileIndices()
+  {
+    return tileIndices;
+  }
+
+  public boolean hasTileWriters()
+  {
+    return true;
+  }
+  
+  public boolean isAlphaPremultiplied()
+  {
+    return isPremultiplied;
+  }
+
+  public boolean isTileWritable(int tileX, int tileY)
+  {
+    if ((tileX != 0) || (tileY != 0))
+      throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
+    return true;
+  }
+
+  public void releaseWritableTile(int tileX, int tileY)
+  {
+    isTileWritable(tileX, tileY);  // for exception
+  }
+
+  //public void removeTileObserver(TileObserver tileobserver) {}
+
+  public void setData(Raster src)
+  {
+    int x = src.getMinX();
+    int y = src.getMinY();
+    int w = src.getWidth();
+    int h = src.getHeight();
+    
+    // create a dest child that has the right bounds...
+    WritableRaster dest =
+      raster.createWritableChild(x, y, w, h, x, y,
+				 null  // same bands
+				 );
+
+    if (src.getSampleModel () instanceof ComponentSampleModel
+        && dest.getSampleModel () instanceof ComponentSampleModel)
+
+      // Refer to ComponentDataBlitOp for optimized data blitting:
+      ComponentDataBlitOp.INSTANCE.filter(src, dest);
+    else
+      {
+        // slower path
+        int samples[] = src.getPixels (x, y, w, h, (int [])null);
+        dest.setPixels (x, y, w, h, samples);
+      }
+  }
+
+  public void setRGB(int x, int y, int argb)
+  {
+    Object rgbElem = colorModel.getDataElements(argb, null);
+    raster.setDataElements(x, y, rgbElem);
+  }
+  
+  public void setRGB(int startX, int startY, int w, int h,
+		     int[] argbArray, int offset, int scanlineStride)
+  {
+    int endX = startX + w;
+    int endY = startY + h;
+    
+    Object rgbElem = null;
+    for (int y=startY; y<endY; y++)
+      {
+	int xoffset = offset;
+	for (int x=startX; x<endX; x++)
+	  {
+	    int argb = argbArray[xoffset++];
+	    rgbElem = colorModel.getDataElements(argb, rgbElem);
+	    raster.setDataElements(x, y, rgbElem);
+	  }
+	offset += scanlineStride;    
+      }
+  }
+    
+  public String toString()
+  {
+    StringBuffer buf;
+
+    buf = new StringBuffer(/* estimated length */ 120);
+    buf.append("BufferedImage@");
+    buf.append(Integer.toHexString(hashCode()));
+    buf.append(": type=");
+    buf.append(type);
+    buf.append(' ');
+    buf.append(colorModel);
+    buf.append(' ');
+    buf.append(raster);
+
+    return buf.toString();
+  }
+
+
+  /**
+   * Adds a tile observer. If the observer is already present, it receives
+   * multiple notifications.
+   *
+   * @param to The TileObserver to add.
+   */
+  public void addTileObserver (TileObserver to)
+  {
+    if (observers == null)
+      observers = new Vector ();
+	
+    observers.add (to);
+  }
+	
+  /**
+   * Removes a tile observer. If the observer was not registered,
+   * nothing happens. If the observer was registered for multiple
+   * notifications, it is now registered for one fewer notification.
+   *
+   * @param to The TileObserver to remove.
+   */
+  public void removeTileObserver (TileObserver to)
+  {
+    if (observers == null)
+      return;
+	
+    observers.remove (to);
+  }
+}
===================================================================
Checking out kaffe/libraries/javalib/java/awt/image/DirectColorModel.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/awt/image/DirectColorModel.java,v
VERS: 1.14
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/awt/image/DirectColorModel.java	Fri Jun 10 22:24:52 2005
@@ -0,0 +1,420 @@
+/* DirectColorModel.java --
+   Copyright (C) 1999, 2000, 2002, 2004  Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+
+import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+
+/**
+ * @author Rolf W. Rasmussen (rolfwr at ii.uib.no)
+ * @author C. Brian Jones (cbj at gnu.org)
+ * @author Mark Benvenuto (mcb54 at columbia.edu)
+ */
+public class DirectColorModel extends PackedColorModel
+{
+  /**
+   * For the color model created with this constructor the pixels
+   * will have fully opaque alpha components with a value of 255.
+   * Each mask should describe a fully contiguous set of bits in the
+   * most likely order of alpha, red, green, blue from the most significant
+   * byte to the least significant byte.
+   * 
+   * @param pixelBits the number of bits wide used for bit size of pixel values
+   * @param rmask the bits describing the red component of a pixel
+   * @param gmask the bits describing the green component of a pixel
+   * @param bmask the bits describing the blue component of a pixel 
+   */
+  public DirectColorModel(int pixelBits, int rmask, int gmask, int bmask)
+  {
+    this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
+	 rmask, gmask, bmask, 0, 
+	 false, // not alpha premultiplied
+	 Buffers.smallestAppropriateTransferType(pixelBits) // find type
+	 );
+  }
+
+  /**
+   * For the color model created with this constructor the pixels
+   * will have fully opaque alpha components with a value of 255.
+   * Each mask should describe a fully contiguous set of bits in the
+   * most likely order of red, green, blue from the most significant
+   * byte to the least significant byte.
+   * 
+   * @param pixelBits the number of bits wide used for bit size of pixel values
+   * @param rmask the bits describing the red component of a pixel
+   * @param gmask the bits describing the green component of a pixel
+   * @param bmask the bits describing the blue component of a pixel 
+   * @param amask the bits describing the alpha component of a pixel 
+   */
+  public DirectColorModel(int pixelBits,
+			  int rmask, int gmask, int bmask, int amask)
+  {
+    this(ColorSpace.getInstance(ColorSpace.CS_sRGB), pixelBits,
+	 rmask, gmask, bmask, amask,
+	 false, // not alpha premultiplied
+	 Buffers.smallestAppropriateTransferType(pixelBits) // find type
+	 );
+  }
+
+  public DirectColorModel(ColorSpace cspace, int pixelBits,
+			  int rmask, int gmask, int bmask, int amask,
+			  boolean isAlphaPremultiplied,
+			  int transferType)
+  {
+    super(cspace, pixelBits,
+	  rmask, gmask, bmask, amask, isAlphaPremultiplied,
+	  ((amask == 0) ? Transparency.OPAQUE : Transparency.TRANSLUCENT),
+	  transferType);
+  }
+    
+  public final int getRedMask()
+  {
+    return getMask(0);
+  }
+
+  public final int getGreenMask()
+  {
+    return getMask(1);
+  }
+
+  public final int getBlueMask()
+  {
+    return getMask(2);
+  }
+
+  public final int getAlphaMask()
+  {
+    return hasAlpha() ? getMask(3) : 0;
+  }
+
+  /**
+   * Get the red component of the given pixel.
+   * <br>
+   */
+  public final int getRed(int pixel)
+  {
+    return extractAndNormalizeSample(pixel, 0);
+  }
+
+  /**
+   * Get the green component of the given pixel.
+   * <br>
+   */
+  public final int getGreen(int pixel)
+  {
+    return extractAndNormalizeSample(pixel, 1);
+  }
+  
+  /**
+   * Get the blue component of the given pixel.
+   * <br>
+   */
+  public final int getBlue(int pixel)
+  {
+    return extractAndNormalizeSample(pixel, 2);
+  }
+
+  /**
+   * Get the alpha component of the given pixel.
+   * <br>
+   */
+  public final int getAlpha(int pixel)
+  {
+    if (!hasAlpha())
+      return 255;
+    return extractAndScaleSample(pixel, 3);
+  }
+
+  private int extractAndNormalizeSample(int pixel, int component)
+  {
+    int value = extractAndScaleSample(pixel, component);
+    if (hasAlpha() && isAlphaPremultiplied())
+      value = value*255/getAlpha(pixel);
+    return value;
+  }
+
+  private int extractAndScaleSample(int pixel, int component)
+  {
+    int field = pixel & getMask(component);
+    int to8BitShift =
+      8 - shifts[component] - getComponentSize(component);
+    return (to8BitShift>0) ?
+      (field << to8BitShift) :
+      (field >>> (-to8BitShift));
+  }
+
+  /**
+   * Get the RGB color value of the given pixel using the default
+   * RGB color model. 
+   * <br>
+   *
+   * @param pixel a pixel value
+   */
+  public final int getRGB(int pixel) 
+  {
+    /* FIXME: The Sun docs show that this method is overridden, but I
+       don't see any way to improve on the superclass
+       implementation. */
+    return super.getRGB(pixel);
+  }
+
+  public int getRed(Object inData)
+  {
+    return getRed(getPixelFromArray(inData));
+  }
+
+  public int getGreen(Object inData)
+  {
+    return getGreen(getPixelFromArray(inData));
+  }
+
+  public int getBlue(Object inData)
+  {
+    return getBlue(getPixelFromArray(inData));
+  }
+    
+  public int getAlpha(Object inData)
+  {
+    return getAlpha(getPixelFromArray(inData));
+  }
+
+  public int getRGB(Object inData)
+  {
+    return getRGB(getPixelFromArray(inData));
+  }
+    
+  /**
+   * Converts a normalized pixel int value in the sRGB color
+   * space to an array containing a single pixel of the color space
+   * of the color model.
+   *
+   * <p>This method performs the inverse function of
+   * <code>getRGB(Object inData)</code>.
+   *
+   * @param rgb pixel as a normalized sRGB, 0xAARRGGBB value.
+   *  
+   * @param pixel to avoid needless creation of arrays, an array to
+   * use to return the pixel can be given. If null, a suitable array
+   * will be created.
+   *
+   * @return array of transferType containing a single pixel. The
+   * pixel should be encoded in the natural way of the color model.
+   *
+   * @see #getRGB(Object)
+   */
+  public Object getDataElements(int rgb, Object pixel)
+  {
+    // FIXME: handle alpha multiply
+    
+    int pixelValue = 0;
+    int a = 0;
+    if (hasAlpha()) {
+      a = (rgb >>> 24) & 0xff;
+      pixelValue = valueToField(a, 3, 8);
+    }
+	
+    if (hasAlpha() && isAlphaPremultiplied())
+      {

*** Patch too long, truncated ***




More information about the kaffe mailing list