imagescript 3.3.0 → 3.4.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.
Files changed (59) hide show
  1. package/README.md +28 -8
  2. package/THIRD_PARTY_NOTICES.md +167 -2
  3. package/dist/animation.d.ts +18 -8
  4. package/dist/animation.js +23 -2
  5. package/dist/codecs/av1/cdef.js +197 -0
  6. package/dist/codecs/av1/data.js +141 -0
  7. package/dist/codecs/av1/decode.js +1769 -0
  8. package/dist/codecs/av1/filmgrain.js +219 -0
  9. package/dist/codecs/av1/frame.js +114 -0
  10. package/dist/codecs/av1/ipred.js +491 -0
  11. package/dist/codecs/av1/itx.js +950 -0
  12. package/dist/codecs/av1/loopfilter.js +149 -0
  13. package/dist/codecs/av1/msac.js +161 -0
  14. package/dist/codecs/av1/obu.js +516 -0
  15. package/dist/codecs/av1/postfilter.js +28 -0
  16. package/dist/codecs/av1/restoration.js +193 -0
  17. package/dist/codecs/av1/tables.js +160 -0
  18. package/dist/codecs/avif.js +581 -0
  19. package/dist/codecs/bmp.js +317 -0
  20. package/dist/codecs/hdr.d.ts +25 -0
  21. package/dist/codecs/hdr.js +201 -0
  22. package/dist/codecs/ico.js +48 -0
  23. package/dist/codecs/jpeg.js +2 -1
  24. package/dist/codecs/jxl/bits.js +126 -0
  25. package/dist/codecs/jxl/blend.js +117 -0
  26. package/dist/codecs/jxl/color.js +116 -0
  27. package/dist/codecs/jxl/dct.js +404 -0
  28. package/dist/codecs/jxl/entropy.js +556 -0
  29. package/dist/codecs/jxl/features.js +325 -0
  30. package/dist/codecs/jxl/filters.js +119 -0
  31. package/dist/codecs/jxl/frame-header.js +195 -0
  32. package/dist/codecs/jxl/frame.js +319 -0
  33. package/dist/codecs/jxl/headers.js +249 -0
  34. package/dist/codecs/jxl/idct.js +484 -0
  35. package/dist/codecs/jxl/modular.js +688 -0
  36. package/dist/codecs/jxl/quant.js +219 -0
  37. package/dist/codecs/jxl/upsample.js +52 -0
  38. package/dist/codecs/jxl/vardct.js +472 -0
  39. package/dist/codecs/jxl.js +89 -0
  40. package/dist/codecs/netpbm.js +239 -0
  41. package/dist/codecs/qoi.js +150 -0
  42. package/dist/codecs/vp8-enc-dsp.js +932 -0
  43. package/dist/codecs/vp8-enc-tables.js +78 -0
  44. package/dist/codecs/vp8-enc.js +1930 -0
  45. package/dist/codecs/webp.js +36 -2
  46. package/dist/image-type.d.ts +15 -1
  47. package/dist/image-type.js +45 -2
  48. package/dist/image.d.ts +47 -6
  49. package/dist/image.js +49 -3
  50. package/dist/index.d.ts +3 -2
  51. package/dist/index.js +2 -2
  52. package/dist/render/hinting.js +26 -18
  53. package/dist/render/layout.js +1 -1
  54. package/dist/render/svg.js +1 -1
  55. package/dist/render/unicode.js +1 -9
  56. package/dist/util/bytes.js +9 -0
  57. package/dist/util/resample.js +4 -2
  58. package/dist/version.js +1 -1
  59. package/package.json +25 -2
