Skip to content

Commit 8c66e9f

Browse files
hansonrhansonr
authored andcommitted
BufferedImage; JSGraphics2D
Better detection and tracking of external editing of BufferedImage data buffers. proper scaling of images using drawImage(img, <destination rect> <source rect>, imageObserver
1 parent 1359750 commit 8c66e9f

File tree

9 files changed

+62
-22
lines changed

9 files changed

+62
-22
lines changed
283 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20210610072922
1+
20210610220339
283 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20210610072922
1+
20210610220339
283 Bytes
Binary file not shown.

sources/net.sf.j2s.java.core/src/java/awt/image/BufferedImage.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ public class BufferedImage extends Image implements RenderedImage, Transparency
129129

130130
private int 秘state = STATE_UNINITIALIZED;
131131

132+
private boolean 秘haveNewPixels;
133+
132134
private static final String[] states = new String[] { "ImageOnly", "Raster", "Graphics", "Video", "8-bitPixels",
133135
"32-bitPixels" };
134136

@@ -140,7 +142,7 @@ public String getStateString() {
140142
if ((秘state & (1 << i)) != 0)
141143
s += states[i] + ";";
142144
}
143-
return "rasterStolen=" + 秘isDataStolen() + " " + (s == "" ? "UNINITIALIZED" : s) + " unDisposedGraphicCount="
145+
return "rasterDirty=" + 秘isRasterDirty(false) + " " + (s == "" ? "UNINITIALIZED" : s) + " unDisposedGraphicCount="
144146
+ gCount + " data[0]=" + (data == null ? null : Integer.toHexString(data[0]));
145147
}
146148

@@ -174,7 +176,10 @@ public String getStateString() {
174176
return ((秘state & STATE_GRAPHICS) != 0);
175177
}
176178

