: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
for (k = 0; k < changingEntriesLength; k++) {
i0 = i + changingTemplateY[k];
j0 = j + changingTemplateX[k];
bit = changingTemplateBit[k];
shift = templateLength - 1;
for (k = 0; k < templateLength; k++, shift--) {
if (j0 >= 0 && j0 < width) {
contextLabel |= bit << shift;
const pixel = decoder.readBit(contexts, contextLabel);
function decodeRefinement(width, height, templateIndex, referenceBitmap, offsetX, offsetY, prediction, at, decodingContext) {
let codingTemplate = RefinementTemplates[templateIndex].coding;
if (templateIndex === 0) {
codingTemplate = codingTemplate.concat([at[0]]);
const codingTemplateLength = codingTemplate.length;
const codingTemplateX = new Int32Array(codingTemplateLength);
const codingTemplateY = new Int32Array(codingTemplateLength);
for (k = 0; k < codingTemplateLength; k++) {
codingTemplateX[k] = codingTemplate[k].x;
codingTemplateY[k] = codingTemplate[k].y;
let referenceTemplate = RefinementTemplates[templateIndex].reference;
if (templateIndex === 0) {
referenceTemplate = referenceTemplate.concat([at[1]]);
const referenceTemplateLength = referenceTemplate.length;
const referenceTemplateX = new Int32Array(referenceTemplateLength);
const referenceTemplateY = new Int32Array(referenceTemplateLength);
for (k = 0; k < referenceTemplateLength; k++) {
referenceTemplateX[k] = referenceTemplate[k].x;
referenceTemplateY[k] = referenceTemplate[k].y;
const referenceWidth = referenceBitmap[0].length;
const referenceHeight = referenceBitmap.length;
const pseudoPixelContext = RefinementReusedContexts[templateIndex];
const decoder = decodingContext.decoder;
const contexts = decodingContext.contextCache.getContexts("GR");
for (let i = 0; i < height; i++) {
const sltp = decoder.readBit(contexts, pseudoPixelContext);
throw new Jbig2Error("prediction is not supported");
const row = new Uint8Array(width);
for (let j = 0; j < width; j++) {
for (k = 0; k < codingTemplateLength; k++) {
i0 = i + codingTemplateY[k];
j0 = j + codingTemplateX[k];
if (i0 < 0 || j0 < 0 || j0 >= width) {
contextLabel = contextLabel << 1 | bitmap[i0][j0];
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) {
contextLabel = contextLabel << 1 | referenceBitmap[i0][j0];
const pixel = decoder.readBit(contexts, contextLabel);
function decodeSymbolDictionary(huffman, refinement, symbols, numberOfNewSymbols, numberOfExportedSymbols, huffmanTables, templateIndex, at, refinementTemplateIndex, refinementAt, decodingContext, huffmanInput) {
if (huffman && refinement) {
throw new Jbig2Error("symbol refinement with Huffman is not supported");
let symbolCodeLength = log2(symbols.length + numberOfNewSymbols);
const decoder = decodingContext.decoder;
const contextCache = decodingContext.contextCache;
let tableB1, symbolWidths;
tableB1 = getStandardTable(1);
symbolCodeLength = Math.max(symbolCodeLength, 1);
while (newSymbols.length < numberOfNewSymbols) {
const deltaHeight = huffman ? huffmanTables.tableDeltaHeight.decode(huffmanInput) : decodeInteger(contextCache, "IADH", decoder);
currentHeight += deltaHeight;
const firstSymbol = huffman ? symbolWidths.length : 0;
const deltaWidth = huffman ? huffmanTables.tableDeltaWidth.decode(huffmanInput) : decodeInteger(contextCache, "IADW", decoder);
if (deltaWidth === null) {
currentWidth += deltaWidth;
totalWidth += currentWidth;
const numberOfInstances = decodeInteger(contextCache, "IAAI", decoder);
if (numberOfInstances > 1) {
bitmap = decodeTextRegion(huffman, refinement, currentWidth, currentHeight, 0, numberOfInstances, 1, symbols.concat(newSymbols), symbolCodeLength, 0, 0, 1, 0, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, 0, huffmanInput);
const symbolId = decodeIAID(contextCache, decoder, symbolCodeLength);
const rdx = decodeInteger(contextCache, "IARDX", decoder);
const rdy = decodeInteger(contextCache, "IARDY", decoder);
const symbol = symbolId < symbols.length ? symbols[symbolId] : newSymbols[symbolId - symbols.length];
bitmap = decodeRefinement(currentWidth, currentHeight, refinementTemplateIndex, symbol, rdx, rdy, false, refinementAt, decodingContext);
symbolWidths.push(currentWidth);
bitmap = decodeBitmap(false, currentWidth, currentHeight, templateIndex, false, null, at, decodingContext);
if (huffman && !refinement) {
const bitmapSize = huffmanTables.tableBitmapSize.decode(huffmanInput);
huffmanInput.byteAlign();
collectiveBitmap = readUncompressedBitmap(huffmanInput, totalWidth, currentHeight);
const originalEnd = huffmanInput.end;
const bitmapEnd = huffmanInput.position + bitmapSize;
huffmanInput.end = bitmapEnd;
collectiveBitmap = decodeMMRBitmap(huffmanInput, totalWidth, currentHeight, false);
huffmanInput.end = originalEnd;
huffmanInput.position = bitmapEnd;
const numberOfSymbolsDecoded = symbolWidths.length;
if (firstSymbol === numberOfSymbolsDecoded - 1) {
newSymbols.push(collectiveBitmap);
for (i = firstSymbol; i < numberOfSymbolsDecoded; i++) {
bitmapWidth = symbolWidths[i];
xMax = xMin + bitmapWidth;
for (y = 0; y < currentHeight; y++) {
symbolBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
newSymbols.push(symbolBitmap);
const exportedSymbols = [],
const totalSymbolsLength = symbols.length + numberOfNewSymbols;
while (flags.length < totalSymbolsLength) {
let runLength = huffman ? tableB1.decode(huffmanInput) : decodeInteger(contextCache, "IAEX", decoder);
currentFlag = !currentFlag;
for (i = 0, ii = symbols.length; i < ii; i++) {
exportedSymbols.push(symbols[i]);
for (let j = 0; j < numberOfNewSymbols; i++, j++) {
exportedSymbols.push(newSymbols[j]);
function decodeTextRegion(huffman, refinement, width, height, defaultPixelValue, numberOfSymbolInstances, stripSize, inputSymbols, symbolCodeLength, transposed, dsOffset, referenceCorner, combinationOperator, huffmanTables, refinementTemplateIndex, refinementAt, decodingContext, logStripSize, huffmanInput) {
if (huffman && refinement) {
throw new Jbig2Error("refinement with Huffman is not supported");
for (i = 0; i < height; i++) {
row = new Uint8Array(width);
for (let j = 0; j < width; j++) {
row[j] = defaultPixelValue;
const decoder = decodingContext.decoder;
const contextCache = decodingContext.contextCache;
let stripT = huffman ? -huffmanTables.tableDeltaT.decode(huffmanInput) : -decodeInteger(contextCache, "IADT", decoder);
while (i < numberOfSymbolInstances) {
const deltaT = huffman ? huffmanTables.tableDeltaT.decode(huffmanInput) : decodeInteger(contextCache, "IADT", decoder);
const deltaFirstS = huffman ? huffmanTables.tableFirstS.decode(huffmanInput) : decodeInteger(contextCache, "IAFS", decoder);
currentT = huffman ? huffmanInput.readBits(logStripSize) : decodeInteger(contextCache, "IAIT", decoder);
const t = stripSize * stripT + currentT;
const symbolId = huffman ? huffmanTables.symbolIDTable.decode(huffmanInput) : decodeIAID(contextCache, decoder, symbolCodeLength);
const applyRefinement = refinement && (huffman ? huffmanInput.readBit() : decodeInteger(contextCache, "IARI", decoder));
let symbolBitmap = inputSymbols[symbolId];
let symbolWidth = symbolBitmap[0].length;
let symbolHeight = symbolBitmap.length;
const rdw = decodeInteger(contextCache, "IARDW", decoder);
const rdh = decodeInteger(contextCache, "IARDH", decoder);
const rdx = decodeInteger(contextCache, "IARDX", decoder);
const rdy = decodeInteger(contextCache, "IARDY", decoder);
symbolBitmap = decodeRefinement(symbolWidth, symbolHeight, refinementTemplateIndex, symbolBitmap, (rdw >> 1) + rdx, (rdh >> 1) + rdy, false, refinementAt, decodingContext);
if (referenceCorner > 1) {
currentS += symbolWidth - 1;
increment = symbolWidth - 1;
} else if (!(referenceCorner & 1)) {
currentS += symbolHeight - 1;
increment = symbolHeight - 1;
const offsetT = t - (referenceCorner & 1 ? 0 : symbolHeight - 1);
const offsetS = currentS - (referenceCorner & 2 ? symbolWidth - 1 : 0);
for (s2 = 0; s2 < symbolHeight; s2++) {
row = bitmap[offsetS + s2];
symbolRow = symbolBitmap[s2];
const maxWidth = Math.min(width - offsetT, symbolWidth);
switch (combinationOperator) {
for (t2 = 0; t2 < maxWidth; t2++) {
row[offsetT + t2] |= symbolRow[t2];
for (t2 = 0; t2 < maxWidth; t2++) {
row[offsetT + t2] ^= symbolRow[t2];
throw new Jbig2Error(`operator ${combinationOperator} is not supported`);
for (t2 = 0; t2 < symbolHeight; t2++) {
row = bitmap[offsetT + t2];
symbolRow = symbolBitmap[t2];
switch (combinationOperator) {
for (s2 = 0; s2 < symbolWidth; s2++) {
row[offsetS + s2] |= symbolRow[s2];
for (s2 = 0; s2 < symbolWidth; s2++) {
row[offsetS + s2] ^= symbolRow[s2];
throw new Jbig2Error(`operator ${combinationOperator} is not supported`);
const deltaS = huffman ? huffmanTables.tableDeltaS.decode(huffmanInput) : decodeInteger(contextCache, "IADS", decoder);
currentS += increment + deltaS + dsOffset;
function decodePatternDictionary(mmr, patternWidth, patternHeight, maxPatternIndex, template, decodingContext) {
const collectiveWidth = (maxPatternIndex + 1) * patternWidth;
const collectiveBitmap = decodeBitmap(mmr, collectiveWidth, patternHeight, template, false, null, at, decodingContext);
for (let i = 0; i <= maxPatternIndex; i++) {
const patternBitmap = [];
const xMin = patternWidth * i;
const xMax = xMin + patternWidth;
for (let y = 0; y < patternHeight; y++) {
patternBitmap.push(collectiveBitmap[y].subarray(xMin, xMax));
patterns.push(patternBitmap);
function decodeHalftoneRegion(mmr, patterns, template, regionWidth, regionHeight, defaultPixelValue, enableSkip, combinationOperator, gridWidth, gridHeight, gridOffsetX, gridOffsetY, gridVectorX, gridVectorY, decodingContext) {
throw new Jbig2Error("skip is not supported");
if (combinationOperator !== 0) {
throw new Jbig2Error(`operator "${combinationOperator}" is not supported in halftone region`);
for (i = 0; i < regionHeight; i++) {
row = new Uint8Array(regionWidth);
for (j = 0; j < regionWidth; j++) {
row[j] = defaultPixelValue;
const numberOfPatterns = patterns.length;
const pattern0 = patterns[0];
const patternWidth = pattern0[0].length,
patternHeight = pattern0.length;
const bitsPerValue = log2(numberOfPatterns);
x: template <= 1 ? 3 : 2,
const grayScaleBitPlanes = [];
mmrInput = new Reader(decodingContext.data, decodingContext.start, decodingContext.end);
for (i = bitsPerValue - 1; i >= 0; i--) {
bitmap = decodeMMRBitmap(mmrInput, gridWidth, gridHeight, true);
bitmap = decodeBitmap(false, gridWidth, gridHeight, template, false, skip, at, decodingContext);
grayScaleBitPlanes[i] = bitmap;
let mg, ng, bit, patternIndex, patternBitmap, x, y, patternRow, regionRow;
for (mg = 0; mg < gridHeight; mg++) {
for (ng = 0; ng < gridWidth; ng++) {
for (j = bitsPerValue - 1; j >= 0; j--) {
bit ^= grayScaleBitPlanes[j][mg][ng];
patternIndex |= bit << j;
patternBitmap = patterns[patternIndex];
x = gridOffsetX + mg * gridVectorY + ng * gridVectorX >> 8;
y = gridOffsetY + mg * gridVectorX - ng * gridVectorY >> 8;
if (x >= 0 && x + patternWidth <= regionWidth && y >= 0 && y + patternHeight <= regionHeight) {
for (i = 0; i < patternHeight; i++) {
regionRow = regionBitmap[y + i];
patternRow = patternBitmap[i];
for (j = 0; j < patternWidth; j++) {
regionRow[x + j] |= patternRow[j];
for (i = 0; i < patternHeight; i++) {
if (regionY < 0 || regionY >= regionHeight) {
regionRow = regionBitmap[regionY];
patternRow = patternBitmap[i];
for (j = 0; j < patternWidth; j++) {
if (regionX >= 0 && regionX < regionWidth) {
regionRow[regionX] |= patternRow[j];
function readSegmentHeader(data, start) {
const segmentHeader = {};
segmentHeader.number = readUint32(data, start);
const flags = data[start + 4];
const segmentType = flags & 0x3f;
if (!SegmentTypes[segmentType]) {
throw new Jbig2Error("invalid segment type: " + segmentType);
segmentHeader.type = segmentType;
segmentHeader.typeName = SegmentTypes[segmentType];
segmentHeader.deferredNonRetain = !!(flags & 0x80);
const pageAssociationFieldSize = !!(flags & 0x40);
const referredFlags = data[start + 5];
let referredToCount = referredFlags >> 5 & 7;
const retainBits = [referredFlags & 31];
let position = start + 6;
if (referredFlags === 7) {
referredToCount = readUint32(data, position - 1) & 0x1fffffff;
let bytes = referredToCount + 7 >> 3;
retainBits[0] = data[position++];
retainBits.push(data[position++]);
} else if (referredFlags === 5 || referredFlags === 6) {
throw new Jbig2Error("invalid referred-to flags");
segmentHeader.retainBits = retainBits;
let referredToSegmentNumberSize = 4;
if (segmentHeader.number <= 256) {
referredToSegmentNumberSize = 1;
} else if (segmentHeader.number <= 65536) {
referredToSegmentNumberSize = 2;
for (i = 0; i < referredToCount; i++) {
if (referredToSegmentNumberSize === 1) {
} else if (referredToSegmentNumberSize === 2) {
number = readUint16(data, position);