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.
@@ -86,86 +86,7 @@ function color32ToCssRGBA(color) {
86
86
  return `rgba(${r},${g},${b},${alpha})`;
87
87
  }
88
88
 
89
- // src/Rect/resolveClipping.ts
90
- var makeClippedRect = () => ({
91
- x: 0,
92
- y: 0,
93
- w: 0,
94
- h: 0,
95
- inBounds: false
96
- });
97
- var makeClippedBlit = () => ({
98
- x: 0,
99
- y: 0,
100
- sx: 0,
101
- sy: 0,
102
- w: 0,
103
- h: 0,
104
- inBounds: false
105
- });
106
- function resolveRectClipping(x, y, w, h, boundaryW, boundaryH, out) {
107
- if (x < 0) {
108
- w += x;
109
- x = 0;
110
- }
111
- if (y < 0) {
112
- h += y;
113
- y = 0;
114
- }
115
- const actualW = Math.min(w, boundaryW - x);
116
- const actualH = Math.min(h, boundaryH - y);
117
- if (actualW <= 0 || actualH <= 0) {
118
- out.inBounds = false;
119
- return out;
120
- }
121
- out.x = x;
122
- out.y = y;
123
- out.w = actualW;
124
- out.h = actualH;
125
- out.inBounds = true;
126
- return out;
127
- }
128
- function resolveBlitClipping(x, y, sx, sy, w, h, dstW, dstH, srcW, srcH, out) {
129
- if (sx < 0) {
130
- x -= sx;
131
- w += sx;
132
- sx = 0;
133
- }
134
- if (sy < 0) {
135
- y -= sy;
136
- h += sy;
137
- sy = 0;
138
- }
139
- w = Math.min(w, srcW - sx);
140
- h = Math.min(h, srcH - sy);
141
- if (x < 0) {
142
- sx -= x;
143
- w += x;
144
- x = 0;
145
- }
146
- if (y < 0) {
147
- sy -= y;
148
- h += y;
149
- y = 0;
150
- }
151
- const actualW = Math.min(w, dstW - x);
152
- const actualH = Math.min(h, dstH - y);
153
- if (actualW <= 0 || actualH <= 0) {
154
- out.inBounds = false;
155
- return out;
156
- }
157
- out.x = x;
158
- out.y = y;
159
- out.sx = sx;
160
- out.sy = sy;
161
- out.w = actualW;
162
- out.h = actualH;
163
- out.inBounds = true;
164
- return out;
165
- }
166
-
167
89
  // src/ImageData/extractImageDataBuffer.ts
168
- var SCRATCH_BLIT = makeClippedBlit();
169
90
  function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
170
91
  const {
171
92
  x,
@@ -178,28 +99,50 @@ function extractImageDataBuffer(imageData, _x, _y, _w, _h) {
178
99
  w: _w,
179
100
  h: _h
180
101
  };
181
- const {
182
- width: srcW,
183
- height: srcH,
184
- data: src
185
- } = imageData;
186
102
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
187
- const out = new Uint8ClampedArray(w * h * 4);
188
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT);
189
- if (!clip.inBounds) return out;
190
- const {
191
- x: dstX,
192
- y: dstY,
193
- sx: srcX,
194
- sy: srcY,
195
- w: copyW,
196
- h: copyH
197
- } = clip;
198
- const rowLen = copyW * 4;
199
- for (let row = 0; row < copyH; row++) {
200
- const srcStart = ((srcY + row) * srcW + srcX) * 4;
201
- const dstStart = ((dstY + row) * w + dstX) * 4;
202
- out.set(src.subarray(srcStart, srcStart + rowLen), dstStart);
103
+ const srcW = imageData.width;
104
+ const srcH = imageData.height;
105
+ const src = imageData.data;
106
+ const outLen = w * h * 4;
107
+ const out = new Uint8ClampedArray(outLen);
108
+ let srcX = x;
109
+ let srcY = y;
110
+ let dstX = 0;
111
+ let dstY = 0;
112
+ let copyW = w;
113
+ let copyH = h;
114
+ if (srcX < 0) {
115
+ dstX = -srcX;
116
+ copyW += srcX;
117
+ srcX = 0;
118
+ }
119
+ if (srcY < 0) {
120
+ dstY = -srcY;
121
+ copyH += srcY;
122
+ srcY = 0;
123
+ }
124
+ copyW = Math.min(copyW, srcW - srcX);
125
+ copyH = Math.min(copyH, srcH - srcY);
126
+ if (copyW <= 0 || copyH <= 0) return out;
127
+ const isAligned = src.byteOffset % 4 === 0;
128
+ if (isAligned) {
129
+ const srcLen32 = src.byteLength / 4;
130
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
131
+ const out32 = new Uint32Array(out.buffer);
132
+ for (let row = 0; row < copyH; row++) {
133
+ const srcStart = (srcY + row) * srcW + srcX;
134
+ const dstStart = (dstY + row) * w + dstX;
135
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
136
+ out32.set(chunk, dstStart);
137
+ }
138
+ } else {
139
+ const rowLen = copyW * 4;
140
+ for (let row = 0; row < copyH; row++) {
141
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
142
+ const dstStart = ((dstY + row) * w + dstX) * 4;
143
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
144
+ out.set(chunk, dstStart);
145
+ }
203
146
  }
204
147
  return out;
205
148
  }
