pixel-data-js 0.4.0 → 0.5.1

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.
Files changed (41) hide show
  1. package/dist/index.dev.cjs +1038 -64
  2. package/dist/index.dev.cjs.map +1 -1
  3. package/dist/index.dev.js +997 -62
  4. package/dist/index.dev.js.map +1 -1
  5. package/dist/index.prod.cjs +1038 -64
  6. package/dist/index.prod.cjs.map +1 -1
  7. package/dist/index.prod.d.ts +540 -69
  8. package/dist/index.prod.js +997 -62
  9. package/dist/index.prod.js.map +1 -1
  10. package/package.json +14 -3
  11. package/src/Algorithm/floodFillSelection.ts +229 -0
  12. package/src/Canvas/PixelCanvas.ts +31 -0
  13. package/src/Canvas/ReusableCanvas.ts +44 -0
  14. package/src/Canvas/_constants.ts +2 -0
  15. package/src/Clipboard/getImageDataFromClipboard.ts +42 -0
  16. package/src/Clipboard/writeImageDataToClipboard.ts +25 -0
  17. package/src/Clipboard/writeImgBlobToClipboard.ts +13 -0
  18. package/src/ImageData/{extractImageData.ts → extractImageDataPixels.ts} +21 -3
  19. package/src/ImageData/imageDataToAlphaMask.ts +35 -0
  20. package/src/ImageData/imageDataToDataUrl.ts +27 -0
  21. package/src/ImageData/imageDataToImgBlob.ts +31 -0
  22. package/src/ImageData/imgBlobToImageData.ts +52 -0
  23. package/src/ImageData/invertImageData.ts +10 -0
  24. package/src/ImageData/resizeImageData.ts +75 -0
  25. package/src/ImageData/{writeImageData.ts → writeImageDataPixels.ts} +22 -3
  26. package/src/IndexedImage/IndexedImage.ts +89 -0
  27. package/src/Input/fileInputChangeToImageData.ts +37 -0
  28. package/src/Input/fileToImageData.ts +75 -0
  29. package/src/Input/getSupportedRasterFormats.ts +74 -0
  30. package/src/Mask/extractMask.ts +86 -0
  31. package/src/Mask/mergeMasks.ts +1 -6
  32. package/src/PixelData/blendColorPixelData.ts +9 -9
  33. package/src/PixelData/fillPixelData.ts +51 -12
  34. package/src/PixelData/invertPixelData.ts +16 -0
  35. package/src/PixelData/pixelDataToAlphaMask.ts +28 -0
  36. package/src/Rect/trimRectBounds.ts +118 -0
  37. package/src/_types.ts +37 -20
  38. package/src/blend-modes.ts +506 -66
  39. package/src/color.ts +6 -6
  40. package/src/globals.d.ts +2 -0
  41. package/src/index.ts +27 -2
@@ -20,8 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ BlendMode: () => BlendMode,
23
24
  COLOR_32_BLEND_MODES: () => COLOR_32_BLEND_MODES,
25
+ COLOR_32_BLEND_TO_INDEX: () => COLOR_32_BLEND_TO_INDEX,
26
+ INDEX_TO_COLOR_32_BLEND: () => INDEX_TO_COLOR_32_BLEND,
24
27
  MaskType: () => MaskType,
28
+ PixelData: () => PixelData,
29
+ UnsupportedFormatError: () => UnsupportedFormatError,
25
30
  applyMaskToPixelData: () => applyMaskToPixelData,
26
31
  base64DecodeArrayBuffer: () => base64DecodeArrayBuffer,
27
32
  base64EncodeArrayBuffer: () => base64EncodeArrayBuffer,
@@ -32,48 +37,76 @@ __export(src_exports, {
32
37
  color32ToHex: () => color32ToHex,
33
38
  colorBurnColor32: () => colorBurnColor32,
34
39
  colorDistance: () => colorDistance,
40
+ colorDodgeColor32: () => colorDodgeColor32,
35
41
  copyImageData: () => copyImageData,
36
42
  copyImageDataLike: () => copyImageDataLike,
37
43
  copyMask: () => copyMask,
44
+ darkenColor32: () => darkenColor32,
45
+ darkerColor32: () => darkerColor32,
38
46
  deserializeImageData: () => deserializeImageData,
39
47
  deserializeNullableImageData: () => deserializeNullableImageData,
40
48
  deserializeRawImageData: () => deserializeRawImageData,
41
49
  differenceColor32: () => differenceColor32,
42
- extractImageData: () => extractImageData,
50
+ divideColor32: () => divideColor32,
51
+ exclusionColor32: () => exclusionColor32,
52
+ extractImageDataPixels: () => extractImageDataPixels,
53
+ extractMask: () => extractMask,
54
+ fileInputChangeToImageData: () => fileInputChangeToImageData,
55
+ fileToImageData: () => fileToImageData,
43
56
  fillPixelData: () => fillPixelData,
57
+ floodFillSelection: () => floodFillSelection,
58
+ getImageDataFromClipboard: () => getImageDataFromClipboard,
59
+ getSupportedPixelFormats: () => getSupportedPixelFormats,
44
60
  hardLightColor32: () => hardLightColor32,
61
+ hardMixColor32: () => hardMixColor32,
62
+ imageDataToAlphaMask: () => imageDataToAlphaMask,
63
+ imageDataToDataUrl: () => imageDataToDataUrl,
64
+ imageDataToImgBlob: () => imageDataToImgBlob,
65
+ imgBlobToImageData: () => imgBlobToImageData,
45
66
  invertAlphaMask: () => invertAlphaMask,
46
67
  invertBinaryMask: () => invertBinaryMask,
68
+ invertImageData: () => invertImageData,
69
+ invertPixelData: () => invertPixelData,
47
70
  lerpColor32: () => lerpColor32,
48
71
  lerpColor32Fast: () => lerpColor32Fast,
72
+ lightenColor32: () => lightenColor32,
73
+ lighterColor32: () => lighterColor32,
74
+ linearBurnColor32: () => linearBurnColor32,
49
75
  linearDodgeColor32: () => linearDodgeColor32,
76
+ linearLightColor32: () => linearLightColor32,
77
+ makePixelCanvas: () => makePixelCanvas,
78
+ makeReusableCanvas: () => makeReusableCanvas,
50
79
  mergeMasks: () => mergeMasks,
51
80
  multiplyColor32: () => multiplyColor32,
52
81
  overlayColor32: () => overlayColor32,
82
+ overwriteColor32: () => overwriteColor32,
53
83
  packColor: () => packColor,
54
84
  packRGBA: () => packRGBA,
85
+ pinLightColor32: () => pinLightColor32,
86
+ pixelDataToAlphaMask: () => pixelDataToAlphaMask,
87
+ resizeImageData: () => resizeImageData,
55
88
  screenColor32: () => screenColor32,
56
89
  serializeImageData: () => serializeImageData,
57
90
  serializeNullableImageData: () => serializeNullableImageData,
91
+ softLightColor32: () => softLightColor32,
58
92
  sourceOverColor32: () => sourceOverColor32,
93
+ subtractColor32: () => subtractColor32,
94
+ trimRectBounds: () => trimRectBounds,
59
95
  unpackAlpha: () => unpackAlpha,
60
96
  unpackBlue: () => unpackBlue,
61
97
  unpackColor: () => unpackColor,
62
98
  unpackColorTo: () => unpackColorTo,
63
99
  unpackGreen: () => unpackGreen,
64
100
  unpackRed: () => unpackRed,
65
- writeImageData: () => writeImageData
101
+ vividLightColor32: () => vividLightColor32,
102
+ writeImageDataPixels: () => writeImageDataPixels,
103
+ writeImageDataToClipboard: () => writeImageDataToClipboard,
104
+ writeImgBlobToClipboard: () => writeImgBlobToClipboard
66
105
  });
