imagescript 3.2.1 → 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 (101) hide show
  1. package/README.md +35 -10
  2. package/THIRD_PARTY_NOTICES.md +298 -2
  3. package/dist/animation.d.ts +25 -8
  4. package/dist/animation.js +44 -13
  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/crc.js +5 -0
  21. package/dist/codecs/gif.js +10 -35
  22. package/dist/codecs/hdr.d.ts +25 -0
  23. package/dist/codecs/hdr.js +201 -0
  24. package/dist/codecs/ico.js +48 -0
  25. package/dist/codecs/jpeg.js +11 -28
  26. package/dist/codecs/jxl/bits.js +126 -0
  27. package/dist/codecs/jxl/blend.js +117 -0
  28. package/dist/codecs/jxl/color.js +116 -0
  29. package/dist/codecs/jxl/dct.js +404 -0
  30. package/dist/codecs/jxl/entropy.js +556 -0
  31. package/dist/codecs/jxl/features.js +325 -0
  32. package/dist/codecs/jxl/filters.js +119 -0
  33. package/dist/codecs/jxl/frame-header.js +195 -0
  34. package/dist/codecs/jxl/frame.js +319 -0
  35. package/dist/codecs/jxl/headers.js +249 -0
  36. package/dist/codecs/jxl/idct.js +484 -0
  37. package/dist/codecs/jxl/modular.js +688 -0
  38. package/dist/codecs/jxl/quant.js +219 -0
  39. package/dist/codecs/jxl/upsample.js +52 -0
  40. package/dist/codecs/jxl/vardct.js +472 -0
  41. package/dist/codecs/jxl.js +89 -0
  42. package/dist/codecs/netpbm.js +239 -0
  43. package/dist/codecs/png.js +22 -10
  44. package/dist/codecs/qoi.js +150 -0
  45. package/dist/codecs/tga.js +3 -1
  46. package/dist/codecs/tiff.js +7 -2
  47. package/dist/codecs/vp8-enc-dsp.js +932 -0
  48. package/dist/codecs/vp8-enc-tables.js +78 -0
  49. package/dist/codecs/vp8-enc.js +1930 -0
  50. package/dist/codecs/vp8.js +3 -1
  51. package/dist/codecs/vp8l.js +126 -58
  52. package/dist/codecs/webp.js +47 -11
  53. package/dist/codecs/zlib.js +81 -69
  54. package/dist/frame.d.ts +1 -0
  55. package/dist/frame.js +4 -2
  56. package/dist/gif.d.ts +1 -0
  57. package/dist/gif.js +2 -2
  58. package/dist/image-type.d.ts +15 -1
  59. package/dist/image-type.js +45 -2
  60. package/dist/image.d.ts +89 -13
  61. package/dist/image.js +266 -113
  62. package/dist/index.d.ts +3 -2
  63. package/dist/index.js +4 -4
  64. package/dist/render/bidi.js +350 -0
  65. package/dist/render/buffer.js +362 -0
  66. package/dist/render/color.js +164 -0
  67. package/dist/render/colr.js +523 -0
  68. package/dist/render/font.js +173 -241
  69. package/dist/render/hinting.js +38 -22
  70. package/dist/render/layout.js +1553 -0
  71. package/dist/render/linebreak.js +210 -0
  72. package/dist/render/segment.js +106 -0
  73. package/dist/render/shape.js +984 -0
  74. package/dist/render/shapers/arabic.js +284 -0
  75. package/dist/render/shapers/hangul.js +142 -0
  76. package/dist/render/shapers/hebrew.js +49 -0
  77. package/dist/render/shapers/index.js +52 -0
  78. package/dist/render/shapers/indic.js +579 -0
  79. package/dist/render/shapers/khmer.js +104 -0
  80. package/dist/render/shapers/machine.js +129 -0
  81. package/dist/render/shapers/myanmar.js +121 -0
  82. package/dist/render/shapers/syllabic.js +100 -0
  83. package/dist/render/shapers/thai.js +125 -0
  84. package/dist/render/shapers/use.js +235 -0
  85. package/dist/render/svg.js +102 -23
  86. package/dist/render/text.js +373 -103
  87. package/dist/render/unicode-data.js +63 -0
  88. package/dist/render/unicode.js +50 -0
  89. package/dist/text-layout.d.ts +4 -1
  90. package/dist/text-layout.js +2 -2
  91. package/dist/util/alpha.js +43 -0
  92. package/dist/util/blur.js +20 -33
  93. package/dist/util/bytes.js +40 -0
  94. package/dist/util/limits.js +34 -0
  95. package/dist/util/options.js +7 -0
  96. package/dist/util/resample.js +126 -7
  97. package/dist/util/rotate.js +43 -0
  98. package/dist/version.js +1 -1
  99. package/licenses/HarfBuzz.txt +42 -0
  100. package/licenses/Unicode-3.0.txt +39 -0
  101. package/package.json +25 -2