@@ -3640,8 +3583,9 @@ var mutatorBlendPixelData = ((writer, deps = defaults13) => {
3640
3583
  });
3641
3584
 
3642
3585
  // src/PixelData/fillPixelData.ts
3643
- var SCRATCH_RECT = makeClippedRect();
3644
3586
  function fillPixelData(dst, color, _x, _y, _w, _h) {
3587
+ const dstW = dst.w;
3588
+ const dstH = dst.h;
3645
3589
  let x;
3646
3590
  let y;
3647
3591
  let w;
@@ -3649,8 +3593,8 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3649
3593
  if (typeof _x === "object") {
3650
3594
  x = _x.x ?? 0;
3651
3595
  y = _x.y ?? 0;
3652
- w = _x.w ?? dst.w;
3653
- h = _x.h ?? dst.h;
3596
+ w = _x.w ?? dstW;
3597
+ h = _x.h ?? dstH;
3654
3598
  } else if (typeof _x === "number") {
3655
3599
  x = _x;
3656
3600
  y = _y;
@@ -3659,24 +3603,41 @@ function fillPixelData(dst, color, _x, _y, _w, _h) {
3659
3603
  } else {
3660
3604
  x = 0;
3661
3605
  y = 0;
3662
- w = dst.w;
3663
- h = dst.h;
3664
- }
3665
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT);
3666
- if (!clip.inBounds) return false;
3667
- const {
3668
- x: finalX,
3669
- y: finalY,
3670
- w: actualW,
3671
- h: actualH
3672
- } = clip;
3606
+ w = dstW;
3607
+ h = dstH;
3608
+ }
3609
+ let dstX = x;
3610
+ let dstY = y;
3611
+ let fillW = w;
3612
+ let fillH = h;
3613
+ if (dstX < 0) {
3614
+ fillW += dstX;
3615
+ dstX = 0;
3616
+ }
3617
+ if (dstY < 0) {
3618
+ fillH += dstY;
3619
+ dstY = 0;
3620
+ }
3621
+ fillW = Math.min(fillW, dstW - dstX);
3622
+ fillH = Math.min(fillH, dstH - dstY);
3623
+ if (fillW <= 0 || fillH <= 0) return false;
3673
3624
  const dst32 = dst.data;
3674
- const dw = dst.w;
3675
3625
  let hasChanged = false;
