1 /* Copyright (C) 2000, 2002 Free Software Foundation
3 This file is part of GNU Classpath.
5 GNU Classpath is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 GNU Classpath is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNU Classpath; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 Linking this library statically or dynamically with other modules is
21 making a combined work based on this library. Thus, the terms and
22 conditions of the GNU General Public License cover the whole
25 As a special exception, the copyright holders of this library give you
26 permission to link this library with independent modules to produce an
27 executable, regardless of the license terms of these independent
28 modules, and to copy and distribute the resulting executable under
29 terms of your choice, provided that you also meet, for each linked
30 independent module, the terms and conditions of the license of that
31 module. An independent module is a module which is not derived from
32 or based on this library. If you modify this library, you may extend
33 this exception to your version of the library, but you are not
34 obligated to do so. If you do not wish to do so, delete this
35 exception statement from your version. */
38 package java
.awt
.image
;
41 import java
.awt
.color
.*;
44 import gnu
.java
.awt
.ComponentDataBlitOp
;
47 * A buffered image always starts at coordinates (0, 0).
49 * The buffered image is not subdivided into multiple tiles. Instead,
50 * the image consists of one large tile (0,0) with the width and
51 * height of the image. This tile is always considered to be checked
54 * @author Rolf W. Rasmussen <rolfwr@ii.uib.no>
56 public class BufferedImage
extends java
.awt
.Image
57 //implements java.awt.image.WritableRenderedImage
59 public static final int TYPE_CUSTOM
= 0,
62 TYPE_INT_ARGB_PRE
= 3,
66 TYPE_4BYTE_ABGR_PRE
= 7,
67 TYPE_USHORT_565_RGB
= 8,
68 TYPE_USHORT_555_RGB
= 9,
70 TYPE_USHORT_GRAY
= 11,
71 TYPE_BYTE_BINARY
= 12,
72 TYPE_BYTE_INDEXED
= 13;
74 final static int[] bits3
= { 8, 8, 8 };
75 final static int[] bits4
= { 8, 8, 8 };
76 final static int[] bits1byte
= { 8 };
77 final static int[] bits1ushort
= { 16 };
79 final static int[] masks_int
= { 0x00ff0000,
82 DataBuffer
.TYPE_INT
};
83 final static int[] masks_565
= { 0xf800,
86 DataBuffer
.TYPE_USHORT
};
87 final static int[] masks_555
= { 0x7c00,
90 DataBuffer
.TYPE_USHORT
};
92 public BufferedImage(int w
, int h
, int type
)
96 boolean alpha
= false;
97 boolean premultiplied
= false;
100 case TYPE_4BYTE_ABGR_PRE
:
101 case TYPE_INT_ARGB_PRE
:
102 premultiplied
= true;
105 case TYPE_4BYTE_ABGR
:
109 ColorSpace cs
= ColorSpace
.getInstance(ColorSpace
.CS_sRGB
);
114 case TYPE_INT_ARGB_PRE
:
115 case TYPE_USHORT_565_RGB
:
116 case TYPE_USHORT_555_RGB
:
122 case TYPE_INT_ARGB_PRE
:
125 case TYPE_USHORT_565_RGB
:
128 case TYPE_USHORT_555_RGB
:
133 cm
= new DirectColorModel(cs
,
134 32, // 32 bits in an int
138 alpha ?
0xff000000 : 0,
140 masks
[3] // data type
146 "FIXME: Programmer is confused. Why (and how) does a " +
147 "TYPE_INT_BGR image use ComponentColorModel to store " +
148 "8-bit values? Is data type TYPE_INT or TYPE_BYTE. What " +
149 "is the difference between TYPE_INT_BGR and TYPE_3BYTE_BGR?";
150 throw new UnsupportedOperationException(msg
);
153 case TYPE_4BYTE_ABGR
:
154 case TYPE_4BYTE_ABGR_PRE
:
156 case TYPE_USHORT_GRAY
:
158 int dataType
= DataBuffer
.TYPE_BYTE
;
163 case TYPE_4BYTE_ABGR
:
164 case TYPE_4BYTE_ABGR_PRE
:
170 case TYPE_USHORT_GRAY
:
172 dataType
= DataBuffer
.TYPE_USHORT
;
175 cm
= new ComponentColorModel(cs
, bits
, alpha
, premultiplied
,
177 Transparency
.TRANSLUCENT
:
181 case TYPE_BYTE_BINARY
:
182 byte[] vals
= { 0, (byte) 0xff };
183 cm
= new IndexColorModel(8, 2, vals
, vals
, vals
);
185 case TYPE_BYTE_INDEXED
:
186 String msg2
= "type not implemented yet";
187 throw new UnsupportedOperationException(msg2
);
188 // FIXME: build color-cube and create color model
192 cm
.createCompatibleWritableRaster(w
, h
),
194 null, // no properties
199 public BufferedImage(int w
, int h
, int type
,
200 IndexColorModel indexcolormodel
)
202 if ((type
!= TYPE_BYTE_BINARY
) && (type
!= TYPE_BYTE_INDEXED
))
203 throw new IllegalArgumentException("type must be binary or indexed");
205 init(indexcolormodel
,
206 indexcolormodel
.createCompatibleWritableRaster(w
, h
),
207 false, // not premultiplied (guess)
208 null, // no properties
212 public BufferedImage(ColorModel colormodel
,
213 WritableRaster writableraster
,
214 boolean premultiplied
,
215 Hashtable properties
)
217 init(colormodel
, writableraster
, premultiplied
, properties
,
219 // TODO: perhaps try to identify type?
222 WritableRaster raster
;
223 ColorModel colorModel
;
224 Hashtable properties
;
225 boolean isPremultiplied
;
228 private void init(ColorModel cm
,
229 WritableRaster writableraster
,
230 boolean premultiplied
,
231 Hashtable properties
,
234 raster
= writableraster
;
236 this.properties
= properties
;
237 isPremultiplied
= premultiplied
;
241 //public void addTileObserver(TileObserver tileobserver) {}
243 public void coerceData(boolean premultiplied
)
245 colorModel
= colorModel
.coerceData(raster
, premultiplied
);
248 public WritableRaster
copyData(WritableRaster dest
)
251 dest
= raster
.createCompatibleWritableRaster();
253 int x
= dest
.getMinX();
254 int y
= dest
.getMinY();
255 int w
= dest
.getWidth();
256 int h
= dest
.getHeight();
258 // create a src child that has the right bounds...
260 raster
.createWritableChild(x
, y
, w
, h
, x
, y
,
264 // Refer to ComponentDataBlitOp for optimized data blitting:
265 ComponentDataBlitOp
.INSTANCE
.filter(src
, dest
);
269 public Graphics2D
createGraphics()
271 throw new UnsupportedOperationException("not implemented");
272 // will require a lot of effort to implement
275 public void flush() {
278 public WritableRaster
getAlphaRaster()
280 return colorModel
.getAlphaRaster(raster
);
283 public ColorModel
getColorModel()
288 public Raster
getData()
290 return copyData(null);
291 /* TODO: this might be optimized by returning the same
292 raster (not writable) as long as image data doesn't change. */
295 public Raster
getData(Rectangle rectangle
)
297 WritableRaster dest
=
298 raster
.createCompatibleWritableRaster(rectangle
);
299 return copyData(dest
);
302 public Graphics
getGraphics()
304 return createGraphics();
307 public int getHeight()
309 return raster
.getHeight();
312 public int getHeight(ImageObserver imageobserver
)
317 public int getMinTileX()
322 public int getMinTileY()
337 public int getNumXTiles()
342 public int getNumYTiles()
347 public Object
getProperty(String string
)
349 if (properties
== null)
351 return properties
.get(string
);
354 public Object
getProperty(String string
, ImageObserver imageobserver
)
356 return getProperty(string
);
360 public String
[] getPropertyNames()
366 public int getRGB(int x
, int y
)
368 Object rgbElem
= raster
.getDataElements(x
, y
,
369 null // create as needed
371 return colorModel
.getRGB(rgbElem
);
374 public int[] getRGB(int startX
, int startY
, int w
, int h
,
376 int offset
, int scanlineStride
)
378 if (rgbArray
== null)
382 00000[#######----- [ = start
383 -----########----- ] = end
385 000000000000000000 */
386 int size
= (h
-1)*scanlineStride
+ w
;
387 rgbArray
= new int[size
];
390 int endX
= startX
+ w
;
391 int endY
= startY
+ h
;
394 Opportunity for optimization by examining color models...
396 Perhaps wrap the rgbArray up in a WritableRaster with packed
397 sRGB color model and perform optimized rendering into the
400 Object rgbElem
= null;
401 for (int y
=startY
; y
<endY
; y
++)
403 int xoffset
= offset
;
404 for (int x
=startX
; x
<endX
; x
++)
407 rgbElem
= raster
.getDataElements(x
, y
, rgbElem
);
408 rgb
= colorModel
.getRGB(rgbElem
);
409 rgbArray
[xoffset
++] = rgb
;
411 offset
+= scanlineStride
;
416 public WritableRaster
getRaster()
421 public SampleModel
getSampleModel()
423 return raster
.getSampleModel();
426 public ImageProducer
getSource()
428 throw new UnsupportedOperationException("not implemented");
431 public Vector
getSources()
436 public BufferedImage
getSubimage(int x
, int y
, int w
, int h
)
438 WritableRaster subRaster
=
439 getRaster().createWritableChild(x
, y
, w
, h
, 0, 0, null);
441 return new BufferedImage(getColorModel(),
447 public Raster
getTile(int tileX
, int tileY
)
449 return getWritableTile(tileX
, tileY
);
452 public int getTileGridXOffset()
454 return 0; // according to javadocs
457 public int getTileGridYOffset()
459 return 0; // according to javadocs
462 public int getTileHeight()
464 return getHeight(); // image is one big tile
467 public int getTileWidth()
469 return getWidth(); // image is one big tile
477 public int getWidth()
479 return raster
.getWidth();
482 public int getWidth(ImageObserver imageobserver
)
487 public WritableRaster
getWritableTile(int tileX
, int tileY
)
489 isTileWritable(tileX
, tileY
); // for exception
493 private static final Point
[] tileIndices
= { new Point() };
495 public Point
[] getWritableTileIndices()
500 public boolean hasTileWriters()
505 public boolean isAlphaPremultiplied()
507 return isPremultiplied
;
510 public boolean isTileWritable(int tileX
, int tileY
)
512 if ((tileX
!= 0) || (tileY
!= 0))
513 throw new ArrayIndexOutOfBoundsException("only tile is (0,0)");
517 public void releaseWritableTile(int tileX
, int tileY
)
519 isTileWritable(tileX
, tileY
); // for exception
522 //public void removeTileObserver(TileObserver tileobserver) {}
524 public void setData(Raster src
)
526 int x
= src
.getMinX();
527 int y
= src
.getMinY();
528 int w
= src
.getWidth();
529 int h
= src
.getHeight();
531 // create a dest child that has the right bounds...
532 WritableRaster dest
=
533 raster
.createWritableChild(x
, y
, w
, h
, x
, y
,
537 // Refer to ComponentDataBlitOp for optimized data blitting:
538 ComponentDataBlitOp
.INSTANCE
.filter(src
, dest
);
541 public void setRGB(int x
, int y
, int argb
)
543 Object rgbElem
= colorModel
.getDataElements(argb
, null);
544 raster
.setDataElements(x
, y
, rgbElem
);
547 public void setRGB(int startX
, int startY
, int w
, int h
,
548 int[] argbArray
, int offset
, int scanlineStride
)
550 int endX
= startX
+ w
;
551 int endY
= startY
+ h
;
553 Object rgbElem
= null;
554 for (int y
=startY
; y
<endY
; y
++)
556 int xoffset
= offset
;
557 for (int x
=startX
; x
<endX
; x
++)
559 int argb
= argbArray
[xoffset
++];
560 rgbElem
= colorModel
.getDataElements(argb
, rgbElem
);
561 raster
.setDataElements(x
, y
, rgbElem
);
563 offset
+= scanlineStride
;
567 public String
toString()
570 return super.toString();