@@ -0,0 +1,932 @@
1
+ import { littleEndian } from "../util/alpha.js";
2
+ export const BPS = 32;
3
+ export const Y_OFF = 0, U_OFF = 16, V_OFF = 24;
4
+ export const YUV_SIZE = BPS * 16, PRED_SIZE = 56 * BPS;
5
+ export const I16DC16 = 0, I16TM16 = 16, I16VE16 = 16 * BPS, I16HE16 = 16 * BPS + 16;
6
+ export const C8DC8 = 32 * BPS, C8TM8 = C8DC8 + 16, C8VE8 = 40 * BPS, C8HE8 = C8VE8 + 16;
7
+ export const I4DC4 = 48 * BPS, I4HD4 = I4DC4 + 4 * BPS, I4TMP = I4HD4 + 8;
8
+ export const I16_MODE_OFFSETS = [I16DC16, I16TM16, I16VE16, I16HE16];
9
+ export const UV_MODE_OFFSETS = [C8DC8, C8TM8, C8VE8, C8HE8];
10
+ export const I4_MODE_OFFSETS = [I4DC4, I4DC4 + 4, I4DC4 + 8, I4DC4 + 12, I4DC4 + 16, I4DC4 + 20, I4DC4 + 24, I4DC4 + 28, I4HD4, I4HD4 + 4];
11
+ export const SCAN = [
12
+ 0, 4, 8, 12, 4 * BPS, 4 * BPS + 4, 4 * BPS + 8, 4 * BPS + 12,
13
+ 8 * BPS, 8 * BPS + 4, 8 * BPS + 8, 8 * BPS + 12, 12 * BPS, 12 * BPS + 4, 12 * BPS + 8, 12 * BPS + 12
14
+ ];
15
+ export const SCAN_UV = [0, 4, 4 * BPS, 4 * BPS + 4, 8, 12, 4 * BPS + 8, 4 * BPS + 12];
16
+ export const ZIGZAG = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15];
17
+ const QFIX = 17;
18
+ export const MAX_LEVEL = 2047;
19
+ const clip8 = (v) => v < 0 ? 0 : v > 255 ? 255 : v;
20
+ const GAMMA_TO_LINEAR = new Uint16Array(256), LINEAR_TO_GAMMA = new Int32Array(33);
21
+ for (let v = 0; v <= 255; v++)
22
+ GAMMA_TO_LINEAR[v] = Math.trunc(Math.pow((1 / 255) * v, 0.8) * 4095 + 0.5);
23
+ for (let v = 0; v <= 32; v++)
24
+ LINEAR_TO_GAMMA[v] = Math.trunc(255 * Math.pow((128 / 4095) * v, 1 / 0.8) + 0.5);
25
+ const INV_ALPHA = new Uint32Array(4 * 255 + 1);
26
+ for (let a = 1; a <= 4 * 255; a++)
27
+ INV_ALPHA[a] = Math.floor((1 << 19) / a);
28
+ function linearToGamma(base, shift) {
29
+ const v = base << shift;
30
+ const pos = v >> 9, x = v & 511;
31
+ return (LINEAR_TO_GAMMA[pos + 1] * x + LINEAR_TO_GAMMA[pos] * (512 - x) + 64) >> 7;
32
+ }
33
+ const SUM_TO_GAMMA = new Uint16Array(4 * 4095 + 1);
34
+ for (let v = 0; v < SUM_TO_GAMMA.length; v++)
35
+ SUM_TO_GAMMA[v] = linearToGamma(v, 0);
36
+ const rgbToY = (r, g, b) => (16839 * r + 33059 * g + 6420 * b + 0x8000 + 0x100000) >> 16;
37
+ const clipUV = (uv) => {
38
+ uv = (uv + (1 << 17) + (128 << 18)) >> 18;
39
+ return uv < 0 ? 0 : uv > 255 ? 255 : uv;
40
+ };
41
+ function weighted(rgba, o, step, next, total) {
42
+ const g = GAMMA_TO_LINEAR, a = o + 3 - (o & 3);
43
+ const sum = rgba[a] * g[rgba[o]] + rgba[a + step] * g[rgba[o + step]] + rgba[a + next] * g[rgba[o + next]] + rgba[a + next + step] * g[rgba[o + next + step]];
44
+ return linearToGamma((sum * INV_ALPHA[total]) >>> 17, 0);
45
+ }
46
+ export function rgbaToYUV(rgba, width, height) {
47
+ const uvWidth = (width + 1) >> 1, uvHeight = (height + 1) >> 1;
48
+ const y = new Uint8Array(width * height), u = new Uint8Array(uvWidth * uvHeight), v = new Uint8Array(uvWidth * uvHeight);
49
+ let hasAlpha = false;
50
+ for (let i = 3; i < width * height * 4; i += 4)
51
+ if (rgba[i] !== 255) {
52
+ hasAlpha = true;
53
+ break;
54
+ }
55
+ const a = hasAlpha ? new Uint8Array(width * height) : null;
56
+ const stride = width * 4;
57
+ if (a)
58
+ for (let j = 0; j < height; j++)
59
+ alphaRow(rgba, j * stride, a, j * width, width);
60
+ const words = littleEndian && rgba.byteOffset % 4 === 0 ? new Uint32Array(rgba.buffer, rgba.byteOffset, width * height) : null;
61
+ for (let j = 0; j < uvHeight; j++) {
62
+ const row = 2 * j * stride;
63
+ const next = 2 * j + 1 < height ? stride : 0;
64
+ let alphaRows = false;
65
+ if (a)
66
+ for (let i = row + 3; i < row + next + stride; i += 4)
67
+ if (rgba[i] !== 255) {
68
+ alphaRows = true;
69
+ break;
70
+ }
71
+ if (words && !alphaRows) {
72
+ pairRow(words, 2 * j * width, next >> 2, y, u, v, j * uvWidth, width);
73
+ continue;
74
+ }
75
+ lumaRow(rgba, row, y, 2 * j * width, width);
76
+ if (next)
77
+ lumaRow(rgba, row + next, y, (2 * j + 1) * width, width);
78
+ if (alphaRows)
79
+ chromaRowAlpha(rgba, row, next, u, v, j * uvWidth, width);
80
+ else
81
+ chromaRow(rgba, row, next, u, v, j * uvWidth, width);
82
+ }
83
+ const picture = { width, height, y, u, v, a, uvStride: uvWidth };
84
+ if (a)
85
+ cleanupTransparentArea(picture);
86
+ return picture;
87
+ }
88
+ function lumaRow(rgba, s, y, d, width) {
89
+ for (let x = 0; x < width; x++, s += 4)
90
+ y[d + x] = rgbToY(rgba[s], rgba[s + 1], rgba[s + 2]);
91
+ }
92
+ function alphaRow(rgba, s, a, d, width) {
93
+ for (let x = 0; x < width; x++, s += 4)
94
+ a[d + x] = rgba[s + 3];
95
+ }
96
+ function pairRow(words, p, next, y, u, v, d, width) {
97
+ const g = GAMMA_TO_LINEAR, pairs = width >> 1;
98
+ for (let i = 0; i < pairs; i++, p += 2) {
99
+ const p0 = words[p], p1 = words[p + 1], p2 = words[p + next], p3 = words[p + next + 1];
100
+ const r0 = p0 & 255, g0 = p0 >> 8 & 255, b0 = p0 >> 16 & 255, r1 = p1 & 255, g1 = p1 >> 8 & 255, b1 = p1 >> 16 & 255;
101
+ const r2 = p2 & 255, g2 = p2 >> 8 & 255, b2 = p2 >> 16 & 255, r3 = p3 & 255, g3 = p3 >> 8 & 255, b3 = p3 >> 16 & 255;
102
+ y[p] = rgbToY(r0, g0, b0);
103
+ y[p + 1] = rgbToY(r1, g1, b1);
104
+ if (next) {
105
+ y[p + next] = rgbToY(r2, g2, b2);
106
+ y[p + next + 1] = rgbToY(r3, g3, b3);
107
+ }
108
+ const r = SUM_TO_GAMMA[g[r0] + g[r1] + g[r2] + g[r3]];
109
+ const gr = SUM_TO_GAMMA[g[g0] + g[g1] + g[g2] + g[g3]];
110
+ const b = SUM_TO_GAMMA[g[b0] + g[b1] + g[b2] + g[b3]];
111
+ u[d + i] = clipUV(-9719 * r - 19081 * gr + 28800 * b);
112
+ v[d + i] = clipUV(28800 * r - 24116 * gr - 4684 * b);
113
+ }
114
+ if (width & 1) {
115
+ const p0 = words[p], p2 = words[p + next];
116
+ const r0 = p0 & 255, g0 = p0 >> 8 & 255, b0 = p0 >> 16 & 255, r2 = p2 & 255, g2 = p2 >> 8 & 255, b2 = p2 >> 16 & 255;
117
+ y[p] = rgbToY(r0, g0, b0);
118
+ if (next)
119
+ y[p + next] = rgbToY(r2, g2, b2);
120
+ const r = linearToGamma(g[r0] + g[r2], 1), gr = linearToGamma(g[g0] + g[g2], 1), b = linearToGamma(g[b0] + g[b2], 1);
121
+ u[d + pairs] = clipUV(-9719 * r - 19081 * gr + 28800 * b);
122
+ v[d + pairs] = clipUV(28800 * r - 24116 * gr - 4684 * b);
123
+ }
124
+ }
125
+ function chromaRow(rgba, row, next, u, v, d, width) {
126
+ const g = GAMMA_TO_LINEAR, pairs = width >> 1;
127
+ let o = row;
128
+ for (let i = 0; i < pairs; i++, o += 8) {
129
+ const r = linearToGamma(g[rgba[o]] + g[rgba[o + 4]] + g[rgba[o + next]] + g[rgba[o + next + 4]], 0);
130
+ const gr = linearToGamma(g[rgba[o + 1]] + g[rgba[o + 5]] + g[rgba[o + next + 1]] + g[rgba[o + next + 5]], 0);
131
+ const b = linearToGamma(g[rgba[o + 2]] + g[rgba[o + 6]] + g[rgba[o + next + 2]] + g[rgba[o + next + 6]], 0);
132
+ u[d + i] = clipUV(-9719 * r - 19081 * gr + 28800 * b);
133
+ v[d + i] = clipUV(28800 * r - 24116 * gr - 4684 * b);
134
+ }
135
+ if (width & 1) {
136
+ const r = linearToGamma(g[rgba[o]] + g[rgba[o + next]], 1);
137
+ const gr = linearToGamma(g[rgba[o + 1]] + g[rgba[o + next + 1]], 1);
138
+ const b = linearToGamma(g[rgba[o + 2]] + g[rgba[o + next + 2]], 1);
139
+ u[d + pairs] = clipUV(-9719 * r - 19081 * gr + 28800 * b);
140
+ v[d + pairs] = clipUV(28800 * r - 24116 * gr - 4684 * b);
141
+ }
142
+ }
143
+ function chromaRowAlpha(rgba, row, next, u, v, d, width) {
144
+ const g = GAMMA_TO_LINEAR, uvWidth = (width + 1) >> 1;
145
+ for (let i = 0; i < uvWidth; i++) {
146
+ const o = row + 8 * i, pair = 2 * i + 1 < width;
147
+ const step = pair ? 4 : 0;
148
+ let r, gr, b;
149
+ const total = pair ? rgba[o + 3] + rgba[o + 7] + rgba[o + next + 3] + rgba[o + next + 7] : 2 * (rgba[o + 3] + rgba[o + next + 3]);
150
+ if (total === 4 * 255 || total === 0) {
151
+ if (pair) {
152
+ r = linearToGamma(g[rgba[o]] + g[rgba[o + 4]] + g[rgba[o + next]] + g[rgba[o + next + 4]], 0);
153
+ gr = linearToGamma(g[rgba[o + 1]] + g[rgba[o + 5]] + g[rgba[o + next + 1]] + g[rgba[o + next + 5]], 0);
154
+ b = linearToGamma(g[rgba[o + 2]] + g[rgba[o + 6]] + g[rgba[o + next + 2]] + g[rgba[o + next + 6]], 0);
155
+ }
156
+ else {
157
+ r = linearToGamma(g[rgba[o]] + g[rgba[o + next]], 1);
158
+ gr = linearToGamma(g[rgba[o + 1]] + g[rgba[o + next + 1]], 1);
159
+ b = linearToGamma(g[rgba[o + 2]] + g[rgba[o + next + 2]], 1);
160
+ }
161
+ }
162
+ else {
163
+ r = weighted(rgba, o, step, next, total);
164
+ gr = weighted(rgba, o + 1, step, next, total);
165
+ b = weighted(rgba, o + 2, step, next, total);
166
+ }
167
+ u[d + i] = clipUV(-9719 * r - 19081 * gr + 28800 * b);
168
+ v[d + i] = clipUV(28800 * r - 24116 * gr - 4684 * b);
169
+ }
170
+ }
171
+ function smoothenBlock(p, x0, y0, w, h) {
172
+ const a = p.a;
173
+ let sum = 0, count = 0;
174
+ for (let y = y0; y < y0 + h; y++) {
175
+ for (let x = x0; x < x0 + w; x++) {
176
+ if (a[y * p.width + x]) {
177
+ count++;
178
+ sum += p.y[y * p.width + x];
179
+ }
180
+ }
181
+ }
182
+ if (count > 0 && count < w * h) {
183
+ const average = Math.floor(sum / count);
184
+ for (let y = y0; y < y0 + h; y++)
185
+ for (let x = x0; x < x0 + w; x++)
186
+ if (!a[y * p.width + x])
187
+ p.y[y * p.width + x] = average;
188
+ }
189
+ return count === 0;
190
+ }
191
+ function cleanupTransparentArea(p) {
192
+ const { width, height, uvStride } = p;
193
+ const flatten = (plane, stride, x0, y0, size, value) => {
194
+ for (let y = y0; y < y0 + size; y++)
195
+ plane.fill(value, y * stride + x0, y * stride + x0 + size);
196
+ };
197
+ let y = 0;
198
+ for (; y + 8 <= height; y += 8) {
199
+ let reset = true, vy = 0, vu = 0, vv = 0;
200
+ let x = 0;
201
+ for (; x + 8 <= width; x += 8) {
202
+ if (smoothenBlock(p, x, y, 8, 8)) {
203
+ if (reset) {
204
+ vy = p.y[y * width + x];
205
+ vu = p.u[(y >> 1) * uvStride + (x >> 1)];
206
+ vv = p.v[(y >> 1) * uvStride + (x >> 1)];
207
+ reset = false;
208
+ }
209
+ flatten(p.y, width, x, y, 8, vy);
210
+ flatten(p.u, uvStride, x >> 1, y >> 1, 4, vu);
211
+ flatten(p.v, uvStride, x >> 1, y >> 1, 4, vv);
212
+ }
213
+ else
214
+ reset = true;
215
+ }
216
+ if (x < width)
217
+ smoothenBlock(p, x, y, width - x, 8);
218
+ }
219
+ if (y < height) {
220
+ let x = 0;
221
+ for (; x + 8 <= width; x += 8)
222
+ smoothenBlock(p, x, y, 8, height - y);
223
+ if (x < width)
224
+ smoothenBlock(p, x, y, width - x, height - y);
225
+ }
226
+ }
227
+ function fill(dst, d, value, size) {
228
+ for (let j = 0; j < size; j++, d += BPS)
229
+ for (let x = 0; x < size; x++)
230
+ dst[d + x] = value;
231
+ }
232
+ function verticalPred(dst, d, top, t, size) {
233
+ if (top)
234
+ for (let j = 0; j < size; j++, d += BPS)
235
+ for (let x = 0; x < size; x++)
236
+ dst[d + x] = top[t + x];
237
+ else
238
+ fill(dst, d, 127, size);
239
+ }
240
+ function horizontalPred(dst, d, left, l, size) {
241
+ if (left) {
242
+ for (let j = 0; j < size; j++, d += BPS) {
243
+ const v = left[l + j];
244
+ for (let x = 0; x < size; x++)
245
+ dst[d + x] = v;
246
+ }
247
+ }
248
+ else
249
+ fill(dst, d, 129, size);
250
+ }
251
+ function trueMotion(dst, d, left, l, top, t, size) {
252
+ if (left) {
253
+ if (top) {
254
+ const corner = left[l - 1];
255
+ for (let y = 0; y < size; y++) {
256
+ const base = left[l + y] - corner;
257
+ for (let x = 0; x < size; x++)
258
+ dst[d + y * BPS + x] = clip8(top[t + x] + base);
259
+ }
260
+ }
261
+ else
262
+ horizontalPred(dst, d, left, l, size);
263
+ }
264
+ else if (top)
265
+ verticalPred(dst, d, top, t, size);
266
+ else
267
+ fill(dst, d, 129, size);
268
+ }
269
+ function dcMode(dst, d, left, l, top, t, size, round, shift) {
270
+ let dc = 0;
271
+ if (top) {
272
+ for (let j = 0; j < size; j++)
273
+ dc += top[t + j];
274
+ if (left)
275
+ for (let j = 0; j < size; j++)
276
+ dc += left[l + j];
277
+ else
278
+ dc += dc;
279
+ dc = (dc + round) >> shift;
280
+ }
281
+ else if (left) {
282
+ for (let j = 0; j < size; j++)
283
+ dc += left[l + j];
284
+ dc += dc;
285
+ dc = (dc + round) >> shift;
286
+ }
287
+ else
288
+ dc = 0x80;
289
+ fill(dst, d, dc, size);
290
+ }
291
+ export function predLuma16(dst, left, l, top, t, modes = 15) {
292
+ if (modes & 1)
293
+ dcMode(dst, I16DC16, left, l, top, t, 16, 16, 5);
294
+ if (modes & 2)
295
+ trueMotion(dst, I16TM16, left, l, top, t, 16);
296
+ if (modes & 4)
297
+ verticalPred(dst, I16VE16, top, t, 16);
298
+ if (modes & 8)
299
+ horizontalPred(dst, I16HE16, left, l, 16);
300
+ }
301
+ export function predChroma8(dst, uLeft, ul, vLeft, vl, top, t, modes = 15) {
302
+ for (let c = 0; c < 2; c++) {
303
+ const left = c ? vLeft : uLeft, l = c ? vl : ul, tt = t + 8 * c, o = 8 * c;
304
+ if (modes & 1)
305
+ dcMode(dst, C8DC8 + o, left, l, top, tt, 8, 8, 4);
306
+ if (modes & 2)
307
+ trueMotion(dst, C8TM8 + o, left, l, top, tt, 8);
308
+ if (modes & 4)
309
+ verticalPred(dst, C8VE8 + o, top, tt, 8);
310
+ if (modes & 8)
311
+ horizontalPred(dst, C8HE8 + o, left, l, 8);
312
+ }
313
+ }
314
+ const avg3 = (a, b, c) => (a + 2 * b + c + 2) >> 2;
315
+ const avg2 = (a, b) => (a + b + 1) >> 1;
316
+ const rowSums = new Int32Array(16), columnSums = new Int32Array(16);
317
+ let sourceSquares = 0, sourceSum = 0;
318
+ function sourceSums16(src, s) {
319
+ let c0 = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7 = 0, c8 = 0, c9 = 0, c10 = 0, c11 = 0, c12 = 0, c13 = 0, c14 = 0, c15 = 0, squares = 0, sum = 0;
320
+ for (let y = 0, o = s; y < 16; y++, o += BPS) {
321
+ const v0 = src[o], v1 = src[o + 1], v2 = src[o + 2], v3 = src[o + 3], v4 = src[o + 4], v5 = src[o + 5], v6 = src[o + 6], v7 = src[o + 7], v8 = src[o + 8], v9 = src[o + 9], v10 = src[o + 10], v11 = src[o + 11], v12 = src[o + 12], v13 = src[o + 13], v14 = src[o + 14], v15 = src[o + 15];
322
+ const row = v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 + v11 + v12 + v13 + v14 + v15;
323
+ rowSums[y] = row;
324
+ sum += row;
325
+ squares += v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3 + v4 * v4 + v5 * v5 + v6 * v6 + v7 * v7 + v8 * v8 + v9 * v9 + v10 * v10 + v11 * v11 + v12 * v12 + v13 * v13 + v14 * v14 + v15 * v15;
326
+ c0 += v0;
327
+ c1 += v1;
328
+ c2 += v2;
329
+ c3 += v3;
330
+ c4 += v4;
331
+ c5 += v5;
332
+ c6 += v6;
333
+ c7 += v7;
334
+ c8 += v8;
335
+ c9 += v9;
336
+ c10 += v10;
337
+ c11 += v11;
338
+ c12 += v12;
339
+ c13 += v13;
340
+ c14 += v14;
341
+ c15 += v15;
342
+ }
343
+ columnSums[0] = c0;
344
+ columnSums[1] = c1;
345
+ columnSums[2] = c2;
346
+ columnSums[3] = c3;
347
+ columnSums[4] = c4;
348
+ columnSums[5] = c5;
349
+ columnSums[6] = c6;
350
+ columnSums[7] = c7;
351
+ columnSums[8] = c8;
352
+ columnSums[9] = c9;
353
+ columnSums[10] = c10;
354
+ columnSums[11] = c11;
355
+ columnSums[12] = c12;
356
+ columnSums[13] = c13;
357
+ columnSums[14] = c14;
358
+ columnSums[15] = c15;
359
+ sourceSquares = squares;
360
+ sourceSum = sum;
361
+ }
362
+ function sourceSums8(src, s) {
363
+ let c0 = 0, c1 = 0, c2 = 0, c3 = 0, c4 = 0, c5 = 0, c6 = 0, c7 = 0, squares = 0, sum = 0;
364
+ for (let y = 0, o = s; y < 8; y++, o += BPS) {
365
+ const v0 = src[o], v1 = src[o + 1], v2 = src[o + 2], v3 = src[o + 3], v4 = src[o + 4], v5 = src[o + 5], v6 = src[o + 6], v7 = src[o + 7];
366
+ const row = v0 + v1 + v2 + v3 + v4 + v5 + v6 + v7;
367
+ rowSums[y] = row;
368
+ sum += row;
369
+ squares += v0 * v0 + v1 * v1 + v2 * v2 + v3 * v3 + v4 * v4 + v5 * v5 + v6 * v6 + v7 * v7;
370
+ c0 += v0;
371
+ c1 += v1;
372
+ c2 += v2;
373
+ c3 += v3;
374
+ c4 += v4;
375
+ c5 += v5;
376
+ c6 += v6;
377
+ c7 += v7;
378
+ }
379
+ columnSums[0] = c0;
380
+ columnSums[1] = c1;
381
+ columnSums[2] = c2;
382
+ columnSums[3] = c3;
383
+ columnSums[4] = c4;
384
+ columnSums[5] = c5;
385
+ columnSums[6] = c6;
386
+ columnSums[7] = c7;
387
+ sourceSquares = squares;
388
+ sourceSum = sum;
389
+ }
390
+ export function predictionSSEs(src, s, size, planes, left0, left1, l, top, t, out) {
391
+ out.fill(0);
392
+ const n = size * size, shift = size === 16 ? 5 : 4;
393
+ for (let c = 0; c < planes; c++, s += 8, t += 8) {
394
+ const left = c ? left1 : left0;
395
+ if (size === 16)
396
+ sourceSums16(src, s);
397
+ else
398
+ sourceSums8(src, s);
399
+ const squares = sourceSquares, sum = sourceSum;
400
+ const fill = (v) => squares - 2 * v * sum + n * v * v;
401
+ let topSum = 0, topSquares = 0, topCross = 0, leftSum = 0, leftSquares = 0, leftCross = 0;
402
+ if (top) {
403
+ for (let x = 0; x < size; x++) {
404
+ const v = top[t + x];
405
+ topSum += v;
406
+ topSquares += v * v;
407
+ topCross += v * columnSums[x];
408
+ }
409
+ }
410
+ if (left) {
411
+ for (let y = 0; y < size; y++) {
412
+ const v = left[l + y];
413
+ leftSum += v;
414
+ leftSquares += v * v;
415
+ leftCross += v * rowSums[y];
416
+ }
417
+ }
418
+ const vertical = top ? squares - 2 * topCross + size * topSquares : fill(127);
419
+ const horizontal = left ? squares - 2 * leftCross + size * leftSquares : fill(129);
420
+ let dc;
421
+ if (top)
422
+ dc = (left ? topSum + leftSum : 2 * topSum) + size >> shift;
423
+ else if (left)
424
+ dc = 2 * leftSum + size >> shift;
425
+ else
426
+ dc = 0x80;
427
+ let tm;
428
+ if (left && top) {
429
+ const corner = left[l - 1];
430
+ let tMin = 255, tMax = 0, bMin = 255, bMax = -255, bSum = 0, bSquares = 0, bCross = 0;
431
+ for (let x = 0; x < size; x++) {
432
+ const v = top[t + x];
433
+ if (v < tMin)
434
+ tMin = v;
435
+ if (v > tMax)
436
+ tMax = v;
437
+ }
438
+ for (let y = 0; y < size; y++) {
439
+ const b = left[l + y] - corner;
440
+ if (b < bMin)
441
+ bMin = b;
442
+ if (b > bMax)
443
+ bMax = b;
444
+ bSum += b;
445
+ bSquares += b * b;
446
+ bCross += b * rowSums[y];
447
+ }
448
+ if (tMin + bMin >= 0 && tMax + bMax <= 255) {
449
+ tm = squares - 2 * topCross - 2 * bCross + size * topSquares + 2 * topSum * bSum + size * bSquares;
450
+ }
451
+ else {
452
+ tm = 0;
453
+ for (let y = 0, o = s; y < size; y++, o += BPS) {
454
+ const b = left[l + y] - corner;
455
+ for (let x = 0; x < size; x++) {
456
+ const d = src[o + x] - clip8(top[t + x] + b);
457
+ tm += d * d;
458
+ }
459
+ }
460
+ }
461
+ }
462
+ else
463
+ tm = left ? horizontal : top ? vertical : fill(129);
464
+ out[0] += fill(dc);
465
+ out[1] += tm;
466
+ out[2] += vertical;
467
+ out[3] += horizontal;
468
+ }
469
+ }
470
+ export function predLuma4(dst, top, t) {
471
+ const X = top[t - 1], I = top[t - 2], J = top[t - 3], K = top[t - 4], L = top[t - 5];
472
+ const A = top[t], B = top[t + 1], C = top[t + 2], D = top[t + 3], E = top[t + 4], F = top[t + 5], G = top[t + 6], H = top[t + 7];
473
+ const R0 = 0, R1 = BPS, R2 = 2 * BPS, R3 = 3 * BPS;
474
+ const dc = (4 + A + B + C + D + I + J + K + L) >> 3;
475
+ for (let y = 0, o = I4DC4; y < 4; y++, o += BPS)
476
+ dst[o] = dst[o + 1] = dst[o + 2] = dst[o + 3] = dc;
477
+ for (let y = 0; y < 4; y++) {
478
+ const base = top[t - 2 - y] - X, o = I4DC4 + 4 + y * BPS;
479
+ dst[o] = clip8(A + base);
480
+ dst[o + 1] = clip8(B + base);
481
+ dst[o + 2] = clip8(C + base);
482
+ dst[o + 3] = clip8(D + base);
483
+ }
484
+ let o = I4DC4 + 8;
485
+ const v0 = avg3(X, A, B), v1 = avg3(A, B, C), v2 = avg3(B, C, D), v3 = avg3(C, D, E);
486
+ for (let y = 0; y < 4; y++, o += BPS) {
487
+ dst[o] = v0;
488
+ dst[o + 1] = v1;
489
+ dst[o + 2] = v2;
490
+ dst[o + 3] = v3;
491
+ }
492
+ o = I4DC4 + 12;
493
+ const he0 = avg3(X, I, J), he1 = avg3(I, J, K), he2 = avg3(J, K, L), he3 = avg3(K, L, L);
494
+ dst[o + R0] = dst[o + R0 + 1] = dst[o + R0 + 2] = dst[o + R0 + 3] = he0;
495
+ dst[o + R1] = dst[o + R1 + 1] = dst[o + R1 + 2] = dst[o + R1 + 3] = he1;
496
+ dst[o + R2] = dst[o + R2 + 1] = dst[o + R2 + 2] = dst[o + R2 + 3] = he2;
497
+ dst[o + R3] = dst[o + R3 + 1] = dst[o + R3 + 2] = dst[o + R3 + 3] = he3;
498
+ o = I4DC4 + 16;
499
+ const xij = avg3(X, I, J), ijk = avg3(I, J, K), axi = avg3(A, X, I), bax = avg3(B, A, X);
500
+ dst[o + R3] = avg3(J, K, L);
501
+ dst[o + R2] = dst[o + R3 + 1] = ijk;
502
+ dst[o + R1] = dst[o + R2 + 1] = dst[o + R3 + 2] = xij;
503
+ dst[o] = dst[o + R1 + 1] = dst[o + R2 + 2] = dst[o + R3 + 3] = axi;
504
+ dst[o + 1] = dst[o + R1 + 2] = dst[o + R2 + 3] = bax;
505
+ dst[o + 2] = dst[o + R1 + 3] = avg3(C, B, A);
506
+ dst[o + 3] = avg3(D, C, B);
507
+ o = I4DC4 + 20;
508
+ dst[o] = dst[o + R2 + 1] = avg2(X, A);
509
+ dst[o + 1] = dst[o + R2 + 2] = avg2(A, B);
510
+ dst[o + 2] = dst[o + R2 + 3] = avg2(B, C);
511
+ dst[o + 3] = avg2(C, D);
512
+ dst[o + R3] = avg3(K, J, I);
513
+ dst[o + R2] = avg3(J, I, X);
514
+ dst[o + R1] = dst[o + R3 + 1] = axi;
515
+ dst[o + R1 + 1] = dst[o + R3 + 2] = avg3(X, A, B);
516
+ dst[o + R1 + 2] = dst[o + R3 + 3] = avg3(A, B, C);
517
+ dst[o + R1 + 3] = avg3(B, C, D);
518
+ o = I4DC4 + 24;
519
+ const bcd = avg3(B, C, D), cde = avg3(C, D, E), def = avg3(D, E, F), efg = avg3(E, F, G);
520
+ dst[o] = avg3(A, B, C);
521
+ dst[o + 1] = dst[o + R1] = bcd;
522
+ dst[o + 2] = dst[o + R1 + 1] = dst[o + R2] = cde;
523
+ dst[o + 3] = dst[o + R1 + 2] = dst[o + R2 + 1] = dst[o + R3] = def;
524
+ dst[o + R1 + 3] = dst[o + R2 + 2] = dst[o + R3 + 1] = efg;
525
+ dst[o + R2 + 3] = dst[o + R3 + 2] = avg3(F, G, H);
526
+ dst[o + R3 + 3] = avg3(G, H, H);
527
+ o = I4DC4 + 28;
528
+ dst[o] = avg2(A, B);
529
+ dst[o + 1] = dst[o + R2] = avg2(B, C);
530
+ dst[o + 2] = dst[o + R2 + 1] = avg2(C, D);
531
+ dst[o + 3] = dst[o + R2 + 2] = avg2(D, E);
532
+ dst[o + R1] = avg3(A, B, C);
533
+ dst[o + R1 + 1] = dst[o + R3] = bcd;
534
+ dst[o + R1 + 2] = dst[o + R3 + 1] = cde;
535
+ dst[o + R1 + 3] = dst[o + R3 + 2] = def;
536
+ dst[o + R2 + 3] = efg;
537
+ dst[o + R3 + 3] = avg3(F, G, H);
538
+ o = I4HD4;
539
+ const jix = avg3(J, I, X), kji = avg3(K, J, I);
540
+ dst[o] = dst[o + R1 + 2] = avg2(I, X);
541
+ dst[o + R1] = dst[o + R2 + 2] = avg2(J, I);
542
+ dst[o + R2] = dst[o + R3 + 2] = avg2(K, J);
543
+ dst[o + R3] = avg2(L, K);
544
+ dst[o + 3] = avg3(A, B, C);
545
+ dst[o + 2] = avg3(X, A, B);
546
+ dst[o + 1] = dst[o + R1 + 3] = axi;
547
+ dst[o + R1 + 1] = dst[o + R2 + 3] = jix;
548
+ dst[o + R2 + 1] = dst[o + R3 + 3] = kji;
549
+ dst[o + R3 + 1] = avg3(L, K, J);
550
+ o = I4HD4 + 4;
551
+ dst[o] = avg2(I, J);
552
+ dst[o + 2] = dst[o + R1] = avg2(J, K);
553
+ dst[o + R1 + 2] = dst[o + R2] = avg2(K, L);
554
+ dst[o + 1] = ijk;
555
+ dst[o + 3] = dst[o + R1 + 1] = avg3(J, K, L);
556
+ dst[o + R1 + 3] = dst[o + R2 + 1] = avg3(K, L, L);
557
+ dst[o + R2 + 3] = dst[o + R2 + 2] = dst[o + R3] = dst[o + R3 + 1] = dst[o + R3 + 2] = dst[o + R3 + 3] = L;
558
+ }
559
+ export function iTransform(ref, r, input, i, dst, d, two) {
560
+ for (let n = 0; n < (two ? 2 : 1); n++, r += 4, i += 16, d += 4) {
561
+ let ac = 0;
562
+ for (let k = 1; k < 16; k++)
563
+ ac |= input[i + k];
564
+ if (!ac) {
565
+ const dc = (input[i] + 4) >> 3;
566
+ for (let k = 0; k < 4; k++) {
567
+ const o = k * BPS;
568
+ dst[d + o] = clip8(ref[r + o] + dc);
569
+ dst[d + o + 1] = clip8(ref[r + o + 1] + dc);
570
+ dst[d + o + 2] = clip8(ref[r + o + 2] + dc);
571
+ dst[d + o + 3] = clip8(ref[r + o + 3] + dc);
572
+ }
573
+ continue;
574
+ }
575
+ const p0 = input[i + 0], q0 = input[i + 4], u0 = input[i + 8], w0 = input[i + 12];
576
+ const a0 = p0 + u0, b0 = p0 - u0;
577
+ const c0 = ((q0 * 35468) >> 16) - (((w0 * 20091) >> 16) + w0), e0 = (((q0 * 20091) >> 16) + q0) + ((w0 * 35468) >> 16);
578
+ const v00 = a0 + e0, v01 = b0 + c0, v02 = b0 - c0, v03 = a0 - e0;
579
+ const p1 = input[i + 1], q1 = input[i + 5], u1 = input[i + 9], w1 = input[i + 13];
580
+ const a1 = p1 + u1, b1 = p1 - u1;
581
+ const c1 = ((q1 * 35468) >> 16) - (((w1 * 20091) >> 16) + w1), e1 = (((q1 * 20091) >> 16) + q1) + ((w1 * 35468) >> 16);
582
+ const v10 = a1 + e1, v11 = b1 + c1, v12 = b1 - c1, v13 = a1 - e1;
583
+ const p2 = input[i + 2], q2 = input[i + 6], u2 = input[i + 10], w2 = input[i + 14];
584
+ const a2 = p2 + u2, b2 = p2 - u2;
585
+ const c2 = ((q2 * 35468) >> 16) - (((w2 * 20091) >> 16) + w2), e2 = (((q2 * 20091) >> 16) + q2) + ((w2 * 35468) >> 16);
586
+ const v20 = a2 + e2, v21 = b2 + c2, v22 = b2 - c2, v23 = a2 - e2;
587
+ const p3 = input[i + 3], q3 = input[i + 7], u3 = input[i + 11], w3 = input[i + 15];
588
+ const a3 = p3 + u3, b3 = p3 - u3;
589
+ const c3 = ((q3 * 35468) >> 16) - (((w3 * 20091) >> 16) + w3), e3 = (((q3 * 20091) >> 16) + q3) + ((w3 * 35468) >> 16);
590
+ const v30 = a3 + e3, v31 = b3 + c3, v32 = b3 - c3, v33 = a3 - e3;
591
+ {
592
+ const dc = v00 + 4;
593
+ const a = dc + v20, b = dc - v20;
594
+ const c = ((v10 * 35468) >> 16) - (((v30 * 20091) >> 16) + v30), e = (((v10 * 20091) >> 16) + v10) + ((v30 * 35468) >> 16);
595
+ dst[d] = clip8(ref[r] + ((a + e) >> 3));
596
+ dst[d + 1] = clip8(ref[r + 1] + ((b + c) >> 3));
597
+ dst[d + 2] = clip8(ref[r + 2] + ((b - c) >> 3));
598
+ dst[d + 3] = clip8(ref[r + 3] + ((a - e) >> 3));
599
+ }
600
+ {
601
+ const dc = v01 + 4;
602
+ const a = dc + v21, b = dc - v21;
603
+ const c = ((v11 * 35468) >> 16) - (((v31 * 20091) >> 16) + v31), e = (((v11 * 20091) >> 16) + v11) + ((v31 * 35468) >> 16);
604
+ dst[d + 1 * BPS] = clip8(ref[r + 1 * BPS] + ((a + e) >> 3));
605
+ dst[d + 1 * BPS + 1] = clip8(ref[r + 1 * BPS + 1] + ((b + c) >> 3));
606
+ dst[d + 1 * BPS + 2] = clip8(ref[r + 1 * BPS + 2] + ((b - c) >> 3));
607
+ dst[d + 1 * BPS + 3] = clip8(ref[r + 1 * BPS + 3] + ((a - e) >> 3));
608
+ }
609
+ {
610
+ const dc = v02 + 4;
611
+ const a = dc + v22, b = dc - v22;
612
+ const c = ((v12 * 35468) >> 16) - (((v32 * 20091) >> 16) + v32), e = (((v12 * 20091) >> 16) + v12) + ((v32 * 35468) >> 16);
613
+ dst[d + 2 * BPS] = clip8(ref[r + 2 * BPS] + ((a + e) >> 3));
614
+ dst[d + 2 * BPS + 1] = clip8(ref[r + 2 * BPS + 1] + ((b + c) >> 3));
615
+ dst[d + 2 * BPS + 2] = clip8(ref[r + 2 * BPS + 2] + ((b - c) >> 3));
616
+ dst[d + 2 * BPS + 3] = clip8(ref[r + 2 * BPS + 3] + ((a - e) >> 3));
617
+ }
618
+ {
619
+ const dc = v03 + 4;
620
+ const a = dc + v23, b = dc - v23;
621
+ const c = ((v13 * 35468) >> 16) - (((v33 * 20091) >> 16) + v33), e = (((v13 * 20091) >> 16) + v13) + ((v33 * 35468) >> 16);
622
+ dst[d + 3 * BPS] = clip8(ref[r + 3 * BPS] + ((a + e) >> 3));
623
+ dst[d + 3 * BPS + 1] = clip8(ref[r + 3 * BPS + 1] + ((b + c) >> 3));
624
+ dst[d + 3 * BPS + 2] = clip8(ref[r + 3 * BPS + 2] + ((b - c) >> 3));
625
+ dst[d + 3 * BPS + 3] = clip8(ref[r + 3 * BPS + 3] + ((a - e) >> 3));
626
+ }
627
+ }
628
+ }
629
+ export function fTransform(src, s, ref, r, out, o) {
630
+ const d00 = src[s] - ref[r], d01 = src[s + 1] - ref[r + 1], d02 = src[s + 2] - ref[r + 2], d03 = src[s + 3] - ref[r + 3];
631
+ const a00 = d00 + d03, a01 = d01 + d02, a02 = d01 - d02, a03 = d00 - d03;
632
+ const t00 = (a00 + a01) * 8, t01 = (a02 * 2217 + a03 * 5352 + 1812) >> 9, t02 = (a00 - a01) * 8, t03 = (a03 * 2217 - a02 * 5352 + 937) >> 9;
633
+ const d10 = src[s + 1 * BPS] - ref[r + 1 * BPS], d11 = src[s + 1 * BPS + 1] - ref[r + 1 * BPS + 1], d12 = src[s + 1 * BPS + 2] - ref[r + 1 * BPS + 2], d13 = src[s + 1 * BPS + 3] - ref[r + 1 * BPS + 3];
634
+ const a10 = d10 + d13, a11 = d11 + d12, a12 = d11 - d12, a13 = d10 - d13;
635
+ const t10 = (a10 + a11) * 8, t11 = (a12 * 2217 + a13 * 5352 + 1812) >> 9, t12 = (a10 - a11) * 8, t13 = (a13 * 2217 - a12 * 5352 + 937) >> 9;
636
+ const d20 = src[s + 2 * BPS] - ref[r + 2 * BPS], d21 = src[s + 2 * BPS + 1] - ref[r + 2 * BPS + 1], d22 = src[s + 2 * BPS + 2] - ref[r + 2 * BPS + 2], d23 = src[s + 2 * BPS + 3] - ref[r + 2 * BPS + 3];
637
+ const a20 = d20 + d23, a21 = d21 + d22, a22 = d21 - d22, a23 = d20 - d23;
638
+ const t20 = (a20 + a21) * 8, t21 = (a22 * 2217 + a23 * 5352 + 1812) >> 9, t22 = (a20 - a21) * 8, t23 = (a23 * 2217 - a22 * 5352 + 937) >> 9;
639
+ const d30 = src[s + 3 * BPS] - ref[r + 3 * BPS], d31 = src[s + 3 * BPS + 1] - ref[r + 3 * BPS + 1], d32 = src[s + 3 * BPS + 2] - ref[r + 3 * BPS + 2], d33 = src[s + 3 * BPS + 3] - ref[r + 3 * BPS + 3];
640
+ const a30 = d30 + d33, a31 = d31 + d32, a32 = d31 - d32, a33 = d30 - d33;
641
+ const t30 = (a30 + a31) * 8, t31 = (a32 * 2217 + a33 * 5352 + 1812) >> 9, t32 = (a30 - a31) * 8, t33 = (a33 * 2217 - a32 * 5352 + 937) >> 9;
642
+ const b00 = t00 + t30, b01 = t10 + t20, b02 = t10 - t20, b03 = t00 - t30;
643
+ out[o + 0] = (b00 + b01 + 7) >> 4;
644
+ out[o + 4] = ((b02 * 2217 + b03 * 5352 + 12000) >> 16) + (b03 !== 0 ? 1 : 0);
645
+ out[o + 8] = (b00 - b01 + 7) >> 4;
646
+ out[o + 12] = (b03 * 2217 - b02 * 5352 + 51000) >> 16;
647
+ const b10 = t01 + t31, b11 = t11 + t21, b12 = t11 - t21, b13 = t01 - t31;
648
+ out[o + 1] = (b10 + b11 + 7) >> 4;
649
+ out[o + 5] = ((b12 * 2217 + b13 * 5352 + 12000) >> 16) + (b13 !== 0 ? 1 : 0);
650
+ out[o + 9] = (b10 - b11 + 7) >> 4;
651
+ out[o + 13] = (b13 * 2217 - b12 * 5352 + 51000) >> 16;
652
+ const b20 = t02 + t32, b21 = t12 + t22, b22 = t12 - t22, b23 = t02 - t32;
653
+ out[o + 2] = (b20 + b21 + 7) >> 4;
654
+ out[o + 6] = ((b22 * 2217 + b23 * 5352 + 12000) >> 16) + (b23 !== 0 ? 1 : 0);
655
+ out[o + 10] = (b20 - b21 + 7) >> 4;
656
+ out[o + 14] = (b23 * 2217 - b22 * 5352 + 51000) >> 16;
657
+ const b30 = t03 + t33, b31 = t13 + t23, b32 = t13 - t23, b33 = t03 - t33;
658
+ out[o + 3] = (b30 + b31 + 7) >> 4;
659
+ out[o + 7] = ((b32 * 2217 + b33 * 5352 + 12000) >> 16) + (b33 !== 0 ? 1 : 0);
660
+ out[o + 11] = (b30 - b31 + 7) >> 4;
661
+ out[o + 15] = (b33 * 2217 - b32 * 5352 + 51000) >> 16;
662
+ }
663
+ const bin = (c) => {
664
+ const v = (c < 0 ? -c : c) >> 3;
665
+ return v < 31 ? v : 31;
666
+ };
667
+ function fTransformHistogram(src, s, ref, r, dist) {
668
+ const d00 = src[s] - ref[r], d01 = src[s + 1] - ref[r + 1], d02 = src[s + 2] - ref[r + 2], d03 = src[s + 3] - ref[r + 3];
669
+ const a00 = d00 + d03, a01 = d01 + d02, a02 = d01 - d02, a03 = d00 - d03;
670
+ const t00 = (a00 + a01) * 8, t01 = (a02 * 2217 + a03 * 5352 + 1812) >> 9, t02 = (a00 - a01) * 8, t03 = (a03 * 2217 - a02 * 5352 + 937) >> 9;
671
+ const d10 = src[s + 1 * BPS] - ref[r + 1 * BPS], d11 = src[s + 1 * BPS + 1] - ref[r + 1 * BPS + 1], d12 = src[s + 1 * BPS + 2] - ref[r + 1 * BPS + 2], d13 = src[s + 1 * BPS + 3] - ref[r + 1 * BPS + 3];
672
+ const a10 = d10 + d13, a11 = d11 + d12, a12 = d11 - d12, a13 = d10 - d13;
673
+ const t10 = (a10 + a11) * 8, t11 = (a12 * 2217 + a13 * 5352 + 1812) >> 9, t12 = (a10 - a11) * 8, t13 = (a13 * 2217 - a12 * 5352 + 937) >> 9;
674
+ const d20 = src[s + 2 * BPS] - ref[r + 2 * BPS], d21 = src[s + 2 * BPS + 1] - ref[r + 2 * BPS + 1], d22 = src[s + 2 * BPS + 2] - ref[r + 2 * BPS + 2], d23 = src[s + 2 * BPS + 3] - ref[r + 2 * BPS + 3];
675
+ const a20 = d20 + d23, a21 = d21 + d22, a22 = d21 - d22, a23 = d20 - d23;
676
+ const t20 = (a20 + a21) * 8, t21 = (a22 * 2217 + a23 * 5352 + 1812) >> 9, t22 = (a20 - a21) * 8, t23 = (a23 * 2217 - a22 * 5352 + 937) >> 9;
677
+ const d30 = src[s + 3 * BPS] - ref[r + 3 * BPS], d31 = src[s + 3 * BPS + 1] - ref[r + 3 * BPS + 1], d32 = src[s + 3 * BPS + 2] - ref[r + 3 * BPS + 2], d33 = src[s + 3 * BPS + 3] - ref[r + 3 * BPS + 3];
678
+ const a30 = d30 + d33, a31 = d31 + d32, a32 = d31 - d32, a33 = d30 - d33;
679
+ const t30 = (a30 + a31) * 8, t31 = (a32 * 2217 + a33 * 5352 + 1812) >> 9, t32 = (a30 - a31) * 8, t33 = (a33 * 2217 - a32 * 5352 + 937) >> 9;
680
+ const b00 = t00 + t30, b01 = t10 + t20, b02 = t10 - t20, b03 = t00 - t30;
681
+ const c0 = (b00 + b01 + 7) >> 4;
682
+ const c4 = ((b02 * 2217 + b03 * 5352 + 12000) >> 16) + (b03 !== 0 ? 1 : 0);
683
+ const c8 = (b00 - b01 + 7) >> 4;
684
+ const c12 = (b03 * 2217 - b02 * 5352 + 51000) >> 16;
685
+ const b10 = t01 + t31, b11 = t11 + t21, b12 = t11 - t21, b13 = t01 - t31;
686
+ const c1 = (b10 + b11 + 7) >> 4;
687
+ const c5 = ((b12 * 2217 + b13 * 5352 + 12000) >> 16) + (b13 !== 0 ? 1 : 0);
688
+ const c9 = (b10 - b11 + 7) >> 4;
689
+ const c13 = (b13 * 2217 - b12 * 5352 + 51000) >> 16;
690
+ const b20 = t02 + t32, b21 = t12 + t22, b22 = t12 - t22, b23 = t02 - t32;
691
+ const c2 = (b20 + b21 + 7) >> 4;
692
+ const c6 = ((b22 * 2217 + b23 * 5352 + 12000) >> 16) + (b23 !== 0 ? 1 : 0);
693
+ const c10 = (b20 - b21 + 7) >> 4;
694
+ const c14 = (b23 * 2217 - b22 * 5352 + 51000) >> 16;
695
+ const b30 = t03 + t33, b31 = t13 + t23, b32 = t13 - t23, b33 = t03 - t33;
696
+ const c3 = (b30 + b31 + 7) >> 4;
697
+ const c7 = ((b32 * 2217 + b33 * 5352 + 12000) >> 16) + (b33 !== 0 ? 1 : 0);
698
+ const c11 = (b30 - b31 + 7) >> 4;
699
+ const c15 = (b33 * 2217 - b32 * 5352 + 51000) >> 16;
700
+ let zeros = 0;
701
+ if (c0 > -8 && c0 < 8)
702
+ zeros++;
703
+ else
704
+ dist[bin(c0)]++;
705
+ if (c1 > -8 && c1 < 8)
706
+ zeros++;
707
+ else
708
+ dist[bin(c1)]++;
709
+ if (c2 > -8 && c2 < 8)
710
+ zeros++;
711
+ else
712
+ dist[bin(c2)]++;
713
+ if (c3 > -8 && c3 < 8)
714
+ zeros++;
715
+ else
716
+ dist[bin(c3)]++;
717
+ if (c4 > -8 && c4 < 8)
718
+ zeros++;
719
+ else
720
+ dist[bin(c4)]++;
721
+ if (c5 > -8 && c5 < 8)
722
+ zeros++;
723
+ else
724
+ dist[bin(c5)]++;
725
+ if (c6 > -8 && c6 < 8)
726
+ zeros++;
727
+ else
728
+ dist[bin(c6)]++;
729
+ if (c7 > -8 && c7 < 8)
730
+ zeros++;
731
+ else
732
+ dist[bin(c7)]++;
733
+ if (c8 > -8 && c8 < 8)
734
+ zeros++;
735
+ else
736
+ dist[bin(c8)]++;
737
+ if (c9 > -8 && c9 < 8)
738
+ zeros++;
739
+ else
740
+ dist[bin(c9)]++;
741
+ if (c10 > -8 && c10 < 8)
742
+ zeros++;
743
+ else
744
+ dist[bin(c10)]++;
745
+ if (c11 > -8 && c11 < 8)
746
+ zeros++;
747
+ else
748
+ dist[bin(c11)]++;
749
+ if (c12 > -8 && c12 < 8)
750
+ zeros++;
751
+ else
752
+ dist[bin(c12)]++;
753
+ if (c13 > -8 && c13 < 8)
754
+ zeros++;
755
+ else
756
+ dist[bin(c13)]++;
757
+ if (c14 > -8 && c14 < 8)
758
+ zeros++;
759
+ else
760
+ dist[bin(c14)]++;
761
+ if (c15 > -8 && c15 < 8)
762
+ zeros++;
763
+ else
764
+ dist[bin(c15)]++;
765
+ return zeros;
766
+ }
767
+ const ftmp = new Int32Array(16);
768
+ export function fTransformWHT(input, out) {
769
+ for (let i = 0, o = 0; i < 4; i++, o += 64) {
770
+ const a0 = input[o] + input[o + 32], a1 = input[o + 16] + input[o + 48];
771
+ const a2 = input[o + 16] - input[o + 48], a3 = input[o] - input[o + 32];
772
+ ftmp[i * 4] = a0 + a1;
773
+ ftmp[i * 4 + 1] = a3 + a2;
774
+ ftmp[i * 4 + 2] = a3 - a2;
775
+ ftmp[i * 4 + 3] = a0 - a1;
776
+ }
777
+ for (let i = 0; i < 4; i++) {
778
+ const a0 = ftmp[i] + ftmp[8 + i], a1 = ftmp[4 + i] + ftmp[12 + i], a2 = ftmp[4 + i] - ftmp[12 + i], a3 = ftmp[i] - ftmp[8 + i];
779
+ out[i] = (a0 + a1) >> 1;
780
+ out[4 + i] = (a3 + a2) >> 1;
781
+ out[8 + i] = (a3 - a2) >> 1;
782
+ out[12 + i] = (a0 - a1) >> 1;
783
+ }
784
+ }
785
+ export function iTransformWHT(input, out) {
786
+ for (let i = 0; i < 4; i++) {
787
+ const a0 = input[i] + input[12 + i], a1 = input[4 + i] + input[8 + i];
788
+ const a2 = input[4 + i] - input[8 + i], a3 = input[i] - input[12 + i];
789
+ ftmp[i] = a0 + a1;
790
+ ftmp[8 + i] = a0 - a1;
791
+ ftmp[4 + i] = a3 + a2;
792
+ ftmp[12 + i] = a3 - a2;
793
+ }
794
+ for (let i = 0, o = 0; i < 4; i++, o += 64) {
795
+ const dc = ftmp[i * 4] + 3;
796
+ const a0 = dc + ftmp[i * 4 + 3], a1 = ftmp[i * 4 + 1] + ftmp[i * 4 + 2];
797
+ const a2 = ftmp[i * 4 + 1] - ftmp[i * 4 + 2], a3 = dc - ftmp[i * 4 + 3];
798
+ out[o] = (a0 + a1) >> 3;
799
+ out[o + 16] = (a3 + a2) >> 3;
800
+ out[o + 32] = (a0 - a1) >> 3;
801
+ out[o + 48] = (a3 - a2) >> 3;
802
+ }
803
+ }
804
+ export function sse4x4(a, ao, b, bo) {
805
+ const d00 = a[ao] - b[bo], d01 = a[ao + 1] - b[bo + 1], d02 = a[ao + 2] - b[bo + 2], d03 = a[ao + 3] - b[bo + 3];
806
+ const d10 = a[ao + 1 * BPS] - b[bo + 1 * BPS], d11 = a[ao + 1 * BPS + 1] - b[bo + 1 * BPS + 1], d12 = a[ao + 1 * BPS + 2] - b[bo + 1 * BPS + 2], d13 = a[ao + 1 * BPS + 3] - b[bo + 1 * BPS + 3];
807
+ const d20 = a[ao + 2 * BPS] - b[bo + 2 * BPS], d21 = a[ao + 2 * BPS + 1] - b[bo + 2 * BPS + 1], d22 = a[ao + 2 * BPS + 2] - b[bo + 2 * BPS + 2], d23 = a[ao + 2 * BPS + 3] - b[bo + 2 * BPS + 3];
808
+ const d30 = a[ao + 3 * BPS] - b[bo + 3 * BPS], d31 = a[ao + 3 * BPS + 1] - b[bo + 3 * BPS + 1], d32 = a[ao + 3 * BPS + 2] - b[bo + 3 * BPS + 2], d33 = a[ao + 3 * BPS + 3] - b[bo + 3 * BPS + 3];
809
+ return d00 * d00 + d01 * d01 + d02 * d02 + d03 * d03 + d10 * d10 + d11 * d11 + d12 * d12 + d13 * d13 + d20 * d20 + d21 * d21 + d22 * d22 + d23 * d23 + d30 * d30 + d31 * d31 + d32 * d32 + d33 * d33;
810
+ }
811
+ export function sse16(a, ao, b, bo, h) {
812
+ let count = 0;
813
+ for (let y = 0; y < h; y++, ao += BPS, bo += BPS) {
814
+ const d0 = a[ao] - b[bo], d1 = a[ao + 1] - b[bo + 1], d2 = a[ao + 2] - b[bo + 2], d3 = a[ao + 3] - b[bo + 3], d4 = a[ao + 4] - b[bo + 4], d5 = a[ao + 5] - b[bo + 5], d6 = a[ao + 6] - b[bo + 6], d7 = a[ao + 7] - b[bo + 7], d8 = a[ao + 8] - b[bo + 8], d9 = a[ao + 9] - b[bo + 9], d10 = a[ao + 10] - b[bo + 10], d11 = a[ao + 11] - b[bo + 11], d12 = a[ao + 12] - b[bo + 12], d13 = a[ao + 13] - b[bo + 13], d14 = a[ao + 14] - b[bo + 14], d15 = a[ao + 15] - b[bo + 15];
815
+ count += d0 * d0 + d1 * d1 + d2 * d2 + d3 * d3 + d4 * d4 + d5 * d5 + d6 * d6 + d7 * d7 + d8 * d8 + d9 * d9 + d10 * d10 + d11 * d11 + d12 * d12 + d13 * d13 + d14 * d14 + d15 * d15;
816
+ }
817
+ return count;
818
+ }
819
+ export function tTransform(input, i, w) {
820
+ let sum = 0;
821
+ for (let k = 0; k < 4; k++, i += BPS) {
822
+ const a0 = input[i] + input[i + 2], a1 = input[i + 1] + input[i + 3], a2 = input[i + 1] - input[i + 3], a3 = input[i] - input[i + 2];
823
+ ftmp[k * 4] = a0 + a1;
824
+ ftmp[k * 4 + 1] = a3 + a2;
825
+ ftmp[k * 4 + 2] = a3 - a2;
826
+ ftmp[k * 4 + 3] = a0 - a1;
827
+ }
828
+ for (let k = 0; k < 4; k++) {
829
+ const a0 = ftmp[k] + ftmp[8 + k], a1 = ftmp[4 + k] + ftmp[12 + k], a2 = ftmp[4 + k] - ftmp[12 + k], a3 = ftmp[k] - ftmp[8 + k];
830
+ sum += w[k] * Math.abs(a0 + a1) + w[k + 4] * Math.abs(a3 + a2) + w[k + 8] * Math.abs(a3 - a2) + w[k + 12] * Math.abs(a0 - a1);
831
+ }
832
+ return sum;
833
+ }
834
+ export function tDisto4x4(source, b, bo, w) {
835
+ return Math.abs(tTransform(b, bo, w) - source) >> 5;
836
+ }
837
+ export function tDisto16x16(sources, b, bo, w) {
838
+ let d = 0;
839
+ for (let n = 0; n < 16; n++)
840
+ d += tDisto4x4(sources[n], b, bo + SCAN[n], w);
841
+ return d;
842
+ }
843
+ export function isFlatSource16(src, s) {
844
+ const v = src[s];
845
+ for (let y = 0; y < 16; y++)
846
+ for (let x = 0; x < 16; x++)
847
+ if (src[s + y * BPS + x] !== v)
848
+ return false;
849
+ return true;
850
+ }
851
+ export function isFlat(levels, l, num, thresh) {
852
+ let score = 0;
853
+ for (; num > 0; num--, l += 16) {
854
+ for (let i = 1; i < 16; i++) {
855
+ if (levels[l + i])
856
+ score++;
857
+ if (score > thresh)
858
+ return false;
859
+ }
860
+ }
861
+ return true;
862
+ }
863
+ export const newMatrix = () => ({
864
+ q: new Uint16Array(16), iq: new Uint16Array(16), bias: new Uint32Array(16), zthresh: new Uint32Array(16), sharpen: new Uint16Array(16)
865
+ });
866
+ export function quantizeBlock(input, i, out, o, m) {
867
+ let nz = 0;
868
+ const sharpen = m.sharpen;
869
+ {
870
+ const c = input[i], sign = c < 0;
871
+ const coeff = (sign ? -c : c) + sharpen[0];
872
+ if (coeff > m.zthresh[0]) {
873
+ let level = (coeff * m.iq[0] + m.bias[0]) >>> QFIX;
874
+ if (level > MAX_LEVEL)
875
+ level = MAX_LEVEL;
876
+ if (sign)
877
+ level = -level;
878
+ input[i] = level * m.q[0];
879
+ out[o] = level;
880
+ nz |= level;
881
+ }
882
+ else
883
+ out[o] = input[i] = 0;
884
+ }
885
+ const q = m.q[1], iq = m.iq[1], bias = m.bias[1], zthresh = m.zthresh[1];
886
+ for (let n = 1; n < 16; n++) {
887
+ const j = ZIGZAG[n];
888
+ const c = input[i + j], sign = c < 0;
889
+ const coeff = (sign ? -c : c) + sharpen[j];
890
+ if (coeff > zthresh) {
891
+ let level = (coeff * iq + bias) >>> QFIX;
892
+ if (level > MAX_LEVEL)
893
+ level = MAX_LEVEL;
894
+ if (sign)
895
+ level = -level;
896
+ input[i + j] = level * q;
897
+ out[o + n] = level;
898
+ nz |= level;
899
+ }
900
+ else
901
+ out[o + n] = input[i + j] = 0;
902
+ }
903
+ return nz !== 0;
904
+ }
905
+ export function mean16x4(src, s, dc, d) {
906
+ for (let k = 0; k < 4; k++, s += 4) {
907
+ let sum = 0;
908
+ for (let y = 0; y < 4; y++)
909
+ for (let x = 0; x < 4; x++)
910
+ sum += src[s + x + y * BPS];
911
+ dc[d + k] = sum;
912
+ }
913
+ }
914
+ const distribution = new Int32Array(32);
915
+ const DSP_SCAN = [...SCAN, 0, 4, 4 * BPS, 4 * BPS + 4, 8, 12, 4 * BPS + 8, 4 * BPS + 12];
916
+ export function histogramAlpha(ref, r, pred, p, start, end) {
917
+ distribution.fill(0);
918
+ let zeros = 0;
919
+ for (let j = start; j < end; j++) {
920
+ zeros += fTransformHistogram(ref, r + DSP_SCAN[j], pred, p + DSP_SCAN[j], distribution);
921
+ }
922
+ distribution[0] += zeros;
923
+ let max = 0, last = 1;
924
+ for (let k = 0; k <= 31; k++) {
925
+ if (distribution[k] > 0) {
926
+ if (distribution[k] > max)
927
+ max = distribution[k];
928
+ last = k;
929
+ }
930
+ }
931
+ return max > 1 ? Math.trunc(510 * last / max) : 0;
932
+ }