summaryrefslogtreecommitdiff
path: root/libjava/classpath/java/awt/image/BufferedImage.java
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/java/awt/image/BufferedImage.java
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/java/awt/image/BufferedImage.java')
-rw-r--r--libjava/classpath/java/awt/image/BufferedImage.java839
1 files changed, 839 insertions, 0 deletions
diff --git a/libjava/classpath/java/awt/image/BufferedImage.java b/libjava/classpath/java/awt/image/BufferedImage.java
new file mode 100644
index 000000000..094c71dd1
--- /dev/null
+++ b/libjava/classpath/java/awt/image/BufferedImage.java
@@ -0,0 +1,839 @@
+/* BufferedImage.java --
+ Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.awt.image;
+
+import gnu.java.awt.Buffers;
+import gnu.java.awt.ClasspathGraphicsEnvironment;
+import gnu.java.awt.ComponentDataBlitOp;
+import gnu.java.lang.CPStringBuilder;
+
+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.Hashtable;
+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@ii.uib.no)
+ */
+public class BufferedImage extends Image
+ implements WritableRenderedImage, Transparency
+{
+ 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;
+
+ /**
+ * Vector of TileObservers (or null)
+ */
+ Vector<TileObserver> tileObservers;
+
+ /**
+ * The image's WritableRaster
+ */
+ WritableRaster raster;
+
+ /**
+ * The associated ColorModel
+ */
+ ColorModel colorModel;
+
+ /**
+ * The image's properties (or null)
+ */
+ Hashtable properties;
+
+ /**
+ * Whether alpha is premultiplied
+ */
+ boolean isPremultiplied;
+
+ /**
+ * The predefined type, if any.
+ */
+ int type;
+
+ /**
+ * Creates a new <code>BufferedImage</code> with the specified width, height
+ * and type. Valid <code>type</code> values are:
+ *
+ * <ul>
+ * <li>{@link #TYPE_INT_RGB}</li>
+ * <li>{@link #TYPE_INT_ARGB}</li>
+ * <li>{@link #TYPE_INT_ARGB_PRE}</li>
+ * <li>{@link #TYPE_INT_BGR}</li>
+ * <li>{@link #TYPE_3BYTE_BGR}</li>
+ * <li>{@link #TYPE_4BYTE_ABGR}</li>
+ * <li>{@link #TYPE_4BYTE_ABGR_PRE}</li>
+ * <li>{@link #TYPE_USHORT_565_RGB}</li>
+ * <li>{@link #TYPE_USHORT_555_RGB}</li>
+ * <li>{@link #TYPE_BYTE_GRAY}</li>
+ * <li>{@link #TYPE_USHORT_GRAY}</li>
+ * <li>{@link #TYPE_BYTE_BINARY}</li>
+ * <li>{@link #TYPE_BYTE_INDEXED}</li>
+ * </ul>
+ *
+ * @param width the width (must be > 0).
+ * @param height the height (must be > 0).
+ * @param type the image type (see the list of valid types above).
+ *
+ * @throws IllegalArgumentException if <code>width</code> or
+ * <code>height</code> is less than or equal to zero.
+ * @throws IllegalArgumentException if <code>type</code> is not one of the
+ * specified values.
+ */
+ public BufferedImage(int width, int height, int type)
+ {
+ SampleModel sm = null;
+ ColorModel cm = null;
+ boolean premultiplied = (type == BufferedImage.TYPE_INT_ARGB_PRE
+ || type == BufferedImage.TYPE_4BYTE_ABGR_PRE);
+
+ switch( type )
+ {
+ case BufferedImage.TYPE_INT_RGB:
+ sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT,
+ width, height,
+ new int[]{ 0x00FF0000,
+ 0x0000FF00,
+ 0x000000FF } ) ;
+ cm = new DirectColorModel( 24, 0xff0000, 0xff00, 0xff );
+ break;
+
+ case BufferedImage.TYPE_3BYTE_BGR:
+ sm = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE,
+ width, height,
+ 3, width * 3,
+ new int[]{ 2, 1, 0 } );
+ cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ false, false,
+ BufferedImage.OPAQUE,
+ DataBuffer.TYPE_BYTE);
+ break;
+
+ case BufferedImage.TYPE_INT_ARGB:
+ case BufferedImage.TYPE_INT_ARGB_PRE:
+ sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT,
+ width, height,
+ new int[]{ 0x00FF0000,
+ 0x0000FF00,
+ 0x000000FF,
+ 0xFF000000 } );
+ if (premultiplied)
+ cm = new DirectColorModel( ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ 32, 0xff0000, 0xff00, 0xff, 0xff000000,
+ true,
+ Buffers.smallestAppropriateTransferType(32));
+ else
+ cm = new DirectColorModel( 32, 0xff0000, 0xff00, 0xff, 0xff000000 );
+
+ break;
+
+ case BufferedImage.TYPE_4BYTE_ABGR:
+ case BufferedImage.TYPE_4BYTE_ABGR_PRE:
+ sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
+ width, height,
+ 4, 4*width,
+ new int[]{3, 2, 1, 0});
+ cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
+ true, premultiplied,
+ BufferedImage.TRANSLUCENT,
+ DataBuffer.TYPE_BYTE);
+ break;
+
+ case BufferedImage.TYPE_INT_BGR:
+ sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT,
+ width, height,
+ new int[]{ 0x000000FF,
+ 0x0000FF00,
+ 0x00FF0000 } ) ;
+ cm = new DirectColorModel( 24, 0xff, 0xff00, 0xff0000 );
+ break;
+
+ case BufferedImage.TYPE_USHORT_565_RGB:
+ sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_USHORT,
+ width, height,
+ new int[]{ 0xF800,
+ 0x7E0,
+ 0x1F } ) ;
+ cm = new DirectColorModel( 16, 0xF800, 0x7E0, 0x1F );
+ break;
+
+ case BufferedImage.TYPE_USHORT_555_RGB:
+ sm = new SinglePixelPackedSampleModel( DataBuffer.TYPE_USHORT,
+ width, height,
+ new int[]{ 0x7C00,
+ 0x3E0,
+ 0x1F } ) ;
+ cm = new DirectColorModel( 15, 0x7C00, 0x3E0, 0x1F );
+ break;
+
+ case BufferedImage.TYPE_BYTE_INDEXED:
+ cm = createDefaultIndexedColorModel( false );
+
+ case BufferedImage.TYPE_BYTE_GRAY:
+ sm = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE,
+ width, height,
+ 1, width, new int[]{ 0 } );
+ break;
+
+ case BufferedImage.TYPE_USHORT_GRAY:
+ sm = new PixelInterleavedSampleModel( DataBuffer.TYPE_USHORT,
+ width, height,
+ 1, width, new int[]{ 0 } );
+ break;
+
+ case BufferedImage.TYPE_BYTE_BINARY:
+ cm = createDefaultIndexedColorModel( true );
+ sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
+ width, height, 1);
+ break;
+
+ default:
+ sm = null;
+ }
+
+ if( sm == null )
+ throw new IllegalArgumentException("Unknown predefined image type.");
+
+ if( cm == null ) // only for the grayscale types
+ {
+ int buftype;
+ int[] bits = new int[1];
+ if( type == BufferedImage.TYPE_BYTE_GRAY )
+ {
+ buftype = DataBuffer.TYPE_BYTE;
+ bits[0] = 8;
+ }
+ else
+ {
+ buftype = DataBuffer.TYPE_USHORT;
+ bits[0] = 16;
+ }
+ ColorSpace graySpace = ColorSpace.getInstance( ColorSpace.CS_GRAY );
+
+ cm = new ComponentColorModel( graySpace, bits, false, false,
+ Transparency.OPAQUE, buftype );
+ }
+
+ WritableRaster rst = null;
+
+ // Attempt to create an accelerated backend for this image
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ if (env instanceof ClasspathGraphicsEnvironment)
+ rst = ((ClasspathGraphicsEnvironment)env).createRaster(cm, sm);
+
+ // Default to a standard Java raster & databuffer if needed
+ if (rst == null)
+ rst = Raster.createWritableRaster(sm, new Point( 0, 0 ) );
+
+ init(cm, rst, 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 TYPE_BYTE_BINARY or TYPE_BYTE_INDEXED");
+ if( indexcolormodel.getMapSize() > 16 && type == TYPE_BYTE_BINARY )
+ throw new IllegalArgumentException("Type TYPE_BYTE_BINARY cannot have a larger than 16-color palette.");
+ if( indexcolormodel.getMapSize() > 256 )
+ throw new IllegalArgumentException("Byte type cannot have a larger than 256-color palette.");
+
+ init( indexcolormodel,
+ indexcolormodel.createCompatibleWritableRaster(w, h),
+ indexcolormodel.isAlphaPremultiplied(),
+ null, // no properties
+ type );
+ }
+
+ public BufferedImage(ColorModel colormodel, WritableRaster writableraster,
+ boolean premultiplied, Hashtable<?,?> properties)
+ {
+ init(colormodel, writableraster, premultiplied, properties, TYPE_CUSTOM);
+ }
+
+
+ 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;
+ }
+
+ /**
+ * Creates the default palettes for the predefined indexed color types
+ * (256-color or black-and-white)
+ *
+ * @param binary - If <code>true</code>, a black and white palette,
+ * otherwise a default 256-color palette is returned.
+ */
+ private IndexColorModel createDefaultIndexedColorModel( boolean binary )
+ {
+ if( binary )
+ {
+ byte[] t = new byte[]{ 0, (byte)255 };
+ return new IndexColorModel( 1, 2, t, t, t );
+ }
+
+ byte[] r = new byte[256];
+ byte[] g = new byte[256];
+ byte[] b = new byte[256];
+
+ int index = 0;
+ for( int i = 0; i < 6; i++ )
+ for( int j = 0; j < 6; j++ )
+ for( int k = 0; k < 6; k++ )
+ {
+ r[ index ] = (byte)(i * 51);
+ g[ index ] = (byte)(j * 51);
+ b[ index ] = (byte)(k * 51);
+ index++;
+ }
+
+ while( index < 256 )
+ {
+ r[ index ] = g[ index ] = b[ index ] =
+ (byte)(18 + (index - 216) * 6);
+ index++;
+ }
+
+ return new IndexColorModel( 8, 256, r, g, b );
+ }
+
+ public void coerceData(boolean premultiplied)
+ {
+ colorModel = colorModel.coerceData(raster, premultiplied);
+ isPremultiplied = 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;
+ }
+
+ /**
+ * Returns the value of the specified property, or
+ * {@link Image#UndefinedProperty} if the property is not defined.
+ *
+ * @param string the property key (<code>null</code> not permitted).
+ *
+ * @return The property value.
+ *
+ * @throws NullPointerException if <code>string</code> is <code>null</code>.
+ */
+ public Object getProperty(String string)
+ {
+ if (string == null)
+ throw new NullPointerException("The property name cannot be null.");
+ Object result = Image.UndefinedProperty;
+ if (properties != null)
+ {
+ Object v = properties.get(string);
+ if (v != null)
+ result = v;
+ }
+ return result;
+ }
+
+ public Object getProperty(String string, ImageObserver imageobserver)
+ {
+ return getProperty(string);
+ }
+
+ /**
+ * Returns <code>null</code> always.
+ *
+ * @return <code>null</code> always.
+ */
+ public String[] getPropertyNames()
+ {
+ // This method should always return null, see:
+ // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4640609
+ return null;
+ }
+
+ public int getRGB(int x, int y)
+ {
+ Object rgbElem = raster.getDataElements(x, y, null);
+ 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<ImageConsumer> consumers = new Vector<ImageConsumer>();
+
+ 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);
+ // We already convert the color to RGB in the getRGB call, so
+ // we pass a simple RGB color model to the consumers.
+ ColorModel model = new DirectColorModel(32, 0xff0000, 0xff00, 0xff,
+ 0xff000000);
+
+ consumers.add(ic);
+
+ for(int i = 0; i < consumers.size(); i++)
+ {
+ ImageConsumer c = 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<RenderedImage> 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);
+
+ 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()
+ {
+ CPStringBuilder buf;
+
+ buf = new CPStringBuilder(/* 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 (tileObservers == null)
+ tileObservers = new Vector<TileObserver>();
+
+ tileObservers.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 (tileObservers == null)
+ return;
+
+ tileObservers.remove (to);
+ }
+
+ /**
+ * Return the transparency type.
+ *
+ * @return One of {@link #OPAQUE}, {@link #BITMASK}, or {@link #TRANSLUCENT}.
+ * @see Transparency#getTransparency()
+ * @since 1.5
+ */
+ public int getTransparency()
+ {
+ return colorModel.getTransparency();
+ }
+}