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,1769 @@
1
+ /*!
2
+ * Decodes the tiles of AV1 intra frames: partitions, modes, palettes, transform sizes, coefficients and the intra
3
+ * reconstruction, ported from dav1d (src/decode.c, src/recon_tmpl.c, src/lf_mask.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 { SymbolDecoder } from "./msac.js";
7
+ import { RESTORATION_NONE, RESTORATION_SWITCHABLE, RESTORATION_WIENER, RESTORATION_SGRPROJ } from "./obu.js";
8
+ import { CDF, BLOCK_DIMENSIONS, TXFM_DIMENSIONS, MAX_TXFM_SIZE_FOR_BS, AL_PART_CTX, BLOCK_SIZES, PARTITION_TYPE_COUNT, INTRA_MODE_CONTEXT, TXTP_FROM_UVMODE, TX_TYPES_PER_SET, FILTER_MODE_TO_Y_MODE, LO_CTX_OFFSETS, SKIP_CTX, TX_TYPE_CLASS, SGR_PARAMS, CFL_ALLOWED_MASK, BL_128X128, BL_8X8, BS_128x128, BS_64x64, BS_4x4, PARTITION_NONE, PARTITION_H, PARTITION_V, PARTITION_SPLIT, PARTITION_T_TOP_SPLIT, PARTITION_T_BOTTOM_SPLIT, PARTITION_T_LEFT_SPLIT, PARTITION_T_RIGHT_SPLIT, PARTITION_H4, PARTITION_V4, DC_PRED, VERT_PRED, VERT_LEFT_PRED, SMOOTH_PRED, SMOOTH_V_PRED, SMOOTH_H_PRED, CFL_PRED, FILTER_PRED, TX_4X4, TX_64X64, TX_16X16, TX_32X32, RTX_4X8, DCT_DCT, IDTX, WHT_WHT, TX_CLASS_2D, TX_CLASS_H, EDGE_ALL_TR_AND_BL, EDGE_ALL_TOP_HAS_RIGHT, EDGE_ALL_LEFT_HAS_BOTTOM, EDGE_I444_TOP_HAS_RIGHT, EDGE_I444_LEFT_HAS_BOTTOM, EDGE_I420_TOP_HAS_RIGHT, EDGE_I420_LEFT_HAS_BOTTOM, edgeTree, defaultCdfs, scan, dequant, quantizerMatrix } from "./tables.js";
9
+ import { prepareEdges, predict, preparedAngle, cflAc, cflPredict, ANGLE_USE_EDGE_FILTER, ANGLE_SMOOTH_EDGE } from "./ipred.js";
10
+ import { inverseTransformAdd } from "./itx.js";
11
+ const bdim = (bs, i) => BLOCK_DIMENSIONS[bs * 4 + i];
12
+ const tdim = (tx, i) => TXFM_DIMENSIONS[tx * 8 + i];
13
+ const W = 0, H = 1, LW = 2, LH = 3, MIN = 4, MAX = 5, SUB = 6, CTX = 7;
14
+ export class Frame {
15
+ seq;
16
+ hdr;
17
+ width;
18
+ height;
19
+ bitdepth;
20
+ bitdepthMax;
21
+ layout;
22
+ ssx;
23
+ ssy;
24
+ planes = [];
25
+ strides = [];
26
+ bw;
27
+ bh;
28
+ b4Stride;
29
+ lfLevels;
30
+ txW;
31
+ txH;
32
+ uvTxW;
33
+ uvTxH;
34
+ skip;
35
+ cdefIdx;
36
+ segMap;
37
+ lr = [[], [], []];
38
+ lrUnitsW = [0, 0, 0];
39
+ lrUnitsH = [0, 0, 0];
40
+ incomplete = false;
41
+ constructor(seq, hdr) {
42
+ this.seq = seq;
43
+ this.hdr = hdr;
44
+ this.width = hdr.width;
45
+ this.height = hdr.height;
46
+ this.bitdepth = seq.bitDepth;
47
+ this.bitdepthMax = (1 << seq.bitDepth) - 1;
48
+ this.layout = seq.monochrome ? 0 : seq.ssx ? seq.ssy ? 1 : 2 : 3;
49
+ this.ssx = seq.ssx;
50
+ this.ssy = seq.ssy;
51
+ this.bw = (hdr.width + 7 >> 3) << 1;
52
+ this.bh = (hdr.height + 7 >> 3) << 1;
53
+ this.b4Stride = this.bw + 31 & ~31;
54
+ const b4Rows = this.bh + 31 & ~31;
55
+ const lumaStride = this.b4Stride * 4, lumaRows = b4Rows * 4;
56
+ for (let p = 0; p < (seq.monochrome ? 1 : 3); p++) {
57
+ const sx = p ? this.ssx : 0, sy = p ? this.ssy : 0;
58
+ this.strides.push(lumaStride >> sx);
59
+ this.planes.push(new Uint16Array((lumaStride >> sx) * (lumaRows >> sy)));
60
+ }
61
+ const n = this.b4Stride * b4Rows;
62
+ this.lfLevels = new Uint8Array(n * 4);
63
+ this.txW = new Uint8Array(n);
64
+ this.txH = new Uint8Array(n);
65
+ this.uvTxW = new Uint8Array(n);
66
+ this.uvTxH = new Uint8Array(n);
67
+ this.skip = new Uint8Array(n);
68
+ this.segMap = new Uint8Array(n);
69
+ this.cdefIdx = new Int8Array((this.b4Stride >> 4) * (b4Rows >> 4)).fill(-1);
70
+ }
71
+ }
72
+ function calcLfLevels(hdr, delta) {
73
+ const lf = hdr.loopFilter;
74
+ const out = [];
75
+ const value = (base, lfDelta, segDelta) => {
76
+ const b = Math.min(63, Math.max(0, Math.min(63, Math.max(0, base + lfDelta)) + segDelta));
77
+ if (!lf.modeRefDeltaEnabled)
78
+ return b;
79
+ return Math.min(63, Math.max(0, b + lf.refDeltas[0] * (1 << (b >= 32 ? 1 : 0))));
80
+ };
81
+ for (let s = 0; s < (hdr.segmentation.enabled ? 8 : 1); s++) {
82
+ if (!lf.levelY[0] && !lf.levelY[1]) {
83
+ out.push([0, 0, 0, 0]);
84
+ continue;
85
+ }
86
+ const seg = hdr.segmentation.enabled ? hdr.segmentation.data[s].deltaLf : [0, 0, 0, 0];
87
+ const multi = hdr.deltaLf.multi;
88
+ out.push([
89
+ value(lf.levelY[0], delta[0], seg[0]),
90
+ value(lf.levelY[1], delta[multi ? 1 : 0], seg[1]),
91
+ lf.levelU ? value(lf.levelU, delta[multi ? 2 : 0], seg[2]) : 0,
92
+ lf.levelV ? value(lf.levelV, delta[multi ? 3 : 0], seg[3]) : 0
93
+ ]);
94
+ }
95
+ return out;
96
+ }
97
+ function quantTables(seq, hdr, qidx) {
98
+ const q = hdr.quant, hbd = seq.bitDepth === 8 ? 0 : seq.bitDepth === 10 ? 1 : 2;
99
+ const clip = (v) => Math.min(255, Math.max(0, v));
100
+ const out = [];
101
+ for (let i = 0; i < (hdr.segmentation.enabled ? 8 : 1); i++) {
102
+ const yac = hdr.segmentation.enabled ? clip(qidx + hdr.segmentation.data[i].deltaQ) : qidx;
103
+ out.push([
104
+ [dequant(hbd, clip(yac + q.ydcDelta), 0), dequant(hbd, yac, 1)],
105
+ [dequant(hbd, clip(yac + q.udcDelta), 0), dequant(hbd, clip(yac + q.uacDelta), 1)],
106
+ [dequant(hbd, clip(yac + q.vdcDelta), 0), dequant(hbd, clip(yac + q.vacDelta), 1)]
107
+ ]);
108
+ }
109
+ return out;
110
+ }
111
+ const neg_deinterleave = (diff, ref, max) => {
112
+ if (!ref)
113
+ return diff;
114
+ if (ref >= max - 1)
115
+ return max - diff - 1;
116
+ if (2 * ref < max) {
117
+ if (diff <= 2 * ref)
118
+ return diff & 1 ? ref + (diff + 1 >> 1) : ref - (diff >> 1);
119
+ return diff;
120
+ }
121
+ if (diff <= 2 * (max - ref - 1))
122
+ return diff & 1 ? ref + (diff + 1 >> 1) : ref - (diff >> 1);
123
+ return max - (diff + 1);
124
+ };
125
+ export function decodeTileGroup(decoder, data, start, end, first, last) {
126
+ const hdr = decoder.frame.hdr;
127
+ let o = start;
128
+ for (let j = first; j <= last; j++) {
129
+ let size;
130
+ if (j === last)
131
+ size = end - o;
132
+ else {
133
+ size = 0;
134
+ for (let k = 0; k < hdr.tiles.sizeBytes; k++)
135
+ size += data[o++] * 2 ** (k * 8);
136
+ size++;
137
+ if (o + size > end)
138
+ throw new Error('AV1: invalid tile size');
139
+ }
140
+ decoder.decodeTile(data, o, o + size, Math.floor(j / hdr.tiles.cols), j % hdr.tiles.cols);
141
+ o += size;
142
+ }
143
+ }
144
+ export class TileDecoder {
145
+ frame;
146
+ seq;
147
+ hdr;
148
+ msac;
149
+ cdf;
150
+ bx = 0;
151
+ by = 0;
152
+ colStart = 0;
153
+ colEnd = 0;
154
+ rowStart = 0;
155
+ rowEnd = 0;
156
+ lastQidx = 0;
157
+ lastDeltaLf = [0, 0, 0, 0];
158
+ dq;
159
+ frameDq;
160
+ lfLvl;
161
+ frameLfLvl;
162
+ lrRef = [];
163
+ cdefSb = 0;
164
+ aMode;
165
+ lMode = new Uint8Array(32);
166
+ aLcoef;
167
+ lLcoef = new Uint8Array(32);
168
+ aCcoef;
169
+ lCcoef = [new Uint8Array(32), new Uint8Array(32)];
170
+ aSegPred;
171
+ lSegPred = new Uint8Array(32);
172
+ aSkip;
173
+ lSkip = new Uint8Array(32);
174
+ aIntra;
175
+ lIntra = new Uint8Array(32);
176
+ aTxIntra;
177
+ lTxIntra = new Int8Array(32);
178
+ aTx;
179
+ lTx = new Int8Array(32);
180
+ aUvmode;
181
+ lUvmode = new Uint8Array(32);
182
+ aPalSz;
183
+ lPalSz = new Uint8Array(32);
184
+ aPalSzUv;
185
+ lPalSzUv = new Uint8Array(32);
186
+ aPartition;
187
+ lPartition = new Uint8Array(16);
188
+ aPal;
189
+ lPal = new Uint16Array(32 * 24);
190
+ pal = new Uint16Array(24);
191
+ palIdxY = new Uint8Array(64 * 64);
192
+ palIdxUv = new Uint8Array(64 * 64);
193
+ palTmp = new Uint8Array(64 * 64);
194
+ cf = new Int32Array(32 * 32);
195
+ levels = new Uint8Array(36 * 36);
196
+ ac = new Int16Array(32 * 32);
197
+ qm = [];
198
+ constructor(frame) {
199
+ this.frame = frame;
200
+ this.seq = frame.seq;
201
+ this.hdr = frame.hdr;
202
+ const n = frame.b4Stride + 32;
203
+ this.aMode = new Uint8Array(n);
204
+ this.aLcoef = new Uint8Array(n);
205
+ this.aCcoef = [new Uint8Array(n), new Uint8Array(n)];
206
+ this.aSegPred = new Uint8Array(n);
207
+ this.aSkip = new Uint8Array(n);
208
+ this.aIntra = new Uint8Array(n);
209
+ this.aTxIntra = new Int8Array(n);
210
+ this.aTx = new Int8Array(n);
211
+ this.aUvmode = new Uint8Array(n);
212
+ this.aPalSz = new Uint8Array(n);
213
+ this.aPalSzUv = new Uint8Array(n);
214
+ this.aPartition = new Uint8Array(n >> 1);
215
+ this.aPal = new Uint16Array(n * 24);
216
+ this.frameDq = this.dq = quantTables(this.seq, this.hdr, this.hdr.quant.yac);
217
+ this.frameLfLvl = this.lfLvl = calcLfLevels(this.hdr, [0, 0, 0, 0]);
218
+ for (let tx = 0; tx < 19; tx++) {
219
+ const q = this.hdr.quant;
220
+ this.qm.push(q.qm ? [q.qmY, q.qmU, q.qmV].map((level, p) => level < 15 ? quantizerMatrix(level, p ? 1 : 0, tx) : null) : [null, null, null]);
221
+ }
222
+ this.resetAbove(0, n);
223
+ if (this.hdr.allowIntrabc) {
224
+ const size = frame.b4Stride * ((frame.bh + 31 & ~31) + 32);
225
+ this.mvY = new Int16Array(size);
226
+ this.mvX = new Int16Array(size);
227
+ this.mvValid = new Uint8Array(size);
228
+ this.mvBs = new Uint8Array(size);
229
+ }
230
+ for (let p = 0; p < frame.planes.length; p++) {
231
+ const type = this.hdr.restoration.types[p];
232
+ if (type === RESTORATION_NONE)
233
+ continue;
234
+ const sx = p ? frame.ssx : 0, sy = p ? frame.ssy : 0;
235
+ const size = 1 << this.hdr.restoration.unitSizeLog2[p ? 1 : 0];
236
+ const w = this.hdr.upscaledWidth + sx >> sx, h = frame.height + sy >> sy;
237
+ const cols = Math.max(1, Math.floor((w + (size >> 1)) / size)), rows = Math.max(1, Math.floor((h + (size >> 1)) / size));
238
+ frame.lrUnitsW[p] = cols;
239
+ frame.lrUnitsH[p] = rows;
240
+ for (let i = 0; i < cols * rows; i++)
241
+ frame.lr[p].push({ type: RESTORATION_NONE, filterV: [3, -7, 15], filterH: [3, -7, 15], sgrWeights: [-32, 31] });
242
+ }
243
+ }
244
+ resetAbove(from, to) {
245
+ this.aIntra.fill(1, from, to);
246
+ this.aUvmode.fill(DC_PRED, from, to);
247
+ this.aMode.fill(DC_PRED, from, to);
248
+ this.aPartition.fill(0, from >> 1, to + 1 >> 1);
249
+ this.aSkip.fill(0, from, to);
250
+ this.aTxIntra.fill(-1, from, to);
251
+ this.aTx.fill(TX_64X64, from, to);
252
+ this.aLcoef.fill(0x40, from, to);
253
+ this.aCcoef[0].fill(0x40, from, to);
254
+ this.aCcoef[1].fill(0x40, from, to);
255
+ this.aSegPred.fill(0, from, to);
256
+ this.aPalSz.fill(0, from, to);
257
+ this.aPalSzUv.fill(0, from, to);
258
+ }
259
+ resetLeft() {
260
+ this.lIntra.fill(1);
261
+ this.lUvmode.fill(DC_PRED);
262
+ this.lMode.fill(DC_PRED);
263
+ this.lPartition.fill(0);
264
+ this.lSkip.fill(0);
265
+ this.lTxIntra.fill(-1);
266
+ this.lTx.fill(TX_64X64);
267
+ this.lLcoef.fill(0x40);
268
+ this.lCcoef[0].fill(0x40);
269
+ this.lCcoef[1].fill(0x40);
270
+ this.lSegPred.fill(0);
271
+ this.lPalSz.fill(0);
272
+ this.lPalSzUv.fill(0);
273
+ }
274
+ tileRow = -1;
275
+ decodeTile(data, start, end, tileRow, tileCol) {
276
+ const f = this.frame, hdr = this.hdr, seq = this.seq;
277
+ if (tileRow !== this.tileRow) {
278
+ this.tileRow = tileRow;
279
+ this.resetAbove(0, this.aMode.length);
280
+ }
281
+ const sbShift = seq.sb128 ? 5 : 4, sbStep = 1 << sbShift;
282
+ this.colStart = hdr.tiles.colStarts[tileCol] << sbShift;
283
+ this.colEnd = Math.min(hdr.tiles.colStarts[tileCol + 1] << sbShift, f.bw);
284
+ this.rowStart = hdr.tiles.rowStarts[tileRow] << sbShift;
285
+ this.rowEnd = Math.min(hdr.tiles.rowStarts[tileRow + 1] << sbShift, f.bh);
286
+ this.cdf = defaultCdfs(hdr.quant.yac);
287
+ this.msac = new SymbolDecoder(data, start, end, !hdr.disableCdfUpdate);
288
+ this.lastQidx = hdr.quant.yac;
289
+ this.lastDeltaLf = [0, 0, 0, 0];
290
+ this.dq = this.frameDq;
291
+ this.lfLvl = this.frameLfLvl;
292
+ for (let p = 0; p < 3; p++)
293
+ this.lrRef[p] = { type: RESTORATION_NONE, filterV: [3, -7, 15], filterH: [3, -7, 15], sgrWeights: [-32, 31] };
294
+ const root = edgeTree(seq.sb128);
295
+ for (this.by = this.rowStart; this.by < this.rowEnd; this.by += sbStep) {
296
+ this.resetLeft();
297
+ for (this.bx = this.colStart; this.bx < this.colEnd; this.bx += sbStep) {
298
+ this.cdefSb = (this.by >> 4) * (f.b4Stride >> 4) + (this.bx >> 4);
299
+ this.readRestorationUnits();
300
+ this.decodeSb(seq.sb128 ? BL_128X128 : 1, root);
301
+ }
302
+ }
303
+ if (this.msac.overread)
304
+ throw new Error('AV1: truncated tile data');
305
+ }
306
+ readRestorationUnits() {
307
+ const f = this.frame, hdr = this.hdr;
308
+ if (hdr.superresDenominator !== 8 && hdr.restoration.types.some(t => t)) {
309
+ this.readRestorationUnitsSuperres();
310
+ return;
311
+ }
312
+ for (let p = 0; p < f.planes.length; p++) {
313
+ const type = hdr.restoration.types[p];
314
+ if (type === RESTORATION_NONE)
315
+ continue;
316
+ const sx = p ? f.ssx : 0, sy = p ? f.ssy : 0;
317
+ const sizeLog2 = hdr.restoration.unitSizeLog2[p ? 1 : 0], size = 1 << sizeLog2, mask = size - 1;
318
+ const y = this.by * 4 >> sy, h = f.height + sy >> sy;
319
+ if (y & mask)
320
+ continue;
321
+ if (y && y + (size >> 1) > h)
322
+ continue;
323
+ const x = this.bx * 4 >> sx, w = f.width + sx >> sx;
324
+ if (x & mask)
325
+ continue;
326
+ if (x && x + (size >> 1) > w)
327
+ continue;
328
+ const unit = f.lr[p][(y >> sizeLog2) * f.lrUnitsW[p] + (x >> sizeLog2)];
329
+ this.readRestorationInfo(unit, p, type);
330
+ }
331
+ }
332
+ readRestorationUnitsSuperres() {
333
+ const f = this.frame, hdr = this.hdr;
334
+ const sbStep = this.seq.sb128 ? 32 : 16;
335
+ for (let p = 0; p < f.planes.length; p++) {
336
+ const type = hdr.restoration.types[p];
337
+ if (type === RESTORATION_NONE)
338
+ continue;
339
+ const sx = p ? f.ssx : 0, sy = p ? f.ssy : 0;
340
+ const sizeLog2 = hdr.restoration.unitSizeLog2[p ? 1 : 0], size = 1 << sizeLog2;
341
+ const y = this.by * 4 >> sy, h = f.height + sy >> sy;
342
+ if (y & size - 1)
343
+ continue;
344
+ if (y && y + (size >> 1) > h)
345
+ continue;
346
+ const d = hdr.superresDenominator;
347
+ const rnd = size * 8 - 1, shift = sizeLog2 + 3;
348
+ const x0 = (4 * this.bx * d >> sx) + rnd >> shift;
349
+ const x1 = (4 * (this.bx + sbStep) * d >> sx) + rnd >> shift;
350
+ for (let x = x0; x < Math.min(x1, f.lrUnitsW[p]); x++) {
351
+ const unit = f.lr[p][(y >> sizeLog2) * f.lrUnitsW[p] + x];
352
+ this.readRestorationInfo(unit, p, type);
353
+ }
354
+ }
355
+ }
356
+ readRestorationInfo(lr, p, frameType) {
357
+ const m = this.msac, cdf = this.cdf;
358
+ if (frameType === RESTORATION_SWITCHABLE) {
359
+ const filter = m.symbol(cdf, CDF.restoreSwitchable, 2);
360
+ lr.type = filter ? filter + 1 : RESTORATION_NONE;
361
+ }
362
+ else {
363
+ const type = m.boolAdapt(cdf, frameType === RESTORATION_WIENER ? CDF.restoreWiener : CDF.restoreSgrproj);
364
+ lr.type = type ? frameType : RESTORATION_NONE;
365
+ }
366
+ const ref = this.lrRef[p];
367
+ if (lr.type === RESTORATION_WIENER) {
368
+ lr.filterV = [
369
+ p ? 0 : m.subexp(ref.filterV[0] + 5, 16, 1) - 5,
370
+ m.subexp(ref.filterV[1] + 23, 32, 2) - 23,
371
+ m.subexp(ref.filterV[2] + 17, 64, 3) - 17
372
+ ];
373
+ lr.filterH = [
374
+ p ? 0 : m.subexp(ref.filterH[0] + 5, 16, 1) - 5,
375
+ m.subexp(ref.filterH[1] + 23, 32, 2) - 23,
376
+ m.subexp(ref.filterH[2] + 17, 64, 3) - 17
377
+ ];
378
+ lr.sgrWeights = ref.sgrWeights.slice();
379
+ this.lrRef[p] = lr;
380
+ }
381
+ else if (lr.type === RESTORATION_SGRPROJ) {
382
+ const idx = m.bools(4);
383
+ lr.type += idx;
384
+ lr.sgrWeights = [
385
+ SGR_PARAMS[idx * 2] ? m.subexp(ref.sgrWeights[0] + 96, 128, 4) - 96 : 0,
386
+ SGR_PARAMS[idx * 2 + 1] ? m.subexp(ref.sgrWeights[1] + 32, 128, 4) - 32 : 95
387
+ ];
388
+ lr.filterV = ref.filterV.slice();
389
+ lr.filterH = ref.filterH.slice();
390
+ this.lrRef[p] = lr;
391
+ }
392
+ }
393
+ decodeSb(bl, node) {
394
+ const f = this.frame;
395
+ const hsz = 16 >> bl;
396
+ const haveH = f.bw > this.bx + hsz, haveV = f.bh > this.by + hsz;
397
+ if (!haveH && !haveV)
398
+ return this.decodeSb(bl + 1, node.split[0]);
399
+ const bx8 = this.bx >> 1, by8 = (this.by & 31) >> 1;
400
+ const ctx = (this.aPartition[bx8] >> (4 - bl) & 1) + ((this.lPartition[by8] >> (4 - bl) & 1) << 1);
401
+ const pc = CDF.partition + (bl * 4 + ctx) * 16;
402
+ const cdf = this.cdf;
403
+ let bp;
404
+ if (haveH && haveV) {
405
+ bp = this.msac.symbol(cdf, pc, PARTITION_TYPE_COUNT[bl]);
406
+ if (f.layout === 2 && (bp === PARTITION_V || bp === PARTITION_V4 || bp === PARTITION_T_LEFT_SPLIT || bp === PARTITION_T_RIGHT_SPLIT))
407
+ throw new Error('AV1: invalid partition');
408
+ const b = (i) => BLOCK_SIZES[(bl * 10 + bp) * 2 + i];
409
+ switch (bp) {
410
+ case PARTITION_NONE:
411
+ this.decodeB(b(0), node.o);
412
+ break;
413
+ case PARTITION_H:
414
+ this.decodeB(b(0), node.h[0]);
415
+ this.by += hsz;
416
+ this.decodeB(b(0), node.h[1]);
417
+ this.by -= hsz;
418
+ break;
419
+ case PARTITION_V:
420
+ this.decodeB(b(0), node.v[0]);
421
+ this.bx += hsz;
422
+ this.decodeB(b(0), node.v[1]);
423
+ this.bx -= hsz;
424
+ break;
425
+ case PARTITION_SPLIT:
426
+ if (bl === BL_8X8) {
427
+ this.decodeB(BS_4x4, EDGE_ALL_TR_AND_BL);
428
+ this.bx++;
429
+ this.decodeB(BS_4x4, node.tip[0]);
430
+ this.bx--;
431
+ this.by++;
432
+ this.decodeB(BS_4x4, node.tip[1]);
433
+ this.bx++;
434
+ this.decodeB(BS_4x4, node.tip[2]);
435
+ this.bx--;
436
+ this.by--;
437
+ }
438
+ else {
439
+ this.decodeSb(bl + 1, node.split[0]);
440
+ this.bx += hsz;
441
+ this.decodeSb(bl + 1, node.split[1]);
442
+ this.bx -= hsz;
443
+ this.by += hsz;
444
+ this.decodeSb(bl + 1, node.split[2]);
445
+ this.bx += hsz;
446
+ this.decodeSb(bl + 1, node.split[3]);
447
+ this.bx -= hsz;
448
+ this.by -= hsz;
449
+ }
450
+ break;
451
+ case PARTITION_T_TOP_SPLIT:
452
+ this.decodeB(b(0), EDGE_ALL_TR_AND_BL);
453
+ this.bx += hsz;
454
+ this.decodeB(b(0), node.v[1]);
455
+ this.bx -= hsz;
456
+ this.by += hsz;
457
+ this.decodeB(b(1), node.h[1]);
458
+ this.by -= hsz;
459
+ break;
460
+ case PARTITION_T_BOTTOM_SPLIT:
461
+ this.decodeB(b(0), node.h[0]);
462
+ this.by += hsz;
463
+ this.decodeB(b(1), node.v[0]);
464
+ this.bx += hsz;
465
+ this.decodeB(b(1), 0);
466
+ this.bx -= hsz;
467
+ this.by -= hsz;
468
+ break;
469
+ case PARTITION_T_LEFT_SPLIT:
470
+ this.decodeB(b(0), EDGE_ALL_TR_AND_BL);
471
+ this.by += hsz;
472
+ this.decodeB(b(0), node.h[1]);
473
+ this.by -= hsz;
474
+ this.bx += hsz;
475
+ this.decodeB(b(1), node.v[1]);
476
+ this.bx -= hsz;
477
+ break;
478
+ case PARTITION_T_RIGHT_SPLIT:
479
+ this.decodeB(b(0), node.v[0]);
480
+ this.bx += hsz;
481
+ this.decodeB(b(1), node.h[0]);
482
+ this.by += hsz;
483
+ this.decodeB(b(1), 0);
484
+ this.by -= hsz;
485
+ this.bx -= hsz;
486
+ break;
487
+ case PARTITION_H4:
488
+ this.decodeB(b(0), node.h[0]);
489
+ this.by += hsz >> 1;
490
+ this.decodeB(b(0), node.h4);
491
+ this.by += hsz >> 1;
492
+ this.decodeB(b(0), EDGE_ALL_LEFT_HAS_BOTTOM);
493
+ this.by += hsz >> 1;
494
+ if (this.by < f.bh)
495
+ this.decodeB(b(0), node.h[1]);
496
+ this.by -= hsz * 3 >> 1;
497
+ break;
498
+ case PARTITION_V4:
499
+ this.decodeB(b(0), node.v[0]);
500
+ this.bx += hsz >> 1;
501
+ this.decodeB(b(0), node.v4);
502
+ this.bx += hsz >> 1;
503
+ this.decodeB(b(0), EDGE_ALL_TOP_HAS_RIGHT);
504
+ this.bx += hsz >> 1;
505
+ if (this.bx < f.bw)
506
+ this.decodeB(b(0), node.v[1]);
507
+ this.bx -= hsz * 3 >> 1;
508
+ break;
509
+ }
510
+ }
511
+ else if (haveH) {
512
+ let prob = cdf[pc + PARTITION_V - 1] - cdf[pc + PARTITION_T_TOP_SPLIT];
513
+ prob += cdf[pc + PARTITION_T_LEFT_SPLIT - 1];
514
+ if (bl !== BL_128X128)
515
+ prob += cdf[pc + PARTITION_V4 - 1] - cdf[pc + PARTITION_T_RIGHT_SPLIT];
516
+ const split = this.msac.boolProb(prob);
517
+ if (split) {
518
+ bp = PARTITION_SPLIT;
519
+ this.decodeSb(bl + 1, node.split[0]);
520
+ this.bx += hsz;
521
+ this.decodeSb(bl + 1, node.split[1]);
522
+ this.bx -= hsz;
523
+ }
524
+ else {
525
+ bp = PARTITION_H;
526
+ this.decodeB(BLOCK_SIZES[(bl * 10 + PARTITION_H) * 2], node.h[0]);
527
+ }
528
+ }
529
+ else {
530
+ let prob = cdf[pc + PARTITION_H - 1] - cdf[pc + PARTITION_H];
531
+ prob += cdf[pc + PARTITION_SPLIT - 1] - cdf[pc + PARTITION_T_LEFT_SPLIT];
532
+ if (bl !== BL_128X128)
533
+ prob += cdf[pc + PARTITION_H4 - 1] - cdf[pc + PARTITION_H4];
534
+ const split = this.msac.boolProb(prob);
535
+ if (f.layout === 2 && !split)
536
+ throw new Error('AV1: invalid partition');
537
+ if (split) {
538
+ bp = PARTITION_SPLIT;
539
+ this.decodeSb(bl + 1, node.split[0]);
540
+ this.by += hsz;
541
+ this.decodeSb(bl + 1, node.split[2]);
542
+ this.by -= hsz;
543
+ }
544
+ else {
545
+ bp = PARTITION_V;
546
+ this.decodeB(BLOCK_SIZES[(bl * 10 + PARTITION_V) * 2], node.v[0]);
547
+ }
548
+ }
549
+ if (bp !== PARTITION_SPLIT || bl === BL_8X8) {
550
+ this.aPartition.fill(AL_PART_CTX[bl * 10 + bp], bx8, bx8 + hsz);
551
+ this.lPartition.fill(AL_PART_CTX[50 + bl * 10 + bp], by8, by8 + hsz);
552
+ }
553
+ }
554
+ decodeB(bs, edgeFlags) {
555
+ const f = this.frame, hdr = this.hdr, seq = this.seq, m = this.msac, cdf = this.cdf;
556
+ const bx = this.bx, by = this.by, bx4 = bx, by4 = by & 31;
557
+ const ssx = f.ssx, ssy = f.ssy;
558
+ const cbx4 = bx4 >> ssx, cby4 = by4 >> ssy;
559
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1), lw4 = bdim(bs, 2), lh4 = bdim(bs, 3);
560
+ const w4 = Math.min(bw4, f.bw - bx), h4 = Math.min(bh4, f.bh - by);
561
+ const cbw4 = bw4 + ssx >> ssx, cbh4 = bh4 + ssy >> ssy;
562
+ const haveLeft = bx > this.colStart, haveTop = by > this.rowStart;
563
+ const hasChroma = f.layout !== 0 && (bw4 > ssx || !!(bx & 1)) && (bh4 > ssy || !!(by & 1));
564
+ const b = { segId: 0, skip: 0, yMode: 0, yAngle: 0, uvMode: 0, uvAngle: 0, cflAlpha: [0, 0], palSz: [0, 0], tx: 0, uvtx: 0 };
565
+ const segmentation = hdr.segmentation;
566
+ let seg = null;
567
+ const readSegId = () => {
568
+ const map = f.segMap, s = f.b4Stride, o = by * s + bx;
569
+ let segCtx, pred;
570
+ if (haveLeft && haveTop) {
571
+ const l = map[o - 1], a = map[o - s], al = map[o - s - 1];
572
+ segCtx = l === a && al === l ? 2 : l === a || al === l || a === al ? 1 : 0;
573
+ pred = a === al ? a : l;
574
+ }
575
+ else {
576
+ segCtx = 0;
577
+ pred = haveLeft ? map[o - 1] : haveTop ? map[o - s] : 0;
578
+ }
579
+ if (b.skip && !segmentation.preskip)
580
+ b.segId = pred;
581
+ else {
582
+ const diff = m.symbol(cdf, CDF.segId + segCtx * 8, 7);
583
+ b.segId = neg_deinterleave(diff, pred, segmentation.lastActiveSegId + 1);
584
+ if (b.segId > segmentation.lastActiveSegId)
585
+ b.segId = 0;
586
+ }
587
+ if (b.segId >= 8)
588
+ b.segId = 0;
589
+ };
590
+ if (segmentation.enabled && segmentation.preskip) {
591
+ readSegId();
592
+ seg = segmentation.data[b.segId];
593
+ }
594
+ if (seg?.skip)
595
+ b.skip = 1;
596
+ else {
597
+ b.skip = m.boolAdapt(cdf, CDF.skip + (this.aSkip[bx4] + this.lSkip[by4]) * 2);
598
+ }
599
+ if (segmentation.enabled && !segmentation.preskip)
600
+ readSegId();
601
+ if (!b.skip) {
602
+ const idx = seq.sb128 ? this.cdefSb + (bx >> 4 & 1) + (by >> 4 & 1) * (f.b4Stride >> 4) : this.cdefSb;
603
+ if (f.cdefIdx[idx] === -1) {
604
+ const v = m.bools(hdr.cdef.bits);
605
+ f.cdefIdx[idx] = v;
606
+ const stride = f.b4Stride >> 4;
607
+ if (bw4 > 16)
608
+ f.cdefIdx[idx + 1] = v;
609
+ if (bh4 > 16)
610
+ f.cdefIdx[idx + stride] = v;
611
+ if (bw4 === 32 && bh4 === 32)
612
+ f.cdefIdx[idx + stride + 1] = v;
613
+ }
614
+ }
615
+ const sbMask = seq.sb128 ? 31 : 15;
616
+ if (!(bx & sbMask) && !(by & sbMask)) {
617
+ const prevQidx = this.lastQidx;
618
+ const prevDeltaLf = this.lastDeltaLf.join();
619
+ if (hdr.deltaQ.present && (bs !== (seq.sb128 ? BS_128x128 : BS_64x64) || !b.skip)) {
620
+ const readDelta = (o) => {
621
+ let d = m.symbol(cdf, o, 3);
622
+ if (d === 3) {
623
+ const n = 1 + m.bools(3);
624
+ d = m.bools(n) + 1 + (1 << n);
625
+ }
626
+ return d;
627
+ };
628
+ let deltaQ = readDelta(CDF.deltaQ);
629
+ if (deltaQ) {
630
+ if (m.bool())
631
+ deltaQ = -deltaQ;
632
+ deltaQ *= 1 << hdr.deltaQ.resLog2;
633
+ }
634
+ this.lastQidx = Math.min(255, Math.max(1, this.lastQidx + deltaQ));
635
+ if (hdr.deltaLf.present) {
636
+ const n = hdr.deltaLf.multi ? f.layout ? 4 : 2 : 1;
637
+ for (let i = 0; i < n; i++) {
638
+ let d = readDelta(CDF.deltaLf + (i + (hdr.deltaLf.multi ? 1 : 0)) * 4);
639
+ if (d) {
640
+ if (m.bool())
641
+ d = -d;
642
+ d *= 1 << hdr.deltaLf.resLog2;
643
+ }
644
+ this.lastDeltaLf[i] = Math.min(63, Math.max(-63, this.lastDeltaLf[i] + d));
645
+ }
646
+ }
647
+ }
648
+ if (this.lastQidx === hdr.quant.yac)
649
+ this.dq = this.frameDq;
650
+ else if (this.lastQidx !== prevQidx)
651
+ this.dq = quantTables(seq, hdr, this.lastQidx);
652
+ if (this.lastDeltaLf.every(v => !v))
653
+ this.lfLvl = this.frameLfLvl;
654
+ else if (this.lastDeltaLf.join() !== prevDeltaLf)
655
+ this.lfLvl = calcLfLevels(hdr, this.lastDeltaLf);
656
+ }
657
+ if (hdr.allowIntrabc && m.boolAdapt(cdf, CDF.intrabc)) {
658
+ this.intrabcBlock(bs, edgeFlags, b, hasChroma);
659
+ this.storeBlock(bs, b, hasChroma);
660
+ return;
661
+ }
662
+ b.yMode = m.symbol(cdf, CDF.kfYMode + (INTRA_MODE_CONTEXT[this.aMode[bx4]] * 5 + INTRA_MODE_CONTEXT[this.lMode[by4]]) * 16, 12);
663
+ if (lw4 + lh4 >= 2 && b.yMode >= VERT_PRED && b.yMode <= VERT_LEFT_PRED)
664
+ b.yAngle = m.symbol(cdf, CDF.angleDelta + (b.yMode - VERT_PRED) * 8, 6) - 3;
665
+ const lossless = hdr.segmentation.lossless[b.segId];
666
+ if (hasChroma) {
667
+ const cflAllowed = lossless ? cbw4 === 1 && cbh4 === 1 : !!(CFL_ALLOWED_MASK & 1 << bs);
668
+ b.uvMode = m.symbol(cdf, CDF.uvMode + ((cflAllowed ? 1 : 0) * 13 + b.yMode) * 16, cflAllowed ? 13 : 12);
669
+ if (b.uvMode === CFL_PRED) {
670
+ const sign = m.symbol(cdf, CDF.cflSign, 7) + 1;
671
+ const signU = sign * 0x56 >> 8, signV = sign - signU * 3;
672
+ if (signU) {
673
+ const ctx = (signU === 2 ? 3 : 0) + signV;
674
+ b.cflAlpha[0] = m.symbol(cdf, CDF.cflAlpha + ctx * 16, 15) + 1;
675
+ if (signU === 1)
676
+ b.cflAlpha[0] = -b.cflAlpha[0];
677
+ }
678
+ if (signV) {
679
+ const ctx = (signV === 2 ? 3 : 0) + signU;
680
+ b.cflAlpha[1] = m.symbol(cdf, CDF.cflAlpha + ctx * 16, 15) + 1;
681
+ if (signV === 1)
682
+ b.cflAlpha[1] = -b.cflAlpha[1];
683
+ }
684
+ }
685
+ else if (lw4 + lh4 >= 2 && b.uvMode >= VERT_PRED && b.uvMode <= VERT_LEFT_PRED) {
686
+ b.uvAngle = m.symbol(cdf, CDF.angleDelta + (b.uvMode - VERT_PRED) * 8, 6) - 3;
687
+ }
688
+ }
689
+ if (hdr.allowScreenContentTools && Math.max(bw4, bh4) <= 16 && bw4 + bh4 >= 4) {
690
+ const szCtx = lw4 + lh4 - 2;
691
+ if (b.yMode === DC_PRED) {
692
+ const palCtx = (this.aPalSz[bx4] > 0 ? 1 : 0) + (this.lPalSz[by4] > 0 ? 1 : 0);
693
+ if (m.boolAdapt(cdf, CDF.palY + (szCtx * 3 + palCtx) * 2))
694
+ this.readPalPlane(b, 0, szCtx, bx4, by4);
695
+ }
696
+ if (hasChroma && b.uvMode === DC_PRED) {
697
+ if (m.boolAdapt(cdf, CDF.palUv + (b.palSz[0] > 0 ? 2 : 0)))
698
+ this.readPalUv(b, szCtx, bx4, by4);
699
+ }
700
+ }
701
+ if (b.yMode === DC_PRED && !b.palSz[0] && Math.max(lw4, lh4) <= 3 && seq.filterIntra) {
702
+ if (m.boolAdapt(cdf, CDF.useFilterIntra + bs * 2)) {
703
+ b.yMode = FILTER_PRED;
704
+ b.yAngle = m.symbol(cdf, CDF.filterIntra, 4);
705
+ }
706
+ }
707
+ if (b.palSz[0])
708
+ this.readPalIndices(this.palIdxY, b.palSz[0], 0, w4, h4, bw4, bh4);
709
+ if (hasChroma && b.palSz[1]) {
710
+ const cw4 = w4 + ssx >> ssx, ch4 = h4 + ssy >> ssy;
711
+ this.readPalIndices(this.palIdxUv, b.palSz[1], 1, cw4, ch4, cbw4, cbh4);
712
+ }
713
+ let tx;
714
+ if (lossless) {
715
+ tx = b.uvtx = TX_4X4;
716
+ }
717
+ else {
718
+ tx = MAX_TXFM_SIZE_FOR_BS[bs * 4];
719
+ b.uvtx = MAX_TXFM_SIZE_FOR_BS[bs * 4 + f.layout];
720
+ if (hdr.txMode === 2 && tdim(tx, MAX) > TX_4X4) {
721
+ const tctx = (this.lTxIntra[by4] >= tdim(tx, LH) ? 1 : 0) + (this.aTxIntra[bx4] >= tdim(tx, LW) ? 1 : 0);
722
+ let depth = m.symbol(cdf, CDF.txSize + ((tdim(tx, MAX) - 1) * 3 + tctx) * 4, Math.min(tdim(tx, MAX), 2));
723
+ while (depth--)
724
+ tx = tdim(tx, SUB);
725
+ }
726
+ }
727
+ b.tx = tx;
728
+ this.reconIntra(bs, edgeFlags, b, hasChroma);
729
+ this.storeBlock(bs, b, hasChroma);
730
+ const yModeNofilt = b.yMode === FILTER_PRED ? DC_PRED : b.yMode;
731
+ const aw = 1 << lw4, lh = 1 << lh4;
732
+ this.aTxIntra.fill(tdim(tx, LW), bx4, bx4 + aw);
733
+ this.lTxIntra.fill(tdim(tx, LH), by4, by4 + lh);
734
+ this.aTx.fill(tdim(tx, LW), bx4, bx4 + aw);
735
+ this.lTx.fill(tdim(tx, LH), by4, by4 + lh);
736
+ this.aMode.fill(yModeNofilt, bx4, bx4 + aw);
737
+ this.lMode.fill(yModeNofilt, by4, by4 + lh);
738
+ this.aPalSz.fill(b.palSz[0], bx4, bx4 + aw);
739
+ this.lPalSz.fill(b.palSz[0], by4, by4 + lh);
740
+ this.aSegPred.fill(0, bx4, bx4 + aw);
741
+ this.lSegPred.fill(0, by4, by4 + lh);
742
+ this.aIntra.fill(1, bx4, bx4 + aw);
743
+ this.lIntra.fill(1, by4, by4 + lh);
744
+ this.aSkip.fill(b.skip, bx4, bx4 + aw);
745
+ this.lSkip.fill(b.skip, by4, by4 + lh);
746
+ this.aPalSzUv.fill(hasChroma ? b.palSz[1] : 0, bx4, bx4 + aw);
747
+ this.lPalSzUv.fill(hasChroma ? b.palSz[1] : 0, by4, by4 + lh);
748
+ if (b.palSz[0]) {
749
+ for (let x = 0; x < bw4; x++)
750
+ this.aPal.set(this.pal.subarray(0, 8), (bx4 + x) * 24);
751
+ for (let y = 0; y < bh4; y++)
752
+ this.lPal.set(this.pal.subarray(0, 8), (by4 + y) * 24);
753
+ }
754
+ if (hasChroma) {
755
+ this.aUvmode.fill(b.uvMode, cbx4, cbx4 + cbw4);
756
+ this.lUvmode.fill(b.uvMode, cby4, cby4 + cbh4);
757
+ if (b.palSz[1]) {
758
+ for (let pl = 1; pl <= 2; pl++) {
759
+ for (let x = 0; x < bw4; x++)
760
+ this.aPal.set(this.pal.subarray(pl * 8, pl * 8 + 8), (bx4 + x) * 24 + pl * 8);
761
+ for (let y = 0; y < bh4; y++)
762
+ this.lPal.set(this.pal.subarray(pl * 8, pl * 8 + 8), (by4 + y) * 24 + pl * 8);
763
+ }
764
+ }
765
+ }
766
+ if (hdr.allowIntrabc)
767
+ this.splatMv(bs, -1, 0, 0);
768
+ }
769
+ storeBlock(bs, b, hasChroma) {
770
+ const f = this.frame, bx = this.bx, by = this.by, ssx = f.ssx, ssy = f.ssy;
771
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1);
772
+ const w4 = Math.min(bw4, f.bw - bx), h4 = Math.min(bh4, f.bh - by);
773
+ const tx = b.tx;
774
+ const lvl = this.lfLvl[b.segId];
775
+ const s4 = f.b4Stride;
776
+ for (let y = 0; y < h4; y++) {
777
+ for (let x = 0; x < w4; x++) {
778
+ const o = (by + y) * s4 + bx + x;
779
+ f.lfLevels.set(lvl, o * 4);
780
+ f.txW[o] = tdim(tx, LW);
781
+ f.txH[o] = tdim(tx, LH);
782
+ f.skip[o] = b.skip;
783
+ }
784
+ }
785
+ if (hasChroma) {
786
+ const cx = bx >> ssx, cy = by >> ssy, cw4 = w4 + ssx >> ssx, ch4 = h4 + ssy >> ssy;
787
+ for (let y = 0; y < ch4; y++) {
788
+ for (let x = 0; x < cw4; x++) {
789
+ const o = (cy + y) * s4 + cx + x;
790
+ f.uvTxW[o] = tdim(b.uvtx, LW);
791
+ f.uvTxH[o] = tdim(b.uvtx, LH);
792
+ }
793
+ }
794
+ }
795
+ if (this.hdr.segmentation.enabled) {
796
+ for (let y = 0; y < bh4 && by + y < f.bh; y++)
797
+ f.segMap.fill(b.segId, (by + y) * s4 + bx, (by + y) * s4 + bx + bw4);
798
+ }
799
+ }
800
+ mvY = null;
801
+ mvX = null;
802
+ mvValid = null;
803
+ mvBs = null;
804
+ txSplit = [0, 0];
805
+ maxYtx = 0;
806
+ txtpMap = new Uint8Array(32 * 32);
807
+ splatMv(bs, valid, y, x) {
808
+ const f = this.frame, s4 = f.b4Stride;
809
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1);
810
+ for (let r = 0; r < bh4; r++) {
811
+ const o = (this.by + r) * s4 + this.bx;
812
+ this.mvY.fill(y, o, o + bw4);
813
+ this.mvX.fill(x, o, o + bw4);
814
+ this.mvValid.fill(valid > 0 ? 1 : 0, o, o + bw4);
815
+ this.mvBs.fill(bs, o, o + bw4);
816
+ }
817
+ }
818
+ findMvs(bs, edgeFlags) {
819
+ const f = this.frame, s4 = f.b4Stride;
820
+ const by4 = this.by, bx4 = this.bx;
821
+ const iw4 = f.width + 3 >> 2, ih4 = f.height + 3 >> 2;
822
+ const colStart = this.colStart, colEnd = Math.min(this.colEnd, iw4), rowStart = this.rowStart, rowEnd = Math.min(this.rowEnd, ih4);
823
+ const bw4 = bdim(bs, 0), w4 = Math.min(Math.min(bw4, 16), colEnd - bx4);
824
+ const bh4 = bdim(bs, 1), h4 = Math.min(Math.min(bh4, 16), rowEnd - by4);
825
+ const valid = this.mvValid, mvY = this.mvY, mvX = this.mvX, mvBs = this.mvBs;
826
+ const stack = [];
827
+ const add = (o, weight) => {
828
+ if (!valid[o])
829
+ return;
830
+ const y = mvY[o], x = mvX[o];
831
+ for (const c of stack) {
832
+ if (c.y === y && c.x === x) {
833
+ c.weight += weight;
834
+ return;
835
+ }
836
+ }
837
+ if (stack.length < 8)
838
+ stack.push({ y, x, weight });
839
+ };
840
+ const scanRow = (row, col, maxRows, step) => {
841
+ const o = row * s4 + col;
842
+ const firstBw4 = bdim(mvBs[o], 0);
843
+ let len = Math.max(step, Math.min(bw4, firstBw4));
844
+ if (bw4 <= firstBw4) {
845
+ const weight = bw4 === 1 ? 2 : Math.max(2, Math.min(2 * maxRows, bdim(mvBs[o], 1)));
846
+ add(o, len * weight);
847
+ return weight >> 1;
848
+ }
849
+ for (let x = 0;;) {
850
+ add(o + x, len * 2);
851
+ x += len;
852
+ if (x >= w4)
853
+ return 1;
854
+ len = Math.max(step, bdim(mvBs[o + x], 0));
855
+ }
856
+ };
857
+ const scanCol = (row, col, maxCols, step) => {
858
+ const o = row * s4 + col;
859
+ const firstBh4 = bdim(mvBs[o], 1);
860
+ let len = Math.max(step, Math.min(bh4, firstBh4));
861
+ if (bh4 <= firstBh4) {
862
+ const weight = bh4 === 1 ? 2 : Math.max(2, Math.min(2 * maxCols, bdim(mvBs[o], 0)));
863
+ add(o, len * weight);
864
+ return weight >> 1;
865
+ }
866
+ for (let y = 0;;) {
867
+ add(o + y * s4, len * 2);
868
+ y += len;
869
+ if (y >= h4)
870
+ return 1;
871
+ len = Math.max(step, bdim(mvBs[o + y * s4], 1));
872
+ }
873
+ };
874
+ const NONE = 0xffffffff;
875
+ let maxRows = 0, nRows = NONE;
876
+ if (by4 > rowStart) {
877
+ maxRows = Math.min((by4 - rowStart + 1) >> 1, 2 + (bh4 > 1 ? 1 : 0));
878
+ nRows = scanRow(by4 - 1, bx4, maxRows, bw4 >= 16 ? 4 : 1);
879
+ }
880
+ let maxCols = 0, nCols = NONE;
881
+ if (bx4 > colStart) {
882
+ maxCols = Math.min((bx4 - colStart + 1) >> 1, 2 + (bw4 > 1 ? 1 : 0));
883
+ nCols = scanCol(by4, bx4 - 1, maxCols, bh4 >= 16 ? 4 : 1);
884
+ }
885
+ if (nRows !== NONE && edgeFlags & EDGE_I444_TOP_HAS_RIGHT && Math.max(bw4, bh4) <= 16 && bw4 + bx4 < colEnd)
886
+ add((by4 - 1) * s4 + bx4 + bw4, 4);
887
+ const nearest = stack.length;
888
+ for (const c of stack)
889
+ c.weight += 640;
890
+ if (nRows !== NONE && nCols !== NONE)
891
+ add((by4 - 1) * s4 + bx4 - 1, 4);
892
+ for (let n = 2; n <= 3; n++) {
893
+ if (nRows !== NONE && n > nRows && n <= maxRows) {
894
+ nRows += scanRow(((by4 - 2 * n + 1) | 1), bx4 | 1, 1 + maxRows - n, bw4 >= 16 ? 4 : 2);
895
+ }
896
+ if (nCols !== NONE && n > nCols && n <= maxCols) {
897
+ nCols += scanCol(by4 | 1, (bx4 - n * 2 + 1) | 1, 1 + maxCols - n, bh4 >= 16 ? 4 : 2);
898
+ }
899
+ }
900
+ const sort = (from, to) => {
901
+ let len = to;
902
+ while (len > from) {
903
+ let last = from;
904
+ for (let n = from + 1; n < len; n++) {
905
+ if (stack[n - 1].weight < stack[n].weight) {
906
+ [stack[n - 1], stack[n]] = [stack[n], stack[n - 1]];
907
+ last = n;
908
+ }
909
+ }
910
+ len = last;
911
+ }
912
+ };
913
+ sort(0, nearest);
914
+ sort(nearest, stack.length);
915
+ const left = -(bx4 + bw4 + 4) * 32, right = (iw4 - bx4 + 4) * 32;
916
+ const top = -(by4 + bh4 + 4) * 32, bottom = (ih4 - by4 + 4) * 32;
917
+ const out = stack.map(c => [Math.min(bottom, Math.max(top, c.y)), Math.min(right, Math.max(left, c.x))]);
918
+ while (out.length < 2)
919
+ out.push([0, 0]);
920
+ return out;
921
+ }
922
+ readMvComponent(comp) {
923
+ const m = this.msac, cdf = this.cdf;
924
+ const sign = m.boolAdapt(cdf, comp ? CDF.mvSign1 : CDF.mvSign0);
925
+ const cl = m.symbol(cdf, comp ? CDF.mvClasses1 : CDF.mvClasses0, 10);
926
+ let up;
927
+ if (!cl)
928
+ up = m.boolAdapt(cdf, comp ? CDF.mvClass01 : CDF.mvClass00);
929
+ else {
930
+ up = 1 << cl;
931
+ for (let n = 0; n < cl; n++)
932
+ up |= m.boolAdapt(cdf, (comp ? CDF.mvClassN1 : CDF.mvClassN0) + n * 2) << n;
933
+ }
934
+ const diff = (up << 3 | 7) + 1;
935
+ return sign ? -diff : diff;
936
+ }
937
+ intrabcBlock(bs, edgeFlags, b, hasChroma) {
938
+ const f = this.frame, seq = this.seq, m = this.msac, cdf = this.cdf;
939
+ const bx = this.bx, by = this.by, bx4 = bx, by4 = by & 31;
940
+ const ssx = f.ssx, ssy = f.ssy;
941
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1);
942
+ const sb128 = seq.sb128 ? 1 : 0;
943
+ const stack = this.findMvs(bs, edgeFlags);
944
+ let [mvy, mvx] = stack[0][0] || stack[0][1] ? stack[0] : stack[1][0] || stack[1][1] ? stack[1] : [0, 0];
945
+ if (!mvy && !mvx) {
946
+ if (by - (16 << sb128) < this.rowStart) {
947
+ mvy = 0;
948
+ mvx = -(512 << sb128) - 2048;
949
+ }
950
+ else {
951
+ mvy = -(512 << sb128);
952
+ mvx = 0;
953
+ }
954
+ }
955
+ const joint = m.symbol(cdf, CDF.mvJoint, 3);
956
+ if (joint & 2)
957
+ mvy += this.readMvComponent(0);
958
+ if (joint & 1)
959
+ mvx += this.readMvComponent(1);
960
+ let borderLeft = this.colStart * 4, borderTop = this.rowStart * 4;
961
+ if (hasChroma) {
962
+ if (bw4 < 2 && ssx)
963
+ borderLeft += 4;
964
+ if (bh4 < 2 && ssy)
965
+ borderTop += 4;
966
+ }
967
+ let srcLeft = bx * 4 + (mvx >> 3), srcTop = by * 4 + (mvy >> 3);
968
+ let srcRight = srcLeft + bw4 * 4, srcBottom = srcTop + bh4 * 4;
969
+ const borderRight = ((this.colEnd + (bw4 - 1)) & ~(bw4 - 1)) * 4;
970
+ if (srcLeft < borderLeft) {
971
+ srcRight += borderLeft - srcLeft;
972
+ srcLeft = borderLeft;
973
+ }
974
+ else if (srcRight > borderRight) {
975
+ srcLeft -= srcRight - borderRight;
976
+ srcRight = borderRight;
977
+ }
978
+ if (srcTop < borderTop) {
979
+ srcBottom += borderTop - srcTop;
980
+ srcTop = borderTop;
981
+ }
982
+ const sbx = (bx >> (4 + sb128)) << (6 + sb128), sby = (by >> (4 + sb128)) << (6 + sb128), sbSize = 1 << (6 + sb128);
983
+ if (srcBottom > sby && srcRight > sbx) {
984
+ if (srcTop - borderTop >= srcBottom - sby) {
985
+ srcTop -= srcBottom - sby;
986
+ srcBottom = sby;
987
+ }
988
+ else if (srcLeft - borderLeft >= srcRight - sbx) {
989
+ srcLeft -= srcRight - sbx;
990
+ srcRight = sbx;
991
+ }
992
+ }
993
+ if (srcBottom > sby + sbSize) {
994
+ srcTop -= srcBottom - (sby + sbSize);
995
+ srcBottom = sby + sbSize;
996
+ }
997
+ if (srcBottom > sby && srcRight > sbx)
998
+ throw new Error('AV1: invalid intra block copy vector');
999
+ mvx = (srcLeft - bx * 4) * 8;
1000
+ mvy = (srcTop - by * 4) * 8;
1001
+ this.readVartxTree(b, bs);
1002
+ b.tx = this.maxYtx;
1003
+ this.reconInter(bs, b, hasChroma, mvy, mvx);
1004
+ this.splatMv(bs, 1, mvy, mvx);
1005
+ const aw = 1 << bdim(bs, 2), lh = 1 << bdim(bs, 3);
1006
+ this.aTxIntra.fill(bdim(bs, 2), bx4, bx4 + aw);
1007
+ this.lTxIntra.fill(bdim(bs, 3), by4, by4 + lh);
1008
+ this.aMode.fill(DC_PRED, bx4, bx4 + aw);
1009
+ this.lMode.fill(DC_PRED, by4, by4 + lh);
1010
+ this.aPalSz.fill(0, bx4, bx4 + aw);
1011
+ this.lPalSz.fill(0, by4, by4 + lh);
1012
+ this.aPalSzUv.fill(0, bx4, bx4 + aw);
1013
+ this.lPalSzUv.fill(0, by4, by4 + lh);
1014
+ this.aSegPred.fill(0, bx4, bx4 + aw);
1015
+ this.lSegPred.fill(0, by4, by4 + lh);
1016
+ this.aIntra.fill(0, bx4, bx4 + aw);
1017
+ this.lIntra.fill(0, by4, by4 + lh);
1018
+ this.aSkip.fill(b.skip, bx4, bx4 + aw);
1019
+ this.lSkip.fill(b.skip, by4, by4 + lh);
1020
+ if (hasChroma) {
1021
+ const cbx4 = bx4 >> ssx, cby4 = by4 >> ssy, cbw4 = bw4 + ssx >> ssx, cbh4 = bh4 + ssy >> ssy;
1022
+ this.aUvmode.fill(DC_PRED, cbx4, cbx4 + cbw4);
1023
+ this.lUvmode.fill(DC_PRED, cby4, cby4 + cbh4);
1024
+ }
1025
+ }
1026
+ readVartxTree(b, bs) {
1027
+ const f = this.frame, hdr = this.hdr;
1028
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1), lw = bdim(bs, 2), lh = bdim(bs, 3);
1029
+ const bx4 = this.bx, by4 = this.by & 31;
1030
+ this.txSplit = [0, 0];
1031
+ this.maxYtx = MAX_TXFM_SIZE_FOR_BS[bs * 4];
1032
+ if (!b.skip && (hdr.segmentation.lossless[b.segId] || this.maxYtx === TX_4X4)) {
1033
+ this.maxYtx = b.uvtx = TX_4X4;
1034
+ if (hdr.txMode === 2) {
1035
+ this.aTx.fill(TX_4X4, bx4, bx4 + (1 << lw));
1036
+ this.lTx.fill(TX_4X4, by4, by4 + (1 << lh));
1037
+ }
1038
+ }
1039
+ else if (hdr.txMode !== 2 || b.skip) {
1040
+ if (hdr.txMode === 2) {
1041
+ this.aTx.fill(lw, bx4, bx4 + (1 << lw));
1042
+ this.lTx.fill(lh, by4, by4 + (1 << lh));
1043
+ }
1044
+ b.uvtx = MAX_TXFM_SIZE_FOR_BS[bs * 4 + f.layout];
1045
+ }
1046
+ else {
1047
+ const ytx = this.maxYtx, tw = tdim(ytx, W), th = tdim(ytx, H);
1048
+ for (let y = 0, yOff = 0; y < bh4; y += th, yOff++) {
1049
+ for (let x = 0, xOff = 0; x < bw4; x += tw, xOff++) {
1050
+ this.readTxTree(ytx, 0, xOff, yOff);
1051
+ this.bx += tw;
1052
+ }
1053
+ this.bx -= bw4 + tw - 1 & ~(tw - 1);
1054
+ this.by += th;
1055
+ }
1056
+ this.by -= bh4 + th - 1 & ~(th - 1);
1057
+ b.uvtx = MAX_TXFM_SIZE_FOR_BS[bs * 4 + f.layout];
1058
+ }
1059
+ }
1060
+ readTxTree(from, depth, xOff, yOff) {
1061
+ const f = this.frame, m = this.msac;
1062
+ const bx4 = this.bx, by4 = this.by & 31;
1063
+ const txw = tdim(from, LW), txh = tdim(from, LH);
1064
+ let split = 0;
1065
+ if (depth < 2 && from > TX_4X4) {
1066
+ const cat = 2 * (TX_64X64 - tdim(from, MAX)) - depth;
1067
+ const a = this.aTx[bx4] < txw ? 1 : 0, l = this.lTx[by4] < txh ? 1 : 0;
1068
+ split = m.boolAdapt(this.cdf, CDF.txPart + (cat * 3 + a + l) * 2);
1069
+ if (split)
1070
+ this.txSplit[depth] |= 1 << (yOff * 4 + xOff);
1071
+ }
1072
+ if (split && tdim(from, MAX) > 1) {
1073
+ const sub = tdim(from, SUB), sw = tdim(sub, W), sh = tdim(sub, H);
1074
+ this.readTxTree(sub, depth + 1, xOff * 2, yOff * 2);
1075
+ this.bx += sw;
1076
+ if (tdim(from, W) >= tdim(from, H) && this.bx < f.bw)
1077
+ this.readTxTree(sub, depth + 1, xOff * 2 + 1, yOff * 2);
1078
+ this.bx -= sw;
1079
+ this.by += sh;
1080
+ if (tdim(from, H) >= tdim(from, W) && this.by < f.bh) {
1081
+ this.readTxTree(sub, depth + 1, xOff * 2, yOff * 2 + 1);
1082
+ this.bx += sw;
1083
+ if (tdim(from, W) >= tdim(from, H) && this.bx < f.bw)
1084
+ this.readTxTree(sub, depth + 1, xOff * 2 + 1, yOff * 2 + 1);
1085
+ this.bx -= sw;
1086
+ }
1087
+ this.by -= sh;
1088
+ }
1089
+ else {
1090
+ this.aTx.fill(split ? TX_4X4 : txw, bx4, bx4 + (1 << tdim(from, LW)));
1091
+ this.lTx.fill(split ? TX_4X4 : txh, by4, by4 + (1 << tdim(from, LH)));
1092
+ }
1093
+ }
1094
+ mc(plane, w4, h4, bx, by, mvy, mvx) {
1095
+ const f = this.frame, ssx = plane ? f.ssx : 0, ssy = plane ? f.ssy : 0;
1096
+ const hMul = 4 >> ssx, vMul = 4 >> ssy;
1097
+ const mx = mvx & (15 >> (ssx ? 0 : 1)), my = mvy & (15 >> (ssy ? 0 : 1));
1098
+ const dx = bx * hMul + (mvx >> (3 + ssx)), dy = by * vMul + (mvy >> (3 + ssy));
1099
+ const w = (f.bw * 4) >> ssx, h = (f.bh * 4) >> ssy;
1100
+ const pic = f.planes[plane], stride = f.strides[plane];
1101
+ const bw = w4 * hMul, bh = h4 * vMul;
1102
+ const fx = mx << (ssx ? 0 : 1), fy = my << (ssy ? 0 : 1);
1103
+ const at = (x, y) => pic[Math.min(h - 1, Math.max(0, y)) * stride + Math.min(w - 1, Math.max(0, x))];
1104
+ const ib = f.bitdepth === 12 ? 2 : 4, rnd = (1 << ib) >> 1, max = f.bitdepthMax;
1105
+ const clip = (v) => v < 0 ? 0 : v > max ? max : v;
1106
+ const out = new Uint16Array(bw * bh);
1107
+ for (let y = 0; y < bh; y++) {
1108
+ for (let x = 0; x < bw; x++) {
1109
+ const sx = dx + x, sy = dy + y;
1110
+ let v;
1111
+ if (fx && fy) {
1112
+ const h0 = 16 * at(sx, sy) + fx * (at(sx + 1, sy) - at(sx, sy)) + ((1 << (4 - ib)) >> 1) >> (4 - ib);
1113
+ const h1 = 16 * at(sx, sy + 1) + fx * (at(sx + 1, sy + 1) - at(sx, sy + 1)) + ((1 << (4 - ib)) >> 1) >> (4 - ib);
1114
+ v = clip((16 * h0 + fy * (h1 - h0) + ((1 << (4 + ib)) >> 1)) >> (4 + ib));
1115
+ }
1116
+ else if (fx) {
1117
+ const p = 16 * at(sx, sy) + fx * (at(sx + 1, sy) - at(sx, sy)) + ((1 << (4 - ib)) >> 1) >> (4 - ib);
1118
+ v = clip((p + rnd) >> ib);
1119
+ }
1120
+ else if (fy) {
1121
+ v = clip((16 * at(sx, sy) + fy * (at(sx, sy + 1) - at(sx, sy)) + 8) >> 4);
1122
+ }
1123
+ else
1124
+ v = at(sx, sy);
1125
+ out[y * bw + x] = v;
1126
+ }
1127
+ }
1128
+ for (let y = 0; y < bh; y++)
1129
+ pic.set(out.subarray(y * bw, (y + 1) * bw), (by * vMul + y) * stride + bx * hMul);
1130
+ }
1131
+ reconInter(bs, b, hasChroma, mvy, mvx) {
1132
+ const f = this.frame, ssx = f.ssx, ssy = f.ssy;
1133
+ const bx = this.bx, by = this.by, bx4 = bx, by4 = by & 31;
1134
+ const cbx4 = bx4 >> ssx, cby4 = by4 >> ssy;
1135
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1);
1136
+ const w4 = Math.min(bw4, f.bw - bx), h4 = Math.min(bh4, f.bh - by);
1137
+ const cbw4 = bw4 + ssx >> ssx, cbh4 = bh4 + ssy >> ssy;
1138
+ this.mc(0, bw4, bh4, bx, by, mvy, mvx);
1139
+ if (hasChroma) {
1140
+ for (let pl = 1; pl < 3; pl++) {
1141
+ this.mc(pl, bw4 << (bw4 === ssx ? 1 : 0), bh4 << (bh4 === ssy ? 1 : 0), bx & ~ssx, by & ~ssy, mvy, mvx);
1142
+ }
1143
+ }
1144
+ if (b.skip) {
1145
+ this.aLcoef.fill(0x40, bx4, bx4 + (1 << bdim(bs, 2)));
1146
+ this.lLcoef.fill(0x40, by4, by4 + (1 << bdim(bs, 3)));
1147
+ if (hasChroma) {
1148
+ const cw = 1 << (31 - Math.clz32(cbw4)), ch = 1 << (31 - Math.clz32(cbh4));
1149
+ for (let pl = 0; pl < 2; pl++) {
1150
+ this.aCcoef[pl].fill(0x40, cbx4, cbx4 + cw);
1151
+ this.lCcoef[pl].fill(0x40, cby4, cby4 + ch);
1152
+ }
1153
+ }
1154
+ return;
1155
+ }
1156
+ const ytx = this.maxYtx, ytw = tdim(ytx, W), yth = tdim(ytx, H);
1157
+ const uvtx = b.uvtx, uvtw = tdim(uvtx, W), uvth = tdim(uvtx, H);
1158
+ const cw4 = w4 + ssx >> ssx, ch4 = h4 + ssy >> ssy;
1159
+ const stride = f.strides[0], cstride = f.strides[1];
1160
+ for (let initY = 0; initY < bh4; initY += 16) {
1161
+ for (let initX = 0; initX < bw4; initX += 16) {
1162
+ let yOff = initY ? 1 : 0;
1163
+ for (let y = initY; y < Math.min(h4, initY + 16); y += yth, yOff++) {
1164
+ let xOff = initX ? 1 : 0;
1165
+ for (let x = initX; x < Math.min(w4, initX + 16); x += ytw, xOff++) {
1166
+ this.bx = bx + x;
1167
+ this.by = by + y;
1168
+ this.readCoefTree(bs, b, ytx, 0, xOff, yOff, 4 * ((by + y) * stride + bx + x));
1169
+ }
1170
+ }
1171
+ this.bx = bx;
1172
+ this.by = by;
1173
+ if (!hasChroma)
1174
+ continue;
1175
+ for (let pl = 0; pl < 2; pl++) {
1176
+ const plane = f.planes[1 + pl];
1177
+ for (let y = initY >> ssy; y < Math.min(ch4, (initY + 16) >> ssy); y += uvth) {
1178
+ for (let x = initX >> ssx; x < Math.min(cw4, (initX + 16) >> ssx); x += uvtw) {
1179
+ const tbx = bx + (x << ssx), tby = by + (y << ssy);
1180
+ this.txtp = this.txtpMap[((by4 + (y << ssy)) & 31) * 32 + ((bx4 + (x << ssx)) & 31)];
1181
+ const eob = this.decodeCoefs(this.aCcoef[pl], cbx4 + x, this.lCcoef[pl], cby4 + y, uvtx, bs, b, 1 + pl, false);
1182
+ const ctw = Math.min(uvtw, (f.bw - tbx + ssx) >> ssx), cth = Math.min(uvth, (f.bh - tby + ssy) >> ssy);
1183
+ this.aCcoef[pl].fill(this.resCtx, cbx4 + x, cbx4 + x + ctw);
1184
+ this.lCcoef[pl].fill(this.resCtx, cby4 + y, cby4 + y + cth);
1185
+ if (eob >= 0)
1186
+ inverseTransformAdd(plane, 4 * (((by >> ssy) + y) * cstride + (bx >> ssx) + x), cstride, this.cf, eob, uvtx, this.txtp, f.bitdepthMax);
1187
+ }
1188
+ }
1189
+ }
1190
+ }
1191
+ }
1192
+ }
1193
+ readCoefTree(bs, b, ytx, depth, xOff, yOff, dst) {
1194
+ const f = this.frame;
1195
+ const tw = tdim(ytx, W), th = tdim(ytx, H);
1196
+ if (depth < 2 && this.txSplit[depth] && this.txSplit[depth] & 1 << (yOff * 4 + xOff)) {
1197
+ const sub = tdim(ytx, SUB), sw = tdim(sub, W), sh = tdim(sub, H);
1198
+ const stride = f.strides[0];
1199
+ this.readCoefTree(bs, b, sub, depth + 1, xOff * 2, yOff * 2, dst);
1200
+ this.bx += sw;
1201
+ if (tw >= th && this.bx < f.bw)
1202
+ this.readCoefTree(bs, b, sub, depth + 1, xOff * 2 + 1, yOff * 2, dst + 4 * sw);
1203
+ this.bx -= sw;
1204
+ this.by += sh;
1205
+ if (th >= tw && this.by < f.bh) {
1206
+ const d2 = dst + 4 * sh * stride;
1207
+ this.readCoefTree(bs, b, sub, depth + 1, xOff * 2, yOff * 2 + 1, d2);
1208
+ this.bx += sw;
1209
+ if (tw >= th && this.bx < f.bw)
1210
+ this.readCoefTree(bs, b, sub, depth + 1, xOff * 2 + 1, yOff * 2 + 1, d2 + 4 * sw);
1211
+ this.bx -= sw;
1212
+ }
1213
+ this.by -= sh;
1214
+ return;
1215
+ }
1216
+ const bx4 = this.bx, by4 = this.by & 31;
1217
+ const eob = this.decodeCoefs(this.aLcoef, bx4, this.lLcoef, by4, ytx, bs, b, 0, false);
1218
+ this.aLcoef.fill(this.resCtx, bx4, bx4 + Math.min(tw, f.bw - this.bx));
1219
+ this.lLcoef.fill(this.resCtx, by4, by4 + Math.min(th, f.bh - this.by));
1220
+ for (let y = 0; y < th; y++)
1221
+ this.txtpMap.fill(this.txtp, ((by4 + y) & 31) * 32 + (bx4 & 31), ((by4 + y) & 31) * 32 + (bx4 & 31) + Math.min(1 << tdim(ytx, LW), 16));
1222
+ if (eob >= 0)
1223
+ inverseTransformAdd(f.planes[0], dst, f.strides[0], this.cf, eob, ytx, this.txtp, f.bitdepthMax);
1224
+ }
1225
+ readPalPlane(b, pl, szCtx, bx4, by4) {
1226
+ const m = this.msac, f = this.frame;
1227
+ const palSz = b.palSz[pl] = m.symbol(this.cdf, CDF.palSize + (pl * 7 + szCtx) * 8, 6) + 2;
1228
+ const cache = [], used = [];
1229
+ let lCache = pl ? this.lPalSzUv[by4] : this.lPalSz[by4];
1230
+ let aCache = by4 & 15 ? pl ? this.aPalSzUv[bx4] : this.aPalSz[bx4] : 0;
1231
+ let l = by4 * 24 + pl * 8, a = bx4 * 24 + pl * 8;
1232
+ const L = this.lPal, A = this.aPal;
1233
+ const push = (v) => {
1234
+ if (!cache.length || cache[cache.length - 1] !== v)
1235
+ cache.push(v);
1236
+ };
1237
+ while (lCache && aCache) {
1238
+ if (L[l] < A[a]) {
1239
+ push(L[l++]);
1240
+ lCache--;
1241
+ }
1242
+ else {
1243
+ if (A[a] === L[l]) {
1244
+ l++;
1245
+ lCache--;
1246
+ }
1247
+ push(A[a++]);
1248
+ aCache--;
1249
+ }
1250
+ }
1251
+ while (lCache-- > 0)
1252
+ push(L[l++]);
1253
+ while (aCache-- > 0)
1254
+ push(A[a++]);
1255
+ for (let n = 0; n < cache.length && used.length < palSz; n++)
1256
+ if (m.bool())
1257
+ used.push(cache[n]);
1258
+ const pal = this.pal, o = pl * 8;
1259
+ let i = used.length;
1260
+ if (i < palSz) {
1261
+ const bpc = f.bitdepth;
1262
+ let prev = pal[o + i++] = m.bools(bpc);
1263
+ if (i < palSz) {
1264
+ let bits = bpc - 3 + m.bools(2);
1265
+ const max = (1 << bpc) - 1, minus = pl ? 0 : 1;
1266
+ do {
1267
+ const delta = m.bools(bits);
1268
+ prev = pal[o + i++] = Math.min(prev + delta + minus, max);
1269
+ if (prev + minus >= max) {
1270
+ for (; i < palSz; i++)
1271
+ pal[o + i] = max;
1272
+ break;
1273
+ }
1274
+ bits = Math.min(bits, 1 + (31 - Math.clz32(max - prev - minus)));
1275
+ } while (i < palSz);
1276
+ }
1277
+ const merged = [];
1278
+ let n = 0, k = used.length;
1279
+ for (i = 0; i < palSz; i++) {
1280
+ if (n < used.length && (k >= palSz || used[n] <= pal[o + k]))
1281
+ merged.push(used[n++]);
1282
+ else
1283
+ merged.push(pal[o + k++]);
1284
+ }
1285
+ pal.set(merged, o);
1286
+ }
1287
+ else
1288
+ pal.set(used, o);
1289
+ }
1290
+ readPalUv(b, szCtx, bx4, by4) {
1291
+ this.readPalPlane(b, 1, szCtx, bx4, by4);
1292
+ const m = this.msac, pal = this.pal, bpc = this.frame.bitdepth;
1293
+ if (m.bool()) {
1294
+ const bits = bpc - 4 + m.bools(2);
1295
+ let prev = pal[16] = m.bools(bpc);
1296
+ const max = (1 << bpc) - 1;
1297
+ for (let i = 1; i < b.palSz[1]; i++) {
1298
+ let delta = m.bools(bits);
1299
+ if (delta && m.bool())
1300
+ delta = -delta;
1301
+ prev = pal[16 + i] = prev + delta & max;
1302
+ }
1303
+ }
1304
+ else {
1305
+ for (let i = 0; i < b.palSz[1]; i++)
1306
+ pal[16 + i] = m.bools(bpc);
1307
+ }
1308
+ }
1309
+ readPalIndices(out, palSz, pl, w4, h4, bw4, bh4) {
1310
+ const m = this.msac, cdf = this.cdf, stride = bw4 * 4, t = this.palTmp;
1311
+ t[0] = m.uniform(palSz);
1312
+ const order = [0, 0, 0, 0, 0, 0, 0, 0];
1313
+ for (let i = 1; i < 4 * (w4 + h4) - 1; i++) {
1314
+ const first = Math.min(i, w4 * 4 - 1), last = Math.max(0, i - h4 * 4 + 1);
1315
+ for (let j = first; j >= last; j--) {
1316
+ const p = (i - j) * stride + j;
1317
+ const haveTop = i - j > 0, haveLeft = j > 0;
1318
+ let ctx, n = 0, mask = 0;
1319
+ const add = (v) => { order[n++] = v; mask |= 1 << v; };
1320
+ if (!haveLeft) {
1321
+ ctx = 0;
1322
+ add(t[p - stride]);
1323
+ }
1324
+ else if (!haveTop) {
1325
+ ctx = 0;
1326
+ add(t[p - 1]);
1327
+ }
1328
+ else {
1329
+ const l = t[p - 1], tp = t[p - stride], tl = t[p - stride - 1];
1330
+ const sameTL = tp === l, sameTTl = tp === tl, sameLTl = l === tl;
1331
+ if (sameTL && sameTTl && sameLTl) {
1332
+ ctx = 4;
1333
+ add(tp);
1334
+ }
1335
+ else if (sameTL) {
1336
+ ctx = 3;
1337
+ add(tp);
1338
+ add(tl);
1339
+ }
1340
+ else if (sameTTl || sameLTl) {
1341
+ ctx = 2;
1342
+ add(tl);
1343
+ add(sameTTl ? l : tp);
1344
+ }
1345
+ else {
1346
+ ctx = 1;
1347
+ add(Math.min(tp, l));
1348
+ add(Math.max(tp, l));
1349
+ add(tl);
1350
+ }
1351
+ }
1352
+ for (let bit = 0; bit < 8; bit++)
1353
+ if (!(mask & 1 << bit))
1354
+ order[n++] = bit;
1355
+ const idx = m.symbol(cdf, CDF.colorMap + ((pl * 7 + palSz - 2) * 5 + ctx) * 8, palSz - 1);
1356
+ t[p] = order[idx];
1357
+ }
1358
+ }
1359
+ const w = w4 * 4, h = h4 * 4, bw = bw4 * 4, bh = bh4 * 4;
1360
+ for (let y = 0; y < h; y++) {
1361
+ for (let x = 0; x < w; x++)
1362
+ out[y * bw + x] = t[y * stride + x];
1363
+ out.fill(t[y * stride + w - 1], y * bw + w, y * bw + bw);
1364
+ }
1365
+ for (let y = h; y < bh; y++)
1366
+ out.copyWithin(y * bw, (h - 1) * bw, h * bw);
1367
+ }
1368
+ txtp = 0;
1369
+ resCtx = 0;
1370
+ decodeCoefs(aArr, a, lArr, l, tx, bs, b, plane, intra = true) {
1371
+ const m = this.msac, cdf = this.cdf, f = this.frame, hdr = this.hdr;
1372
+ const chroma = plane ? 1 : 0;
1373
+ const lossless = hdr.segmentation.lossless[b.segId];
1374
+ const tlw = tdim(tx, LW), tlh = tdim(tx, LH), tctx = tdim(tx, CTX), tmin = tdim(tx, MIN), tmax = tdim(tx, MAX);
1375
+ let sctx;
1376
+ const aw = 1 << tlw, lh = 1 << tlh;
1377
+ if (chroma) {
1378
+ const bl2 = bdim(bs, 2), bl3 = bdim(bs, 3);
1379
+ const notOneBlk = bl2 - (bl2 && f.ssx ? 1 : 0) > tlw || bl3 - (bl3 && f.ssy ? 1 : 0) > tlh;
1380
+ let ca = 0, cl = 0;
1381
+ for (let i = 0; i < aw; i++)
1382
+ if (aArr[a + i] !== 0x40) {
1383
+ ca = 1;
1384
+ break;
1385
+ }
1386
+ for (let i = 0; i < lh; i++)
1387
+ if (lArr[l + i] !== 0x40) {
1388
+ cl = 1;
1389
+ break;
1390
+ }
1391
+ sctx = 7 + (notOneBlk ? 3 : 0) + ca + cl;
1392
+ }
1393
+ else if (bdim(bs, 2) === tlw && bdim(bs, 3) === tlh) {
1394
+ sctx = 0;
1395
+ }
1396
+ else {
1397
+ let la = 0, ll = 0;
1398
+ for (let i = 0; i < aw; i++)
1399
+ la |= aArr[a + i];
1400
+ for (let i = 0; i < lh; i++)
1401
+ ll |= lArr[l + i];
1402
+ sctx = SKIP_CTX[Math.min(la & 0x3f, 4) * 5 + Math.min(ll & 0x3f, 4)];
1403
+ }
1404
+ if (m.boolAdapt(cdf, CDF.coefSkip + (tctx * 13 + sctx) * 2)) {
1405
+ this.resCtx = 0x40;
1406
+ this.txtp = lossless ? WHT_WHT : DCT_DCT;
1407
+ return -1;
1408
+ }
1409
+ let txtp;
1410
+ if (lossless)
1411
+ txtp = WHT_WHT;
1412
+ else if (tmax + (intra ? 1 : 0) >= TX_64X64)
1413
+ txtp = DCT_DCT;
1414
+ else if (chroma) {
1415
+ if (intra)
1416
+ txtp = TXTP_FROM_UVMODE[b.uvMode];
1417
+ else {
1418
+ const y = this.txtp;
1419
+ if (tmax === TX_32X32)
1420
+ txtp = y === IDTX ? IDTX : DCT_DCT;
1421
+ else if (tmin === TX_16X16 && (1 << y & (1 << 15 | 1 << 14 | 1 << 13 | 1 << 12)))
1422
+ txtp = DCT_DCT;
1423
+ else
1424
+ txtp = y;
1425
+ }
1426
+ }
1427
+ else if (!hdr.segmentation.qidx[b.segId])
1428
+ txtp = DCT_DCT;
1429
+ else if (!intra) {
1430
+ if (hdr.reducedTxSet || tmax === TX_32X32)
1431
+ txtp = m.boolAdapt(cdf, CDF.txtpInter3 + tmin * 2) ? DCT_DCT : IDTX;
1432
+ else if (tmin === TX_16X16)
1433
+ txtp = TX_TYPES_PER_SET[m.symbol(cdf, CDF.txtpInter2, 11) + 12];
1434
+ else
1435
+ txtp = TX_TYPES_PER_SET[m.symbol(cdf, CDF.txtpInter1 + tmin * 16, 15) + 24];
1436
+ }
1437
+ else {
1438
+ const yModeNofilt = b.yMode === FILTER_PRED ? FILTER_MODE_TO_Y_MODE[b.yAngle] : b.yMode;
1439
+ if (hdr.reducedTxSet || tmin === TX_16X16)
1440
+ txtp = TX_TYPES_PER_SET[m.symbol(cdf, CDF.txtpIntra2 + (tmin * 13 + yModeNofilt) * 8, 4)];
1441
+ else
1442
+ txtp = TX_TYPES_PER_SET[m.symbol(cdf, CDF.txtpIntra1 + (tmin * 13 + yModeNofilt) * 8, 6) + 5];
1443
+ }
1444
+ this.txtp = txtp;
1445
+ const slw = Math.min(tlw, 3), slh = Math.min(tlh, 3);
1446
+ const tx2d = slw + slh;
1447
+ const txClass = TX_TYPE_CLASS[txtp];
1448
+ const is1d = txClass !== TX_CLASS_2D ? 1 : 0;
1449
+ let eobBin;
1450
+ switch (tx2d) {
1451
+ case 0:
1452
+ eobBin = m.symbol(cdf, CDF.eobBin16 + (chroma * 2 + is1d) * 8, 4);
1453
+ break;
1454
+ case 1:
1455
+ eobBin = m.symbol(cdf, CDF.eobBin32 + (chroma * 2 + is1d) * 8, 5);
1456
+ break;
1457
+ case 2:
1458
+ eobBin = m.symbol(cdf, CDF.eobBin64 + (chroma * 2 + is1d) * 8, 6);
1459
+ break;
1460
+ case 3:
1461
+ eobBin = m.symbol(cdf, CDF.eobBin128 + (chroma * 2 + is1d) * 8, 7);
1462
+ break;
1463
+ case 4:
1464
+ eobBin = m.symbol(cdf, CDF.eobBin256 + (chroma * 2 + is1d) * 16, 8);
1465
+ break;
1466
+ case 5:
1467
+ eobBin = m.symbol(cdf, CDF.eobBin512 + chroma * 16, 9);
1468
+ break;
1469
+ default:
1470
+ eobBin = m.symbol(cdf, CDF.eobBin1024 + chroma * 16, 10);
1471
+ break;
1472
+ }
1473
+ let eob;
1474
+ if (eobBin > 1) {
1475
+ const hi = m.boolAdapt(cdf, CDF.eobHiBit + ((tctx * 2 + chroma) * 11 + eobBin) * 2);
1476
+ eob = (hi | 2) << (eobBin - 2) | m.bools(eobBin - 2);
1477
+ }
1478
+ else
1479
+ eob = eobBin;
1480
+ const cf = this.cf, levels = this.levels;
1481
+ const eobCdf = CDF.eobBaseTok + (tctx * 2 + chroma) * 16;
1482
+ const hiCdf = CDF.brTok + (Math.min(tctx, 3) * 2 + chroma) * 84;
1483
+ let rc, dcTok;
1484
+ if (eob) {
1485
+ const loCdf = CDF.baseTok + (tctx * 2 + chroma) * 164;
1486
+ let ctx = 1 + (eob > 2 << tx2d ? 1 : 0) + (eob > 4 << tx2d ? 1 : 0);
1487
+ const eobTok = m.symbol(cdf, eobCdf + ctx * 4, 2);
1488
+ let tok = eobTok + 1;
1489
+ let levelTok = tok * 0x41;
1490
+ let mag = 0;
1491
+ let scanTable = null, stride, shift, shift2, mask, offsets = 0;
1492
+ if (txClass === TX_CLASS_2D) {
1493
+ const nonsquare = tx >= RTX_4X8 ? 1 : 0;
1494
+ offsets = (nonsquare + (tx & nonsquare)) * 25;
1495
+ scanTable = scan(tx);
1496
+ stride = 4 << slh;
1497
+ shift = slh + 2;
1498
+ shift2 = 0;
1499
+ mask = (4 << slh) - 1;
1500
+ levels.fill(0, 0, stride * ((4 << slw) + 2));
1501
+ }
1502
+ else if (txClass === TX_CLASS_H) {
1503
+ stride = 16;
1504
+ shift = slh + 2;
1505
+ shift2 = 0;
1506
+ mask = (4 << slh) - 1;
1507
+ levels.fill(0, 0, stride * ((4 << slh) + 2));
1508
+ }
1509
+ else {
1510
+ stride = 16;
1511
+ shift = slw + 2;
1512
+ shift2 = slh + 2;
1513
+ mask = (4 << slw) - 1;
1514
+ levels.fill(0, 0, stride * ((4 << slw) + 2));
1515
+ }
1516
+ let hiMag = 0;
1517
+ const loCtx = (lv, x, y) => {
1518
+ let mg = levels[lv + 1] + levels[lv + stride];
1519
+ let off;
1520
+ if (txClass === TX_CLASS_2D) {
1521
+ mg += levels[lv + stride + 1];
1522
+ hiMag = mg;
1523
+ mg += levels[lv + 2] + levels[lv + 2 * stride];
1524
+ off = LO_CTX_OFFSETS[offsets + Math.min(y, 4) * 5 + Math.min(x, 4)];
1525
+ }
1526
+ else {
1527
+ mg += levels[lv + 2];
1528
+ hiMag = mg;
1529
+ mg += levels[lv + 3] + levels[lv + 4];
1530
+ off = 26 + (y > 1 ? 10 : y * 5);
1531
+ }
1532
+ return off + (mg > 512 ? 4 : mg + 64 >> 7);
1533
+ };
1534
+ const position = (i) => {
1535
+ if (txClass === TX_CLASS_2D) {
1536
+ const r = scanTable[i];
1537
+ return [r, r >> shift, r & mask];
1538
+ }
1539
+ const x = i & mask, y = i >> shift;
1540
+ return [txClass === TX_CLASS_H ? i : x << shift2 | y, x, y];
1541
+ };
1542
+ const [r, x, y] = position(eob);
1543
+ rc = r;
1544
+ if (eobTok === 2) {
1545
+ ctx = (txClass === TX_CLASS_2D ? (x | y) > 1 : y !== 0) ? 14 : 7;
1546
+ tok = m.hiTok(cdf, hiCdf + ctx * 4);
1547
+ levelTok = tok + (3 << 6);
1548
+ }
1549
+ cf[rc] = tok << 11;
1550
+ levels[x * stride + y] = levelTok;
1551
+ for (let i = eob - 1; i > 0; i--) {
1552
+ const [rcI, xi, yi0] = position(i);
1553
+ const lv = xi * stride + yi0;
1554
+ ctx = loCtx(lv, xi, yi0);
1555
+ const yi = txClass === TX_CLASS_2D ? yi0 | xi : yi0;
1556
+ tok = m.symbol(cdf, loCdf + ctx * 4, 3);
1557
+ if (tok === 3) {
1558
+ mag = hiMag & 63;
1559
+ ctx = (yi > (txClass === TX_CLASS_2D ? 1 : 0) ? 14 : 7) + (mag > 12 ? 6 : mag + 1 >> 1);
1560
+ tok = m.hiTok(cdf, hiCdf + ctx * 4);
1561
+ levels[lv] = tok + (3 << 6);
1562
+ cf[rcI] = tok << 11 | rc;
1563
+ rc = rcI;
1564
+ }
1565
+ else {
1566
+ levels[lv] = tok * 0x41;
1567
+ if (tok) {
1568
+ cf[rcI] = tok << 11 | rc;
1569
+ rc = rcI;
1570
+ }
1571
+ else
1572
+ cf[rcI] = 0;
1573
+ }
1574
+ }
1575
+ ctx = txClass === TX_CLASS_2D ? 0 : loCtx(0, 0, 0);
1576
+ dcTok = m.symbol(cdf, loCdf + ctx * 4, 3);
1577
+ if (dcTok === 3) {
1578
+ if (txClass === TX_CLASS_2D)
1579
+ hiMag = levels[1] + levels[stride] + levels[stride + 1];
1580
+ mag = hiMag & 63;
1581
+ ctx = mag > 12 ? 6 : mag + 1 >> 1;
1582
+ dcTok = m.hiTok(cdf, hiCdf + ctx * 4);
1583
+ }
1584
+ }
1585
+ else {
1586
+ const tokBr = m.symbol(cdf, eobCdf, 2);
1587
+ dcTok = 1 + tokBr;
1588
+ if (tokBr === 2)
1589
+ dcTok = m.hiTok(cdf, hiCdf);
1590
+ rc = 0;
1591
+ }
1592
+ const dq = this.dq[b.segId][plane];
1593
+ const qm = txtp < IDTX ? this.qm[tx][plane] : null;
1594
+ const dqShift = Math.max(0, tctx - 2);
1595
+ const cfMax = (128 << (f.bitdepth === 8 ? 8 : f.bitdepth)) - 1;
1596
+ let culLevel, dcSignLevel;
1597
+ if (!dcTok) {
1598
+ culLevel = 0;
1599
+ dcSignLevel = 1 << 6;
1600
+ }
1601
+ else {
1602
+ let sctx2 = 0;
1603
+ for (let i = 0; i < aw; i++)
1604
+ sctx2 += aArr[a + i] >> 6;
1605
+ for (let i = 0; i < lh; i++)
1606
+ sctx2 += lArr[l + i] >> 6;
1607
+ sctx2 -= aw + lh;
1608
+ const dcSignCtx = (sctx2 !== 0 ? 1 : 0) + (sctx2 > 0 ? 1 : 0);
1609
+ const dcSign = m.boolAdapt(cdf, CDF.dcSign + (chroma * 3 + dcSignCtx) * 2);
1610
+ let dcDq = dq[0];
1611
+ dcSignLevel = (dcSign - 1) & (2 << 6);
1612
+ if (qm)
1613
+ dcDq = (dcDq * qm[0] + 16) >> 5;
1614
+ if (dcTok === 15) {
1615
+ dcTok = m.golomb() + 15 & 0xfffff;
1616
+ dcDq = (dcDq * dcTok & 0xffffff) >> dqShift;
1617
+ dcDq = Math.min(dcDq, cfMax + dcSign);
1618
+ }
1619
+ else {
1620
+ dcDq = (dcDq * dcTok) >> dqShift;
1621
+ if (qm)
1622
+ dcDq = Math.min(dcDq, cfMax + dcSign);
1623
+ }
1624
+ culLevel = dcTok;
1625
+ cf[0] = dcSign ? -dcDq : dcDq;
1626
+ }
1627
+ if (rc) {
1628
+ const acDq = dq[1];
1629
+ do {
1630
+ const sign = m.bool();
1631
+ const rcTok = cf[rc];
1632
+ let tok, d = qm ? (acDq * qm[rc] + 16) >> 5 : acDq;
1633
+ if (rcTok >= 15 << 11) {
1634
+ tok = m.golomb() + 15 & 0xfffff;
1635
+ d = (d * tok & 0xffffff) >> dqShift;
1636
+ d = Math.min(d, cfMax + sign);
1637
+ }
1638
+ else {
1639
+ tok = rcTok >> 11;
1640
+ d = (d * tok) >> dqShift;
1641
+ if (qm)
1642
+ d = Math.min(d, cfMax + sign);
1643
+ }
1644
+ culLevel += tok;
1645
+ cf[rc] = sign ? -d : d;
1646
+ rc = rcTok & 0x3ff;
1647
+ } while (rc);
1648
+ }
1649
+ this.resCtx = Math.min(culLevel, 63) | dcSignLevel;
1650
+ return eob;
1651
+ }
1652
+ reconIntra(bs, edgeFlags, b, hasChroma) {
1653
+ const f = this.frame, seq = this.seq;
1654
+ const bx = this.bx, by = this.by, bx4 = bx, by4 = by & 31;
1655
+ const ssx = f.ssx, ssy = f.ssy;
1656
+ const cbx4 = bx4 >> ssx, cby4 = by4 >> ssy;
1657
+ const bw4 = bdim(bs, 0), bh4 = bdim(bs, 1);
1658
+ const w4 = Math.min(bw4, f.bw - bx), h4 = Math.min(bh4, f.bh - by);
1659
+ const cw4 = w4 + ssx >> ssx, ch4 = h4 + ssy >> ssy;
1660
+ const cbw4 = bw4 + ssx >> ssx, cbh4 = bh4 + ssy >> ssy;
1661
+ const tx = b.tx, uvtx = b.uvtx;
1662
+ const tw = tdim(tx, W), th = tdim(tx, H), uvtw = tdim(uvtx, W), uvth = tdim(uvtx, H);
1663
+ const filterFlag = seq.intraEdgeFilter ? ANGLE_USE_EDGE_FILTER : 0;
1664
+ const bdMax = f.bitdepthMax;
1665
+ const pic = f.planes[0], stride = f.strides[0];
1666
+ const smFlag = (mode) => mode === SMOOTH_PRED || mode === SMOOTH_H_PRED || mode === SMOOTH_V_PRED ? ANGLE_SMOOTH_EDGE : 0;
1667
+ for (let initY = 0; initY < h4; initY += 16) {
1668
+ const subH4 = Math.min(h4, 16 + initY);
1669
+ const subCh4 = Math.min(ch4, initY + 16 >> ssy);
1670
+ for (let initX = 0; initX < w4; initX += 16) {
1671
+ if (b.palSz[0]) {
1672
+ const d = 4 * (by * stride + bx), bw = bw4 * 4;
1673
+ for (let y = 0; y < bh4 * 4; y++)
1674
+ for (let x = 0; x < bw; x++)
1675
+ pic[d + y * stride + x] = this.pal[this.palIdxY[y * bw + x]];
1676
+ }
1677
+ const intraFlags = (this.aIntra[bx4] ? smFlag(this.aMode[bx4]) : 0) | (this.lIntra[by4] ? smFlag(this.lMode[by4]) : 0) | filterFlag;
1678
+ const sbHasTr = initX + 16 < w4 ? 1 : initY ? 0 : edgeFlags & EDGE_I444_TOP_HAS_RIGHT;
1679
+ const sbHasBl = initX ? 0 : initY + 16 < h4 ? 1 : edgeFlags & EDGE_I444_LEFT_HAS_BOTTOM;
1680
+ const subW4 = Math.min(w4, initX + 16);
1681
+ for (let y = initY; y < subH4; y += th) {
1682
+ const ty = by + y;
1683
+ let d = 4 * (ty * stride + bx + initX);
1684
+ for (let x = initX; x < subW4; x += tw, d += 4 * tw) {
1685
+ const tx4 = bx + x;
1686
+ if (!b.palSz[0]) {
1687
+ const flags = (((y > initY || !sbHasTr) && x + tw >= subW4) ? 0 : EDGE_I444_TOP_HAS_RIGHT) |
1688
+ ((x > initX || (!sbHasBl && y + th >= subH4)) ? 0 : EDGE_I444_LEFT_HAS_BOTTOM);
1689
+ const mode = prepareEdges(tx4, tx4 > this.colStart, ty, ty > this.rowStart, this.colEnd, this.rowEnd, flags, pic, d, stride, b.yMode, b.yAngle, tw, th, seq.intraEdgeFilter, f.bitdepth);
1690
+ predict(mode, pic, d, stride, tw * 4, th * 4, preparedAngle | intraFlags, 4 * f.bw - 4 * tx4, 4 * f.bh - 4 * ty, bdMax);
1691
+ }
1692
+ if (!b.skip) {
1693
+ const eob = this.decodeCoefs(this.aLcoef, bx4 + x, this.lLcoef, by4 + y, tx, bs, b, 0);
1694
+ this.aLcoef.fill(this.resCtx, bx4 + x, bx4 + x + Math.min(tw, f.bw - tx4));
1695
+ this.lLcoef.fill(this.resCtx, by4 + y, by4 + y + Math.min(th, f.bh - ty));
1696
+ if (eob >= 0)
1697
+ inverseTransformAdd(pic, d, stride, this.cf, eob, tx, this.txtp, bdMax);
1698
+ }
1699
+ else {
1700
+ this.aLcoef.fill(0x40, bx4 + x, bx4 + x + tw);
1701
+ this.lLcoef.fill(0x40, by4 + y, by4 + y + th);
1702
+ }
1703
+ }
1704
+ }
1705
+ if (!hasChroma)
1706
+ continue;
1707
+ const cstride = f.strides[1];
1708
+ if (b.uvMode === CFL_PRED) {
1709
+ const yo = 4 * (bx & ~ssx) + 4 * (by & ~ssy) * stride;
1710
+ const furthestR = ((cw4 << ssx) + tw - 1) & ~(tw - 1);
1711
+ const furthestB = ((ch4 << ssy) + th - 1) & ~(th - 1);
1712
+ cflAc(this.ac, pic, yo, stride, cbw4 - (furthestR >> ssx), cbh4 - (furthestB >> ssy), cbw4 * 4, cbh4 * 4, ssx, ssy);
1713
+ const uvOff = 4 * ((bx >> ssx) + (by >> ssy) * cstride);
1714
+ for (let pl = 0; pl < 2; pl++) {
1715
+ if (!b.cflAlpha[pl])
1716
+ continue;
1717
+ const xpos = bx >> ssx, ypos = by >> ssy;
1718
+ const mode = prepareEdges(xpos, xpos > this.colStart >> ssx, ypos, ypos > this.rowStart >> ssy, this.colEnd >> ssx, this.rowEnd >> ssy, 0, f.planes[1 + pl], uvOff, cstride, DC_PRED, 0, uvtw, uvth, false, f.bitdepth);
1719
+ cflPredict(mode, f.planes[1 + pl], uvOff, cstride, uvtw * 4, uvth * 4, this.ac, b.cflAlpha[pl], bdMax);
1720
+ }
1721
+ }
1722
+ else if (b.palSz[1]) {
1723
+ const uvOff = 4 * ((bx >> ssx) + (by >> ssy) * cstride), bw = cbw4 * 4;
1724
+ for (let pl = 1; pl <= 2; pl++) {
1725
+ const plane = f.planes[pl];
1726
+ for (let y = 0; y < cbh4 * 4; y++)
1727
+ for (let x = 0; x < bw; x++)
1728
+ plane[uvOff + y * cstride + x] = this.pal[pl * 8 + this.palIdxUv[y * bw + x]];
1729
+ }
1730
+ }
1731
+ const smUv = smFlag(this.aUvmode[cbx4]) | smFlag(this.lUvmode[cby4]);
1732
+ const edge = f.layout === 1 ? [EDGE_I420_TOP_HAS_RIGHT, EDGE_I420_LEFT_HAS_BOTTOM] : f.layout === 2 ? [2, 16] : [1, 8];
1733
+ const uvSbHasTr = (initX + 16 >> ssx) < cw4 ? 1 : initY ? 0 : edgeFlags & edge[0];
1734
+ const uvSbHasBl = initX ? 0 : (initY + 16 >> ssy) < ch4 ? 1 : edgeFlags & edge[1];
1735
+ const subCw4 = Math.min(cw4, initX + 16 >> ssx);
1736
+ for (let pl = 0; pl < 2; pl++) {
1737
+ const plane = f.planes[1 + pl];
1738
+ const aC = this.aCcoef[pl], lC = this.lCcoef[pl];
1739
+ for (let y = initY >> ssy, tyl = by + initY; y < subCh4; y += uvth, tyl += uvth << ssy) {
1740
+ let d = 4 * ((tyl >> ssy) * cstride + (bx + initX >> ssx));
1741
+ for (let x = initX >> ssx, txl = bx + initX; x < subCw4; x += uvtw, txl += uvtw << ssx, d += uvtw * 4) {
1742
+ if (!(b.uvMode === CFL_PRED && b.cflAlpha[pl]) && !b.palSz[1]) {
1743
+ const flags = (((y > (initY >> ssy) || !uvSbHasTr) && x + uvtw >= subCw4) ? 0 : EDGE_I444_TOP_HAS_RIGHT) |
1744
+ ((x > (initX >> ssx) || (!uvSbHasBl && y + uvth >= subCh4)) ? 0 : EDGE_I444_LEFT_HAS_BOTTOM);
1745
+ const uvMode = b.uvMode === CFL_PRED ? DC_PRED : b.uvMode;
1746
+ const xpos = txl >> ssx, ypos = tyl >> ssy;
1747
+ const mode = prepareEdges(xpos, xpos > this.colStart >> ssx, ypos, ypos > this.rowStart >> ssy, this.colEnd >> ssx, this.rowEnd >> ssy, flags, plane, d, cstride, uvMode, b.uvAngle, uvtw, uvth, seq.intraEdgeFilter, f.bitdepth);
1748
+ predict(mode, plane, d, cstride, uvtw * 4, uvth * 4, preparedAngle | filterFlag | smUv, (4 * f.bw + ssx - 4 * (txl & ~ssx)) >> ssx, (4 * f.bh + ssy - 4 * (tyl & ~ssy)) >> ssy, bdMax);
1749
+ }
1750
+ if (!b.skip) {
1751
+ const eob = this.decodeCoefs(aC, cbx4 + x, lC, cby4 + y, uvtx, bs, b, 1 + pl);
1752
+ const ctw = Math.min(uvtw, (f.bw - txl + ssx) >> ssx);
1753
+ const cth = Math.min(uvth, (f.bh - tyl + ssy) >> ssy);
1754
+ aC.fill(this.resCtx, cbx4 + x, cbx4 + x + ctw);
1755
+ lC.fill(this.resCtx, cby4 + y, cby4 + y + cth);
1756
+ if (eob >= 0)
1757
+ inverseTransformAdd(plane, d, cstride, this.cf, eob, uvtx, this.txtp, bdMax);
1758
+ }
1759
+ else {
1760
+ aC.fill(0x40, cbx4 + x, cbx4 + x + uvtw);
1761
+ lC.fill(0x40, cby4 + y, cby4 + y + uvth);
1762
+ }
1763
+ }
1764
+ }
1765
+ }
1766
+ }
1767
+ }
1768
+ }
1769
+ }