Remove the closure from BitModel in the src/core/jpx.js file

This commit is contained in:
Jonas Jenwald 2023-04-21 21:16:57 +02:00
parent b0a1af306d
commit 88616f77ae

View File

@ -1738,381 +1738,380 @@ class InclusionTree {
} }
// Section D. Coefficient bit modeling // Section D. Coefficient bit modeling
const BitModel = (function BitModelClosure() { class BitModel {
const UNIFORM_CONTEXT = 17; static UNIFORM_CONTEXT = 17;
const RUNLENGTH_CONTEXT = 18;
static RUNLENGTH_CONTEXT = 18;
// Table D-1 // Table D-1
// The index is binary presentation: 0dddvvhh, ddd - sum of Di (0..4), // The index is binary presentation: 0dddvvhh, ddd - sum of Di (0..4),
// vv - sum of Vi (0..2), and hh - sum of Hi (0..2) // vv - sum of Vi (0..2), and hh - sum of Hi (0..2)
const LLAndLHContextsLabel = new Uint8Array([ static LLAndLHContextsLabel = new Uint8Array([
0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4, 0, 5, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 1, 6, 8, 0, 3, 7, 8, 0, 4,
7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6,
8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8, 8, 0, 3, 7, 8, 0, 4, 7, 8, 0, 0, 0, 0, 0, 2, 6, 8, 0, 3, 7, 8, 0, 4, 7, 8,
]); ]);
const HLContextLabel = new Uint8Array([
static HLContextLabel = new Uint8Array([
0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8, 0, 3, 4, 0, 5, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 1, 3, 4, 0, 6, 7, 7, 0, 8,
8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3,
4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8, 4, 0, 6, 7, 7, 0, 8, 8, 8, 0, 0, 0, 0, 0, 2, 3, 4, 0, 6, 7, 7, 0, 8, 8, 8,
]); ]);
const HHContextLabel = new Uint8Array([
static HHContextLabel = new Uint8Array([
0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5, 0, 1, 2, 0, 1, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 3, 4, 5, 0, 4, 5, 5, 0, 5,
5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8, 5, 5, 0, 0, 0, 0, 0, 6, 7, 7, 0, 7, 7, 7, 0, 7, 7, 7, 0, 0, 0, 0, 0, 8, 8,
8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8,
]); ]);
// eslint-disable-next-line no-shadow constructor(width, height, subband, zeroBitPlanes, mb) {
class BitModel { this.width = width;
constructor(width, height, subband, zeroBitPlanes, mb) { this.height = height;
this.width = width;
this.height = height;
let contextLabelTable; let contextLabelTable;
if (subband === "HH") { if (subband === "HH") {
contextLabelTable = HHContextLabel; contextLabelTable = BitModel.HHContextLabel;
} else if (subband === "HL") { } else if (subband === "HL") {
contextLabelTable = HLContextLabel; contextLabelTable = BitModel.HLContextLabel;
} else { } else {
contextLabelTable = LLAndLHContextsLabel; contextLabelTable = BitModel.LLAndLHContextsLabel;
}
this.contextLabelTable = contextLabelTable;
const coefficientCount = width * height;
// coefficients outside the encoding region treated as insignificant
// add border state cells for significanceState
this.neighborsSignificance = new Uint8Array(coefficientCount);
this.coefficentsSign = new Uint8Array(coefficientCount);
let coefficentsMagnitude;
if (mb > 14) {
coefficentsMagnitude = new Uint32Array(coefficientCount);
} else if (mb > 6) {
coefficentsMagnitude = new Uint16Array(coefficientCount);
} else {
coefficentsMagnitude = new Uint8Array(coefficientCount);
}
this.coefficentsMagnitude = coefficentsMagnitude;
this.processingFlags = new Uint8Array(coefficientCount);
const bitsDecoded = new Uint8Array(coefficientCount);
if (zeroBitPlanes !== 0) {
for (let i = 0; i < coefficientCount; i++) {
bitsDecoded[i] = zeroBitPlanes;
}
}
this.bitsDecoded = bitsDecoded;
this.reset();
} }
this.contextLabelTable = contextLabelTable;
setDecoder(decoder) { const coefficientCount = width * height;
this.decoder = decoder;
// coefficients outside the encoding region treated as insignificant
// add border state cells for significanceState
this.neighborsSignificance = new Uint8Array(coefficientCount);
this.coefficentsSign = new Uint8Array(coefficientCount);
let coefficentsMagnitude;
if (mb > 14) {
coefficentsMagnitude = new Uint32Array(coefficientCount);
} else if (mb > 6) {
coefficentsMagnitude = new Uint16Array(coefficientCount);
} else {
coefficentsMagnitude = new Uint8Array(coefficientCount);
} }
this.coefficentsMagnitude = coefficentsMagnitude;
this.processingFlags = new Uint8Array(coefficientCount);
reset() { const bitsDecoded = new Uint8Array(coefficientCount);
// We have 17 contexts that are accessed via context labels, if (zeroBitPlanes !== 0) {
// plus the uniform and runlength context. for (let i = 0; i < coefficientCount; i++) {
this.contexts = new Int8Array(19); bitsDecoded[i] = zeroBitPlanes;
}
// Contexts are packed into 1 byte:
// highest 7 bits carry the index, lowest bit carries mps
this.contexts[0] = (4 << 1) | 0;
this.contexts[UNIFORM_CONTEXT] = (46 << 1) | 0;
this.contexts[RUNLENGTH_CONTEXT] = (3 << 1) | 0;
} }
this.bitsDecoded = bitsDecoded;
setNeighborsSignificance(row, column, index) { this.reset();
const neighborsSignificance = this.neighborsSignificance; }
const width = this.width,
height = this.height;
const left = column > 0;
const right = column + 1 < width;
let i;
if (row > 0) { setDecoder(decoder) {
i = index - width; this.decoder = decoder;
if (left) { }
neighborsSignificance[i - 1] += 0x10;
}
if (right) {
neighborsSignificance[i + 1] += 0x10;
}
neighborsSignificance[i] += 0x04;
}
if (row + 1 < height) { reset() {
i = index + width; // We have 17 contexts that are accessed via context labels,
if (left) { // plus the uniform and runlength context.
neighborsSignificance[i - 1] += 0x10; this.contexts = new Int8Array(19);
}
if (right) {
neighborsSignificance[i + 1] += 0x10;
}
neighborsSignificance[i] += 0x04;
}
// Contexts are packed into 1 byte:
// highest 7 bits carry the index, lowest bit carries mps
this.contexts[0] = (4 << 1) | 0;
this.contexts[BitModel.UNIFORM_CONTEXT] = (46 << 1) | 0;
this.contexts[BitModel.RUNLENGTH_CONTEXT] = (3 << 1) | 0;
}
setNeighborsSignificance(row, column, index) {
const neighborsSignificance = this.neighborsSignificance;
const width = this.width,
height = this.height;
const left = column > 0;
const right = column + 1 < width;
let i;
if (row > 0) {
i = index - width;
if (left) { if (left) {
neighborsSignificance[index - 1] += 0x01; neighborsSignificance[i - 1] += 0x10;
} }
if (right) { if (right) {
neighborsSignificance[index + 1] += 0x01; neighborsSignificance[i + 1] += 0x10;
} }
neighborsSignificance[index] |= 0x80; neighborsSignificance[i] += 0x04;
} }
runSignificancePropagationPass() { if (row + 1 < height) {
const decoder = this.decoder; i = index + width;
const width = this.width, if (left) {
height = this.height; neighborsSignificance[i - 1] += 0x10;
const coefficentsMagnitude = this.coefficentsMagnitude; }
const coefficentsSign = this.coefficentsSign; if (right) {
const neighborsSignificance = this.neighborsSignificance; neighborsSignificance[i + 1] += 0x10;
const processingFlags = this.processingFlags; }
const contexts = this.contexts; neighborsSignificance[i] += 0x04;
const labels = this.contextLabelTable; }
const bitsDecoded = this.bitsDecoded;
const processedInverseMask = ~1;
const processedMask = 1;
const firstMagnitudeBitMask = 2;
for (let i0 = 0; i0 < height; i0 += 4) { if (left) {
for (let j = 0; j < width; j++) { neighborsSignificance[index - 1] += 0x01;
let index = i0 * width + j; }
for (let i1 = 0; i1 < 4; i1++, index += width) { if (right) {
const i = i0 + i1; neighborsSignificance[index + 1] += 0x01;
if (i >= height) { }
break; neighborsSignificance[index] |= 0x80;
} }
// clear processed flag first
processingFlags[index] &= processedInverseMask;
if (coefficentsMagnitude[index] || !neighborsSignificance[index]) { runSignificancePropagationPass() {
continue; const decoder = this.decoder;
} const width = this.width,
height = this.height;
const coefficentsMagnitude = this.coefficentsMagnitude;
const coefficentsSign = this.coefficentsSign;
const neighborsSignificance = this.neighborsSignificance;
const processingFlags = this.processingFlags;
const contexts = this.contexts;
const labels = this.contextLabelTable;
const bitsDecoded = this.bitsDecoded;
const processedInverseMask = ~1;
const processedMask = 1;
const firstMagnitudeBitMask = 2;
const contextLabel = labels[neighborsSignificance[index]]; for (let i0 = 0; i0 < height; i0 += 4) {
const decision = decoder.readBit(contexts, contextLabel); for (let j = 0; j < width; j++) {
if (decision) { let index = i0 * width + j;
const sign = this.decodeSignBit(i, j, index); for (let i1 = 0; i1 < 4; i1++, index += width) {
coefficentsSign[index] = sign; const i = i0 + i1;
coefficentsMagnitude[index] = 1; if (i >= height) {
this.setNeighborsSignificance(i, j, index); break;
processingFlags[index] |= firstMagnitudeBitMask;
}
bitsDecoded[index]++;
processingFlags[index] |= processedMask;
} }
// clear processed flag first
processingFlags[index] &= processedInverseMask;
if (coefficentsMagnitude[index] || !neighborsSignificance[index]) {
continue;
}
const contextLabel = labels[neighborsSignificance[index]];
const decision = decoder.readBit(contexts, contextLabel);
if (decision) {
const sign = this.decodeSignBit(i, j, index);
coefficentsSign[index] = sign;
coefficentsMagnitude[index] = 1;
this.setNeighborsSignificance(i, j, index);
processingFlags[index] |= firstMagnitudeBitMask;
}
bitsDecoded[index]++;
processingFlags[index] |= processedMask;
} }
} }
} }
}
decodeSignBit(row, column, index) { decodeSignBit(row, column, index) {
const width = this.width, const width = this.width,
height = this.height; height = this.height;
const coefficentsMagnitude = this.coefficentsMagnitude; const coefficentsMagnitude = this.coefficentsMagnitude;
const coefficentsSign = this.coefficentsSign; const coefficentsSign = this.coefficentsSign;
let contribution, sign0, sign1, significance1; let contribution, sign0, sign1, significance1;
let contextLabel, decoded; let contextLabel, decoded;
// calculate horizontal contribution // calculate horizontal contribution
significance1 = column > 0 && coefficentsMagnitude[index - 1] !== 0; significance1 = column > 0 && coefficentsMagnitude[index - 1] !== 0;
if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) { if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) {
sign1 = coefficentsSign[index + 1]; sign1 = coefficentsSign[index + 1];
if (significance1) { if (significance1) {
sign0 = coefficentsSign[index - 1];
contribution = 1 - sign1 - sign0;
} else {
contribution = 1 - sign1 - sign1;
}
} else if (significance1) {
sign0 = coefficentsSign[index - 1]; sign0 = coefficentsSign[index - 1];
contribution = 1 - sign0 - sign0; contribution = 1 - sign1 - sign0;
} else { } else {
contribution = 0; contribution = 1 - sign1 - sign1;
} }
const horizontalContribution = 3 * contribution; } else if (significance1) {
sign0 = coefficentsSign[index - 1];
contribution = 1 - sign0 - sign0;
} else {
contribution = 0;
}
const horizontalContribution = 3 * contribution;
// calculate vertical contribution and combine with the horizontal // calculate vertical contribution and combine with the horizontal
significance1 = row > 0 && coefficentsMagnitude[index - width] !== 0; significance1 = row > 0 && coefficentsMagnitude[index - width] !== 0;
if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) { if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) {
sign1 = coefficentsSign[index + width]; sign1 = coefficentsSign[index + width];
if (significance1) { if (significance1) {
sign0 = coefficentsSign[index - width];
contribution = 1 - sign1 - sign0 + horizontalContribution;
} else {
contribution = 1 - sign1 - sign1 + horizontalContribution;
}
} else if (significance1) {
sign0 = coefficentsSign[index - width]; sign0 = coefficentsSign[index - width];
contribution = 1 - sign0 - sign0 + horizontalContribution; contribution = 1 - sign1 - sign0 + horizontalContribution;
} else { } else {
contribution = horizontalContribution; contribution = 1 - sign1 - sign1 + horizontalContribution;
} }
} else if (significance1) {
if (contribution >= 0) { sign0 = coefficentsSign[index - width];
contextLabel = 9 + contribution; contribution = 1 - sign0 - sign0 + horizontalContribution;
decoded = this.decoder.readBit(this.contexts, contextLabel); } else {
} else { contribution = horizontalContribution;
contextLabel = 9 - contribution;
decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1;
}
return decoded;
} }
runMagnitudeRefinementPass() { if (contribution >= 0) {
const decoder = this.decoder; contextLabel = 9 + contribution;
const width = this.width, decoded = this.decoder.readBit(this.contexts, contextLabel);
height = this.height; } else {
const coefficentsMagnitude = this.coefficentsMagnitude; contextLabel = 9 - contribution;
const neighborsSignificance = this.neighborsSignificance; decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1;
const contexts = this.contexts; }
const bitsDecoded = this.bitsDecoded; return decoded;
const processingFlags = this.processingFlags; }
const processedMask = 1;
const firstMagnitudeBitMask = 2;
const length = width * height;
const width4 = width * 4;
for (let index0 = 0, indexNext; index0 < length; index0 = indexNext) { runMagnitudeRefinementPass() {
indexNext = Math.min(length, index0 + width4); const decoder = this.decoder;
for (let j = 0; j < width; j++) { const width = this.width,
for (let index = index0 + j; index < indexNext; index += width) { height = this.height;
// significant but not those that have just become const coefficentsMagnitude = this.coefficentsMagnitude;
if ( const neighborsSignificance = this.neighborsSignificance;
!coefficentsMagnitude[index] || const contexts = this.contexts;
(processingFlags[index] & processedMask) !== 0 const bitsDecoded = this.bitsDecoded;
) { const processingFlags = this.processingFlags;
continue; const processedMask = 1;
} const firstMagnitudeBitMask = 2;
const length = width * height;
const width4 = width * 4;
let contextLabel = 16; for (let index0 = 0, indexNext; index0 < length; index0 = indexNext) {
if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) { indexNext = Math.min(length, index0 + width4);
processingFlags[index] ^= firstMagnitudeBitMask; for (let j = 0; j < width; j++) {
// first refinement for (let index = index0 + j; index < indexNext; index += width) {
const significance = neighborsSignificance[index] & 127; // significant but not those that have just become
contextLabel = significance === 0 ? 15 : 14; if (
} !coefficentsMagnitude[index] ||
(processingFlags[index] & processedMask) !== 0
const bit = decoder.readBit(contexts, contextLabel); ) {
coefficentsMagnitude[index] = continue;
(coefficentsMagnitude[index] << 1) | bit;
bitsDecoded[index]++;
processingFlags[index] |= processedMask;
} }
let contextLabel = 16;
if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) {
processingFlags[index] ^= firstMagnitudeBitMask;
// first refinement
const significance = neighborsSignificance[index] & 127;
contextLabel = significance === 0 ? 15 : 14;
}
const bit = decoder.readBit(contexts, contextLabel);
coefficentsMagnitude[index] =
(coefficentsMagnitude[index] << 1) | bit;
bitsDecoded[index]++;
processingFlags[index] |= processedMask;
} }
} }
} }
}
runCleanupPass() { runCleanupPass() {
const decoder = this.decoder; const decoder = this.decoder;
const width = this.width, const width = this.width,
height = this.height; height = this.height;
const neighborsSignificance = this.neighborsSignificance; const neighborsSignificance = this.neighborsSignificance;
const coefficentsMagnitude = this.coefficentsMagnitude; const coefficentsMagnitude = this.coefficentsMagnitude;
const coefficentsSign = this.coefficentsSign; const coefficentsSign = this.coefficentsSign;
const contexts = this.contexts; const contexts = this.contexts;
const labels = this.contextLabelTable; const labels = this.contextLabelTable;
const bitsDecoded = this.bitsDecoded; const bitsDecoded = this.bitsDecoded;
const processingFlags = this.processingFlags; const processingFlags = this.processingFlags;
const processedMask = 1; const processedMask = 1;
const firstMagnitudeBitMask = 2; const firstMagnitudeBitMask = 2;
const oneRowDown = width; const oneRowDown = width;
const twoRowsDown = width * 2; const twoRowsDown = width * 2;
const threeRowsDown = width * 3; const threeRowsDown = width * 3;
let iNext; let iNext;
for (let i0 = 0; i0 < height; i0 = iNext) { for (let i0 = 0; i0 < height; i0 = iNext) {
iNext = Math.min(i0 + 4, height); iNext = Math.min(i0 + 4, height);
const indexBase = i0 * width; const indexBase = i0 * width;
const checkAllEmpty = i0 + 3 < height; const checkAllEmpty = i0 + 3 < height;
for (let j = 0; j < width; j++) { for (let j = 0; j < width; j++) {
const index0 = indexBase + j; const index0 = indexBase + j;
// using the property: labels[neighborsSignificance[index]] === 0 // using the property: labels[neighborsSignificance[index]] === 0
// when neighborsSignificance[index] === 0 // when neighborsSignificance[index] === 0
const allEmpty = const allEmpty =
checkAllEmpty && checkAllEmpty &&
processingFlags[index0] === 0 && processingFlags[index0] === 0 &&
processingFlags[index0 + oneRowDown] === 0 && processingFlags[index0 + oneRowDown] === 0 &&
processingFlags[index0 + twoRowsDown] === 0 && processingFlags[index0 + twoRowsDown] === 0 &&
processingFlags[index0 + threeRowsDown] === 0 && processingFlags[index0 + threeRowsDown] === 0 &&
neighborsSignificance[index0] === 0 && neighborsSignificance[index0] === 0 &&
neighborsSignificance[index0 + oneRowDown] === 0 && neighborsSignificance[index0 + oneRowDown] === 0 &&
neighborsSignificance[index0 + twoRowsDown] === 0 && neighborsSignificance[index0 + twoRowsDown] === 0 &&
neighborsSignificance[index0 + threeRowsDown] === 0; neighborsSignificance[index0 + threeRowsDown] === 0;
let i1 = 0, let i1 = 0,
index = index0; index = index0;
let i = i0, let i = i0,
sign; sign;
if (allEmpty) { if (allEmpty) {
const hasSignificantCoefficent = decoder.readBit( const hasSignificantCoefficent = decoder.readBit(
contexts, contexts,
RUNLENGTH_CONTEXT BitModel.RUNLENGTH_CONTEXT
); );
if (!hasSignificantCoefficent) { if (!hasSignificantCoefficent) {
bitsDecoded[index0]++; bitsDecoded[index0]++;
bitsDecoded[index0 + oneRowDown]++; bitsDecoded[index0 + oneRowDown]++;
bitsDecoded[index0 + twoRowsDown]++; bitsDecoded[index0 + twoRowsDown]++;
bitsDecoded[index0 + threeRowsDown]++; bitsDecoded[index0 + threeRowsDown]++;
continue; // next column continue; // next column
} }
i1 = i1 =
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | (decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1) |
decoder.readBit(contexts, UNIFORM_CONTEXT); decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT);
if (i1 !== 0) { if (i1 !== 0) {
i = i0 + i1; i = i0 + i1;
index += i1 * width; index += i1 * width;
} }
sign = this.decodeSignBit(i, j, index);
coefficentsSign[index] = sign;
coefficentsMagnitude[index] = 1;
this.setNeighborsSignificance(i, j, index);
processingFlags[index] |= firstMagnitudeBitMask;
index = index0;
for (let i2 = i0; i2 <= i; i2++, index += width) {
bitsDecoded[index]++;
}
i1++;
}
for (i = i0 + i1; i < iNext; i++, index += width) {
if (
coefficentsMagnitude[index] ||
(processingFlags[index] & processedMask) !== 0
) {
continue;
}
const contextLabel = labels[neighborsSignificance[index]];
const decision = decoder.readBit(contexts, contextLabel);
if (decision === 1) {
sign = this.decodeSignBit(i, j, index); sign = this.decodeSignBit(i, j, index);
coefficentsSign[index] = sign; coefficentsSign[index] = sign;
coefficentsMagnitude[index] = 1; coefficentsMagnitude[index] = 1;
this.setNeighborsSignificance(i, j, index); this.setNeighborsSignificance(i, j, index);
processingFlags[index] |= firstMagnitudeBitMask; processingFlags[index] |= firstMagnitudeBitMask;
index = index0;
for (let i2 = i0; i2 <= i; i2++, index += width) {
bitsDecoded[index]++;
}
i1++;
}
for (i = i0 + i1; i < iNext; i++, index += width) {
if (
coefficentsMagnitude[index] ||
(processingFlags[index] & processedMask) !== 0
) {
continue;
}
const contextLabel = labels[neighborsSignificance[index]];
const decision = decoder.readBit(contexts, contextLabel);
if (decision === 1) {
sign = this.decodeSignBit(i, j, index);
coefficentsSign[index] = sign;
coefficentsMagnitude[index] = 1;
this.setNeighborsSignificance(i, j, index);
processingFlags[index] |= firstMagnitudeBitMask;
}
bitsDecoded[index]++;
} }
bitsDecoded[index]++;
} }
} }
} }
checkSegmentationSymbol() {
const decoder = this.decoder;
const contexts = this.contexts;
const symbol =
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 3) |
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 2) |
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) |
decoder.readBit(contexts, UNIFORM_CONTEXT);
if (symbol !== 0xa) {
throw new JpxError("Invalid segmentation symbol");
}
}
} }
return BitModel; checkSegmentationSymbol() {
})(); const decoder = this.decoder;
const contexts = this.contexts;
const symbol =
(decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 3) |
(decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 2) |
(decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT) << 1) |
decoder.readBit(contexts, BitModel.UNIFORM_CONTEXT);
if (symbol !== 0xa) {
throw new JpxError("Invalid segmentation symbol");
}
}
}
// Section F, Discrete wavelet transformation // Section F, Discrete wavelet transformation
class Transform { class Transform {