177-
public boolean 秘isDataStolen() {
179+
boolean 秘isRasterDirty(boolean doReset) {
180+
if (raster.dataBuffer.theTrackable.秘isDirty(doReset)) {
181+
return true;
182+
}
178183
boolean b = raster.dataBuffer.theTrackable.getState() == sun.java2d.StateTrackable.State.UNTRACKABLE;
179184
return b;
180185
}
@@ -184,14 +189,16 @@ public String getStateString() {
184189
* @return true if data are stolen, and the raster is active, not the canvas
185190
*/
186191
public boolean 秘dataStolenAndHaveRaster() {
187-
return 秘isDataStolen() && 秘haveRaster();
192+
boolean b = 秘haveNewPixels || 秘isRasterDirty(false) && 秘haveRaster();
193+
秘haveNewPixels = false;
194+
return b;
188195
}
189196

190197
/**
191198
* @return data are stolen, but createGraphics() has been used last
192199
*/
193200
public boolean 秘dataStolenButNoRaster() {
194-
return 秘isDataStolen() && !秘haveRaster();
201+
return 秘isRasterDirty(false) && !秘haveRaster();
195202
}
196203

197204
/*
@@ -910,7 +917,7 @@ public WritableRaster getRaster() {
910917
}
911918

912919
void 秘ensureRasterUpToDate() {
913-
if (秘isDataStolen() || !秘haveRaster() && 秘state != STATE_UNINITIALIZED) {
920+
if (秘isRasterDirty(false) || !秘haveRaster() && 秘state != STATE_UNINITIALIZED) {
914921
秘updateStateFromHTML5Canvas(0, false);
915922
秘unsetGraphics();
916923
}
@@ -1004,7 +1011,7 @@ public WritableRaster getAlphaRaster() {
10041011
* @see #setRGB(int, int, int, int, int[], int, int)
10051012
*/
10061013
public int getRGB(int x, int y) {
1007-
boolean isStolen = 秘isDataStolen();
1014+
boolean isStolen = 秘isRasterDirty(false);
10081015
if (isStolen && !秘haveRaster())
10091016
秘ensureRasterUpToDate();
10101017
if (!isStolen && (秘haveCanvas() || 秘state == STATE_UNINITIALIZED) && 秘ensureCanGetRGBPixels()) {
@@ -1044,7 +1051,7 @@ public int getRGB(int x, int y) {
10441051
* @see #setRGB(int, int, int, int, int[], int, int)
10451052
*/
10461053
public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) {
1047-
boolean isStolen = 秘isDataStolen();
1054+
boolean isStolen = 秘isRasterDirty(false);
10481055
if (isStolen && !秘haveRaster())
10491056
秘ensureRasterUpToDate();
10501057
if (!isStolen && (秘haveCanvas() || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED)
@@ -1124,7 +1131,7 @@ public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int of
11241131
* @see #getRGB(int, int, int, int, int[], int, int)
11251132
*/
11261133
public synchronized void setRGB(int x, int y, int rgb) {
1127-
boolean isStolen = 秘isDataStolen();
1134+
boolean isStolen = 秘isRasterDirty(false);
11281135
if (isStolen && !秘haveRaster())
11291136
秘ensureRasterUpToDate();
11301137
if (!isStolen && (秘haveCanvas() || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED)
@@ -1168,7 +1175,7 @@ public synchronized void setRGB(int x, int y, int rgb) {
11681175
* @see #getRGB(int, int, int, int, int[], int, int)
11691176
*/
11701177
public void setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) {
1171-
boolean isStolen = 秘isDataStolen();
1178+
boolean isStolen = 秘isRasterDirty(false);
11721179
if (isStolen && !秘haveRaster())
11731180
秘ensureRasterUpToDate();
11741181
if (!isStolen && (秘haveCanvas() || 秘state == STATE_IMAGENODE || 秘state == STATE_UNINITIALIZED)
@@ -1398,7 +1405,7 @@ public Graphics2D createGraphics() {
13981405
*/
13991406
@Override
14001407
public void flush() {
1401-
boolean isStolen = 秘isDataStolen();
1408+
boolean isStolen = 秘isRasterDirty(false);
14021409
boolean haveRaster = 秘haveRaster();
14031410
if (isStolen && !haveRaster)
14041411
秘ensureRasterUpToDate(); // will set STATE_RASTER
@@ -2199,7 +2206,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
21992206
}
22002207

22012208
/**
2202-
* For JSGraphics2D only.
2209+
* Called by JSGraphics2D only in a last-minute check to see if our raster hold new data
22032210
*
22042211
* @return a int[] array that is actually bytes [b g r a...] in the form the
22052212
* HTML5 canvas can process directly.
@@ -2208,6 +2215,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
22082215
public Object get秘pixFromRaster() {
22092216
if (!秘haveRaster())
22102217
return null;
2218+
秘isRasterDirty(true); // rest dirty
22112219
SunWritableRaster r = (SunWritableRaster) raster;
22122220
switch (imageType) {
22132221
case TYPE_INT_RGB:
@@ -2219,6 +2227,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
22192227
case TYPE_4BYTE_HTML5:
22202228
return 秘pix;
22212229
}
2230+
秘haveNewPixels = true;
22222231
return 秘getPixelsFromRaster(8);
22232232
}
22242233

@@ -2233,12 +2242,16 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
22332242
*/
22342243
private Object 秘getPixelsFromRaster(int nbits) {
22352244
// Coerse byte[] to int[] for SwingJS
2245+
秘isRasterDirty(true); // reset
2246+
boolean wasUntrackable = (raster.dataBuffer.theTrackable.getState() == sun.java2d.StateTrackable.State.UNTRACKABLE);
22362247
int n = 秘wxh;
22372248
byte[] b;
22382249
秘state &= ~STATE_HAVE_PIXELS;
22392250
switch (imageType) {
22402251
case TYPE_4BYTE_HTML5:
22412252
b = ((DataBufferByte) raster.getDataBuffer()).getData();
2253+
if (!wasUntrackable)
2254+
raster.秘setStable(true);
22422255
if (nbits == 32) {
22432256
int[] data = new int[n];
22442257
toIntARGB(b, data, 0xFF000000);
@@ -2251,7 +2264,10 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
22512264
case TYPE_INT_ARGB:
22522265
if (nbits == 32) {
22532266
秘state |= STATE_HAVE_PIXELS32;
2254-
return 秘pix = ((DataBufferInt) raster.getDataBuffer()).getData();
2267+
秘pix = ((DataBufferInt) raster.getDataBuffer()).getData();
2268+
if (!wasUntrackable)
2269+
raster.秘setStable(true);
2270+
return 秘pix;
22552271
}
22562272
break;
22572273
}
@@ -2346,7 +2362,7 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
23462362
* is not a raster image, or create its image
23472363
*/
23482364
public DOMNode 秘getImageNode(int mode) {
2349-
if (秘isDataStolen())
2365+
if (秘isRasterDirty(false))
23502366
秘state |= STATE_RASTER;
23512367

23522368
// If we have raster data and are not forcing, return the canvas if it exists.
@@ -2360,12 +2376,13 @@ private void toInt3BGR(byte[] ctxData, int[] buf) {
23602376
: 秘dataStolenAndHaveRaster() ? null
23612377
: (DOMNode) (秘haveRaster() || 秘canvas != null ? 秘canvas : createImageNode());
23622378
case GET_IMAGE_FOR_ICON:
2363-
if (!秘isDataStolen())
2379+
if (!秘isRasterDirty(false))
23642380
return (DOMNode) (秘canvas != null && !秘haveVideo() ? 秘canvas
23652381
: 秘imgNode != null ? 秘copyImageNode() : createImageNode());
23662382
// $fall-through$
23672383
case GET_IMAGE_FROM_RASTER:
23682384
// we are forcing
2385+
秘haveNewPixels = true;
23692386
秘getPixelsFromRaster(0);
23702387
秘g = null;
23712388
秘getImageGraphic();

sources/net.sf.j2s.java.core/src/sun/awt/image/SunWritableRaster.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,28 +128,29 @@ public static void markDirty(WritableRaster wr) {
128128
// SurfaceData.getPrimarySurfaceData(img).markDirty();
129129
// }
130130
//
131-
private StateTrackableDelegate theTrackable;
131+
// private StateTrackableDelegate theTrackable;
132132

133133
public SunWritableRaster(SampleModel sampleModel, Point origin) {
134134
super(sampleModel, origin);
135-
theTrackable = stealTrackable(dataBuffer);
135+
// theTrackable = stealTrackable(dataBuffer);
136136
}
137137

138138
public SunWritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) {
139139
super(sampleModel, dataBuffer, origin);
140-
theTrackable = stealTrackable(dataBuffer);
140+
// theTrackable = stealTrackable(dataBuffer);
141141
}
142142

143143
public SunWritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion,
144144
Point sampleModelTranslate, WritableRaster parent) {
145145
super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent);
146-
theTrackable = stealTrackable(dataBuffer);
146+
// theTrackable = stealTrackable(dataBuffer);
147147
}
148148

149149
/**
150150
* Mark the TrackableDelegate of the associated DataBuffer dirty.
151151
*/
152152
public final void markDirty() {
153-
theTrackable.markDirty();
153+
stealTrackable(dataBuffer).markDirty();
154+
// theTrackable.markDirty();
154155
}
155156
}

sources/net.sf.j2s.java.core/src/sun/java2d/StateTrackableDelegate.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public static StateTrackableDelegate createInstance(State state) {
8181
}
8282

8383
private State theState;
84-
StateTracker theTracker; // package private for easy access from tracker
84+
public /** SwingJS needs this */ StateTracker theTracker; // package private for easy access from tracker
8585
private int numDynamicAgents;
8686

8787
/**
@@ -247,5 +247,22 @@ protected synchronized void removeDynamicAgent() {
247247
*/
248248
public final void markDirty() {
249249
theTracker = null;
250+
isDirty = true;
251+
}
252+
253+
private boolean isDirty;
254+
/**
255+
* SwingJS we have the problem that we also have a canvas to worry about. This checks that
256+
* the raster data has been touched within the internal DataBuffer methods. It then clears
257+
* that.
258+
* @param doReset
259+
*
260+
* @return
261+
*/
262+
public boolean 秘isDirty(boolean doReset) {
263+
boolean isDirty = this.isDirty;
264+
if (doReset)
265+
this.isDirty = false;
266+
return isDirty;
250267
}
251268
}

sources/net.sf.j2s.java.core/src/swingjs/JSGraphics2D.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,11 @@ public boolean drawImage(Image img, int x, int y, int width, int height, ImageOb
593593
if (img != null) {
594594
DOMNode imgNode = ((BufferedImage) img).秘getImageNode(BufferedImage.GET_IMAGE_ALLOW_NULL);
595595
if (imgNode == null) {
596+
if (width != img.getWidth(null) || height != img.getHeight(null)) {
597+
// scaled image
598+
drawImage(img, x, y, x + width, y + width, 0, 0, img.getWidth(null), img.getHeight(null), observer);
599+
return true;
600+
}
596601
drawImagePriv(img, x, y, width, height, observer);
597602
} else {
598603
ctx.drawImage(imgNode, x, y, width, height);

0 commit comments

Comments
 (0)