1 /* Copyright (C) 2000 Free Software Foundation
3 This file is part of libgcj.
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 package java.awt.image;
12 import java.awt.color.*;
15 import gnu.gcj.awt.ComponentDataBlitOp;
18 * A buffered image always starts at coordinates (0, 0).
20 * The buffered image is not subdivided into multiple tiles. Instead,
21 * the image consists of one large tile (0,0) with the width and
22 * height of the image. This tile is always considered to be checked
25 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
27 public class BufferedImage extends java.awt.Image
28 //implements java.awt.image.WritableRenderedImage
30 public static final int TYPE_CUSTOM = 0,
33 TYPE_INT_ARGB_PRE = 3,
37 TYPE_4BYTE_ABGR_PRE = 7,
38 TYPE_USHORT_565_RGB = 8,
39 TYPE_USHORT_555_RGB = 9,
41 TYPE_USHORT_GRAY = 11,
42 TYPE_BYTE_BINARY = 12,
43 TYPE_BYTE_INDEXED = 13;
45 final static int[] bits3 = { 8, 8, 8 };
46 final static int[] bits4 = { 8, 8, 8 };
47 final static int[] bits1byte = { 8 };
48 final static int[] bits1ushort = { 16 };
50 final static int[] masks_int = { 0x00ff0000,
53 DataBuffer.TYPE_INT };
54 final static int[] masks_565 = { 0xf800,
57 DataBuffer.TYPE_USHORT};
58 final static int[] masks_555 = { 0x7c00,
61 DataBuffer.TYPE_USHORT};
63 public BufferedImage(int w, int h, int type)
67 boolean alpha = false;
68 boolean premultiplied = false;
71 case TYPE_4BYTE_ABGR_PRE:
72 case TYPE_INT_ARGB_PRE:
80 ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
85 case TYPE_INT_ARGB_PRE:
86 case TYPE_USHORT_565_RGB:
87 case TYPE_USHORT_555_RGB:
93 case TYPE_INT_ARGB_PRE:
96 case TYPE_USHORT_565_RGB:
99 case TYPE_USHORT_555_RGB:
104 cm = new DirectColorModel(cs,
105 32, // 32 bits in an int
109 alpha ? 0xff000000 : 0,
111 masks[3] // data type
117 "FIXME: Programmer is confused. Why (and how) does a " +
118 "TYPE_INT_BGR image use ComponentColorModel to store " +
119 "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
120 "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
121 throw new UnsupportedOperationException(msg);
124 case TYPE_4BYTE_ABGR:
125 case TYPE_4BYTE_ABGR_PRE:
127 case TYPE_USHORT_GRAY:
129 int dataType = DataBuffer.TYPE_BYTE;
134 case TYPE_4BYTE_ABGR:
135 case TYPE_4BYTE_ABGR_PRE:
141 case TYPE_USHORT_GRAY:
143 dataType = DataBuffer.TYPE_USHORT;
146 cm = new ComponentColorModel(cs, bits, alpha, premultiplied,
148 Transparency.TRANSLUCENT:
152 case TYPE_BYTE_BINARY:
153 byte[] vals = { 0, (byte) 0xff };
154 cm = new IndexColorModel(8, 2, vals, vals, vals);
156 case TYPE_BYTE_INDEXED:
157 String msg2 = "type not implemented yet";
158 throw new UnsupportedOperationException(msg2);
159 // FIXME: build color-cube and create color model
163 cm.createCompatibleWritableRaster(w, h),
165 null, // no properties
170 public BufferedImage(int w, int h, int type,
171 IndexColorModel indexcolormodel)
173 if ((type != TYPE_BYTE_BINARY) && (type != TYPE_BYTE_INDEXED))
174 throw new IllegalArgumentException("type must be binary or indexed");
176 init(indexcolormodel,
177 indexcolormodel.createCompatibleWritableRaster(w, h),
178 false, // not premultiplied (guess)
179 null, // no properties
183 public BufferedImage(ColorModel colormodel,
184 WritableRaster writableraster,
185 boolean premultiplied,
186 Hashtable properties)
188 init(colormodel, writableraster, premultiplied, properties,
190 // TODO: perhaps try to identify type?
193 WritableRaster raster;
194 ColorModel colorModel;
195 Hashtable properties;
196 boolean isPremultiplied;
199 private void init(ColorModel cm,
200 WritableRaster writableraster,
201 boolean premultiplied,
202 Hashtable properties,
205 raster = writableraster;
207 this.properties = properties;
208 isPremultiplied = premultiplied;
212 //public void addTileObserver(TileObserver tileobserver) {}
214 public void coerceData(boolean premultiplied)
216 colorModel = colorModel.coerceData(raster, premultiplied);
219 public WritableRaster copyData(WritableRaster dest)
222 dest = raster.createCompatibleWritableRaster();
224 int x = dest.getMinX();
225 int y = dest.getMinY();
226 int w = dest.getWidth();
227 int h = dest.getHeight();
229 // create a src child that has the right bounds...
231 raster.createWritableChild(x, y, w, h, x, y,
235 // Refer to ComponentDataBlitOp for optimized data blitting:
236 ComponentDataBlitOp.INSTANCE.filter(src, dest);
240 public Graphics2D createGraphics()
242 throw new UnsupportedOperationException("not implemented");
243 // will require a lot of effort to implement
246 public void flush() {
249 public WritableRaster getAlphaRaster()
251 return colorModel.getAlphaRaster(raster);
254 public ColorModel getColorModel()
259 public Raster getData()
261 return copyData(null);
262 /* TODO: this might be optimized by returning the same
263 raster (not writable) as long as image data doesn't change. */
266 public Raster getData(Rectangle rectangle)
268 WritableRaster dest =
269 raster.createCompatibleWritableRaster(rectangle);
270 return copyData(dest);
273 public Graphics getGraphics()
275 return createGraphics();
278 public int getHeight()
280 return raster.getHeight();
283 public int getHeight(ImageObserver imageobserver)
288 public int getMinTileX()
293 public int getMinTileY()
308 public int getNumXTiles()
313 public int getNumYTiles()
318 public Object getProperty(String string)
320 if (properties == null)
322 return properties.get(string);
325 public Object getProperty(String string, ImageObserver imageobserver)
327 return getProperty(string);
331 public String[] getPropertyNames()
337 public int getRGB(int x, int y)
339 Object rgbElem = raster.getDataElements(x, y,
340 null // create as needed
342 return colorModel.getRGB(rgbElem);
345 public int[] getRGB(int startX, int startY, int w, int h,
347 int offset, int scanlineStride)
349 if (rgbArray == null)
353 00000[#######----- [ = start
354 -----########----- ] = end
356 000000000000000000 */
357 int size = (h-1)*scanlineStride + w;
358 rgbArray = new int[size];
361 int endX = startX + w;
362 int endY = startY + h;
365 Opportunity for optimization by examining color models...
367 Perhaps wrap the rgbArray up in a WritableRaster with packed
368 sRGB color model and perform optimized rendering into the
371 Object rgbElem = null;
372 for (int y=startY; y<endY; y++)
374 int xoffset = offset;
375 for (int x=startX; x<endX; x++)
378 rgbElem = raster.getDataElements(x, y, rgbElem);
379 rgb = colorModel.getRGB(rgbElem);
380 rgbArray[xoffset++] = rgb;
382 offset += scanlineStride;
387 public WritableRaster getRaster()
392 public SampleModel getSampleModel()
394 return raster.getSampleModel();
397 public ImageProducer getSource()
399 throw new UnsupportedOperationException("not implemented");
402 public Vector getSources()
407 public BufferedImage getSubimage(int x, int y, int w, int h)
409 WritableRaster subRaster =
410 getRaster().createWritableChild(x, y, w, h, 0, 0, null);
412 return new BufferedImage(getColorModel(),
418 public Raster getTile(int tileX, int tileY)
420 return getWritableTile(tileX, tileY);
423 public int getTileGridXOffset()
425 return 0; // according to javadocs
428 public int getTileGridYOffset()
430 return 0; // according to javadocs
433 public int getTileHeight()
435 return getHeight(); // image is one big tile
438 public int getTileWidth()
440 return getWidth(); // image is one big tile
448 public int getWidth()
450 return raster.getWidth();
453 public int getWidth(ImageObserver imageobserver)
458 public WritableRaster getWritableTile(int tileX, int tileY)
460 isTileWritable(tileX, tileY); // for exception
464 private static final Point[] tileIndices = { new Point() };
466 public Point[] getWritableTileIndices()
471 public boolean hasTileWriters()
476 public boolean isAlphaPremultiplied()
478 return isPremultiplied;
481 public boolean isTileWritable(int tileX, int tileY)
483 if ((tileX != 0) || (tileY != 0))
484 throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
488 public void releaseWritableTile(int tileX, int tileY)
490 isTileWritable(tileX, tileY); // for exception
493 //public void removeTileObserver(TileObserver tileobserver) {}
495 public void setData(Raster src)
497 int x = src.getMinX();
498 int y = src.getMinY();
499 int w = src.getWidth();
500 int h = src.getHeight();
502 // create a dest child that has the right bounds...
503 WritableRaster dest =
504 raster.createWritableChild(x, y, w, h, x, y,
508 // Refer to ComponentDataBlitOp for optimized data blitting:
509 ComponentDataBlitOp.INSTANCE.filter(src, dest);
512 public void setRGB(int x, int y, int argb)
514 Object rgbElem = colorModel.getDataElements(argb, null);
515 raster.setDataElements(x, y, rgbElem);
518 public void setRGB(int startX, int startY, int w, int h,
519 int[] argbArray, int offset, int scanlineStride)
521 int endX = startX + w;
522 int endY = startY + h;
524 Object rgbElem = null;
525 for (int y=startY; y<endY; y++)
527 int xoffset = offset;
528 for (int x=startX; x<endX; x++)
530 int argb = argbArray[xoffset++];
531 rgbElem = colorModel.getDataElements(argb, rgbElem);
532 raster.setDataElements(x, y, rgbElem);
534 offset += scanlineStride;
538 public String toString()
541 return super.toString();