pixel-data-js 0.2.0 → 0.4.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.
@@ -22,27 +22,32 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  COLOR_32_BLEND_MODES: () => COLOR_32_BLEND_MODES,
24
24
  MaskType: () => MaskType,
25
- applyAlphaMask: () => applyAlphaMask,
26
- applyBinaryMask: () => applyBinaryMask,
25
+ applyMaskToPixelData: () => applyMaskToPixelData,
27
26
  base64DecodeArrayBuffer: () => base64DecodeArrayBuffer,
28
27
  base64EncodeArrayBuffer: () => base64EncodeArrayBuffer,
29
- blendImageData: () => blendImageData,
28
+ blendColorPixelData: () => blendColorPixelData,
29
+ blendPixelData: () => blendPixelData,
30
+ clearPixelData: () => clearPixelData,
30
31
  color32ToCssRGBA: () => color32ToCssRGBA,
31
32
  color32ToHex: () => color32ToHex,
32
33
  colorBurnColor32: () => colorBurnColor32,
33
34
  colorDistance: () => colorDistance,
34
35
  copyImageData: () => copyImageData,
35
36
  copyImageDataLike: () => copyImageDataLike,
37
+ copyMask: () => copyMask,
36
38
  deserializeImageData: () => deserializeImageData,
37
39
  deserializeNullableImageData: () => deserializeNullableImageData,
38
40
  deserializeRawImageData: () => deserializeRawImageData,
39
41
  differenceColor32: () => differenceColor32,
40
- extractPixelData: () => extractPixelData,
42
+ extractImageData: () => extractImageData,
43
+ fillPixelData: () => fillPixelData,
41
44
  hardLightColor32: () => hardLightColor32,
45
+ invertAlphaMask: () => invertAlphaMask,
46
+ invertBinaryMask: () => invertBinaryMask,
42
47
  lerpColor32: () => lerpColor32,
43
48
  lerpColor32Fast: () => lerpColor32Fast,
44
49
  linearDodgeColor32: () => linearDodgeColor32,
45
- makeImageDataColor32Adapter: () => makeImageDataColor32Adapter,
50
+ mergeMasks: () => mergeMasks,
46
51
  multiplyColor32: () => multiplyColor32,
47
52
  overlayColor32: () => overlayColor32,
48
53
  packColor: () => packColor,
@@ -56,11 +61,19 @@ __export(src_exports, {
56
61
  unpackColor: () => unpackColor,
57
62
  unpackColorTo: () => unpackColorTo,
58
63
  unpackGreen: () => unpackGreen,
59
- unpackRed: () => unpackRed
64
+ unpackRed: () => unpackRed,
65
+ writeImageData: () => writeImageData
60
66
  });
61
67
  module.exports = __toCommonJS(src_exports);
62
68
 
