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:
parent
d59c9ab3ab
commit
0addf3a0d4
@ -24,35 +24,33 @@ class Jbig2Error extends BaseException {
|
||||
}
|
||||
}
|
||||
|
||||
const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
// Utility data structures
|
||||
function ContextCache() {}
|
||||
|
||||
ContextCache.prototype = {
|
||||
class ContextCache {
|
||||
getContexts(id) {
|
||||
if (id in this) {
|
||||
return this[id];
|
||||
}
|
||||
return (this[id] = new Int8Array(1 << 16));
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function DecodingContext(data, start, end) {
|
||||
class DecodingContext {
|
||||
constructor(data, start, end) {
|
||||
this.data = data;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
DecodingContext.prototype = {
|
||||
get decoder() {
|
||||
const decoder = new ArithmeticDecoder(this.data, this.start, this.end);
|
||||
return shadow(this, "decoder", decoder);
|
||||
},
|
||||
}
|
||||
|
||||
get contextCache() {
|
||||
const cache = new ContextCache();
|
||||
return shadow(this, "contextCache", cache);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Annex A. Arithmetic Integer Decoding Procedure
|
||||
// A.2 Procedure for decoding values
|
||||
@ -64,8 +62,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
let v = 0;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const bit = decoder.readBit(contexts, prev);
|
||||
prev =
|
||||
prev < 256 ? (prev << 1) | bit : (((prev << 1) | bit) & 511) | 256;
|
||||
prev = prev < 256 ? (prev << 1) | bit : (((prev << 1) | bit) & 511) | 256;
|
||||
v = (v << 1) | bit;
|
||||
}
|
||||
return v >>> 0;
|
||||
@ -555,12 +552,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
for (k = 0; k < referenceTemplateLength; k++) {
|
||||
i0 = i + referenceTemplateY[k] - offsetY;
|
||||
j0 = j + referenceTemplateX[k] - offsetX;
|
||||
if (
|
||||
i0 < 0 ||
|
||||
i0 >= referenceHeight ||
|
||||
j0 < 0 ||
|
||||
j0 >= referenceWidth
|
||||
) {
|
||||
if (i0 < 0 || i0 >= referenceHeight || j0 < 0 || j0 >= referenceWidth) {
|
||||
contextLabel <<= 1; // out of bound pixel
|
||||
} else {
|
||||
contextLabel = (contextLabel << 1) | referenceBitmap[i0][j0];
|
||||
@ -626,11 +618,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
let bitmap;
|
||||
if (refinement) {
|
||||
// 6.5.8.2 Refinement/aggregate-coded symbol bitmap
|
||||
const numberOfInstances = decodeInteger(
|
||||
contextCache,
|
||||
"IAAI",
|
||||
decoder
|
||||
);
|
||||
const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder);
|
||||
if (numberOfInstances > 1) {
|
||||
bitmap = decodeTextRegion(
|
||||
huffman,
|
||||
@ -654,11 +642,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
huffmanInput
|
||||
);
|
||||
} else {
|
||||
const symbolId = decodeIAID(
|
||||
contextCache,
|
||||
decoder,
|
||||
symbolCodeLength
|
||||
);
|
||||
const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);
|
||||
const rdx = decodeInteger(contextCache, "IARDX", decoder); // 6.4.11.3
|
||||
const rdy = decodeInteger(contextCache, "IARDY", decoder); // 6.4.11.4
|
||||
const symbol =
|
||||
@ -1021,9 +1005,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
if (combinationOperator !== 0) {
|
||||
throw new Jbig2Error(
|
||||
"operator " +
|
||||
combinationOperator +
|
||||
" is not supported in halftone region"
|
||||
`operator "${combinationOperator}" is not supported in halftone region`
|
||||
);
|
||||
}
|
||||
|
||||
@ -1564,10 +1546,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
return { imgData, width, height };
|
||||
}
|
||||
|
||||
function SimpleSegmentVisitor() {}
|
||||
|
||||
SimpleSegmentVisitor.prototype = {
|
||||
onPageInformation: function SimpleSegmentVisitor_onPageInformation(info) {
|
||||
class SimpleSegmentVisitor {
|
||||
onPageInformation(info) {
|
||||
this.currentPageInfo = info;
|
||||
const rowSize = (info.width + 7) >> 3;
|
||||
const buffer = new Uint8ClampedArray(rowSize * info.height);
|
||||
@ -1579,8 +1559,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
}
|
||||
this.buffer = buffer;
|
||||
},
|
||||
drawBitmap: function SimpleSegmentVisitor_drawBitmap(regionInfo, bitmap) {
|
||||
}
|
||||
|
||||
drawBitmap(regionInfo, bitmap) {
|
||||
const pageInfo = this.currentPageInfo;
|
||||
const width = regionInfo.width,
|
||||
height = regionInfo.height;
|
||||
@ -1632,13 +1613,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
`operator ${combinationOperator} is not supported`
|
||||
);
|
||||
}
|
||||
},
|
||||
onImmediateGenericRegion: function SimpleSegmentVisitor_onImmediateGenericRegion(
|
||||
region,
|
||||
data,
|
||||
start,
|
||||
end
|
||||
) {
|
||||
}
|
||||
|
||||
onImmediateGenericRegion(region, data, start, end) {
|
||||
const regionInfo = region.info;
|
||||
const decodingContext = new DecodingContext(data, start, end);
|
||||
const bitmap = decodeBitmap(
|
||||
@ -1652,11 +1629,13 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
decodingContext
|
||||
);
|
||||
this.drawBitmap(regionInfo, bitmap);
|
||||
},
|
||||
onImmediateLosslessGenericRegion: function SimpleSegmentVisitor_onImmediateLosslessGenericRegion() {
|
||||
}
|
||||
|
||||
onImmediateLosslessGenericRegion() {
|
||||
this.onImmediateGenericRegion.apply(this, arguments);
|
||||
},
|
||||
onSymbolDictionary: function SimpleSegmentVisitor_onSymbolDictionary(
|
||||
}
|
||||
|
||||
onSymbolDictionary(
|
||||
dictionary,
|
||||
currentSegment,
|
||||
referredSegments,
|
||||
@ -1705,14 +1684,9 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
decodingContext,
|
||||
huffmanInput
|
||||
);
|
||||
},
|
||||
onImmediateTextRegion: function SimpleSegmentVisitor_onImmediateTextRegion(
|
||||
region,
|
||||
referredSegments,
|
||||
data,
|
||||
start,
|
||||
end
|
||||
) {
|
||||
}
|
||||
|
||||
onImmediateTextRegion(region, referredSegments, data, start, end) {
|
||||
const regionInfo = region.info;
|
||||
let huffmanTables, huffmanInput;
|
||||
|
||||
@ -1762,10 +1736,12 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
huffmanInput
|
||||
);
|
||||
this.drawBitmap(regionInfo, bitmap);
|
||||
},
|
||||
onImmediateLosslessTextRegion: function SimpleSegmentVisitor_onImmediateLosslessTextRegion() {
|
||||
}
|
||||
|
||||
onImmediateLosslessTextRegion() {
|
||||
this.onImmediateTextRegion.apply(this, arguments);
|
||||
},
|
||||
}
|
||||
|
||||
onPatternDictionary(dictionary, currentSegment, data, start, end) {
|
||||
let patterns = this.patterns;
|
||||
if (!patterns) {
|
||||
@ -1780,7 +1756,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
dictionary.template,
|
||||
decodingContext
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
onImmediateHalftoneRegion(region, referredSegments, data, start, end) {
|
||||
// HalftoneRegion refers to exactly one PatternDictionary.
|
||||
const patterns = this.patterns[referredSegments[0]];
|
||||
@ -1804,20 +1781,23 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
decodingContext
|
||||
);
|
||||
this.drawBitmap(regionInfo, bitmap);
|
||||
},
|
||||
}
|
||||
|
||||
onImmediateLosslessHalftoneRegion() {
|
||||
this.onImmediateHalftoneRegion.apply(this, arguments);
|
||||
},
|
||||
}
|
||||
|
||||
onTables(currentSegment, data, start, end) {
|
||||
let customTables = this.customTables;
|
||||
if (!customTables) {
|
||||
this.customTables = customTables = {};
|
||||
}
|
||||
customTables[currentSegment] = decodeTablesSegment(data, start, end);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function HuffmanLine(lineData) {
|
||||
class HuffmanLine {
|
||||
constructor(lineData) {
|
||||
if (lineData.length === 2) {
|
||||
// OOB line.
|
||||
this.isOOB = true;
|
||||
@ -1837,8 +1817,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
this.isLowerRange = lineData[4] === "lower";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function HuffmanTreeNode(line) {
|
||||
class HuffmanTreeNode {
|
||||
constructor(line) {
|
||||
this.children = [];
|
||||
if (line) {
|
||||
// Leaf node
|
||||
@ -1853,7 +1835,6 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
HuffmanTreeNode.prototype = {
|
||||
buildTree(line, shift) {
|
||||
const bit = (line.prefixCode >> shift) & 1;
|
||||
if (shift <= 0) {
|
||||
@ -1867,7 +1848,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
node.buildTree(line, shift - 1);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
decodeNode(reader) {
|
||||
if (this.isLeaf) {
|
||||
if (this.isOOB) {
|
||||
@ -1881,10 +1863,11 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
throw new Jbig2Error("invalid Huffman data");
|
||||
}
|
||||
return node.decodeNode(reader);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function HuffmanTable(lines, prefixCodesDone) {
|
||||
class HuffmanTable {
|
||||
constructor(lines, prefixCodesDone) {
|
||||
if (!prefixCodesDone) {
|
||||
this.assignPrefixCodes(lines);
|
||||
}
|
||||
@ -1898,10 +1881,10 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
HuffmanTable.prototype = {
|
||||
decode(reader) {
|
||||
return this.rootNode.decodeNode(reader);
|
||||
},
|
||||
}
|
||||
|
||||
assignPrefixCodes(lines) {
|
||||
// Annex B.3 Assigning the prefix codes.
|
||||
const linesLength = lines.length;
|
||||
@ -1935,8 +1918,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
}
|
||||
currentLength++;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function decodeTablesSegment(data, start, end) {
|
||||
// Decodes a Tables segment, i.e., a custom Huffman table.
|
||||
@ -1965,9 +1948,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
|
||||
// Lower range table line
|
||||
prefixLength = reader.readBits(prefixSizeBits);
|
||||
lines.push(
|
||||
new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"])
|
||||
);
|
||||
lines.push(new HuffmanLine([lowestValue - 1, prefixLength, 32, 0, "lower"]));
|
||||
|
||||
// Upper range table line
|
||||
prefixLength = reader.readBits(prefixSizeBits);
|
||||
@ -2248,7 +2229,8 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
return table;
|
||||
}
|
||||
|
||||
function Reader(data, start, end) {
|
||||
class Reader {
|
||||
constructor(data, start, end) {
|
||||
this.data = data;
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
@ -2257,7 +2239,6 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
this.currentByte = 0;
|
||||
}
|
||||
|
||||
Reader.prototype = {
|
||||
readBit() {
|
||||
if (this.shift < 0) {
|
||||
if (this.position >= this.end) {
|
||||
@ -2269,7 +2250,7 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
const bit = (this.currentByte >> this.shift) & 1;
|
||||
this.shift--;
|
||||
return bit;
|
||||
},
|
||||
}
|
||||
|
||||
readBits(numBits) {
|
||||
let result = 0,
|
||||
@ -2278,19 +2259,19 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
result |= this.readBit() << i;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
}
|
||||
|
||||
byteAlign() {
|
||||
this.shift = -1;
|
||||
},
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.position >= this.end) {
|
||||
return -1;
|
||||
}
|
||||
return this.data[this.position++];
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getCustomHuffmanTable(index, referredTo, customTables) {
|
||||
// Returns a Tables segment that has been earlier decoded.
|
||||
@ -2571,23 +2552,17 @@ const Jbig2Image = (function Jbig2ImageClosure() {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
function Jbig2Image() {}
|
||||
|
||||
Jbig2Image.prototype = {
|
||||
class Jbig2Image {
|
||||
parseChunks(chunks) {
|
||||
return parseJbig2Chunks(chunks);
|
||||
},
|
||||
}
|
||||
|
||||
parse(data) {
|
||||
const { imgData, width, height } = parseJbig2(data);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
return imgData;
|
||||
},
|
||||
};
|
||||
|
||||
return Jbig2Image;
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
export { Jbig2Image };
|
||||
|
Loading…
x
Reference in New Issue
Block a user