@woosh/meep-engine 2.74.0 → 2.75.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bundle-worker-image-decoder.js +1 -1
- package/build/meep.cjs +202 -204
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +202 -204
- package/package.json +1 -1
- package/src/core/binary/UINT32_MAX.js +5 -0
- package/src/core/bvh2/bvh3/BVH.js +44 -2
- package/src/core/bvh2/bvh3/BVH.spec.js +45 -0
- package/src/core/bvh2/bvh3/build_triangle_morton_codes.js +73 -0
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +5 -101
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +59 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.js +31 -32
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_nearest_to_point.spec.js +139 -0
- package/src/core/collection/SCRATCH_UINT32_TRAVERSAL_STACK.js +1 -0
- package/src/core/events/signal/SignalBinding.js +18 -16
- package/src/core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js +1 -0
- package/src/core/geom/3d/aabb/aabb3_unsigned_distance_sqr_to_point.js +36 -0
- package/src/core/model/ObservedBoolean.js +1 -1
- package/src/core/process/worker/OnDemandWorkerManager.js +5 -1
- package/src/engine/asset/loaders/ArrayBufferLoader.js +13 -15
- package/src/engine/asset/loaders/image/ImageDecoderWorker.js +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +5 -7
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
- package/src/engine/asset/loaders/image/png/PNG.js +339 -332
- package/src/engine/asset/loaders/image/png/PNGReader.js +59 -16
- package/src/engine/asset/loaders/image/png/prototypePNG.js +13 -4
- package/src/engine/graphics/texture/virtual/v2/{SparseTexture.js → PageTexture.js} +62 -18
- package/src/engine/graphics/texture/virtual/v2/ResidentTileTexture.js +46 -0
- package/src/engine/graphics/texture/virtual/v2/{TileLoader.js → VirtualTextureTileLoader.js} +11 -8
- package/src/engine/graphics/texture/virtual/v2/{UsageMetadata.js → VirtualTextureUsage.js} +2 -8
- package/src/engine/graphics/texture/virtual/v2/{VirtualTextureManager.js → VirtualTextureUsageUpdater.js} +7 -5
- package/src/engine/graphics/texture/virtual/v2/debug/ResidencyDebugView.js +17 -5
- package/src/engine/graphics/texture/virtual/v2/debug/UsageDebugView.js +1 -1
- package/src/engine/graphics/texture/virtual/v2/debug/UsagePyramidDebugView.js +1 -1
- package/src/engine/graphics/texture/virtual/v2/prototype.js +78 -59
- package/src/engine/graphics/texture/virtual/v2/tile/{TextureTile.js → VirtualTextureTile.js} +2 -2
- package/src/engine/graphics/texture/virtual/v2/tile/compose_tile_address.js +4 -0
- /package/src/engine/graphics/texture/virtual/v2/{ShaderUsage.js → VirtualTextureUsageShader.js} +0 -0
|
@@ -1,431 +1,438 @@
|
|
|
1
|
-
|
|
1
|
+
export class PNG {
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @type {number}
|
|
6
|
+
*/
|
|
7
|
+
width = 0;
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @type {number}
|
|
11
|
+
*/
|
|
12
|
+
height = 0;
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Number of bits per channel?
|
|
11
16
|
* @type {number}
|
|
12
17
|
*/
|
|
13
|
-
|
|
18
|
+
bitDepth = 0;
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
colorType = 0;
|
|
21
|
+
compressionMethod = 0;
|
|
22
|
+
filterMethod = 0;
|
|
23
|
+
interlaceMethod = 0;
|
|
19
24
|
|
|
20
25
|
/**
|
|
21
26
|
* Number of channels in the image
|
|
22
27
|
* @example RGB = 3, RGBA = 4, etc.
|
|
23
28
|
* @type {number}
|
|
24
29
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
colors = 0;
|
|
31
|
+
alpha = false;
|
|
32
|
+
pixelBits = 0;
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
palette = null;
|
|
30
35
|
|
|
31
36
|
/**
|
|
32
37
|
*
|
|
33
38
|
* @type {Uint8Array|null}
|
|
34
39
|
*/
|
|
35
|
-
|
|
40
|
+
pixels = null;
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
43
|
* Transparency palette
|
|
39
44
|
* @type {Uint8Array|null}
|
|
40
45
|
*/
|
|
41
|
-
|
|
46
|
+
trns = null;
|
|
42
47
|
|
|
43
48
|
|
|
44
49
|
/**
|
|
45
50
|
* Text metadata coming from tEXt chunks
|
|
46
51
|
* @type {Object<string>}
|
|
47
52
|
*/
|
|
48
|
-
|
|
49
|
-
}
|
|
53
|
+
text = {};
|
|
50
54
|
|
|
51
|
-
PNG.prototype.getWidth = function () {
|
|
52
|
-
return this.width;
|
|
53
|
-
};
|
|
54
55
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
PNG.prototype.getHeight = function () {
|
|
60
|
-
return this.height;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
PNG.prototype.setHeight = function (height) {
|
|
64
|
-
this.height = height;
|
|
65
|
-
};
|
|
56
|
+
getWidth() {
|
|
57
|
+
return this.width;
|
|
58
|
+
}
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
60
|
+
setWidth(width) {
|
|
61
|
+
this.width = width;
|
|
62
|
+
}
|
|
70
63
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
throw new Error("invalid bith depth " + bitDepth);
|
|
64
|
+
getHeight() {
|
|
65
|
+
return this.height;
|
|
74
66
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
PNG.prototype.getColorType = function () {
|
|
79
|
-
return this.colorType;
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
PNG.prototype.setColorType = function (colorType) {
|
|
83
|
-
|
|
84
|
-
// Color Allowed Interpretation
|
|
85
|
-
// Type Bit Depths
|
|
86
|
-
//
|
|
87
|
-
// 0 1,2,4,8,16 Each pixel is a grayscale sample.
|
|
88
|
-
//
|
|
89
|
-
// 2 8,16 Each pixel is an R,G,B triple.
|
|
90
|
-
//
|
|
91
|
-
// 3 1,2,4,8 Each pixel is a palette index;
|
|
92
|
-
// a PLTE chunk must appear.
|
|
93
|
-
//
|
|
94
|
-
// 4 8,16 Each pixel is a grayscale sample,
|
|
95
|
-
// followed by an alpha sample.
|
|
96
|
-
//
|
|
97
|
-
// 6 8,16 Each pixel is an R,G,B triple,
|
|
98
|
-
// followed by an alpha sample.
|
|
99
|
-
|
|
100
|
-
var colors = 0, alpha = false;
|
|
101
|
-
|
|
102
|
-
switch (colorType) {
|
|
103
|
-
case 0:
|
|
104
|
-
colors = 1;
|
|
105
|
-
break;
|
|
106
|
-
case 2:
|
|
107
|
-
colors = 3;
|
|
108
|
-
break;
|
|
109
|
-
case 3:
|
|
110
|
-
colors = 1;
|
|
111
|
-
break;
|
|
112
|
-
case 4:
|
|
113
|
-
colors = 2;
|
|
114
|
-
alpha = true;
|
|
115
|
-
break;
|
|
116
|
-
case 6:
|
|
117
|
-
colors = 4;
|
|
118
|
-
alpha = true;
|
|
119
|
-
break;
|
|
120
|
-
default:
|
|
121
|
-
throw new Error("invalid color type");
|
|
67
|
+
|
|
68
|
+
setHeight(height) {
|
|
69
|
+
this.height = height;
|
|
122
70
|
}
|
|
123
71
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
};
|
|
72
|
+
getBitDepth() {
|
|
73
|
+
return this.bitDepth;
|
|
74
|
+
}
|
|
128
75
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
76
|
+
setBitDepth(bitDepth) {
|
|
77
|
+
if ([1, 2, 4, 8, 16].indexOf(bitDepth) === -1) {
|
|
78
|
+
throw new Error("invalid bith depth " + bitDepth);
|
|
79
|
+
}
|
|
80
|
+
this.bitDepth = bitDepth;
|
|
81
|
+
}
|
|
132
82
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
throw new Error("invalid compression method " + compressionMethod);
|
|
83
|
+
getColorType() {
|
|
84
|
+
return this.colorType;
|
|
136
85
|
}
|
|
137
|
-
this.compressionMethod = compressionMethod;
|
|
138
|
-
};
|
|
139
86
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
87
|
+
setColorType(colorType) {
|
|
88
|
+
|
|
89
|
+
// Color Allowed Interpretation
|
|
90
|
+
// Type Bit Depths
|
|
91
|
+
//
|
|
92
|
+
// 0 1,2,4,8,16 Each pixel is a grayscale sample.
|
|
93
|
+
//
|
|
94
|
+
// 2 8,16 Each pixel is an R,G,B triple.
|
|
95
|
+
//
|
|
96
|
+
// 3 1,2,4,8 Each pixel is a palette index;
|
|
97
|
+
// a PLTE chunk must appear.
|
|
98
|
+
//
|
|
99
|
+
// 4 8,16 Each pixel is a grayscale sample,
|
|
100
|
+
// followed by an alpha sample.
|
|
101
|
+
//
|
|
102
|
+
// 6 8,16 Each pixel is an R,G,B triple,
|
|
103
|
+
// followed by an alpha sample.
|
|
104
|
+
|
|
105
|
+
let colors = 0, alpha = false;
|
|
106
|
+
|
|
107
|
+
switch (colorType) {
|
|
108
|
+
case 0:
|
|
109
|
+
colors = 1;
|
|
110
|
+
break;
|
|
111
|
+
case 2:
|
|
112
|
+
colors = 3;
|
|
113
|
+
break;
|
|
114
|
+
case 3:
|
|
115
|
+
colors = 1;
|
|
116
|
+
break;
|
|
117
|
+
case 4:
|
|
118
|
+
colors = 2;
|
|
119
|
+
alpha = true;
|
|
120
|
+
break;
|
|
121
|
+
case 6:
|
|
122
|
+
colors = 4;
|
|
123
|
+
alpha = true;
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
throw new Error("invalid color type");
|
|
127
|
+
}
|
|
143
128
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
129
|
+
this.colors = colors;
|
|
130
|
+
this.alpha = alpha;
|
|
131
|
+
this.colorType = colorType;
|
|
147
132
|
}
|
|
148
|
-
this.filterMethod = filterMethod;
|
|
149
|
-
};
|
|
150
133
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
PNG.prototype.setInterlaceMethod = function (interlaceMethod) {
|
|
156
|
-
if (interlaceMethod !== 0 && interlaceMethod !== 1) {
|
|
157
|
-
throw new Error("invalid interlace method " + interlaceMethod);
|
|
134
|
+
getCompressionMethod() {
|
|
135
|
+
return this.compressionMethod;
|
|
158
136
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
*/
|
|
166
|
-
PNG.prototype.setTRNS = function (trns) {
|
|
167
|
-
this.trns = trns;
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
PNG.prototype.setPalette = function (palette) {
|
|
171
|
-
if (palette.length % 3 !== 0) {
|
|
172
|
-
throw new Error("incorrect PLTE chunk length");
|
|
137
|
+
|
|
138
|
+
setCompressionMethod(compressionMethod) {
|
|
139
|
+
if (compressionMethod !== 0) {
|
|
140
|
+
throw new Error("invalid compression method " + compressionMethod);
|
|
141
|
+
}
|
|
142
|
+
this.compressionMethod = compressionMethod;
|
|
173
143
|
}
|
|
174
|
-
|
|
175
|
-
|
|
144
|
+
|
|
145
|
+
getFilterMethod() {
|
|
146
|
+
return this.filterMethod;
|
|
176
147
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* get the pixel color on a certain location in a normalized way
|
|
186
|
-
* result is an array: [red, green, blue, alpha]
|
|
187
|
-
*/
|
|
188
|
-
PNG.prototype.getPixel = function (result, result_offset, x, y) {
|
|
189
|
-
var pixels = this.pixels;
|
|
190
|
-
|
|
191
|
-
if (!pixels) {
|
|
192
|
-
throw new Error("pixel data is empty");
|
|
148
|
+
|
|
149
|
+
setFilterMethod(filterMethod) {
|
|
150
|
+
if (filterMethod !== 0) {
|
|
151
|
+
throw new Error("invalid filter method " + filterMethod);
|
|
152
|
+
}
|
|
153
|
+
this.filterMethod = filterMethod;
|
|
193
154
|
}
|
|
194
155
|
|
|
195
|
-
|
|
196
|
-
|
|
156
|
+
getInterlaceMethod() {
|
|
157
|
+
return this.interlaceMethod;
|
|
197
158
|
}
|
|
198
159
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
r = pixels[i];
|
|
206
|
-
g = r;
|
|
207
|
-
b = r;
|
|
208
|
-
a = 255;
|
|
209
|
-
break;
|
|
210
|
-
case 2:
|
|
211
|
-
r = pixels[i];
|
|
212
|
-
g = pixels[i + 1];
|
|
213
|
-
b = pixels[i + 2];
|
|
214
|
-
a = 255;
|
|
215
|
-
break;
|
|
216
|
-
case 3:
|
|
217
|
-
a = 255;
|
|
218
|
-
|
|
219
|
-
if (this.trns != null) {
|
|
220
|
-
a = this.trns[pixels[i]];
|
|
221
|
-
}
|
|
160
|
+
setInterlaceMethod(interlaceMethod) {
|
|
161
|
+
if (interlaceMethod !== 0 && interlaceMethod !== 1) {
|
|
162
|
+
throw new Error("invalid interlace method " + interlaceMethod);
|
|
163
|
+
}
|
|
164
|
+
this.interlaceMethod = interlaceMethod;
|
|
165
|
+
}
|
|
222
166
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
break;
|
|
231
|
-
case 4:
|
|
232
|
-
r = pixels[i];
|
|
233
|
-
g = r;
|
|
234
|
-
b = r;
|
|
235
|
-
a = pixels[i + 1];
|
|
236
|
-
break;
|
|
237
|
-
case 6:
|
|
238
|
-
r = pixels[i];
|
|
239
|
-
g = pixels[i + 1];
|
|
240
|
-
b = pixels[i + 2];
|
|
241
|
-
a = pixels[i + 3];
|
|
242
|
-
break;
|
|
243
|
-
default:
|
|
244
|
-
throw new Error('Unsupported color type');
|
|
167
|
+
/**
|
|
168
|
+
*
|
|
169
|
+
* @param {Uint8Array} trns
|
|
170
|
+
*/
|
|
171
|
+
setTRNS(trns) {
|
|
172
|
+
this.trns = trns;
|
|
245
173
|
}
|
|
246
174
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
175
|
+
setPalette(palette) {
|
|
176
|
+
if (palette.length % 3 !== 0) {
|
|
177
|
+
throw new Error("incorrect PLTE chunk length");
|
|
178
|
+
}
|
|
179
|
+
if (palette.length > (Math.pow(2, this.bitDepth) * 3)) {
|
|
180
|
+
throw new Error("palette has more colors than 2^bitdepth");
|
|
181
|
+
}
|
|
182
|
+
this.palette = palette;
|
|
183
|
+
}
|
|
252
184
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
*/
|
|
257
|
-
PNG.prototype.getRGBA8Array_fromRGB = function (destination) {
|
|
185
|
+
getPalette() {
|
|
186
|
+
return this.palette;
|
|
187
|
+
}
|
|
258
188
|
|
|
259
|
-
|
|
260
|
-
|
|
189
|
+
/**
|
|
190
|
+
* get the pixel color on a certain location in a normalized way
|
|
191
|
+
* result is an array: [red, green, blue, alpha]
|
|
192
|
+
*/
|
|
193
|
+
getPixel(result, result_offset, x, y) {
|
|
194
|
+
const pixels = this.pixels;
|
|
261
195
|
|
|
262
|
-
|
|
196
|
+
if (!pixels) {
|
|
197
|
+
throw new Error("pixel data is empty");
|
|
198
|
+
}
|
|
263
199
|
|
|
264
|
-
|
|
200
|
+
if (x >= this.width || y >= this.height) {
|
|
201
|
+
throw new Error("x,y position out of bound");
|
|
202
|
+
}
|
|
265
203
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
204
|
+
const i = this.colors * this.bitDepth / 8 * (y * this.width + x);
|
|
205
|
+
|
|
206
|
+
let r, g, b, a;
|
|
207
|
+
|
|
208
|
+
switch (this.colorType) {
|
|
209
|
+
case 0:
|
|
210
|
+
r = pixels[i];
|
|
211
|
+
g = r;
|
|
212
|
+
b = r;
|
|
213
|
+
a = 255;
|
|
214
|
+
break;
|
|
215
|
+
case 2:
|
|
216
|
+
r = pixels[i];
|
|
217
|
+
g = pixels[i + 1];
|
|
218
|
+
b = pixels[i + 2];
|
|
219
|
+
a = 255;
|
|
220
|
+
break;
|
|
221
|
+
case 3:
|
|
222
|
+
a = 255;
|
|
223
|
+
|
|
224
|
+
if (this.trns != null) {
|
|
225
|
+
a = this.trns[pixels[i]];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const offset = pixels[i] * 3;
|
|
229
|
+
|
|
230
|
+
const palette = this.palette;
|
|
231
|
+
r = palette[offset];
|
|
232
|
+
g = palette[offset + 1];
|
|
233
|
+
b = palette[offset + 2];
|
|
234
|
+
|
|
235
|
+
break;
|
|
236
|
+
case 4:
|
|
237
|
+
r = pixels[i];
|
|
238
|
+
g = r;
|
|
239
|
+
b = r;
|
|
240
|
+
a = pixels[i + 1];
|
|
241
|
+
break;
|
|
242
|
+
case 6:
|
|
243
|
+
r = pixels[i];
|
|
244
|
+
g = pixels[i + 1];
|
|
245
|
+
b = pixels[i + 2];
|
|
246
|
+
a = pixels[i + 3];
|
|
247
|
+
break;
|
|
248
|
+
default:
|
|
249
|
+
throw new Error('Unsupported color type');
|
|
250
|
+
}
|
|
269
251
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
252
|
+
result[result_offset + 0] = r;
|
|
253
|
+
result[result_offset + 1] = g;
|
|
254
|
+
result[result_offset + 2] = b;
|
|
255
|
+
result[result_offset + 3] = a;
|
|
274
256
|
}
|
|
275
257
|
|
|
276
|
-
|
|
258
|
+
/**
|
|
259
|
+
* Assumes pixels are stored as RGB without A component, will set A to 255
|
|
260
|
+
* @param {Uint8Array} destination
|
|
261
|
+
*/
|
|
262
|
+
getRGBA8Array_fromRGB(destination) {
|
|
277
263
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
* @param {Uint8Array} destination
|
|
281
|
-
*/
|
|
282
|
-
PNG.prototype.getRGBA8Array_generic = function (destination) {
|
|
264
|
+
const height = this.height;
|
|
265
|
+
const width = this.width;
|
|
283
266
|
|
|
284
|
-
|
|
285
|
-
const width = this.width;
|
|
267
|
+
const pixel_count = width * height;
|
|
286
268
|
|
|
287
|
-
|
|
288
|
-
const row_index = y * width;
|
|
269
|
+
const source = this.pixels;
|
|
289
270
|
|
|
290
|
-
for (
|
|
291
|
-
const
|
|
271
|
+
for (let i = 0; i < pixel_count; i++) {
|
|
272
|
+
const i3 = i * 3;
|
|
273
|
+
const i4 = i3 + i;
|
|
292
274
|
|
|
293
|
-
|
|
275
|
+
destination[i4] = source[i3];
|
|
276
|
+
destination[i4 + 1] = source[i3 + 1];
|
|
277
|
+
destination[i4 + 2] = source[i3 + 2];
|
|
278
|
+
destination[i4 + 3] = 255;
|
|
294
279
|
}
|
|
280
|
+
|
|
295
281
|
}
|
|
296
282
|
|
|
297
|
-
|
|
283
|
+
/**
|
|
284
|
+
*
|
|
285
|
+
* @param {Uint8Array} destination
|
|
286
|
+
*/
|
|
287
|
+
getRGBA8Array_generic(destination) {
|
|
298
288
|
|
|
289
|
+
const height = this.height;
|
|
290
|
+
const width = this.width;
|
|
299
291
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
* Matches the api of canvas.getImageData
|
|
303
|
-
*/
|
|
304
|
-
PNG.prototype.getRGBA8Array = function () {
|
|
305
|
-
if (this.colorType === 6) {
|
|
306
|
-
// RGBA color type, return pixels directly
|
|
307
|
-
return this.pixels;
|
|
308
|
-
}
|
|
292
|
+
for (let y = 0; y < height; y++) {
|
|
293
|
+
const row_index = y * width;
|
|
309
294
|
|
|
310
|
-
|
|
311
|
-
|
|
295
|
+
for (let x = 0; x < width; x++) {
|
|
296
|
+
const address = (row_index + x) * 4;
|
|
312
297
|
|
|
313
|
-
|
|
298
|
+
this.getPixel(destination, address, x, y);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
314
301
|
|
|
315
|
-
if (this.colorType === 2) {
|
|
316
|
-
// RGB color type
|
|
317
|
-
this.getRGBA8Array_fromRGB(data);
|
|
318
|
-
} else {
|
|
319
|
-
// original, slow generic method
|
|
320
|
-
this.getRGBA8Array_generic(data);
|
|
321
302
|
}
|
|
322
303
|
|
|
323
|
-
|
|
324
|
-
|
|
304
|
+
/**
|
|
305
|
+
* get the pixels of the image as a RGBA array of the form [r1, g1, b1, a1, r2, b2, g2, a2, ...]
|
|
306
|
+
* Matches the api of canvas.getImageData
|
|
307
|
+
*/
|
|
308
|
+
getRGBA8Array() {
|
|
309
|
+
if (this.colorType === 6) {
|
|
310
|
+
// RGBA color type, return pixels directly
|
|
311
|
+
return this.pixels;
|
|
312
|
+
}
|
|
325
313
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const h = this.height;
|
|
314
|
+
const height = this.height;
|
|
315
|
+
const width = this.width;
|
|
329
316
|
|
|
330
|
-
|
|
317
|
+
const data = new Uint8Array(width * height * 4);
|
|
331
318
|
|
|
332
|
-
|
|
319
|
+
if (this.colorType === 2) {
|
|
320
|
+
// RGB color type
|
|
321
|
+
this.getRGBA8Array_fromRGB(data);
|
|
322
|
+
} else {
|
|
323
|
+
// original, slow generic method
|
|
324
|
+
this.getRGBA8Array_generic(data);
|
|
325
|
+
}
|
|
333
326
|
|
|
334
|
-
|
|
335
|
-
if (transparency_lookup !== null) {
|
|
336
|
-
// has transparency
|
|
337
|
-
itemSize = 4;
|
|
338
|
-
} else {
|
|
339
|
-
itemSize = 3;
|
|
327
|
+
return data;
|
|
340
328
|
}
|
|
341
329
|
|
|
342
|
-
|
|
330
|
+
getUint8Data_case3() {
|
|
331
|
+
const w = this.width;
|
|
332
|
+
const h = this.height;
|
|
333
|
+
|
|
334
|
+
const area = w * h;
|
|
335
|
+
|
|
336
|
+
let itemSize;
|
|
343
337
|
|
|
344
|
-
|
|
345
|
-
|
|
338
|
+
const transparency_lookup = this.trns;
|
|
339
|
+
if (transparency_lookup !== null) {
|
|
340
|
+
// has transparency
|
|
341
|
+
itemSize = 4;
|
|
342
|
+
} else {
|
|
343
|
+
itemSize = 3;
|
|
344
|
+
}
|
|
346
345
|
|
|
347
|
-
|
|
346
|
+
const result_data = new Uint8Array(area * itemSize);
|
|
348
347
|
|
|
349
|
-
|
|
350
|
-
const
|
|
348
|
+
const pixels = this.pixels;
|
|
349
|
+
const palette = this.palette;
|
|
351
350
|
|
|
352
|
-
const
|
|
351
|
+
const d = this.colors * Math.ceil(this.bitDepth / 8);
|
|
353
352
|
|
|
354
|
-
|
|
353
|
+
for (let i = 0; i < area; i++) {
|
|
354
|
+
const destination_address = i * itemSize;
|
|
355
355
|
|
|
356
|
-
|
|
357
|
-
result_data[destination_address + 1] = palette[lookup_value + 1];
|
|
358
|
-
result_data[destination_address + 2] = palette[lookup_value + 2];
|
|
359
|
-
}
|
|
356
|
+
const lookup_index = pixels[i * d];
|
|
360
357
|
|
|
361
|
-
|
|
362
|
-
if (transparency_lookup !== null) {
|
|
363
|
-
const transparency_lookup_size = transparency_lookup.length;
|
|
358
|
+
const lookup_value = lookup_index * 3;
|
|
364
359
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
360
|
+
result_data[destination_address] = palette[lookup_value];
|
|
361
|
+
result_data[destination_address + 1] = palette[lookup_value + 1];
|
|
362
|
+
result_data[destination_address + 2] = palette[lookup_value + 2];
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
//transparency
|
|
366
|
+
if (transparency_lookup !== null) {
|
|
367
|
+
const transparency_lookup_size = transparency_lookup.length;
|
|
368
|
+
|
|
369
|
+
for (let i = 0; i < area; i++) {
|
|
370
|
+
const pixel_index = pixels[i * d];
|
|
371
|
+
|
|
372
|
+
const result_address = i * 4 + 3;
|
|
373
|
+
|
|
374
|
+
if (pixel_index >= transparency_lookup_size) {
|
|
375
|
+
/*
|
|
376
|
+
when sampling outside of lookup, value defaults to 255
|
|
377
|
+
@see "tRNS" chunk in PNG 1.2 spec
|
|
378
|
+
*/
|
|
379
|
+
result_data[result_address] = 255;
|
|
380
|
+
} else {
|
|
381
|
+
result_data[result_address] = transparency_lookup[pixel_index];
|
|
382
|
+
}
|
|
378
383
|
}
|
|
379
384
|
}
|
|
385
|
+
|
|
386
|
+
return {
|
|
387
|
+
data: result_data,
|
|
388
|
+
itemSize: itemSize
|
|
389
|
+
}
|
|
380
390
|
}
|
|
381
391
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
392
|
+
/**
|
|
393
|
+
* @returns {{itemSize:number, data:Uint8Array, bitDepth: number}}
|
|
394
|
+
*/
|
|
395
|
+
getUint8Data() {
|
|
396
|
+
let data;
|
|
397
|
+
let itemSize = 0; // note, can take this from this.colors
|
|
398
|
+
|
|
399
|
+
const color_type = this.colorType;
|
|
400
|
+
|
|
401
|
+
switch (color_type) {
|
|
402
|
+
case 0:
|
|
403
|
+
data = this.pixels;
|
|
404
|
+
itemSize = 1;
|
|
405
|
+
break;
|
|
406
|
+
case 2:
|
|
407
|
+
data = this.pixels;
|
|
408
|
+
itemSize = 3;
|
|
409
|
+
break;
|
|
410
|
+
case 3:
|
|
411
|
+
// palette
|
|
412
|
+
const c3 = this.getUint8Data_case3();
|
|
413
|
+
|
|
414
|
+
data = c3.data;
|
|
415
|
+
itemSize = c3.itemSize;
|
|
416
|
+
|
|
417
|
+
break;
|
|
418
|
+
case 4:
|
|
419
|
+
// grayscale with alpha
|
|
420
|
+
data = this.pixels;
|
|
421
|
+
itemSize = 2;
|
|
422
|
+
break;
|
|
423
|
+
case 6:
|
|
424
|
+
data = this.pixels;
|
|
425
|
+
itemSize = 4;
|
|
426
|
+
break;
|
|
427
|
+
default:
|
|
428
|
+
throw new Error('Unsupported color type');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return {
|
|
432
|
+
data,
|
|
433
|
+
itemSize
|
|
434
|
+
};
|
|
385
435
|
}
|
|
386
436
|
}
|
|
387
437
|
|
|
388
|
-
/**
|
|
389
|
-
* @returns {{itemSize:number, data:Uint8Array, bitDepth: number}}
|
|
390
|
-
*/
|
|
391
|
-
PNG.prototype.getUint8Data = function () {
|
|
392
|
-
let data;
|
|
393
|
-
let itemSize = 0; // note, can take this from this.colors
|
|
394
|
-
|
|
395
|
-
const color_type = this.colorType;
|
|
396
|
-
|
|
397
|
-
switch (color_type) {
|
|
398
|
-
case 0:
|
|
399
|
-
data = this.pixels;
|
|
400
|
-
itemSize = 1;
|
|
401
|
-
break;
|
|
402
|
-
case 2:
|
|
403
|
-
data = this.pixels;
|
|
404
|
-
itemSize = 3;
|
|
405
|
-
break;
|
|
406
|
-
case 3:
|
|
407
|
-
// palette
|
|
408
|
-
const c3 = this.getUint8Data_case3();
|
|
409
|
-
|
|
410
|
-
data = c3.data;
|
|
411
|
-
itemSize = c3.itemSize;
|
|
412
|
-
|
|
413
|
-
break;
|
|
414
|
-
case 4:
|
|
415
|
-
// grayscale with alpha
|
|
416
|
-
data = this.pixels;
|
|
417
|
-
itemSize = 2;
|
|
418
|
-
break;
|
|
419
|
-
case 6:
|
|
420
|
-
data = this.pixels;
|
|
421
|
-
itemSize = 4;
|
|
422
|
-
break;
|
|
423
|
-
default:
|
|
424
|
-
throw new Error('Unsupported color type');
|
|
425
|
-
}
|
|
426
438
|
|
|
427
|
-
return {
|
|
428
|
-
data,
|
|
429
|
-
itemSize
|
|
430
|
-
};
|
|
431
|
-
};
|