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.
package/dist/index.dev.js CHANGED
@@ -1,4 +1,11 @@
1
- // src/ImageData/blend-modes.ts
1
+ // src/_types.ts
2
+ var MaskType = /* @__PURE__ */ ((MaskType2) => {
3
+ MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
4
+ MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
5
+ return MaskType2;
6
+ })(MaskType || {});
7
+
8
+ // src/blend-modes.ts
2
9
  var sourceOverColor32 = (src, dst) => {
3
10
  const a = src >>> 24 & 255;
4
11
  if (a === 255) return src;
@@ -134,176 +141,83 @@ var COLOR_32_BLEND_MODES = {
134
141
  colorBurn: colorBurnColor32
135
142
  };
136
143
 
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
- }
144
+ // src/color.ts
145
+ function packColor(r, g, b, a) {
146
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
212
147
  }
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;
148
+ function packRGBA({ r, g, b, a }) {
149
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
238
150
  }
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
- }
151
+ var unpackRed = (packed) => packed >>> 0 & 255;
152
+ var unpackGreen = (packed) => packed >>> 8 & 255;
153
+ var unpackBlue = (packed) => packed >>> 16 & 255;
154
+ var unpackAlpha = (packed) => packed >>> 24 & 255;
155
+ function unpackColor(packed) {
156
+ return {
157
+ r: packed >>> 0 & 255,
158
+ g: packed >>> 8 & 255,
159
+ b: packed >>> 16 & 255,
160
+ a: packed >>> 24 & 255
161
+ };
162
+ }
163
+ var SCRATCH_RGBA = { r: 0, g: 0, b: 0, a: 0 };
164
+ function unpackColorTo(packed, scratch = SCRATCH_RGBA) {
165
+ scratch.r = packed >>> 0 & 255;
166
+ scratch.g = packed >>> 8 & 255;
167
+ scratch.b = packed >>> 16 & 255;
168
+ scratch.a = packed >>> 24 & 255;
169
+ return scratch;
170
+ }
171
+ function colorDistance(a, b) {
172
+ const dr = (a & 255) - (b & 255);
173
+ const dg = (a >>> 8 & 255) - (b >>> 8 & 255);
174
+ const db = (a >>> 16 & 255) - (b >>> 16 & 255);
175
+ const da = (a >>> 24 & 255) - (b >>> 24 & 255);
176
+ return dr * dr + dg * dg + db * db + da * da;
177
+ }
178
+ function lerpColor32(a, b, t) {
179
+ const r = (a & 255) + t * ((b & 255) - (a & 255));
180
+ const g = (a >>> 8 & 255) + t * ((b >>> 8 & 255) - (a >>> 8 & 255));
181
+ const b_ = (a >>> 16 & 255) + t * ((b >>> 16 & 255) - (a >>> 16 & 255));
182
+ const a_ = (a >>> 24 & 255) + t * ((b >>> 24 & 255) - (a >>> 24 & 255));
183
+ return (a_ << 24 | b_ << 16 | g << 8 | r) >>> 0;
184
+ }
185
+ function lerpColor32Fast(src, dst, w) {
186
+ const invA = 255 - w;
187
+ const rb = (src & 16711935) * w + (dst & 16711935) * invA >>> 8 & 16711935;
188
+ const ga = (src >>> 8 & 16711935) * w + (dst >>> 8 & 16711935) * invA >>> 8 & 16711935;
189
+ return (rb | ga << 8) >>> 0;
190
+ }
191
+ function color32ToHex(color) {
192
+ const r = (color & 255).toString(16).padStart(2, "0");
193
+ const g = (color >>> 8 & 255).toString(16).padStart(2, "0");
194
+ const b = (color >>> 16 & 255).toString(16).padStart(2, "0");
195
+ const a = (color >>> 24 & 255).toString(16).padStart(2, "0");
196
+ return `#${r}${g}${b}${a}`;
197
+ }
198
+ function color32ToCssRGBA(color) {
199
+ const r = color & 255;
200
+ const g = color >>> 8 & 255;
201
+ const b = color >>> 16 & 255;
202
+ const a = color >>> 24 & 255;
203
+ const alpha = Number((a / 255).toFixed(3));
204
+ return `rgba(${r},${g},${b},${alpha})`;
282
205
  }
