pixel-data-js 0.0.3 → 0.2.0
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/dist/index.dev.cjs +462 -2
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +431 -1
- package/dist/index.dev.js.map +1 -1
- package/dist/index.prod.cjs +462 -2
- package/dist/index.prod.cjs.map +1 -1
- package/dist/index.prod.d.ts +249 -3
- package/dist/index.prod.js +431 -1
- package/dist/index.prod.js.map +1 -1
- package/package.json +1 -1
- package/src/ImageData/blend-modes.ts +228 -0
- package/src/ImageData/blit.ts +177 -0
- package/src/ImageData/mask.ts +150 -0
- package/src/ImageData/read-write-pixels.ts +66 -1
- package/src/ImageData/serialization.ts +1 -1
- package/src/_types.ts +29 -7
- package/src/color.ts +34 -1
- package/src/index.ts +6 -0
package/dist/index.dev.js
CHANGED
|
@@ -1,3 +1,340 @@
|
|
|
1
|
+
// src/ImageData/blend-modes.ts
|
|
2
|
+
var sourceOverColor32 = (src, dst) => {
|
|
3
|
+
const a = src >>> 24 & 255;
|
|
4
|
+
if (a === 255) return src;
|
|
5
|
+
if (a === 0) return dst;
|
|
6
|
+
const rbMask = 16711935;
|
|
7
|
+
const gMask = 65280;
|
|
8
|
+
const sRB = src & rbMask;
|
|
9
|
+
const sG = src & gMask;
|
|
10
|
+
const dRB = dst & rbMask;
|
|
11
|
+
const dG = dst & gMask;
|
|
12
|
+
const invA = 255 - a;
|
|
13
|
+
const outRB = sRB * a + dRB * invA >> 8 & rbMask;
|
|
14
|
+
const outG = sG * a + dG * invA >> 8 & gMask;
|
|
15
|
+
const outA = a + ((dst >>> 24 & 255) * invA >> 8);
|
|
16
|
+
return (outA << 24 | outRB | outG) >>> 0;
|
|
17
|
+
};
|
|
18
|
+
var screenColor32 = (src, dst) => {
|
|
19
|
+
const sa = src >>> 24 & 255;
|
|
20
|
+
if (sa === 0) return dst;
|
|
21
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
22
|
+
const br = 255 - ((255 - (src & 255)) * (255 - dr) >> 8);
|
|
23
|
+
const bg = 255 - ((255 - (src >> 8 & 255)) * (255 - dg) >> 8);
|
|
24
|
+
const bb = 255 - ((255 - (src >> 16 & 255)) * (255 - db) >> 8);
|
|
25
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
26
|
+
const invA = 255 - sa;
|
|
27
|
+
const r = br * sa + dr * invA >> 8;
|
|
28
|
+
const g = bg * sa + dg * invA >> 8;
|
|
29
|
+
const b = bb * sa + db * invA >> 8;
|
|
30
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
31
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
32
|
+
};
|
|
33
|
+
var linearDodgeColor32 = (src, dst) => {
|
|
34
|
+
const sa = src >>> 24 & 255;
|
|
35
|
+
if (sa === 0) return dst;
|
|
36
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
37
|
+
const br = Math.min(255, (src & 255) + dr);
|
|
38
|
+
const bg = Math.min(255, (src >> 8 & 255) + dg);
|
|
39
|
+
const bb = Math.min(255, (src >> 16 & 255) + db);
|
|
40
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
41
|
+
const invA = 255 - sa;
|
|
42
|
+
const r = br * sa + dr * invA >> 8;
|
|
43
|
+
const g = bg * sa + dg * invA >> 8;
|
|
44
|
+
const b = bb * sa + db * invA >> 8;
|
|
45
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
46
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
47
|
+
};
|
|
48
|
+
var multiplyColor32 = (src, dst) => {
|
|
49
|
+
const sa = src >>> 24 & 255;
|
|
50
|
+
if (sa === 0) return dst;
|
|
51
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
52
|
+
const br = (src & 255) * dr >> 8;
|
|
53
|
+
const bg = (src >> 8 & 255) * dg >> 8;
|
|
54
|
+
const bb = (src >> 16 & 255) * db >> 8;
|
|
55
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
56
|
+
const invA = 255 - sa;
|
|
57
|
+
const r = br * sa + dr * invA >> 8;
|
|
58
|
+
const g = bg * sa + dg * invA >> 8;
|
|
59
|
+
const b = bb * sa + db * invA >> 8;
|
|
60
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
61
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
62
|
+
};
|
|
63
|
+
var differenceColor32 = (src, dst) => {
|
|
64
|
+
const sa = src >>> 24 & 255;
|
|
65
|
+
if (sa === 0) return dst;
|
|
66
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
67
|
+
const br = Math.abs((src & 255) - dr);
|
|
68
|
+
const bg = Math.abs((src >> 8 & 255) - dg);
|
|
69
|
+
const bb = Math.abs((src >> 16 & 255) - db);
|
|
70
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
71
|
+
const invA = 255 - sa;
|
|
72
|
+
const r = br * sa + dr * invA >> 8;
|
|
73
|
+
const g = bg * sa + dg * invA >> 8;
|
|
74
|
+
const b = bb * sa + db * invA >> 8;
|
|
75
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
76
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
77
|
+
};
|
|
78
|
+
var hardLightColor32 = (src, dst) => {
|
|
79
|
+
const sa = src >>> 24 & 255;
|
|
80
|
+
if (sa === 0) return dst;
|
|
81
|
+
const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
|
|
82
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
83
|
+
const br = sr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
|
|
84
|
+
const bg = sg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
|
|
85
|
+
const bb = sb < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
|
|
86
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
87
|
+
const invA = 255 - sa;
|
|
88
|
+
const r = br * sa + dr * invA >> 8;
|
|
89
|
+
const g = bg * sa + dg * invA >> 8;
|
|
90
|
+
const b = bb * sa + db * invA >> 8;
|
|
91
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
92
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
93
|
+
};
|
|
94
|
+
var colorBurnColor32 = (src, dst) => {
|
|
95
|
+
const sa = src >>> 24 & 255;
|
|
96
|
+
if (sa === 0) return dst;
|
|
97
|
+
const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
|
|
98
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
99
|
+
const br = dr === 255 ? 255 : Math.max(0, 255 - (255 - dr << 8) / (sr || 1));
|
|
100
|
+
const bg = dg === 255 ? 255 : Math.max(0, 255 - (255 - dg << 8) / (sg || 1));
|
|
101
|
+
const bb = db === 255 ? 255 : Math.max(0, 255 - (255 - db << 8) / (sb || 1));
|
|
102
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
103
|
+
const invA = 255 - sa;
|
|
104
|
+
const r = br * sa + dr * invA >> 8;
|
|
105
|
+
const g = bg * sa + dg * invA >> 8;
|
|
106
|
+
const b = bb * sa + db * invA >> 8;
|
|
107
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
108
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
109
|
+
};
|
|
110
|
+
var overlayColor32 = (src, dst) => {
|
|
111
|
+
const sa = src >>> 24 & 255;
|
|
112
|
+
if (sa === 0) return dst;
|
|
113
|
+
const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
|
|
114
|
+
const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
|
|
115
|
+
const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
|
|
116
|
+
const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
|
|
117
|
+
const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
|
|
118
|
+
if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
|
|
119
|
+
const invA = 255 - sa;
|
|
120
|
+
const r = br * sa + dr * invA >> 8;
|
|
121
|
+
const g = bg * sa + dg * invA >> 8;
|
|
122
|
+
const b = bb * sa + db * invA >> 8;
|
|
123
|
+
const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
|
|
124
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
125
|
+
};
|
|
126
|
+
var COLOR_32_BLEND_MODES = {
|
|
127
|
+
sourceOver: sourceOverColor32,
|
|
128
|
+
screen: screenColor32,
|
|
129
|
+
linearDodge: linearDodgeColor32,
|
|
130
|
+
multiply: multiplyColor32,
|
|
131
|
+
difference: differenceColor32,
|
|
132
|
+
overlay: overlayColor32,
|
|
133
|
+
hardLight: hardLightColor32,
|
|
134
|
+
colorBurn: colorBurnColor32
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/_types.ts
|
|
138
|
+
var MaskType = /* @__PURE__ */ ((MaskType2) => {
|
|
139
|
+
MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
|
|
140
|
+
MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
|
|
141
|
+
return MaskType2;
|
|
142
|
+
})(MaskType || {});
|
|
143
|
+
|
|
144
|
+
// src/ImageData/blit.ts
|
|
145
|
+
function blendImageData(dst, src, opts) {
|
|
146
|
+
let {
|
|
147
|
+
dx = 0,
|
|
148
|
+
dy = 0,
|
|
149
|
+
sx = 0,
|
|
150
|
+
sy = 0,
|
|
151
|
+
sw = src.width,
|
|
152
|
+
sh = src.height,
|
|
153
|
+
opacity = 1,
|
|
154
|
+
alpha,
|
|
155
|
+
blendFn = sourceOverColor32,
|
|
156
|
+
mask
|
|
157
|
+
} = opts;
|
|
158
|
+
if (sx < 0) {
|
|
159
|
+
dx -= sx;
|
|
160
|
+
sw += sx;
|
|
161
|
+
sx = 0;
|
|
162
|
+
}
|
|
163
|
+
if (sy < 0) {
|
|
164
|
+
dy -= sy;
|
|
165
|
+
sh += sy;
|
|
166
|
+
sy = 0;
|
|
167
|
+
}
|
|
168
|
+
sw = Math.min(sw, src.width - sx);
|
|
169
|
+
sh = Math.min(sh, src.height - sy);
|
|
170
|
+
if (dx < 0) {
|
|
171
|
+
sx -= dx;
|
|
172
|
+
sw += dx;
|
|
173
|
+
dx = 0;
|
|
174
|
+
}
|
|
175
|
+
if (dy < 0) {
|
|
176
|
+
sy -= dy;
|
|
177
|
+
sh += dy;
|
|
178
|
+
dy = 0;
|
|
179
|
+
}
|
|
180
|
+
const actualW = Math.min(sw, dst.width - dx);
|
|
181
|
+
const actualH = Math.min(sh, dst.height - dy);
|
|
182
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
183
|
+
const dst32 = new Uint32Array(dst.data.buffer);
|
|
184
|
+
const src32 = new Uint32Array(src.data.buffer);
|
|
185
|
+
const dw = dst.width;
|
|
186
|
+
const sw_orig = src.width;
|
|
187
|
+
const gAlpha = alpha !== void 0 ? alpha | 0 : Math.round(opacity * 255);
|
|
188
|
+
const maskIsAlpha = mask?.type === 0 /* ALPHA */;
|
|
189
|
+
for (let iy = 0; iy < actualH; iy++) {
|
|
190
|
+
const dRow = (iy + dy) * dw;
|
|
191
|
+
const sRow = (iy + sy) * sw_orig;
|
|
192
|
+
for (let ix = 0; ix < actualW; ix++) {
|
|
193
|
+
const di = dRow + (ix + dx);
|
|
194
|
+
const si = sRow + (ix + sx);
|
|
195
|
+
let s = src32[si];
|
|
196
|
+
let sa = s >>> 24 & 255;
|
|
197
|
+
if (sa === 0) continue;
|
|
198
|
+
let activeWeight = gAlpha;
|
|
199
|
+
if (mask) {
|
|
200
|
+
const m = mask.data[si];
|
|
201
|
+
if (m === 0) continue;
|
|
202
|
+
activeWeight = maskIsAlpha ? m * activeWeight + 128 >> 8 : activeWeight;
|
|
203
|
+
}
|
|
204
|
+
if (activeWeight < 255) {
|
|
205
|
+
sa = sa * activeWeight + 128 >> 8;
|
|
206
|
+
}
|
|
207
|
+
if (sa === 0) continue;
|
|
208
|
+
s = (s & 16777215 | sa << 24) >>> 0;
|
|
209
|
+
dst32[di] = blendFn(s, dst32[di]);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/ImageData/mask.ts
|
|
215
|
+
function applyBinaryMask(dst, mask, opts = {}) {
|
|
216
|
+
const { width: maskWidth, height: maskHeight } = mask;
|
|
217
|
+
const { dx = 0, dy = 0, sx = 0, sy = 0, sw = maskWidth, sh = maskHeight } = opts;
|
|
218
|
+
const x0 = Math.max(0, dx, dx + (0 - sx));
|
|
219
|
+
const y0 = Math.max(0, dy, dy + (0 - sy));
|
|
220
|
+
const x1 = Math.min(dst.width, dx + sw, dx + (maskWidth - sx));
|
|
221
|
+
const y1 = Math.min(dst.height, dy + sh, dy + (maskHeight - sy));
|
|
222
|
+
if (x1 <= x0 || y1 <= y0) return;
|
|
223
|
+
const { data: dstData, width: dstW } = dst;
|
|
224
|
+
for (let y = y0; y < y1; y++) {
|
|
225
|
+
const maskY = y - dy + sy;
|
|
226
|
+
const dstRowOffset = y * dstW * 4;
|
|
227
|
+
const maskRowOffset = maskY * maskWidth;
|
|
228
|
+
for (let x = x0; x < x1; x++) {
|
|
229
|
+
const maskX = x - dx + sx;
|
|
230
|
+
const mIdx = maskRowOffset + maskX;
|
|
231
|
+
if (mask.data[mIdx] === 0) {
|
|
232
|
+
const aIdx = dstRowOffset + x * 4 + 3;
|
|
233
|
+
dstData[aIdx] = 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return dst;
|
|
238
|
+
}
|
|
239
|
+
function applyAlphaMask(dst, mask, opts = {}) {
|
|
240
|
+
let { dx = 0, dy = 0, sx = 0, sy = 0, sw = mask.width, sh = mask.height } = opts;
|
|
241
|
+
if (dx < 0) {
|
|
242
|
+
sx -= dx;
|
|
243
|
+
sw += dx;
|
|
244
|
+
dx = 0;
|
|
245
|
+
}
|
|
246
|
+
if (dy < 0) {
|
|
247
|
+
sy -= dy;
|
|
248
|
+
sh += dy;
|
|
249
|
+
dy = 0;
|
|
250
|
+
}
|
|
251
|
+
if (sx < 0) {
|
|
252
|
+
dx -= sx;
|
|
253
|
+
sw += sx;
|
|
254
|
+
sx = 0;
|
|
255
|
+
}
|
|
256
|
+
if (sy < 0) {
|
|
257
|
+
dy -= sy;
|
|
258
|
+
sh += sy;
|
|
259
|
+
sy = 0;
|
|
260
|
+
}
|
|
261
|
+
const actualW = Math.min(sw, dst.width - dx, mask.width - sx);
|
|
262
|
+
const actualH = Math.min(sh, dst.height - dy, mask.height - sy);
|
|
263
|
+
if (actualW <= 0 || actualH <= 0) return;
|
|
264
|
+
const dData = dst.data;
|
|
265
|
+
const mData = mask.data;
|
|
266
|
+
const dW = dst.width;
|
|
267
|
+
const mW = mask.width;
|
|
268
|
+
for (let y = 0; y < actualH; y++) {
|
|
269
|
+
const dOffset = (dy + y) * dW + dx << 2;
|
|
270
|
+
const mOffset = (sy + y) * mW + sx;
|
|
271
|
+
for (let x = 0; x < actualW; x++) {
|
|
272
|
+
const mVal = mData[mOffset + x];
|
|
273
|
+
if (mVal === 255) continue;
|
|
274
|
+
const aIdx = dOffset + (x << 2) + 3;
|
|
275
|
+
if (mVal === 0) {
|
|
276
|
+
dData[aIdx] = 0;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
dData[aIdx] = dData[aIdx] * mVal + 257 >> 8;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/ImageData/read-write-pixels.ts
|
|
285
|
+
function makeImageDataColor32Adapter(imageData) {
|
|
286
|
+
const data32 = new Uint32Array(imageData.data.buffer);
|
|
287
|
+
function inBounds(x, y) {
|
|
288
|
+
return x < 0 || x >= imageData.width || y < 0 || y >= imageData.height;
|
|
289
|
+
}
|
|
290
|
+
function setPixel(x, y, color) {
|
|
291
|
+
if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return;
|
|
292
|
+
data32[y * imageData.width + x] = color;
|
|
293
|
+
}
|
|
294
|
+
function getPixel(x, y) {
|
|
295
|
+
if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return;
|
|
296
|
+
return data32[y * imageData.width + x];
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
inBounds,
|
|
300
|
+
imageData,
|
|
301
|
+
data32,
|
|
302
|
+
setPixel,
|
|
303
|
+
getPixel
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
function extractPixelData(imageData, _x, _y, _w, _h) {
|
|
307
|
+
const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
|
|
308
|
+
const { width: srcW, height: srcH, data: src } = imageData;
|
|
309
|
+
if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
|
|
310
|
+
const out = new Uint8ClampedArray(w * h * 4);
|
|
311
|
+
const x0 = Math.max(0, x);
|
|
312
|
+
const y0 = Math.max(0, y);
|
|
313
|
+
const x1 = Math.min(srcW, x + w);
|
|
314
|
+
const y1 = Math.min(srcH, y + h);
|
|
315
|
+
if (x1 <= x0 || y1 <= y0) return out;
|
|
316
|
+
for (let row = 0; row < y1 - y0; row++) {
|
|
317
|
+
const srcRow = y0 + row;
|
|
318
|
+
const srcStart = (srcRow * srcW + x0) * 4;
|
|
319
|
+
const rowLen = (x1 - x0) * 4;
|
|
320
|
+
const dstRow = y0 - y + row;
|
|
321
|
+
const dstCol = x0 - x;
|
|
322
|
+
const dstStart = (dstRow * w + dstCol) * 4;
|
|
323
|
+
out.set(src.subarray(srcStart, srcStart + rowLen), dstStart);
|
|
324
|
+
}
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
function copyImageData({ data, width, height }) {
|
|
328
|
+
return new ImageData(data.slice(), width, height);
|
|
329
|
+
}
|
|
330
|
+
function copyImageDataLike({ data, width, height }) {
|
|
331
|
+
return {
|
|
332
|
+
data: data.slice(),
|
|
333
|
+
width,
|
|
334
|
+
height
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
1
338
|
// src/ImageData/serialization.ts
|
|
2
339
|
function base64EncodeArrayBuffer(buffer) {
|
|
3
340
|
const binary = String.fromCharCode(...new Uint8Array(buffer));
|
|
@@ -37,13 +374,106 @@ function deserializeNullableImageData(serialized) {
|
|
|
37
374
|
if (!serialized) return null;
|
|
38
375
|
return deserializeImageData(serialized);
|
|
39
376
|
}
|
|
377
|
+
|
|
378
|
+
// src/color.ts
|
|
379
|
+
function packColor(r, g, b, a) {
|
|
380
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
381
|
+
}
|
|
382
|
+
function packRGBA({ r, g, b, a }) {
|
|
383
|
+
return (a << 24 | b << 16 | g << 8 | r) >>> 0;
|
|
384
|
+
}
|
|
385
|
+
var unpackRed = (packed) => packed >>> 0 & 255;
|
|
386
|
+
var unpackGreen = (packed) => packed >>> 8 & 255;
|
|
387
|
+
var unpackBlue = (packed) => packed >>> 16 & 255;
|
|
388
|
+
var unpackAlpha = (packed) => packed >>> 24 & 255;
|
|
389
|
+
function unpackColor(packed) {
|
|
390
|
+
return {
|
|
391
|
+
r: packed >>> 0 & 255,
|
|
392
|
+
g: packed >>> 8 & 255,
|
|
393
|
+
b: packed >>> 16 & 255,
|
|
394
|
+
a: packed >>> 24 & 255
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
var SCRATCH_RGBA = { r: 0, g: 0, b: 0, a: 0 };
|
|
398
|
+
function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
|
|
399
|
+
scratch.r = packed >>> 0 & 255;
|
|
400
|
+
scratch.g = packed >>> 8 & 255;
|
|
401
|
+
scratch.b = packed >>> 16 & 255;
|
|
402
|
+
scratch.a = packed >>> 24 & 255;
|
|
403
|
+
return scratch;
|
|
404
|
+
}
|
|
405
|
+
function colorDistance(a, b) {
|
|
406
|
+
const dr = (a & 255) - (b & 255);
|
|
407
|
+
const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
|
|
408
|
+
const db = (a >>> 16 & 255) - (b >>> 16 & 255);
|
|
409
|
+
const da = (a >>> 24 & 255) - (b >>> 24 & 255);
|
|
410
|
+
return dr * dr + dg * dg + db * db + da * da;
|
|
411
|
+
}
|
|
412
|
+
function lerpColor32(a, b, t) {
|
|
413
|
+
const r = (a & 255) + t * ((b & 255) - (a & 255));
|
|
414
|
+
const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
|
|
415
|
+
const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
|
|
416
|
+
const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
|
|
417
|
+
return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
|
|
418
|
+
}
|
|
419
|
+
function lerpColor32Fast(src, dst, w) {
|
|
420
|
+
const invA = 255 - w;
|
|
421
|
+
const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
|
|
422
|
+
const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
|
|
423
|
+
return (rb | ga << 8) >>> 0;
|
|
424
|
+
}
|
|
425
|
+
function color32ToHex(color) {
|
|
426
|
+
const r = (color & 255).toString(16).padStart(2, "0");
|
|
427
|
+
const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
|
|
428
|
+
const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
|
|
429
|
+
const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
|
|
430
|
+
return `#${r}${g}${b}${a}`;
|
|
431
|
+
}
|
|
432
|
+
function color32ToCssRGBA(color) {
|
|
433
|
+
const r = color & 255;
|
|
434
|
+
const g = color >>> 8 & 255;
|
|
435
|
+
const b = color >>> 16 & 255;
|
|
436
|
+
const a = color >>> 24 & 255;
|
|
437
|
+
const alpha = Number((a / 255).toFixed(3));
|
|
438
|
+
return `rgba(${r},${g},${b},${alpha})`;
|
|
439
|
+
}
|
|
40
440
|
export {
|
|
441
|
+
COLOR_32_BLEND_MODES,
|
|
442
|
+
MaskType,
|
|
443
|
+
applyAlphaMask,
|
|
444
|
+
applyBinaryMask,
|
|
41
445
|
base64DecodeArrayBuffer,
|
|
42
446
|
base64EncodeArrayBuffer,
|
|
447
|
+
blendImageData,
|
|
448
|
+
color32ToCssRGBA,
|
|
449
|
+
color32ToHex,
|
|
450
|
+
colorBurnColor32,
|
|
451
|
+
colorDistance,
|
|
452
|
+
copyImageData,
|
|
453
|
+
copyImageDataLike,
|
|
43
454
|
deserializeImageData,
|
|
44
455
|
deserializeNullableImageData,
|
|
45
456
|
deserializeRawImageData,
|
|
457
|
+
differenceColor32,
|
|
458
|
+
extractPixelData,
|
|
459
|
+
hardLightColor32,
|
|
460
|
+
lerpColor32,
|
|
461
|
+
lerpColor32Fast,
|
|
462
|
+
linearDodgeColor32,
|
|
463
|
+
makeImageDataColor32Adapter,
|
|
464
|
+
multiplyColor32,
|
|
465
|
+
overlayColor32,
|
|
466
|
+
packColor,
|
|
467
|
+
packRGBA,
|
|
468
|
+
screenColor32,
|
|
46
469
|
serializeImageData,
|
|
47
|
-
serializeNullableImageData
|
|
470
|
+
serializeNullableImageData,
|
|
471
|
+
sourceOverColor32,
|
|
472
|
+
unpackAlpha,
|
|
473
|
+
unpackBlue,
|
|
474
|
+
unpackColor,
|
|
475
|
+
unpackColorTo,
|
|
476
|
+
unpackGreen,
|
|
477
|
+
unpackRed
|
|
48
478
|
};
|
|
49
479
|
//# sourceMappingURL=index.dev.js.map
|
package/dist/index.dev.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ImageData/serialization.ts"],"sourcesContent":["import type { Base64EncodedUInt8Array, ImageDataLike, SerializedImageData } from '../_types'\n\nexport function base64EncodeArrayBuffer(buffer: ArrayBufferLike): Base64EncodedUInt8Array {\n const binary = String.fromCharCode(...new Uint8Array(buffer))\n return btoa(binary) as Base64EncodedUInt8Array\n}\n\nexport function base64DecodeArrayBuffer(encoded: Base64EncodedUInt8Array): Uint8ClampedArray {\n const binary = atob(encoded)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n/**\n * Serialize for use in JSON. Pixel data is stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageDataLike>(imageData: T): SerializedImageData {\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64EncodeArrayBuffer(imageData.data.buffer),\n }\n}\n\nexport function serializeNullableImageData<T extends ImageDataLike | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeRawImageData<T extends SerializedImageData>(serialized: T): ImageDataLike {\n return {\n width: serialized.width,\n height: serialized.height,\n data: base64DecodeArrayBuffer(serialized.data as Base64EncodedUInt8Array),\n }\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const data = base64DecodeArrayBuffer(serialized.data as Base64EncodedUInt8Array)\n\n return new ImageData(data as ImageDataArray, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n"],"mappings":";AAEO,SAAS,wBAAwB,QAAkD;AACxF,QAAM,SAAS,OAAO,aAAa,GAAG,IAAI,WAAW,MAAM,CAAC;AAC5D,SAAO,KAAK,MAAM;AACpB;AAEO,SAAS,wBAAwB,SAAqD;AAC3F,QAAM,SAAS,KAAK,OAAO;AAC3B,QAAM,QAAQ,IAAI,kBAAkB,OAAO,MAAM;AACjD,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,SAAO;AACT;AAKO,SAAS,mBAA4C,WAAmC;AAC7F,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB,QAAQ,UAAU;AAAA,IAClB,MAAM,wBAAwB,UAAU,KAAK,MAAM;AAAA,EACrD;AACF;AAEO,SAAS,2BAA2D,WAA2D;AACpI,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,mBAAmB,SAAS;AACrC;AAEO,SAAS,wBAAuD,YAA8B;AACnG,SAAO;AAAA,IACL,OAAO,WAAW;AAAA,IAClB,QAAQ,WAAW;AAAA,IACnB,MAAM,wBAAwB,WAAW,IAA+B;AAAA,EAC1E;AACF;AAEO,SAAS,qBAAoD,YAA0B;AAC5F,QAAM,OAAO,wBAAwB,WAAW,IAA+B;AAE/E,SAAO,IAAI,UAAU,MAAwB,WAAW,OAAO,WAAW,MAAM;AAClF;AAEO,SAAS,6BAAmE,YAAkD;AACnI,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,qBAAqB,UAAU;AACxC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/ImageData/blend-modes.ts","../src/_types.ts","../src/ImageData/blit.ts","../src/ImageData/mask.ts","../src/ImageData/read-write-pixels.ts","../src/ImageData/serialization.ts","../src/color.ts"],"sourcesContent":["import type { BlendColor32, Color32 } from '../_types'\n\nexport const sourceOverColor32: BlendColor32 = (src, dst) => {\n const a = (src >>> 24) & 0xFF\n if (a === 255) return src\n if (a === 0) return dst\n\n // Pattern: (src * a + dst * (255 - a)) >> 8\n // We process RB and G separately so they don't overflow into each other\n const rbMask = 0xFF00FF\n const gMask = 0x00FF00\n\n const sRB = src & rbMask\n const sG = src & gMask\n const dRB = dst & rbMask\n const dG = dst & gMask\n\n const invA = 255 - a\n\n const outRB = ((sRB * a + dRB * invA) >> 8) & rbMask\n const outG = ((sG * a + dG * invA) >> 8) & gMask\n\n // Re-pack with opaque alpha (or calculate combined alpha if needed)\n const outA = (a + (((dst >>> 24) & 0xFF) * invA >> 8))\n return ((outA << 24) | outRB | outG) >>> 0 as Color32\n}\n\n/**\n * Screen: Lightens the destination (inverse of Multiply).\n * Result = 1 - ((1 - Src) * (1 - Dst))\n */\nexport const screenColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math\n const br = 255 - (((255 - (src & 0xFF)) * (255 - dr)) >> 8)\n const bg = 255 - (((255 - ((src >> 8) & 0xFF)) * (255 - dg)) >> 8)\n const bb = 255 - (((255 - ((src >> 16) & 0xFF)) * (255 - db)) >> 8)\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Linear Dodge (Additive): Simply adds the source to the destination.\n * Clamps at 255.\n */\nexport const linearDodgeColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math (Additive with clamping)\n const br = Math.min(255, (src & 0xFF) + dr)\n const bg = Math.min(255, ((src >> 8) & 0xFF) + dg)\n const bb = Math.min(255, ((src >> 16) & 0xFF) + db)\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Multiply: Darkens the destination based on the source color.\n * Result = (Src * Dst) / 255\n */\nexport const multiplyColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math\n const br = ((src & 0xFF) * dr) >> 8\n const bg = (((src >> 8) & 0xFF) * dg) >> 8\n const bb = (((src >> 16) & 0xFF) * db) >> 8\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Difference: Subtracts the darker color from the lighter color.\n * Result = |Src - Dst|\n */\nexport const differenceColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math\n const br = Math.abs((src & 0xFF) - dr)\n const bg = Math.abs(((src >> 8) & 0xFF) - dg)\n const bb = Math.abs(((src >> 16) & 0xFF) - db)\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Hard Light: Decides Multiply vs Screen based on SOURCE brightness.\n * Acts like a harsh spotlight.\n */\nexport const hardLightColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const sr = src & 0xFF, sg = (src >> 8) & 0xFF, sb = (src >> 16) & 0xFF\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math\n const br = sr < 128 ? (2 * sr * dr) >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8)\n const bg = sg < 128 ? (2 * sg * dg) >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8)\n const bb = sb < 128 ? (2 * sb * db) >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8)\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Color Burn: Darkens the destination to reflect the source color.\n * Intense saturation in the darks.\n */\nexport const colorBurnColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const sr = src & 0xFF, sg = (src >> 8) & 0xFF, sb = (src >> 16) & 0xFF\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math (Avoid division by zero)\n const br = dr === 255 ? 255 : Math.max(0, 255 - ((255 - dr) << 8) / (sr || 1))\n const bg = dg === 255 ? 255 : Math.max(0, 255 - ((255 - dg) << 8) / (sg || 1))\n const bb = db === 255 ? 255 : Math.max(0, 255 - ((255 - db) << 8) / (sb || 1))\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n/**\n * Overlay: The classic \"Contrast\" mode.\n * Decides Multiply vs Screen based on DESTINATION brightness.\n */\nexport const overlayColor32: BlendColor32 = (src, dst) => {\n const sa = (src >>> 24) & 0xFF\n if (sa === 0) return dst\n\n const sr = src & 0xFF, sg = (src >> 8) & 0xFF, sb = (src >> 16) & 0xFF\n const dr = dst & 0xFF, dg = (dst >> 8) & 0xFF, db = (dst >> 16) & 0xFF\n\n // 1. Core Math\n const br = dr < 128 ? (2 * sr * dr) >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8)\n const bg = dg < 128 ? (2 * sg * dg) >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8)\n const bb = db < 128 ? (2 * sb * db) >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8)\n\n if (sa === 255) return (0xFF000000 | (bb << 16) | (bg << 8) | br) >>> 0 as Color32\n\n // 2. Alpha Lerp inlined\n const invA = 255 - sa\n const r = (br * sa + dr * invA) >> 8\n const g = (bg * sa + dg * invA) >> 8\n const b = (bb * sa + db * invA) >> 8\n const a = (255 * sa + ((dst >>> 24) & 0xFF) * invA) >> 8\n\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\nexport const COLOR_32_BLEND_MODES = {\n sourceOver: sourceOverColor32,\n screen: screenColor32,\n linearDodge: linearDodgeColor32,\n multiply: multiplyColor32,\n difference: differenceColor32,\n overlay: overlayColor32,\n hardLight: hardLightColor32,\n colorBurn: colorBurnColor32,\n}\n","// ALL values are 0-255 (including alpha which in CSS is 0-1)\nexport type RGBA = { r: number, g: number, b: number, a: number }\n\n// A 32-bit integer containing r,g,b,a data\nexport type Color32 = number & { readonly __brandColor32: unique symbol }\n\nexport type BlendColor32 = (src: Color32, dst: Color32) => Color32\n\nexport type ImageDataLike = {\n width: number\n height: number\n data: Uint8ClampedArray<ArrayBuffer>\n}\n\nexport type SerializedImageData = {\n width: number\n height: number\n data: string\n}\n\nexport type Base64EncodedUInt8Array = string & { readonly __brandBase64UInt8Array: unique symbol }\n\nexport type Rect = { x: number; y: number; w: number; h: number }\n\nexport enum MaskType {\n ALPHA,\n BINARY\n}\n\ninterface BaseMaskData {\n readonly width: number\n readonly height: number\n readonly data: Uint8Array\n}\n\nexport interface AlphaMask extends BaseMaskData {\n readonly type: MaskType.ALPHA\n}\n\nexport interface BinaryMask extends BaseMaskData {\n readonly type: MaskType.BINARY\n}\n\nexport type AnyMask = AlphaMask | BinaryMask\n","import { type AnyMask, type BlendColor32, type Color32, type ImageDataLike, MaskType } from '../_types'\nimport { sourceOverColor32 } from './blend-modes'\n\nexport type BlendImageDataOptions = {\n /**\n * The x-coordinate in the destination image where the blend begins.\n * @default 0\n */\n dx?: number\n\n /**\n * The y-coordinate in the destination image where the blend begins.\n * @default 0\n */\n dy?: number\n\n /**\n * The x-coordinate of the top-left corner of the sub-rectangle\n * of the source image to extract.\n * @default 0\n */\n sx?: number\n\n /**\n * The y-coordinate of the top-left corner of the sub-rectangle\n * of the source image to extract.\n * @default 0\n */\n sy?: number\n\n /**\n * The width of the sub-rectangle of the source image to extract.\n * Defaults to the full remaining width of the source.\n */\n sw?: number\n\n /**\n * The height of the sub-rectangle of the source image to extract.\n * Defaults to the full remaining height of the source.\n */\n sh?: number\n\n /**\n * Overall layer opacity, typically ranging from 0.0 (transparent) to 1.0 (opaque).\n * @default 1.0\n */\n opacity?: number\n\n /**\n * Same as opacity but is 0-255 and faster when processing. If Present opacity is ignored.\n * @default undefined\n */\n alpha?: number\n\n /**\n * An optional alpha mask buffer.\n * The values in this array (0-255) determine the intensity of the blend\n * at each corresponding pixel.\n */\n mask?: AnyMask | null\n\n /**\n * The specific blending function/algorithm to use for pixel math\n * (e.g., Multiply, Screen, Overlay).\n */\n blendFn?: BlendColor32\n};\n\n/**\n * Blits source ImageData into a destination ImageData using 32-bit integer bitwise blending.\n * This function bypasses standard Canvas API limitations by operating directly on\n * Uint32Array views. It supports various blend modes, binary/alpha masking, and\n * automatic clipping of both source and destination bounds.\n * @example\n * blendImageData32(ctx.getImageData(0,0,100,100), sprite, {\n * blendFn: COLOR_32_BLEND_MODES.multiply,\n * mask: brushMask,\n * maskMode: MaskMode.ALPHA\n * });\n */\nexport function blendImageData(\n dst: ImageDataLike,\n src: ImageDataLike,\n opts: BlendImageDataOptions,\n) {\n let {\n dx = 0,\n dy = 0,\n sx = 0,\n sy = 0,\n sw = src.width,\n sh = src.height,\n opacity = 1,\n alpha,\n blendFn = sourceOverColor32,\n mask,\n } = opts\n\n // 1. Clip Source Area\n if (sx < 0) {\n dx -= sx\n sw += sx\n sx = 0\n }\n if (sy < 0) {\n dy -= sy\n sh += sy\n sy = 0\n }\n sw = Math.min(sw, src.width - sx)\n sh = Math.min(sh, src.height - sy)\n\n // 2. Clip Destination Area\n if (dx < 0) {\n sx -= dx\n sw += dx\n dx = 0\n }\n if (dy < 0) {\n sy -= dy\n sh += dy\n dy = 0\n }\n const actualW = Math.min(sw, dst.width - dx)\n const actualH = Math.min(sh, dst.height - dy)\n\n if (actualW <= 0 || actualH <= 0) return\n\n // 32-bit views of the same memory\n const dst32 = new Uint32Array(dst.data.buffer)\n const src32 = new Uint32Array(src.data.buffer)\n\n const dw = dst.width\n const sw_orig = src.width\n\n const gAlpha = alpha !== undefined\n ? (alpha | 0)\n : Math.round(opacity * 255)\n\n const maskIsAlpha = mask?.type === MaskType.ALPHA\n\n for (let iy = 0; iy < actualH; iy++) {\n const dRow = (iy + dy) * dw\n const sRow = (iy + sy) * sw_orig\n\n for (let ix = 0; ix < actualW; ix++) {\n const di = dRow + (ix + dx)\n const si = sRow + (ix + sx)\n\n let s = src32[si] as Color32\n let sa = (s >>> 24) & 0xFF\n\n // skip fully transparent pixel\n if (sa === 0) continue\n\n let activeWeight = gAlpha\n\n if (mask) {\n const m = mask.data[si]\n if (m === 0) continue\n activeWeight = maskIsAlpha ? (m * activeWeight + 128) >> 8 : activeWeight\n }\n\n if (activeWeight < 255) {\n sa = (sa * activeWeight + 128) >> 8\n }\n\n // If combined alpha is 0 after masking/opacity, skip the blend math\n if (sa === 0) continue\n\n // Re-pack source with final calculated alpha\n s = ((s & 0x00FFFFFF) | (sa << 24)) >>> 0 as Color32\n\n dst32[di] = blendFn(s, dst32[di] as Color32)\n }\n }\n}\n","import type { AlphaMask, BinaryMask, ImageDataLike } from '../_types'\n\nexport type ApplyMaskOptions = {\n /**\n * The x-coordinate in the destination image where the mask begins.\n * @default 0\n */\n dx?: number\n\n /**\n * The y-coordinate in the destination image where the mask begins.\n * @default 0\n */\n dy?: number\n\n /**\n * The x-coordinate of the top-left corner of the sub-rectangle\n * of the source image to extract.\n * @default 0\n */\n sx?: number\n\n /**\n * The y-coordinate of the top-left corner of the sub-rectangle\n * of the source image to extract.\n * @default 0\n */\n sy?: number\n\n /**\n * The width of the sub-rectangle of the source image to extract.\n * Defaults to the full remaining width of the source.\n */\n sw?: number\n\n /**\n * The height of the sub-rectangle of the source image to extract.\n * Defaults to the full remaining height of the source.\n */\n sh?: number;\n}\n\n/**\n * Applies a binary (on/off) mask to an RGBA buffer.\n * If mask value is 0, pixel becomes transparent.\n */\nexport function applyBinaryMask(\n dst: ImageDataLike,\n mask: BinaryMask,\n opts: ApplyMaskOptions = {},\n) {\n const { width: maskWidth, height: maskHeight } = mask\n\n const { dx = 0, dy = 0, sx = 0, sy = 0, sw = maskWidth, sh = maskHeight } = opts\n\n // 1. Calculate intersection boundaries\n const x0 = Math.max(0, dx, dx + (0 - sx))\n const y0 = Math.max(0, dy, dy + (0 - sy))\n const x1 = Math.min(dst.width, dx + sw, dx + (maskWidth - sx))\n const y1 = Math.min(dst.height, dy + sh, dy + (maskHeight - sy))\n\n if (x1 <= x0 || y1 <= y0) return\n\n const { data: dstData, width: dstW } = dst\n\n for (let y = y0; y < y1; y++) {\n const maskY = y - dy + sy\n const dstRowOffset = y * dstW * 4\n const maskRowOffset = maskY * maskWidth\n\n for (let x = x0; x < x1; x++) {\n const maskX = x - dx + sx\n const mIdx = maskRowOffset + maskX\n\n // Binary check: If mask is 0, kill the alpha\n if (mask.data[mIdx] === 0) {\n const aIdx = dstRowOffset + (x * 4) + 3\n dstData[aIdx] = 0\n }\n }\n }\n\n return dst\n}\n\n/**\n * Applies a smooth alpha mask to an RGBA buffer.\n * Multiplies existing Alpha by (maskValue / 255).\n */\nexport function applyAlphaMask(\n dst: ImageData,\n mask: AlphaMask,\n opts: ApplyMaskOptions = {},\n): void {\n let { dx = 0, dy = 0, sx = 0, sy = 0, sw = mask.width, sh = mask.height } = opts\n\n // 1. Clipping Logic\n if (dx < 0) {\n sx -= dx\n sw += dx\n dx = 0\n }\n if (dy < 0) {\n sy -= dy\n sh += dy\n dy = 0\n }\n if (sx < 0) {\n dx -= sx\n sw += sx\n sx = 0\n }\n if (sy < 0) {\n dy -= sy\n sh += sy\n sy = 0\n }\n const actualW = Math.min(sw, dst.width - dx, mask.width - sx)\n const actualH = Math.min(sh, dst.height - dy, mask.height - sy)\n\n if (actualW <= 0 || actualH <= 0) return\n\n const dData = dst.data\n const mData = mask.data\n const dW = dst.width\n const mW = mask.width\n\n for (let y = 0; y < actualH; y++) {\n const dOffset = ((dy + y) * dW + dx) << 2\n const mOffset = (sy + y) * mW + sx\n\n for (let x = 0; x < actualW; x++) {\n const mVal = mData[mOffset + x]\n\n if (mVal === 255) continue\n\n const aIdx = dOffset + (x << 2) + 3\n\n // --- BRANCH: Zero Alpha ---\n if (mVal === 0) {\n dData[aIdx] = 0\n continue\n }\n\n // To get 101 from 200 * 128, we use the bias (a * m + 257) >> 8\n // 25600 + 257 = 25857. 25857 >> 8 = 101.\n dData[aIdx] = (dData[aIdx] * mVal + 257) >> 8\n }\n }\n}\n","import type { Color32, ImageDataLike, Rect } from '../_types'\n\nexport function makeImageDataColor32Adapter(imageData: ImageDataLike) {\n const data32 = new Uint32Array(imageData.data.buffer)\n\n function inBounds(x: number, y: number) {\n return x < 0 || x >= imageData.width || y < 0 || y >= imageData.height\n }\n\n function setPixel(\n x: number,\n y: number,\n color: Color32,\n ): void {\n if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return\n data32[y * imageData.width + x] = color\n }\n\n function getPixel(\n x: number,\n y: number,\n ): Color32 | undefined {\n if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return\n\n return data32[y * imageData.width + x] as Color32\n }\n\n return {\n inBounds,\n imageData,\n data32,\n setPixel,\n getPixel,\n }\n}\n\nexport function extractPixelData(\n imageData: ImageDataLike,\n rect: Rect,\n): Uint8ClampedArray\n\nexport function extractPixelData(\n imageData: ImageDataLike,\n x: number,\n y: number,\n w: number,\n h: number,\n): Uint8ClampedArray\nexport function extractPixelData(\n imageData: ImageDataLike,\n _x: Rect | number,\n _y?: number,\n _w?: number,\n _h?: number,\n): Uint8ClampedArray {\n const { x, y, w, h } = typeof _x === 'object'\n ? _x\n : { x: _x, y: _y!, w: _w!, h: _h! }\n\n const { width: srcW, height: srcH, data: src } = imageData\n // Safety check for invalid dimensions\n if (w <= 0 || h <= 0) return new Uint8ClampedArray(0)\n const out = new Uint8ClampedArray(w * h * 4)\n\n const x0 = Math.max(0, x)\n const y0 = Math.max(0, y)\n const x1 = Math.min(srcW, x + w)\n const y1 = Math.min(srcH, y + h)\n\n // If no intersection, return the empty\n if (x1 <= x0 || y1 <= y0) return out\n\n for (let row = 0; row < (y1 - y0); row++) {\n // Where to read from the source canvas\n const srcRow = y0 + row\n const srcStart = (srcRow * srcW + x0) * 4\n const rowLen = (x1 - x0) * 4\n\n // Where to write into the 'out' patch\n const dstRow = (y0 - y) + row\n const dstCol = (x0 - x)\n const dstStart = (dstRow * w + dstCol) * 4\n\n // Perform the high-speed bulk copy\n out.set(src.subarray(srcStart, srcStart + rowLen), dstStart)\n }\n\n return out\n}\n\nexport function copyImageData({ data, width, height }: ImageDataLike): ImageData {\n return new ImageData(data.slice(), width, height)\n}\n\nexport function copyImageDataLike({ data, width, height }: ImageDataLike): ImageDataLike {\n return {\n data: data.slice(),\n width,\n height,\n }\n}\n","import type { Base64EncodedUInt8Array, ImageDataLike, SerializedImageData } from '../_types'\n\nexport function base64EncodeArrayBuffer(buffer: ArrayBufferLike): Base64EncodedUInt8Array {\n const binary = String.fromCharCode(...new Uint8Array(buffer))\n return btoa(binary) as Base64EncodedUInt8Array\n}\n\nexport function base64DecodeArrayBuffer(encoded: Base64EncodedUInt8Array): Uint8ClampedArray<ArrayBuffer> {\n const binary = atob(encoded)\n const bytes = new Uint8ClampedArray(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n}\n\n/**\n * Serialize for use in JSON. Pixel data is stored as base64 encoded string.\n */\nexport function serializeImageData<T extends ImageDataLike>(imageData: T): SerializedImageData {\n return {\n width: imageData.width,\n height: imageData.height,\n data: base64EncodeArrayBuffer(imageData.data.buffer),\n }\n}\n\nexport function serializeNullableImageData<T extends ImageDataLike | null>(imageData: T): T extends null ? null : SerializedImageData {\n if (!imageData) return null as any\n\n return serializeImageData(imageData) as any\n}\n\nexport function deserializeRawImageData<T extends SerializedImageData>(serialized: T): ImageDataLike {\n return {\n width: serialized.width,\n height: serialized.height,\n data: base64DecodeArrayBuffer(serialized.data as Base64EncodedUInt8Array),\n }\n}\n\nexport function deserializeImageData<T extends SerializedImageData>(serialized: T): ImageData {\n const data = base64DecodeArrayBuffer(serialized.data as Base64EncodedUInt8Array)\n\n return new ImageData(data as ImageDataArray, serialized.width, serialized.height) as any\n}\n\nexport function deserializeNullableImageData<T extends SerializedImageData | null>(serialized: T): T extends null ? null : ImageData {\n if (!serialized) return null as any\n return deserializeImageData(serialized) as any\n}\n","import type { Color32, RGBA } from './_types'\n\n/**\n * Packs RGBA into a 32-bit integer compatible with\n * Little-Endian Uint32Array views on ImageData.\n */\nexport function packColor(r: number, g: number, b: number, a: number): Color32 {\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\nexport function packRGBA({ r, g, b, a }: RGBA): Color32 {\n return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\nexport const unpackRed = (packed: Color32): number => (packed >>> 0) & 0xFF\nexport const unpackGreen = (packed: Color32): number => (packed >>> 8) & 0xFF\nexport const unpackBlue = (packed: Color32): number => (packed >>> 16) & 0xFF\nexport const unpackAlpha = (packed: Color32): number => (packed >>> 24) & 0xFF\n\nexport function unpackColor(packed: Color32): RGBA {\n return {\n r: (packed >>> 0) & 0xFF,\n g: (packed >>> 8) & 0xFF,\n b: (packed >>> 16) & 0xFF,\n a: (packed >>> 24) & 0xFF,\n }\n}\n\nconst SCRATCH_RGBA: RGBA = { r: 0, g: 0, b: 0, a: 0 }\n\n// uses a scratch arg for memory perf. Be careful about re-use.\nexport function unpackColorTo(packed: Color32, scratch = SCRATCH_RGBA): RGBA {\n scratch.r = (packed >>> 0) & 0xFF\n scratch.g = (packed >>> 8) & 0xFF\n scratch.b = (packed >>> 16) & 0xFF\n scratch.a = (packed >>> 24) & 0xFF\n return scratch\n}\n\nexport function colorDistance(a: Color32, b: Color32): number {\n const dr = (a & 0xFF) - (b & 0xFF)\n const dg = ((a >>> 8) & 0xFF) - ((b >>> 8) & 0xFF)\n const db = ((a >>> 16) & 0xFF) - ((b >>> 16) & 0xFF)\n const da = ((a >>> 24) & 0xFF) - ((b >>> 24) & 0xFF)\n return dr * dr + dg * dg + db * db + da * da\n}\n\n/**\n * Linearly interpolates between two 32-bit colors using a floating-point weight.\n * * This is the preferred method for UI animations or scenarios where high\n * precision is required. It uses the standard `a + t * (b - a)` formula\n * for each channel.\n * @param a - The starting color as a 32-bit integer (AABBGGRR).\n * @param b - The target color as a 32-bit integer (AABBGGRR).\n * @param t - The interpolation factor between 0.0 and 1.0.\n * @returns The interpolated 32-bit color.\n */\nexport function lerpColor32(a: Color32, b: Color32, t: number): Color32 {\n const r = (a & 0xFF) + t * ((b & 0xFF) - (a & 0xFF))\n const g = ((a >>> 8) & 0xFF) + t * (((b >>> 8) & 0xFF) - ((a >>> 8) & 0xFF))\n const b_ = ((a >>> 16) & 0xFF) + t * (((b >>> 16) & 0xFF) - ((a >>> 16) & 0xFF))\n const a_ = ((a >>> 24) & 0xFF) + t * (((b >>> 24) & 0xFF) - ((a >>> 24) & 0xFF))\n\n return ((a_ << 24) | (b_ << 16) | (g << 8) | r) >>> 0 as Color32\n}\n\n/**\n * Linearly interpolates between two 32-bit colors using integer fixed-point math.\n * Highly optimized for image processing and real-time blitting. It processes\n * channels in parallel using bitmasks (RB and GA pairs).\n * @note Subject to a 1-bit drift (rounding down) due to fast bit-shift division.\n * @param src - The source (foreground) color as a 32-bit integer.\n * @param dst - The destination (background) color as a 32-bit integer.\n * @param w - The blend weight as a byte value from 0 to 255. Where 0 is 100% dst and 255 is 100% src\n * @returns The blended 32-bit color.\n */export function lerpColor32Fast(src: Color32, dst: Color32, w: number): Color32 {\n const invA = 255 - w;\n\n // Masking Red and Blue: 0x00FF00FF\n // We process R and B in one go, then shift back down\n const rb = (((src & 0x00FF00FF) * w + (dst & 0x00FF00FF) * invA) >>> 8) & 0x00FF00FF;\n\n // Masking Green and Alpha: 0xFF00FF00\n // We shift down first to avoid overflow, then shift back up\n const ga = ((((src >>> 8) & 0x00FF00FF) * w + ((dst >>> 8) & 0x00FF00FF) * invA) >>> 8) & 0x00FF00FF;\n\n return (rb | (ga << 8)) >>> 0 as Color32;\n}\n\n// Convert 0xAABBGGRR to #RRGGBBAA\nexport function color32ToHex(color: Color32): string {\n const r = (color & 0xFF).toString(16).padStart(2, '0')\n const g = ((color >>> 8) & 0xFF).toString(16).padStart(2, '0')\n const b = ((color >>> 16) & 0xFF).toString(16).padStart(2, '0')\n const a = ((color >>> 24) & 0xFF).toString(16).padStart(2, '0')\n return `#${r}${g}${b}${a}`\n}\n\n/**\n * Converts a 32-bit integer (0xAABBGGRR) to a CSS rgba() string.\n * Example: 0xFF0000FF -> \"rgba(255,0,0,1)\"\n */\nexport function color32ToCssRGBA(color: Color32): string {\n const r = color & 0xFF\n const g = (color >>> 8) & 0xFF\n const b = (color >>> 16) & 0xFF\n const a = (color >>> 24) & 0xFF\n\n const alpha = Number((a / 255).toFixed(3))\n\n return `rgba(${r},${g},${b},${alpha})`\n}\n"],"mappings":"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","names":["MaskType"]}
|