3676
- for (let iy = 0; iy < actualH; iy++) {
3677
- const rowOffset = (finalY + iy) * dw;
3678
- const start = rowOffset + finalX;
3679
- const end = start + actualW;
3626
+ if (dstX === 0 && fillW === dstW) {
3627
+ const start = dstY * dstW;
3628
+ const end = start + fillW * fillH;
3629
+ for (let i = start; i < end; i++) {
3630
+ if (dst32[i] !== color) {
3631
+ dst32[i] = color;
3632
+ hasChanged = true;
3633
+ }
3634
+ }
3635
+ return hasChanged;
3636
+ }
3637
+ for (let iy = 0; iy < fillH; iy++) {
3638
+ const rowOffset = (dstY + iy) * dstW;
3639
+ const start = rowOffset + dstX;
3640
+ const end = start + fillW;
3680
3641
  for (let i = start; i < end; i++) {
3681
3642
  if (dst32[i] !== color) {
3682
3643
  dst32[i] = color;
@@ -3738,39 +3699,48 @@ var mutatorFillRect = ((writer, deps = defaults15) => {
3738
3699
  });
3739
3700
 
3740
3701
  // src/PixelData/fillPixelDataBinaryMask.ts
3741
- var SCRATCH_RECT2 = makeClippedRect();
3742
3702
  function fillPixelDataBinaryMask(target, color, mask, x = 0, y = 0) {
3703
+ const targetW = target.w;
3704
+ const targetH = target.h;
3743
3705
  const maskW = mask.w;
3744
3706
  const maskH = mask.h;
3745
- const clip = resolveRectClipping(x, y, maskW, maskH, target.w, target.h, SCRATCH_RECT2);
3746
- if (!clip.inBounds) return false;
3747
- const {
3748
- x: finalX,
3749
- y: finalY,
3750
- w: actualW,
3751
- h: actualH
3752
- } = clip;
3707
+ let dstX = x;
3708
+ let dstY = y;
3709
+ let actualW = maskW;
3710
+ let actualH = maskH;
3711
+ if (dstX < 0) {
3712
+ actualW += dstX;
3713
+ dstX = 0;
3714
+ }
3715
+ if (dstY < 0) {
3716
+ actualH += dstY;
3717
+ dstY = 0;
3718
+ }
3719
+ actualW = Math.min(actualW, targetW - dstX);
3720
+ actualH = Math.min(actualH, targetH - dstY);
3721
+ if (actualW <= 0 || actualH <= 0) return false;
3753
3722
  const maskData = mask.data;
3754
3723
  const dst32 = target.data;
3755
- const dw = target.w;
3724
+ const mx = dstX - x;
3725
+ const my = dstY - y;
3756
3726
  let hasChanged = false;
3727
+ let dIdx = dstY * targetW + dstX;
3728
+ let mIdx = my * maskW + mx;
3729
+ const dStride = targetW - actualW;
3730
+ const mStride = maskW - actualW;
3757
3731
  for (let iy = 0; iy < actualH; iy++) {
3758
- const currentY = finalY + iy;
3759
- const maskY = currentY - y;
3760
- const maskOffset = maskY * maskW;
3761
- const dstRowOffset = currentY * dw;
3762
3732
  for (let ix = 0; ix < actualW; ix++) {
3763
- const currentX = finalX + ix;
3764
- const maskX = currentX - x;
3765
- const maskIndex = maskOffset + maskX;
3766
- if (maskData[maskIndex]) {
3767
- const current = dst32[dstRowOffset + currentX];
3768
- if (current !== color) {
3769
- dst32[dstRowOffset + currentX] = color;
3733
+ if (maskData[mIdx]) {
3734
+ if (dst32[dIdx] !== color) {
3735
+ dst32[dIdx] = color;
3770
3736
  hasChanged = true;
3771
3737
  }
3772
3738
  }
3739
+ dIdx++;
3740
+ mIdx++;
3773
3741
  }
3742
+ dIdx += dStride;
3743
+ mIdx += mStride;
3774
3744
  }
3775
3745
  return hasChanged;
3776
3746
  }
@@ -3792,35 +3762,43 @@ var mutatorFillBinaryMask = ((writer, deps = defaults16) => {
3792
3762
  });
3793
3763
 
3794
3764
  // src/PixelData/invertPixelData.ts
3795
- var SCRATCH_RECT3 = makeClippedRect();
3796
3765
  function invertPixelData(target, opts) {
3766
+ const targetW = target.w;
3767
+ const targetH = target.h;
3797
3768
  const mask = opts?.mask;
3769
+ const invertMask = opts?.invertMask ?? false;
3798
3770
  const targetX = opts?.x ?? 0;
3799
3771
  const targetY = opts?.y ?? 0;
3800
3772
  const mx = opts?.mx ?? 0;
3801
3773
  const my = opts?.my ?? 0;
3802
- const width = opts?.w ?? target.w;
3803
- const height = opts?.h ?? target.h;
3804
- const invertMask = opts?.invertMask ?? false;
3805
- const clip = resolveRectClipping(targetX, targetY, width, height, target.w, target.h, SCRATCH_RECT3);
3806
- if (!clip.inBounds) return false;
3807
- const {
3808
- x,
3809
- y,
3810
- w: actualW,
3811
- h: actualH
3812
- } = clip;
3774
+ const w = opts?.w ?? targetW;
3775
+ const h = opts?.h ?? targetH;
3776
+ let x = targetX;
3777
+ let y = targetY;
3778
+ let actualW = w;
3779
+ let actualH = h;
3780
+ if (x < 0) {
3781
+ actualW += x;
3782
+ x = 0;
3783
+ }
3784
+ if (y < 0) {
3785
+ actualH += y;
3786
+ y = 0;
3787
+ }
3788
+ actualW = Math.min(actualW, targetW - x);
3789
+ actualH = Math.min(actualH, targetH - y);
3790
+ if (actualW <= 0 || actualH <= 0) return false;
3813
3791
  const dst32 = target.data;
3814
- const dw = target.w;
3815
- const mPitch = mask?.w ?? width;
3792
+ const dw = targetW;
3816
3793
  const dx = x - targetX;
3817
3794
  const dy = y - targetY;
3818
3795
  let dIdx = y * dw + x;
3819
- let mIdx = (my + dy) * mPitch + (mx + dx);
3820
3796
  const dStride = dw - actualW;
3821
- const mStride = mPitch - actualW;
3822
3797
  if (mask) {
3823
3798
  const maskData = mask.data;
3799
+ const mPitch = mask.w;
3800
+ let mIdx = (my + dy) * mPitch + (mx + dx);
3801
+ const mStride = mPitch - actualW;
3824
3802
  for (let iy = 0; iy < actualH; iy++) {
3825
3803
  for (let ix = 0; ix < actualW; ix++) {
3826
3804
  const mVal = maskData[mIdx];
@@ -3893,12 +3871,9 @@ function makeFullPixelMutator(writer) {
3893
3871
  }
3894
3872
 
3895
3873
  // src/ImageData/copyImageData.ts
3896
- function copyImageData({
3897
- data,
3898
- width,
3899
- height
3900
- }) {
3901
- return new ImageData(data.slice(), width, height);
3874
+ function copyImageData(source) {
3875
+ const dataCopy = new Uint8ClampedArray(source.data);
3876
+ return new ImageData(dataCopy, source.width, source.height);
3902
3877
  }
3903
3878
  function copyImageDataLike({
3904
3879
  data,
@@ -3912,6 +3887,26 @@ function copyImageDataLike({
3912
3887
  };
3913
3888
  }
3914
3889
 
3890
+ // src/ImageData/extractImageData.ts
3891
+ function extractImageData(imageData, _x, _y, _w, _h) {
3892
+ const {
3893
+ x,
3894
+ y,
3895
+ w,
3896
+ h
3897
+ } = typeof _x === "object" ? _x : {
3898
+ x: _x,
3899
+ y: _y,
3900
+ w: _w,
3901
+ h: _h
3902
+ };
3903
+ if (w <= 0 || h <= 0) return null;
3904
+ const result = new ImageData(w, h);
3905
+ const buffer = extractImageDataBuffer(imageData, x, y, w, h);
3906
+ result.data.set(buffer);
3907
+ return result;
3908
+ }
3909
+
3915
3910
  // src/ImageData/ImageDataLike.ts
3916
3911
  function makeImageDataLike(width, height, data) {
3917
3912
  const size = width * height * 4;
@@ -4062,94 +4057,117 @@ function uInt32ArrayToImageDataLike(data, width, height) {
4062
4057
  }
4063
4058
 
4064
4059
  // src/ImageData/writeImageData.ts
4065
- var SCRATCH_BLIT2 = makeClippedBlit();
4066
- function writeImageData(target, source, x, y, sx = 0, sy = 0, sw = source.width, sh = source.height, mask = null, maskType = 1 /* BINARY */) {
4060
+ function writeImageData(target, source, x = 0, y = 0) {
4067
4061
  const dstW = target.width;
4068
4062
  const dstH = target.height;
4069
- const dstData = target.data;
4063
+ const dst = target.data;
4070
4064
  const srcW = source.width;
4071
- const srcData = source.data;
4072
- const clip = resolveBlitClipping(x, y, sx, sy, sw, sh, dstW, dstH, srcW, source.height, SCRATCH_BLIT2);
4073
- if (!clip.inBounds) return;
4074
- const {
4075
- x: dstX,
4076
- y: dstY,
4077
- sx: srcX,
4078
- sy: srcY,
4079
- w: copyW,
4080
- h: copyH
4081
- } = clip;
4082
- const useMask = !!mask;
4083
- for (let row = 0; row < copyH; row++) {
4084
- const currentDstY = dstY + row;
4085
- const currentSrcY = srcY + row;
4086
- const dstStart = (currentDstY * dstW + dstX) * 4;
4087
- const srcStart = (currentSrcY * srcW + srcX) * 4;
4088
- if (useMask && mask) {
4089
- for (let ix = 0; ix < copyW; ix++) {
4090
- const mi = currentSrcY * srcW + (srcX + ix);
4091
- const alpha = mask[mi];
4092
- if (alpha === 0) {
4093
- continue;
4094
- }
4095
- const di = dstStart + ix * 4;
4096
- const si = srcStart + ix * 4;
4097
- if (maskType === 1 /* BINARY */ || alpha === 255) {
4098
- dstData[di] = srcData[si];
4099
- dstData[di + 1] = srcData[si + 1];
4100
- dstData[di + 2] = srcData[si + 2];
4101
- dstData[di + 3] = srcData[si + 3];
4102
- } else {
4103
- const a = alpha / 255;
4104
- const invA = 1 - a;
4105
- dstData[di] = srcData[si] * a + dstData[di] * invA;
4106
- dstData[di + 1] = srcData[si + 1] * a + dstData[di + 1] * invA;
4107
- dstData[di + 2] = srcData[si + 2] * a + dstData[di + 2] * invA;
4108
- dstData[di + 3] = srcData[si + 3] * a + dstData[di + 3] * invA;
4109
- }
4110
- }
4111
- } else {
4112
- const byteLen = copyW * 4;
4113
- const sub = srcData.subarray(srcStart, srcStart + byteLen);
4114
- dstData.set(sub, dstStart);
4065
+ const srcH = source.height;
4066
+ const src = source.data;
4067
+ let dstX = x;
4068
+ let dstY = y;
4069
+ let srcX = 0;
4070
+ let srcY = 0;
4071
+ let copyW = srcW;
4072
+ let copyH = srcH;
4073
+ if (dstX < 0) {
4074
+ srcX = -dstX;
4075
+ copyW += dstX;
4076
+ dstX = 0;
4077
+ }
4078
+ if (dstY < 0) {
4079
+ srcY = -dstY;
4080
+ copyH += dstY;
4081
+ dstY = 0;
4082
+ }
4083
+ copyW = Math.min(copyW, dstW - dstX);
4084
+ copyH = Math.min(copyH, dstH - dstY);
4085
+ if (copyW <= 0 || copyH <= 0) return;
4086
+ const isDstAligned = dst.byteOffset % 4 === 0;
4087
+ const isSrcAligned = src.byteOffset % 4 === 0;
4088
+ if (isDstAligned && isSrcAligned) {
4089
+ const dstLen32 = dst.byteLength / 4;
4090
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4091
+ const srcLen32 = src.byteLength / 4;
4092
+ const src32 = new Uint32Array(src.buffer, src.byteOffset, srcLen32);
4093
+ for (let row = 0; row < copyH; row++) {
4094
+ const dstStart = (dstY + row) * dstW + dstX;
4095
+ const srcStart = (srcY + row) * srcW + srcX;
4096
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4097
+ dst32.set(chunk, dstStart);
4098
+ }
4099
+ } else {
4100
+ const rowLen = copyW * 4;
4101
+ for (let row = 0; row < copyH; row++) {
4102
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4103
+ const srcStart = ((srcY + row) * srcW + srcX) * 4;
4104
+ const chunk = src.subarray(srcStart, srcStart + rowLen);
4105
+ dst.set(chunk, dstStart);
4115
4106
  }
4116
4107
  }
4117
4108
  }
4118
4109
 
4119
4110
  // src/ImageData/writeImageDataBuffer.ts
4120
- var SCRATCH_BLIT3 = makeClippedBlit();
4121
4111
  function writeImageDataBuffer(target, data, _x, _y, _w, _h) {
4122
- const {
4123
- x,
4124
- y,
4125
- w,
4126
- h
4127
- } = typeof _x === "object" ? _x : {
4128
- x: _x,
4129
- y: _y,
4130
- w: _w,
4131
- h: _h
4132
- };
4133
- const {
4134
- width: dstW,
4135
- height: dstH,
4136
- data: dst
4137
- } = target;
4138
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT3);
4139
- if (!clip.inBounds) return;
4140
- const {
4141
- x: dstX,
4142
- y: dstY,
4143
- sx: srcX,
4144
- sy: srcY,
4145
- w: copyW,
4146
- h: copyH
4147
- } = clip;
4148
- const rowLen = copyW * 4;
4149
- for (let row = 0; row < copyH; row++) {
4150
- const dstStart = ((dstY + row) * dstW + dstX) * 4;
4151
- const srcStart = ((srcY + row) * w + srcX) * 4;
4152
- dst.set(data.subarray(srcStart, srcStart + rowLen), dstStart);
4112
+ let x;
4113
+ let y;
4114
+ let w;
4115
+ let h;
4116
+ if (typeof _x === "object") {
4117
+ x = _x.x;
4118
+ y = _x.y;
4119
+ w = _x.w;
4120
+ h = _x.h;
4121
+ } else {
4122
+ x = _x;
4123
+ y = _y;
4124
+ w = _w;
4125
+ h = _h;
4126
+ }
4127
+ if (w <= 0 || h <= 0) return;
4128
+ const dstW = target.width;
4129
+ const dstH = target.height;
4130
+ const dst = target.data;
4131
+ let dstX = x;
4132
+ let dstY = y;
4133
+ let srcX = 0;
4134
+ let srcY = 0;
4135
+ let copyW = w;
4136
+ let copyH = h;
4137
+ if (dstX < 0) {
4138
+ srcX = -dstX;
4139
+ copyW += dstX;
4140
+ dstX = 0;
4141
+ }
4142
+ if (dstY < 0) {
4143
+ srcY = -dstY;
4144
+ copyH += dstY;
4145
+ dstY = 0;
4146
+ }
4147
+ copyW = Math.min(copyW, dstW - dstX);
4148
+ copyH = Math.min(copyH, dstH - dstY);
4149
+ if (copyW <= 0 || copyH <= 0) return;
4150
+ const isDstAligned = dst.byteOffset % 4 === 0;
4151
+ const isSrcAligned = data.byteOffset % 4 === 0;
4152
+ if (isDstAligned && isSrcAligned) {
4153
+ const dstLen32 = dst.byteLength / 4;
4154
+ const dst32 = new Uint32Array(dst.buffer, dst.byteOffset, dstLen32);
4155
+ const srcLen32 = data.byteLength / 4;
4156
+ const src32 = new Uint32Array(data.buffer, data.byteOffset, srcLen32);
4157
+ for (let row = 0; row < copyH; row++) {
4158
+ const dstStart = (dstY + row) * dstW + dstX;
4159
+ const srcStart = (srcY + row) * w + srcX;
4160
+ const chunk = src32.subarray(srcStart, srcStart + copyW);
4161
+ dst32.set(chunk, dstStart);
4162
+ }
4163
+ } else {
4164
+ const rowLen = copyW * 4;
4165
+ for (let row = 0; row < copyH; row++) {
4166
+ const dstStart = ((dstY + row) * dstW + dstX) * 4;
4167
+ const srcStart = ((srcY + row) * w + srcX) * 4;
4168
+ const chunk = data.subarray(srcStart, srcStart + rowLen);
4169
+ dst.set(chunk, dstStart);
4170
+ }
4153
4171
  }
4154
4172
  }
4155
4173
 
@@ -6082,8 +6100,9 @@ function blendPixelDataPaintBuffer(target, paintBuffer, alpha = 255, blendFn, bl
6082
6100
  }
6083
6101
 
6084
6102
  // src/PixelData/fillPixelDataFast.ts
6085
- var SCRATCH_RECT4 = makeClippedRect();
6086
6103
  function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6104
+ const dstW = dst.w;
6105
+ const dstH = dst.h;
6087
6106
  let x;
6088
6107
  let y;
6089
6108
  let w;
@@ -6104,23 +6123,30 @@ function fillPixelDataFast(dst, color, _x, _y, _w, _h) {
6104
6123
  w = dst.w;
6105
6124
  h = dst.h;
6106
6125
  }
6107
- const clip = resolveRectClipping(x, y, w, h, dst.w, dst.h, SCRATCH_RECT4);
6108
- if (!clip.inBounds) return;
6109
- const {
6110
- x: finalX,
6111
- y: finalY,
6112
- w: actualW,
6113
- h: actualH
6114
- } = clip;
6126
+ let dstX = x;
6127
+ let dstY = y;
6128
+ let fillW = w;
6129
+ let fillH = h;
6130
+ if (dstX < 0) {
6131
+ fillW += dstX;
6132
+ dstX = 0;
6133
+ }
6134
+ if (dstY < 0) {
6135
+ fillH += dstY;
6136
+ dstY = 0;
6137
+ }
6138
+ fillW = Math.min(fillW, dstW - dstX);
6139
+ fillH = Math.min(fillH, dstH - dstY);
6140
+ if (fillW <= 0 || fillH <= 0) return;
6115
6141
  const dst32 = dst.data;
6116
6142
  const dw = dst.w;
6117
- if (actualW === dw && actualH === dst.h && finalX === 0 && finalY === 0) {
6143
+ if (fillW === dw && fillH === dst.h && dstX === 0 && dstY === 0) {
6118
6144
  dst32.fill(color);
6119
6145
  return;
6120
6146
  }
6121
- for (let iy = 0; iy < actualH; iy++) {
6122
- const start = (finalY + iy) * dw + finalX;
6123
- const end = start + actualW;
6147
+ for (let iy = 0; iy < fillH; iy++) {
6148
+ const start = (dstY + iy) * dw + dstX;
6149
+ const end = start + fillW;
6124
6150
  dst32.fill(color, start, end);
6125
6151
  }
6126
6152
  }
@@ -6138,36 +6164,46 @@ function copyPixelData(target) {
6138
6164
  }
6139
6165
 
6140
6166
  // src/PixelData/extractPixelDataBuffer.ts
6141
- var SCRATCH_BLIT4 = makeClippedBlit();
6142
6167
  function extractPixelDataBuffer(source, _x, _y, _w, _h) {
6143
- const {
6144
- x,
6145
- y,
6146
- w,
6147
- h
6148
- } = typeof _x === "object" ? _x : {
6149
- x: _x,
6150
- y: _y,
6151
- w: _w,
6152
- h: _h
6153
- };
6168
+ let x;
6169
+ let y;
6170
+ let w;
6171
+ let h;
6172
+ if (typeof _x === "object") {
6173
+ x = _x.x;
6174
+ y = _x.y;
6175
+ w = _x.w;
6176
+ h = _x.h;
6177
+ } else {
6178
+ x = _x;
6179
+ y = _y;
6180
+ w = _w;
6181
+ h = _h;
6182
+ }
6154
6183
  const srcW = source.w;
6155
6184
  const srcH = source.h;
6156
6185
  const srcData = source.data;
6157
- if (w <= 0 || h <= 0) {
6158
- return new Uint32Array(0);
6159
- }
6186
+ if (w <= 0 || h <= 0) return new Uint32Array(0);
6160
6187
  const dstData = new Uint32Array(w * h);
6161
- const clip = resolveBlitClipping(0, 0, x, y, w, h, w, h, srcW, srcH, SCRATCH_BLIT4);
6162
- if (!clip.inBounds) return dstData;
6163
- const {
6164
- x: dstX,
6165
- y: dstY,
6166
- sx: srcX,
6167
- sy: srcY,
6168
- w: copyW,
6169
- h: copyH
6170
- } = clip;
6188
+ let srcX = x;
6189
+ let srcY = y;
6190
+ let dstX = 0;
6191
+ let dstY = 0;
6192
+ let copyW = w;
6193
+ let copyH = h;
6194
+ if (srcX < 0) {
6195
+ dstX = -srcX;
6196
+ copyW += srcX;
6197
+ srcX = 0;
6198
+ }
6199
+ if (srcY < 0) {
6200
+ dstY = -srcY;
6201
+ copyH += srcY;
6202
+ srcY = 0;
6203
+ }
6204
+ copyW = Math.min(copyW, srcW - srcX);
6205
+ copyH = Math.min(copyH, srcH - srcY);
6206
+ if (copyW <= 0 || copyH <= 0) return dstData;
6171
6207
  for (let row = 0; row < copyH; row++) {
6172
6208
  const srcStart = (srcY + row) * srcW + srcX;
6173
6209
  const dstStart = (dstY + row) * w + dstX;
@@ -6260,6 +6296,46 @@ function resamplePixelDataInPlace(pixelData, factor) {
6260
6296
  resampled.imageData = uInt32ArrayToImageData(resampled.data, resampled.w, resampled.h);
6261
6297
  }
6262
6298
 
6299
+ // src/PixelData/resizePixelData.ts
6300
+ function resizePixelData(target, newWidth, newHeight, offsetX = 0, offsetY = 0, out) {
6301
+ const newData = new Uint32Array(newWidth * newHeight);
6302
+ const {
6303
+ w: oldW,
6304
+ h: oldH,
6305
+ data: oldData
6306
+ } = target;
6307
+ const result = out ?? {};
6308
+ result.w = newWidth;
6309
+ result.h = newHeight;
6310
+ result.data = newData;
6311
+ const x0 = Math.max(0, offsetX);
6312
+ const y0 = Math.max(0, offsetY);
6313
+ const x1 = Math.min(newWidth, offsetX + oldW);
6314
+ const y1 = Math.min(newHeight, offsetY + oldH);
6315
+ if (x1 <= x0 || y1 <= y0) {
6316
+ return result;
6317
+ }
6318
+ const copyW = x1 - x0;
6319
+ const copyH = y1 - y0;
6320
+ if (copyW === oldW && copyW === newWidth && offsetX === 0) {
6321
+ const srcStart = (y0 - offsetY) * oldW;
6322
+ const dstStart = y0 * newWidth;
6323
+ const len = copyW * copyH;
6324
+ newData.set(oldData.subarray(srcStart, srcStart + len), dstStart);
6325
+ return result;
6326
+ }
6327
+ for (let row = 0; row < copyH; row++) {
6328
+ const dstY = y0 + row;
6329
+ const srcY = dstY - offsetY;
6330
+ const srcX = x0 - offsetX;
6331
+ const dstStart = dstY * newWidth + x0;
6332
+ const srcStart = srcY * oldW + srcX;
6333
+ const chunk = oldData.subarray(srcStart, srcStart + copyW);
6334
+ newData.set(chunk, dstStart);
6335
+ }
6336
+ return result;
6337
+ }
6338
+
6263
6339
  // src/PixelData/rotatePixelData.ts
6264
6340
  function rotatePixelData(pixelData) {
6265
6341
  const width = pixelData.w;
@@ -6313,36 +6389,50 @@ function uInt32ArrayToPixelData(data, width, height) {
6313
6389
  }
6314
6390
 
6315
6391
  // src/PixelData/writePixelDataBuffer.ts
6316
- var SCRATCH_BLIT5 = makeClippedBlit();
6317
6392
  function writePixelDataBuffer(target, data, _x, _y, _w, _h) {
6318
- const {
6319
- x,
6320
- y,
6321
- w,
6322
- h
6323
- } = typeof _x === "object" ? _x : {
6324
- x: _x,
6325
- y: _y,
6326
- w: _w,
6327
- h: _h
6328
- };
6393
+ let x;
6394
+ let y;
6395
+ let w;
6396
+ let h;
6397
+ if (typeof _x === "object") {
6398
+ x = _x.x;
6399
+ y = _x.y;
6400
+ w = _x.w;
6401
+ h = _x.h;
6402
+ } else {
6403
+ x = _x;
6404
+ y = _y;
6405
+ w = _w;
6406
+ h = _h;
6407
+ }
6408
+ if (w <= 0 || h <= 0) return;
6329
6409
  const dstW = target.w;
6330
6410
  const dstH = target.h;
6331
6411
  const dstData = target.data;
6332
- const clip = resolveBlitClipping(x, y, 0, 0, w, h, dstW, dstH, w, h, SCRATCH_BLIT5);
6333
- if (!clip.inBounds) return;
6334
- const {
6335
- x: dstX,
6336
- y: dstY,
6337
- sx: srcX,
6338
- sy: srcY,
6339
- w: copyW,
6340
- h: copyH
6341
- } = clip;
6412
+ let dstX = x;
6413
+ let dstY = y;
6414
+ let srcX = 0;
6415
+ let srcY = 0;
6416
+ let copyW = w;
6417
+ let copyH = h;
6418
+ if (dstX < 0) {
6419
+ srcX = -dstX;
6420
+ copyW += dstX;
6421
+ dstX = 0;
6422
+ }
6423
+ if (dstY < 0) {
6424
+ srcY = -dstY;
6425
+ copyH += dstY;
6426
+ dstY = 0;
6427
+ }
6428
+ copyW = Math.min(copyW, dstW - dstX);
6429
+ copyH = Math.min(copyH, dstH - dstY);
6430
+ if (copyW <= 0 || copyH <= 0) return;
6342
6431
  for (let row = 0; row < copyH; row++) {
6343
6432
  const dstStart = (dstY + row) * dstW + dstX;
6344
6433
  const srcStart = (srcY + row) * w + srcX;
6345
- dstData.set(data.subarray(srcStart, srcStart + copyW), dstStart);
6434
+ const chunk = data.subarray(srcStart, srcStart + copyW);
6435
+ dstData.set(chunk, dstStart);
6346
6436
  }
6347
6437
  }
6348
6438
 
@@ -6359,6 +6449,41 @@ function writePaintBufferToPixelData(target, paintBuffer, writePixelDataBufferFn
6359
6449
  }
6360
6450
  }
6361
6451
  }
6452
+
6453
+ // src/PixelData/writePixelData.ts
6454
+ function writePixelData(target, source, x = 0, y = 0) {
6455
+ const dstW = target.w;
6456
+ const dstH = target.h;
6457
+ const dst = target.data;
6458
+ const srcW = source.w;
6459
+ const srcH = source.h;
6460
+ const src = source.data;
6461
+ let dstX = x;
6462
+ let dstY = y;
6463
+ let srcX = 0;
6464
+ let srcY = 0;
6465
+ let copyW = srcW;
6466
+ let copyH = srcH;
6467
+ if (dstX < 0) {
6468
+ srcX = -dstX;
6469
+ copyW += dstX;
6470
+ dstX = 0;
6471
+ }
6472
+ if (dstY < 0) {
6473
+ srcY = -dstY;
6474
+ copyH += dstY;
6475
+ dstY = 0;
6476
+ }
6477
+ copyW = Math.min(copyW, dstW - dstX);
6478
+ copyH = Math.min(copyH, dstH - dstY);
6479
+ if (copyW <= 0 || copyH <= 0) return;
6480
+ for (let row = 0; row < copyH; row++) {
6481
+ const dstStart = (dstY + row) * dstW + dstX;
6482
+ const srcStart = (srcY + row) * srcW + srcX;
6483
+ const chunk = src.subarray(srcStart, srcStart + copyW);
6484
+ dst.set(chunk, dstStart);
6485
+ }
6486
+ }
6362
6487
  export {
6363
6488
  AlphaMaskPaintBuffer,
6364
6489
  BASE_FAST_BLEND_MODE_FUNCTIONS,
@@ -6433,6 +6558,7 @@ export {
6433
6558
  eachTileInBounds,
6434
6559
  exclusionFast,
6435
6560
  exclusionPerfect,
6561
+ extractImageData,
6436
6562
  extractImageDataBuffer,
6437
6563
  extractMask,
6438
6564
  extractMaskBuffer,
@@ -6496,8 +6622,6 @@ export {
6496
6622
  makeCircleBinaryMaskOutline,
6497
6623
  makeCirclePaintAlphaMask,
6498
6624
  makeCirclePaintBinaryMask,
6499
- makeClippedBlit,
6500
- makeClippedRect,
6501
6625
  makeColorPaintBufferCanvasRenderer,
6502
6626
  makeColorPaintBufferCommitter,
6503
6627
  makeColorPaintBufferManager,
@@ -6564,8 +6688,7 @@ export {
6564
6688
  resamplePixelDataInPlace,
6565
6689
  resampleUint32Array,
6566
6690
  resizeImageData,
6567
- resolveBlitClipping,
6568
- resolveRectClipping,
6691
+ resizePixelData,
6569
6692
  rotatePixelData,
6570
6693
  screenFast,
6571
6694
  screenPerfect,
@@ -6605,6 +6728,7 @@ export {
6605
6728
  writeImageDataToClipboard,
6606
6729
  writeImgBlobToClipboard,
6607
6730
  writePaintBufferToPixelData,
6731
+ writePixelData,
6608
6732
  writePixelDataBuffer,
6609
6733
  xorFast,
6610
6734
  xorPerfect