@@ -0,0 +1,491 @@
1
+ /*!
2
+ * AV1 intra prediction: the edges of a block, and DC, directional, smooth, Paeth, filter, chroma from luma and
3
+ * palette prediction, ported from dav1d (src/ipred_prepare_tmpl.c, src/ipred_tmpl.c). Copyright (c) 2018-2021,
4
+ * VideoLAN and dav1d authors, Copyright (c) 2018, Two Orioles, LLC, BSD-2-Clause License (see THIRD_PARTY_NOTICES.md)
5
+ */
6
+ import { DC_PRED, VERT_PRED, HOR_PRED, VERT_LEFT_PRED, SMOOTH_PRED, SMOOTH_V_PRED, SMOOTH_H_PRED, PAETH_PRED, FILTER_PRED, LEFT_DC_PRED, TOP_DC_PRED, DC_128_PRED, Z1_PRED, Z2_PRED, Z3_PRED, EDGE_I444_TOP_HAS_RIGHT, EDGE_I444_LEFT_HAS_BOTTOM, SM_WEIGHTS, DR_INTRA_DERIVATIVE, FILTER_INTRA_TAPS } from "./tables.js";
7
+ export const ANGLE_USE_EDGE_FILTER = 1024, ANGLE_SMOOTH_EDGE = 512;
8
+ export const EDGE = 128;
9
+ export const edgeBuffer = new Uint16Array(2 * EDGE + 1);
10
+ const MODE_TO_ANGLE = [90, 180, 45, 135, 113, 157, 203, 67];
11
+ const NEEDS_LEFT = 1, NEEDS_TOP = 2, NEEDS_TOPLEFT = 4, NEEDS_TOPRIGHT = 8, NEEDS_BOTTOMLEFT = 16;
12
+ const NEEDS = [];
13
+ NEEDS[DC_PRED] = NEEDS_TOP | NEEDS_LEFT;
14
+ NEEDS[VERT_PRED] = NEEDS_TOP;
15
+ NEEDS[HOR_PRED] = NEEDS_LEFT;
16
+ NEEDS[LEFT_DC_PRED] = NEEDS_LEFT;
17
+ NEEDS[TOP_DC_PRED] = NEEDS_TOP;
18
+ NEEDS[DC_128_PRED] = 0;
19
+ NEEDS[Z1_PRED] = NEEDS_TOP | NEEDS_TOPRIGHT | NEEDS_TOPLEFT;
20
+ NEEDS[Z2_PRED] = NEEDS_LEFT | NEEDS_TOP | NEEDS_TOPLEFT;
21
+ NEEDS[Z3_PRED] = NEEDS_LEFT | NEEDS_BOTTOMLEFT | NEEDS_TOPLEFT;
22
+ NEEDS[SMOOTH_PRED] = NEEDS[SMOOTH_V_PRED] = NEEDS[SMOOTH_H_PRED] = NEEDS_LEFT | NEEDS_TOP;
23
+ NEEDS[PAETH_PRED] = NEEDS[FILTER_PRED] = NEEDS_LEFT | NEEDS_TOP | NEEDS_TOPLEFT;
24
+ export let preparedAngle = 0;
25
+ export function prepareEdges(x, haveLeft, y, haveTop, w, h, edgeFlags, pic, dst, stride, mode, angle, tw, th, filterEdge, bitdepth) {
26
+ const e = edgeBuffer;
27
+ if (mode >= VERT_PRED && mode <= VERT_LEFT_PRED) {
28
+ angle = MODE_TO_ANGLE[mode - VERT_PRED] + 3 * angle;
29
+ if (angle <= 90)
30
+ mode = angle < 90 && haveTop ? Z1_PRED : VERT_PRED;
31
+ else if (angle < 180)
32
+ mode = Z2_PRED;
33
+ else
34
+ mode = angle > 180 && haveLeft ? Z3_PRED : HOR_PRED;
35
+ }
36
+ else if (mode === DC_PRED) {
37
+ mode = haveLeft ? haveTop ? DC_PRED : LEFT_DC_PRED : haveTop ? TOP_DC_PRED : DC_128_PRED;
38
+ }
39
+ else if (mode === PAETH_PRED) {
40
+ mode = haveLeft ? haveTop ? PAETH_PRED : HOR_PRED : haveTop ? VERT_PRED : DC_128_PRED;
41
+ }
42
+ preparedAngle = angle;
43
+ const needs = NEEDS[mode];
44
+ const top = dst - stride;
45
+ if (needs & NEEDS_LEFT) {
46
+ const sz = th << 2, left = EDGE - sz;
47
+ if (haveLeft) {
48
+ const have = Math.min(sz, (h - y) << 2);
49
+ for (let i = 0; i < have; i++)
50
+ e[left + sz - 1 - i] = pic[dst + stride * i - 1];
51
+ if (have < sz)
52
+ e.fill(e[left + sz - have], left, left + sz - have);
53
+ }
54
+ else
55
+ e.fill(haveTop ? pic[top] : (1 << bitdepth >> 1) + 1, left, left + sz);
56
+ if (needs & NEEDS_BOTTOMLEFT) {
57
+ const haveBottomLeft = haveLeft && y + th < h && edgeFlags & EDGE_I444_LEFT_HAS_BOTTOM;
58
+ if (haveBottomLeft) {
59
+ const have = Math.min(sz, (h - y - th) << 2);
60
+ for (let i = 0; i < have; i++)
61
+ e[left - 1 - i] = pic[dst + (sz + i) * stride - 1];
62
+ if (have < sz)
63
+ e.fill(e[left - have], left - sz, left - have);
64
+ }
65
+ else
66
+ e.fill(e[left], left - sz, left);
67
+ }
68
+ }
69
+ if (needs & NEEDS_TOP) {
70
+ const sz = tw << 2, t = EDGE + 1;
71
+ if (haveTop) {
72
+ const have = Math.min(sz, (w - x) << 2);
73
+ for (let i = 0; i < have; i++)
74
+ e[t + i] = pic[top + i];
75
+ if (have < sz)
76
+ e.fill(e[t + have - 1], t + have, t + sz);
77
+ }
78
+ else
79
+ e.fill(haveLeft ? pic[dst - 1] : (1 << bitdepth >> 1) - 1, t, t + sz);
80
+ if (needs & NEEDS_TOPRIGHT) {
81
+ const haveTopRight = haveTop && x + tw < w && edgeFlags & EDGE_I444_TOP_HAS_RIGHT;
82
+ if (haveTopRight) {
83
+ const have = Math.min(sz, (w - x - tw) << 2);
84
+ for (let i = 0; i < have; i++)
85
+ e[t + sz + i] = pic[top + sz + i];
86
+ if (have < sz)
87
+ e.fill(e[t + sz + have - 1], t + sz + have, t + 2 * sz);
88
+ }
89
+ else
90
+ e.fill(e[t + sz - 1], t + sz, t + 2 * sz);
91
+ }
92
+ }
93
+ if (needs & NEEDS_TOPLEFT) {
94
+ if (haveLeft)
95
+ e[EDGE] = haveTop ? pic[top - 1] : pic[dst - 1];
96
+ else
97
+ e[EDGE] = haveTop ? pic[top] : 1 << bitdepth >> 1;
98
+ if (mode === Z2_PRED && tw + th >= 6 && filterEdge)
99
+ e[EDGE] = ((e[EDGE - 1] + e[EDGE + 1]) * 5 + e[EDGE] * 6 + 8) >> 4;
100
+ }
101
+ return mode;
102
+ }
103
+ function splat(dst, d, stride, width, height, v) {
104
+ for (let y = 0; y < height; y++, d += stride)
105
+ dst.fill(v, d, d + width);
106
+ }
107
+ const ctz = (v) => 31 - Math.clz32(v & -v);
108
+ function dcTop(e, width) {
109
+ let dc = width >> 1;
110
+ for (let i = 0; i < width; i++)
111
+ dc += e[EDGE + 1 + i];
112
+ return dc >> ctz(width);
113
+ }
114
+ function dcLeft(e, height) {
115
+ let dc = height >> 1;
116
+ for (let i = 0; i < height; i++)
117
+ dc += e[EDGE - 1 - i];
118
+ return dc >> ctz(height);
119
+ }
120
+ function dcBoth(e, width, height, hbd) {
121
+ let dc = (width + height) >> 1;
122
+ for (let i = 0; i < width; i++)
123
+ dc += e[EDGE + 1 + i];
124
+ for (let i = 0; i < height; i++)
125
+ dc += e[EDGE - 1 - i];
126
+ dc >>= ctz(width + height);
127
+ if (width !== height) {
128
+ const quarter = width > height * 2 || height > width * 2;
129
+ dc = hbd ? Math.floor(dc * (quarter ? 0x6667 : 0xAAAB) / 131072) : dc * (quarter ? 0x3334 : 0x5556) >>> 16;
130
+ }
131
+ return dc;
132
+ }
133
+ export function dcValue(mode, width, height, bitdepthMax) {
134
+ const e = edgeBuffer;
135
+ switch (mode) {
136
+ case DC_PRED: return dcBoth(e, width, height, bitdepthMax > 255);
137
+ case LEFT_DC_PRED: return dcLeft(e, height);
138
+ case TOP_DC_PRED: return dcTop(e, width);
139
+ default: return (bitdepthMax + 1) >> 1;
140
+ }
141
+ }
142
+ function filterStrength(wh, angle, smooth) {
143
+ if (smooth) {
144
+ if (wh <= 8) {
145
+ if (angle >= 64)
146
+ return 2;
147
+ if (angle >= 40)
148
+ return 1;
149
+ }
150
+ else if (wh <= 16) {
151
+ if (angle >= 48)
152
+ return 2;
153
+ if (angle >= 20)
154
+ return 1;
155
+ }
156
+ else if (wh <= 24) {
157
+ if (angle >= 4)
158
+ return 3;
159
+ }
160
+ else
161
+ return 3;
162
+ }
163
+ else {
164
+ if (wh <= 8) {
165
+ if (angle >= 56)
166
+ return 1;
167
+ }
168
+ else if (wh <= 16) {
169
+ if (angle >= 40)
170
+ return 1;
171
+ }
172
+ else if (wh <= 24) {
173
+ if (angle >= 32)
174
+ return 3;
175
+ if (angle >= 16)
176
+ return 2;
177
+ if (angle >= 8)
178
+ return 1;
179
+ }
180
+ else if (wh <= 32) {
181
+ if (angle >= 32)
182
+ return 3;
183
+ if (angle >= 4)
184
+ return 2;
185
+ return 1;
186
+ }
187
+ else
188
+ return 3;
189
+ }
190
+ return 0;
191
+ }
192
+ const KERNELS = [[0, 4, 8, 4, 0], [0, 5, 6, 5, 0], [2, 4, 4, 4, 2]];
193
+ const clampIndex = (i, from, to) => i < from ? from : i > to - 1 ? to - 1 : i;
194
+ function filterEdge(out, o, sz, limFrom, limTo, inp, i0, from, to, strength) {
195
+ const k = KERNELS[strength - 1];
196
+ let i = 0;
197
+ for (; i < Math.min(sz, limFrom); i++)
198
+ out[o + i] = inp[i0 + clampIndex(i, from, to)];
199
+ for (; i < Math.min(limTo, sz); i++) {
200
+ let s = 0;
201
+ for (let j = 0; j < 5; j++)
202
+ s += inp[i0 + clampIndex(i - 2 + j, from, to)] * k[j];
203
+ out[o + i] = (s + 8) >> 4;
204
+ }
205
+ for (; i < sz; i++)
206
+ out[o + i] = inp[i0 + clampIndex(i, from, to)];
207
+ }
208
+ const upsampled = (wh, angle, smooth) => angle < 40 && wh <= 16 >> (smooth ? 1 : 0);
209
+ function upsampleEdge(out, o, hsz, inp, i0, from, to, bitdepthMax) {
210
+ let i;
211
+ for (i = 0; i < hsz - 1; i++) {
212
+ out[o + i * 2] = inp[i0 + clampIndex(i, from, to)];
213
+ const s = -inp[i0 + clampIndex(i - 1, from, to)] + 9 * inp[i0 + clampIndex(i, from, to)] + 9 * inp[i0 + clampIndex(i + 1, from, to)] - inp[i0 + clampIndex(i + 2, from, to)];
214
+ const v = (s + 8) >> 4;
215
+ out[o + i * 2 + 1] = v < 0 ? 0 : v > bitdepthMax ? bitdepthMax : v;
216
+ }
217
+ out[o + i * 2] = inp[i0 + clampIndex(i, from, to)];
218
+ }
219
+ const scratch = new Uint16Array(64 + 64 + 1);
220
+ function z1(dst, d, stride, width, height, angle, bitdepthMax) {
221
+ const e = edgeBuffer;
222
+ const smooth = !!(angle >> 9 & 1), edgeFilter = !!(angle >> 10);
223
+ angle &= 511;
224
+ let dx = DR_INTRA_DERIVATIVE[angle >> 1];
225
+ let top, t0, maxBase;
226
+ const up = edgeFilter && upsampled(width + height, 90 - angle, smooth);
227
+ if (up) {
228
+ upsampleEdge(scratch, 0, width + height, e, EDGE + 1, -1, width + Math.min(width, height), bitdepthMax);
229
+ top = scratch;
230
+ t0 = 0;
231
+ maxBase = 2 * (width + height) - 2;
232
+ dx <<= 1;
233
+ }
234
+ else {
235
+ const strength = edgeFilter ? filterStrength(width + height, 90 - angle, smooth) : 0;
236
+ if (strength) {
237
+ filterEdge(scratch, 0, width + height, 0, width + height, e, EDGE + 1, -1, width + Math.min(width, height), strength);
238
+ top = scratch;
239
+ t0 = 0;
240
+ maxBase = width + height - 1;
241
+ }
242
+ else {
243
+ top = e;
244
+ t0 = EDGE + 1;
245
+ maxBase = width + Math.min(width, height) - 1;
246
+ }
247
+ }
248
+ const inc = up ? 2 : 1;
249
+ for (let y = 0, xpos = dx; y < height; y++, d += stride, xpos += dx) {
250
+ const frac = xpos & 0x3e;
251
+ for (let x = 0, base = xpos >> 6; x < width; x++, base += inc) {
252
+ if (base < maxBase)
253
+ dst[d + x] = (top[t0 + base] * (64 - frac) + top[t0 + base + 1] * frac + 32) >> 6;
254
+ else {
255
+ dst.fill(top[t0 + maxBase], d + x, d + width);
256
+ break;
257
+ }
258
+ }
259
+ }
260
+ }
261
+ function z2(dst, d, stride, width, height, angle, maxWidth, maxHeight, bitdepthMax) {
262
+ const e = edgeBuffer;
263
+ const smooth = !!(angle >> 9 & 1), edgeFilter = !!(angle >> 10);
264
+ angle &= 511;
265
+ let dy = DR_INTRA_DERIVATIVE[(angle - 90) >> 1];
266
+ let dx = DR_INTRA_DERIVATIVE[(180 - angle) >> 1];
267
+ const upLeft = edgeFilter && upsampled(width + height, 180 - angle, smooth);
268
+ const upAbove = edgeFilter && upsampled(width + height, angle - 90, smooth);
269
+ const s = scratch, tl = 64;
270
+ if (upAbove) {
271
+ upsampleEdge(s, tl, width + 1, e, EDGE, 0, width + 1, bitdepthMax);
272
+ dx <<= 1;
273
+ }
274
+ else {
275
+ const strength = edgeFilter ? filterStrength(width + height, angle - 90, smooth) : 0;
276
+ if (strength)
277
+ filterEdge(s, tl + 1, width, 0, maxWidth, e, EDGE + 1, -1, width, strength);
278
+ else
279
+ s.set(e.subarray(EDGE + 1, EDGE + 1 + width), tl + 1);
280
+ }
281
+ if (upLeft) {
282
+ upsampleEdge(s, tl - height * 2, height + 1, e, EDGE - height, 0, height + 1, bitdepthMax);
283
+ dy <<= 1;
284
+ }
285
+ else {
286
+ const strength = edgeFilter ? filterStrength(width + height, 180 - angle, smooth) : 0;
287
+ if (strength)
288
+ filterEdge(s, tl - height, height, height - maxHeight, height, e, EDGE - height, 0, height + 1, strength);
289
+ else
290
+ s.set(e.subarray(EDGE - height, EDGE), tl - height);
291
+ }
292
+ s[tl] = e[EDGE];
293
+ const incX = upAbove ? 2 : 1;
294
+ const left = tl - (upLeft ? 2 : 1);
295
+ for (let y = 0, xpos = ((upAbove ? 2 : 1) << 6) - dx; y < height; y++, xpos -= dx, d += stride) {
296
+ let baseX = xpos >> 6;
297
+ const fracX = xpos & 0x3e;
298
+ for (let x = 0, ypos = (y << (6 + (upLeft ? 1 : 0))) - dy; x < width; x++, baseX += incX, ypos -= dy) {
299
+ let v;
300
+ if (baseX >= 0)
301
+ v = s[tl + baseX] * (64 - fracX) + s[tl + baseX + 1] * fracX;
302
+ else {
303
+ const baseY = ypos >> 6, fracY = ypos & 0x3e;
304
+ v = s[left - baseY] * (64 - fracY) + s[left - baseY - 1] * fracY;
305
+ }
306
+ dst[d + x] = (v + 32) >> 6;
307
+ }
308
+ }
309
+ }
310
+ function z3(dst, d, stride, width, height, angle, bitdepthMax) {
311
+ const e = edgeBuffer;
312
+ const smooth = !!(angle >> 9 & 1), edgeFilter = !!(angle >> 10);
313
+ angle &= 511;
314
+ let dy = DR_INTRA_DERIVATIVE[(270 - angle) >> 1];
315
+ let left, l0, maxBase;
316
+ const up = edgeFilter && upsampled(width + height, angle - 180, smooth);
317
+ if (up) {
318
+ upsampleEdge(scratch, 0, width + height, e, EDGE - (width + height), Math.max(width - height, 0), width + height + 1, bitdepthMax);
319
+ left = scratch;
320
+ l0 = 2 * (width + height) - 2;
321
+ maxBase = 2 * (width + height) - 2;
322
+ dy <<= 1;
323
+ }
324
+ else {
325
+ const strength = edgeFilter ? filterStrength(width + height, angle - 180, smooth) : 0;
326
+ if (strength) {
327
+ filterEdge(scratch, 0, width + height, 0, width + height, e, EDGE - (width + height), Math.max(width - height, 0), width + height + 1, strength);
328
+ left = scratch;
329
+ l0 = width + height - 1;
330
+ maxBase = width + height - 1;
331
+ }
332
+ else {
333
+ left = e;
334
+ l0 = EDGE - 1;
335
+ maxBase = height + Math.min(width, height) - 1;
336
+ }
337
+ }
338
+ const inc = up ? 2 : 1;
339
+ for (let x = 0, ypos = dy; x < width; x++, ypos += dy) {
340
+ const frac = ypos & 0x3e;
341
+ for (let y = 0, base = ypos >> 6; y < height; y++, base += inc) {
342
+ if (base < maxBase)
343
+ dst[d + y * stride + x] = (left[l0 - base] * (64 - frac) + left[l0 - base - 1] * frac + 32) >> 6;
344
+ else {
345
+ for (; y < height; y++)
346
+ dst[d + y * stride + x] = left[l0 - maxBase];
347
+ break;
348
+ }
349
+ }
350
+ }
351
+ }
352
+ function filterIntra(dst, d, stride, width, height, filter, bitdepthMax) {
353
+ const e = edgeBuffer;
354
+ const taps = filter * 56;
355
+ let topArr = e, top = EDGE + 1;
356
+ for (let y = 0; y < height; y += 2) {
357
+ let tlArr = e, tl = EDGE - y;
358
+ let leftArr = e, left = tl - 1, leftStride = -1;
359
+ for (let x = 0; x < width; x += 4) {
360
+ const p0 = tlArr[tl];
361
+ const p1 = topArr[top], p2 = topArr[top + 1], p3 = topArr[top + 2], p4 = topArr[top + 3];
362
+ const p5 = leftArr[left], p6 = leftArr[left + leftStride];
363
+ let ptr = d + x;
364
+ for (let yy = 0, k = 0; yy < 2; yy++, ptr += stride) {
365
+ for (let xx = 0; xx < 4; xx++, k++) {
366
+ const t = taps + k * 7;
367
+ const acc = FILTER_INTRA_TAPS[t] * p0 + FILTER_INTRA_TAPS[t + 1] * p1 + FILTER_INTRA_TAPS[t + 2] * p2 +
368
+ FILTER_INTRA_TAPS[t + 3] * p3 + FILTER_INTRA_TAPS[t + 4] * p4 + FILTER_INTRA_TAPS[t + 5] * p5 +
369
+ FILTER_INTRA_TAPS[t + 6] * p6;
370
+ const v = (acc + 8) >> 4;
371
+ dst[ptr + xx] = v < 0 ? 0 : v > bitdepthMax ? bitdepthMax : v;
372
+ }
373
+ }
374
+ leftArr = dst;
375
+ left = d + x + 4 - 1;
376
+ leftStride = stride;
377
+ top += 4;
378
+ tlArr = topArr;
379
+ tl = top - 1;
380
+ }
381
+ topArr = dst;
382
+ top = d + stride;
383
+ d += stride * 2;
384
+ }
385
+ }
386
+ export function predict(mode, dst, d, stride, width, height, angle, maxWidth, maxHeight, bitdepthMax) {
387
+ const e = edgeBuffer;
388
+ switch (mode) {
389
+ case DC_PRED:
390
+ case LEFT_DC_PRED:
391
+ case TOP_DC_PRED:
392
+ case DC_128_PRED:
393
+ return splat(dst, d, stride, width, height, dcValue(mode, width, height, bitdepthMax));
394
+ case VERT_PRED:
395
+ for (let y = 0; y < height; y++, d += stride)
396
+ dst.set(e.subarray(EDGE + 1, EDGE + 1 + width), d);
397
+ return;
398
+ case HOR_PRED:
399
+ for (let y = 0; y < height; y++, d += stride)
400
+ dst.fill(e[EDGE - 1 - y], d, d + width);
401
+ return;
402
+ case PAETH_PRED: {
403
+ const topleft = e[EDGE];
404
+ for (let y = 0; y < height; y++, d += stride) {
405
+ const left = e[EDGE - 1 - y];
406
+ for (let x = 0; x < width; x++) {
407
+ const top = e[EDGE + 1 + x];
408
+ const base = left + top - topleft;
409
+ const ldiff = Math.abs(left - base), tdiff = Math.abs(top - base), tldiff = Math.abs(topleft - base);
410
+ dst[d + x] = ldiff <= tdiff && ldiff <= tldiff ? left : tdiff <= tldiff ? top : topleft;
411
+ }
412
+ }
413
+ return;
414
+ }
415
+ case SMOOTH_PRED: {
416
+ const right = e[EDGE + width], bottom = e[EDGE - height];
417
+ for (let y = 0; y < height; y++, d += stride) {
418
+ const wv = SM_WEIGHTS[height + y], left = e[EDGE - 1 - y];
419
+ for (let x = 0; x < width; x++) {
420
+ const wh = SM_WEIGHTS[width + x];
421
+ dst[d + x] = (wv * e[EDGE + 1 + x] + (256 - wv) * bottom + wh * left + (256 - wh) * right + 256) >> 9;
422
+ }
423
+ }
424
+ return;
425
+ }
426
+ case SMOOTH_V_PRED: {
427
+ const bottom = e[EDGE - height];
428
+ for (let y = 0; y < height; y++, d += stride) {
429
+ const wv = SM_WEIGHTS[height + y];
430
+ for (let x = 0; x < width; x++)
431
+ dst[d + x] = (wv * e[EDGE + 1 + x] + (256 - wv) * bottom + 128) >> 8;
432
+ }
433
+ return;
434
+ }
435
+ case SMOOTH_H_PRED: {
436
+ const right = e[EDGE + width];
437
+ for (let y = 0; y < height; y++, d += stride) {
438
+ const left = e[EDGE - 1 - y];
439
+ for (let x = 0; x < width; x++) {
440
+ const wh = SM_WEIGHTS[width + x];
441
+ dst[d + x] = (wh * left + (256 - wh) * right + 128) >> 8;
442
+ }
443
+ }
444
+ return;
445
+ }
446
+ case Z1_PRED: return z1(dst, d, stride, width, height, angle, bitdepthMax);
447
+ case Z2_PRED: return z2(dst, d, stride, width, height, angle, maxWidth, maxHeight, bitdepthMax);
448
+ case Z3_PRED: return z3(dst, d, stride, width, height, angle, bitdepthMax);
449
+ case FILTER_PRED: return filterIntra(dst, d, stride, width, height, angle & 511, bitdepthMax);
450
+ }
451
+ }
452
+ export function cflAc(ac, y, yo, stride, wPad, hPad, width, height, ssHor, ssVer) {
453
+ let a = 0, row;
454
+ for (row = 0; row < height - 4 * hPad; row++) {
455
+ let x;
456
+ for (x = 0; x < width - 4 * wPad; x++) {
457
+ let sum = y[yo + (x << ssHor)];
458
+ if (ssHor)
459
+ sum += y[yo + x * 2 + 1];
460
+ if (ssVer) {
461
+ sum += y[yo + (x << ssHor) + stride];
462
+ if (ssHor)
463
+ sum += y[yo + x * 2 + 1 + stride];
464
+ }
465
+ ac[a + x] = sum << (1 + (ssVer ? 0 : 1) + (ssHor ? 0 : 1));
466
+ }
467
+ for (; x < width; x++)
468
+ ac[a + x] = ac[a + x - 1];
469
+ a += width;
470
+ yo += stride << ssVer;
471
+ }
472
+ for (; row < height; row++, a += width)
473
+ ac.copyWithin(a, a - width, a);
474
+ const log2 = ctz(width) + ctz(height);
475
+ let sum = (1 << log2) >> 1;
476
+ for (let i = 0; i < width * height; i++)
477
+ sum += ac[i];
478
+ sum >>= log2;
479
+ for (let i = 0; i < width * height; i++)
480
+ ac[i] -= sum;
481
+ }
482
+ export function cflPredict(mode, dst, d, stride, width, height, ac, alpha, bitdepthMax) {
483
+ const dc = dcValue(mode, width, height, bitdepthMax);
484
+ for (let y = 0, a = 0; y < height; y++, d += stride) {
485
+ for (let x = 0; x < width; x++, a++) {
486
+ const diff = alpha * ac[a];
487
+ const v = dc + (diff < 0 ? -((-diff + 32) >> 6) : (diff + 32) >> 6);
488
+ dst[d + x] = v < 0 ? 0 : v > bitdepthMax ? bitdepthMax : v;
489
+ }
490
+ }
491
+ }