1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.javascript.host.canvas;
16
17 import org.htmlunit.corejs.javascript.Context;
18 import org.htmlunit.corejs.javascript.Function;
19 import org.htmlunit.corejs.javascript.ScriptableObject;
20 import org.htmlunit.corejs.javascript.VarScope;
21 import org.htmlunit.corejs.javascript.typedarrays.NativeArrayBuffer;
22 import org.htmlunit.corejs.javascript.typedarrays.NativeUint8ClampedArray;
23 import org.htmlunit.javascript.HtmlUnitScriptable;
24 import org.htmlunit.javascript.JavaScriptEngine;
25 import org.htmlunit.javascript.configuration.JsxClass;
26 import org.htmlunit.javascript.configuration.JsxConstructor;
27 import org.htmlunit.javascript.configuration.JsxGetter;
28 import org.htmlunit.javascript.host.dom.DOMException;
29 import org.htmlunit.platform.canvas.rendering.RenderingBackend;
30
31
32
33
34
35
36
37
38
39 @JsxClass
40 public class ImageData extends HtmlUnitScriptable {
41
42 private final byte[] bytes_;
43 private final int width_;
44 private final int height_;
45 private NativeUint8ClampedArray data_;
46
47
48
49
50 public ImageData() {
51 this(null, 0, 0, 0, 0);
52 }
53
54
55
56
57
58
59
60
61
62
63 @JsxConstructor
64 public static ImageData jsConstructor(final Context cx, final VarScope scope,
65 final Object[] args, final Function ctorObj, final boolean inNewExpr) {
66 if (args.length < 2) {
67 throw JavaScriptEngine.typeError("ImageData ctor - too less arguments");
68 }
69
70 NativeUint8ClampedArray data = null;
71 final int width;
72 final int height;
73 if (args[0] instanceof NativeUint8ClampedArray array) {
74 data = array;
75 if (data.getArrayLength() % 4 != 0) {
76 throw JavaScriptEngine.asJavaScriptException(
77 (HtmlUnitScriptable) getTopLevelScope(scope).getGlobalThis(),
78 "ImageData ctor - data length mod 4 not zero",
79 DOMException.INVALID_STATE_ERR);
80 }
81
82 width = (int) JavaScriptEngine.toInteger(args[1]);
83 if (args.length < 3) {
84 height = data.getArrayLength() / 4 / width;
85
86 if (data.getArrayLength() != 4 * width * height) {
87 throw JavaScriptEngine.asJavaScriptException(
88 (HtmlUnitScriptable) getTopLevelScope(scope).getGlobalThis(),
89 "ImageData ctor - width not correct",
90 DOMException.INDEX_SIZE_ERR);
91 }
92 }
93 else {
94 height = (int) JavaScriptEngine.toInteger(args[2]);
95 }
96
97 if (data.getArrayLength() != 4 * width * height) {
98 throw JavaScriptEngine.asJavaScriptException(
99 (HtmlUnitScriptable) getTopLevelScope(scope).getGlobalThis(),
100 "ImageData ctor - width/height not correct",
101 DOMException.INDEX_SIZE_ERR);
102 }
103 }
104 else {
105 width = (int) JavaScriptEngine.toInteger(args[0]);
106 height = (int) JavaScriptEngine.toInteger(args[1]);
107 }
108
109 if (width < 0) {
110 throw JavaScriptEngine.asJavaScriptException(
111 (HtmlUnitScriptable) getTopLevelScope(scope).getGlobalThis(),
112 "ImageData ctor - width negative",
113 DOMException.INDEX_SIZE_ERR);
114 }
115 if (height < 0) {
116 throw JavaScriptEngine.asJavaScriptException(
117 (HtmlUnitScriptable) getTopLevelScope(scope).getGlobalThis(),
118 "ImageData ctor - height negative",
119 DOMException.INDEX_SIZE_ERR);
120 }
121
122 final ImageData result = new ImageData(null, 0, 0, width, height);
123 if (data != null) {
124 final byte[] bytes = data.getBuffer().getBuffer();
125 System.arraycopy(bytes, 0, result.bytes_, 0, Math.min(bytes.length, result.bytes_.length));
126 }
127 return result;
128 }
129
130 ImageData(final RenderingBackend context, final int x, final int y, final int width, final int height) {
131 super();
132 if (context == null) {
133 bytes_ = new byte[width * height * 4];
134 }
135 else {
136 bytes_ = context.getBytes(width, height, x, y);
137 }
138
139 width_ = width;
140 height_ = height;
141 }
142
143
144
145
146
147 @JsxGetter
148 public int getWidth() {
149 return width_;
150 }
151
152
153
154
155
156 @JsxGetter
157 public int getHeight() {
158 return height_;
159 }
160
161
162
163
164
165
166 @JsxGetter
167 public NativeUint8ClampedArray getData() {
168 if (data_ == null) {
169 final NativeArrayBuffer arrayBuffer = new NativeArrayBuffer(bytes_.length);
170 System.arraycopy(bytes_, 0, arrayBuffer.getBuffer(), 0, bytes_.length);
171
172 data_ = new NativeUint8ClampedArray(arrayBuffer, 0, bytes_.length);
173 data_.setParentScope(getParentScope());
174 data_.setPrototype(ScriptableObject.getClassPrototype(getParentScope(), data_.getClassName()));
175 }
176
177 return data_;
178 }
179
180 }