Convert src/core/jbig2.js to use standard classes

*Please note:* Ignoring whitespace-only changes is probably necessary in order to review this.
This commit is contained in:
Jonas Jenwald 2021-05-05 12:27:53 +02:00
parent d59c9ab3ab
commit 0addf3a0d4

View File

@ -24,39 +24,37 @@ class Jbig2Error extends BaseException {
} }
} }
const Jbig2Image = (function Jbig2ImageClosure() { // Utility data structures
// Utility data structures class ContextCache {
function ContextCache() {}
ContextCache.prototype = {
getContexts(id) { getContexts(id) {
if (id in this) { if (id in this) {
return this[id]; return this[id];
} }
return (this[id] = new Int8Array(1 << 16)); return (this[id] = new Int8Array(1 << 16));
}, }
}; }
function DecodingContext(data, start, end) { class DecodingContext {
constructor(data, start, end) {
this.data = data; this.data = data;
this.start = start; this.start = start;
this.end = end; this.end = end;
} }
DecodingContext.prototype = {
get decoder() { get decoder() {
const decoder = new ArithmeticDecoder(this.data, this.start, this.end); const decoder = new ArithmeticDecoder(this.data, this.start, this.end);
return shadow(this, "decoder", decoder); return shadow(this, "decoder", decoder);
}, }
get contextCache() { get contextCache() {
const cache = new ContextCache(); const cache = new ContextCache();
return shadow(this, "contextCache", cache); return shadow(this, "contextCache", cache);
}, }
}; }
// Annex A. Arithmetic Integer Decoding Procedure // Annex A. Arithmetic Integer Decoding Procedure
// A.2 Procedure for decoding values // A.2 Procedure for decoding values
function decodeInteger(contextCache, procedure, decoder) { function decodeInteger(contextCache, procedure, decoder) {
const contexts = contextCache.getContexts(procedure); const contexts = contextCache.getContexts(procedure);
let prev = 1; let prev = 1;
@ -64,8 +62,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
let v = 0; let v = 0;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
const bit = decoder.readBit(contexts, prev); const bit = decoder.readBit(contexts, prev);
prev = prev = prev < 256 ? (prev << 1) | bit : (((prev << 1) | bit) & 511) | 256;
prev < 256 ? (prev << 1) | bit : (((prev << 1) | bit) & 511) | 256;
v = (v << 1) | bit; v = (v << 1) | bit;
} }
return v >>> 0; return v >>> 0;
@ -92,10 +89,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
return -value; return -value;
} }
return null; return null;
} }
// A.3 The IAID decoding procedure // A.3 The IAID decoding procedure
function decodeIAID(contextCache, decoder, codeLength) { function decodeIAID(contextCache, decoder, codeLength) {
const contexts = contextCache.getContexts("IAID"); const contexts = contextCache.getContexts("IAID");
let prev = 1; let prev = 1;
@ -107,10 +104,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
return prev & ((1 << codeLength) - 1); return prev & ((1 << codeLength) - 1);
} }
return prev & 0x7fffffff; return prev & 0x7fffffff;
} }
// 7.3 Segment types // 7.3 Segment types
const SegmentTypes = [ const SegmentTypes = [
"SymbolDictionary", "SymbolDictionary",
null, null,
null, null,
@ -174,9 +171,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
null, null,
null, null,
"Extension", "Extension",
]; ];
const CodingTemplates = [ const CodingTemplates = [
[ [
{ x: -1, y: -2 }, { x: -1, y: -2 },
{ x: 0, y: -2 }, { x: 0, y: -2 },
@ -227,9 +224,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
{ x: -2, y: 0 }, { x: -2, y: 0 },
{ x: -1, y: 0 }, { x: -1, y: 0 },
], ],
]; ];
const RefinementTemplates = [ const RefinementTemplates = [
{ {
coding: [ coding: [
{ x: 0, y: -1 }, { x: 0, y: -1 },
@ -263,22 +260,22 @@ const Jbig2Image = (function Jbig2ImageClosure() {
{ x: 1, y: 1 }, { x: 1, y: 1 },
], ],
}, },
]; ];
// See 6.2.5.7 Decoding the bitmap. // See 6.2.5.7 Decoding the bitmap.
const ReusedContexts = [ const ReusedContexts = [
0x9b25, // 10011 0110010 0101 0x9b25, // 10011 0110010 0101
0x0795, // 0011 110010 101 0x0795, // 0011 110010 101
0x00e5, // 001 11001 01 0x00e5, // 001 11001 01
0x0195, // 011001 0101 0x0195, // 011001 0101
]; ];
const RefinementReusedContexts = [ const RefinementReusedContexts = [
0x0020, // '000' + '0' (coding) + '00010000' + '0' (reference) 0x0020, // '000' + '0' (coding) + '00010000' + '0' (reference)
0x0008, // '0000' + '001000' 0x0008, // '0000' + '001000'
]; ];
function decodeBitmapTemplate0(width, height, decodingContext) { function decodeBitmapTemplate0(width, height, decodingContext) {
const decoder = decodingContext.decoder; const decoder = decodingContext.decoder;
const contexts = decodingContext.contextCache.getContexts("GB"); const contexts = decodingContext.contextCache.getContexts("GB");
const bitmap = []; const bitmap = [];
@ -319,10 +316,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
return bitmap; return bitmap;
} }
// 6.2 Generic Region Decoding Procedure // 6.2 Generic Region Decoding Procedure
function decodeBitmap( function decodeBitmap(
mmr, mmr,
width, width,
height, height,
@ -331,7 +328,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
skip, skip,
at, at,
decodingContext decodingContext
) { ) {
if (mmr) { if (mmr) {
const input = new Reader( const input = new Reader(
decodingContext.data, decodingContext.data,
@ -482,10 +479,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
return bitmap; return bitmap;
} }
// 6.3.2 Generic Refinement Region Decoding Procedure // 6.3.2 Generic Refinement Region Decoding Procedure
function decodeRefinement( function decodeRefinement(
width, width,
height, height,
templateIndex, templateIndex,
@ -495,7 +492,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
prediction, prediction,
at, at,
decodingContext decodingContext
) { ) {
let codingTemplate = RefinementTemplates[templateIndex].coding; let codingTemplate = RefinementTemplates[templateIndex].coding;
if (templateIndex === 0) { if (templateIndex === 0) {
codingTemplate = codingTemplate.concat([at[0]]); codingTemplate = codingTemplate.concat([at[0]]);
@ -555,12 +552,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
for (k = 0; k < referenceTemplateLength; k++) { for (k = 0; k < referenceTemplateLength; k++) {
i0 = i + referenceTemplateY[k] - offsetY; i0 = i + referenceTemplateY[k] - offsetY;
j0 = j + referenceTemplateX[k] - offsetX; j0 = j + referenceTemplateX[k] - offsetX;
if ( if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {
i0 < 0 ||
i0 >= referenceHeight ||
j0 < 0 ||
j0 >= referenceWidth
) {
contextLabel <<= 1; // out of bound pixel contextLabel <<= 1; // out of bound pixel
} else { } else {
contextLabel = (contextLabel << 1) | referenceBitmap[i0][j0]; contextLabel = (contextLabel << 1) | referenceBitmap[i0][j0];
@ -572,10 +564,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
return bitmap; return bitmap;
} }
// 6.5.5 Decoding the symbol dictionary // 6.5.5 Decoding the symbol dictionary
function decodeSymbolDictionary( function decodeSymbolDictionary(
huffman, huffman,
refinement, refinement,
symbols, symbols,
@ -588,7 +580,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
refinementAt, refinementAt,
decodingContext, decodingContext,
huffmanInput huffmanInput
) { ) {
if (huffman && refinement) { if (huffman && refinement) {
throw new Jbig2Error("symbol refinement with Huffman is not supported"); throw new Jbig2Error("symbol refinement with Huffman is not supported");
} }
@ -626,11 +618,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
let bitmap; let bitmap;
if (refinement) { if (refinement) {
// 6.5.8.2 Refinement/aggregate-coded symbol bitmap // 6.5.8.2 Refinement/aggregate-coded symbol bitmap
const numberOfInstances = decodeInteger( const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder);
contextCache,
"IAAI",
decoder
);
if (numberOfInstances > 1) { if (numberOfInstances > 1) {
bitmap = decodeTextRegion( bitmap = decodeTextRegion(
huffman, huffman,
@ -654,11 +642,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
huffmanInput huffmanInput
); );
} else { } else {
const symbolId = decodeIAID( const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);
contextCache,
decoder,
symbolCodeLength
);
const rdx = decodeInteger(contextCache, "IARDX", decoder); // 6.4.11.3 const rdx = decodeInteger(contextCache, "IARDX", decoder); // 6.4.11.3
const rdy = decodeInteger(contextCache, "IARDY", decoder); // 6.4.11.4 const rdy = decodeInteger(contextCache, "IARDY", decoder); // 6.4.11.4
const symbol = const symbol =
@ -776,9 +760,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
return exportedSymbols; return exportedSymbols;
} }
function decodeTextRegion( function decodeTextRegion(
huffman, huffman,
refinement, refinement,
width, width,
@ -798,7 +782,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
decodingContext, decodingContext,
logStripSize, logStripSize,
huffmanInput huffmanInput
) { ) {
if (huffman && refinement) { if (huffman && refinement) {
throw new Jbig2Error("refinement with Huffman is not supported"); throw new Jbig2Error("refinement with Huffman is not supported");
} }
@ -942,16 +926,16 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} while (true); } while (true);
} }
return bitmap; return bitmap;
} }
function decodePatternDictionary( function decodePatternDictionary(
mmr, mmr,
patternWidth, patternWidth,
patternHeight, patternHeight,
maxPatternIndex, maxPatternIndex,
template, template,
decodingContext decodingContext
) { ) {
const at = []; const at = [];
if (!mmr) { if (!mmr) {
at.push({ at.push({
@ -996,9 +980,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
patterns.push(patternBitmap); patterns.push(patternBitmap);
} }
return patterns; return patterns;
} }
function decodeHalftoneRegion( function decodeHalftoneRegion(
mmr, mmr,
patterns, patterns,
template, template,
@ -1014,16 +998,14 @@ const Jbig2Image = (function Jbig2ImageClosure() {
gridVectorX, gridVectorX,
gridVectorY, gridVectorY,
decodingContext decodingContext
) { ) {
const skip = null; const skip = null;
if (enableSkip) { if (enableSkip) {
throw new Jbig2Error("skip is not supported"); throw new Jbig2Error("skip is not supported");
} }
if (combinationOperator !== 0) { if (combinationOperator !== 0) {
throw new Jbig2Error( throw new Jbig2Error(
"operator " + `operator "${combinationOperator}" is not supported in halftone region`
combinationOperator +
" is not supported in halftone region"
); );
} }
@ -1142,9 +1124,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
return regionBitmap; return regionBitmap;
} }
function readSegmentHeader(data, start) { function readSegmentHeader(data, start) {
const segmentHeader = {}; const segmentHeader = {};
segmentHeader.number = readUint32(data, start); segmentHeader.number = readUint32(data, start);
const flags = data[start + 4]; const flags = data[start + 4];
@ -1243,9 +1225,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
segmentHeader.headerEnd = position; segmentHeader.headerEnd = position;
return segmentHeader; return segmentHeader;
} }
function readSegments(header, data, start, end) { function readSegments(header, data, start, end) {
const segments = []; const segments = [];
let position = start; let position = start;
while (position < end) { while (position < end) {
@ -1273,10 +1255,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
return segments; return segments;
} }
// 7.4.1 Region segment information field // 7.4.1 Region segment information field
function readRegionSegmentInformation(data, start) { function readRegionSegmentInformation(data, start) {
return { return {
width: readUint32(data, start), width: readUint32(data, start),
height: readUint32(data, start + 4), height: readUint32(data, start + 4),
@ -1284,10 +1266,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
y: readUint32(data, start + 12), y: readUint32(data, start + 12),
combinationOperator: data[start + 16] & 7, combinationOperator: data[start + 16] & 7,
}; };
} }
const RegionSegmentInformationFieldLength = 17; const RegionSegmentInformationFieldLength = 17;
function processSegment(segment, visitor) { function processSegment(segment, visitor) {
const header = segment.header; const header = segment.header;
const data = segment.data, const data = segment.data,
@ -1495,15 +1477,15 @@ const Jbig2Image = (function Jbig2ImageClosure() {
if (callbackName in visitor) { if (callbackName in visitor) {
visitor[callbackName].apply(visitor, args); visitor[callbackName].apply(visitor, args);
} }
} }
function processSegments(segments, visitor) { function processSegments(segments, visitor) {
for (let i = 0, ii = segments.length; i < ii; i++) { for (let i = 0, ii = segments.length; i < ii; i++) {
processSegment(segments[i], visitor); processSegment(segments[i], visitor);
} }
} }
function parseJbig2Chunks(chunks) { function parseJbig2Chunks(chunks) {
const visitor = new SimpleSegmentVisitor(); const visitor = new SimpleSegmentVisitor();
for (let i = 0, ii = chunks.length; i < ii; i++) { for (let i = 0, ii = chunks.length; i < ii; i++) {
const chunk = chunks[i]; const chunk = chunks[i];
@ -1511,9 +1493,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
processSegments(segments, visitor); processSegments(segments, visitor);
} }
return visitor.buffer; return visitor.buffer;
} }
function parseJbig2(data) { function parseJbig2(data) {
const end = data.length; const end = data.length;
let position = 0; let position = 0;
@ -1562,12 +1544,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
return { imgData, width, height }; return { imgData, width, height };
} }
function SimpleSegmentVisitor() {} class SimpleSegmentVisitor {
onPageInformation(info) {
SimpleSegmentVisitor.prototype = {
onPageInformation: function SimpleSegmentVisitor_onPageInformation(info) {
this.currentPageInfo = info; this.currentPageInfo = info;
const rowSize = (info.width + 7) >> 3; const rowSize = (info.width + 7) >> 3;
const buffer = new Uint8ClampedArray(rowSize * info.height); const buffer = new Uint8ClampedArray(rowSize * info.height);
@ -1579,8 +1559,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
this.buffer = buffer; this.buffer = buffer;
}, }
drawBitmap: function SimpleSegmentVisitor_drawBitmap(regionInfo, bitmap) {
drawBitmap(regionInfo, bitmap) {
const pageInfo = this.currentPageInfo; const pageInfo = this.currentPageInfo;
const width = regionInfo.width, const width = regionInfo.width,
height = regionInfo.height; height = regionInfo.height;
@ -1632,13 +1613,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
`operator ${combinationOperator} is not supported` `operator ${combinationOperator} is not supported`
); );
} }
}, }
onImmediateGenericRegion: function SimpleSegmentVisitor_onImmediateGenericRegion(
region, onImmediateGenericRegion(region, data, start, end) {
data,
start,
end
) {
const regionInfo = region.info; const regionInfo = region.info;
const decodingContext = new DecodingContext(data, start, end); const decodingContext = new DecodingContext(data, start, end);
const bitmap = decodeBitmap( const bitmap = decodeBitmap(
@ -1652,11 +1629,13 @@ const Jbig2Image = (function Jbig2ImageClosure() {
decodingContext decodingContext
); );
this.drawBitmap(regionInfo, bitmap); this.drawBitmap(regionInfo, bitmap);
}, }
onImmediateLosslessGenericRegion: function SimpleSegmentVisitor_onImmediateLosslessGenericRegion() {
onImmediateLosslessGenericRegion() {
this.onImmediateGenericRegion.apply(this, arguments); this.onImmediateGenericRegion.apply(this, arguments);
}, }
onSymbolDictionary: function SimpleSegmentVisitor_onSymbolDictionary(
onSymbolDictionary(
dictionary, dictionary,
currentSegment, currentSegment,
referredSegments, referredSegments,
@ -1705,14 +1684,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
decodingContext, decodingContext,
huffmanInput huffmanInput
); );
}, }
onImmediateTextRegion: function SimpleSegmentVisitor_onImmediateTextRegion(
region, onImmediateTextRegion(region, referredSegments, data, start, end) {
referredSegments,
data,
start,
end
) {
const regionInfo = region.info; const regionInfo = region.info;
let huffmanTables, huffmanInput; let huffmanTables, huffmanInput;
@ -1762,10 +1736,12 @@ const Jbig2Image = (function Jbig2ImageClosure() {
huffmanInput huffmanInput
); );
this.drawBitmap(regionInfo, bitmap); this.drawBitmap(regionInfo, bitmap);
}, }
onImmediateLosslessTextRegion: function SimpleSegmentVisitor_onImmediateLosslessTextRegion() {
onImmediateLosslessTextRegion() {
this.onImmediateTextRegion.apply(this, arguments); this.onImmediateTextRegion.apply(this, arguments);
}, }
onPatternDictionary(dictionary, currentSegment, data, start, end) { onPatternDictionary(dictionary, currentSegment, data, start, end) {
let patterns = this.patterns; let patterns = this.patterns;
if (!patterns) { if (!patterns) {
@ -1780,7 +1756,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
dictionary.template, dictionary.template,
decodingContext decodingContext
); );
}, }
onImmediateHalftoneRegion(region, referredSegments, data, start, end) { onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
// HalftoneRegion refers to exactly one PatternDictionary. // HalftoneRegion refers to exactly one PatternDictionary.
const patterns = this.patterns[referredSegments[0]]; const patterns = this.patterns[referredSegments[0]];
@ -1804,20 +1781,23 @@ const Jbig2Image = (function Jbig2ImageClosure() {
decodingContext decodingContext
); );
this.drawBitmap(regionInfo, bitmap); this.drawBitmap(regionInfo, bitmap);
}, }
onImmediateLosslessHalftoneRegion() { onImmediateLosslessHalftoneRegion() {
this.onImmediateHalftoneRegion.apply(this, arguments); this.onImmediateHalftoneRegion.apply(this, arguments);
}, }
onTables(currentSegment, data, start, end) { onTables(currentSegment, data, start, end) {
let customTables = this.customTables; let customTables = this.customTables;
if (!customTables) { if (!customTables) {
this.customTables = customTables = {}; this.customTables = customTables = {};
} }
customTables[currentSegment] = decodeTablesSegment(data, start, end); customTables[currentSegment] = decodeTablesSegment(data, start, end);
}, }
}; }
function HuffmanLine(lineData) { class HuffmanLine {
constructor(lineData) {
if (lineData.length === 2) { if (lineData.length === 2) {
// OOB line. // OOB line.
this.isOOB = true; this.isOOB = true;
@ -1837,8 +1817,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
this.isLowerRange = lineData[4] === "lower"; this.isLowerRange = lineData[4] === "lower";
} }
} }
}
function HuffmanTreeNode(line) { class HuffmanTreeNode {
constructor(line) {
this.children = []; this.children = [];
if (line) { if (line) {
// Leaf node // Leaf node
@ -1853,7 +1835,6 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
HuffmanTreeNode.prototype = {
buildTree(line, shift) { buildTree(line, shift) {
const bit = (line.prefixCode >> shift) & 1; const bit = (line.prefixCode >> shift) & 1;
if (shift <= 0) { if (shift <= 0) {
@ -1867,7 +1848,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
node.buildTree(line, shift - 1); node.buildTree(line, shift - 1);
} }
}, }
decodeNode(reader) { decodeNode(reader) {
if (this.isLeaf) { if (this.isLeaf) {
if (this.isOOB) { if (this.isOOB) {
@ -1881,10 +1863,11 @@ const Jbig2Image = (function Jbig2ImageClosure() {
throw new Jbig2Error("invalid Huffman data"); throw new Jbig2Error("invalid Huffman data");
} }
return node.decodeNode(reader); return node.decodeNode(reader);
}, }
}; }
function HuffmanTable(lines, prefixCodesDone) { class HuffmanTable {
constructor(lines, prefixCodesDone) {
if (!prefixCodesDone) { if (!prefixCodesDone) {
this.assignPrefixCodes(lines); this.assignPrefixCodes(lines);
} }
@ -1898,10 +1881,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
HuffmanTable.prototype = {
decode(reader) { decode(reader) {
return this.rootNode.decodeNode(reader); return this.rootNode.decodeNode(reader);
}, }
assignPrefixCodes(lines) { assignPrefixCodes(lines) {
// Annex B.3 Assigning the prefix codes. // Annex B.3 Assigning the prefix codes.
const linesLength = lines.length; const linesLength = lines.length;
@ -1935,10 +1918,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
currentLength++; currentLength++;
} }
}, }
}; }
function decodeTablesSegment(data, start, end) { function decodeTablesSegment(data, start, end) {
// Decodes a Tables segment, i.e., a custom Huffman table. // Decodes a Tables segment, i.e., a custom Huffman table.
// Annex B.2 Code table structure. // Annex B.2 Code table structure.
const flags = data[start]; const flags = data[start];
@ -1965,9 +1948,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
// Lower range table line // Lower range table line
prefixLength = reader.readBits(prefixSizeBits); prefixLength = reader.readBits(prefixSizeBits);
lines.push( lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"]));
new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"])
);
// Upper range table line // Upper range table line
prefixLength = reader.readBits(prefixSizeBits); prefixLength = reader.readBits(prefixSizeBits);
@ -1980,11 +1961,11 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
return new HuffmanTable(lines, false); return new HuffmanTable(lines, false);
} }
const standardTablesCache = {}; const standardTablesCache = {};
function getStandardTable(number) { function getStandardTable(number) {
// Annex B.5 Standard Huffman tables. // Annex B.5 Standard Huffman tables.
let table = standardTablesCache[number]; let table = standardTablesCache[number];
if (table) { if (table) {
@ -2246,9 +2227,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
table = new HuffmanTable(lines, true); table = new HuffmanTable(lines, true);
standardTablesCache[number] = table; standardTablesCache[number] = table;
return table; return table;
} }
function Reader(data, start, end) { class Reader {
constructor(data, start, end) {
this.data = data; this.data = data;
this.start = start; this.start = start;
this.end = end; this.end = end;
@ -2257,7 +2239,6 @@ const Jbig2Image = (function Jbig2ImageClosure() {
this.currentByte = 0; this.currentByte = 0;
} }
Reader.prototype = {
readBit() { readBit() {
if (this.shift < 0) { if (this.shift < 0) {
if (this.position >= this.end) { if (this.position >= this.end) {
@ -2269,7 +2250,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
const bit = (this.currentByte >> this.shift) & 1; const bit = (this.currentByte >> this.shift) & 1;
this.shift--; this.shift--;
return bit; return bit;
}, }
readBits(numBits) { readBits(numBits) {
let result = 0, let result = 0,
@ -2278,21 +2259,21 @@ const Jbig2Image = (function Jbig2ImageClosure() {
result |= this.readBit() << i; result |= this.readBit() << i;
} }
return result; return result;
}, }
byteAlign() { byteAlign() {
this.shift = -1; this.shift = -1;
}, }
next() { next() {
if (this.position >= this.end) { if (this.position >= this.end) {
return -1; return -1;
} }
return this.data[this.position++]; return this.data[this.position++];
}, }
}; }
function getCustomHuffmanTable(index, referredTo, customTables) { function getCustomHuffmanTable(index, referredTo, customTables) {
// Returns a Tables segment that has been earlier decoded. // Returns a Tables segment that has been earlier decoded.
// See 7.4.2.1.6 (symbol dictionary) or 7.4.3.1.6 (text region). // See 7.4.2.1.6 (symbol dictionary) or 7.4.3.1.6 (text region).
let currentIndex = 0; let currentIndex = 0;
@ -2306,15 +2287,15 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
} }
throw new Jbig2Error("can't find custom Huffman table"); throw new Jbig2Error("can't find custom Huffman table");
} }
function getTextRegionHuffmanTables( function getTextRegionHuffmanTables(
textRegion, textRegion,
referredTo, referredTo,
customTables, customTables,
numberOfSymbols, numberOfSymbols,
reader reader
) { ) {
// 7.4.3.1.7 Symbol ID Huffman table decoding // 7.4.3.1.7 Symbol ID Huffman table decoding
// Read code lengths for RUNCODEs 0...34. // Read code lengths for RUNCODEs 0...34.
@ -2435,13 +2416,13 @@ const Jbig2Image = (function Jbig2ImageClosure() {
tableDeltaS, tableDeltaS,
tableDeltaT, tableDeltaT,
}; };
} }
function getSymbolDictionaryHuffmanTables( function getSymbolDictionaryHuffmanTables(
dictionary, dictionary,
referredTo, referredTo,
customTables customTables
) { ) {
// 7.4.2.1.6 Symbol dictionary segment Huffman table selection // 7.4.2.1.6 Symbol dictionary segment Huffman table selection
let customIndex = 0, let customIndex = 0,
@ -2509,9 +2490,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
tableBitmapSize, tableBitmapSize,
tableAggregateInstances, tableAggregateInstances,
}; };
} }
function readUncompressedBitmap(reader, width, height) { function readUncompressedBitmap(reader, width, height) {
const bitmap = []; const bitmap = [];
for (let y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
const row = new Uint8Array(width); const row = new Uint8Array(width);
@ -2522,9 +2503,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
reader.byteAlign(); reader.byteAlign();
} }
return bitmap; return bitmap;
} }
function decodeMMRBitmap(input, width, height, endOfBlock) { function decodeMMRBitmap(input, width, height, endOfBlock) {
// MMR is the same compression algorithm as the PDF filter // MMR is the same compression algorithm as the PDF filter
// CCITTFaxDecode with /K -1. // CCITTFaxDecode with /K -1.
const params = { const params = {
@ -2569,25 +2550,19 @@ const Jbig2Image = (function Jbig2ImageClosure() {
} }
return bitmap; return bitmap;
} }
// eslint-disable-next-line no-shadow class Jbig2Image {
function Jbig2Image() {}
Jbig2Image.prototype = {
parseChunks(chunks) { parseChunks(chunks) {
return parseJbig2Chunks(chunks); return parseJbig2Chunks(chunks);
}, }
parse(data) { parse(data) {
const { imgData, width, height } = parseJbig2(data); const { imgData, width, height } = parseJbig2(data);
this.width = width; this.width = width;
this.height = height; this.height = height;
return imgData; return imgData;
}, }
}; }
return Jbig2Image;
})();
export { Jbig2Image }; export { Jbig2Image };