Skip to content

Commit 5a118f9

Browse files
committed
implements BufferedImage.TYPE_4BYTE_HTML5
- [r g b a...] as returned from canvas ctx, so it can be copied straight into that UInt8 array anding with 0xFF Vastly speeds up image creation and use when no actual graphics is created.
1 parent e6fe1a8 commit 5a118f9

File tree

10 files changed

+122
-80
lines changed

10 files changed

+122
-80
lines changed
365 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20200227134114
1+
20200228164908
365 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20200227134114
1+
20200228164908
365 Bytes
Binary file not shown.

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

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public class BufferedImage extends Image implements RenderedImage, Transparency
149149
* set to true if pixels have been generated from an HTML5 canvas
150150
*
151151
*/
152-
private boolean 秘haveCanvasPixels;
152+
private boolean 秘havePixels;
153153

154154
/**
155155
* the HTML5 canvas that originated 秘pix or that was created from them.
@@ -240,6 +240,15 @@ public class BufferedImage extends Image implements RenderedImage, Transparency
240240
*/
241241
public static final int TYPE_3BYTE_BGR = 5;
242242

243+
/**
244+
* Represents an image with 8-bit RGBA color components with the colors Blue,
245+
* Green, and Red stored in 3 bytes and 1 byte of alpha. The image has a
246+
* <code>ComponentColorModel</code> with alpha. The color data in this image is
247+
* considered not to be premultiplied with alpha. The byte data is interleaved
248+
* in a single byte array in the order B, G, R, A from lower to higher byte
249+
* addresses within each pixel.
250+
*/
251+
public static final int TYPE_4BYTE_HTML5 = -6;
243252
/**
244253
* Represents an image with 8-bit RGBA color components with the colors Blue,
245254
* Green, and Red stored in 3 bytes and 1 byte of alpha. The image has a
@@ -433,6 +442,18 @@ public BufferedImage(int width, int height, int imageType) {
433442
}
434443
break;
435444

445+
case TYPE_4BYTE_HTML5: { // [r g b a...]
446+
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
447+
int[] nBits = { 8, 8, 8, 8 };
448+
int[] bOffs = { 0, 1, 2, 3 };
449+
colorModel = new ComponentColorModel(cs, nBits, true, false, Transparency.TRANSLUCENT,
450+
DataBuffer.TYPE_BYTE);
451+
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height, width * 4, 4, bOffs, null);
452+
秘pix = ((DataBufferInt) raster.getDataBuffer()).data;
453+
this.秘havePixels = true;
454+
}
455+
break;
456+
436457
case TYPE_4BYTE_ABGR_PRE: {
437458
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
438459
int[] nBits = { 8, 8, 8, 8 };
@@ -882,7 +903,7 @@ public int[] getRGB(int startX, int startY, int w, int h, int[] rgbArray, int of
882903
* @return true if pixels had to be set
883904
*/
884905
public boolean 秘ensureHavePixels(boolean andSetImageNode) {
885-
if (!秘haveCanvasPixels && (秘imgNode != null || 秘g != null)) {
906+
if (!秘havePixels && (秘imgNode != null || 秘g != null)) {
886907
秘setPixelsFromHTML5Canavas(andSetImageNode);
887908
return true;
888909
}
@@ -929,8 +950,7 @@ public int[] getRangeRGB(int startX, int startY, int w, int h, int[] rgbArray, i
929950
* @see #getRGB(int, int, int, int, int[], int, int)
930951
*/
931952
public synchronized void setRGB(int x, int y, int rgb) {
932-
if (秘ensureHavePixels(false))
933-
;
953+
if (秘ensureHavePixels(false));
934954
int[] pixels = (秘pix == null ? 秘pixSaved : 秘pix);
935955
pixels[y * this.width + x] = rgb;
936956
}
@@ -1673,7 +1693,7 @@ public void setImageFromHTML5Canvas(JSGraphics2D g) {
16731693
if (秘pix == null)
16741694
toIntARGB(data, 秘pix = new int[data.length >> 2]);
16751695
秘imgNode = (andSetImgNode ? canvas : null);
1676-
秘haveCanvasPixels = true;
1696+
秘havePixels = true;
16771697
}
16781698

16791699
/**
@@ -1752,7 +1772,7 @@ public void flush() {
17521772
// call this method after drawing to ensure that
17531773
// pixels are recreated from the HTML5 canvas
17541774
秘pix = null;
1755-
秘haveCanvasPixels = false;
1775+
秘havePixels = false;
17561776
}
17571777

17581778
/**
@@ -1806,6 +1826,7 @@ public Graphics2D getImageGraphic() {
18061826
case TYPE_INT_ARGB:
18071827
case TYPE_INT_ARGB_PRE:
18081828
case TYPE_4BYTE_ABGR:
1829+
case TYPE_4BYTE_HTML5:
18091830
case TYPE_4BYTE_ABGR_PRE:
18101831
return false;
18111832
case TYPE_INT_RGB:
@@ -1859,27 +1880,33 @@ public Graphics2D getImageGraphic() {
18591880
*/
18601881
private int[] 秘getPixelsFromRaster() {
18611882
int n = width * height;
1883+
if (imageType == TYPE_4BYTE_HTML5)
1884+
return 秘pix;
18621885
if (秘pix == null || 秘pix.length != n * 4)
18631886
秘pix = new int[n * 4];
18641887
ColorModel cm = getColorModel();
18651888
boolean isPacked = cm instanceof PackedColorModel;
1866-
int nc = cm.getNumComponents();
1867-
int[] a = new int[isPacked ? n : n * nc];
1868-
getRaster().getPixels(0, 0, width, height, a);
18691889
int[] p = 秘pix;
18701890
if (isPacked) {
1891+
int[] a = new int[n];
18711892
for (int i = 0, pt = 0; i < n; i++, pt += 4) {
18721893
cm.getComponents(a[i], p, pt);
18731894
}
18741895
} else {
1875-
int[] pixel = new int[nc];
1876-
for (int i = 0, apt = 0, pt = 0; i < n; i++, pt += 4) {
1877-
for (int j = 0; j < nc; j++)
1878-
pixel[j] = a[apt++];
1879-
cm.getComponents(pixel, p, pt);
1880-
if (nc < 4)
1881-
p[pt + 3] = 0xFF;
1882-
}
1896+
int nc = cm.getNumComponents();
1897+
getRaster().getPixels(0, 0, width, height, 秘pix);
1898+
switch (nc) {
1899+
case 3:
1900+
for (int i = n * 4, j = n * 3; --i >= 0;) {
1901+
if (i % 4 == 3)
1902+
p[i--] = 0xFF;
1903+
p[i] = p[--j];
1904+
}
1905+
break;
1906+
case 4:
1907+
getRaster().getPixels(0, 0, width, height, 秘pix);
1908+
break;
1909+
}
18831910
}
18841911
return p;
18851912
}
@@ -1894,6 +1921,8 @@ public Graphics2D getImageGraphic() {
18941921
*/
18951922

18961923
public DOMNode 秘getImageNode() {
1924+
if (imageType == TYPE_4BYTE_HTML5)
1925+
return null;
18971926
Object node = (秘canvas != null ? 秘canvas : 秘imgNode);
18981927
if (node == null)
18991928
node = JSGraphicsCompositor.createImageNode(this);
@@ -1914,7 +1943,7 @@ else if (秘userRaster) {
19141943
*/
19151944
protected void 秘setPixels(int[] argb) {
19161945
秘pix = argb;
1917-
秘haveCanvasPixels = true;
1946+
秘havePixels = true;
19181947
}
19191948

19201949

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

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public DirectColorModel(int bits, int rmask, int gmask,
186186
bits, rmask, gmask, bmask, amask, false,
187187
amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT,
188188
ColorModel.getDefaultTransferType(bits));
189-
setFields();
189+
// SwingJS for native code only setFields();
190190
}
191191

192192
/**
@@ -238,28 +238,28 @@ public DirectColorModel(ColorSpace space, int bits, int rmask,
238238
isAlphaPremultiplied,
239239
amask == 0 ? Transparency.OPAQUE : Transparency.TRANSLUCENT,
240240
transferType);
241-
// SwingJS if (ColorModel.isLinearRGBspace(colorSpace)) {
242-
// is_LinearRGB = true;
243-
// if (maxBits <= 8) {
244-
// lRGBprecision = 8;
245-
// tosRGB8LUT = ColorModel.getLinearRGB8TosRGB8LUT();
246-
// fromsRGB8LUT8 = ColorModel.getsRGB8ToLinearRGB8LUT();
247-
// } else {
248-
// lRGBprecision = 16;
249-
// tosRGB8LUT = ColorModel.getLinearRGB16TosRGB8LUT();
250-
// fromsRGB8LUT16 = ColorModel.getsRGB8ToLinearRGB16LUT();
251-
// }
252-
// } else if (!is_sRGB) {
253-
// for (int i = 0; i < 3; i++) {
254-
// // super constructor checks that space is TYPE_RGB
255-
// // check here that min/max are all 0.0/1.0
256-
// if ((space.getMinValue(i) != 0.0f) ||
257-
// (space.getMaxValue(i) != 1.0f)) {
258-
// throw new IllegalArgumentException(
259-
// "Illegal min/max RGB component value");
260-
// }
261-
// }
262-
// }
241+
if (ColorModel.isLinearRGBspace(colorSpace)) {
242+
is_LinearRGB = true;
243+
if (maxBits <= 8) {
244+
lRGBprecision = 8;
245+
tosRGB8LUT = ColorModel.getLinearRGB8TosRGB8LUT();
246+
fromsRGB8LUT8 = ColorModel.getsRGB8ToLinearRGB8LUT();
247+
} else {
248+
lRGBprecision = 16;
249+
tosRGB8LUT = ColorModel.getLinearRGB16TosRGB8LUT();
250+
fromsRGB8LUT16 = ColorModel.getsRGB8ToLinearRGB16LUT();
251+
}
252+
} else if (!is_sRGB) {
253+
for (int i = 0; i < 3; i++) {
254+
// super constructor checks that space is TYPE_RGB
255+
// check here that min/max are all 0.0/1.0
256+
if ((space.getMinValue(i) != 0.0f) ||
257+
(space.getMaxValue(i) != 1.0f)) {
258+
throw new IllegalArgumentException(
259+
"Illegal min/max RGB component value");
260+
}
261+
}
262+
}
263263
// setFields();
264264
}
265265

@@ -1392,32 +1392,32 @@ public boolean isCompatibleRaster(Raster raster) {
13921392
return (raster.getTransferType() == transferType);
13931393
}
13941394

1395-
private void setFields() {
1396-
// Set the private fields
1397-
// REMIND: Get rid of these from the native code
1398-
red_mask = maskArray[0];
1399-
red_offset = maskOffsets[0];
1400-
green_mask = maskArray[1];
1401-
green_offset = maskOffsets[1];
1402-
blue_mask = maskArray[2];
1403-
blue_offset = maskOffsets[2];
1404-
if (nBits[0] < 8) {
1405-
red_scale = (1 << nBits[0]) - 1;
1406-
}
1407-
if (nBits[1] < 8) {
1408-
green_scale = (1 << nBits[1]) - 1;
1409-
}
1410-
if (nBits[2] < 8) {
1411-
blue_scale = (1 << nBits[2]) - 1;
1412-
}
1413-
if (supportsAlpha) {
1414-
alpha_mask = maskArray[3];
1415-
alpha_offset = maskOffsets[3];
1416-
if (nBits[3] < 8) {
1417-
alpha_scale = (1 << nBits[3]) - 1;
1418-
}
1419-
}
1420-
}
1395+
// private void setFields() {
1396+
// // Set the private fields
1397+
// // REMIND: Get rid of these from the native code
1398+
// red_mask = maskArray[0];
1399+
// red_offset = maskOffsets[0];
1400+
// green_mask = maskArray[1];
1401+
// green_offset = maskOffsets[1];
1402+
// blue_mask = maskArray[2];
1403+
// blue_offset = maskOffsets[2];
1404+
// if (nBits[0] < 8) {
1405+
// red_scale = (1 << nBits[0]) - 1;
1406+
// }
1407+
// if (nBits[1] < 8) {
1408+
// green_scale = (1 << nBits[1]) - 1;
1409+
// }
1410+
// if (nBits[2] < 8) {
1411+
// blue_scale = (1 << nBits[2]) - 1;
1412+
// }
1413+
// if (supportsAlpha) {
1414+
// alpha_mask = maskArray[3];
1415+
// alpha_offset = maskOffsets[3];
1416+
// if (nBits[3] < 8) {
1417+
// alpha_scale = (1 << nBits[3]) - 1;
1418+
// }
1419+
// }
1420+
// }
14211421

14221422
/**
14231423
* Returns a <code>String</code> that represents this

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,15 @@
3535

3636

3737
package java.awt.image;
38-
import swingjs.JSUtil;
39-
import swingjs.api.Interface;
40-
import java.awt.Rectangle;
4138
import java.awt.Point;
39+
import java.awt.Rectangle;
4240

41+
import sun.awt.image.ByteBandedRaster;
4342
import sun.awt.image.ByteInterleavedRaster;
44-
import sun.awt.image.ShortInterleavedRaster;
43+
import sun.awt.image.BytePackedRaster;
4544
import sun.awt.image.IntegerInterleavedRaster;
46-
import sun.awt.image.ByteBandedRaster;
4745
import sun.awt.image.ShortBandedRaster;
48-
import sun.awt.image.BytePackedRaster;
46+
import sun.awt.image.ShortInterleavedRaster;
4947
import sun.awt.image.SunWritableRaster;
5048

5149
/**
@@ -127,7 +125,7 @@
127125
*/
128126
public class Raster {
129127

130-
private BufferedImage image;
128+
private BufferedImage image; // SwingJS -- necessary?
131129

132130
public void setImage(BufferedImage image) {
133131
this.image = image;

sources/net.sf.j2s.java.core/src/javax/imageio/ImageTypeSpecifier.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,13 @@ private static ImageTypeSpecifier createSpecifier(int type) {
11771177
true,
11781178
false);
11791179

1180+
case BufferedImage.TYPE_4BYTE_HTML5:
1181+
return createInterleaved(sRGB,
1182+
new int[] { 0, 3, 2, 1 },
1183+
DataBuffer.TYPE_BYTE,
1184+
true,
1185+
false);
1186+
11801187
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
11811188
return createInterleaved(sRGB,
11821189
new int[] { 3, 2, 1, 0 },

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,8 +585,9 @@ public boolean drawImage(Image img, int x, int y, int width, int height, ImageOb
585585
DOMNode imgNode = ((BufferedImage)img).秘getImageNode();
586586
if (imgNode == null) {
587587
drawImagePriv(img, x, y, width, height, observer);
588-
}
588+
} else {
589589
ctx.drawImage(imgNode, x, y, width, height);
590+
}
590591
if (observer != null)
591592
observe(img, observer, imgNode != null);
592593
}
@@ -607,9 +608,16 @@ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1,
607608
byte[] bytes = null;
608609
DOMNode imgNode = ((BufferedImage)img).秘getImageNode();
609610
if (imgNode == null) {
610-
JSUtil.notImplemented("JSGraphics2D.drawImage cannot could not create an image node");
611+
if (sx2 - sx1 != dx2 - dx1 || sy2 - sy1 != dy2 - dy1
612+
|| sx1 != 0 || sx2 != img.getWidth(null)
613+
|| sy1 != 0 || sy2 != img.getHeight(null)) {
614+
this.drawImage(img, dx1, dy1, sx2 - sx1, sy2 - sy1, observer);
615+
} else {
616+
JSUtil.notImplemented("JSGraphics2D.drawImage cannot could not create an image node");
617+
}
611618
} else {
612-
ctx.drawImage(imgNode, sx1, sy1, sx2 - sx1, sy2 - sy1, dx1, dy1, dx2 - dx1, dy2 - dy1);
619+
// we would need an image to do this
620+
ctx.drawImage(imgNode, sx1, sy1, sx2 - sx1, sy2 - sy1, 0, 0, dx2 - dx1, dy2 - dy1);
613621
}
614622
if (observer != null)
615623
observe(img, observer, imgNode != null);
@@ -690,7 +698,7 @@ private boolean drawImagePriv(Image img, int x, int y, int width, int height, Im
690698
}
691699
} else {
692700
for (int i = 0, n = Math.min(buf8.length, pixels.length); i < n; i++) {
693-
buf8[i] = pixels[i];
701+
buf8[i] = pixels[i] & 0xFF;
694702
}
695703
}
696704
x += m[4];

0 commit comments

Comments
 (0)