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
@@ -1,11 +1,5 @@
1
- // src/_types.ts
2
- var MaskType = /* @__PURE__ */ ((MaskType2) => {
3
- MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
4
- MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
5
- return MaskType2;
6
- })(MaskType || {});
7
-
8
1
  // src/blend-modes.ts
2
+ var overwriteColor32 = (src, dst) => src;
9
3
  var sourceOverColor32 = (src, dst) => {
10
4
  const a = src >>> 24 & 255;
11
5
  if (a === 255) return src;
@@ -22,6 +16,112 @@ var sourceOverColor32 = (src, dst) => {
22
16
  const outA = a + ((dst >>> 24 & 255) * invA >> 8);
23
17
  return (outA << 24 | outRB | outG) >>> 0;
24
18
  };
19
+ var darkenColor32 = (src, dst) => {
20
+ const sa = src >>> 24 & 255;
21
+ if (sa === 0) return dst;
22
+ const br = Math.min(src & 255, dst & 255);
23
+ const bg = Math.min(src >> 8 & 255, dst >> 8 & 255);
24
+ const bb = Math.min(src >> 16 & 255, dst >> 16 & 255);
25
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
26
+ const dr = dst & 255;
27
+ const dg = dst >> 8 & 255;
28
+ const db = dst >> 16 & 255;
29
+ const invA = 255 - sa;
30
+ const r = br * sa + dr * invA >> 8;
31
+ const g = bg * sa + dg * invA >> 8;
32
+ const b = bb * sa + db * invA >> 8;
33
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
34
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
35
+ };
36
+ var multiplyColor32 = (src, dst) => {
37
+ const sa = src >>> 24 & 255;
38
+ if (sa === 0) return dst;
39
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
40
+ const br = (src & 255) * dr + 128 >> 8;
41
+ const bg = (src >> 8 & 255) * dg >> 8;
42
+ const bb = (src >> 16 & 255) * db >> 8;
43
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
44
+ const invA = 255 - sa;
45
+ const r = br * sa + dr * invA >> 8;
46
+ const g = bg * sa + dg * invA >> 8;
47
+ const b = bb * sa + db * invA >> 8;
48
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
49
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
50
+ };
51
+ var colorBurnColor32 = (src, dst) => {
52
+ const sa = src >>> 24 & 255;
53
+ if (sa === 0) return dst;
54
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
55
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
56
+ const br = dr === 255 ? 255 : Math.max(0, 255 - (255 - dr << 8) / (sr || 1));
57
+ const bg = dg === 255 ? 255 : Math.max(0, 255 - (255 - dg << 8) / (sg || 1));
58
+ const bb = db === 255 ? 255 : Math.max(0, 255 - (255 - db << 8) / (sb || 1));
59
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
60
+ const invA = 255 - sa;
61
+ const r = br * sa + dr * invA >> 8;
62
+ const g = bg * sa + dg * invA >> 8;
63
+ const b = bb * sa + db * invA >> 8;
64
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
65
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
66
+ };
67
+ var linearBurnColor32 = (src, dst) => {
68
+ const sa = src >>> 24 & 255;
69
+ if (sa === 0) return dst;
70
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
71
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
72
+ const br = Math.max(0, dr + sr - 255);
73
+ const bg = Math.max(0, dg + sg - 255);
74
+ const bb = Math.max(0, db + sb - 255);
75
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
76
+ const invA = 255 - sa;
77
+ const r = br * sa + dr * invA >> 8;
78
+ const g = bg * sa + dg * invA >> 8;
79
+ const b = bb * sa + db * invA >> 8;
80
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
81
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
82
+ };
83
+ var darkerColor32 = (src, dst) => {
84
+ const sa = src >>> 24 & 255;
85
+ if (sa === 0) return dst;
86
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
87
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
88
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
89
+ const lumDst = dr * 77 + dg * 151 + db * 28;
90
+ let br, bg, bb;
91
+ if (lumSrc < lumDst) {
92
+ br = sr;
93
+ bg = sg;
94
+ bb = sb;
95
+ } else {
96
+ br = dr;
97
+ bg = dg;
98
+ bb = db;
99
+ }
100
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
101
+ const invA = 255 - sa;
102
+ const r = br * sa + dr * invA >> 8;
103
+ const g = bg * sa + dg * invA >> 8;
104
+ const b = bb * sa + db * invA >> 8;
105
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
106
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
107
+ };
108
+ var lightenColor32 = (src, dst) => {
109
+ const sa = src >>> 24 & 255;
110
+ if (sa === 0) return dst;
111
+ const br = Math.max(src & 255, dst & 255);
112
+ const bg = Math.max(src >> 8 & 255, dst >> 8 & 255);
113
+ const bb = Math.max(src >> 16 & 255, dst >> 16 & 255);
114
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
115
+ const dr = dst & 255;
116
+ const dg = dst >> 8 & 255;
117
+ const db = dst >> 16 & 255;
118
+ const invA = 255 - sa;
119
+ const r = br * sa + dr * invA >> 8;
120
+ const g = bg * sa + dg * invA >> 8;
121
+ const b = bb * sa + db * invA >> 8;
122
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
123
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
124
+ };
25
125
  var screenColor32 = (src, dst) => {
26
126
  const sa = src >>> 24 & 255;
27
127
  if (sa === 0) return dst;
@@ -37,6 +137,22 @@ var screenColor32 = (src, dst) => {
37
137
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
38
138
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
39
139
  };
140
+ var colorDodgeColor32 = (src, dst) => {
141
+ const sa = src >>> 24 & 255;
142
+ if (sa === 0) return dst;
143
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
144
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
145
+ const br = sr === 255 ? 255 : Math.min(255, (dr << 8) / (255 - sr));
146
+ const bg = sg === 255 ? 255 : Math.min(255, (dg << 8) / (255 - sg));
147
+ const bb = sb === 255 ? 255 : Math.min(255, (db << 8) / (255 - sb));
148
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
149
+ const invA = 255 - sa;
150
+ const r = br * sa + dr * invA >> 8;
151
+ const g = bg * sa + dg * invA >> 8;
152
+ const b = bb * sa + db * invA >> 8;
153
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
154
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
155
+ };
40
156
  var linearDodgeColor32 = (src, dst) => {
41
157
  const sa = src >>> 24 & 255;
42
158
  if (sa === 0) return dst;
@@ -52,13 +168,23 @@ var linearDodgeColor32 = (src, dst) => {
52
168
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
53
169
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
54
170
  };
55
- var multiplyColor32 = (src, dst) => {
171
+ var lighterColor32 = (src, dst) => {
56
172
  const sa = src >>> 24 & 255;
57
173
  if (sa === 0) return dst;
58
174
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
59
- const br = (src & 255) * dr >> 8;
60
- const bg = (src >> 8 & 255) * dg >> 8;
61
- const bb = (src >> 16 & 255) * db >> 8;
175
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
176
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
177
+ const lumDst = dr * 77 + dg * 151 + db * 28;
178
+ let br, bg, bb;
179
+ if (lumSrc > lumDst) {
180
+ br = sr;
181
+ bg = sg;
182
+ bb = sb;
183
+ } else {
184
+ br = dr;
185
+ bg = dg;
186
+ bb = db;
187
+ }
62
188
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
63
189
  const invA = 255 - sa;
64
190
  const r = br * sa + dr * invA >> 8;
@@ -67,13 +193,14 @@ var multiplyColor32 = (src, dst) => {
67
193
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
68
194
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
69
195
  };
70
- var differenceColor32 = (src, dst) => {
196
+ var overlayColor32 = (src, dst) => {
71
197
  const sa = src >>> 24 & 255;
72
198
  if (sa === 0) return dst;
199
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
73
200
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
74
- const br = Math.abs((src & 255) - dr);
75
- const bg = Math.abs((src >> 8 & 255) - dg);
76
- const bb = Math.abs((src >> 16 & 255) - db);
201
+ const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
202
+ const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
203
+ const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
77
204
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
78
205
  const invA = 255 - sa;
79
206
  const r = br * sa + dr * invA >> 8;
@@ -82,11 +209,27 @@ var differenceColor32 = (src, dst) => {
82
209
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
83
210
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
84
211
  };
85
- var hardLightColor32 = (src, dst) => {
212
+ var softLightColor32 = (src, dst) => {
86
213
  const sa = src >>> 24 & 255;
87
214
  if (sa === 0) return dst;
215
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
88
216
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
217
+ const br = (255 - dr) * (sr * dr >> 8) + dr * (255 - ((255 - sr) * (255 - dr) >> 8)) >> 8;
218
+ const bg = (255 - dg) * (sg * dg >> 8) + dg * (255 - ((255 - sg) * (255 - dg) >> 8)) >> 8;
219
+ const bb = (255 - db) * (sb * db >> 8) + db * (255 - ((255 - sb) * (255 - db) >> 8)) >> 8;
220
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
221
+ const invA = 255 - sa;
222
+ const r = br * sa + dr * invA >> 8;
223
+ const g = bg * sa + dg * invA >> 8;
224
+ const b = bb * sa + db * invA >> 8;
225
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
226
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
227
+ };
228
+ var hardLightColor32 = (src, dst) => {
229
+ const sa = src >>> 24 & 255;
230
+ if (sa === 0) return dst;
89
231
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
232
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
90
233
  const br = sr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
91
234
  const bg = sg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
92
235
  const bb = sb < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
@@ -98,14 +241,30 @@ var hardLightColor32 = (src, dst) => {
98
241
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
99
242
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
100
243
  };
101
- var colorBurnColor32 = (src, dst) => {
244
+ var vividLightColor32 = (src, dst) => {
102
245
  const sa = src >>> 24 & 255;
103
246
  if (sa === 0) return dst;
247
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
104
248
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
249
+ 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)));
250
+ 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)));
251
+ 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)));
252
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
253
+ const invA = 255 - sa;
254
+ const r = br * sa + dr * invA >> 8;
255
+ const g = bg * sa + dg * invA >> 8;
256
+ const b = bb * sa + db * invA >> 8;
257
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
258
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
259
+ };
260
+ var linearLightColor32 = (src, dst) => {
261
+ const sa = src >>> 24 & 255;
262
+ if (sa === 0) return dst;
105
263
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
106
- const br = dr === 255 ? 255 : Math.max(0, 255 - (255 - dr << 8) / (sr || 1));
107
- const bg = dg === 255 ? 255 : Math.max(0, 255 - (255 - dg << 8) / (sg || 1));
108
- const bb = db === 255 ? 255 : Math.max(0, 255 - (255 - db << 8) / (sb || 1));
264
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
265
+ const br = Math.max(0, Math.min(255, dr + 2 * sr - 255));
266
+ const bg = Math.max(0, Math.min(255, dg + 2 * sg - 255));
267
+ const bb = Math.max(0, Math.min(255, db + 2 * sb - 255));
109
268
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
110
269
  const invA = 255 - sa;
111
270
  const r = br * sa + dr * invA >> 8;
@@ -114,14 +273,30 @@ var colorBurnColor32 = (src, dst) => {
114
273
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
115
274
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
116
275
  };
117
- var overlayColor32 = (src, dst) => {
276
+ var pinLightColor32 = (src, dst) => {
118
277
  const sa = src >>> 24 & 255;
119
278
  if (sa === 0) return dst;
279
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
120
280
  const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
281
+ const br = sr < 128 ? Math.min(dr, 2 * sr) : Math.max(dr, 2 * (sr - 128));
282
+ const bg = sg < 128 ? Math.min(dg, 2 * sg) : Math.max(dg, 2 * (sg - 128));
283
+ const bb = sb < 128 ? Math.min(db, 2 * sb) : Math.max(db, 2 * (sb - 128));
284
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
285
+ const invA = 255 - sa;
286
+ const r = br * sa + dr * invA >> 8;
287
+ const g = bg * sa + dg * invA >> 8;
288
+ const b = bb * sa + db * invA >> 8;
289
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
290
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
291
+ };
292
+ var hardMixColor32 = (src, dst) => {
293
+ const sa = src >>> 24 & 255;
294
+ if (sa === 0) return dst;
121
295
  const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
122
- const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
123
- const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
124
- const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
296
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
297
+ 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;
298
+ 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;
299
+ 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;
125
300
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
126
301
  const invA = 255 - sa;
127
302
  const r = br * sa + dr * invA >> 8;
@@ -130,16 +305,147 @@ var overlayColor32 = (src, dst) => {
130
305
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
131
306
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
132
307
  };
133
- var COLOR_32_BLEND_MODES = {
134
- sourceOver: sourceOverColor32,
135
- screen: screenColor32,
136
- linearDodge: linearDodgeColor32,
137
- multiply: multiplyColor32,
138
- difference: differenceColor32,
139
- overlay: overlayColor32,
140
- hardLight: hardLightColor32,
141
- colorBurn: colorBurnColor32
308
+ var differenceColor32 = (src, dst) => {
309
+ const sa = src >>> 24 & 255;
310
+ if (sa === 0) return dst;
311
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
312
+ const br = Math.abs((src & 255) - dr);
313
+ const bg = Math.abs((src >> 8 & 255) - dg);
314
+ const bb = Math.abs((src >> 16 & 255) - db);
315
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
316
+ const invA = 255 - sa;
317
+ const r = br * sa + dr * invA >> 8;
318
+ const g = bg * sa + dg * invA >> 8;
319
+ const b = bb * sa + db * invA >> 8;
320
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
321
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
322
+ };
323
+ var exclusionColor32 = (src, dst) => {
324
+ const sa = src >>> 24 & 255;
325
+ if (sa === 0) return dst;
326
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
327
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
328
+ const br = dr + sr - (dr * sr >> 7);
329
+ const bg = dg + sg - (dg * sg >> 7);
330
+ const bb = db + sb - (db * sb >> 7);
331
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
332
+ const invA = 255 - sa;
333
+ const r = br * sa + dr * invA >> 8;
334
+ const g = bg * sa + dg * invA >> 8;
335
+ const b = bb * sa + db * invA >> 8;
336
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
337
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
142
338
  };
339
+ var subtractColor32 = (src, dst) => {
340
+ const sa = src >>> 24 & 255;
341
+ if (sa === 0) return dst;
342
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
343
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
344
+ const br = Math.max(0, dr - sr);
345
+ const bg = Math.max(0, dg - sg);
346
+ const bb = Math.max(0, db - sb);
347
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
348
+ const invA = 255 - sa;
349
+ const r = br * sa + dr * invA >> 8;
350
+ const g = bg * sa + dg * invA >> 8;
351
+ const b = bb * sa + db * invA >> 8;
352
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
353
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
354
+ };
355
+ var divideColor32 = (src, dst) => {
356
+ const sa = src >>> 24 & 255;
357
+ if (sa === 0) return dst;
358
+ const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
359
+ const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
360
+ const br = sr === 0 ? 255 : Math.min(255, (dr << 8) / sr);
361
+ const bg = sg === 0 ? 255 : Math.min(255, (dg << 8) / sg);
362
+ const bb = sb === 0 ? 255 : Math.min(255, (db << 8) / sb);
363
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
364
+ const invA = 255 - sa;
365
+ const r = br * sa + dr * invA >> 8;
366
+ const g = bg * sa + dg * invA >> 8;
367
+ const b = bb * sa + db * invA >> 8;
368
+ const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
369
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
370
+ };
371
+ var BlendMode = /* @__PURE__ */ ((BlendMode2) => {
372
+ BlendMode2[BlendMode2["overwrite"] = 0] = "overwrite";
373
+ BlendMode2[BlendMode2["sourceOver"] = 1] = "sourceOver";
374
+ BlendMode2[BlendMode2["darken"] = 2] = "darken";
375
+ BlendMode2[BlendMode2["multiply"] = 3] = "multiply";
376
+ BlendMode2[BlendMode2["colorBurn"] = 4] = "colorBurn";
377
+ BlendMode2[BlendMode2["linearBurn"] = 5] = "linearBurn";
378
+ BlendMode2[BlendMode2["darkerColor"] = 6] = "darkerColor";
379
+ BlendMode2[BlendMode2["lighten"] = 7] = "lighten";
380
+ BlendMode2[BlendMode2["screen"] = 8] = "screen";
381
+ BlendMode2[BlendMode2["colorDodge"] = 9] = "colorDodge";
382
+ BlendMode2[BlendMode2["linearDodge"] = 10] = "linearDodge";
383
+ BlendMode2[BlendMode2["lighterColor"] = 11] = "lighterColor";
384
+ BlendMode2[BlendMode2["overlay"] = 12] = "overlay";
385
+ BlendMode2[BlendMode2["softLight"] = 13] = "softLight";
386
+ BlendMode2[BlendMode2["hardLight"] = 14] = "hardLight";
387
+ BlendMode2[BlendMode2["vividLight"] = 15] = "vividLight";
388
+ BlendMode2[BlendMode2["linearLight"] = 16] = "linearLight";
389
+ BlendMode2[BlendMode2["pinLight"] = 17] = "pinLight";
390
+ BlendMode2[BlendMode2["hardMix"] = 18] = "hardMix";
391
+ BlendMode2[BlendMode2["difference"] = 19] = "difference";
392
+ BlendMode2[BlendMode2["exclusion"] = 20] = "exclusion";
393
+ BlendMode2[BlendMode2["subtract"] = 21] = "subtract";
394
+ BlendMode2[BlendMode2["divide"] = 22] = "divide";
395
+ return BlendMode2;
396
+ })(BlendMode || {});
397
+ var BLENDER_REGISTRY = [
398
+ [0 /* overwrite */, overwriteColor32],
399
+ [1 /* sourceOver */, sourceOverColor32],
400
+ [2 /* darken */, darkenColor32],
401
+ [3 /* multiply */, multiplyColor32],
402
+ [4 /* colorBurn */, colorBurnColor32],
403
+ [5 /* linearBurn */, linearBurnColor32],
404
+ [6 /* darkerColor */, darkerColor32],
405
+ [7 /* lighten */, lightenColor32],
406
+ [8 /* screen */, screenColor32],
407
+ [9 /* colorDodge */, colorDodgeColor32],
408
+ [10 /* linearDodge */, linearDodgeColor32],
409
+ [11 /* lighterColor */, lighterColor32],
410
+ [12 /* overlay */, overlayColor32],
411
+ [13 /* softLight */, softLightColor32],
412
+ [14 /* hardLight */, hardLightColor32],
413
+ [15 /* vividLight */, vividLightColor32],
414
+ [16 /* linearLight */, linearLightColor32],
415
+ [17 /* pinLight */, pinLightColor32],
416
+ [18 /* hardMix */, hardMixColor32],
417
+ [19 /* difference */, differenceColor32],
418
+ [20 /* exclusion */, exclusionColor32],
419
+ [21 /* subtract */, subtractColor32],
420
+ [22 /* divide */, divideColor32]
421
+ ];
422
+ var COLOR_32_BLEND_MODES = [];
423
+ for (const [index, blend] of BLENDER_REGISTRY) {
424
+ COLOR_32_BLEND_MODES[index] = blend;
425
+ }
426
+ var COLOR_32_BLEND_TO_INDEX = new Map(
427
+ BLENDER_REGISTRY.map((entry, index) => {
428
+ return [
429
+ entry[1],
430
+ index
431
+ ];
432
+ })
433
+ );
434
+ var INDEX_TO_COLOR_32_BLEND = new Map(
435
+ BLENDER_REGISTRY.map((entry, index) => {
436
+ return [
437
+ index,
438
+ entry[1]
439
+ ];
440
+ })
441
+ );
442
+
443
+ // src/_types.ts
444
+ var MaskType = /* @__PURE__ */ ((MaskType2) => {
445
+ MaskType2[MaskType2["ALPHA"] = 0] = "ALPHA";
446
+ MaskType2[MaskType2["BINARY"] = 1] = "BINARY";
447
+ return MaskType2;
448
+ })(MaskType || {});
143
449
 
144
450
  // src/color.ts
145
451
  function packColor(r, g, b, a) {
@@ -204,20 +510,8 @@ function color32ToCssRGBA(color) {
204
510
  return `rgba(${r},${g},${b},${alpha})`;
205
511
  }
206
512
 
207
- // src/ImageData/copyImageData.ts
208
- function copyImageData({ data, width, height }) {
209
- return new ImageData(data.slice(), width, height);
210
- }
211
- function copyImageDataLike({ data, width, height }) {
212
- return {
213
- data: data.slice(),
214
- width,
215
- height
216
- };
217
- }
218
-
219
- // src/ImageData/extractImageData.ts
220
- function extractImageData(imageData, _x, _y, _w, _h) {
513
+ // src/ImageData/extractImageDataPixels.ts
514
+ function extractImageDataPixels(imageData, _x, _y, _w, _h) {
221
515
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
222
516
  const { width: srcW, height: srcH, data: src } = imageData;
223
517
  if (w <= 0 || h <= 0) return new Uint8ClampedArray(0);
@@ -239,6 +533,487 @@ function extractImageData(imageData, _x, _y, _w, _h) {
239
533
  return out;
240
534
  }
241
535
 
536
+ // src/Mask/extractMask.ts
537
+ function extractMask(mask, maskWidth, xOrRect, y, w, h) {
538
+ let finalX;
539
+ let finalY;
540
+ let finalW;
541
+ let finalH;
542
+ if (typeof xOrRect === "object") {
543
+ finalX = xOrRect.x;
544
+ finalY = xOrRect.y;
545
+ finalW = xOrRect.w;
546
+ finalH = xOrRect.h;
547
+ } else {
548
+ finalX = xOrRect;
549
+ finalY = y;
550
+ finalW = w;
551
+ finalH = h;
552
+ }
553
+ const out = new Uint8Array(finalW * finalH);
554
+ const srcH = mask.length / maskWidth;
555
+ for (let row = 0; row < finalH; row++) {
556
+ const currentSrcY = finalY + row;
557
+ if (currentSrcY < 0 || currentSrcY >= srcH) {
558
+ continue;
559
+ }
560
+ const start = Math.max(0, finalX);
561
+ const end = Math.min(maskWidth, finalX + finalW);
562
+ if (start < end) {
563
+ const srcOffset = currentSrcY * maskWidth + start;
564
+ const dstOffset = row * finalW + (start - finalX);
565
+ const count = end - start;
566
+ out.set(
567
+ mask.subarray(srcOffset, srcOffset + count),
568
+ dstOffset
569
+ );
570
+ }
571
+ }
572
+ return out;
573
+ }
574
+
575
+ // src/Rect/trimRectBounds.ts
576
+ function trimRectBounds(target, bounds) {
577
+ const originalX = target.x;
578
+ const originalY = target.y;
579
+ const originalW = target.w;
580
+ const intersectedX = Math.max(target.x, bounds.x);
581
+ const intersectedY = Math.max(target.y, bounds.y);
582
+ const intersectedMaxX = Math.min(
583
+ target.x + target.w,
584
+ bounds.x + bounds.w
585
+ );
586
+ const intersectedMaxY = Math.min(
587
+ target.y + target.h,
588
+ bounds.y + bounds.h
589
+ );
590
+ if (intersectedMaxX <= intersectedX || intersectedMaxY <= intersectedY) {
591
+ target.w = 0;
592
+ target.h = 0;
593
+ if ("mask" in target && target.mask) {
594
+ target.mask = new Uint8Array(0);
595
+ }
596
+ return;
597
+ }
598
+ const intersectedW = intersectedMaxX - intersectedX;
599
+ const intersectedH = intersectedMaxY - intersectedY;
600
+ const offsetX = intersectedX - originalX;
601
+ const offsetY = intersectedY - originalY;
602
+ target.x = intersectedX;
603
+ target.y = intersectedY;
604
+ target.w = intersectedW;
605
+ target.h = intersectedH;
606
+ if ("mask" in target && target.mask) {
607
+ const currentMask = extractMask(
608
+ target.mask,
609
+ originalW,
610
+ offsetX,
611
+ offsetY,
612
+ intersectedW,
613
+ intersectedH
614
+ );
615
+ let minX = intersectedW;
616
+ let maxX = -1;
617
+ let minY = intersectedH;
618
+ let maxY = -1;
619
+ for (let y = 0; y < intersectedH; y++) {
620
+ for (let x = 0; x < intersectedW; x++) {
621
+ if (currentMask[y * intersectedW + x] !== 0) {
622
+ if (x < minX) minX = x;
623
+ if (x > maxX) maxX = x;
624
+ if (y < minY) minY = y;
625
+ if (y > maxY) maxY = y;
626
+ }
627
+ }
628
+ }
629
+ if (maxX === -1) {
630
+ target.w = 0;
631
+ target.h = 0;
632
+ target.mask = new Uint8Array(0);
633
+ return;
634
+ }
635
+ const finalW = maxX - minX + 1;
636
+ const finalH = maxY - minY + 1;
637
+ if (finalW !== intersectedW || finalH !== intersectedH) {
638
+ target.mask = extractMask(
639
+ currentMask,
640
+ intersectedW,
641
+ minX,
642
+ minY,
643
+ finalW,
644
+ finalH
645
+ );
646
+ target.x += minX;
647
+ target.y += minY;
648
+ target.w = finalW;
649
+ target.h = finalH;
650
+ } else {
651
+ target.mask = currentMask;
652
+ }
653
+ }
654
+ }
655
+
656
+ // src/Algorithm/floodFillSelection.ts
657
+ function floodFillSelection(img, startX, startY, {
658
+ contiguous = true,
659
+ tolerance = 0,
660
+ bounds
661
+ } = {}) {
662
+ let imageData;
663
+ let data32;
664
+ if ("data32" in img) {
665
+ data32 = img.data32;
666
+ imageData = img.imageData;
667
+ } else {
668
+ data32 = new Uint32Array(
669
+ img.data.buffer,
670
+ img.data.byteOffset,
671
+ img.data.byteLength >> 2
672
+ );
673
+ imageData = img;
674
+ }
675
+ const {
676
+ width,
677
+ height
678
+ } = img;
679
+ const limit = bounds || {
680
+ x: 0,
681
+ y: 0,
682
+ w: width,
683
+ h: height
684
+ };
685
+ const xMin = Math.max(0, limit.x);
686
+ const xMax = Math.min(width - 1, limit.x + limit.w - 1);
687
+ const yMin = Math.max(0, limit.y);
688
+ const yMax = Math.min(height - 1, limit.y + limit.h - 1);
689
+ if (startX < xMin || startX > xMax || startY < yMin || startY > yMax) {
690
+ return null;
691
+ }
692
+ const baseColor = data32[startY * width + startX];
693
+ let matchCount = 0;
694
+ const matchX = new Uint16Array(width * height);
695
+ const matchY = new Uint16Array(width * height);
696
+ let minX = startX;
697
+ let maxX = startX;
698
+ let minY = startY;
699
+ let maxY = startY;
700
+ if (contiguous) {
701
+ const visited = new Uint8Array(width * height);
702
+ const stack = new Uint32Array(width * height);
703
+ let stackPtr = 0;
704
+ stack[stackPtr++] = startY << 16 | startX;
705
+ visited[startY * width + startX] = 1;
706
+ while (stackPtr > 0) {
707
+ const val = stack[--stackPtr];
708
+ const x = val & 65535;
709
+ const y = val >>> 16;
710
+ matchX[matchCount] = x;
711
+ matchY[matchCount] = y;
712
+ matchCount++;
713
+ if (x < minX) minX = x;
714
+ if (x > maxX) maxX = x;
715
+ if (y < minY) minY = y;
716
+ if (y > maxY) maxY = y;
717
+ if (x + 1 <= xMax) {
718
+ const idx = y * width + (x + 1);
719
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
720
+ visited[idx] = 1;
721
+ stack[stackPtr++] = y << 16 | x + 1;
722
+ }
723
+ }
724
+ if (x - 1 >= xMin) {
725
+ const idx = y * width + (x - 1);
726
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
727
+ visited[idx] = 1;
728
+ stack[stackPtr++] = y << 16 | x - 1;
729
+ }
730
+ }
731
+ if (y + 1 <= yMax) {
732
+ const idx = (y + 1) * width + x;
733
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
734
+ visited[idx] = 1;
735
+ stack[stackPtr++] = y + 1 << 16 | x;
736
+ }
737
+ }
738
+ if (y - 1 >= yMin) {
739
+ const idx = (y - 1) * width + x;
740
+ if (!visited[idx] && colorDistance(data32[idx], baseColor) <= tolerance) {
741
+ visited[idx] = 1;
742
+ stack[stackPtr++] = y - 1 << 16 | x;
743
+ }
744
+ }
745
+ }
746
+ } else {
747
+ for (let y = yMin; y <= yMax; y++) {
748
+ for (let x = xMin; x <= xMax; x++) {
749
+ const color = data32[y * width + x];
750
+ if (colorDistance(color, baseColor) <= tolerance) {
751
+ matchX[matchCount] = x;
752
+ matchY[matchCount] = y;
753
+ matchCount++;
754
+ if (x < minX) minX = x;
755
+ if (x > maxX) maxX = x;
756
+ if (y < minY) minY = y;
757
+ if (y > maxY) maxY = y;
758
+ }
759
+ }
760
+ }
761
+ }
762
+ if (matchCount === 0) {
763
+ return null;
764
+ }
765
+ const selectionRect = {
766
+ x: minX,
767
+ y: minY,
768
+ w: maxX - minX + 1,
769
+ h: maxY - minY + 1,
770
+ mask: new Uint8Array((maxX - minX + 1) * (maxY - minY + 1)),
771
+ maskType: 1 /* BINARY */
772
+ };
773
+ const sw = selectionRect.w;
774
+ const sh = selectionRect.h;
775
+ const finalMask = selectionRect.mask;
776
+ for (let i = 0; i < matchCount; i++) {
777
+ const mx = matchX[i] - selectionRect.x;
778
+ const my = matchY[i] - selectionRect.y;
779
+ if (mx >= 0 && mx < sw && my >= 0 && my < sh) {
780
+ finalMask[my * sw + mx] = 1;
781
+ }
782
+ }
783
+ trimRectBounds(
784
+ selectionRect,
785
+ { x: 0, y: 0, w: width, h: height }
786
+ );
787
+ const extracted = extractImageDataPixels(
788
+ imageData,
789
+ selectionRect.x,
790
+ selectionRect.y,
791
+ selectionRect.w,
792
+ selectionRect.h
793
+ );
794
+ return {
795
+ startX,
796
+ startY,
797
+ selectionRect,
798
+ pixels: extracted
799
+ };
800
+ }
801
+
802
+ // src/Canvas/_constants.ts
803
+ var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
804
+ var CANVAS_CTX_FAILED = "Failed to create Canvas context";
805
+
806
+ // src/Canvas/PixelCanvas.ts
807
+ function makePixelCanvas(canvas) {
808
+ const ctx = canvas.getContext("2d");
809
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
810
+ ctx.imageSmoothingEnabled = false;
811
+ return {
812
+ canvas,
813
+ ctx,
814
+ resize(w, h) {
815
+ canvas.width = w;
816
+ canvas.height = h;
817
+ ctx.imageSmoothingEnabled = false;
818
+ }
819
+ };
820
+ }
821
+
822
+ // src/Canvas/ReusableCanvas.ts
823
+ function makeReusableCanvas() {
824
+ let canvas = null;
825
+ let ctx = null;
826
+ function get2(width, height) {
827
+ if (canvas === null) {
828
+ canvas = document.createElement("canvas");
829
+ ctx = canvas.getContext("2d");
830
+ if (!ctx) throw new Error(CANVAS_CTX_FAILED);
831
+ }
832
+ if (canvas.width !== width || canvas.height !== height) {
833
+ canvas.width = width;
834
+ canvas.height = height;
835
+ ctx.imageSmoothingEnabled = false;
836
+ } else {
837
+ ctx.clearRect(0, 0, width, height);
838
+ }
839
+ return { canvas, ctx };
840
+ }
841
+ get2.reset = () => {
842
+ canvas = null;
843
+ ctx = null;
844
+ };
845
+ return get2;
846
+ }
847
+
848
+ // src/ImageData/imgBlobToImageData.ts
849
+ async function imgBlobToImageData(blob) {
850
+ let bitmap = null;
851
+ try {
852
+ bitmap = await createImageBitmap(blob);
853
+ const canvas = new OffscreenCanvas(
854
+ bitmap.width,
855
+ bitmap.height
856
+ );
857
+ const ctx = canvas.getContext("2d");
858
+ if (!ctx) {
859
+ throw new Error("Failed to get 2D context");
860
+ }
861
+ ctx.drawImage(bitmap, 0, 0);
862
+ return ctx.getImageData(
863
+ 0,
864
+ 0,
865
+ bitmap.width,
866
+ bitmap.height
867
+ );
868
+ } finally {
869
+ bitmap?.close();
870
+ }
871
+ }
872
+
873
+ // src/Clipboard/getImageDataFromClipboard.ts
874
+ async function getImageDataFromClipboard(clipboardEvent) {
875
+ const items = clipboardEvent?.clipboardData?.items;
876
+ if (!items?.length) return null;
877
+ for (let i = 0; i < items.length; i++) {
878
+ const item = items[i];
879
+ if (item.type.startsWith("image/")) {
880
+ const blob = item.getAsFile();
881
+ if (!blob) {
882
+ continue;
883
+ }
884
+ return imgBlobToImageData(blob);
885
+ }
886
+ }
887
+ return null;
888
+ }
889
+
890
+ // src/ImageData/imageDataToImgBlob.ts
891
+ async function imageDataToImgBlob(imageData) {
892
+ const canvas = new OffscreenCanvas(imageData.width, imageData.height);
893
+ const ctx = canvas.getContext("2d");
894
+ if (!ctx) throw new Error("could not create 2d context");
895
+ ctx.putImageData(imageData, 0, 0);
896
+ return canvas.convertToBlob({
897
+ type: "image/png"
898
+ });
899
+ }
900
+
901
+ // src/Clipboard/writeImgBlobToClipboard.ts
902
+ async function writeImgBlobToClipboard(blob) {
903
+ const item = new ClipboardItem({
904
+ "image/png": blob
905
+ });
906
+ await navigator.clipboard.write([item]);
907
+ }
908
+
909
+ // src/Clipboard/writeImageDataToClipboard.ts
910
+ async function writeImageDataToClipboard(imageData) {
911
+ const blob = await imageDataToImgBlob(imageData);
912
+ return writeImgBlobToClipboard(blob);
913
+ }
914
+
915
+ // src/ImageData/copyImageData.ts
916
+ function copyImageData({ data, width, height }) {
917
+ return new ImageData(data.slice(), width, height);
918
+ }
919
+ function copyImageDataLike({ data, width, height }) {
920
+ return {
921
+ data: data.slice(),
922
+ width,
923
+ height
924
+ };
925
+ }
926
+
927
+ // src/PixelData/pixelDataToAlphaMask.ts
928
+ function pixelDataToAlphaMask(pixelData) {
929
+ const {
930
+ data32,
931
+ width,
932
+ height
933
+ } = pixelData;
934
+ const len = data32.length;
935
+ const mask = new Uint8Array(width * height);
936
+ for (let i = 0; i < len; i++) {
937
+ const val = data32[i];
938
+ mask[i] = val >>> 24 & 255;
939
+ }
940
+ return mask;
941
+ }
942
+
943
+ // src/ImageData/imageDataToAlphaMask.ts
944
+ function imageDataToAlphaMask(imageData) {
945
+ const {
946
+ width,
947
+ height,
948
+ data
949
+ } = imageData;
950
+ const data32 = new Uint32Array(
951
+ data.buffer,
952
+ data.byteOffset,
953
+ data.byteLength >> 2
954
+ );
955
+ const len = data32.length;
956
+ const mask = new Uint8Array(width * height);
957
+ for (let i = 0; i < len; i++) {
958
+ const val = data32[i];
959
+ mask[i] = val >>> 24 & 255;
960
+ }
961
+ return mask;
962
+ }
963
+
964
+ // src/ImageData/imageDataToDataUrl.ts
965
+ var get = makeReusableCanvas();
966
+ function imageDataToDataUrl(imageData) {
967
+ const { canvas, ctx } = get(imageData.width, imageData.height);
968
+ ctx.putImageData(imageData, 0, 0);
969
+ return canvas.toDataURL();
970
+ }
971
+ imageDataToDataUrl.reset = get.reset;
972
+
973
+ // src/ImageData/invertImageData.ts
974
+ function invertImageData(imageData) {
975
+ const data = imageData.data;
976
+ let length = data.length;
977
+ for (let i = 0; i < length; i += 4) {
978
+ data[i] = 255 - data[i];
979
+ data[i + 1] = 255 - data[i + 1];
980
+ data[i + 2] = 255 - data[i + 2];
981
+ }
982
+ return imageData;
983
+ }
984
+
985
+ // src/ImageData/resizeImageData.ts
986
+ function resizeImageData(current, newWidth, newHeight, offsetX = 0, offsetY = 0) {
987
+ const result = new ImageData(newWidth, newHeight);
988
+ const {
989
+ width: oldW,
990
+ height: oldH,
991
+ data: oldData
992
+ } = current;
993
+ const newData = result.data;
994
+ const x0 = Math.max(0, offsetX);
995
+ const y0 = Math.max(0, offsetY);
996
+ const x1 = Math.min(newWidth, offsetX + oldW);
997
+ const y1 = Math.min(newHeight, offsetY + oldH);
998
+ if (x1 <= x0 || y1 <= y0) {
999
+ return result;
1000
+ }
1001
+ const rowCount = y1 - y0;
1002
+ const rowLen = (x1 - x0) * 4;
1003
+ for (let row = 0; row < rowCount; row++) {
1004
+ const dstY = y0 + row;
1005
+ const srcY = dstY - offsetY;
1006
+ const srcX = x0 - offsetX;
1007
+ const dstStart = (dstY * newWidth + x0) * 4;
1008
+ const srcStart = (srcY * oldW + srcX) * 4;
1009
+ newData.set(
1010
+ oldData.subarray(srcStart, srcStart + rowLen),
1011
+ dstStart
1012
+ );
1013
+ }
1014
+ return result;
1015
+ }
1016
+
242
1017
  // src/ImageData/serialization.ts
243
1018
  function base64EncodeArrayBuffer(buffer) {
244
1019
  const binary = String.fromCharCode(...new Uint8Array(buffer));
@@ -279,8 +1054,8 @@ function deserializeNullableImageData(serialized) {
279
1054
  return deserializeImageData(serialized);
280
1055
  }
281
1056
 
282
- // src/ImageData/writeImageData.ts
283
- function writeImageData(imageData, data, _x, _y, _w, _h) {
1057
+ // src/ImageData/writeImageDataPixels.ts
1058
+ function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
284
1059
  const { x, y, w, h } = typeof _x === "object" ? _x : { x: _x, y: _y, w: _w, h: _h };
285
1060
  const { width: dstW, height: dstH, data: dst } = imageData;
286
1061
  const x0 = Math.max(0, x);
@@ -300,6 +1075,90 @@ function writeImageData(imageData, data, _x, _y, _w, _h) {
300
1075
  }
301
1076
  }
302
1077
 
1078
+ // src/Input/fileInputChangeToImageData.ts
1079
+ async function fileInputChangeToImageData(event) {
1080
+ const target = event.target;
1081
+ const file = target.files?.[0];
1082
+ if (!file) return null;
1083
+ return await fileToImageData(file);
1084
+ }
1085
+
1086
+ // src/Input/fileToImageData.ts
1087
+ var UnsupportedFormatError = class extends Error {
1088
+ constructor(mimeType) {
1089
+ super(`File type ${mimeType} is not a supported image format.`);
1090
+ this.name = "UnsupportedFormatError";
1091
+ }
1092
+ };
1093
+ async function fileToImageData(file) {
1094
+ if (!file) return null;
1095
+ if (!file.type.startsWith("image/")) {
1096
+ throw new UnsupportedFormatError(file.type);
1097
+ }
1098
+ let bitmap = null;
1099
+ try {
1100
+ bitmap = await createImageBitmap(file);
1101
+ const canvas = new OffscreenCanvas(
1102
+ bitmap.width,
1103
+ bitmap.height
1104
+ );
1105
+ const ctx = canvas.getContext("2d");
1106
+ if (!ctx) throw new Error(OFFSCREEN_CANVAS_CTX_FAILED);
1107
+ ctx.drawImage(
1108
+ bitmap,
1109
+ 0,
1110
+ 0
1111
+ );
1112
+ return ctx.getImageData(
1113
+ 0,
1114
+ 0,
1115
+ bitmap.width,
1116
+ bitmap.height
1117
+ );
1118
+ } finally {
1119
+ bitmap?.close();
1120
+ }
1121
+ }
1122
+
1123
+ // src/Input/getSupportedRasterFormats.ts
1124
+ var formatsPromise = null;
1125
+ var defaultRasterMimes = [
1126
+ "image/png",
1127
+ "image/jpeg",
1128
+ "image/webp",
1129
+ "image/avif",
1130
+ "image/gif",
1131
+ "image/bmp"
1132
+ ];
1133
+ async function getSupportedPixelFormats(rasterMimes = defaultRasterMimes) {
1134
+ if (formatsPromise) {
1135
+ return formatsPromise;
1136
+ }
1137
+ const probeCanvas = async () => {
1138
+ const canvas = new OffscreenCanvas(1, 1);
1139
+ const results = await Promise.all(
1140
+ rasterMimes.map(async (mime) => {
1141
+ try {
1142
+ const blob = await canvas.convertToBlob({
1143
+ type: mime
1144
+ });
1145
+ return blob.type === mime ? mime : null;
1146
+ } catch {
1147
+ return null;
1148
+ }
1149
+ })
1150
+ );
1151
+ return results.filter((type) => {
1152
+ return type !== null;
1153
+ });
1154
+ };
1155
+ formatsPromise = probeCanvas().catch((error) => {
1156
+ formatsPromise = null;
1157
+ throw error;
1158
+ });
1159
+ return formatsPromise;
1160
+ }
1161
+
303
1162
  // src/Mask/copyMask.ts
304
1163
  function copyMask(src) {
305
1164
  return src.slice();
@@ -385,6 +1244,23 @@ function mergeMasks(dst, dstWidth, src, opts) {
385
1244
  }
386
1245
  }
387
1246
 
1247
+ // src/PixelData.ts
1248
+ var PixelData = class {
1249
+ constructor(imageData) {
1250
+ this.imageData = imageData;
1251
+ this.width = imageData.width;
1252
+ this.height = imageData.height;
1253
+ this.data32 = new Uint32Array(
1254
+ imageData.data.buffer,
1255
+ imageData.data.byteOffset,
1256
+ imageData.data.byteLength >> 2
1257
+ );
1258
+ }
1259
+ data32;
1260
+ width;
1261
+ height;
1262
+ };
1263
+
388
1264
  // src/PixelData/applyMaskToPixelData.ts
389
1265
  function applyMaskToPixelData(dst, mask, opts) {
390
1266
  const {
@@ -716,17 +1592,27 @@ function blendPixelData(dst, src, opts) {
716
1592
  }
717
1593
 
718
1594
  // src/PixelData/fillPixelData.ts
719
- function fillPixelData(dst, color, rect) {
720
- const {
721
- x: targetX = 0,
722
- y: targetY = 0,
723
- w: width = dst.width,
724
- h: height = dst.height
725
- } = rect || {};
726
- let x = targetX;
727
- let y = targetY;
728
- let w = width;
729
- let h = height;
1595
+ function fillPixelData(dst, color, _x, _y, _w, _h) {
1596
+ let x;
1597
+ let y;
1598
+ let w;
1599
+ let h;
1600
+ if (typeof _x === "object") {
1601
+ x = _x.x ?? 0;
1602
+ y = _x.y ?? 0;
1603
+ w = _x.w ?? dst.width;
1604
+ h = _x.h ?? dst.height;
1605
+ } else if (typeof _x === "number") {
1606
+ x = _x;
1607
+ y = _y;
1608
+ w = _w;
1609
+ h = _h;
1610
+ } else {
1611
+ x = 0;
1612
+ y = 0;
1613
+ w = dst.width;
1614
+ h = dst.height;
1615
+ }
730
1616
  if (x < 0) {
731
1617
  w += x;
732
1618
  x = 0;
@@ -757,9 +1643,24 @@ function fillPixelData(dst, color, rect) {
757
1643
  function clearPixelData(dst, rect) {
758
1644
  fillPixelData(dst, 0, rect);
759
1645
  }
1646
+
1647
+ // src/PixelData/invertPixelData.ts
1648
+ function invertPixelData(pixelData) {
1649
+ const data32 = pixelData.data32;
1650
+ const len = data32.length;
1651
+ for (let i = 0; i < len; i++) {
1652
+ data32[i] = data32[i] ^ 16777215;
1653
+ }
1654
+ return pixelData;
1655
+ }
760
1656
  export {
1657
+ BlendMode,
761
1658
  COLOR_32_BLEND_MODES,
1659
+ COLOR_32_BLEND_TO_INDEX,
1660
+ INDEX_TO_COLOR_32_BLEND,
762
1661
  MaskType,
1662
+ PixelData,
1663
+ UnsupportedFormatError,
763
1664
  applyMaskToPixelData,
764
1665
  base64DecodeArrayBuffer,
765
1666
  base64EncodeArrayBuffer,
@@ -770,36 +1671,70 @@ export {
770
1671
  color32ToHex,
771
1672
  colorBurnColor32,
772
1673
  colorDistance,
1674
+ colorDodgeColor32,
773
1675
  copyImageData,
774
1676
  copyImageDataLike,
775
1677
  copyMask,
1678
+ darkenColor32,
1679
+ darkerColor32,
776
1680
  deserializeImageData,
777
1681
  deserializeNullableImageData,
778
1682
  deserializeRawImageData,
779
1683
  differenceColor32,
780
- extractImageData,
1684
+ divideColor32,
1685
+ exclusionColor32,
1686
+ extractImageDataPixels,
1687
+ extractMask,
1688
+ fileInputChangeToImageData,
1689
+ fileToImageData,
781
1690
  fillPixelData,
1691
+ floodFillSelection,
1692
+ getImageDataFromClipboard,
1693
+ getSupportedPixelFormats,
782
1694
  hardLightColor32,
1695
+ hardMixColor32,
1696
+ imageDataToAlphaMask,
1697
+ imageDataToDataUrl,
1698
+ imageDataToImgBlob,
1699
+ imgBlobToImageData,
783
1700
  invertAlphaMask,
784
1701
  invertBinaryMask,
1702
+ invertImageData,
1703
+ invertPixelData,
785
1704
  lerpColor32,
786
1705
  lerpColor32Fast,
1706
+ lightenColor32,
1707
+ lighterColor32,
1708
+ linearBurnColor32,
787
1709
  linearDodgeColor32,
1710
+ linearLightColor32,
1711
+ makePixelCanvas,
1712
+ makeReusableCanvas,
788
1713
  mergeMasks,
789
1714
  multiplyColor32,
790
1715
  overlayColor32,
1716
+ overwriteColor32,
791
1717
  packColor,
792
1718
  packRGBA,
1719
+ pinLightColor32,
1720
+ pixelDataToAlphaMask,
1721
+ resizeImageData,
793
1722
  screenColor32,
794
1723
  serializeImageData,
795
1724
  serializeNullableImageData,
1725
+ softLightColor32,
796
1726
  sourceOverColor32,
1727
+ subtractColor32,
1728
+ trimRectBounds,
797
1729
  unpackAlpha,
798
1730
  unpackBlue,
799
1731
  unpackColor,
800
1732
  unpackColorTo,
801
1733
  unpackGreen,
802
1734
  unpackRed,
803
- writeImageData
1735
+ vividLightColor32,
1736
+ writeImageDataPixels,
1737
+ writeImageDataToClipboard,
1738
+ writeImgBlobToClipboard
804
1739
  };
805
1740
  //# sourceMappingURL=index.prod.js.map