67
106
  module.exports = __toCommonJS(src_exports);
68
107
 
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
108
  // src/blend-modes.ts
109
+ var overwriteColor32 = (src, dst) => src;
77
110
  var sourceOverColor32 = (src, dst) => {
78
111
  const a = src >>> 24 & 255;
79
112
  if (a === 255) return src;
@@ -90,6 +123,112 @@ var sourceOverColor32 = (src, dst) => {
90
123
  const outA = a + ((dst >>> 24 & 255) * invA >> 8);
91
124
  return (outA << 24 | outRB | outG) >>> 0;
92
125
  };
126
+ var darkenColor32 = (src, dst) => {
127
+ const sa = src >>> 24 & 255;
128
+ if (sa === 0) return dst;
129
+ const br = Math.min(src & 255, dst & 255);
130
+ const bg = Math.min(src >> 8 & 255, dst >> 8 & 255);
131
+ const bb = Math.min(src >> 16 & 255, dst >> 16 & 255);
132
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
133
+ const dr = dst & 255;
134
+ const dg = dst >> 8 & 255;
135
+ const db = dst >> 16 & 255;
136
+ const invA = 255 - sa;
137
+ const r = br * sa + dr * invA >> 8;
138
+ const g = bg * sa + dg * invA >> 8;
139
+ const b = bb * sa + db * invA >> 8;
140
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
141
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
142
+ };
143
+ var multiplyColor32 = (src, dst) => {
144
+ const sa = src >>> 24 & 255;
145
+ if (sa === 0) return dst;
146
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
147
+ const br = (src & 255) * dr + 128 >> 8;
148
+ const bg = (src >> 8 & 255) * dg >> 8;
149
+ const bb = (src >> 16 & 255) * db >> 8;
150
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
151
+ const invA = 255 - sa;
152
+ const r = br * sa + dr * invA >> 8;
153
+ const g = bg * sa + dg * invA >> 8;
154
+ const b = bb * sa + db * invA >> 8;
155
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
156
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
157
+ };
158
+ var colorBurnColor32 = (src, dst) => {
159
+ const sa = src >>> 24 & 255;
160
+ if (sa === 0) return dst;
161
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
162
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
163
+ const br = dr === 255 ? 255 : Math.max(0, 255 - (255 - dr << 8) / (sr || 1));
164
+ const bg = dg === 255 ? 255 : Math.max(0, 255 - (255 - dg << 8) / (sg || 1));
165
+ const bb = db === 255 ? 255 : Math.max(0, 255 - (255 - db << 8) / (sb || 1));
166
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
167
+ const invA = 255 - sa;
168
+ const r = br * sa + dr * invA >> 8;
169
+ const g = bg * sa + dg * invA >> 8;
170
+ const b = bb * sa + db * invA >> 8;
171
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
172
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
173
+ };
174
+ var linearBurnColor32 = (src, dst) => {
175
+ const sa = src >>> 24 & 255;
176
+ if (sa === 0) return dst;
177
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
178
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
179
+ const br = Math.max(0, dr + sr - 255);
180
+ const bg = Math.max(0, dg + sg - 255);
181
+ const bb = Math.max(0, db + sb - 255);
182
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
183
+ const invA = 255 - sa;
184
+ const r = br * sa + dr * invA >> 8;
185
+ const g = bg * sa + dg * invA >> 8;
186
+ const b = bb * sa + db * invA >> 8;
187
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
188
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
189
+ };
190
+ var darkerColor32 = (src, dst) => {
191
+ const sa = src >>> 24 & 255;
192
+ if (sa === 0) return dst;
193
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
194
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
195
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
196
+ const lumDst = dr * 77 + dg * 151 + db * 28;
197
+ let br, bg, bb;
198
+ if (lumSrc < lumDst) {
199
+ br = sr;
200
+ bg = sg;
201
+ bb = sb;
202
+ } else {
203
+ br = dr;
204
+ bg = dg;
205
+ bb = db;
206
+ }
207
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
208
+ const invA = 255 - sa;
209
+ const r = br * sa + dr * invA >> 8;
210
+ const g = bg * sa + dg * invA >> 8;
211
+ const b = bb * sa + db * invA >> 8;
212
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
213
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
214
+ };
215
+ var lightenColor32 = (src, dst) => {
216
+ const sa = src >>> 24 & 255;
217
+ if (sa === 0) return dst;
218
+ const br = Math.max(src & 255, dst & 255);
219
+ const bg = Math.max(src >> 8 & 255, dst >> 8 & 255);
220
+ const bb = Math.max(src >> 16 & 255, dst >> 16 & 255);
221
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
222
+ const dr = dst & 255;
223
+ const dg = dst >> 8 & 255;
224
+ const db = dst >> 16 & 255;
225
+ const invA = 255 - sa;
226
+ const r = br * sa + dr * invA >> 8;
227
+ const g = bg * sa + dg * invA >> 8;
228
+ const b = bb * sa + db * invA >> 8;
229
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
230
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
231
+ };
93
232
  var screenColor32 = (src, dst) => {
94
233
  const sa = src >>> 24 & 255;
95
234
  if (sa === 0) return dst;
@@ -105,6 +244,22 @@ var screenColor32 = (src, dst) => {
105
244
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
106
245
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
107
246
  };
247
+ var colorDodgeColor32 = (src, dst) => {
248
+ const sa = src >>> 24 & 255;
249
+ if (sa === 0) return dst;
250
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
251
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
252
+ const br = sr === 255 ? 255 : Math.min(255, (dr << 8) / (255 - sr));
253
+ const bg = sg === 255 ? 255 : Math.min(255, (dg << 8) / (255 - sg));
254
+ const bb = sb === 255 ? 255 : Math.min(255, (db << 8) / (255 - sb));
255
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
256
+ const invA = 255 - sa;
257
+ const r = br * sa + dr * invA >> 8;
258
+ const g = bg * sa + dg * invA >> 8;
259
+ const b = bb * sa + db * invA >> 8;
260
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
261
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
262
+ };
108
263
  var linearDodgeColor32 = (src, dst) => {
109
264
  const sa = src >>> 24 & 255;
110
265
  if (sa === 0) return dst;
@@ -120,13 +275,23 @@ var linearDodgeColor32 = (src, dst) => {
120
275
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
121
276
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
122
277
  };
123
- var multiplyColor32 = (src, dst) => {
278
+ var lighterColor32 = (src, dst) => {
124
279
  const sa = src >>> 24 & 255;
125
280
  if (sa === 0) return dst;
126
281
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
127
- const br = (src & 255) * dr >> 8;
128
- const bg = (src >> 8 & 255) * dg >> 8;
129
- const bb = (src >> 16 & 255) * db >> 8;
282
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
283
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
284
+ const lumDst = dr * 77 + dg * 151 + db * 28;
285
+ let br, bg, bb;
286
+ if (lumSrc > lumDst) {
287
+ br = sr;
288
+ bg = sg;
289
+ bb = sb;
290
+ } else {
291
+ br = dr;
292
+ bg = dg;
293
+ bb = db;
294
+ }
130
295
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
131
296
  const invA = 255 - sa;
132
297
  const r = br * sa + dr * invA >> 8;
@@ -135,13 +300,14 @@ var multiplyColor32 = (src, dst) => {
135
300
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
136
301
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
137
302
  };
138
- var differenceColor32 = (src, dst) => {
303
+ var overlayColor32 = (src, dst) => {
139
304
  const sa = src >>> 24 & 255;
140
305
  if (sa === 0) return dst;
306
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
141
307
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
142
- const br = Math.abs((src & 255) - dr);
143
- const bg = Math.abs((src >> 8 & 255) - dg);
144
- const bb = Math.abs((src >> 16 & 255) - db);
308
+ const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
309
+ const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
310
+ const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
145
311
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
146
312
  const invA = 255 - sa;
147
313
  const r = br * sa + dr * invA >> 8;
@@ -150,11 +316,27 @@ var differenceColor32 = (src, dst) => {
150
316
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
151
317
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
152
318
  };
153
- var hardLightColor32 = (src, dst) => {
319
+ var softLightColor32 = (src, dst) => {
154
320
  const sa = src >>> 24 & 255;
155
321
  if (sa === 0) return dst;
322
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
156
323
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
324
+ const br = (255 - dr) * (sr * dr >> 8) + dr * (255 - ((255 - sr) * (255 - dr) >> 8)) >> 8;
325
+ const bg = (255 - dg) * (sg * dg >> 8) + dg * (255 - ((255 - sg) * (255 - dg) >> 8)) >> 8;
326
+ const bb = (255 - db) * (sb * db >> 8) + db * (255 - ((255 - sb) * (255 - db) >> 8)) >> 8;
327
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
328
+ const invA = 255 - sa;
329
+ const r = br * sa + dr * invA >> 8;
330
+ const g = bg * sa + dg * invA >> 8;
331
+ const b = bb * sa + db * invA >> 8;
332
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
333
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
334
+ };
335
+ var hardLightColor32 = (src, dst) => {
336
+ const sa = src >>> 24 & 255;
337
+ if (sa === 0) return dst;
157
338
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
339
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
158
340
  const br = sr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
159
341
  const bg = sg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
160
342
  const bb = sb < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
@@ -166,14 +348,30 @@ var hardLightColor32 = (src, dst) => {
166
348
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
167
349
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
168
350
  };
169
- var colorBurnColor32 = (src, dst) => {
351
+ var vividLightColor32 = (src, dst) => {
170
352
  const sa = src >>> 24 & 255;
171
353
  if (sa === 0) return dst;
354
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
172
355
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
356
+ const br = sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - (255 - dr << 8) / (2 * sr)) : sr === 255 ? 255 : Math.min(255, (dr << 8) / (2 * (255 - sr)));
357
+ const bg = sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - (255 - dg << 8) / (2 * sg)) : sg === 255 ? 255 : Math.min(255, (dg << 8) / (2 * (255 - sg)));
358
+ const bb = sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - (255 - db << 8) / (2 * sb)) : sb === 255 ? 255 : Math.min(255, (db << 8) / (2 * (255 - sb)));
359
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
360
+ const invA = 255 - sa;
361
+ const r = br * sa + dr * invA >> 8;
362
+ const g = bg * sa + dg * invA >> 8;
363
+ const b = bb * sa + db * invA >> 8;
364
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
365
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
366
+ };
367
+ var linearLightColor32 = (src, dst) => {
368
+ const sa = src >>> 24 & 255;
369
+ if (sa === 0) return dst;
173
370
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
174
- const br = dr === 255 ? 255 : Math.max(0, 255 - (255 - dr << 8) / (sr || 1));
175
- const bg = dg === 255 ? 255 : Math.max(0, 255 - (255 - dg << 8) / (sg || 1));
176
- const bb = db === 255 ? 255 : Math.max(0, 255 - (255 - db << 8) / (sb || 1));
371
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
372
+ const br = Math.max(0, Math.min(255, dr + 2 * sr - 255));
373
+ const bg = Math.max(0, Math.min(255, dg + 2 * sg - 255));
374
+ const bb = Math.max(0, Math.min(255, db + 2 * sb - 255));
177
375
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
178
376
  const invA = 255 - sa;
179
377
  const r = br * sa + dr * invA >> 8;
@@ -182,14 +380,30 @@ var colorBurnColor32 = (src, dst) => {
182
380
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
183
381
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
184
382
  };
185
- var overlayColor32 = (src, dst) => {
383
+ var pinLightColor32 = (src, dst) => {
186
384
  const sa = src >>> 24 & 255;
187
385
  if (sa === 0) return dst;
386
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
188
387
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
388
+ const br = sr < 128 ? Math.min(dr, 2 * sr) : Math.max(dr, 2 * (sr - 128));
389
+ const bg = sg < 128 ? Math.min(dg, 2 * sg) : Math.max(dg, 2 * (sg - 128));
390
+ const bb = sb < 128 ? Math.min(db, 2 * sb) : Math.max(db, 2 * (sb - 128));
391
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
392
+ const invA = 255 - sa;
393
+ const r = br * sa + dr * invA >> 8;
394
+ const g = bg * sa + dg * invA >> 8;
395
+ const b = bb * sa + db * invA >> 8;
396
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
397
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
398
+ };
399
+ var hardMixColor32 = (src, dst) => {
400
+ const sa = src >>> 24 & 255;
401
+ if (sa === 0) return dst;
189
402
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
190
- const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
191
- const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
192
- const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
403
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
404
+ const br = (sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - (255 - dr << 8) / (2 * sr)) : sr === 255 ? 255 : Math.min(255, (dr << 8) / (2 * (255 - sr)))) < 128 ? 0 : 255;
405
+ const bg = (sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - (255 - dg << 8) / (2 * sg)) : sg === 255 ? 255 : Math.min(255, (dg << 8) / (2 * (255 - sg)))) < 128 ? 0 : 255;
406
+ const bb = (sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - (255 - db << 8) / (2 * sb)) : sb === 255 ? 255 : Math.min(255, (db << 8) / (2 * (255 - sb)))) < 128 ? 0 : 255;
193
407
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
194
408
  const invA = 255 - sa;
195
409
  const r = br * sa + dr * invA >> 8;
@@ -198,16 +412,147 @@ var overlayColor32 = (src, dst) => {
198
412
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
199
413
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
200
414
  };
201
- var COLOR_32_BLEND_MODES = {
202
- sourceOver: sourceOverColor32,
203
- screen: screenColor32,
204
- linearDodge: linearDodgeColor32,
205
- multiply: multiplyColor32,
206
- difference: differenceColor32,
207
- overlay: overlayColor32,
208
- hardLight: hardLightColor32,
209
- colorBurn: colorBurnColor32
415
+ var differenceColor32 = (src, dst) => {
416
+ const sa = src >>> 24 & 255;
417
+ if (sa === 0) return dst;
418
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
419
+ const br = Math.abs((src & 255) - dr);
420
+ const bg = Math.abs((src >> 8 & 255) - dg);
421
+ const bb = Math.abs((src >> 16 & 255) - db);
422
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
423
+ const invA = 255 - sa;
424
+ const r = br * sa + dr * invA >> 8;
425
+ const g = bg * sa + dg * invA >> 8;
426
+ const b = bb * sa + db * invA >> 8;
427
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
428
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
429
+ };
430
+ var exclusionColor32 = (src, dst) => {
431
+ const sa = src >>> 24 & 255;
432
+ if (sa === 0) return dst;
433
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
434
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
435
+ const br = dr + sr - (dr * sr >> 7);
436
+ const bg = dg + sg - (dg * sg >> 7);
437
+ const bb = db + sb - (db * sb >> 7);
438
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
439
+ const invA = 255 - sa;
440
+ const r = br * sa + dr * invA >> 8;
441
+ const g = bg * sa + dg * invA >> 8;
442
+ const b = bb * sa + db * invA >> 8;
443
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
444
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
210
445
  };
446
+ var subtractColor32 = (src, dst) => {
447
+ const sa = src >>> 24 & 255;
448
+ if (sa === 0) return dst;
449
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
450
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
451
+ const br = Math.max(0, dr - sr);
452
+ const bg = Math.max(0, dg - sg);
453
+ const bb = Math.max(0, db - sb);
454
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
455
+ const invA = 255 - sa;
456
+ const r = br * sa + dr * invA >> 8;
457
+ const g = bg * sa + dg * invA >> 8;
458
+ const b = bb * sa + db * invA >> 8;
459
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
460
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
461
+ };
462
+ var divideColor32 = (src, dst) => {
463
+ const sa = src >>> 24 & 255;
464
+ if (sa === 0) return dst;
465
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
466
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
467
+ const br = sr === 0 ? 255 : Math.min(255, (dr << 8) / sr);
468
+ const bg = sg === 0 ? 255 : Math.min(255, (dg << 8) / sg);
469
+ const bb = sb === 0 ? 255 : Math.min(255, (db << 8) / sb);
470
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
471
+ const invA = 255 - sa;
472
+ const r = br * sa + dr * invA >> 8;
473
+ const g = bg * sa + dg * invA >> 8;
474
+ const b = bb * sa + db * invA >> 8;
475
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
476
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
477
+ };
478
+ var BlendMode = /* @__PURE__ */ ((BlendMode2) => {
479
+ BlendMode2[BlendMode2["overwrite"] = 0] = "overwrite";
480
+ BlendMode2[BlendMode2["sourceOver"] = 1] = "sourceOver";
481
+ BlendMode2[BlendMode2["darken"] = 2] = "darken";
482
+ BlendMode2[BlendMode2["multiply"] = 3] = "multiply";
483
+ BlendMode2[BlendMode2["colorBurn"] = 4] = "colorBurn";
484
+ BlendMode2[BlendMode2["linearBurn"] = 5] = "linearBurn";
485
+ BlendMode2[BlendMode2["darkerColor"] = 6] = "darkerColor";
486
+ BlendMode2[BlendMode2["lighten"] = 7] = "lighten";
487
+ BlendMode2[BlendMode2["screen"] = 8] = "screen";
488
+ BlendMode2[BlendMode2["colorDodge"] = 9] = "colorDodge";
489
+ BlendMode2[BlendMode2["linearDodge"] = 10] = "linearDodge";
490
+ BlendMode2[BlendMode2["lighterColor"] = 11] = "lighterColor";
491
+ BlendMode2[BlendMode2["overlay"] = 12] = "overlay";
492
+ BlendMode2[BlendMode2["softLight"] = 13] = "softLight";
493
+ BlendMode2[BlendMode2["hardLight"] = 14] = "hardLight";
494
+ BlendMode2[BlendMode2["vividLight"] = 15] = "vividLight";
495
+ BlendMode2[BlendMode2["linearLight"] = 16] = "linearLight";
496
+ BlendMode2[BlendMode2["pinLight"] = 17] = "pinLight";
497
+ BlendMode2[BlendMode2["hardMix"] = 18] = "hardMix";
498
+ BlendMode2[BlendMode2["difference"] = 19] = "difference";
499
+ BlendMode2[BlendMode2["exclusion"] = 20] = "exclusion";
500
+ BlendMode2[BlendMode2["subtract"] = 21] = "subtract";
501
+ BlendMode2[BlendMode2["divide"] = 22] = "divide";
502
+ return BlendMode2;
503
+ })(BlendMode || {});
504
+ var BLENDER_REGISTRY = [
505
+ [0 /* overwrite */, overwriteColor32],
506
+ [1 /* sourceOver */, sourceOverColor32],
507
+ [2 /* darken */, darkenColor32],
508
+ [3 /* multiply */, multiplyColor32],
509
+ [4 /* colorBurn */, colorBurnColor32],
510
+ [5 /* linearBurn */, linearBurnColor32],
511
+ [6 /* darkerColor */, darkerColor32],
512
+ [7 /* lighten */, lightenColor32],
513
+ [8 /* screen */, screenColor32],
514
+ [9 /* colorDodge */, colorDodgeColor32],
515
+ [10 /* linearDodge */, linearDodgeColor32],
516
+ [11 /* lighterColor */, lighterColor32],
517
+ [12 /* overlay */, overlayColor32],
518
+ [13 /* softLight */, softLightColor32],
519
+ [14 /* hardLight */, hardLightColor32],
520
+ [15 /* vividLight */, vividLightColor32],
521
+ [16 /* linearLight */, linearLightColor32],
522
+ [17 /* pinLight */, pinLightColor32],
523
+ [18 /* hardMix */, hardMixColor32],
524
+ [19 /* difference */, differenceColor32],
525
+ [20 /* exclusion */, exclusionColor32],
526
+ [21 /* subtract */, subtractColor32],
527
+ [22 /* divide */, divideColor32]
528
+ ];
529
+ var COLOR_32_BLEND_MODES = [];
530
+ for (const [index, blend] of BLENDER_REGISTRY) {
531
+ COLOR_32_BLEND_MODES[index] = blend;
532
+ }
533
+ var COLOR_32_BLEND_TO_INDEX = new Map(
534
+ BLENDER_REGISTRY.map((entry, index) => {
535
+ return [
536
+ entry[1],
537
+ index
538
+ ];
539
+ })
540
+ );
541
+ var INDEX_TO_COLOR_32_BLEND = new Map(
542
+ BLENDER_REGISTRY.map((entry, index) => {
543
+ return [
544
+ index,
545
+ entry[1]
546
+ ];
547
+ })
548
+ );
549
+
550
+ // src/_types.ts
551
+ var MaskType = /* @__PURE__ */ ((MaskType2) => {
552
+ MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
553
+ MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
554
+ return MaskType2;
555
+ })(MaskType || {});
211
556
 
212
557
  // src/color.ts
213
558
  function packColor(r, g, b, a) {
@@ -272,20 +617,8 @@ function color32ToCssRGBA(color) {
272
617
  return `rgba(${r},${g},${b},${alpha})`;
273
618
  }
274
619
 
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 }) {
280
- return {
281
- data: data.slice(),
282
- width,
283
- height
284
- };
285
- }
286
-
287
- // src/ImageData/extractImageData.ts
288
- function extractImageData(imageData, _x, _y, _w, _h) {
620
+ // src/ImageData/extractImageDataPixels.ts
621
+ function extractImageDataPixels(imageData, _x, _y, _w, _h) {
289
622
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
290
623
  const { width: srcW, height: srcH, data: src } = imageData;
291
624
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
@@ -307,6 +640,487 @@ function extractImageData(imageData, _x, _y, _w, _h) {
307
640
  return out;
308
641
  }
309
642
 
643
+ // src/Mask/extractMask.ts
644
+ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
645
+ let finalX;
646
+ let finalY;
647
+ let finalW;
648
+ let finalH;
649
+ if (typeof xOrRect === "object") {
650
+ finalX = xOrRect.x;
651
+ finalY = xOrRect.y;
652
+ finalW = xOrRect.w;
653
+ finalH = xOrRect.h;
654
+ } else {
655
+ finalX = xOrRect;
656
+ finalY = y;
657
+ finalW = w;
658
+ finalH = h;
659
+ }
660
+ const out = new Uint8Array(finalW * finalH);
661
+ const srcH = mask.length / maskWidth;
662
+ for (let row = 0; row < finalH; row++) {
663
+ const currentSrcY = finalY + row;
664
+ if (currentSrcY < 0 || currentSrcY >= srcH) {
665
+ continue;
666
+ }
667
+ const start = Math.max(0, finalX);
668
+ const end = Math.min(maskWidth, finalX + finalW);
669
+ if (start < end) {
670
+ const srcOffset = currentSrcY * maskWidth + start;
671
+ const dstOffset = row * finalW + (start - finalX);
672
+ const count = end - start;
673
+ out.set(
674
+ mask.subarray(srcOffset, srcOffset + count),
675
+ dstOffset
676
+ );
677
+ }
678
+ }
679
+ return out;
680
+ }
681
+
682
+ // src/Rect/trimRectBounds.ts
683
+ function trimRectBounds(target, bounds) {
684
+ const originalX = target.x;
685
+ const originalY = target.y;
686
+ const originalW = target.w;
687
+ const intersectedX = Math.max(target.x, bounds.x);
688
+ const intersectedY = Math.max(target.y, bounds.y);
689
+ const intersectedMaxX = Math.min(
690
+ target.x + target.w,
691
+ bounds.x + bounds.w
692
+ );
693
+ const intersectedMaxY = Math.min(
694
+ target.y + target.h,
695
+ bounds.y + bounds.h
696
+ );
697
+ if (intersectedMaxX <= intersectedX || intersectedMaxY <= intersectedY) {
698
+ target.w = 0;
699
+ target.h = 0;
700
+ if ("mask" in target && target.mask) {
701
+ target.mask = new Uint8Array(0);
702
+ }
703
+ return;
704
+ }
705
+ const intersectedW = intersectedMaxX - intersectedX;
706
+ const intersectedH = intersectedMaxY - intersectedY;
707
+ const offsetX = intersectedX - originalX;
708
+ const offsetY = intersectedY - originalY;
709
+ target.x = intersectedX;
710
+ target.y = intersectedY;
711
+ target.w = intersectedW;
712
+ target.h = intersectedH;
713
+ if ("mask" in target && target.mask) {
714
+ const currentMask = extractMask(
715
+ target.mask,
716
+ originalW,
717
+ offsetX,
718
+ offsetY,
719
+ intersectedW,
720
+ intersectedH
721
+ );
722
+ let minX = intersectedW;
723
+ let maxX = -1;
724
+ let minY = intersectedH;
725
+ let maxY = -1;
726
+ for (let y = 0; y < intersectedH; y++) {
727
+ for (let x = 0; x < intersectedW; x++) {
728
+ if (currentMask[y * intersectedW + x] !== 0) {
729
+ if (x < minX) minX = x;
730
+ if (x > maxX) maxX = x;
731
+ if (y < minY) minY = y;
732
+ if (y > maxY) maxY = y;
733
+ }
734
+ }
735
+ }
736
+ if (maxX === -1) {
737
+ target.w = 0;
738
+ target.h = 0;
739
+ target.mask = new Uint8Array(0);
740
+ return;
741
+ }
742
+ const finalW = maxX - minX + 1;
743
+ const finalH = maxY - minY + 1;
744
+ if (finalW !== intersectedW || finalH !== intersectedH) {
745
+ target.mask = extractMask(
746
+ currentMask,
747
+ intersectedW,
748
+ minX,
749
+ minY,
750
+ finalW,
751
+ finalH
752
+ );
753
+ target.x += minX;
754
+ target.y += minY;
755
+ target.w = finalW;
756
+ target.h = finalH;
757
+ } else {
758
+ target.mask = currentMask;
759
+ }
760
+ }
761
+ }
762
+
763
+ // src/Algorithm/floodFillSelection.ts
764
+ function floodFillSelection(img, startX, startY, {
765
+ contiguous = true,
766
+ tolerance = 0,
767
+ bounds
768
+ } = {}) {
769
+ let imageData;
770
+ let data32;
771
+ if ("data32" in img) {
772
+ data32 = img.data32;
773
+ imageData = img.imageData;
774
+ } else {
775
+ data32 = new Uint32Array(
776
+ img.data.buffer,
777
+ img.data.byteOffset,
778
+ img.data.byteLength >> 2
779
+ );
780
+ imageData = img;
781
+ }
782
+ const {
783
+ width,
784
+ height
785
+ } = img;
786
+ const limit = bounds || {
787
+ x: 0,
788
+ y: 0,
789
+ w: width,
790
+ h: height
791
+ };
792
+ const xMin = Math.max(0, limit.x);
793
+ const xMax = Math.min(width - 1, limit.x + limit.w - 1);
794
+ const yMin = Math.max(0, limit.y);
795
+ const yMax = Math.min(height - 1, limit.y + limit.h - 1);
796
+ if (startX < xMin || startX > xMax || startY < yMin || startY > yMax) {
797
+ return null;
798
+ }
799
+ const baseColor = data32[startY * width + startX];
800
+ let matchCount = 0;
801
+ const matchX = new Uint16Array(width * height);
802
+ const matchY = new Uint16Array(width * height);
803
+ let minX = startX;
804
+ let maxX = startX;
805
+ let minY = startY;
806
+ let maxY = startY;
807
+ if (contiguous) {
808
+ const visited = new Uint8Array(width * height);
809
+ const stack = new Uint32Array(width * height);
810
+ let stackPtr = 0;
811
+ stack[stackPtr++] = startY << 16 | startX;
812
+ visited[startY * width + startX] = 1;
813
+ while (stackPtr > 0) {
814
+ const val = stack[--stackPtr];
815
+ const x = val & 65535;
816
+ const y = val >>> 16;
817
+ matchX[matchCount] = x;
818
+ matchY[matchCount] = y;
819
+ matchCount++;
820
+ if (x < minX) minX = x;
821
+ if (x > maxX) maxX = x;
822
+ if (y < minY) minY = y;
823
+ if (y > maxY) maxY = y;
824
+ if (x + 1 <= xMax) {
825
+ const idx = y * width + (x + 1);
826
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
827
+ visited[idx] = 1;
828
+ stack[stackPtr++] = y << 16 | x + 1;
829
+ }
830
+ }
831
+ if (x - 1 >= xMin) {
832
+ const idx = y * width + (x - 1);
833
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
834
+ visited[idx] = 1;
835
+ stack[stackPtr++] = y << 16 | x - 1;
836
+ }
837
+ }
838
+ if (y + 1 <= yMax) {
839
+ const idx = (y + 1) * width + x;
840
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
841
+ visited[idx] = 1;
842
+ stack[stackPtr++] = y + 1 << 16 | x;
843
+ }
844
+ }
845
+ if (y - 1 >= yMin) {
846
+ const idx = (y - 1) * width + x;
847
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
848
+ visited[idx] = 1;
849
+ stack[stackPtr++] = y - 1 << 16 | x;
850
+ }
851
+ }
852
+ }
853
+ } else {
854
+ for (let y = yMin; y <= yMax; y++) {
855
+ for (let x = xMin; x <= xMax; x++) {
856
+ const color = data32[y * width + x];
857
+ if (colorDistance(color, baseColor) <= tolerance) {
858
+ matchX[matchCount] = x;
859
+ matchY[matchCount] = y;
860
+ matchCount++;
861
+ if (x < minX) minX = x;
862
+ if (x > maxX) maxX = x;
863
+ if (y < minY) minY = y;
864
+ if (y > maxY) maxY = y;
865
+ }
866
+ }
867
+ }
868
+ }
869
+ if (matchCount === 0) {
870
+ return null;
871
+ }
872
+ const selectionRect = {
873
+ x: minX,
874
+ y: minY,
875
+ w: maxX - minX + 1,
876
+ h: maxY - minY + 1,
877
+ mask: new Uint8Array((maxX - minX + 1) * (maxY - minY + 1)),
878
+ maskType: 1 /* BINARY */
879
+ };
880
+ const sw = selectionRect.w;
881
+ const sh = selectionRect.h;
882
+ const finalMask = selectionRect.mask;
883
+ for (let i = 0; i < matchCount; i++) {
884
+ const mx = matchX[i] - selectionRect.x;
885
+ const my = matchY[i] - selectionRect.y;
886
+ if (mx >= 0 && mx < sw && my >= 0 && my < sh) {
887
+ finalMask[my * sw + mx] = 1;
888
+ }
889
+ }
890
+ trimRectBounds(
891
+ selectionRect,
892
+ { x: 0, y: 0, w: width, h: height }
893
+ );
894
+ const extracted = extractImageDataPixels(
895
+ imageData,
896
+ selectionRect.x,
897
+ selectionRect.y,
898
+ selectionRect.w,
899
+ selectionRect.h
900
+ );
901
+ return {
902
+ startX,
903
+ startY,
904
+ selectionRect,
905
+ pixels: extracted
906
+ };
907
+ }
908
+
909
+ // src/Canvas/_constants.ts
910
+ var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
911
+ var CANVAS_CTX_FAILED = "Failed to create Canvas context";
912
+
913
+ // src/Canvas/PixelCanvas.ts
914
+ function makePixelCanvas(canvas) {
915
+ const ctx = canvas.getContext("2d");
916
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
917
+ ctx.imageSmoothingEnabled = false;
918
+ return {
919
+ canvas,
920
+ ctx,
921
+ resize(w, h) {
922
+ canvas.width = w;
923
+ canvas.height = h;
924
+ ctx.imageSmoothingEnabled = false;
925
+ }
926
+ };
927
+ }
928
+
929
+ // src/Canvas/ReusableCanvas.ts
930
+ function makeReusableCanvas() {
931
+ let canvas = null;
932
+ let ctx = null;
933
+ function get2(width, height) {
934
+ if (canvas === null) {
935
+ canvas = document.createElement("canvas");
936
+ ctx = canvas.getContext("2d");
937
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
938
+ }
939
+ if (canvas.width !== width || canvas.height !== height) {
940
+ canvas.width = width;
941
+ canvas.height = height;
942
+ ctx.imageSmoothingEnabled = false;
943
+ } else {
944
+ ctx.clearRect(0, 0, width, height);
945
+ }
946
+ return { canvas, ctx };
947
+ }
948
+ get2.reset = () => {
949
+ canvas = null;
950
+ ctx = null;
951
+ };
952
+ return get2;
953
+ }
954
+
955
+ // src/ImageData/imgBlobToImageData.ts
956
+ async function imgBlobToImageData(blob) {
957
+ let bitmap = null;
958
+ try {
959
+ bitmap = await createImageBitmap(blob);
960
+ const canvas = new OffscreenCanvas(
961
+ bitmap.width,
962
+ bitmap.height
963
+ );
964
+ const ctx = canvas.getContext("2d");
965
+ if (!ctx) {
966
+ throw new Error("Failed to get 2D context");
967
+ }
968
+ ctx.drawImage(bitmap, 0, 0);
969
+ return ctx.getImageData(
970
+ 0,
971
+ 0,
972
+ bitmap.width,
973
+ bitmap.height
974
+ );
975
+ } finally {
976
+ bitmap?.close();
977
+ }
978
+ }
979
+
980
+ // src/Clipboard/getImageDataFromClipboard.ts
981
+ async function getImageDataFromClipboard(clipboardEvent) {
982
+ const items = clipboardEvent?.clipboardData?.items;
983
+ if (!items?.length) return null;
984
+ for (let i = 0; i < items.length; i++) {
985
+ const item = items[i];
986
+ if (item.type.startsWith("image/")) {
987
+ const blob = item.getAsFile();
988
+ if (!blob) {
989
+ continue;
990
+ }
991
+ return imgBlobToImageData(blob);
992
+ }
993
+ }
994
+ return null;
995
+ }
996
+
997
+ // src/ImageData/imageDataToImgBlob.ts
998
+ async function imageDataToImgBlob(imageData) {
999
+ const canvas = new OffscreenCanvas(imageData.width, imageData.height);
1000
+ const ctx = canvas.getContext("2d");
1001
+ if (!ctx) throw new Error("could not create 2d context");
1002
+ ctx.putImageData(imageData, 0, 0);
1003
+ return canvas.convertToBlob({
1004
+ type: "image/png"
1005
+ });
1006
+ }
1007
+
1008
+ // src/Clipboard/writeImgBlobToClipboard.ts
1009
+ async function writeImgBlobToClipboard(blob) {
1010
+ const item = new ClipboardItem({
1011
+ "image/png": blob
1012
+ });
1013
+ await navigator.clipboard.write([item]);
1014
+ }
1015
+
1016
+ // src/Clipboard/writeImageDataToClipboard.ts
1017
+ async function writeImageDataToClipboard(imageData) {
1018
+ const blob = await imageDataToImgBlob(imageData);
1019
+ return writeImgBlobToClipboard(blob);
1020
+ }
1021
+
1022
+ // src/ImageData/copyImageData.ts
1023
+ function copyImageData({ data, width, height }) {
1024
+ return new ImageData(data.slice(), width, height);
1025
+ }
1026
+ function copyImageDataLike({ data, width, height }) {
1027
+ return {
1028
+ data: data.slice(),
1029
+ width,
1030
+ height
1031
+ };
1032
+ }
1033
+
1034
+ // src/PixelData/pixelDataToAlphaMask.ts
1035
+ function pixelDataToAlphaMask(pixelData) {
1036
+ const {
1037
+ data32,
1038
+ width,
1039
+ height
1040
+ } = pixelData;
1041
+ const len = data32.length;
1042
+ const mask = new Uint8Array(width * height);
1043
+ for (let i = 0; i < len; i++) {
1044
+ const val = data32[i];
1045
+ mask[i] = val >>> 24 & 255;
1046
+ }
1047
+ return mask;
1048
+ }
1049
+
1050
+ // src/ImageData/imageDataToAlphaMask.ts
1051
+ function imageDataToAlphaMask(imageData) {
1052
+ const {
1053
+ width,
1054
+ height,
1055
+ data
1056
+ } = imageData;
1057
+ const data32 = new Uint32Array(
1058
+ data.buffer,
1059
+ data.byteOffset,
1060
+ data.byteLength >> 2
1061
+ );
1062
+ const len = data32.length;
1063
+ const mask = new Uint8Array(width * height);
1064
+ for (let i = 0; i < len; i++) {
1065
+ const val = data32[i];
1066
+ mask[i] = val >>> 24 & 255;
1067
+ }
1068
+ return mask;
1069
+ }
1070
+
1071
+ // src/ImageData/imageDataToDataUrl.ts
1072
+ var get = makeReusableCanvas();
1073
+ function imageDataToDataUrl(imageData) {
1074
+ const { canvas, ctx } = get(imageData.width, imageData.height);
1075
+ ctx.putImageData(imageData, 0, 0);
1076
+ return canvas.toDataURL();
1077
+ }
1078
+ imageDataToDataUrl.reset = get.reset;
1079
+
1080
+ // src/ImageData/invertImageData.ts
1081
+ function invertImageData(imageData) {
1082
+ const data = imageData.data;
1083
+ let length = data.length;
1084
+ for (let i = 0; i < length; i += 4) {
1085
+ data[i] = 255 - data[i];
1086
+ data[i + 1] = 255 - data[i + 1];
1087
+ data[i + 2] = 255 - data[i + 2];
1088
+ }
1089
+ return imageData;
1090
+ }
1091
+
1092
+ // src/ImageData/resizeImageData.ts
1093
+ function resizeImageData(current, newWidth, newHeight, offsetX = 0, offsetY = 0) {
1094
+ const result = new ImageData(newWidth, newHeight);
1095
+ const {
1096
+ width: oldW,
1097
+ height: oldH,
1098
+ data: oldData
1099
+ } = current;
1100
+ const newData = result.data;
1101
+ const x0 = Math.max(0, offsetX);
1102
+ const y0 = Math.max(0, offsetY);
1103
+ const x1 = Math.min(newWidth, offsetX + oldW);
1104
+ const y1 = Math.min(newHeight, offsetY + oldH);
1105
+ if (x1 <= x0 || y1 <= y0) {
1106
+ return result;
1107
+ }
1108
+ const rowCount = y1 - y0;
1109
+ const rowLen = (x1 - x0) * 4;
1110
+ for (let row = 0; row < rowCount; row++) {
1111
+ const dstY = y0 + row;
1112
+ const srcY = dstY - offsetY;
1113
+ const srcX = x0 - offsetX;
1114
+ const dstStart = (dstY * newWidth + x0) * 4;
1115
+ const srcStart = (srcY * oldW + srcX) * 4;
1116
+ newData.set(
1117
+ oldData.subarray(srcStart, srcStart + rowLen),
1118
+ dstStart
1119
+ );
1120
+ }
1121
+ return result;
1122
+ }
1123
+
310
1124
  // src/ImageData/serialization.ts
311
1125
  function base64EncodeArrayBuffer(buffer) {
312
1126
  const binary = String.fromCharCode(...new Uint8Array(buffer));
@@ -347,8 +1161,8 @@ function deserializeNullableImageData(serialized) {
347
1161
  return deserializeImageData(serialized);
348
1162
  }
349
1163
 
350
- // src/ImageData/writeImageData.ts
351
- function writeImageData(imageData, data, _x, _y, _w, _h) {
1164
+ // src/ImageData/writeImageDataPixels.ts
1165
+ function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
352
1166
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
353
1167
  const { width: dstW, height: dstH, data: dst } = imageData;
354
1168
  const x0 = Math.max(0, x);
@@ -368,6 +1182,90 @@ function writeImageData(imageData, data, _x, _y, _w, _h) {
368
1182
  }
369
1183
  }
370
1184
 
1185
+ // src/Input/fileInputChangeToImageData.ts
1186
+ async function fileInputChangeToImageData(event) {
1187
+ const target = event.target;
1188
+ const file = target.files?.[0];
1189
+ if (!file) return null;
1190
+ return await fileToImageData(file);
1191
+ }
1192
+
1193
+ // src/Input/fileToImageData.ts
1194
+ var UnsupportedFormatError = class extends Error {
1195
+ constructor(mimeType) {
1196
+ super(`File type ${mimeType} is not a supported image format.`);
1197
+ this.name = "UnsupportedFormatError";
1198
+ }
1199
+ };
1200
+ async function fileToImageData(file) {
1201
+ if (!file) return null;
1202
+ if (!file.type.startsWith("image/")) {
1203
+ throw new UnsupportedFormatError(file.type);
1204
+ }
1205
+ let bitmap = null;
1206
+ try {
1207
+ bitmap = await createImageBitmap(file);
1208
+ const canvas = new OffscreenCanvas(
1209
+ bitmap.width,
1210
+ bitmap.height
1211
+ );
1212
+ const ctx = canvas.getContext("2d");
1213
+ if (!ctx) throw new Error(OFFSCREEN_CANVAS_CTX_FAILED);
1214
+ ctx.drawImage(
1215
+ bitmap,
1216
+ 0,
1217
+ 0
1218
+ );
1219
+ return ctx.getImageData(
1220
+ 0,
1221
+ 0,
1222
+ bitmap.width,
1223
+ bitmap.height
1224
+ );
1225
+ } finally {
1226
+ bitmap?.close();
1227
+ }
1228
+ }
1229
+
1230
+ // src/Input/getSupportedRasterFormats.ts
1231
+ var formatsPromise = null;
1232
+ var defaultRasterMimes = [
1233
+ "image/png",
1234
+ "image/jpeg",
1235
+ "image/webp",
1236
+ "image/avif",
1237
+ "image/gif",
1238
+ "image/bmp"
1239
+ ];
1240
+ async function getSupportedPixelFormats(rasterMimes = defaultRasterMimes) {
1241
+ if (formatsPromise) {
1242
+ return formatsPromise;
1243
+ }
1244
+ const probeCanvas = async () => {
1245
+ const canvas = new OffscreenCanvas(1, 1);
1246
+ const results = await Promise.all(
1247
+ rasterMimes.map(async (mime) => {
1248
+ try {
1249
+ const blob = await canvas.convertToBlob({
1250
+ type: mime
1251
+ });
1252
+ return blob.type === mime ? mime : null;
1253
+ } catch {
1254
+ return null;
1255
+ }
1256
+ })
1257
+ );
1258
+ return results.filter((type) => {
1259
+ return type !== null;
1260
+ });
1261
+ };
1262
+ formatsPromise = probeCanvas().catch((error) => {
1263
+ formatsPromise = null;
1264
+ throw error;
1265
+ });
1266
+ return formatsPromise;
1267
+ }
1268
+
371
1269
  // src/Mask/copyMask.ts
372
1270
  function copyMask(src) {
373
1271
  return src.slice();
@@ -453,6 +1351,23 @@ function mergeMasks(dst, dstWidth, src, opts) {
453
1351
  }
454
1352
  }
455
1353
 
1354
+ // src/PixelData.ts
1355
+ var PixelData = class {
1356
+ constructor(imageData) {
1357
+ this.imageData = imageData;
1358
+ this.width = imageData.width;
1359
+ this.height = imageData.height;
1360
+ this.data32 = new Uint32Array(
1361
+ imageData.data.buffer,
1362
+ imageData.data.byteOffset,
1363
+ imageData.data.byteLength >> 2
1364
+ );
1365
+ }
1366
+ data32;
1367
+ width;
1368
+ height;
1369
+ };
1370
+
456
1371
  // src/PixelData/applyMaskToPixelData.ts
457
1372
  function applyMaskToPixelData(dst, mask, opts) {
458
1373
  const {
@@ -784,17 +1699,27 @@ function blendPixelData(dst, src, opts) {
784
1699
  }
785
1700
 
786
1701
  // 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;
1702
+ function fillPixelData(dst, color, _x, _y, _w, _h) {
1703
+ let x;
1704
+ let y;
1705
+ let w;
1706
+ let h;
1707
+ if (typeof _x === "object") {
1708
+ x = _x.x ?? 0;
1709
+ y = _x.y ?? 0;
1710
+ w = _x.w ?? dst.width;
1711
+ h = _x.h ?? dst.height;
1712
+ } else if (typeof _x === "number") {
1713
+ x = _x;
1714
+ y = _y;
1715
+ w = _w;
1716
+ h = _h;
1717
+ } else {
1718
+ x = 0;
1719
+ y = 0;
1720
+ w = dst.width;
1721
+ h = dst.height;
1722
+ }
798
1723
  if (x < 0) {
799
1724
  w += x;
800
1725
  x = 0;
@@ -825,10 +1750,25 @@ function fillPixelData(dst, color, rect) {
825
1750
  function clearPixelData(dst, rect) {
826
1751
  fillPixelData(dst, 0, rect);
827
1752
  }
1753
+
1754
+ // src/PixelData/invertPixelData.ts
1755
+ function invertPixelData(pixelData) {
1756
+ const data32 = pixelData.data32;
1757
+ const len = data32.length;
1758
+ for (let i = 0; i < len; i++) {
1759
+ data32[i] = data32[i] ^ 16777215;
1760
+ }
1761
+ return pixelData;
1762
+ }
828
1763
  // Annotate the CommonJS export names for ESM import in node:
829
1764
  0 && (module.exports = {
1765
+ BlendMode,
830
1766
  COLOR_32_BLEND_MODES,
1767
+ COLOR_32_BLEND_TO_INDEX,
1768
+ INDEX_TO_COLOR_32_BLEND,
831
1769
  MaskType,
1770
+ PixelData,
1771
+ UnsupportedFormatError,
832
1772
  applyMaskToPixelData,
833
1773
  base64DecodeArrayBuffer,
834
1774
  base64EncodeArrayBuffer,
@@ -839,36 +1779,70 @@ function clearPixelData(dst, rect) {
839
1779
  color32ToHex,
840
1780
  colorBurnColor32,
841
1781
  colorDistance,
1782
+ colorDodgeColor32,
842
1783
  copyImageData,
843
1784
  copyImageDataLike,
844
1785
  copyMask,
1786
+ darkenColor32,
1787
+ darkerColor32,
845
1788
  deserializeImageData,
846
1789
  deserializeNullableImageData,
847
1790
  deserializeRawImageData,
848
1791
  differenceColor32,
849
- extractImageData,
1792
+ divideColor32,
1793
+ exclusionColor32,
1794
+ extractImageDataPixels,
1795
+ extractMask,
1796
+ fileInputChangeToImageData,
1797
+ fileToImageData,
850
1798
  fillPixelData,
1799
+ floodFillSelection,
1800
+ getImageDataFromClipboard,
1801
+ getSupportedPixelFormats,
851
1802
  hardLightColor32,
1803
+ hardMixColor32,
1804
+ imageDataToAlphaMask,
1805
+ imageDataToDataUrl,
1806
+ imageDataToImgBlob,
1807
+ imgBlobToImageData,
852
1808
  invertAlphaMask,
853
1809
  invertBinaryMask,
1810
+ invertImageData,
1811
+ invertPixelData,
854
1812
  lerpColor32,
855
1813
  lerpColor32Fast,
1814
+ lightenColor32,
1815
+ lighterColor32,
1816
+ linearBurnColor32,
856
1817
  linearDodgeColor32,
1818
+ linearLightColor32,
1819
+ makePixelCanvas,
1820
+ makeReusableCanvas,
857
1821
  mergeMasks,
858
1822
  multiplyColor32,
859
1823
  overlayColor32,
1824
+ overwriteColor32,
860
1825
  packColor,
861
1826
  packRGBA,
1827
+ pinLightColor32,
1828
+ pixelDataToAlphaMask,
1829
+ resizeImageData,
862
1830
  screenColor32,
863
1831
  serializeImageData,
864
1832
  serializeNullableImageData,
1833
+ softLightColor32,
865
1834
  sourceOverColor32,
1835
+ subtractColor32,
1836
+ trimRectBounds,
866
1837
  unpackAlpha,
867
1838
  unpackBlue,
868
1839
  unpackColor,
869
1840
  unpackColorTo,
870
1841
  unpackGreen,
871
1842
  unpackRed,
872
- writeImageData
1843
+ vividLightColor32,
1844
+ writeImageDataPixels,
1845
+ writeImageDataToClipboard,
1846
+ writeImgBlobToClipboard
873
1847
  });
874
1848
  //# sourceMappingURL=index.dev.cjs.map