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