pixel-data-js 0.5.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,31 +1,56 @@
1
- // src/blend-modes.ts
2
- var overwriteColor32 = (src, dst) => src;
3
- var sourceOverColor32 = (src, dst) => {
4
- const a = src >>> 24 & 255;
5
- if (a === 255) return src;
6
- if (a === 0) return dst;
7
- const rbMask = 16711935;
8
- const gMask = 65280;
9
- const sRB = src & rbMask;
10
- const sG = src & gMask;
11
- const dRB = dst & rbMask;
12
- const dG = dst & gMask;
13
- const invA = 255 - a;
14
- const outRB = sRB * a + dRB * invA >> 8 & rbMask;
15
- const outG = sG * a + dG * invA >> 8 & gMask;
16
- const outA = a + ((dst >>> 24 & 255) * invA >> 8);
17
- return (outA << 24 | outRB | outG) >>> 0;
1
+ // src/BlendModes/blend-modes.ts
2
+ var BlendMode = /* @__PURE__ */ ((BlendMode2) => {
3
+ BlendMode2[BlendMode2["overwrite"] = 0] = "overwrite";
4
+ BlendMode2[BlendMode2["sourceOver"] = 1] = "sourceOver";
5
+ BlendMode2[BlendMode2["darken"] = 2] = "darken";
6
+ BlendMode2[BlendMode2["multiply"] = 3] = "multiply";
7
+ BlendMode2[BlendMode2["colorBurn"] = 4] = "colorBurn";
8
+ BlendMode2[BlendMode2["linearBurn"] = 5] = "linearBurn";
9
+ BlendMode2[BlendMode2["darkerColor"] = 6] = "darkerColor";
10
+ BlendMode2[BlendMode2["lighten"] = 7] = "lighten";
11
+ BlendMode2[BlendMode2["screen"] = 8] = "screen";
12
+ BlendMode2[BlendMode2["colorDodge"] = 9] = "colorDodge";
13
+ BlendMode2[BlendMode2["linearDodge"] = 10] = "linearDodge";
14
+ BlendMode2[BlendMode2["lighterColor"] = 11] = "lighterColor";
15
+ BlendMode2[BlendMode2["overlay"] = 12] = "overlay";
16
+ BlendMode2[BlendMode2["softLight"] = 13] = "softLight";
17
+ BlendMode2[BlendMode2["hardLight"] = 14] = "hardLight";
18
+ BlendMode2[BlendMode2["vividLight"] = 15] = "vividLight";
19
+ BlendMode2[BlendMode2["linearLight"] = 16] = "linearLight";
20
+ BlendMode2[BlendMode2["pinLight"] = 17] = "pinLight";
21
+ BlendMode2[BlendMode2["hardMix"] = 18] = "hardMix";
22
+ BlendMode2[BlendMode2["difference"] = 19] = "difference";
23
+ BlendMode2[BlendMode2["exclusion"] = 20] = "exclusion";
24
+ BlendMode2[BlendMode2["subtract"] = 21] = "subtract";
25
+ BlendMode2[BlendMode2["divide"] = 22] = "divide";
26
+ return BlendMode2;
27
+ })(BlendMode || {});
28
+
29
+ // src/BlendModes/blend-modes-fast.ts
30
+ var overwriteFast = (src, _dst) => src;
31
+ var sourceOverFast = (src, dst) => {
32
+ const sa = src >>> 24 & 255;
33
+ if (sa === 255) return src;
34
+ if (sa === 0) return dst;
35
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
36
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
37
+ const da = dst >>> 24 & 255;
38
+ const invA = 255 - sa;
39
+ const r = sr * sa + dr * invA >> 8;
40
+ const g = sg * sa + dg * invA >> 8;
41
+ const b = sb * sa + db * invA >> 8;
42
+ const a = 255 * sa + da * invA >> 8;
43
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
18
44
  };
19
- var darkenColor32 = (src, dst) => {
45
+ var darkenFast = (src, dst) => {
20
46
  const sa = src >>> 24 & 255;
21
47
  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);
48
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
49
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
50
+ const br = sr < dr ? sr : dr;
51
+ const bg = sg < dg ? sg : dg;
52
+ const bb = sb < db ? sb : db;
25
53
  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
54
  const invA = 255 - sa;
30
55
  const r = br * sa + dr * invA >> 8;
31
56
  const g = bg * sa + dg * invA >> 8;
@@ -33,45 +58,51 @@ var darkenColor32 = (src, dst) => {
33
58
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
34
59
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
35
60
  };
36
- var multiplyColor32 = (src, dst) => {
61
+ var multiplyFast = (src, dst) => {
37
62
  const sa = src >>> 24 & 255;
38
63
  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;
64
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
65
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
66
+ const br = sr * dr >> 8;
67
+ const bg = sg * dg >> 8;
68
+ const bb = sb * db >> 8;
43
69
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
44
70
  const invA = 255 - sa;
71
+ const da = dst >>> 24 & 255;
45
72
  const r = br * sa + dr * invA >> 8;
46
73
  const g = bg * sa + dg * invA >> 8;
47
74
  const b = bb * sa + db * invA >> 8;
48
- const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
75
+ const a = 255 * sa + da * invA >> 8;
49
76
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
50
77
  };
51
- var colorBurnColor32 = (src, dst) => {
78
+ var colorBurnFast = (src, dst) => {
52
79
  const sa = src >>> 24 & 255;
53
80
  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));
81
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
82
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
83
+ const br = dr === 255 ? 255 : sr === 0 ? 0 : Math.max(0, 255 - (255 - dr << 8) / sr | 0);
84
+ const bg = dg === 255 ? 255 : sg === 0 ? 0 : Math.max(0, 255 - (255 - dg << 8) / sg | 0);
85
+ const bb = db === 255 ? 255 : sb === 0 ? 0 : Math.max(0, 255 - (255 - db << 8) / sb | 0);
59
86
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
60
87
  const invA = 255 - sa;
88
+ const da = dst >>> 24 & 255;
61
89
  const r = br * sa + dr * invA >> 8;
62
90
  const g = bg * sa + dg * invA >> 8;
63
91
  const b = bb * sa + db * invA >> 8;
64
- const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
92
+ const a = 255 * sa + da * invA >> 8;
65
93
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
66
94
  };
67
- var linearBurnColor32 = (src, dst) => {
95
+ var linearBurnFast = (src, dst) => {
68
96
  const sa = src >>> 24 & 255;
69
97
  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);
98
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
99
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
100
+ const brU = dr + sr - 255;
101
+ const bgU = dg + sg - 255;
102
+ const bbU = db + sb - 255;
103
+ const br = brU < 0 ? 0 : brU;
104
+ const bg = bgU < 0 ? 0 : bgU;
105
+ const bb = bbU < 0 ? 0 : bbU;
75
106
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
76
107
  const invA = 255 - sa;
77
108
  const r = br * sa + dr * invA >> 8;
@@ -80,11 +111,11 @@ var linearBurnColor32 = (src, dst) => {
80
111
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
81
112
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
82
113
  };
83
- var darkerColor32 = (src, dst) => {
114
+ var darkerFast = (src, dst) => {
84
115
  const sa = src >>> 24 & 255;
85
116
  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;
117
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
118
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
88
119
  const lumSrc = sr * 77 + sg * 151 + sb * 28;
89
120
  const lumDst = dr * 77 + dg * 151 + db * 28;
90
121
  let br, bg, bb;
@@ -105,7 +136,7 @@ var darkerColor32 = (src, dst) => {
105
136
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
106
137
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
107
138
  };
108
- var lightenColor32 = (src, dst) => {
139
+ var lightenFast = (src, dst) => {
109
140
  const sa = src >>> 24 & 255;
110
141
  if (sa === 0) return dst;
111
142
  const br = Math.max(src & 255, dst & 255);
@@ -122,13 +153,13 @@ var lightenColor32 = (src, dst) => {
122
153
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
123
154
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
124
155
  };
125
- var screenColor32 = (src, dst) => {
156
+ var screenFast = (src, dst) => {
126
157
  const sa = src >>> 24 & 255;
127
158
  if (sa === 0) return dst;
128
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
159
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
129
160
  const br = 255 - ((255 - (src & 255)) * (255 - dr) >> 8);
130
- const bg = 255 - ((255 - (src >> 8 & 255)) * (255 - dg) >> 8);
131
- const bb = 255 - ((255 - (src >> 16 & 255)) * (255 - db) >> 8);
161
+ const bg = 255 - ((255 - (src >>> 8 & 255)) * (255 - dg) >> 8);
162
+ const bb = 255 - ((255 - (src >>> 16 & 255)) * (255 - db) >> 8);
132
163
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
133
164
  const invA = 255 - sa;
134
165
  const r = br * sa + dr * invA >> 8;
@@ -137,14 +168,14 @@ var screenColor32 = (src, dst) => {
137
168
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
138
169
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
139
170
  };
140
- var colorDodgeColor32 = (src, dst) => {
171
+ var colorDodgeFast = (src, dst) => {
141
172
  const sa = src >>> 24 & 255;
142
173
  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));
174
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
175
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
176
+ const br = sr === 255 ? 255 : Math.min(255, (dr << 8) / (255 - sr) | 0);
177
+ const bg = sg === 255 ? 255 : Math.min(255, (dg << 8) / (255 - sg) | 0);
178
+ const bb = sb === 255 ? 255 : Math.min(255, (db << 8) / (255 - sb) | 0);
148
179
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
149
180
  const invA = 255 - sa;
150
181
  const r = br * sa + dr * invA >> 8;
@@ -153,13 +184,16 @@ var colorDodgeColor32 = (src, dst) => {
153
184
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
154
185
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
155
186
  };
156
- var linearDodgeColor32 = (src, dst) => {
187
+ var linearDodgeFast = (src, dst) => {
157
188
  const sa = src >>> 24 & 255;
158
189
  if (sa === 0) return dst;
159
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
160
- const br = Math.min(255, (src & 255) + dr);
161
- const bg = Math.min(255, (src >> 8 & 255) + dg);
162
- const bb = Math.min(255, (src >> 16 & 255) + db);
190
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
191
+ const brU = (src & 255) + dr;
192
+ const bgU = (src >>> 8 & 255) + dg;
193
+ const bbU = (src >>> 16 & 255) + db;
194
+ const br = brU > 255 ? 255 : brU;
195
+ const bg = bgU > 255 ? 255 : bgU;
196
+ const bb = bbU > 255 ? 255 : bbU;
163
197
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
164
198
  const invA = 255 - sa;
165
199
  const r = br * sa + dr * invA >> 8;
@@ -168,11 +202,11 @@ var linearDodgeColor32 = (src, dst) => {
168
202
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
169
203
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
170
204
  };
171
- var lighterColor32 = (src, dst) => {
205
+ var lighterFast = (src, dst) => {
172
206
  const sa = src >>> 24 & 255;
173
207
  if (sa === 0) return dst;
174
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
175
- const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
208
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
209
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
176
210
  const lumSrc = sr * 77 + sg * 151 + sb * 28;
177
211
  const lumDst = dr * 77 + dg * 151 + db * 28;
178
212
  let br, bg, bb;
@@ -193,11 +227,11 @@ var lighterColor32 = (src, dst) => {
193
227
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
194
228
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
195
229
  };
196
- var overlayColor32 = (src, dst) => {
230
+ var overlayFast = (src, dst) => {
197
231
  const sa = src >>> 24 & 255;
198
232
  if (sa === 0) return dst;
199
- const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
200
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
233
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
234
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
201
235
  const br = dr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
202
236
  const bg = dg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
203
237
  const bb = db < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
@@ -209,11 +243,11 @@ var overlayColor32 = (src, dst) => {
209
243
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
210
244
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
211
245
  };
212
- var softLightColor32 = (src, dst) => {
246
+ var softLightFast = (src, dst) => {
213
247
  const sa = src >>> 24 & 255;
214
248
  if (sa === 0) return dst;
215
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
216
- const sr = src & 255, sg = src >> 8 & 255, sb = src >> 16 & 255;
249
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
250
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
217
251
  const br = (255 - dr) * (sr * dr >> 8) + dr * (255 - ((255 - sr) * (255 - dr) >> 8)) >> 8;
218
252
  const bg = (255 - dg) * (sg * dg >> 8) + dg * (255 - ((255 - sg) * (255 - dg) >> 8)) >> 8;
219
253
  const bb = (255 - db) * (sb * db >> 8) + db * (255 - ((255 - sb) * (255 - db) >> 8)) >> 8;
@@ -225,11 +259,11 @@ var softLightColor32 = (src, dst) => {
225
259
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
226
260
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
227
261
  };
228
- var hardLightColor32 = (src, dst) => {
262
+ var hardLightFast = (src, dst) => {
229
263
  const sa = src >>> 24 & 255;
230
264
  if (sa === 0) return dst;
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;
265
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
266
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
233
267
  const br = sr < 128 ? 2 * sr * dr >> 8 : 255 - (2 * (255 - sr) * (255 - dr) >> 8);
234
268
  const bg = sg < 128 ? 2 * sg * dg >> 8 : 255 - (2 * (255 - sg) * (255 - dg) >> 8);
235
269
  const bb = sb < 128 ? 2 * sb * db >> 8 : 255 - (2 * (255 - sb) * (255 - db) >> 8);
@@ -241,14 +275,14 @@ var hardLightColor32 = (src, dst) => {
241
275
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
242
276
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
243
277
  };
244
- var vividLightColor32 = (src, dst) => {
278
+ var vividLightFast = (src, dst) => {
245
279
  const sa = src >>> 24 & 255;
246
280
  if (sa === 0) return dst;
247
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
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)));
281
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
282
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
283
+ const br = sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - (255 - dr << 8) / (2 * sr) | 0) : sr === 255 ? 255 : Math.min(255, (dr << 8) / (2 * (255 - sr)) | 0);
284
+ const bg = sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - (255 - dg << 8) / (2 * sg) | 0) : sg === 255 ? 255 : Math.min(255, (dg << 8) / (2 * (255 - sg)) | 0);
285
+ const bb = sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - (255 - db << 8) / (2 * sb) | 0) : sb === 255 ? 255 : Math.min(255, (db << 8) / (2 * (255 - sb)) | 0);
252
286
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
253
287
  const invA = 255 - sa;
254
288
  const r = br * sa + dr * invA >> 8;
@@ -257,14 +291,17 @@ var vividLightColor32 = (src, dst) => {
257
291
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
258
292
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
259
293
  };
260
- var linearLightColor32 = (src, dst) => {
294
+ var linearLightFast = (src, dst) => {
261
295
  const sa = src >>> 24 & 255;
262
296
  if (sa === 0) return dst;
263
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
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));
297
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
298
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
299
+ const brU = dr + 2 * sr - 255;
300
+ const bgU = dg + 2 * sg - 255;
301
+ const bbU = db + 2 * sb - 255;
302
+ const br = brU < 0 ? 0 : brU > 255 ? 255 : brU;
303
+ const bg = bgU < 0 ? 0 : bgU > 255 ? 255 : bgU;
304
+ const bb = bbU < 0 ? 0 : bbU > 255 ? 255 : bbU;
268
305
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
269
306
  const invA = 255 - sa;
270
307
  const r = br * sa + dr * invA >> 8;
@@ -273,14 +310,14 @@ var linearLightColor32 = (src, dst) => {
273
310
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
274
311
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
275
312
  };
276
- var pinLightColor32 = (src, dst) => {
313
+ var pinLightFast = (src, dst) => {
277
314
  const sa = src >>> 24 & 255;
278
315
  if (sa === 0) return dst;
279
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
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));
316
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
317
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
318
+ const br = sr < 128 ? dr < 2 * sr ? dr : 2 * sr : dr > 2 * sr - 256 ? dr : 2 * sr - 256;
319
+ const bg = sg < 128 ? dg < 2 * sg ? dg : 2 * sg : dg > 2 * sg - 256 ? dg : 2 * sg - 256;
320
+ const bb = sb < 128 ? db < 2 * sb ? db : 2 * sb : db > 2 * sb - 256 ? db : 2 * sb - 256;
284
321
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
285
322
  const invA = 255 - sa;
286
323
  const r = br * sa + dr * invA >> 8;
@@ -289,14 +326,14 @@ var pinLightColor32 = (src, dst) => {
289
326
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
290
327
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
291
328
  };
292
- var hardMixColor32 = (src, dst) => {
329
+ var hardMixFast = (src, dst) => {
293
330
  const sa = src >>> 24 & 255;
294
331
  if (sa === 0) return dst;
295
- const dr = dst & 255, dg = dst >> 8 & 255, db = dst >> 16 & 255;
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;
332
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
333
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
334
+ const br = (sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - (255 - dr << 8) / (2 * sr) | 0) : sr === 255 ? 255 : Math.min(255, (dr << 8) / (2 * (255 - sr)) | 0)) < 128 ? 0 : 255;
335
+ const bg = (sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - (255 - dg << 8) / (2 * sg) | 0) : sg === 255 ? 255 : Math.min(255, (dg << 8) / (2 * (255 - sg)) | 0)) < 128 ? 0 : 255;
336
+ const bb = (sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - (255 - db << 8) / (2 * sb) | 0) : sb === 255 ? 255 : Math.min(255, (db << 8) / (2 * (255 - sb)) | 0)) < 128 ? 0 : 255;
300
337
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
301
338
  const invA = 255 - sa;
302
339
  const r = br * sa + dr * invA >> 8;
@@ -305,13 +342,16 @@ var hardMixColor32 = (src, dst) => {
305
342
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
306
343
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
307
344
  };
308
- var differenceColor32 = (src, dst) => {
345
+ var differenceFast = (src, dst) => {
309
346
  const sa = src >>> 24 & 255;
310
347
  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);
348
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
349
+ const brD = (src & 255) - dr;
350
+ const bgD = (src >>> 8 & 255) - dg;
351
+ const bbD = (src >>> 16 & 255) - db;
352
+ const br = brD < 0 ? -brD : brD;
353
+ const bg = bgD < 0 ? -bgD : bgD;
354
+ const bb = bbD < 0 ? -bbD : bbD;
315
355
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
316
356
  const invA = 255 - sa;
317
357
  const r = br * sa + dr * invA >> 8;
@@ -320,11 +360,11 @@ var differenceColor32 = (src, dst) => {
320
360
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
321
361
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
322
362
  };
323
- var exclusionColor32 = (src, dst) => {
363
+ var exclusionFast = (src, dst) => {
324
364
  const sa = src >>> 24 & 255;
325
365
  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;
366
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
367
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
328
368
  const br = dr + sr - (dr * sr >> 7);
329
369
  const bg = dg + sg - (dg * sg >> 7);
330
370
  const bb = db + sb - (db * sb >> 7);
@@ -336,14 +376,17 @@ var exclusionColor32 = (src, dst) => {
336
376
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
337
377
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
338
378
  };
339
- var subtractColor32 = (src, dst) => {
379
+ var subtractFast = (src, dst) => {
340
380
  const sa = src >>> 24 & 255;
341
381
  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);
382
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
383
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
384
+ const brU = dr - sr;
385
+ const bgU = dg - sg;
386
+ const bbU = db - sb;
387
+ const br = brU < 0 ? 0 : brU;
388
+ const bg = bgU < 0 ? 0 : bgU;
389
+ const bb = bbU < 0 ? 0 : bbU;
347
390
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
348
391
  const invA = 255 - sa;
349
392
  const r = br * sa + dr * invA >> 8;
@@ -352,14 +395,14 @@ var subtractColor32 = (src, dst) => {
352
395
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
353
396
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
354
397
  };
355
- var divideColor32 = (src, dst) => {
398
+ var divideFast = (src, dst) => {
356
399
  const sa = src >>> 24 & 255;
357
400
  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);
401
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
402
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
403
+ const br = sr === 0 ? 255 : Math.min(255, (dr << 8) / sr | 0);
404
+ const bg = sg === 0 ? 255 : Math.min(255, (dg << 8) / sg | 0);
405
+ const bb = sb === 0 ? 255 : Math.min(255, (db << 8) / sb | 0);
363
406
  if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
364
407
  const invA = 255 - sa;
365
408
  const r = br * sa + dr * invA >> 8;
@@ -368,77 +411,76 @@ var divideColor32 = (src, dst) => {
368
411
  const a = 255 * sa + (dst >>> 24 & 255) * invA >> 8;
369
412
  return (a << 24 | b << 16 | g << 8 | r) >>> 0;
370
413
  };
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]
414
+ var FAST_BLENDER_REGISTRY = [
415
+ [0 /* overwrite */, overwriteFast],
416
+ [1 /* sourceOver */, sourceOverFast],
417
+ [2 /* darken */, darkenFast],
418
+ [3 /* multiply */, multiplyFast],
419
+ [4 /* colorBurn */, colorBurnFast],
420
+ [5 /* linearBurn */, linearBurnFast],
421
+ [6 /* darkerColor */, darkerFast],
422
+ [7 /* lighten */, lightenFast],
423
+ [8 /* screen */, screenFast],
424
+ [9 /* colorDodge */, colorDodgeFast],
425
+ [10 /* linearDodge */, linearDodgeFast],
426
+ [11 /* lighterColor */, lighterFast],
427
+ [12 /* overlay */, overlayFast],
428
+ [13 /* softLight */, softLightFast],
429
+ [14 /* hardLight */, hardLightFast],
430
+ [15 /* vividLight */, vividLightFast],
431
+ [16 /* linearLight */, linearLightFast],
432
+ [17 /* pinLight */, pinLightFast],
433
+ [18 /* hardMix */, hardMixFast],
434
+ [19 /* difference */, differenceFast],
435
+ [20 /* exclusion */, exclusionFast],
436
+ [21 /* subtract */, subtractFast],
437
+ [22 /* divide */, divideFast]
421
438
  ];
422
- var COLOR_32_BLEND_MODES = [];
423
- for (const [index, blend] of BLENDER_REGISTRY) {
424
- COLOR_32_BLEND_MODES[index] = blend;
439
+ var FAST_BLEND_MODES = [];
440
+ for (const [index, blend] of FAST_BLENDER_REGISTRY) {
441
+ FAST_BLEND_MODES[index] = blend;
425
442
  }
426
- var COLOR_32_BLEND_TO_INDEX = new Map(
427
- BLENDER_REGISTRY.map((entry, index) => {
443
+ var FAST_BLEND_TO_INDEX = new Map(
444
+ FAST_BLENDER_REGISTRY.map((entry, index) => {
428
445
  return [
429
446
  entry[1],
430
447
  index
431
448
  ];
432
449
  })
433
450
  );
434
- var INDEX_TO_COLOR_32_BLEND = new Map(
435
- BLENDER_REGISTRY.map((entry, index) => {
451
+ var INDEX_TO_FAST_BLEND = new Map(
452
+ FAST_BLENDER_REGISTRY.map((entry, index) => {
436
453
  return [
437
454
  index,
438
455
  entry[1]
439
456
  ];
440
457
  })
441
458
  );
459
+ var FAST_BLEND_MODE_BY_NAME = {
460
+ overwrite: overwriteFast,
461
+ sourceOver: sourceOverFast,
462
+ darken: darkenFast,
463
+ multiply: multiplyFast,
464
+ colorBurn: colorBurnFast,
465
+ linearBurn: linearBurnFast,
466
+ darkerColor: darkerFast,
467
+ lighten: lightenFast,
468
+ screen: screenFast,
469
+ colorDodge: colorDodgeFast,
470
+ linearDodge: linearDodgeFast,
471
+ lighterColor: lighterFast,
472
+ overlay: overlayFast,
473
+ softLight: softLightFast,
474
+ hardLight: hardLightFast,
475
+ vividLight: vividLightFast,
476
+ linearLight: linearLightFast,
477
+ pinLight: pinLightFast,
478
+ hardMix: hardMixFast,
479
+ difference: differenceFast,
480
+ exclusion: exclusionFast,
481
+ subtract: subtractFast,
482
+ divide: divideFast
483
+ };
442
484
 
443
485
  // src/_types.ts
444
486
  var MaskType = /* @__PURE__ */ ((MaskType2) => {
@@ -799,6 +841,477 @@ function floodFillSelection(img, startX, startY, {
799
841
  };
800
842
  }
801
843
 
844
+ // src/BlendModes/blend-modes-perfect.ts
845
+ var overwritePerfect = (src, _dst) => src;
846
+ var sourceOverPerfect = (src, dst) => {
847
+ const sa = src >>> 24 & 255;
848
+ if (sa === 255) return src;
849
+ if (sa === 0) return dst;
850
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
851
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
852
+ const da = dst >>> 24 & 255;
853
+ const invA = 255 - sa;
854
+ const r = (sr * sa + dr * invA) / 255 | 0;
855
+ const g = (sg * sa + dg * invA) / 255 | 0;
856
+ const b = (sb * sa + db * invA) / 255 | 0;
857
+ const a = (255 * sa + da * invA) / 255 | 0;
858
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
859
+ };
860
+ var darkenPerfect = (src, dst) => {
861
+ const sa = src >>> 24 & 255;
862
+ if (sa === 0) return dst;
863
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
864
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
865
+ const br = sr < dr ? sr : dr;
866
+ const bg = sg < dg ? sg : dg;
867
+ const bb = sb < db ? sb : db;
868
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
869
+ const invA = 255 - sa;
870
+ const r = (br * sa + dr * invA) / 255 | 0;
871
+ const g = (bg * sa + dg * invA) / 255 | 0;
872
+ const b = (bb * sa + db * invA) / 255 | 0;
873
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
874
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
875
+ };
876
+ var multiplyPerfect = (src, dst) => {
877
+ const sa = src >>> 24 & 255;
878
+ if (sa === 0) return dst;
879
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
880
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
881
+ const br = sr * dr / 255 | 0;
882
+ const bg = sg * dg / 255 | 0;
883
+ const bb = sb * db / 255 | 0;
884
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
885
+ const invA = 255 - sa;
886
+ const da = dst >>> 24 & 255;
887
+ const r = (br * sa + dr * invA) / 255 | 0;
888
+ const g = (bg * sa + dg * invA) / 255 | 0;
889
+ const b = (bb * sa + db * invA) / 255 | 0;
890
+ const a = (255 * sa + da * invA) / 255 | 0;
891
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
892
+ };
893
+ var colorBurnPerfect = (src, dst) => {
894
+ const sa = src >>> 24 & 255;
895
+ if (sa === 0) return dst;
896
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
897
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
898
+ const br = dr === 255 ? 255 : sr === 0 ? 0 : Math.max(0, 255 - ((255 - dr) * 255 / sr | 0));
899
+ const bg = dg === 255 ? 255 : sg === 0 ? 0 : Math.max(0, 255 - ((255 - dg) * 255 / sg | 0));
900
+ const bb = db === 255 ? 255 : sb === 0 ? 0 : Math.max(0, 255 - ((255 - db) * 255 / sb | 0));
901
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
902
+ const invA = 255 - sa;
903
+ const da = dst >>> 24 & 255;
904
+ const r = (br * sa + dr * invA) / 255 | 0;
905
+ const g = (bg * sa + dg * invA) / 255 | 0;
906
+ const b = (bb * sa + db * invA) / 255 | 0;
907
+ const a = (255 * sa + da * invA) / 255 | 0;
908
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
909
+ };
910
+ var linearBurnPerfect = (src, dst) => {
911
+ const sa = src >>> 24 & 255;
912
+ if (sa === 0) return dst;
913
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
914
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
915
+ const brU = dr + sr - 255;
916
+ const br = brU < 0 ? 0 : brU;
917
+ const bgU = dg + sg - 255;
918
+ const bg = bgU < 0 ? 0 : bgU;
919
+ const bbU = db + sb - 255;
920
+ const bb = bbU < 0 ? 0 : bbU;
921
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
922
+ const invA = 255 - sa;
923
+ const r = (br * sa + dr * invA) / 255 | 0;
924
+ const g = (bg * sa + dg * invA) / 255 | 0;
925
+ const b = (bb * sa + db * invA) / 255 | 0;
926
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
927
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
928
+ };
929
+ var darkerPerfect = (src, dst) => {
930
+ const sa = src >>> 24 & 255;
931
+ if (sa === 0) return dst;
932
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
933
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
934
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
935
+ const lumDst = dr * 77 + dg * 151 + db * 28;
936
+ let br, bg, bb;
937
+ if (lumSrc < lumDst) {
938
+ br = sr;
939
+ bg = sg;
940
+ bb = sb;
941
+ } else {
942
+ br = dr;
943
+ bg = dg;
944
+ bb = db;
945
+ }
946
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
947
+ const invA = 255 - sa;
948
+ const r = (br * sa + dr * invA) / 255 | 0;
949
+ const g = (bg * sa + dg * invA) / 255 | 0;
950
+ const b = (bb * sa + db * invA) / 255 | 0;
951
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
952
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
953
+ };
954
+ var lightenPerfect = (src, dst) => {
955
+ const sa = src >>> 24 & 255;
956
+ if (sa === 0) return dst;
957
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
958
+ const br = (src & 255) > dr ? src & 255 : dr;
959
+ const bg = (src >>> 8 & 255) > dg ? src >>> 8 & 255 : dg;
960
+ const bb = (src >>> 16 & 255) > db ? src >>> 16 & 255 : db;
961
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
962
+ const invA = 255 - sa;
963
+ const r = (br * sa + dr * invA) / 255 | 0;
964
+ const g = (bg * sa + dg * invA) / 255 | 0;
965
+ const b = (bb * sa + db * invA) / 255 | 0;
966
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
967
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
968
+ };
969
+ var screenPerfect = (src, dst) => {
970
+ const sa = src >>> 24 & 255;
971
+ if (sa === 0) return dst;
972
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
973
+ const br = 255 - ((255 - (src & 255)) * (255 - dr) / 255 | 0);
974
+ const bg = 255 - ((255 - (src >>> 8 & 255)) * (255 - dg) / 255 | 0);
975
+ const bb = 255 - ((255 - (src >>> 16 & 255)) * (255 - db) / 255 | 0);
976
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
977
+ const invA = 255 - sa;
978
+ const r = (br * sa + dr * invA) / 255 | 0;
979
+ const g = (bg * sa + dg * invA) / 255 | 0;
980
+ const b = (bb * sa + db * invA) / 255 | 0;
981
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
982
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
983
+ };
984
+ var colorDodgePerfect = (src, dst) => {
985
+ const sa = src >>> 24 & 255;
986
+ if (sa === 0) return dst;
987
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
988
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
989
+ const br = sr === 255 ? 255 : Math.min(255, dr * 255 / (255 - sr) | 0);
990
+ const bg = sg === 255 ? 255 : Math.min(255, dg * 255 / (255 - sg) | 0);
991
+ const bb = sb === 255 ? 255 : Math.min(255, db * 255 / (255 - sb) | 0);
992
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
993
+ const invA = 255 - sa;
994
+ const r = (br * sa + dr * invA) / 255 | 0;
995
+ const g = (bg * sa + dg * invA) / 255 | 0;
996
+ const b = (bb * sa + db * invA) / 255 | 0;
997
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
998
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
999
+ };
1000
+ var linearDodgePerfect = (src, dst) => {
1001
+ const sa = src >>> 24 & 255;
1002
+ if (sa === 0) return dst;
1003
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1004
+ const brU = (src & 255) + dr;
1005
+ const br = brU > 255 ? 255 : brU;
1006
+ const bgU = (src >>> 8 & 255) + dg;
1007
+ const bg = bgU > 255 ? 255 : bgU;
1008
+ const bbU = (src >>> 16 & 255) + db;
1009
+ const bb = bbU > 255 ? 255 : bbU;
1010
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1011
+ const invA = 255 - sa;
1012
+ const r = (br * sa + dr * invA) / 255 | 0;
1013
+ const g = (bg * sa + dg * invA) / 255 | 0;
1014
+ const b = (bb * sa + db * invA) / 255 | 0;
1015
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1016
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1017
+ };
1018
+ var lighterPerfect = (src, dst) => {
1019
+ const sa = src >>> 24 & 255;
1020
+ if (sa === 0) return dst;
1021
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1022
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1023
+ const lumSrc = sr * 77 + sg * 151 + sb * 28;
1024
+ const lumDst = dr * 77 + dg * 151 + db * 28;
1025
+ let br, bg, bb;
1026
+ if (lumSrc > lumDst) {
1027
+ br = sr;
1028
+ bg = sg;
1029
+ bb = sb;
1030
+ } else {
1031
+ br = dr;
1032
+ bg = dg;
1033
+ bb = db;
1034
+ }
1035
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1036
+ const invA = 255 - sa;
1037
+ const r = (br * sa + dr * invA) / 255 | 0;
1038
+ const g = (bg * sa + dg * invA) / 255 | 0;
1039
+ const b = (bb * sa + db * invA) / 255 | 0;
1040
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1041
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1042
+ };
1043
+ var overlayPerfect = (src, dst) => {
1044
+ const sa = src >>> 24 & 255;
1045
+ if (sa === 0) return dst;
1046
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1047
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1048
+ const br = dr < 128 ? 2 * sr * dr / 255 | 0 : 255 - (2 * (255 - sr) * (255 - dr) / 255 | 0);
1049
+ const bg = dg < 128 ? 2 * sg * dg / 255 | 0 : 255 - (2 * (255 - sg) * (255 - dg) / 255 | 0);
1050
+ const bb = db < 128 ? 2 * sb * db / 255 | 0 : 255 - (2 * (255 - sb) * (255 - db) / 255 | 0);
1051
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1052
+ const invA = 255 - sa;
1053
+ const r = (br * sa + dr * invA) / 255 | 0;
1054
+ const g = (bg * sa + dg * invA) / 255 | 0;
1055
+ const b = (bb * sa + db * invA) / 255 | 0;
1056
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1057
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1058
+ };
1059
+ var softLightPerfect = (src, dst) => {
1060
+ const sa = src >>> 24 & 255;
1061
+ if (sa === 0) return dst;
1062
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1063
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1064
+ const br = ((255 - dr) * (sr * dr / 255 | 0) + dr * (255 - ((255 - sr) * (255 - dr) / 255 | 0))) / 255 | 0;
1065
+ const bg = ((255 - dg) * (sg * dg / 255 | 0) + dg * (255 - ((255 - sg) * (255 - dg) / 255 | 0))) / 255 | 0;
1066
+ const bb = ((255 - db) * (sb * db / 255 | 0) + db * (255 - ((255 - sb) * (255 - db) / 255 | 0))) / 255 | 0;
1067
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1068
+ const invA = 255 - sa;
1069
+ const r = (br * sa + dr * invA) / 255 | 0;
1070
+ const g = (bg * sa + dg * invA) / 255 | 0;
1071
+ const b = (bb * sa + db * invA) / 255 | 0;
1072
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1073
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1074
+ };
1075
+ var hardLightPerfect = (src, dst) => {
1076
+ const sa = src >>> 24 & 255;
1077
+ if (sa === 0) return dst;
1078
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1079
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1080
+ const br = sr < 128 ? 2 * sr * dr / 255 | 0 : 255 - (2 * (255 - sr) * (255 - dr) / 255 | 0);
1081
+ const bg = sg < 128 ? 2 * sg * dg / 255 | 0 : 255 - (2 * (255 - sg) * (255 - dg) / 255 | 0);
1082
+ const bb = sb < 128 ? 2 * sb * db / 255 | 0 : 255 - (2 * (255 - sb) * (255 - db) / 255 | 0);
1083
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1084
+ const invA = 255 - sa;
1085
+ const r = (br * sa + dr * invA) / 255 | 0;
1086
+ const g = (bg * sa + dg * invA) / 255 | 0;
1087
+ const b = (bb * sa + db * invA) / 255 | 0;
1088
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1089
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1090
+ };
1091
+ var vividLightPerfect = (src, dst) => {
1092
+ const sa = src >>> 24 & 255;
1093
+ if (sa === 0) return dst;
1094
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1095
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1096
+ const br = sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - ((255 - dr) * 255 / (2 * sr) | 0)) : sr === 255 ? 255 : Math.min(255, dr * 255 / (2 * (255 - sr)) | 0);
1097
+ const bg = sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - ((255 - dg) * 255 / (2 * sg) | 0)) : sg === 255 ? 255 : Math.min(255, dg * 255 / (2 * (255 - sg)) | 0);
1098
+ const bb = sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - ((255 - db) * 255 / (2 * sb) | 0)) : sb === 255 ? 255 : Math.min(255, db * 255 / (2 * (255 - sb)) | 0);
1099
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1100
+ const invA = 255 - sa;
1101
+ const r = (br * sa + dr * invA) / 255 | 0;
1102
+ const g = (bg * sa + dg * invA) / 255 | 0;
1103
+ const b = (bb * sa + db * invA) / 255 | 0;
1104
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1105
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1106
+ };
1107
+ var linearLightPerfect = (src, dst) => {
1108
+ const sa = src >>> 24 & 255;
1109
+ if (sa === 0) return dst;
1110
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1111
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1112
+ const brU = dr + 2 * sr - 255;
1113
+ const br = brU < 0 ? 0 : brU > 255 ? 255 : brU;
1114
+ const bgU = dg + 2 * sg - 255;
1115
+ const bg = bgU < 0 ? 0 : bgU > 255 ? 255 : bgU;
1116
+ const bbU = db + 2 * sb - 255;
1117
+ const bb = bbU < 0 ? 0 : bbU > 255 ? 255 : bbU;
1118
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1119
+ const invA = 255 - sa;
1120
+ const r = (br * sa + dr * invA) / 255 | 0;
1121
+ const g = (bg * sa + dg * invA) / 255 | 0;
1122
+ const b = (bb * sa + db * invA) / 255 | 0;
1123
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1124
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1125
+ };
1126
+ var pinLightPerfect = (src, dst) => {
1127
+ const sa = src >>> 24 & 255;
1128
+ if (sa === 0) return dst;
1129
+ const dr = dst & 255;
1130
+ const dg = dst >>> 8 & 255;
1131
+ const db = dst >>> 16 & 255;
1132
+ const sr = src & 255;
1133
+ const sg = src >>> 8 & 255;
1134
+ const sb = src >>> 16 & 255;
1135
+ const br = sr < 128 ? dr < sr << 1 ? dr : sr << 1 : dr > sr - 128 << 1 ? dr : sr - 128 << 1;
1136
+ const bg = sg < 128 ? dg < sg << 1 ? dg : sg << 1 : dg > sg - 128 << 1 ? dg : sg - 128 << 1;
1137
+ const bb = sb < 128 ? db < sb << 1 ? db : sb << 1 : db > sb - 128 << 1 ? db : sb - 128 << 1;
1138
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1139
+ const invA = 255 - sa;
1140
+ const da = dst >>> 24 & 255;
1141
+ const r = (br * sa + dr * invA + 128) / 255 | 0;
1142
+ const g = (bg * sa + dg * invA + 128) / 255 | 0;
1143
+ const b = (bb * sa + db * invA + 128) / 255 | 0;
1144
+ const a = (255 * sa + da * invA + 128) / 255 | 0;
1145
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1146
+ };
1147
+ var hardMixPerfect = (src, dst) => {
1148
+ const sa = src >>> 24 & 255;
1149
+ if (sa === 0) return dst;
1150
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1151
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1152
+ const br = (sr < 128 ? sr === 0 ? 0 : Math.max(0, 255 - ((255 - dr) * 255 / (2 * sr) | 0)) : sr === 255 ? 255 : Math.min(255, dr * 255 / (2 * (255 - sr)) | 0)) < 128 ? 0 : 255;
1153
+ const bg = (sg < 128 ? sg === 0 ? 0 : Math.max(0, 255 - ((255 - dg) * 255 / (2 * sg) | 0)) : sg === 255 ? 255 : Math.min(255, dg * 255 / (2 * (255 - sg)) | 0)) < 128 ? 0 : 255;
1154
+ const bb = (sb < 128 ? sb === 0 ? 0 : Math.max(0, 255 - ((255 - db) * 255 / (2 * sb) | 0)) : sb === 255 ? 255 : Math.min(255, db * 255 / (2 * (255 - sb)) | 0)) < 128 ? 0 : 255;
1155
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1156
+ const invA = 255 - sa;
1157
+ const r = (br * sa + dr * invA) / 255 | 0;
1158
+ const g = (bg * sa + dg * invA) / 255 | 0;
1159
+ const b = (bb * sa + db * invA) / 255 | 0;
1160
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1161
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1162
+ };
1163
+ var differencePerfect = (src, dst) => {
1164
+ const sa = src >>> 24 & 255;
1165
+ if (sa === 0) return dst;
1166
+ const dr = dst & 255;
1167
+ const dg = dst >>> 8 & 255;
1168
+ const db = dst >>> 16 & 255;
1169
+ const sr = src & 255;
1170
+ const sg = src >>> 8 & 255;
1171
+ const sb = src >>> 16 & 255;
1172
+ const br = Math.abs(dr - sr);
1173
+ const bg = Math.abs(dg - sg);
1174
+ const bb = Math.abs(db - sb);
1175
+ if (sa === 255) {
1176
+ return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1177
+ }
1178
+ const invA = 255 - sa;
1179
+ const da = dst >>> 24 & 255;
1180
+ const r = (br * sa + dr * invA + 128) / 255 | 0;
1181
+ const g = (bg * sa + dg * invA + 128) / 255 | 0;
1182
+ const b = (bb * sa + db * invA + 128) / 255 | 0;
1183
+ const a = (255 * sa + da * invA + 128) / 255 | 0;
1184
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1185
+ };
1186
+ var exclusionPerfect = (src, dst) => {
1187
+ const sa = src >>> 24 & 255;
1188
+ if (sa === 0) return dst;
1189
+ const dr = dst & 255;
1190
+ const dg = dst >>> 8 & 255;
1191
+ const db = dst >>> 16 & 255;
1192
+ const sr = src & 255;
1193
+ const sg = src >>> 8 & 255;
1194
+ const sb = src >>> 16 & 255;
1195
+ const br = dr + sr - (dr * sr >> 7);
1196
+ const bg = dg + sg - (dg * sg >> 7);
1197
+ const bb = db + sb - (db * sb >> 7);
1198
+ if (sa === 255) {
1199
+ return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1200
+ }
1201
+ const invA = 255 - sa;
1202
+ const da = dst >>> 24 & 255;
1203
+ const r = (br * sa + dr * invA) / 255 | 0;
1204
+ const g = (bg * sa + dg * invA) / 255 | 0;
1205
+ const b = (bb * sa + db * invA) / 255 | 0;
1206
+ const a = (255 * sa + da * invA) / 255 | 0;
1207
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1208
+ };
1209
+ var subtractPerfect = (src, dst) => {
1210
+ const sa = src >>> 24 & 255;
1211
+ if (sa === 0) return dst;
1212
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1213
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1214
+ const brU = dr - sr;
1215
+ const br = brU < 0 ? 0 : brU;
1216
+ const bgU = dg - sg;
1217
+ const bg = bgU < 0 ? 0 : bgU;
1218
+ const bbU = db - sb;
1219
+ const bb = bbU < 0 ? 0 : bbU;
1220
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1221
+ const invA = 255 - sa;
1222
+ const r = (br * sa + dr * invA) / 255 | 0;
1223
+ const g = (bg * sa + dg * invA) / 255 | 0;
1224
+ const b = (bb * sa + db * invA) / 255 | 0;
1225
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1226
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1227
+ };
1228
+ var dividePerfect = (src, dst) => {
1229
+ const sa = src >>> 24 & 255;
1230
+ if (sa === 0) return dst;
1231
+ const dr = dst & 255, dg = dst >>> 8 & 255, db = dst >>> 16 & 255;
1232
+ const sr = src & 255, sg = src >>> 8 & 255, sb = src >>> 16 & 255;
1233
+ const br = sr === 0 ? 255 : Math.min(255, dr * 255 / sr | 0);
1234
+ const bg = sg === 0 ? 255 : Math.min(255, dg * 255 / sg | 0);
1235
+ const bb = sb === 0 ? 255 : Math.min(255, db * 255 / sb | 0);
1236
+ if (sa === 255) return (4278190080 | bb << 16 | bg << 8 | br) >>> 0;
1237
+ const invA = 255 - sa;
1238
+ const r = (br * sa + dr * invA) / 255 | 0;
1239
+ const g = (bg * sa + dg * invA) / 255 | 0;
1240
+ const b = (bb * sa + db * invA) / 255 | 0;
1241
+ const a = (255 * sa + (dst >>> 24 & 255) * invA) / 255 | 0;
1242
+ return (a << 24 | b << 16 | g << 8 | r) >>> 0;
1243
+ };
1244
+ var PERFECT_BLENDER_REGISTRY = [
1245
+ [0 /* overwrite */, overwritePerfect],
1246
+ [1 /* sourceOver */, sourceOverPerfect],
1247
+ [2 /* darken */, darkenPerfect],
1248
+ [3 /* multiply */, multiplyPerfect],
1249
+ [4 /* colorBurn */, colorBurnPerfect],
1250
+ [5 /* linearBurn */, linearBurnPerfect],
1251
+ [6 /* darkerColor */, darkerPerfect],
1252
+ [7 /* lighten */, lightenPerfect],
1253
+ [8 /* screen */, screenPerfect],
1254
+ [9 /* colorDodge */, colorDodgePerfect],
1255
+ [10 /* linearDodge */, linearDodgePerfect],
1256
+ [11 /* lighterColor */, lighterPerfect],
1257
+ [12 /* overlay */, overlayPerfect],
1258
+ [13 /* softLight */, softLightPerfect],
1259
+ [14 /* hardLight */, hardLightPerfect],
1260
+ [15 /* vividLight */, vividLightPerfect],
1261
+ [16 /* linearLight */, linearLightPerfect],
1262
+ [17 /* pinLight */, pinLightPerfect],
1263
+ [18 /* hardMix */, hardMixPerfect],
1264
+ [19 /* difference */, differencePerfect],
1265
+ [20 /* exclusion */, exclusionPerfect],
1266
+ [21 /* subtract */, subtractPerfect],
1267
+ [22 /* divide */, dividePerfect]
1268
+ ];
1269
+ var PERFECT_BLEND_MODES = [];
1270
+ for (const [index, blend] of PERFECT_BLENDER_REGISTRY) {
1271
+ PERFECT_BLEND_MODES[index] = blend;
1272
+ }
1273
+ var PERFECT_BLEND_TO_INDEX = new Map(
1274
+ PERFECT_BLENDER_REGISTRY.map((entry, index) => {
1275
+ return [
1276
+ entry[1],
1277
+ index
1278
+ ];
1279
+ })
1280
+ );
1281
+ var INDEX_TO_PERFECT_BLEND = new Map(
1282
+ PERFECT_BLENDER_REGISTRY.map((entry, index) => {
1283
+ return [
1284
+ index,
1285
+ entry[1]
1286
+ ];
1287
+ })
1288
+ );
1289
+ var PERFECT_BLEND_MODE_BY_NAME = {
1290
+ overwrite: overwritePerfect,
1291
+ sourceOver: sourceOverPerfect,
1292
+ darken: darkenPerfect,
1293
+ multiply: multiplyPerfect,
1294
+ colorBurn: colorBurnPerfect,
1295
+ linearBurn: linearBurnPerfect,
1296
+ darkerColor: darkerPerfect,
1297
+ lighten: lightenPerfect,
1298
+ screen: screenPerfect,
1299
+ colorDodge: colorDodgePerfect,
1300
+ linearDodge: linearDodgePerfect,
1301
+ lighterColor: lighterPerfect,
1302
+ overlay: overlayPerfect,
1303
+ softLight: softLightPerfect,
1304
+ hardLight: hardLightPerfect,
1305
+ vividLight: vividLightPerfect,
1306
+ linearLight: linearLightPerfect,
1307
+ pinLight: pinLightPerfect,
1308
+ hardMix: hardMixPerfect,
1309
+ difference: differencePerfect,
1310
+ exclusion: exclusionPerfect,
1311
+ subtract: subtractPerfect,
1312
+ divide: dividePerfect
1313
+ };
1314
+
802
1315
  // src/Canvas/_constants.ts
803
1316
  var OFFSCREEN_CANVAS_CTX_FAILED = "Failed to create OffscreenCanvas context";
804
1317
  var CANVAS_CTX_FAILED = "Failed to create Canvas context";
@@ -1079,40 +1592,27 @@ function writeImageDataPixels(imageData, data, _x, _y, _w, _h) {
1079
1592
  function makeIndexedImage(imageData) {
1080
1593
  const width = imageData.width;
1081
1594
  const height = imageData.height;
1082
- const rawData = imageData.data;
1083
- const indexedData = new Int32Array(rawData.length / 4);
1595
+ const rawData = new Uint32Array(imageData.data.buffer);
1596
+ const indexedData = new Int32Array(rawData.length);
1084
1597
  const colorMap = /* @__PURE__ */ new Map();
1085
1598
  const tempPalette = [];
1086
- const transparentKey = "0,0,0,0";
1599
+ const transparentColor = 0;
1087
1600
  const transparentPalletIndex = 0;
1088
- colorMap.set(transparentKey, transparentPalletIndex);
1089
- tempPalette.push(0);
1090
- tempPalette.push(0);
1091
- tempPalette.push(0);
1092
- tempPalette.push(0);
1093
- for (let i = 0; i < indexedData.length; i++) {
1094
- const r = rawData[i * 4];
1095
- const g = rawData[i * 4 + 1];
1096
- const b = rawData[i * 4 + 2];
1097
- const a = rawData[i * 4 + 3];
1098
- let key;
1099
- if (a === 0) {
1100
- key = transparentKey;
1101
- } else {
1102
- key = `${r},${g},${b},${a}`;
1103
- }
1104
- let id = colorMap.get(key);
1601
+ colorMap.set(transparentColor, transparentPalletIndex);
1602
+ tempPalette.push(transparentColor);
1603
+ for (let i = 0; i < rawData.length; i++) {
1604
+ const pixel = rawData[i];
1605
+ const isTransparent = pixel >>> 24 === 0;
1606
+ const colorKey = isTransparent ? transparentColor : pixel;
1607
+ let id = colorMap.get(colorKey);
1105
1608
  if (id === void 0) {
1106
1609
  id = colorMap.size;
1107
- tempPalette.push(r);
1108
- tempPalette.push(g);
1109
- tempPalette.push(b);
1110
- tempPalette.push(a);
1111
- colorMap.set(key, id);
1610
+ tempPalette.push(colorKey);
1611
+ colorMap.set(colorKey, id);
1112
1612
  }
1113
1613
  indexedData[i] = id;
1114
1614
  }
1115
- const palette = new Uint8Array(tempPalette);
1615
+ const palette = new Int32Array(tempPalette);
1116
1616
  return {
1117
1617
  width,
1118
1618
  height,
@@ -1122,6 +1622,48 @@ function makeIndexedImage(imageData) {
1122
1622
  };
1123
1623
  }
1124
1624
 
1625
+ // src/IndexedImage/indexedImageToAverageColor.ts
1626
+ function indexedImageToAverageColor(indexedImage, includeTransparent = false) {
1627
+ const { data, palette, transparentPalletIndex } = indexedImage;
1628
+ const counts = new Uint32Array(palette.length / 4);
1629
+ for (let i = 0; i < data.length; i++) {
1630
+ const id = data[i];
1631
+ counts[id]++;
1632
+ }
1633
+ let rSum = 0;
1634
+ let gSum = 0;
1635
+ let bSum = 0;
1636
+ let aSum = 0;
1637
+ let totalWeight = 0;
1638
+ for (let id = 0; id < counts.length; id++) {
1639
+ const weight = counts[id];
1640
+ if (weight === 0) {
1641
+ continue;
1642
+ }
1643
+ if (!includeTransparent && id === transparentPalletIndex) {
1644
+ continue;
1645
+ }
1646
+ const pIdx = id * 4;
1647
+ const r2 = palette[pIdx];
1648
+ const g2 = palette[pIdx + 1];
1649
+ const b2 = palette[pIdx + 2];
1650
+ const a2 = palette[pIdx + 3];
1651
+ rSum += r2 * weight;
1652
+ gSum += g2 * weight;
1653
+ bSum += b2 * weight;
1654
+ aSum += a2 * weight;
1655
+ totalWeight += weight;
1656
+ }
1657
+ if (totalWeight === 0) {
1658
+ return packColor(0, 0, 0, 0);
1659
+ }
1660
+ const r = rSum / totalWeight | 0;
1661
+ const g = gSum / totalWeight | 0;
1662
+ const b = bSum / totalWeight | 0;
1663
+ const a = aSum / totalWeight | 0;
1664
+ return packColor(r, g, b, a);
1665
+ }
1666
+
1125
1667
  // src/Input/fileInputChangeToImageData.ts
1126
1668
  async function fileInputChangeToImageData(event) {
1127
1669
  const target = event.target;
@@ -1291,8 +1833,8 @@ function mergeMasks(dst, dstWidth, src, opts) {
1291
1833
  }
1292
1834
  }
1293
1835
 
1294
- // src/PixelData.ts
1295
- var PixelData = class {
1836
+ // src/PixelData/PixelData.ts
1837
+ var PixelData = class _PixelData {
1296
1838
  constructor(imageData) {
1297
1839
  this.imageData = imageData;
1298
1840
  this.width = imageData.width;
@@ -1300,12 +1842,22 @@ var PixelData = class {
1300
1842
  this.data32 = new Uint32Array(
1301
1843
  imageData.data.buffer,
1302
1844
  imageData.data.byteOffset,
1845
+ // Shift right by 2 is a fast bitwise division by 4.
1303
1846
  imageData.data.byteLength >> 2
1304
1847
  );
1305
1848
  }
1306
1849
  data32;
1307
1850
  width;
1308
1851
  height;
1852
+ copy() {
1853
+ const buffer = new Uint8ClampedArray(this.data32.buffer.slice(0));
1854
+ const imageData = {
1855
+ data: buffer,
1856
+ width: this.width,
1857
+ height: this.height
1858
+ };
1859
+ return new _PixelData(imageData);
1860
+ }
1309
1861
  };
1310
1862
 
1311
1863
  // src/PixelData/applyMaskToPixelData.ts
@@ -1403,7 +1955,7 @@ function blendColorPixelData(dst, color, opts) {
1403
1955
  w: width = dst.width,
1404
1956
  h: height = dst.height,
1405
1957
  alpha: globalAlpha = 255,
1406
- blendFn = sourceOverColor32,
1958
+ blendFn = FAST_BLEND_MODES[1 /* sourceOver */],
1407
1959
  mask,
1408
1960
  maskType = 0 /* ALPHA */,
1409
1961
  mw,
@@ -1512,7 +2064,7 @@ function blendPixelData(dst, src, opts) {
1512
2064
  w: width = src.width,
1513
2065
  h: height = src.height,
1514
2066
  alpha: globalAlpha = 255,
1515
- blendFn = sourceOverColor32,
2067
+ blendFn = FAST_BLEND_MODES[1 /* sourceOver */],
1516
2068
  mask,
1517
2069
  maskType = 0 /* ALPHA */,
1518
2070
  mw,
@@ -1702,10 +2254,17 @@ function invertPixelData(pixelData) {
1702
2254
  }
1703
2255
  export {
1704
2256
  BlendMode,
1705
- COLOR_32_BLEND_MODES,
1706
- COLOR_32_BLEND_TO_INDEX,
1707
- INDEX_TO_COLOR_32_BLEND,
2257
+ FAST_BLENDER_REGISTRY,
2258
+ FAST_BLEND_MODES,
2259
+ FAST_BLEND_MODE_BY_NAME,
2260
+ FAST_BLEND_TO_INDEX,
2261
+ INDEX_TO_FAST_BLEND,
2262
+ INDEX_TO_PERFECT_BLEND,
1708
2263
  MaskType,
2264
+ PERFECT_BLENDER_REGISTRY,
2265
+ PERFECT_BLEND_MODES,
2266
+ PERFECT_BLEND_MODE_BY_NAME,
2267
+ PERFECT_BLEND_TO_INDEX,
1709
2268
  PixelData,
1710
2269
  UnsupportedFormatError,
1711
2270
  applyMaskToPixelData,
@@ -1716,20 +2275,27 @@ export {
1716
2275
  clearPixelData,
1717
2276
  color32ToCssRGBA,
1718
2277
  color32ToHex,
1719
- colorBurnColor32,
2278
+ colorBurnFast,
2279
+ colorBurnPerfect,
1720
2280
  colorDistance,
1721
- colorDodgeColor32,
2281
+ colorDodgeFast,
2282
+ colorDodgePerfect,
1722
2283
  copyImageData,
1723
2284
  copyImageDataLike,
1724
2285
  copyMask,
1725
- darkenColor32,
1726
- darkerColor32,
2286
+ darkenFast,
2287
+ darkenPerfect,
2288
+ darkerFast,
2289
+ darkerPerfect,
1727
2290
  deserializeImageData,
1728
2291
  deserializeNullableImageData,
1729
2292
  deserializeRawImageData,
1730
- differenceColor32,
1731
- divideColor32,
1732
- exclusionColor32,
2293
+ differenceFast,
2294
+ differencePerfect,
2295
+ divideFast,
2296
+ dividePerfect,
2297
+ exclusionFast,
2298
+ exclusionPerfect,
1733
2299
  extractImageDataPixels,
1734
2300
  extractMask,
1735
2301
  fileInputChangeToImageData,
@@ -1738,41 +2304,57 @@ export {
1738
2304
  floodFillSelection,
1739
2305
  getImageDataFromClipboard,
1740
2306
  getSupportedPixelFormats,
1741
- hardLightColor32,
1742
- hardMixColor32,
2307
+ hardLightFast,
2308
+ hardLightPerfect,
2309
+ hardMixFast,
2310
+ hardMixPerfect,
1743
2311
  imageDataToAlphaMask,
1744
2312
  imageDataToDataUrl,
1745
2313
  imageDataToImgBlob,
1746
2314
  imgBlobToImageData,
2315
+ indexedImageToAverageColor,
1747
2316
  invertAlphaMask,
1748
2317
  invertBinaryMask,
1749
2318
  invertImageData,
1750
2319
  invertPixelData,
1751
2320
  lerpColor32,
1752
2321
  lerpColor32Fast,
1753
- lightenColor32,
1754
- lighterColor32,
1755
- linearBurnColor32,
1756
- linearDodgeColor32,
1757
- linearLightColor32,
2322
+ lightenFast,
2323
+ lightenPerfect,
2324
+ lighterFast,
2325
+ lighterPerfect,
2326
+ linearBurnFast,
2327
+ linearBurnPerfect,
2328
+ linearDodgeFast,
2329
+ linearDodgePerfect,
2330
+ linearLightFast,
2331
+ linearLightPerfect,
1758
2332
  makeIndexedImage,
1759
2333
  makePixelCanvas,
1760
2334
  makeReusableCanvas,
1761
2335
  mergeMasks,
1762
- multiplyColor32,
1763
- overlayColor32,
1764
- overwriteColor32,
2336
+ multiplyFast,
2337
+ multiplyPerfect,
2338
+ overlayFast,
2339
+ overlayPerfect,
2340
+ overwriteFast,
2341
+ overwritePerfect,
1765
2342
  packColor,
1766
2343
  packRGBA,
1767
- pinLightColor32,
2344
+ pinLightFast,
2345
+ pinLightPerfect,
1768
2346
  pixelDataToAlphaMask,
1769
2347
  resizeImageData,
1770
- screenColor32,
2348
+ screenFast,
2349
+ screenPerfect,
1771
2350
  serializeImageData,
1772
2351
  serializeNullableImageData,
1773
- softLightColor32,
1774
- sourceOverColor32,
1775
- subtractColor32,
2352
+ softLightFast,
2353
+ softLightPerfect,
2354
+ sourceOverFast,
2355
+ sourceOverPerfect,
2356
+ subtractFast,
2357
+ subtractPerfect,
1776
2358
  trimRectBounds,
1777
2359
  unpackAlpha,
1778
2360
  unpackBlue,
@@ -1780,7 +2362,8 @@ export {
1780
2362
  unpackColorTo,
1781
2363
  unpackGreen,
1782
2364
  unpackRed,
1783
- vividLightColor32,
2365
+ vividLightFast,
2366
+ vividLightPerfect,
1784
2367
  writeImageDataPixels,
1785
2368
  writeImageDataToClipboard,
1786
2369
  writeImgBlobToClipboard