63
- // src/ImageData/blend-modes.ts
69
+ // src/_types.ts
70
+ var MaskType = /* @__PURE__ */ ((MaskType2) => {
71
+ MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
72
+ MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
73
+ return MaskType2;
74
+ })(MaskType || {});
75
+
76
+ // src/blend-modes.ts
64
77
  var sourceOverColor32 = (src, dst) => {
65
78
  const a = src >>> 24 & 255;
66
79
  if (a === 255) return src;
@@ -196,176 +209,83 @@ var COLOR_32_BLEND_MODES = {
196
209
  colorBurn: colorBurnColor32
197
210
  };
198
211
 
199
- // src/_types.ts
200
- var MaskType = /* @__PURE__ */ ((MaskType2) => {
201
- MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
202
- MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
203
- return MaskType2;
204
- })(MaskType || {});
205
-
206
- // src/ImageData/blit.ts
207
- function blendImageData(dst, src, opts) {
208
- let {
209
- dx = 0,
210
- dy = 0,
211
- sx = 0,
212
- sy = 0,
213
- sw = src.width,
214
- sh = src.height,
215
- opacity = 1,
216
- alpha,
217
- blendFn = sourceOverColor32,
218
- mask
219
- } = opts;
220
- if (sx < 0) {
221
- dx -= sx;
222
- sw += sx;
223
- sx = 0;
224
- }
225
- if (sy < 0) {
226
- dy -= sy;
227
- sh += sy;
228
- sy = 0;
229
- }
230
- sw = Math.min(sw, src.width - sx);
231
- sh = Math.min(sh, src.height - sy);
232
- if (dx < 0) {
233
- sx -= dx;
234
- sw += dx;
235
- dx = 0;
236
- }
237
- if (dy < 0) {
238
- sy -= dy;
239
- sh += dy;
240
- dy = 0;
241
- }
242
- const actualW = Math.min(sw, dst.width - dx);
243
- const actualH = Math.min(sh, dst.height - dy);
244
- if (actualW <= 0 || actualH <= 0) return;
245
- const dst32 = new Uint32Array(dst.data.buffer);
246
- const src32 = new Uint32Array(src.data.buffer);
247
- const dw = dst.width;
248
- const sw_orig = src.width;
249
- const gAlpha = alpha !== void 0 ? alpha | 0 : Math.round(opacity * 255);
250
- const maskIsAlpha = mask?.type === 0 /* ALPHA */;
251
- for (let iy = 0; iy < actualH; iy++) {
252
- const dRow = (iy + dy) * dw;
253
- const sRow = (iy + sy) * sw_orig;
254
- for (let ix = 0; ix < actualW; ix++) {
255
- const di = dRow + (ix + dx);
256
- const si = sRow + (ix + sx);
257
- let s = src32[si];
258
- let sa = s >>> 24 & 255;
259
- if (sa === 0) continue;
260
- let activeWeight = gAlpha;
261
- if (mask) {
262
- const m = mask.data[si];
263
- if (m === 0) continue;
264
- activeWeight = maskIsAlpha ? m * activeWeight + 128 >> 8 : activeWeight;
265
- }
266
- if (activeWeight < 255) {
267
- sa = sa * activeWeight + 128 >> 8;
268
- }
269
- if (sa === 0) continue;
270
- s = (s & 16777215 | sa << 24) >>> 0;
271
- dst32[di] = blendFn(s, dst32[di]);
272
- }
273
- }
212
+ // src/color.ts
213
+ function packColor(r, g, b, a) {
214
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
274
215
  }
275
-
276
- // src/ImageData/mask.ts
277
- function applyBinaryMask(dst, mask, opts = {}) {
278
- const { width: maskWidth, height: maskHeight } = mask;
279
- const { dx = 0, dy = 0, sx = 0, sy = 0, sw = maskWidth, sh = maskHeight } = opts;
280
- const x0 = Math.max(0, dx, dx + (0 - sx));
281
- const y0 = Math.max(0, dy, dy + (0 - sy));
282
- const x1 = Math.min(dst.width, dx + sw, dx + (maskWidth - sx));
283
- const y1 = Math.min(dst.height, dy + sh, dy + (maskHeight - sy));
284
- if (x1 <= x0 || y1 <= y0) return;
285
- const { data: dstData, width: dstW } = dst;
286
- for (let y = y0; y < y1; y++) {
287
- const maskY = y - dy + sy;
288
- const dstRowOffset = y * dstW * 4;
289
- const maskRowOffset = maskY * maskWidth;
290
- for (let x = x0; x < x1; x++) {
291
- const maskX = x - dx + sx;
292
- const mIdx = maskRowOffset + maskX;
293
- if (mask.data[mIdx] === 0) {
294
- const aIdx = dstRowOffset + x * 4 + 3;
295
- dstData[aIdx] = 0;
296
- }
297
- }
298
- }
299
- return dst;
216
+ function packRGBA({ r, g, b, a }) {
217
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
300
218
  }
301
- function applyAlphaMask(dst, mask, opts = {}) {
302
- let { dx = 0, dy = 0, sx = 0, sy = 0, sw = mask.width, sh = mask.height } = opts;
303
- if (dx < 0) {
304
- sx -= dx;
305
- sw += dx;
306
- dx = 0;
307
- }
308
- if (dy < 0) {
309
- sy -= dy;
310
- sh += dy;
311
- dy = 0;
312
- }
313
- if (sx < 0) {
314
- dx -= sx;
315
- sw += sx;
316
- sx = 0;
317
- }
318
- if (sy < 0) {
319
- dy -= sy;
320
- sh += sy;
321
- sy = 0;
322
- }
323
- const actualW = Math.min(sw, dst.width - dx, mask.width - sx);
324
- const actualH = Math.min(sh, dst.height - dy, mask.height - sy);
325
- if (actualW <= 0 || actualH <= 0) return;
326
- const dData = dst.data;
327
- const mData = mask.data;
328
- const dW = dst.width;
329
- const mW = mask.width;
330
- for (let y = 0; y < actualH; y++) {
331
- const dOffset = (dy + y) * dW + dx << 2;
332
- const mOffset = (sy + y) * mW + sx;
333
- for (let x = 0; x < actualW; x++) {
334
- const mVal = mData[mOffset + x];
335
- if (mVal === 255) continue;
336
- const aIdx = dOffset + (x << 2) + 3;
337
- if (mVal === 0) {
338
- dData[aIdx] = 0;
339
- continue;
340
- }
341
- dData[aIdx] = dData[aIdx] * mVal + 257 >> 8;
342
- }
343
- }
219
+ var unpackRed = (packed) => packed >>> 0 & 255;
220
+ var unpackGreen = (packed) => packed >>> 8 & 255;
221
+ var unpackBlue = (packed) => packed >>> 16 & 255;
222
+ var unpackAlpha = (packed) => packed >>> 24 & 255;
223
+ function unpackColor(packed) {
224
+ return {
225
+ r: packed >>> 0 & 255,
226
+ g: packed >>> 8 & 255,
227
+ b: packed >>> 16 & 255,
228
+ a: packed >>> 24 & 255
229
+ };
230
+ }
231
+ var SCRATCH_RGBA = { r: 0, g: 0, b: 0, a: 0 };
232
+ function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
233
+ scratch.r = packed >>> 0 & 255;
234
+ scratch.g = packed >>> 8 & 255;
235
+ scratch.b = packed >>> 16 & 255;
236
+ scratch.a = packed >>> 24 & 255;
237
+ return scratch;
238
+ }
239
+ function colorDistance(a, b) {
240
+ const dr = (a & 255) - (b & 255);
241
+ const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
242
+ const db = (a >>> 16 & 255) - (b >>> 16 & 255);
243
+ const da = (a >>> 24 & 255) - (b >>> 24 & 255);
244
+ return dr * dr + dg * dg + db * db + da * da;
245
+ }
246
+ function lerpColor32(a, b, t) {
247
+ const r = (a & 255) + t * ((b & 255) - (a & 255));
248
+ const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
249
+ const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
250
+ const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
251
+ return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
252
+ }
253
+ function lerpColor32Fast(src, dst, w) {
254
+ const invA = 255 - w;
255
+ const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
256
+ const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
257
+ return (rb | ga << 8) >>> 0;
258
+ }
259
+ function color32ToHex(color) {
260
+ const r = (color & 255).toString(16).padStart(2, "0");
261
+ const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
262
+ const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
263
+ const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
264
+ return `#${r}${g}${b}${a}`;
265
+ }
266
+ function color32ToCssRGBA(color) {
267
+ const r = color & 255;
268
+ const g = color >>> 8 & 255;
269
+ const b = color >>> 16 & 255;
270
+ const a = color >>> 24 & 255;
271
+ const alpha = Number((a / 255).toFixed(3));
272
+ return `rgba(${r},${g},${b},${alpha})`;
344
273
  }
345
274
 
346
- // src/ImageData/read-write-pixels.ts
347
- function makeImageDataColor32Adapter(imageData) {
348
- const data32 = new Uint32Array(imageData.data.buffer);
349
- function inBounds(x, y) {
350
- return x < 0 || x >= imageData.width || y < 0 || y >= imageData.height;
351
- }
352
- function setPixel(x, y, color) {
353
- if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return;
354
- data32[y * imageData.width + x] = color;
355
- }
356
- function getPixel(x, y) {
357
- if (x < 0 || x >= imageData.width || y < 0 || y >= imageData.height) return;
358
- return data32[y * imageData.width + x];
359
- }
275
+ // src/ImageData/copyImageData.ts
276
+ function copyImageData({ data, width, height }) {
277
+ return new ImageData(data.slice(), width, height);
278
+ }
279
+ function copyImageDataLike({ data, width, height }) {
360
280
  return {
361
- inBounds,
362
- imageData,
363
- data32,
364
- setPixel,
365
- getPixel
281
+ data: data.slice(),
282
+ width,
283
+ height
366
284
  };
367
285
  }
368
- function extractPixelData(imageData, _x, _y, _w, _h) {
286
+
287
+ // src/ImageData/extractImageData.ts
288
+ function extractImageData(imageData, _x, _y, _w, _h) {
369
289
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
370
290
  const { width: srcW, height: srcH, data: src } = imageData;
371
291
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
@@ -386,16 +306,6 @@ function extractPixelData(imageData, _x, _y, _w, _h) {
386
306
  }
387
307
  return out;
388
308
  }
389
- function copyImageData({ data, width, height }) {
390
- return new ImageData(data.slice(), width, height);
391
- }
392
- function copyImageDataLike({ data, width, height }) {
393
- return {
394
- data: data.slice(),
395
- width,
396
- height
397
- };
398
- }
399
309
 
400
310
  // src/ImageData/serialization.ts
401
311
  function base64EncodeArrayBuffer(buffer) {
@@ -437,93 +347,514 @@ function deserializeNullableImageData(serialized) {
437
347
  return deserializeImageData(serialized);
438
348
  }
439
349
 
440
- // src/color.ts
441
- function packColor(r, g, b, a) {
442
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
350
+ // src/ImageData/writeImageData.ts
351
+ function writeImageData(imageData, data, _x, _y, _w, _h) {
352
+ const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
353
+ const { width: dstW, height: dstH, data: dst } = imageData;
354
+ const x0 = Math.max(0, x);
355
+ const y0 = Math.max(0, y);
356
+ const x1 = Math.min(dstW, x + w);
357
+ const y1 = Math.min(dstH, y + h);
358
+ if (x1 <= x0 || y1 <= y0) return;
359
+ const rowLen = (x1 - x0) * 4;
360
+ const srcCol = x0 - x;
361
+ const srcYOffset = y0 - y;
362
+ const actualH = y1 - y0;
363
+ for (let row = 0; row < actualH; row++) {
364
+ const dstStart = ((y0 + row) * dstW + x0) * 4;
365
+ const srcRow = srcYOffset + row;
366
+ const o = (srcRow * w + srcCol) * 4;
367
+ dst.set(data.subarray(o, o + rowLen), dstStart);
368
+ }
443
369
  }
444
- function packRGBA({ r, g, b, a }) {
445
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
370
+
371
+ // src/Mask/copyMask.ts
372
+ function copyMask(src) {
373
+ return src.slice();
446
374
  }
447
- var unpackRed = (packed) => packed >>> 0 & 255;
448
- var unpackGreen = (packed) => packed >>> 8 & 255;
449
- var unpackBlue = (packed) => packed >>> 16 & 255;
450
- var unpackAlpha = (packed) => packed >>> 24 & 255;
451
- function unpackColor(packed) {
452
- return {
453
- r: packed >>> 0 & 255,
454
- g: packed >>> 8 & 255,
455
- b: packed >>> 16 & 255,
456
- a: packed >>> 24 & 255
457
- };
375
+
376
+ // src/Mask/invertMask.ts
377
+ function invertBinaryMask(dst) {
378
+ const len = dst.length;
379
+ for (let i = 0; i < len; i++) {
380
+ dst[i] = dst[i] === 0 ? 1 : 0;
381
+ }
458
382
  }
459
- var SCRATCH_RGBA = { r: 0, g: 0, b: 0, a: 0 };
460
- function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
461
- scratch.r = packed >>> 0 & 255;
462
- scratch.g = packed >>> 8 & 255;
463
- scratch.b = packed >>> 16 & 255;
464
- scratch.a = packed >>> 24 & 255;
465
- return scratch;
383
+ function invertAlphaMask(dst) {
384
+ const len = dst.length;
385
+ for (let i = 0; i < len; i++) {
386
+ dst[i] = 255 - dst[i];
387
+ }
466
388
  }
467
- function colorDistance(a, b) {
468
- const dr = (a & 255) - (b & 255);
469
- const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
470
- const db = (a >>> 16 & 255) - (b >>> 16 & 255);
471
- const da = (a >>> 24 & 255) - (b >>> 24 & 255);
472
- return dr * dr + dg * dg + db * db + da * da;
389
+
390
+ // src/Mask/mergeMasks.ts
391
+ function mergeMasks(dst, dstWidth, src, opts) {
392
+ const {
393
+ x: targetX = 0,
394
+ y: targetY = 0,
395
+ w: width = 0,
396
+ h: height = 0,
397
+ alpha: globalAlpha = 255,
398
+ maskType = 0 /* ALPHA */,
399
+ mw,
400
+ mx = 0,
401
+ my = 0,
402
+ invertMask = false
403
+ } = opts;
404
+ if (width <= 0 || height <= 0 || globalAlpha === 0) {
405
+ return;
406
+ }
407
+ const sPitch = mw ?? width;
408
+ const isAlpha = maskType === 0 /* ALPHA */;
409
+ for (let iy = 0; iy < height; iy++) {
410
+ const dy = targetY + iy;
411
+ const sy = my + iy;
412
+ if (dy < 0 || sy < 0) {
413
+ continue;
414
+ }
415
+ for (let ix = 0; ix < width; ix++) {
416
+ const dx = targetX + ix;
417
+ const sx = mx + ix;
418
+ if (dx < 0 || dx >= dstWidth || sx < 0 || sx >= sPitch) {
419
+ continue;
420
+ }
421
+ const dIdx = dy * dstWidth + dx;
422
+ const sIdx = sy * sPitch + sx;
423
+ const mVal = src[sIdx];
424
+ let weight = globalAlpha;
425
+ if (isAlpha) {
426
+ const effectiveM = invertMask ? 255 - mVal : mVal;
427
+ if (effectiveM === 0) {
428
+ dst[dIdx] = 0;
429
+ continue;
430
+ }
431
+ weight = globalAlpha === 255 ? effectiveM : effectiveM * globalAlpha + 128 >> 8;
432
+ } else {
433
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
434
+ if (!isHit) {
435
+ dst[dIdx] = 0;
436
+ continue;
437
+ }
438
+ weight = globalAlpha;
439
+ }
440
+ if (weight === 0) {
441
+ dst[dIdx] = 0;
442
+ continue;
443
+ }
444
+ const da = dst[dIdx];
445
+ if (da === 0) {
446
+ } else if (weight === 255) {
447
+ } else if (da === 255) {
448
+ dst[dIdx] = weight;
449
+ } else {
450
+ dst[dIdx] = da * weight + 128 >> 8;
451
+ }
452
+ }
453
+ }
473
454
  }
474
- function lerpColor32(a, b, t) {
475
- const r = (a & 255) + t * ((b & 255) - (a & 255));
476
- const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
477
- const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
478
- const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
479
- return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
455
+
456
+ // src/PixelData/applyMaskToPixelData.ts
457
+ function applyMaskToPixelData(dst, mask, opts) {
458
+ const {
459
+ x: targetX = 0,
460
+ y: targetY = 0,
461
+ w: width = dst.width,
462
+ h: height = dst.height,
463
+ alpha: globalAlpha = 255,
464
+ maskType = 0 /* ALPHA */,
465
+ mw,
466
+ mx = 0,
467
+ my = 0,
468
+ invertMask = false
469
+ } = opts;
470
+ let x = targetX;
471
+ let y = targetY;
472
+ let w = width;
473
+ let h = height;
474
+ if (x < 0) {
475
+ w += x;
476
+ x = 0;
477
+ }
478
+ if (y < 0) {
479
+ h += y;
480
+ y = 0;
481
+ }
482
+ const actualW = Math.min(w, dst.width - x);
483
+ const actualH = Math.min(h, dst.height - y);
484
+ if (actualW <= 0 || actualH <= 0 || globalAlpha === 0) {
485
+ return;
486
+ }
487
+ const dst32 = dst.data32;
488
+ const dw = dst.width;
489
+ const mPitch = mw ?? width;
490
+ const isAlpha = maskType === 0 /* ALPHA */;
491
+ const dx = x - targetX;
492
+ const dy = y - targetY;
493
+ let dIdx = y * dw + x;
494
+ let mIdx = (my + dy) * mPitch + (mx + dx);
495
+ const dStride = dw - actualW;
496
+ const mStride = mPitch - actualW;
497
+ for (let iy = 0; iy < actualH; iy++) {
498
+ for (let ix = 0; ix < actualW; ix++) {
499
+ const mVal = mask[mIdx];
500
+ let weight = globalAlpha;
501
+ if (isAlpha) {
502
+ const effectiveM = invertMask ? 255 - mVal : mVal;
503
+ if (effectiveM === 0) {
504
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
505
+ dIdx++;
506
+ mIdx++;
507
+ continue;
508
+ }
509
+ weight = globalAlpha === 255 ? effectiveM : effectiveM * globalAlpha + 128 >> 8;
510
+ } else {
511
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
512
+ if (!isHit) {
513
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
514
+ dIdx++;
515
+ mIdx++;
516
+ continue;
517
+ }
518
+ weight = globalAlpha;
519
+ }
520
+ if (weight === 0) {
521
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
522
+ } else {
523
+ const d = dst32[dIdx];
524
+ const da = d >>> 24;
525
+ let finalAlpha = da;
526
+ if (da === 0) {
527
+ } else if (weight === 255) {
528
+ } else if (da === 255) {
529
+ finalAlpha = weight;
530
+ } else {
531
+ finalAlpha = da * weight + 128 >> 8;
532
+ }
533
+ dst32[dIdx] = (d & 16777215 | finalAlpha << 24) >>> 0;
534
+ }
535
+ dIdx++;
536
+ mIdx++;
537
+ }
538
+ dIdx += dStride;
539
+ mIdx += mStride;
540
+ }
480
541
  }
481
- function lerpColor32Fast(src, dst, w) {
482
- const invA = 255 - w;
483
- const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
484
- const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
485
- return (rb | ga << 8) >>> 0;
542
+
543
+ // src/PixelData/blendColorPixelData.ts
544
+ function blendColorPixelData(dst, color, opts) {
545
+ const {
546
+ x: targetX = 0,
547
+ y: targetY = 0,
548
+ w: width = dst.width,
549
+ h: height = dst.height,
550
+ alpha: globalAlpha = 255,
551
+ blendFn = sourceOverColor32,
552
+ mask,
553
+ maskType = 0 /* ALPHA */,
554
+ mw,
555
+ mx = 0,
556
+ my = 0,
557
+ invertMask = false
558
+ } = opts;
559
+ if (globalAlpha === 0) return;
560
+ let x = targetX;
561
+ let y = targetY;
562
+ let w = width;
563
+ let h = height;
564
+ if (x < 0) {
565
+ w += x;
566
+ x = 0;
567
+ }
568
+ if (y < 0) {
569
+ h += y;
570
+ y = 0;
571
+ }
572
+ const actualW = Math.min(w, dst.width - x);
573
+ const actualH = Math.min(h, dst.height - y);
574
+ if (actualW <= 0 || actualH <= 0) return;
575
+ const dst32 = dst.data32;
576
+ const dw = dst.width;
577
+ const mPitch = mw ?? width;
578
+ const isAlphaMask = maskType === 0 /* ALPHA */;
579
+ const dx = x - targetX;
580
+ const dy = y - targetY;
581
+ let dIdx = y * dw + x;
582
+ let mIdx = (my + dy) * mPitch + (mx + dx);
583
+ const dStride = dw - actualW;
584
+ const mStride = mPitch - actualW;
585
+ const baseSrcColor = color;
586
+ const baseSrcAlpha = baseSrcColor >>> 24;
587
+ for (let iy = 0; iy < actualH; iy++) {
588
+ for (let ix = 0; ix < actualW; ix++) {
589
+ if (baseSrcAlpha === 0) {
590
+ dIdx++;
591
+ mIdx++;
592
+ continue;
593
+ }
594
+ let weight = globalAlpha;
595
+ if (mask) {
596
+ const mVal = mask[mIdx];
597
+ if (isAlphaMask) {
598
+ const effectiveM = invertMask ? 255 - mVal : mVal;
599
+ if (effectiveM === 0) {
600
+ dIdx++;
601
+ mIdx++;
602
+ continue;
603
+ }
604
+ if (globalAlpha === 255) {
605
+ weight = effectiveM;
606
+ } else if (effectiveM === 255) {
607
+ weight = globalAlpha;
608
+ } else {
609
+ weight = effectiveM * globalAlpha + 128 >> 8;
610
+ }
611
+ } else {
612
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
613
+ if (!isHit) {
614
+ dIdx++;
615
+ mIdx++;
616
+ continue;
617
+ }
618
+ weight = globalAlpha;
619
+ }
620
+ if (weight === 0) {
621
+ dIdx++;
622
+ mIdx++;
623
+ continue;
624
+ }
625
+ }
626
+ let currentSrcAlpha = baseSrcAlpha;
627
+ let currentSrcColor = baseSrcColor;
628
+ if (weight < 255) {
629
+ if (baseSrcAlpha === 255) {
630
+ currentSrcAlpha = weight;
631
+ } else {
632
+ currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
633
+ }
634
+ if (currentSrcAlpha === 0) {
635
+ dIdx++;
636
+ mIdx++;
637
+ continue;
638
+ }
639
+ currentSrcColor = (baseSrcColor & 16777215 | currentSrcAlpha << 24) >>> 0;
640
+ }
641
+ dst32[dIdx] = blendFn(currentSrcColor, dst32[dIdx]);
642
+ dIdx++;
643
+ mIdx++;
644
+ }
645
+ dIdx += dStride;
646
+ mIdx += mStride;
647
+ }
486
648
  }
487
- function color32ToHex(color) {
488
- const r = (color & 255).toString(16).padStart(2, "0");
489
- const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
490
- const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
491
- const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
492
- return `#${r}${g}${b}${a}`;
649
+
650
+ // src/PixelData/blendPixelData.ts
651
+ function blendPixelData(dst, src, opts) {
652
+ const {
653
+ x: targetX = 0,
654
+ y: targetY = 0,
655
+ sx: sourceX = 0,
656
+ sy: sourceY = 0,
657
+ w: width = src.width,
658
+ h: height = src.height,
659
+ alpha: globalAlpha = 255,
660
+ blendFn = sourceOverColor32,
661
+ mask,
662
+ maskType = 0 /* ALPHA */,
663
+ mw,
664
+ mx = 0,
665
+ my = 0,
666
+ invertMask = false
667
+ } = opts;
668
+ if (globalAlpha === 0) return;
669
+ let x = targetX;
670
+ let y = targetY;
671
+ let sx = sourceX;
672
+ let sy = sourceY;
673
+ let w = width;
674
+ let h = height;
675
+ if (sx < 0) {
676
+ x -= sx;
677
+ w += sx;
678
+ sx = 0;
679
+ }
680
+ if (sy < 0) {
681
+ y -= sy;
682
+ h += sy;
683
+ sy = 0;
684
+ }
685
+ w = Math.min(w, src.width - sx);
686
+ h = Math.min(h, src.height - sy);
687
+ if (x < 0) {
688
+ sx -= x;
689
+ w += x;
690
+ x = 0;
691
+ }
692
+ if (y < 0) {
693
+ sy -= y;
694
+ h += y;
695
+ y = 0;
696
+ }
697
+ const actualW = Math.min(w, dst.width - x);
698
+ const actualH = Math.min(h, dst.height - y);
699
+ if (actualW <= 0 || actualH <= 0) return;
700
+ const dst32 = dst.data32;
701
+ const src32 = src.data32;
702
+ const dw = dst.width;
703
+ const sw = src.width;
704
+ const mPitch = mw ?? width;
705
+ const isAlphaMask = maskType === 0 /* ALPHA */;
706
+ const dx = x - targetX;
707
+ const dy = y - targetY;
708
+ let dIdx = y * dw + x;
709
+ let sIdx = sy * sw + sx;
710
+ let mIdx = (my + dy) * mPitch + (mx + dx);
711
+ const dStride = dw - actualW;
712
+ const sStride = sw - actualW;
713
+ const mStride = mPitch - actualW;
714
+ for (let iy = 0; iy < actualH; iy++) {
715
+ for (let ix = 0; ix < actualW; ix++) {
716
+ const baseSrcColor = src32[sIdx];
717
+ const baseSrcAlpha = baseSrcColor >>> 24;
718
+ if (baseSrcAlpha === 0) {
719
+ dIdx++;
720
+ sIdx++;
721
+ mIdx++;
722
+ continue;
723
+ }
724
+ let weight = globalAlpha;
725
+ if (mask) {
726
+ const mVal = mask[mIdx];
727
+ if (isAlphaMask) {
728
+ const effectiveM = invertMask ? 255 - mVal : mVal;
729
+ if (effectiveM === 0) {
730
+ dIdx++;
731
+ sIdx++;
732
+ mIdx++;
733
+ continue;
734
+ }
735
+ if (globalAlpha === 255) {
736
+ weight = effectiveM;
737
+ } else if (effectiveM === 255) {
738
+ weight = globalAlpha;
739
+ } else {
740
+ weight = effectiveM * globalAlpha + 128 >> 8;
741
+ }
742
+ } else {
743
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
744
+ if (!isHit) {
745
+ dIdx++;
746
+ sIdx++;
747
+ mIdx++;
748
+ continue;
749
+ }
750
+ weight = globalAlpha;
751
+ }
752
+ if (weight === 0) {
753
+ dIdx++;
754
+ sIdx++;
755
+ mIdx++;
756
+ continue;
757
+ }
758
+ }
759
+ let currentSrcAlpha = baseSrcAlpha;
760
+ let currentSrcColor = baseSrcColor;
761
+ if (weight < 255) {
762
+ if (baseSrcAlpha === 255) {
763
+ currentSrcAlpha = weight;
764
+ } else {
765
+ currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
766
+ }
767
+ if (currentSrcAlpha === 0) {
768
+ dIdx++;
769
+ sIdx++;
770
+ mIdx++;
771
+ continue;
772
+ }
773
+ currentSrcColor = (baseSrcColor & 16777215 | currentSrcAlpha << 24) >>> 0;
774
+ }
775
+ dst32[dIdx] = blendFn(currentSrcColor, dst32[dIdx]);
776
+ dIdx++;
777
+ sIdx++;
778
+ mIdx++;
779
+ }
780
+ dIdx += dStride;
781
+ sIdx += sStride;
782
+ mIdx += mStride;
783
+ }
493
784
  }
494
- function color32ToCssRGBA(color) {
495
- const r = color & 255;
496
- const g = color >>> 8 & 255;
497
- const b = color >>> 16 & 255;
498
- const a = color >>> 24 & 255;
499
- const alpha = Number((a / 255).toFixed(3));
500
- return `rgba(${r},${g},${b},${alpha})`;
785
+
786
+ // src/PixelData/fillPixelData.ts
787
+ function fillPixelData(dst, color, rect) {
788
+ const {
789
+ x: targetX = 0,
790
+ y: targetY = 0,
791
+ w: width = dst.width,
792
+ h: height = dst.height
793
+ } = rect || {};
794
+ let x = targetX;
795
+ let y = targetY;
796
+ let w = width;
797
+ let h = height;
798
+ if (x < 0) {
799
+ w += x;
800
+ x = 0;
801
+ }
802
+ if (y < 0) {
803
+ h += y;
804
+ y = 0;
805
+ }
806
+ const actualW = Math.min(w, dst.width - x);
807
+ const actualH = Math.min(h, dst.height - y);
808
+ if (actualW <= 0 || actualH <= 0) {
809
+ return;
810
+ }
811
+ const dst32 = dst.data32;
812
+ const dw = dst.width;
813
+ if (actualW === dw && actualH === dst.height && x === 0 && y === 0) {
814
+ dst32.fill(color);
815
+ return;
816
+ }
817
+ for (let iy = 0; iy < actualH; iy++) {
818
+ const start = (y + iy) * dw + x;
819
+ const end = start + actualW;
820
+ dst32.fill(color, start, end);
821
+ }
822
+ }
823
+
824
+ // src/PixelData/clearPixelData.ts
825
+ function clearPixelData(dst, rect) {
826
+ fillPixelData(dst, 0, rect);
501
827
  }
502
828
  // Annotate the CommonJS export names for ESM import in node:
503
829
  0 && (module.exports = {
504
830
  COLOR_32_BLEND_MODES,
505
831
  MaskType,
506
- applyAlphaMask,
507
- applyBinaryMask,
832
+ applyMaskToPixelData,
508
833
  base64DecodeArrayBuffer,
509
834
  base64EncodeArrayBuffer,
510
- blendImageData,
835
+ blendColorPixelData,
836
+ blendPixelData,
837
+ clearPixelData,
511
838
  color32ToCssRGBA,
512
839
  color32ToHex,
513
840
  colorBurnColor32,
514
841
  colorDistance,
515
842
  copyImageData,
516
843
  copyImageDataLike,
844
+ copyMask,
517
845
  deserializeImageData,
518
846
  deserializeNullableImageData,
519
847
  deserializeRawImageData,
520
848
  differenceColor32,
521
- extractPixelData,
849
+ extractImageData,
850
+ fillPixelData,
522
851
  hardLightColor32,
852
+ invertAlphaMask,
853
+ invertBinaryMask,
523
854
  lerpColor32,
524
855
  lerpColor32Fast,
525
856
  linearDodgeColor32,
526
- makeImageDataColor32Adapter,
857
+ mergeMasks,
527
858
  multiplyColor32,
528
859
  overlayColor32,
529
860
  packColor,
@@ -537,6 +868,7 @@ function color32ToCssRGBA(color) {
537
868
  unpackColor,
538
869
  unpackColorTo,
539
870
  unpackGreen,
540
- unpackRed
871
+ unpackRed,
872
+ writeImageData
541
873
  });
542
874
  //# sourceMappingURL=index.dev.cjs.map