pixel-data-js 0.31.0 → 0.33.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.
@@ -93,6 +93,7 @@ __export(src_exports, {
93
93
  eachTileInBounds: () => eachTileInBounds,
94
94
  exclusionFast: () => exclusionFast,
95
95
  exclusionPerfect: () => exclusionPerfect,
96
+ extractImageData: () => extractImageData,
96
97
  extractImageDataBuffer: () => extractImageDataBuffer,
97
98
  extractMask: () => extractMask,
98
99
  extractMaskBuffer: () => extractMaskBuffer,
@@ -156,8 +157,6 @@ __export(src_exports, {
156
157
  makeCircleBinaryMaskOutline: () => makeCircleBinaryMaskOutline,
157
158
  makeCirclePaintAlphaMask: () => makeCirclePaintAlphaMask,
158
159
  makeCirclePaintBinaryMask: () => makeCirclePaintBinaryMask,
159
- makeClippedBlit: () => makeClippedBlit,
160
- makeClippedRect: () => makeClippedRect,
161
160
  makeColorPaintBufferCanvasRenderer: () => makeColorPaintBufferCanvasRenderer,
162
161
  makeColorPaintBufferCommitter: () => makeColorPaintBufferCommitter,
163
162
  makeColorPaintBufferManager: () => makeColorPaintBufferManager,
@@ -224,8 +223,7 @@ __export(src_exports, {
224
223
  resamplePixelDataInPlace: () => resamplePixelDataInPlace,
225
224
  resampleUint32Array: () => resampleUint32Array,
226
225
  resizeImageData: () => resizeImageData,
227
- resolveBlitClipping: () => resolveBlitClipping,
228
- resolveRectClipping: () => resolveRectClipping,
226
+ resizePixelData: () => resizePixelData,
229
227
  rotatePixelData: () => rotatePixelData,
230
228
  screenFast: () => screenFast,
231
229
  screenPerfect: () => screenPerfect,
@@ -265,6 +263,7 @@ __export(src_exports, {
265
263
  writeImageDataToClipboard: () => writeImageDataToClipboard,
266
264
  writeImgBlobToClipboard: () => writeImgBlobToClipboard,
267
265
  writePaintBufferToPixelData: () => writePaintBufferToPixelData,
266
+ writePixelData: () => writePixelData,
268
267
  writePixelDataBuffer: () => writePixelDataBuffer,
269
268
  xorFast: () => xorFast,
270
269
  xorPerfect: () => xorPerfect
@@ -353,86 +352,7 @@ function color32ToCssRGBA(color) {
353
352
  return `rgba(${r},${g},${b},${alpha})`;
354
353
  }
355
354
 
356
- // src/Rect/resolveClipping.ts
357
- var makeClippedRect = () => ({
358
- x: 0,
359
- y: 0,
360
- w: 0,
361
- h: 0,
362
- inBounds: false
363
- });
364
- var makeClippedBlit = () => ({
365
- x: 0,
366
- y: 0,
367
- sx: 0,
368
- sy: 0,
369
- w: 0,
370
- h: 0,
371
- inBounds: false
372
- });
373
- function resolveRectClipping(x, y, w, h, boundaryW, boundaryH, out) {
374
- if (x < 0) {
375
- w += x;
376
- x = 0;
377
- }
378
- if (y < 0) {
379
- h += y;
380
- y = 0;
381
- }
382
- const actualW = Math.min(w, boundaryW - x);
383
- const actualH = Math.min(h, boundaryH - y);
384
- if (actualW <= 0 || actualH <= 0) {
385
- out.inBounds = false;
386
- return out;
387
- }
388
- out.x = x;
389
- out.y = y;
390
- out.w = actualW;
391
- out.h = actualH;
392
- out.inBounds = true;
393
- return out;
394
- }
395
- function resolveBlitClipping(x, y, sx, sy, w, h, dstW, dstH, srcW, srcH, out) {
396
- if (sx < 0) {
397
- x -= sx;
398
- w += sx;
399
- sx = 0;
400
- }
401
- if (sy < 0) {
402
- y -= sy;
403
- h += sy;
404
- sy = 0;
405
- }
406
- w = Math.min(w, srcW - sx);
407
- h = Math.min(h, srcH - sy);
408
- if (x < 0) {
409
- sx -= x;
410
- w += x;
411
- x = 0;
412
- }
413
- if (y < 0) {
414
- sy -= y;
415
- h += y;
416
- y = 0;
417
- }
418
- const actualW = Math.min(w, dstW - x);
419
- const actualH = Math.min(h, dstH - y);
420
- if (actualW <= 0 || actualH <= 0) {
421
- out.inBounds = false;
422
- return out;
423
- }
424
- out.x = x;
425
- out.y = y;
426
- out.sx = sx;
427
- out.sy = sy;
428
- out.w = actualW;
429
- out.h = actualH;
430
- out.inBounds = true;
431
- return out;
432
- }
433
-
434
355
  // src/ImageData/extractImageDataBuffer.ts
435
- var SCRATCH_BLIT = makeClippedBlit();
436
356
  function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
437
357
  const {
438
358
  x,
@@ -445,28 +365,50 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
445
365
  w: _w,
446
366
  h: _h
447
367
  };
448
- const {
449
- width: srcW,
450
- height: srcH,
451
- data: src
452
- } = imageData;
453
368
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
454
- const out = new Uint8ClampedArray(w * h * 4);
455
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT);
456
- if (!clip.inBounds) return out;
457
- const {
458
- x: dstX,
459
- y: dstY,
460
- sx: srcX,
461
- sy: srcY,
462
- w: copyW,
463
- h: copyH
464
- } = clip;
465
- const rowLen = copyW * 4;
466
- for (let row = 0; row < copyH; row++) {
467
- const srcStart = ((srcY + row) * srcW + srcX) * 4;
468
- const dstStart = ((dstY + row) * w + dstX) * 4;
469
- out.set(src.subarray(srcStart, srcStart + rowLen), dstStart);
369
+ const srcW = imageData.width;
370
+ const srcH = imageData.height;
371
+ const src = imageData.data;
372
+ const outLen = w * h * 4;
373
+ const out = new Uint8ClampedArray(outLen);
374
+ let srcX = x;
375
+ let srcY = y;
376
+ let dstX = 0;
377
+ let dstY = 0;
378
+ let copyW = w;
379
+ let copyH = h;
380
+ if (srcX < 0) {
381
+ dstX = -srcX;
382
+ copyW += srcX;
383
+ srcX = 0;
384
+ }
385
+ if (srcY < 0) {
386
+ dstY = -srcY;
387
+ copyH += srcY;
388
+ srcY = 0;
389
+ }
390
+ copyW = Math.min(copyW, srcW - srcX);
391
+ copyH = Math.min(copyH, srcH - srcY);
392
+ if (copyW <= 0 || copyH <= 0) return out;
393
+ const isAligned = src.byteOffset % 4 === 0;
394
+ if (isAligned) {
395
+ const srcLen32 = src.byteLength / 4;
396
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
397
+ const out32 = new Uint32Array(out.buffer);
398
+ for (let row = 0; row < copyH; row++) {
399
+ const srcStart = (srcY + row) * srcW + srcX;
400
+ const dstStart = (dstY + row) * w + dstX;
401
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
402
+ out32.set(chunk, dstStart);
403
+ }
404
+ } else {
405
+ const rowLen = copyW * 4;
406
+ for (let row = 0; row < copyH; row++) {
407
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
408
+ const dstStart = ((dstY + row) * w + dstX) * 4;
409
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
410
+ out.set(chunk, dstStart);
411
+ }
470
412
  }
471
413
  return out;
472
414
  }
@@ -3907,8 +3849,9 @@ var mutatorBlendPixelData = ((writer, deps = defaults13) => {
3907
3849
  });
3908
3850
 
3909
3851
  // src/PixelData/fillPixelData.ts
3910
- var SCRATCH_RECT = makeClippedRect();
3911
3852
  function fillPixelData(dst, color, _x, _y, _w, _h) {
3853
+ const dstW = dst.w;
3854
+ const dstH = dst.h;
3912
3855
  let x;
3913
3856
  let y;
3914
3857
  let w;
@@ -3916,8 +3859,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3916
3859
  if (typeof _x === "object") {
3917
3860
  x = _x.x ?? 0;
3918
3861
  y = _x.y ?? 0;
3919
- w = _x.w ?? dst.w;
3920
- h = _x.h ?? dst.h;
3862
+ w = _x.w ?? dstW;
3863
+ h = _x.h ?? dstH;
3921
3864
  } else if (typeof _x === "number") {
3922
3865
  x = _x;
3923
3866
  y = _y;
@@ -3926,24 +3869,41 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3926
3869
  } else {
3927
3870
  x = 0;
3928
3871
  y = 0;
3929
- w = dst.w;
3930
- h = dst.h;
3931
- }
3932
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT);
3933
- if (!clip.inBounds) return false;
3934
- const {
3935
- x: finalX,
3936
- y: finalY,
3937
- w: actualW,
3938
- h: actualH
3939
- } = clip;
3872
+ w = dstW;
3873
+ h = dstH;
3874
+ }
3875
+ let dstX = x;
3876
+ let dstY = y;
3877
+ let fillW = w;
3878
+ let fillH = h;
3879
+ if (dstX < 0) {
3880
+ fillW += dstX;
3881
+ dstX = 0;
3882
+ }
3883
+ if (dstY < 0) {
3884
+ fillH += dstY;
3885
+ dstY = 0;
3886
+ }
3887
+ fillW = Math.min(fillW, dstW - dstX);
3888
+ fillH = Math.min(fillH, dstH - dstY);
3889
+ if (fillW <= 0 || fillH <= 0) return false;
3940
3890
  const dst32 = dst.data;
3941
- const dw = dst.w;
3942
3891
  let hasChanged = false;
3943
- for (let iy = 0; iy < actualH; iy++) {
3944
- const rowOffset = (finalY + iy) * dw;
3945
- const start = rowOffset + finalX;
3946
- const end = start + actualW;
3892
+ if (dstX === 0 && fillW === dstW) {
3893
+ const start = dstY * dstW;
3894
+ const end = start + fillW * fillH;
3895
+ for (let i = start; i < end; i++) {
3896
+ if (dst32[i] !== color) {
3897
+ dst32[i] = color;
3898
+ hasChanged = true;
3899
+ }
3900
+ }
3901
+ return hasChanged;
3902
+ }
3903
+ for (let iy = 0; iy < fillH; iy++) {
3904
+ const rowOffset = (dstY + iy) * dstW;
3905
+ const start = rowOffset + dstX;
3906
+ const end = start + fillW;
3947
3907
  for (let i = start; i < end; i++) {
3948
3908
  if (dst32[i] !== color) {
3949
3909
  dst32[i] = color;
@@ -4005,39 +3965,48 @@ var mutatorFillRect = ((writer, deps = defaults15) => {
4005
3965
  });
4006
3966
 
4007
3967
  // src/PixelData/fillPixelDataBinaryMask.ts
4008
- var SCRATCH_RECT2 = makeClippedRect();
4009
3968
  function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3969
+ const targetW = target.w;
3970
+ const targetH = target.h;
4010
3971
  const maskW = mask.w;
4011
3972
  const maskH = mask.h;
4012
- const clip = resolveRectClipping(x, y, maskW, maskH, target.w, target.h, SCRATCH_RECT2);
4013
- if (!clip.inBounds) return false;
4014
- const {
4015
- x: finalX,
4016
- y: finalY,
4017
- w: actualW,
4018
- h: actualH
4019
- } = clip;
3973
+ let dstX = x;
3974
+ let dstY = y;
3975
+ let actualW = maskW;
3976
+ let actualH = maskH;
3977
+ if (dstX < 0) {
3978
+ actualW += dstX;
3979
+ dstX = 0;
3980
+ }
3981
+ if (dstY < 0) {
3982
+ actualH += dstY;
3983
+ dstY = 0;
3984
+ }
3985
+ actualW = Math.min(actualW, targetW - dstX);
3986
+ actualH = Math.min(actualH, targetH - dstY);
3987
+ if (actualW <= 0 || actualH <= 0) return false;
4020
3988
  const maskData = mask.data;
4021
3989
  const dst32 = target.data;
4022
- const dw = target.w;
3990
+ const mx = dstX - x;
3991
+ const my = dstY - y;
4023
3992
  let hasChanged = false;
3993
+ let dIdx = dstY * targetW + dstX;
3994
+ let mIdx = my * maskW + mx;
3995
+ const dStride = targetW - actualW;
3996
+ const mStride = maskW - actualW;
4024
3997
  for (let iy = 0; iy < actualH; iy++) {
4025
- const currentY = finalY + iy;
4026
- const maskY = currentY - y;
4027
- const maskOffset = maskY * maskW;
4028
- const dstRowOffset = currentY * dw;
4029
3998
  for (let ix = 0; ix < actualW; ix++) {
4030
- const currentX = finalX + ix;
4031
- const maskX = currentX - x;
4032
- const maskIndex = maskOffset + maskX;
4033
- if (maskData[maskIndex]) {
4034
- const current = dst32[dstRowOffset + currentX];
4035
- if (current !== color) {
4036
- dst32[dstRowOffset + currentX] = color;
3999
+ if (maskData[mIdx]) {
4000
+ if (dst32[dIdx] !== color) {
4001
+ dst32[dIdx] = color;
4037
4002
  hasChanged = true;
4038
4003
  }
4039
4004
  }
4005
+ dIdx++;
4006
+ mIdx++;
4040
4007
  }
4008
+ dIdx += dStride;
4009
+ mIdx += mStride;
4041
4010
  }
4042
4011
  return hasChanged;
4043
4012
  }
@@ -4059,35 +4028,43 @@ var mutatorFillBinaryMask = ((writer, deps = defaults16) => {
4059
4028
  });
4060
4029
 
4061
4030
  // src/PixelData/invertPixelData.ts
4062
- var SCRATCH_RECT3 = makeClippedRect();
4063
4031
  function invertPixelData(target, opts) {
4032
+ const targetW = target.w;
4033
+ const targetH = target.h;
4064
4034
  const mask = opts?.mask;
4035
+ const invertMask = opts?.invertMask ?? false;
4065
4036
  const targetX = opts?.x ?? 0;
4066
4037
  const targetY = opts?.y ?? 0;
4067
4038
  const mx = opts?.mx ?? 0;
4068
4039
  const my = opts?.my ?? 0;
4069
- const width = opts?.w ?? target.w;
4070
- const height = opts?.h ?? target.h;
4071
- const invertMask = opts?.invertMask ?? false;
4072
- const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT3);
4073
- if (!clip.inBounds) return false;
4074
- const {
4075
- x,
4076
- y,
4077
- w: actualW,
4078
- h: actualH
4079
- } = clip;
4040
+ const w = opts?.w ?? targetW;
4041
+ const h = opts?.h ?? targetH;
4042
+ let x = targetX;
4043
+ let y = targetY;
4044
+ let actualW = w;
4045
+ let actualH = h;
4046
+ if (x < 0) {
4047
+ actualW += x;
4048
+ x = 0;
4049
+ }
4050
+ if (y < 0) {
4051
+ actualH += y;
4052
+ y = 0;
4053
+ }
4054
+ actualW = Math.min(actualW, targetW - x);
4055
+ actualH = Math.min(actualH, targetH - y);
4056
+ if (actualW <= 0 || actualH <= 0) return false;
4080
4057
  const dst32 = target.data;
4081
- const dw = target.w;
4082
- const mPitch = mask?.w ?? width;
4058
+ const dw = targetW;
4083
4059
  const dx = x - targetX;
4084
4060
  const dy = y - targetY;
4085
4061
  let dIdx = y * dw + x;
4086
- let mIdx = (my + dy) * mPitch + (mx + dx);
4087
4062
  const dStride = dw - actualW;
4088
- const mStride = mPitch - actualW;
4089
4063
  if (mask) {
4090
4064
  const maskData = mask.data;
4065
+ const mPitch = mask.w;
4066
+ let mIdx = (my + dy) * mPitch + (mx + dx);
4067
+ const mStride = mPitch - actualW;
4091
4068
  for (let iy = 0; iy < actualH; iy++) {
4092
4069
  for (let ix = 0; ix < actualW; ix++) {
4093
4070
  const mVal = maskData[mIdx];
@@ -4160,12 +4137,9 @@ function makeFullPixelMutator(writer) {
4160
4137
  }
4161
4138
 
4162
4139
  // src/ImageData/copyImageData.ts
4163
- function copyImageData({
4164
- data,
4165
- width,
4166
- height
4167
- }) {
4168
- return new ImageData(data.slice(), width, height);
4140
+ function copyImageData(source) {
4141
+ const dataCopy = new Uint8ClampedArray(source.data);
4142
+ return new ImageData(dataCopy, source.width, source.height);
4169
4143
  }
4170
4144
  function copyImageDataLike({
4171
4145
  data,
@@ -4179,6 +4153,26 @@ function copyImageDataLike({
4179
4153
  };
4180
4154
  }
4181
4155
 
4156
+ // src/ImageData/extractImageData.ts
4157
+ function extractImageData(imageData, _x, _y, _w, _h) {
4158
+ const {
4159
+ x,
4160
+ y,
4161
+ w,
4162
+ h
4163
+ } = typeof _x === "object" ? _x : {
4164
+ x: _x,
4165
+ y: _y,
4166
+ w: _w,
4167
+ h: _h
4168
+ };
4169
+ if (w <= 0 || h <= 0) return null;
4170
+ const result = new ImageData(w, h);
4171
+ const buffer = extractImageDataBuffer(imageData, x, y, w, h);
4172
+ result.data.set(buffer);
4173
+ return result;
4174
+ }
4175
+
4182
4176
  // src/ImageData/ImageDataLike.ts
4183
4177
  function makeImageDataLike(width, height, data) {
4184
4178
  const size = width * height * 4;
@@ -4329,94 +4323,117 @@ function uInt32ArrayToImageDataLike(data, width, height) {
4329
4323
  }
4330
4324
 
4331
4325
  // src/ImageData/writeImageData.ts
4332
- var SCRATCH_BLIT2 = makeClippedBlit();
4333
- function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
4326
+ function writeImageData(target, source, x = 0, y = 0) {
4334
4327
  const dstW = target.width;
4335
4328
  const dstH = target.height;
4336
- const dstData = target.data;
4329
+ const dst = target.data;
4337
4330
  const srcW = source.width;
4338
- const srcData = source.data;
4339
- const clip = resolveBlitClipping(x, y, sx, sy, sw, sh, dstW, dstH, srcW, source.height, SCRATCH_BLIT2);
4340
- if (!clip.inBounds) return;
4341
- const {
4342
- x: dstX,
4343
- y: dstY,
4344
- sx: srcX,
4345
- sy: srcY,
4346
- w: copyW,
4347
- h: copyH
4348
- } = clip;
4349
- const useMask = !!mask;
4350
- for (let row = 0; row < copyH; row++) {
4351
- const currentDstY = dstY + row;
4352
- const currentSrcY = srcY + row;
4353
- const dstStart = (currentDstY * dstW + dstX) * 4;
4354
- const srcStart = (currentSrcY * srcW + srcX) * 4;
4355
- if (useMask && mask) {
4356
- for (let ix = 0; ix < copyW; ix++) {
4357
- const mi = currentSrcY * srcW + (srcX + ix);
4358
- const alpha = mask[mi];
4359
- if (alpha === 0) {
4360
- continue;
4361
- }
4362
- const di = dstStart + ix * 4;
4363
- const si = srcStart + ix * 4;
4364
- if (maskType === 1 /* BINARY */ || alpha === 255) {
4365
- dstData[di] = srcData[si];
4366
- dstData[di + 1] = srcData[si + 1];
4367
- dstData[di + 2] = srcData[si + 2];
4368
- dstData[di + 3] = srcData[si + 3];
4369
- } else {
4370
- const a = alpha / 255;
4371
- const invA = 1 - a;
4372
- dstData[di] = srcData[si] * a + dstData[di] * invA;
4373
- dstData[di + 1] = srcData[si + 1] * a + dstData[di + 1] * invA;
4374
- dstData[di + 2] = srcData[si + 2] * a + dstData[di + 2] * invA;
4375
- dstData[di + 3] = srcData[si + 3] * a + dstData[di + 3] * invA;
4376
- }
4377
- }
4378
- } else {
4379
- const byteLen = copyW * 4;
4380
- const sub = srcData.subarray(srcStart, srcStart + byteLen);
4381
- dstData.set(sub, dstStart);
4331
+ const srcH = source.height;
4332
+ const src = source.data;
4333
+ let dstX = x;
4334
+ let dstY = y;
4335
+ let srcX = 0;
4336
+ let srcY = 0;
4337
+ let copyW = srcW;
4338
+ let copyH = srcH;
4339
+ if (dstX < 0) {
4340
+ srcX = -dstX;
4341
+ copyW += dstX;
4342
+ dstX = 0;
4343
+ }
4344
+ if (dstY < 0) {
4345
+ srcY = -dstY;
4346
+ copyH += dstY;
4347
+ dstY = 0;
4348
+ }
4349
+ copyW = Math.min(copyW, dstW - dstX);
4350
+ copyH = Math.min(copyH, dstH - dstY);
4351
+ if (copyW <= 0 || copyH <= 0) return;
4352
+ const isDstAligned = dst.byteOffset % 4 === 0;
4353
+ const isSrcAligned = src.byteOffset % 4 === 0;
4354
+ if (isDstAligned && isSrcAligned) {
4355
+ const dstLen32 = dst.byteLength / 4;
4356
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4357
+ const srcLen32 = src.byteLength / 4;
4358
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
4359
+ for (let row = 0; row < copyH; row++) {
4360
+ const dstStart = (dstY + row) * dstW + dstX;
4361
+ const srcStart = (srcY + row) * srcW + srcX;
4362
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4363
+ dst32.set(chunk, dstStart);
4364
+ }
4365
+ } else {
4366
+ const rowLen = copyW * 4;
4367
+ for (let row = 0; row < copyH; row++) {
4368
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4369
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
4370
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
4371
+ dst.set(chunk, dstStart);
4382
4372
  }
4383
4373
  }
4384
4374
  }
4385
4375
 
4386
4376
  // src/ImageData/writeImageDataBuffer.ts
4387
- var SCRATCH_BLIT3 = makeClippedBlit();
4388
4377
  function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
4389
- const {
4390
- x,
4391
- y,
4392
- w,
4393
- h
4394
- } = typeof _x === "object" ? _x : {
4395
- x: _x,
4396
- y: _y,
4397
- w: _w,
4398
- h: _h
4399
- };
4400
- const {
4401
- width: dstW,
4402
- height: dstH,
4403
- data: dst
4404
- } = target;
4405
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT3);
4406
- if (!clip.inBounds) return;
4407
- const {
4408
- x: dstX,
4409
- y: dstY,
4410
- sx: srcX,
4411
- sy: srcY,
4412
- w: copyW,
4413
- h: copyH
4414
- } = clip;
4415
- const rowLen = copyW * 4;
4416
- for (let row = 0; row < copyH; row++) {
4417
- const dstStart = ((dstY + row) * dstW + dstX) * 4;
4418
- const srcStart = ((srcY + row) * w + srcX) * 4;
4419
- dst.set(data.subarray(srcStart, srcStart + rowLen), dstStart);
4378
+ let x;
4379
+ let y;
4380
+ let w;
4381
+ let h;
4382
+ if (typeof _x === "object") {
4383
+ x = _x.x;
4384
+ y = _x.y;
4385
+ w = _x.w;
4386
+ h = _x.h;
4387
+ } else {
4388
+ x = _x;
4389
+ y = _y;
4390
+ w = _w;
4391
+ h = _h;
4392
+ }
4393
+ if (w <= 0 || h <= 0) return;
4394
+ const dstW = target.width;
4395
+ const dstH = target.height;
4396
+ const dst = target.data;
4397
+ let dstX = x;
4398
+ let dstY = y;
4399
+ let srcX = 0;
4400
+ let srcY = 0;
4401
+ let copyW = w;
4402
+ let copyH = h;
4403
+ if (dstX < 0) {
4404
+ srcX = -dstX;
4405
+ copyW += dstX;
4406
+ dstX = 0;
4407
+ }
4408
+ if (dstY < 0) {
4409
+ srcY = -dstY;
4410
+ copyH += dstY;
4411
+ dstY = 0;
4412
+ }
4413
+ copyW = Math.min(copyW, dstW - dstX);
4414
+ copyH = Math.min(copyH, dstH - dstY);
4415
+ if (copyW <= 0 || copyH <= 0) return;
4416
+ const isDstAligned = dst.byteOffset % 4 === 0;
4417
+ const isSrcAligned = data.byteOffset % 4 === 0;
4418
+ if (isDstAligned && isSrcAligned) {
4419
+ const dstLen32 = dst.byteLength / 4;
4420
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4421
+ const srcLen32 = data.byteLength / 4;
4422
+ const src32 = new Uint32Array(data.buffer, data.byteOffset, srcLen32);
4423
+ for (let row = 0; row < copyH; row++) {
4424
+ const dstStart = (dstY + row) * dstW + dstX;
4425
+ const srcStart = (srcY + row) * w + srcX;
4426
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4427
+ dst32.set(chunk, dstStart);
4428
+ }
4429
+ } else {
4430
+ const rowLen = copyW * 4;
4431
+ for (let row = 0; row < copyH; row++) {
4432
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4433
+ const srcStart = ((srcY + row) * w + srcX) * 4;
4434
+ const chunk = data.subarray(srcStart, srcStart + rowLen);
4435
+ dst.set(chunk, dstStart);
4436
+ }
4420
4437
  }
4421
4438
  }
4422
4439
 
@@ -6349,8 +6366,9 @@ function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, bl
6349
6366
  }
6350
6367
 
6351
6368
  // src/PixelData/fillPixelDataFast.ts
6352
- var SCRATCH_RECT4 = makeClippedRect();
6353
6369
  function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6370
+ const dstW = dst.w;
6371
+ const dstH = dst.h;
6354
6372
  let x;
6355
6373
  let y;
6356
6374
  let w;
@@ -6371,23 +6389,30 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6371
6389
  w = dst.w;
6372
6390
  h = dst.h;
6373
6391
  }
6374
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT4);
6375
- if (!clip.inBounds) return;
6376
- const {
6377
- x: finalX,
6378
- y: finalY,
6379
- w: actualW,
6380
- h: actualH
6381
- } = clip;
6392
+ let dstX = x;
6393
+ let dstY = y;
6394
+ let fillW = w;
6395
+ let fillH = h;
6396
+ if (dstX < 0) {
6397
+ fillW += dstX;
6398
+ dstX = 0;
6399
+ }
6400
+ if (dstY < 0) {
6401
+ fillH += dstY;
6402
+ dstY = 0;
6403
+ }
6404
+ fillW = Math.min(fillW, dstW - dstX);
6405
+ fillH = Math.min(fillH, dstH - dstY);
6406
+ if (fillW <= 0 || fillH <= 0) return;
6382
6407
  const dst32 = dst.data;
6383
6408
  const dw = dst.w;
6384
- if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
6409
+ if (fillW === dw && fillH === dst.h && dstX === 0 && dstY === 0) {
6385
6410
  dst32.fill(color);
6386
6411
  return;
6387
6412
  }
6388
- for (let iy = 0; iy < actualH; iy++) {
6389
- const start = (finalY + iy) * dw + finalX;
6390
- const end = start + actualW;
6413
+ for (let iy = 0; iy < fillH; iy++) {
6414
+ const start = (dstY + iy) * dw + dstX;
6415
+ const end = start + fillW;
6391
6416
  dst32.fill(color, start, end);
6392
6417
  }
6393
6418
  }
@@ -6405,36 +6430,46 @@ function copyPixelData(target) {
6405
6430
  }
6406
6431
 
6407
6432
  // src/PixelData/extractPixelDataBuffer.ts
6408
- var SCRATCH_BLIT4 = makeClippedBlit();
6409
6433
  function extractPixelDataBuffer(source, _x, _y, _w, _h) {
6410
- const {
6411
- x,
6412
- y,
6413
- w,
6414
- h
6415
- } = typeof _x === "object" ? _x : {
6416
- x: _x,
6417
- y: _y,
6418
- w: _w,
6419
- h: _h
6420
- };
6434
+ let x;
6435
+ let y;
6436
+ let w;
6437
+ let h;
6438
+ if (typeof _x === "object") {
6439
+ x = _x.x;
6440
+ y = _x.y;
6441
+ w = _x.w;
6442
+ h = _x.h;
6443
+ } else {
6444
+ x = _x;
6445
+ y = _y;
6446
+ w = _w;
6447
+ h = _h;
6448
+ }
6421
6449
  const srcW = source.w;
6422
6450
  const srcH = source.h;
6423
6451
  const srcData = source.data;
6424
- if (w <= 0 || h <= 0) {
6425
- return new Uint32Array(0);
6426
- }
6452
+ if (w <= 0 || h <= 0) return new Uint32Array(0);
6427
6453
  const dstData = new Uint32Array(w * h);
6428
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT4);
6429
- if (!clip.inBounds) return dstData;
6430
- const {
6431
- x: dstX,
6432
- y: dstY,
6433
- sx: srcX,
6434
- sy: srcY,
6435
- w: copyW,
6436
- h: copyH
6437
- } = clip;
6454
+ let srcX = x;
6455
+ let srcY = y;
6456
+ let dstX = 0;
6457
+ let dstY = 0;
6458
+ let copyW = w;
6459
+ let copyH = h;
6460
+ if (srcX < 0) {
6461
+ dstX = -srcX;
6462
+ copyW += srcX;
6463
+ srcX = 0;
6464
+ }
6465
+ if (srcY < 0) {
6466
+ dstY = -srcY;
6467
+ copyH += srcY;
6468
+ srcY = 0;
6469
+ }
6470
+ copyW = Math.min(copyW, srcW - srcX);
6471
+ copyH = Math.min(copyH, srcH - srcY);
6472
+ if (copyW <= 0 || copyH <= 0) return dstData;
6438
6473
  for (let row = 0; row < copyH; row++) {
6439
6474
  const srcStart = (srcY + row) * srcW + srcX;
6440
6475
  const dstStart = (dstY + row) * w + dstX;
@@ -6527,6 +6562,46 @@ function resamplePixelDataInPlace(pixelData, factor) {
6527
6562
  resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
6528
6563
  }
6529
6564
 
6565
+ // src/PixelData/resizePixelData.ts
6566
+ function resizePixelData(target, newWidth, newHeight, offsetX = 0, offsetY = 0, out) {
6567
+ const newData = new Uint32Array(newWidth * newHeight);
6568
+ const {
6569
+ w: oldW,
6570
+ h: oldH,
6571
+ data: oldData
6572
+ } = target;
6573
+ const result = out ?? {};
6574
+ result.w = newWidth;
6575
+ result.h = newHeight;
6576
+ result.data = newData;
6577
+ const x0 = Math.max(0, offsetX);
6578
+ const y0 = Math.max(0, offsetY);
6579
+ const x1 = Math.min(newWidth, offsetX + oldW);
6580
+ const y1 = Math.min(newHeight, offsetY + oldH);
6581
+ if (x1 <= x0 || y1 <= y0) {
6582
+ return result;
6583
+ }
6584
+ const copyW = x1 - x0;
6585
+ const copyH = y1 - y0;
6586
+ if (copyW === oldW && copyW === newWidth && offsetX === 0) {
6587
+ const srcStart = (y0 - offsetY) * oldW;
6588
+ const dstStart = y0 * newWidth;
6589
+ const len = copyW * copyH;
6590
+ newData.set(oldData.subarray(srcStart, srcStart + len), dstStart);
6591
+ return result;
6592
+ }
6593
+ for (let row = 0; row < copyH; row++) {
6594
+ const dstY = y0 + row;
6595
+ const srcY = dstY - offsetY;
6596
+ const srcX = x0 - offsetX;
6597
+ const dstStart = dstY * newWidth + x0;
6598
+ const srcStart = srcY * oldW + srcX;
6599
+ const chunk = oldData.subarray(srcStart, srcStart + copyW);
6600
+ newData.set(chunk, dstStart);
6601
+ }
6602
+ return result;
6603
+ }
6604
+
6530
6605
  // src/PixelData/rotatePixelData.ts
6531
6606
  function rotatePixelData(pixelData) {
6532
6607
  const width = pixelData.w;
@@ -6580,36 +6655,50 @@ function uInt32ArrayToPixelData(data, width, height) {
6580
6655
  }
6581
6656
 
6582
6657
  // src/PixelData/writePixelDataBuffer.ts
6583
- var SCRATCH_BLIT5 = makeClippedBlit();
6584
6658
  function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
6585
- const {
6586
- x,
6587
- y,
6588
- w,
6589
- h
6590
- } = typeof _x === "object" ? _x : {
6591
- x: _x,
6592
- y: _y,
6593
- w: _w,
6594
- h: _h
6595
- };
6659
+ let x;
6660
+ let y;
6661
+ let w;
6662
+ let h;
6663
+ if (typeof _x === "object") {
6664
+ x = _x.x;
6665
+ y = _x.y;
6666
+ w = _x.w;
6667
+ h = _x.h;
6668
+ } else {
6669
+ x = _x;
6670
+ y = _y;
6671
+ w = _w;
6672
+ h = _h;
6673
+ }
6674
+ if (w <= 0 || h <= 0) return;
6596
6675
  const dstW = target.w;
6597
6676
  const dstH = target.h;
6598
6677
  const dstData = target.data;
6599
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT5);
6600
- if (!clip.inBounds) return;
6601
- const {
6602
- x: dstX,
6603
- y: dstY,
6604
- sx: srcX,
6605
- sy: srcY,
6606
- w: copyW,
6607
- h: copyH
6608
- } = clip;
6678
+ let dstX = x;
6679
+ let dstY = y;
6680
+ let srcX = 0;
6681
+ let srcY = 0;
6682
+ let copyW = w;
6683
+ let copyH = h;
6684
+ if (dstX < 0) {
6685
+ srcX = -dstX;
6686
+ copyW += dstX;
6687
+ dstX = 0;
6688
+ }
6689
+ if (dstY < 0) {
6690
+ srcY = -dstY;
6691
+ copyH += dstY;
6692
+ dstY = 0;
6693
+ }
6694
+ copyW = Math.min(copyW, dstW - dstX);
6695
+ copyH = Math.min(copyH, dstH - dstY);
6696
+ if (copyW <= 0 || copyH <= 0) return;
6609
6697
  for (let row = 0; row < copyH; row++) {
6610
6698
  const dstStart = (dstY + row) * dstW + dstX;
6611
6699
  const srcStart = (srcY + row) * w + srcX;
6612
- dstData.set(data.subarray(srcStart, srcStart + copyW), dstStart);
6700
+ const chunk = data.subarray(srcStart, srcStart + copyW);
6701
+ dstData.set(chunk, dstStart);
6613
6702
  }
6614
6703
  }
6615
6704
 
@@ -6626,6 +6715,41 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6626
6715
  }
6627
6716
  }
6628
6717
  }
6718
+
6719
+ // src/PixelData/writePixelData.ts
6720
+ function writePixelData(target, source, x = 0, y = 0) {
6721
+ const dstW = target.w;
6722
+ const dstH = target.h;
6723
+ const dst = target.data;
6724
+ const srcW = source.w;
6725
+ const srcH = source.h;
6726
+ const src = source.data;
6727
+ let dstX = x;
6728
+ let dstY = y;
6729
+ let srcX = 0;
6730
+ let srcY = 0;
6731
+ let copyW = srcW;
6732
+ let copyH = srcH;
6733
+ if (dstX < 0) {
6734
+ srcX = -dstX;
6735
+ copyW += dstX;
6736
+ dstX = 0;
6737
+ }
6738
+ if (dstY < 0) {
6739
+ srcY = -dstY;
6740
+ copyH += dstY;
6741
+ dstY = 0;
6742
+ }
6743
+ copyW = Math.min(copyW, dstW - dstX);
6744
+ copyH = Math.min(copyH, dstH - dstY);
6745
+ if (copyW <= 0 || copyH <= 0) return;
6746
+ for (let row = 0; row < copyH; row++) {
6747
+ const dstStart = (dstY + row) * dstW + dstX;
6748
+ const srcStart = (srcY + row) * srcW + srcX;
6749
+ const chunk = src.subarray(srcStart, srcStart + copyW);
6750
+ dst.set(chunk, dstStart);
6751
+ }
6752
+ }
6629
6753
  // Annotate the CommonJS export names for ESM import in node:
6630
6754
  0 && (module.exports = {
6631
6755
  AlphaMaskPaintBuffer,
@@ -6701,6 +6825,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6701
6825
  eachTileInBounds,
6702
6826
  exclusionFast,
6703
6827
  exclusionPerfect,
6828
+ extractImageData,
6704
6829
  extractImageDataBuffer,
6705
6830
  extractMask,
6706
6831
  extractMaskBuffer,
@@ -6764,8 +6889,6 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6764
6889
  makeCircleBinaryMaskOutline,
6765
6890
  makeCirclePaintAlphaMask,
6766
6891
  makeCirclePaintBinaryMask,
6767
- makeClippedBlit,
6768
- makeClippedRect,
6769
6892
  makeColorPaintBufferCanvasRenderer,
6770
6893
  makeColorPaintBufferCommitter,
6771
6894
  makeColorPaintBufferManager,
@@ -6832,8 +6955,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6832
6955
  resamplePixelDataInPlace,
6833
6956
  resampleUint32Array,
6834
6957
  resizeImageData,
6835
- resolveBlitClipping,
6836
- resolveRectClipping,
6958
+ resizePixelData,
6837
6959
  rotatePixelData,
6838
6960
  screenFast,
6839
6961
  screenPerfect,
@@ -6873,6 +6995,7 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6873
6995
  writeImageDataToClipboard,
6874
6996
  writeImgBlobToClipboard,
6875
6997
  writePaintBufferToPixelData,
6998
+ writePixelData,
6876
6999
  writePixelDataBuffer,
6877
7000
  xorFast,
6878
7001
  xorPerfect