Merge pull request #4434 from p01/jbig2Optimizations
Jbig2 optimizations
This commit is contained in:
commit
8266225b73
@ -128,41 +128,39 @@ var ArithmeticDecoder = (function ArithmeticDecoderClosure() {
|
|||||||
var cx_index = contexts[pos] >> 1, cx_mps = contexts[pos] & 1;
|
var cx_index = contexts[pos] >> 1, cx_mps = contexts[pos] & 1;
|
||||||
var qeTableIcx = QeTable[cx_index];
|
var qeTableIcx = QeTable[cx_index];
|
||||||
var qeIcx = qeTableIcx.qe;
|
var qeIcx = qeTableIcx.qe;
|
||||||
var nmpsIcx = qeTableIcx.nmps;
|
|
||||||
var nlpsIcx = qeTableIcx.nlps;
|
|
||||||
var switchIcx = qeTableIcx.switchFlag;
|
|
||||||
var d;
|
var d;
|
||||||
this.a -= qeIcx;
|
var a = this.a - qeIcx;
|
||||||
|
|
||||||
if (this.chigh < qeIcx) {
|
if (this.chigh < qeIcx) {
|
||||||
// exchangeLps
|
// exchangeLps
|
||||||
if (this.a < qeIcx) {
|
if (a < qeIcx) {
|
||||||
this.a = qeIcx;
|
a = qeIcx;
|
||||||
d = cx_mps;
|
d = cx_mps;
|
||||||
cx_index = nmpsIcx;
|
cx_index = qeTableIcx.nmps;
|
||||||
} else {
|
} else {
|
||||||
this.a = qeIcx;
|
a = qeIcx;
|
||||||
d = 1 - cx_mps;
|
d = 1 ^ cx_mps;
|
||||||
if (switchIcx) {
|
if (qeTableIcx.switchFlag === 1) {
|
||||||
cx_mps = d;
|
cx_mps = d;
|
||||||
}
|
}
|
||||||
cx_index = nlpsIcx;
|
cx_index = qeTableIcx.nlps;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.chigh -= qeIcx;
|
this.chigh -= qeIcx;
|
||||||
if ((this.a & 0x8000) !== 0) {
|
if ((a & 0x8000) !== 0) {
|
||||||
|
this.a = a;
|
||||||
return cx_mps;
|
return cx_mps;
|
||||||
}
|
}
|
||||||
// exchangeMps
|
// exchangeMps
|
||||||
if (this.a < qeIcx) {
|
if (a < qeIcx) {
|
||||||
d = 1 - cx_mps;
|
d = 1 ^ cx_mps;
|
||||||
if (switchIcx) {
|
if (qeTableIcx.switchFlag === 1) {
|
||||||
cx_mps = d;
|
cx_mps = d;
|
||||||
}
|
}
|
||||||
cx_index = nlpsIcx;
|
cx_index = qeTableIcx.nlps;
|
||||||
} else {
|
} else {
|
||||||
d = cx_mps;
|
d = cx_mps;
|
||||||
cx_index = nmpsIcx;
|
cx_index = qeTableIcx.nmps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// C.3.3 renormD;
|
// C.3.3 renormD;
|
||||||
@ -171,11 +169,12 @@ var ArithmeticDecoder = (function ArithmeticDecoderClosure() {
|
|||||||
this.byteIn();
|
this.byteIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.a <<= 1;
|
a <<= 1;
|
||||||
this.chigh = ((this.chigh << 1) & 0xFFFF) | ((this.clow >> 15) & 1);
|
this.chigh = ((this.chigh << 1) & 0xFFFF) | ((this.clow >> 15) & 1);
|
||||||
this.clow = (this.clow << 1) & 0xFFFF;
|
this.clow = (this.clow << 1) & 0xFFFF;
|
||||||
this.ct--;
|
this.ct--;
|
||||||
} while ((this.a & 0x8000) === 0);
|
} while ((a & 0x8000) === 0);
|
||||||
|
this.a = a;
|
||||||
|
|
||||||
contexts[pos] = cx_index << 1 | cx_mps;
|
contexts[pos] = cx_index << 1 | cx_mps;
|
||||||
return d;
|
return d;
|
||||||
|
@ -105,7 +105,7 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
offset = 340;
|
offset = 340;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
v = v * 2 + bit;
|
v = ((v << 1) | bit) >>> 0;
|
||||||
if (--toRead === 0) {
|
if (--toRead === 0) {
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
}
|
||||||
@ -124,12 +124,12 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
var prev = 1;
|
var prev = 1;
|
||||||
for (var i = 0; i < codeLength; i++) {
|
for (var i = 0; i < codeLength; i++) {
|
||||||
var bit = decoder.readBit(contexts, prev);
|
var bit = decoder.readBit(contexts, prev);
|
||||||
prev = (prev * 2) + bit;
|
prev = (prev << 1) | bit;
|
||||||
}
|
}
|
||||||
if (codeLength < 31) {
|
if (codeLength < 31) {
|
||||||
return prev & ((1 << codeLength) - 1);
|
return prev & ((1 << codeLength) - 1);
|
||||||
}
|
}
|
||||||
return prev - Math.pow(2, codeLength);
|
return prev & 0x7FFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7.3 Segment types
|
// 7.3 Segment types
|
||||||
@ -255,26 +255,41 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
changingTemplateEntries.push(k);
|
changingTemplateEntries.push(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changingTemplateEntries = new Uint8Array(changingTemplateEntries);
|
|
||||||
var changingEntriesLength = changingTemplateEntries.length;
|
var changingEntriesLength = changingTemplateEntries.length;
|
||||||
|
|
||||||
|
var changingTemplateX = new Int8Array(changingEntriesLength);
|
||||||
|
var changingTemplateY = new Int8Array(changingEntriesLength);
|
||||||
|
var changingTemplateBit = new Uint16Array(changingEntriesLength);
|
||||||
|
for (var c = 0; c < changingEntriesLength; c++) {
|
||||||
|
k = changingTemplateEntries[c];
|
||||||
|
changingTemplateX[c] = template[k].x;
|
||||||
|
changingTemplateY[c] = template[k].y;
|
||||||
|
changingTemplateBit[c] = 1 << (templateLength - 1 - k);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the safe bounding box edges from the width, height, minX, maxX, minY
|
||||||
|
var sbb_left = -minX;
|
||||||
|
var sbb_top = -minY;
|
||||||
|
var sbb_right = width - maxX;
|
||||||
|
|
||||||
var pseudoPixelContext = ReusedContexts[templateIndex];
|
var pseudoPixelContext = ReusedContexts[templateIndex];
|
||||||
|
var row = new Uint8Array(width);
|
||||||
var bitmap = [];
|
var bitmap = [];
|
||||||
|
|
||||||
var decoder = decodingContext.decoder;
|
var decoder = decodingContext.decoder;
|
||||||
var contexts = decodingContext.contextCache.getContexts('GB');
|
var contexts = decodingContext.contextCache.getContexts('GB');
|
||||||
|
|
||||||
var ltp = 0, c, j, i0, j0, k, contextLabel = 0;
|
var ltp = 0, c, j, i0, j0, k, contextLabel = 0, bit, shift;
|
||||||
for (var i = 0; i < height; i++) {
|
for (var i = 0; i < height; i++) {
|
||||||
if (prediction) {
|
if (prediction) {
|
||||||
var sltp = decoder.readBit(contexts, pseudoPixelContext);
|
var sltp = decoder.readBit(contexts, pseudoPixelContext);
|
||||||
ltp ^= sltp;
|
ltp ^= sltp;
|
||||||
|
if (ltp) {
|
||||||
|
bitmap.push(row); // duplicate previous row
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ltp) {
|
row = new Uint8Array(row);
|
||||||
bitmap.push(bitmap[bitmap.length - 1]); // duplicate previous row
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var row = new Uint8Array(width);
|
|
||||||
bitmap.push(row);
|
bitmap.push(row);
|
||||||
for (j = 0; j < width; j++) {
|
for (j = 0; j < width; j++) {
|
||||||
if (useskip && skip[i][j]) {
|
if (useskip && skip[i][j]) {
|
||||||
@ -283,24 +298,33 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
}
|
}
|
||||||
// Are we in the middle of a scanline, so we can reuse contextLabel
|
// Are we in the middle of a scanline, so we can reuse contextLabel
|
||||||
// bits?
|
// bits?
|
||||||
if (i + minY > 0 && j + minX >= 0 && j + maxX < width) {
|
if (j >= sbb_left && j < sbb_right && i >= sbb_top) {
|
||||||
// If yes, we can just shift the bits that are reusable and only
|
// If yes, we can just shift the bits that are reusable and only
|
||||||
// fetch the remaining ones.
|
// fetch the remaining ones.
|
||||||
contextLabel = (contextLabel << 1) & reuseMask;
|
contextLabel = (contextLabel << 1) & reuseMask;
|
||||||
for (c = 0; c < changingEntriesLength; c++) {
|
for (k = 0; k < changingEntriesLength; k++) {
|
||||||
k = changingTemplateEntries[c];
|
i0 = i + changingTemplateY[k];
|
||||||
i0 = i + templateY[k];
|
j0 = j + changingTemplateX[k];
|
||||||
j0 = j + templateX[k];
|
bit = bitmap[i0][j0];
|
||||||
contextLabel |= bitmap[i0][j0] << (templateLength - 1 - k);
|
if (bit) {
|
||||||
|
bit = changingTemplateBit[k];
|
||||||
|
contextLabel |= bit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// compute the contextLabel from scratch
|
// compute the contextLabel from scratch
|
||||||
contextLabel = 0;
|
contextLabel = 0;
|
||||||
for (k = 0; k < templateLength; k++) {
|
shift = templateLength - 1;
|
||||||
i0 = i + templateY[k];
|
for (k = 0; k < templateLength; k++, shift--) {
|
||||||
j0 = j + templateX[k];
|
j0 = j + templateX[k];
|
||||||
if (i0 >= 0 && j0 >= 0 && j0 < width) {
|
if (j0 >= 0 && j0 < width) {
|
||||||
contextLabel |= bitmap[i0][j0] << (templateLength - 1 - k);
|
i0 = i + templateY[k];
|
||||||
|
if (i0 >= 0) {
|
||||||
|
bit = bitmap[i0][j0];
|
||||||
|
if (bit) {
|
||||||
|
contextLabel |= bit << shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -352,13 +376,13 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
if (prediction) {
|
if (prediction) {
|
||||||
var sltp = decoder.readBit(contexts, pseudoPixelContext);
|
var sltp = decoder.readBit(contexts, pseudoPixelContext);
|
||||||
ltp ^= sltp;
|
ltp ^= sltp;
|
||||||
|
if (ltp) {
|
||||||
|
error('JBIG2 error: prediction is not supported');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var row = new Uint8Array(width);
|
var row = new Uint8Array(width);
|
||||||
bitmap.push(row);
|
bitmap.push(row);
|
||||||
for (var j = 0; j < width; j++) {
|
for (var j = 0; j < width; j++) {
|
||||||
if (ltp) {
|
|
||||||
error('JBIG2 error: prediction is not supported');
|
|
||||||
}
|
|
||||||
|
|
||||||
var contextLabel = 0;
|
var contextLabel = 0;
|
||||||
for (var k = 0; k < codingTemplateLength; k++) {
|
for (var k = 0; k < codingTemplateLength; k++) {
|
||||||
@ -938,34 +962,46 @@ var Jbig2Image = (function Jbig2ImageClosure() {
|
|||||||
var combinationOperator = pageInfo.combinationOperatorOverride ?
|
var combinationOperator = pageInfo.combinationOperatorOverride ?
|
||||||
regionInfo.combinationOperator : pageInfo.combinationOperator;
|
regionInfo.combinationOperator : pageInfo.combinationOperator;
|
||||||
var buffer = this.buffer;
|
var buffer = this.buffer;
|
||||||
for (var i = 0; i < height; i++) {
|
var mask0 = 128 >> (regionInfo.x & 7);
|
||||||
var mask = 128 >> (regionInfo.x & 7);
|
var offset0 = regionInfo.y * rowSize + (regionInfo.x >> 3);
|
||||||
var offset = (i + regionInfo.y) * rowSize + (regionInfo.x >> 3);
|
switch (combinationOperator) {
|
||||||
switch (combinationOperator) {
|
case 0: // OR
|
||||||
case 0: // OR
|
for (var i = 0; i < height; i++) {
|
||||||
|
var mask = mask0;
|
||||||
|
var offset = offset0;
|
||||||
for (var j = 0; j < width; j++) {
|
for (var j = 0; j < width; j++) {
|
||||||
buffer[offset] |= bitmap[i][j] ? mask : 0;
|
if (bitmap[i][j]) {
|
||||||
|
buffer[offset] |= mask;
|
||||||
|
}
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
if (!mask) {
|
if (!mask) {
|
||||||
mask = 128;
|
mask = 128;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
offset0 += rowSize;
|
||||||
case 2: // XOR
|
}
|
||||||
|
break;
|
||||||
|
case 2: // XOR
|
||||||
|
for (var i = 0; i < height; i++) {
|
||||||
|
var mask = mask0;
|
||||||
|
var offset = offset0;
|
||||||
for (var j = 0; j < width; j++) {
|
for (var j = 0; j < width; j++) {
|
||||||
buffer[offset] ^= bitmap[i][j] ? mask : 0;
|
if (bitmap[i][j]) {
|
||||||
|
buffer[offset] ^= mask;
|
||||||
|
}
|
||||||
mask >>= 1;
|
mask >>= 1;
|
||||||
if (!mask) {
|
if (!mask) {
|
||||||
mask = 128;
|
mask = 128;
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
offset0 += rowSize;
|
||||||
default:
|
}
|
||||||
error('JBIG2 error: operator ' + combinationOperator +
|
break;
|
||||||
' is not supported');
|
default:
|
||||||
}
|
error('JBIG2 error: operator ' + combinationOperator +
|
||||||
|
' is not supported');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onImmediateGenericRegion:
|
onImmediateGenericRegion:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user