9416b14e8b
This simplifies/consolidates the ESLint configuration slightly in the `src/` folder, and prevents the addition of any new files where `var` is being used.[1] Hence we no longer need to manually add `/* eslint no-var: error */` in files, which is easy to forget, and can instead disable the rule in the `src/core/` files where `var` is still in use. --- [1] Obviously the `no-var` rule can, in the same way as every other rule, be disabled on a case-by-case basis where actually necessary.
183 lines
5.8 KiB
JavaScript
183 lines
5.8 KiB
JavaScript
/* Copyright 2012 Mozilla Foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
// Table C-2
|
|
const QeTable = [
|
|
{ qe: 0x5601, nmps: 1, nlps: 1, switchFlag: 1 },
|
|
{ qe: 0x3401, nmps: 2, nlps: 6, switchFlag: 0 },
|
|
{ qe: 0x1801, nmps: 3, nlps: 9, switchFlag: 0 },
|
|
{ qe: 0x0ac1, nmps: 4, nlps: 12, switchFlag: 0 },
|
|
{ qe: 0x0521, nmps: 5, nlps: 29, switchFlag: 0 },
|
|
{ qe: 0x0221, nmps: 38, nlps: 33, switchFlag: 0 },
|
|
{ qe: 0x5601, nmps: 7, nlps: 6, switchFlag: 1 },
|
|
{ qe: 0x5401, nmps: 8, nlps: 14, switchFlag: 0 },
|
|
{ qe: 0x4801, nmps: 9, nlps: 14, switchFlag: 0 },
|
|
{ qe: 0x3801, nmps: 10, nlps: 14, switchFlag: 0 },
|
|
{ qe: 0x3001, nmps: 11, nlps: 17, switchFlag: 0 },
|
|
{ qe: 0x2401, nmps: 12, nlps: 18, switchFlag: 0 },
|
|
{ qe: 0x1c01, nmps: 13, nlps: 20, switchFlag: 0 },
|
|
{ qe: 0x1601, nmps: 29, nlps: 21, switchFlag: 0 },
|
|
{ qe: 0x5601, nmps: 15, nlps: 14, switchFlag: 1 },
|
|
{ qe: 0x5401, nmps: 16, nlps: 14, switchFlag: 0 },
|
|
{ qe: 0x5101, nmps: 17, nlps: 15, switchFlag: 0 },
|
|
{ qe: 0x4801, nmps: 18, nlps: 16, switchFlag: 0 },
|
|
{ qe: 0x3801, nmps: 19, nlps: 17, switchFlag: 0 },
|
|
{ qe: 0x3401, nmps: 20, nlps: 18, switchFlag: 0 },
|
|
{ qe: 0x3001, nmps: 21, nlps: 19, switchFlag: 0 },
|
|
{ qe: 0x2801, nmps: 22, nlps: 19, switchFlag: 0 },
|
|
{ qe: 0x2401, nmps: 23, nlps: 20, switchFlag: 0 },
|
|
{ qe: 0x2201, nmps: 24, nlps: 21, switchFlag: 0 },
|
|
{ qe: 0x1c01, nmps: 25, nlps: 22, switchFlag: 0 },
|
|
{ qe: 0x1801, nmps: 26, nlps: 23, switchFlag: 0 },
|
|
{ qe: 0x1601, nmps: 27, nlps: 24, switchFlag: 0 },
|
|
{ qe: 0x1401, nmps: 28, nlps: 25, switchFlag: 0 },
|
|
{ qe: 0x1201, nmps: 29, nlps: 26, switchFlag: 0 },
|
|
{ qe: 0x1101, nmps: 30, nlps: 27, switchFlag: 0 },
|
|
{ qe: 0x0ac1, nmps: 31, nlps: 28, switchFlag: 0 },
|
|
{ qe: 0x09c1, nmps: 32, nlps: 29, switchFlag: 0 },
|
|
{ qe: 0x08a1, nmps: 33, nlps: 30, switchFlag: 0 },
|
|
{ qe: 0x0521, nmps: 34, nlps: 31, switchFlag: 0 },
|
|
{ qe: 0x0441, nmps: 35, nlps: 32, switchFlag: 0 },
|
|
{ qe: 0x02a1, nmps: 36, nlps: 33, switchFlag: 0 },
|
|
{ qe: 0x0221, nmps: 37, nlps: 34, switchFlag: 0 },
|
|
{ qe: 0x0141, nmps: 38, nlps: 35, switchFlag: 0 },
|
|
{ qe: 0x0111, nmps: 39, nlps: 36, switchFlag: 0 },
|
|
{ qe: 0x0085, nmps: 40, nlps: 37, switchFlag: 0 },
|
|
{ qe: 0x0049, nmps: 41, nlps: 38, switchFlag: 0 },
|
|
{ qe: 0x0025, nmps: 42, nlps: 39, switchFlag: 0 },
|
|
{ qe: 0x0015, nmps: 43, nlps: 40, switchFlag: 0 },
|
|
{ qe: 0x0009, nmps: 44, nlps: 41, switchFlag: 0 },
|
|
{ qe: 0x0005, nmps: 45, nlps: 42, switchFlag: 0 },
|
|
{ qe: 0x0001, nmps: 45, nlps: 43, switchFlag: 0 },
|
|
{ qe: 0x5601, nmps: 46, nlps: 46, switchFlag: 0 },
|
|
];
|
|
|
|
/**
|
|
* This class implements the QM Coder decoding as defined in
|
|
* JPEG 2000 Part I Final Committee Draft Version 1.0
|
|
* Annex C.3 Arithmetic decoding procedure
|
|
* available at http://www.jpeg.org/public/fcd15444-1.pdf
|
|
*
|
|
* The arithmetic decoder is used in conjunction with context models to decode
|
|
* JPEG2000 and JBIG2 streams.
|
|
*/
|
|
class ArithmeticDecoder {
|
|
// C.3.5 Initialisation of the decoder (INITDEC)
|
|
constructor(data, start, end) {
|
|
this.data = data;
|
|
this.bp = start;
|
|
this.dataEnd = end;
|
|
|
|
this.chigh = data[start];
|
|
this.clow = 0;
|
|
|
|
this.byteIn();
|
|
|
|
this.chigh = ((this.chigh << 7) & 0xffff) | ((this.clow >> 9) & 0x7f);
|
|
this.clow = (this.clow << 7) & 0xffff;
|
|
this.ct -= 7;
|
|
this.a = 0x8000;
|
|
}
|
|
|
|
// C.3.4 Compressed data input (BYTEIN)
|
|
byteIn() {
|
|
const data = this.data;
|
|
let bp = this.bp;
|
|
|
|
if (data[bp] === 0xff) {
|
|
if (data[bp + 1] > 0x8f) {
|
|
this.clow += 0xff00;
|
|
this.ct = 8;
|
|
} else {
|
|
bp++;
|
|
this.clow += data[bp] << 9;
|
|
this.ct = 7;
|
|
this.bp = bp;
|
|
}
|
|
} else {
|
|
bp++;
|
|
this.clow += bp < this.dataEnd ? data[bp] << 8 : 0xff00;
|
|
this.ct = 8;
|
|
this.bp = bp;
|
|
}
|
|
if (this.clow > 0xffff) {
|
|
this.chigh += this.clow >> 16;
|
|
this.clow &= 0xffff;
|
|
}
|
|
}
|
|
|
|
// C.3.2 Decoding a decision (DECODE)
|
|
readBit(contexts, pos) {
|
|
// Contexts are packed into 1 byte:
|
|
// highest 7 bits carry cx.index, lowest bit carries cx.mps
|
|
let cx_index = contexts[pos] >> 1,
|
|
cx_mps = contexts[pos] & 1;
|
|
const qeTableIcx = QeTable[cx_index];
|
|
const qeIcx = qeTableIcx.qe;
|
|
let d;
|
|
let a = this.a - qeIcx;
|
|
|
|
if (this.chigh < qeIcx) {
|
|
// exchangeLps
|
|
if (a < qeIcx) {
|
|
a = qeIcx;
|
|
d = cx_mps;
|
|
cx_index = qeTableIcx.nmps;
|
|
} else {
|
|
a = qeIcx;
|
|
d = 1 ^ cx_mps;
|
|
if (qeTableIcx.switchFlag === 1) {
|
|
cx_mps = d;
|
|
}
|
|
cx_index = qeTableIcx.nlps;
|
|
}
|
|
} else {
|
|
this.chigh -= qeIcx;
|
|
if ((a & 0x8000) !== 0) {
|
|
this.a = a;
|
|
return cx_mps;
|
|
}
|
|
// exchangeMps
|
|
if (a < qeIcx) {
|
|
d = 1 ^ cx_mps;
|
|
if (qeTableIcx.switchFlag === 1) {
|
|
cx_mps = d;
|
|
}
|
|
cx_index = qeTableIcx.nlps;
|
|
} else {
|
|
d = cx_mps;
|
|
cx_index = qeTableIcx.nmps;
|
|
}
|
|
}
|
|
// C.3.3 renormD;
|
|
do {
|
|
if (this.ct === 0) {
|
|
this.byteIn();
|
|
}
|
|
|
|
a <<= 1;
|
|
this.chigh = ((this.chigh << 1) & 0xffff) | ((this.clow >> 15) & 1);
|
|
this.clow = (this.clow << 1) & 0xffff;
|
|
this.ct--;
|
|
} while ((a & 0x8000) === 0);
|
|
this.a = a;
|
|
|
|
contexts[pos] = (cx_index << 1) | cx_mps;
|
|
return d;
|
|
}
|
|
}
|
|
|
|
export { ArithmeticDecoder };
|