@@ -117,26 +117,21 @@ public class BufferedImage extends Image implements RenderedImage, Transparency
117117{
118118
119119 private static final int STATE_UNINITIALIZED = 0 ;
120- private static final int STATE_IMAGENODE_AVAIL = 1 << 0 ;
120+
121+ private static final int STATE_IMAGENODE = 1 << 0 ;
122+ private static final int STATE_RASTER = 1 << 1 ;
123+ private static final int STATE_GRAPHICS = 1 << 2 ;
124+ private static final int STATE_VIDEO = 1 << 3 ;
121125
122- private static final int STATE_RASTER_AVAIL = 1 << 2 ;
123126
124- private static final int STATE_GRAPHICS_INUSE = 1 << 3 ;
125- private static final int STATE_GRAPHICS_AVAIL = 1 << 4 ;
126-
127- private static final int STATE_HAVE_PIXELS8 = 1 << 5 ; // byte[]
128- private static final int STATE_HAVE_PIXELS32 = 1 << 6 ; // int[]
129-
130- private static final int STATE_VIDEO = 1 << 7 ;
131-
132- private static final int STATE_GRAPHICS = STATE_GRAPHICS_AVAIL | STATE_GRAPHICS_INUSE ;
133- private static final int STATE_RASTER = STATE_RASTER_AVAIL ;
127+ private static final int STATE_HAVE_PIXELS8 = 1 << 4 ; // byte[]
128+ private static final int STATE_HAVE_PIXELS32 = 1 << 5 ; // int[]
134129 private static final int STATE_HAVE_PIXELS = STATE_HAVE_PIXELS8 | STATE_HAVE_PIXELS32 ;
135130
136131 private int 秘state = STATE_UNINITIALIZED ;
137132
138- private static final String [] states = new String [] { "ImageOnly" , "RasterInUse " , "RasterAvail " , "GraphicsInUse " ,
139- "GraphicsAvail" , " 8-bitPixels" , "32-bitPixels" , "video " };
133+ private static final String [] states = new String [] { "ImageOnly" , "Raster " , "Graphics " , "Video " ,
134+ "8-bitPixels" , "32-bitPixels" };
140135
141136 public String getStateString () {
142137 int [] data = /** @j2sNative this.raster.data || */
@@ -146,7 +141,7 @@ public String getStateString() {
146141 if ((秘state & (1 << i )) != 0 )
147142 s += states [i ] + ";" ;
148143 }
149- return "rasterStolen=" + 秘isDataStolen () + " " + (s == "" ? "UN " : s ) + " unDisposedGraphicCount=" + gCount
144+ return "rasterStolen=" + 秘isDataStolen () + " " + (s == "" ? "UNINITIALIZED " : s ) + " unDisposedGraphicCount=" + gCount
150145 + " data[0]=" + (data == null ? null : Integer .toHexString (data [0 ]));
151146 }
152147
@@ -165,7 +160,7 @@ public String getStateString() {
165160 }
166161
167162 public boolean 秘haveImage () {
168- return ((秘state & STATE_IMAGENODE_AVAIL ) != 0 );
163+ return ((秘state & STATE_IMAGENODE ) != 0 );
169164 }
170165
171166 public boolean 秘haveVideo () {
@@ -184,6 +179,21 @@ public String getStateString() {
184179 boolean b = raster .dataBuffer .theTrackable .getState () == sun .java2d .StateTrackable .State .UNTRACKABLE ;
185180 return b ;
186181 }
182+
183+ /**
184+ *
185+ * @return true if data are stolen, and the raster is active, not the canvas
186+ */
187+ public boolean 秘dataStolenAndHaveRaster () {
188+ return 秘isDataStolen () && 秘haveRaster ();
189+ }
190+
191+ /**
192+ * @return data are stolen, but createGraphics() has been used last
193+ */
194+ public boolean 秘dataStolenButNoRaster () {
195+ return 秘isDataStolen () && !秘haveRaster ();
196+ }
187197
188198 /*
189199 * ImageNode means this is a JSImage specifically for an ImageIcon or was
@@ -491,7 +501,7 @@ public BufferedImage(int width, int height, int imageType) {
491501 raster = colorModel .createCompatibleWritableRaster (width , height );
492502 raster .秘setImage (this );
493503 秘pix = ((DataBufferInt ) raster .getDataBuffer ()).data ;
494- 秘state = STATE_GRAPHICS_AVAIL | STATE_HAVE_PIXELS32 | STATE_RASTER_AVAIL ;
504+ 秘state = STATE_GRAPHICS | STATE_HAVE_PIXELS32 | STATE_RASTER ;
495505 break ;
496506 case TYPE_INT_ARGB :
497507 colorModel = ColorModel .getRGBdefault ();
@@ -543,9 +553,9 @@ public BufferedImage(int width, int height, int imageType) {
543553 raster = Raster .createInterleavedRaster (DataBuffer .TYPE_BYTE , width , height , width * 4 , 4 , bOffs , null );
544554 秘pix = ((DataBufferInt ) raster .getDataBuffer ()).data ;
545555 if (秘haveVideo ()) {
546- 秘state = STATE_VIDEO | STATE_GRAPHICS_AVAIL | STATE_HAVE_PIXELS32 | STATE_RASTER_AVAIL ;
556+ 秘state = STATE_VIDEO | STATE_GRAPHICS | STATE_HAVE_PIXELS32 | STATE_RASTER ;
547557 } else {
548- 秘state = STATE_GRAPHICS_AVAIL | STATE_RASTER_AVAIL | STATE_HAVE_PIXELS8 ;
558+ 秘state = STATE_GRAPHICS | STATE_RASTER | STATE_HAVE_PIXELS8 ;
549559 }
550560 }
551561 break ;
@@ -904,11 +914,11 @@ public WritableRaster getRaster() {
904914 秘updateStateFromHTML5Canvas (0 , false );
905915 秘unsetGraphics ();
906916 }
907- 秘state |= STATE_RASTER_AVAIL ;
917+ 秘state |= STATE_RASTER ;
908918 }
909919
910920 private void 秘unsetGraphics () {
911- 秘state &= ~(STATE_GRAPHICS | STATE_IMAGENODE_AVAIL );
921+ 秘state &= ~(STATE_GRAPHICS | STATE_IMAGENODE );
912922 秘imgNode = null ;
913923 }
914924
@@ -930,6 +940,7 @@ public WritableRaster getRaster() {
930940 }
931941 return true ;
932942 default :
943+ 秘ensureRasterUpToDate ();
933944 return false ;
934945 }
935946
@@ -993,7 +1004,10 @@ public WritableRaster getAlphaRaster() {
9931004 * @see #setRGB(int, int, int, int, int[], int, int)
9941005 */
9951006 public int getRGB (int x , int y ) {
996- if (!秘isDataStolen () && (秘haveCanvas () || 秘state == STATE_UNINITIALIZED ) && 秘ensureCanGetRGBPixels ()) {
1007+ boolean isStolen = 秘isDataStolen ();
1008+ if (isStolen && !秘haveRaster ())
1009+ 秘ensureRasterUpToDate ();
1010+ if (!isStolen && (秘haveCanvas () || 秘state == STATE_UNINITIALIZED ) && 秘ensureCanGetRGBPixels ()) {
9971011 return ((int []) 秘pix )[y * this .width + x ];
9981012 }
9991013 return colorModel .getRGB (raster .getDataElements (x , y , null ));
@@ -1030,7 +1044,10 @@ public int getRGB(int x, int y) {
10301044 * @see #setRGB(int, int, int, int, int[], int, int)
10311045 */
10321046 public int [] getRGB (int startX , int startY , int w , int h , int [] rgbArray , int offset , int scansize ) {
1033- if (!秘isDataStolen () && (秘haveCanvas () || 秘state == STATE_IMAGENODE_AVAIL || 秘state == STATE_UNINITIALIZED )
1047+ boolean isStolen = 秘isDataStolen ();
1048+ if (isStolen && !秘haveRaster ())
1049+ 秘ensureRasterUpToDate ();
1050+ if (!isStolen && (秘haveCanvas () || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED )
10341051 && 秘ensureCanGetRGBPixels ()) {
10351052 int [] pixels = (int []) 秘pix ;
10361053 if (pixels != null ) {
@@ -1085,7 +1102,7 @@ public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int of
10851102 }
10861103 }
10871104 秘state |= STATE_RASTER ;
1088- 秘state &= ~(STATE_GRAPHICS_AVAIL | STATE_IMAGENODE_AVAIL );
1105+ 秘state &= ~(STATE_GRAPHICS | STATE_IMAGENODE );
10891106 return rgbArray ;
10901107 }
10911108
@@ -1107,7 +1124,10 @@ public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int of
11071124 * @see #getRGB(int, int, int, int, int[], int, int)
11081125 */
11091126 public synchronized void setRGB (int x , int y , int rgb ) {
1110- if (!秘isDataStolen () && (秘haveCanvas () || 秘state == STATE_IMAGENODE_AVAIL || 秘state == STATE_UNINITIALIZED )
1127+ boolean isStolen = 秘isDataStolen ();
1128+ if (isStolen && !秘haveRaster ())
1129+ 秘ensureRasterUpToDate ();
1130+ if (!isStolen && (秘haveCanvas () || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED )
11111131 && 秘ensureCanGetRGBPixels ()) {
11121132 int [] pixels = (int []) 秘pix ;
11131133 pixels [y * this .width + x ] = rgb ;
@@ -1148,7 +1168,10 @@ public synchronized void setRGB(int x, int y, int rgb) {
11481168 * @see #getRGB(int, int, int, int, int[], int, int)
11491169 */
11501170 public void setRGB (int startX , int startY , int w , int h , int [] rgbArray , int offset , int scansize ) {
1151- if (!秘isDataStolen () && (秘haveCanvas () || 秘state == STATE_IMAGENODE_AVAIL || 秘state == STATE_UNINITIALIZED )
1171+ boolean isStolen = 秘isDataStolen ();
1172+ if (isStolen && !秘haveRaster ())
1173+ 秘ensureRasterUpToDate ();
1174+ if (!isStolen && (秘haveCanvas () || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED )
11521175 && 秘ensureCanGetRGBPixels ()) {
11531176 int [] pixels = (int []) 秘pix ;
11541177 int width = this .width ;
@@ -1168,7 +1191,7 @@ public void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int off
11681191 }
11691192 }
11701193 秘unsetGraphics ();
1171- 秘state |= STATE_RASTER_AVAIL ;
1194+ 秘state |= STATE_RASTER ;
11721195 }
11731196
11741197 /**
@@ -1331,7 +1354,7 @@ public Graphics2D createGraphics() {
13311354 秘g = new JSGraphics2D (秘canvas );
13321355 }
13331356
1334- if (秘haveRaster () && 秘isDataStolen ()) {
1357+ if (秘dataStolenAndHaveRaster ()) {
13351358 // we need to draw the image now, because it might
13361359 // have pixels. Note that Java actually does not
13371360 // allow creating a Graphics from MemoryImageSource
@@ -1348,7 +1371,7 @@ public Graphics2D createGraphics() {
13481371 gCount ++;
13491372 秘g .image = this ;
13501373
1351- 秘state = STATE_GRAPHICS_INUSE ;
1374+ 秘state = STATE_GRAPHICS ;
13521375
13531376 Graphics2D g2d = (Graphics2D ) (Object ) 秘g ;
13541377 if (秘component != null ) {
@@ -1361,17 +1384,30 @@ public Graphics2D createGraphics() {
13611384
13621385 public void 秘graphicsDisposed () {
13631386 gCount = Math .max (0 , gCount - 1 );
1364- 秘state = ( gCount == 0 ? STATE_GRAPHICS_AVAIL : STATE_GRAPHICS_INUSE ) ;
1387+ 秘state = STATE_GRAPHICS ;
13651388 }
13661389
1390+ /**
1391+ * If data are stolen and we don't have raster, because createImage() or getImage()
1392+ * has been called, recreate the raster.
1393+ *
1394+ * If we have a raster but no pixels, create the pixels.
1395+ *
1396+ * Then create the canvas.
1397+ *
1398+ */
13671399 @ Override
13681400 public void flush () {
1369- if (秘isDataStolen ())
1370- 秘state |= STATE_RASTER ;
1401+ boolean isStolen = 秘isDataStolen ();
1402+ boolean haveRaster = 秘haveRaster ();
1403+ if (isStolen && !haveRaster )
1404+ 秘ensureRasterUpToDate (); // will set STATE_RASTER
13711405 if (秘haveRaster () && 秘pix == null ) {
13721406 秘getPixelsFromRaster (0 );
13731407 }
13741408 秘getImageGraphic ();
1409+ if (isStolen || haveRaster )
1410+ 秘state |= STATE_RASTER ;
13751411 while (gCount > 0 && --gCount >= 0 )
13761412 秘g .dispose ();
13771413 }
@@ -1401,7 +1437,7 @@ public void _setImageNode(Object node, boolean async) {
14011437// Object pixels = 秘pix;
14021438 秘imgNode = (DOMNode ) node ;
14031439 if (秘haveVideo ()) {
1404- 秘state |= STATE_GRAPHICS | STATE_IMAGENODE_AVAIL ;
1440+ 秘state |= STATE_GRAPHICS | STATE_IMAGENODE ;
14051441 } else {
14061442 if (DOMNode .getAttr (node , "tagName" ) == "VIDEO" ) {
14071443 // from HTML5Video via HTML5Canvas
@@ -1412,9 +1448,9 @@ public void _setImageNode(Object node, boolean async) {
14121448 秘getImageGraphic ().dispose ();
14131449 }
14141450 秘canvas .getContext ("2d" ).drawImage (秘imgNode , 0 , 0 , width , height );
1415- 秘state = STATE_VIDEO | STATE_GRAPHICS | STATE_IMAGENODE_AVAIL ;
1451+ 秘state = STATE_VIDEO | STATE_GRAPHICS | STATE_IMAGENODE ;
14161452 } else {
1417- 秘state = STATE_GRAPHICS | STATE_IMAGENODE_AVAIL ;
1453+ 秘state = STATE_GRAPHICS | STATE_IMAGENODE ;
14181454 }
14191455 }
14201456
@@ -2024,26 +2060,24 @@ public int getTransparency() {
20242060 case TYPE_BYTE_GRAY :
20252061 toByteGray (data , ((DataBufferByte ) buf ).data );
20262062 break ;
2027- case TYPE_BYTE_BINARY :
2028- toByteBinary (data , ((DataBufferByte ) buf ).data );
2029- break ;
20302063 case TYPE_USHORT_GRAY :
20312064 toUShortGray (data , ((DataBufferShort ) buf ).data );
20322065 break ;
2066+ case TYPE_BYTE_BINARY :
2067+ case TYPE_BYTE_INDEXED :
20332068 case TYPE_USHORT_565_RGB :
20342069 case TYPE_USHORT_555_RGB :
2035- case TYPE_BYTE_INDEXED :
2036- JSUtil .notImplemented ("BufferedImage setPixels for type " + imageType );
2070+ toRaster (data );
20372071 break ;
20382072 }
20392073 if (秘pix == null ) {
20402074 toIntARGB (data , (int []) (秘pix = new int [data .length >> 2 ]));
20412075 }
2042- 秘state = STATE_GRAPHICS_AVAIL | STATE_RASTER_AVAIL ;
2076+ 秘state = STATE_GRAPHICS | STATE_RASTER ;
20432077 秘state |= (haveHTML5Pixels ? STATE_HAVE_PIXELS8 : STATE_HAVE_PIXELS32 );
20442078 秘imgNode = (andSetImageNode ? canvas : null );
20452079 if (andSetImageNode ) {
2046- 秘state |= STATE_IMAGENODE_AVAIL ;
2080+ 秘state |= STATE_IMAGENODE ;
20472081 }
20482082 }
20492083
@@ -2094,8 +2128,19 @@ private void toByte3BGR(byte[] ctxData, byte[] buf) {
20942128 }
20952129 }
20962130
2097- private void toByteBinary (byte [] ctxData , byte [] buf ) {
2098- JSUtil .notImplemented (null );
2131+ /**
2132+ * This model involves two colors. red/blue for instance.
2133+ * The bits are packed into the raster bytes
2134+ *
2135+ * @param ctxData
2136+ * @param buf
2137+ */
2138+ private void toRaster (byte [] ctxData ) {
2139+ ColorModel cm = getColorModel ();
2140+ int [] iData = new int [ctxData .length >> 2 ];
2141+ for (int i = 0 , pt = 0 , n = ctxData .length ; i < n ; i += 4 )
2142+ iData [pt ++] = cm .getDataElement ((int [])(Object )ctxData , i );
2143+ raster .setDataElements (0 , 0 , width , height , iData );
20992144 }
21002145
21012146 private void toUShortGray (byte [] ctxData , short [] buf ) {
@@ -2298,7 +2343,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
22982343 */
22992344 public DOMNode 秘getImageNode (int mode ) {
23002345 if (秘isDataStolen ())
2301- 秘state |= STATE_RASTER_AVAIL ;
2346+ 秘state |= STATE_RASTER ;
23022347
23032348 // If we have raster data and are not forcing, return the canvas if it exists.
23042349 // If we we have no raster data and are not forcing, force the issue anyway
@@ -2308,7 +2353,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
23082353 default :
23092354 case GET_IMAGE_ALLOW_NULL :
23102355 return 秘haveImage () ? 秘imgNode
2311- : 秘isDataStolen () ? null
2356+ : 秘dataStolenAndHaveRaster () ? null
23122357 : (DOMNode ) (秘haveRaster () || 秘canvas != null ? 秘canvas : createImageNode ());
23132358 case GET_IMAGE_FOR_ICON :
23142359 if (!秘isDataStolen ())
@@ -2348,7 +2393,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
23482393 /**
23492394 * argb.img = this;
23502395 */
2351- 秘state = STATE_GRAPHICS_AVAIL ;
2396+ 秘state = STATE_GRAPHICS ;
23522397 if (argb .length == 秘wxh ) {
23532398 秘state |= STATE_HAVE_PIXELS32 ;
23542399 switch (imageType ) {
@@ -2357,7 +2402,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
23572402 case TYPE_INT_ARGB :
23582403 ((DataBufferInt ) raster .dataBuffer ).data = ((IntegerComponentRaster ) raster ).data = argb ;
23592404 raster .秘setStable (true );
2360- 秘state |= STATE_RASTER_AVAIL ;
2405+ 秘state |= STATE_RASTER ;
23612406 break ;
23622407 default :
23632408 break ;
0 commit comments