283
206
 
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
- }
207
+ // src/ImageData/copyImageData.ts
208
+ function copyImageData({ data, width, height }) {
209
+ return new ImageData(data.slice(), width, height);
210
+ }
211
+ function copyImageDataLike({ data, width, height }) {
298
212
  return {
299
- inBounds,
300
- imageData,
301
- data32,
302
- setPixel,
303
- getPixel
213
+ data: data.slice(),
214
+ width,
215
+ height
304
216
  };
305
217
  }
306
- function extractPixelData(imageData, _x, _y, _w, _h) {
218
+
219
+ // src/ImageData/extractImageData.ts
220
+ function extractImageData(imageData, _x, _y, _w, _h) {
307
221
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
308
222
  const { width: srcW, height: srcH, data: src } = imageData;
309
223
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
@@ -324,16 +238,6 @@ function extractPixelData(imageData, _x, _y, _w, _h) {
324
238
  }
325
239
  return out;
326
240
  }
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
241
 
338
242
  // src/ImageData/serialization.ts
339
243
  function base64EncodeArrayBuffer(buffer) {
@@ -375,92 +279,513 @@ function deserializeNullableImageData(serialized) {
375
279
  return deserializeImageData(serialized);
376
280
  }
377
281
 
378
- // src/color.ts
379
- function packColor(r, g, b, a) {
380
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
282
+ // src/ImageData/writeImageData.ts
283
+ function writeImageData(imageData, data, _x, _y, _w, _h) {
284
+ const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
285
+ const { width: dstW, height: dstH, data: dst } = imageData;
286
+ const x0 = Math.max(0, x);
287
+ const y0 = Math.max(0, y);
288
+ const x1 = Math.min(dstW, x + w);
289
+ const y1 = Math.min(dstH, y + h);
290
+ if (x1 <= x0 || y1 <= y0) return;
291
+ const rowLen = (x1 - x0) * 4;
292
+ const srcCol = x0 - x;
293
+ const srcYOffset = y0 - y;
294
+ const actualH = y1 - y0;
295
+ for (let row = 0; row < actualH; row++) {
296
+ const dstStart = ((y0 + row) * dstW + x0) * 4;
297
+ const srcRow = srcYOffset + row;
298
+ const o = (srcRow * w + srcCol) * 4;
299
+ dst.set(data.subarray(o, o + rowLen), dstStart);
300
+ }
381
301
  }
382
- function packRGBA({ r, g, b, a }) {
383
- return (a << 24 | b << 16 | g << 8 | r) >>> 0;
302
+
303
+ // src/Mask/copyMask.ts
304
+ function copyMask(src) {
305
+ return src.slice();
384
306
  }
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
- };
307
+
308
+ // src/Mask/invertMask.ts
309
+ function invertBinaryMask(dst) {
310
+ const len = dst.length;
311
+ for (let i = 0; i < len; i++) {
312
+ dst[i] = dst[i] === 0 ? 1 : 0;
313
+ }
396
314
  }
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;
315
+ function invertAlphaMask(dst) {
316
+ const len = dst.length;
317
+ for (let i = 0; i < len; i++) {
318
+ dst[i] = 255 - dst[i];
319
+ }
404
320
  }
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;
321
+
322
+ // src/Mask/mergeMasks.ts
323
+ function mergeMasks(dst, dstWidth, src, opts) {
324
+ const {
325
+ x: targetX = 0,
326
+ y: targetY = 0,
327
+ w: width = 0,
328
+ h: height = 0,
329
+ alpha: globalAlpha = 255,
330
+ maskType = 0 /* ALPHA */,
331
+ mw,
332
+ mx = 0,
333
+ my = 0,
334
+ invertMask = false
335
+ } = opts;
336
+ if (width <= 0 || height <= 0 || globalAlpha === 0) {
337
+ return;
338
+ }
339
+ const sPitch = mw ?? width;
340
+ const isAlpha = maskType === 0 /* ALPHA */;
341
+ for (let iy = 0; iy < height; iy++) {
342
+ const dy = targetY + iy;
343
+ const sy = my + iy;
344
+ if (dy < 0 || sy < 0) {
345
+ continue;
346
+ }
347
+ for (let ix = 0; ix < width; ix++) {
348
+ const dx = targetX + ix;
349
+ const sx = mx + ix;
350
+ if (dx < 0 || dx >= dstWidth || sx < 0 || sx >= sPitch) {
351
+ continue;
352
+ }
353
+ const dIdx = dy * dstWidth + dx;
354
+ const sIdx = sy * sPitch + sx;
355
+ const mVal = src[sIdx];
356
+ let weight = globalAlpha;
357
+ if (isAlpha) {
358
+ const effectiveM = invertMask ? 255 - mVal : mVal;
359
+ if (effectiveM === 0) {
360
+ dst[dIdx] = 0;
361
+ continue;
362
+ }
363
+ weight = globalAlpha === 255 ? effectiveM : effectiveM * globalAlpha + 128 >> 8;
364
+ } else {
365
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
366
+ if (!isHit) {
367
+ dst[dIdx] = 0;
368
+ continue;
369
+ }
370
+ weight = globalAlpha;
371
+ }
372
+ if (weight === 0) {
373
+ dst[dIdx] = 0;
374
+ continue;
375
+ }
376
+ const da = dst[dIdx];
377
+ if (da === 0) {
378
+ } else if (weight === 255) {
379
+ } else if (da === 255) {
380
+ dst[dIdx] = weight;
381
+ } else {
382
+ dst[dIdx] = da * weight + 128 >> 8;
383
+ }
384
+ }
385
+ }
411
386
  }
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;
387
+
388
+ // src/PixelData/applyMaskToPixelData.ts
389
+ function applyMaskToPixelData(dst, mask, opts) {
390
+ const {
391
+ x: targetX = 0,
392
+ y: targetY = 0,
393
+ w: width = dst.width,
394
+ h: height = dst.height,
395
+ alpha: globalAlpha = 255,
396
+ maskType = 0 /* ALPHA */,
397
+ mw,
398
+ mx = 0,
399
+ my = 0,
400
+ invertMask = false
401
+ } = opts;
402
+ let x = targetX;
403
+ let y = targetY;
404
+ let w = width;
405
+ let h = height;
406
+ if (x < 0) {
407
+ w += x;
408
+ x = 0;
409
+ }
410
+ if (y < 0) {
411
+ h += y;
412
+ y = 0;
413
+ }
414
+ const actualW = Math.min(w, dst.width - x);
415
+ const actualH = Math.min(h, dst.height - y);
416
+ if (actualW <= 0 || actualH <= 0 || globalAlpha === 0) {
417
+ return;
418
+ }
419
+ const dst32 = dst.data32;
420
+ const dw = dst.width;
421
+ const mPitch = mw ?? width;
422
+ const isAlpha = maskType === 0 /* ALPHA */;
423
+ const dx = x - targetX;
424
+ const dy = y - targetY;
425
+ let dIdx = y * dw + x;
426
+ let mIdx = (my + dy) * mPitch + (mx + dx);
427
+ const dStride = dw - actualW;
428
+ const mStride = mPitch - actualW;
429
+ for (let iy = 0; iy < actualH; iy++) {
430
+ for (let ix = 0; ix < actualW; ix++) {
431
+ const mVal = mask[mIdx];
432
+ let weight = globalAlpha;
433
+ if (isAlpha) {
434
+ const effectiveM = invertMask ? 255 - mVal : mVal;
435
+ if (effectiveM === 0) {
436
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
437
+ dIdx++;
438
+ mIdx++;
439
+ continue;
440
+ }
441
+ weight = globalAlpha === 255 ? effectiveM : effectiveM * globalAlpha + 128 >> 8;
442
+ } else {
443
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
444
+ if (!isHit) {
445
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
446
+ dIdx++;
447
+ mIdx++;
448
+ continue;
449
+ }
450
+ weight = globalAlpha;
451
+ }
452
+ if (weight === 0) {
453
+ dst32[dIdx] = (dst32[dIdx] & 16777215) >>> 0;
454
+ } else {
455
+ const d = dst32[dIdx];
456
+ const da = d >>> 24;
457
+ let finalAlpha = da;
458
+ if (da === 0) {
459
+ } else if (weight === 255) {
460
+ } else if (da === 255) {
461
+ finalAlpha = weight;
462
+ } else {
463
+ finalAlpha = da * weight + 128 >> 8;
464
+ }
465
+ dst32[dIdx] = (d & 16777215 | finalAlpha << 24) >>> 0;
466
+ }
467
+ dIdx++;
468
+ mIdx++;
469
+ }
470
+ dIdx += dStride;
471
+ mIdx += mStride;
472
+ }
418
473
  }
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;
474
+
475
+ // src/PixelData/blendColorPixelData.ts
476
+ function blendColorPixelData(dst, color, opts) {
477
+ const {
478
+ x: targetX = 0,
479
+ y: targetY = 0,
480
+ w: width = dst.width,
481
+ h: height = dst.height,
482
+ alpha: globalAlpha = 255,
483
+ blendFn = sourceOverColor32,
484
+ mask,
485
+ maskType = 0 /* ALPHA */,
486
+ mw,
487
+ mx = 0,
488
+ my = 0,
489
+ invertMask = false
490
+ } = opts;
491
+ if (globalAlpha === 0) return;
492
+ let x = targetX;
493
+ let y = targetY;
494
+ let w = width;
495
+ let h = height;
496
+ if (x < 0) {
497
+ w += x;
498
+ x = 0;
499
+ }
500
+ if (y < 0) {
501
+ h += y;
502
+ y = 0;
503
+ }
504
+ const actualW = Math.min(w, dst.width - x);
505
+ const actualH = Math.min(h, dst.height - y);
506
+ if (actualW <= 0 || actualH <= 0) return;
507
+ const dst32 = dst.data32;
508
+ const dw = dst.width;
509
+ const mPitch = mw ?? width;
510
+ const isAlphaMask = maskType === 0 /* ALPHA */;
511
+ const dx = x - targetX;
512
+ const dy = y - targetY;
513
+ let dIdx = y * dw + x;
514
+ let mIdx = (my + dy) * mPitch + (mx + dx);
515
+ const dStride = dw - actualW;
516
+ const mStride = mPitch - actualW;
517
+ const baseSrcColor = color;
518
+ const baseSrcAlpha = baseSrcColor >>> 24;
519
+ for (let iy = 0; iy < actualH; iy++) {
520
+ for (let ix = 0; ix < actualW; ix++) {
521
+ if (baseSrcAlpha === 0) {
522
+ dIdx++;
523
+ mIdx++;
524
+ continue;
525
+ }
526
+ let weight = globalAlpha;
527
+ if (mask) {
528
+ const mVal = mask[mIdx];
529
+ if (isAlphaMask) {
530
+ const effectiveM = invertMask ? 255 - mVal : mVal;
531
+ if (effectiveM === 0) {
532
+ dIdx++;
533
+ mIdx++;
534
+ continue;
535
+ }
536
+ if (globalAlpha === 255) {
537
+ weight = effectiveM;
538
+ } else if (effectiveM === 255) {
539
+ weight = globalAlpha;
540
+ } else {
541
+ weight = effectiveM * globalAlpha + 128 >> 8;
542
+ }
543
+ } else {
544
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
545
+ if (!isHit) {
546
+ dIdx++;
547
+ mIdx++;
548
+ continue;
549
+ }
550
+ weight = globalAlpha;
551
+ }
552
+ if (weight === 0) {
553
+ dIdx++;
554
+ mIdx++;
555
+ continue;
556
+ }
557
+ }
558
+ let currentSrcAlpha = baseSrcAlpha;
559
+ let currentSrcColor = baseSrcColor;
560
+ if (weight < 255) {
561
+ if (baseSrcAlpha === 255) {
562
+ currentSrcAlpha = weight;
563
+ } else {
564
+ currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
565
+ }
566
+ if (currentSrcAlpha === 0) {
567
+ dIdx++;
568
+ mIdx++;
569
+ continue;
570
+ }
571
+ currentSrcColor = (baseSrcColor & 16777215 | currentSrcAlpha << 24) >>> 0;
572
+ }
573
+ dst32[dIdx] = blendFn(currentSrcColor, dst32[dIdx]);
574
+ dIdx++;
575
+ mIdx++;
576
+ }
577
+ dIdx += dStride;
578
+ mIdx += mStride;
579
+ }
424
580
  }
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}`;
581
+
582
+ // src/PixelData/blendPixelData.ts
583
+ function blendPixelData(dst, src, opts) {
584
+ const {
585
+ x: targetX = 0,
586
+ y: targetY = 0,
587
+ sx: sourceX = 0,
588
+ sy: sourceY = 0,
589
+ w: width = src.width,
590
+ h: height = src.height,
591
+ alpha: globalAlpha = 255,
592
+ blendFn = sourceOverColor32,
593
+ mask,
594
+ maskType = 0 /* ALPHA */,
595
+ mw,
596
+ mx = 0,
597
+ my = 0,
598
+ invertMask = false
599
+ } = opts;
600
+ if (globalAlpha === 0) return;
601
+ let x = targetX;
602
+ let y = targetY;
603
+ let sx = sourceX;
604
+ let sy = sourceY;
605
+ let w = width;
606
+ let h = height;
607
+ if (sx < 0) {
608
+ x -= sx;
609
+ w += sx;
610
+ sx = 0;
611
+ }
612
+ if (sy < 0) {
613
+ y -= sy;
614
+ h += sy;
615
+ sy = 0;
616
+ }
617
+ w = Math.min(w, src.width - sx);
618
+ h = Math.min(h, src.height - sy);
619
+ if (x < 0) {
620
+ sx -= x;
621
+ w += x;
622
+ x = 0;
623
+ }
624
+ if (y < 0) {
625
+ sy -= y;
626
+ h += y;
627
+ y = 0;
628
+ }
629
+ const actualW = Math.min(w, dst.width - x);
630
+ const actualH = Math.min(h, dst.height - y);
631
+ if (actualW <= 0 || actualH <= 0) return;
632
+ const dst32 = dst.data32;
633
+ const src32 = src.data32;
634
+ const dw = dst.width;
635
+ const sw = src.width;
636
+ const mPitch = mw ?? width;
637
+ const isAlphaMask = maskType === 0 /* ALPHA */;
638
+ const dx = x - targetX;
639
+ const dy = y - targetY;
640
+ let dIdx = y * dw + x;
641
+ let sIdx = sy * sw + sx;
642
+ let mIdx = (my + dy) * mPitch + (mx + dx);
643
+ const dStride = dw - actualW;
644
+ const sStride = sw - actualW;
645
+ const mStride = mPitch - actualW;
646
+ for (let iy = 0; iy < actualH; iy++) {
647
+ for (let ix = 0; ix < actualW; ix++) {
648
+ const baseSrcColor = src32[sIdx];
649
+ const baseSrcAlpha = baseSrcColor >>> 24;
650
+ if (baseSrcAlpha === 0) {
651
+ dIdx++;
652
+ sIdx++;
653
+ mIdx++;
654
+ continue;
655
+ }
656
+ let weight = globalAlpha;
657
+ if (mask) {
658
+ const mVal = mask[mIdx];
659
+ if (isAlphaMask) {
660
+ const effectiveM = invertMask ? 255 - mVal : mVal;
661
+ if (effectiveM === 0) {
662
+ dIdx++;
663
+ sIdx++;
664
+ mIdx++;
665
+ continue;
666
+ }
667
+ if (globalAlpha === 255) {
668
+ weight = effectiveM;
669
+ } else if (effectiveM === 255) {
670
+ weight = globalAlpha;
671
+ } else {
672
+ weight = effectiveM * globalAlpha + 128 >> 8;
673
+ }
674
+ } else {
675
+ const isHit = invertMask ? mVal === 0 : mVal === 1;
676
+ if (!isHit) {
677
+ dIdx++;
678
+ sIdx++;
679
+ mIdx++;
680
+ continue;
681
+ }
682
+ weight = globalAlpha;
683
+ }
684
+ if (weight === 0) {
685
+ dIdx++;
686
+ sIdx++;
687
+ mIdx++;
688
+ continue;
689
+ }
690
+ }
691
+ let currentSrcAlpha = baseSrcAlpha;
692
+ let currentSrcColor = baseSrcColor;
693
+ if (weight < 255) {
694
+ if (baseSrcAlpha === 255) {
695
+ currentSrcAlpha = weight;
696
+ } else {
697
+ currentSrcAlpha = baseSrcAlpha * weight + 128 >> 8;
698
+ }
699
+ if (currentSrcAlpha === 0) {
700
+ dIdx++;
701
+ sIdx++;
702
+ mIdx++;
703
+ continue;
704
+ }
705
+ currentSrcColor = (baseSrcColor & 16777215 | currentSrcAlpha << 24) >>> 0;
706
+ }
707
+ dst32[dIdx] = blendFn(currentSrcColor, dst32[dIdx]);
708
+ dIdx++;
709
+ sIdx++;
710
+ mIdx++;
711
+ }
712
+ dIdx += dStride;
713
+ sIdx += sStride;
714
+ mIdx += mStride;
715
+ }
431
716
  }
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})`;
717
+
718
+ // src/PixelData/fillPixelData.ts
719
+ function fillPixelData(dst, color, rect) {
720
+ const {
721
+ x: targetX = 0,
722
+ y: targetY = 0,
723
+ w: width = dst.width,
724
+ h: height = dst.height
725
+ } = rect || {};
726
+ let x = targetX;
727
+ let y = targetY;
728
+ let w = width;
729
+ let h = height;
730
+ if (x < 0) {
731
+ w += x;
732
+ x = 0;
733
+ }
734
+ if (y < 0) {
735
+ h += y;
736
+ y = 0;
737
+ }
738
+ const actualW = Math.min(w, dst.width - x);
739
+ const actualH = Math.min(h, dst.height - y);
740
+ if (actualW <= 0 || actualH <= 0) {
741
+ return;
742
+ }
743
+ const dst32 = dst.data32;
744
+ const dw = dst.width;
745
+ if (actualW === dw && actualH === dst.height && x === 0 && y === 0) {
746
+ dst32.fill(color);
747
+ return;
748
+ }
749
+ for (let iy = 0; iy < actualH; iy++) {
750
+ const start = (y + iy) * dw + x;
751
+ const end = start + actualW;
752
+ dst32.fill(color, start, end);
753
+ }
754
+ }
755
+
756
+ // src/PixelData/clearPixelData.ts
757
+ function clearPixelData(dst, rect) {
758
+ fillPixelData(dst, 0, rect);
439
759
  }
440
760
  export {
441
761
  COLOR_32_BLEND_MODES,
442
762
  MaskType,
443
- applyAlphaMask,
444
- applyBinaryMask,
763
+ applyMaskToPixelData,
445
764
  base64DecodeArrayBuffer,
446
765
  base64EncodeArrayBuffer,
447
- blendImageData,
766
+ blendColorPixelData,
767
+ blendPixelData,
768
+ clearPixelData,
448
769
  color32ToCssRGBA,
449
770
  color32ToHex,
450
771
  colorBurnColor32,
451
772
  colorDistance,
452
773
  copyImageData,
453
774
  copyImageDataLike,
775
+ copyMask,
454
776
  deserializeImageData,
455
777
  deserializeNullableImageData,
456
778
  deserializeRawImageData,
457
779
  differenceColor32,
458
- extractPixelData,
780
+ extractImageData,
781
+ fillPixelData,
459
782
  hardLightColor32,
783
+ invertAlphaMask,
784
+ invertBinaryMask,
460
785
  lerpColor32,
461
786
  lerpColor32Fast,
462
787
  linearDodgeColor32,
463
- makeImageDataColor32Adapter,
788
+ mergeMasks,
464
789
  multiplyColor32,
465
790
  overlayColor32,
466
791
  packColor,
@@ -474,6 +799,7 @@ export {
474
799
  unpackColor,
475
800
  unpackColorTo,
476
801
  unpackGreen,
477
- unpackRed
802
+ unpackRed,
803
+ writeImageData
478
804
  };
479
805
  //# sourceMappingURL=index.dev.js.map