diff --git a/src/core/jpg.js b/src/core/jpg.js index a238d2d70..d7faa25ab 100644 --- a/src/core/jpg.js +++ b/src/core/jpg.js @@ -235,53 +235,54 @@ var JpegImage = (function JpegImageClosure() { var s; var rs; while (k <= e) { - var z = dctZigZag[k]; + let offsetZ = offset + dctZigZag[k]; + let sign = component.blockData[offsetZ] < 0 ? -1 : 1; switch (successiveACState) { - case 0: // initial state - rs = decodeHuffman(component.huffmanTableAC); - s = rs & 15; - r = rs >> 4; - if (s === 0) { - if (r < 15) { - eobrun = receive(r) + (1 << r); - successiveACState = 4; + case 0: // initial state + rs = decodeHuffman(component.huffmanTableAC); + s = rs & 15; + r = rs >> 4; + if (s === 0) { + if (r < 15) { + eobrun = receive(r) + (1 << r); + successiveACState = 4; + } else { + r = 16; + successiveACState = 1; + } } else { - r = 16; - successiveACState = 1; + if (s !== 1) { + throw new JpegError('invalid ACn encoding'); + } + successiveACNextValue = receiveAndExtend(s); + successiveACState = r ? 2 : 3; } - } else { - if (s !== 1) { - throw new JpegError('invalid ACn encoding'); + continue; + case 1: // skipping r zero items + case 2: + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } else { + r--; + if (r === 0) { + successiveACState = successiveACState === 2 ? 3 : 0; + } } - successiveACNextValue = receiveAndExtend(s); - successiveACState = r ? 2 : 3; - } - continue; - case 1: // skipping r zero items - case 2: - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } else { - r--; - if (r === 0) { - successiveACState = successiveACState === 2 ? 3 : 0; + break; + case 3: // set value for a zero item + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } else { + component.blockData[offsetZ] = + successiveACNextValue << successive; + successiveACState = 0; } - } - break; - case 3: // set value for a zero item - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } else { - component.blockData[offset + z] = - successiveACNextValue << successive; - successiveACState = 0; - } - break; - case 4: // eob - if (component.blockData[offset + z]) { - component.blockData[offset + z] += (readBit() << successive); - } - break; + break; + case 4: // eob + if (component.blockData[offsetZ]) { + component.blockData[offsetZ] += sign * (readBit() << successive); + } + break; } k++; } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index d7c1980a1..d74dbd5f8 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -67,6 +67,7 @@ !issue9105_reduced.pdf !issue9291.pdf !bad-PageLabels.pdf +!decodeACSuccessive.pdf !filled-background.pdf !ArabicCIDTrueType.pdf !ThuluthFeatures.pdf diff --git a/test/pdfs/decodeACSuccessive.pdf b/test/pdfs/decodeACSuccessive.pdf new file mode 100644 index 000000000..ed05a3cf5 Binary files /dev/null and b/test/pdfs/decodeACSuccessive.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 3958b19c6..0648b967c 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -3589,6 +3589,14 @@ "type": "eq", "nativeImageDecoderSupport": "none" }, + { "id": "decodeACSuccessive", + "file": "pdfs/decodeACSuccessive.pdf", + "md5": "7749c032624fe27ab8e8d7d5e9a4a93f", + "rounds": 1, + "link": false, + "type": "eq", + "nativeImageDecoderSupport": "none" + }, { "id": "issue5592", "file": "pdfs/issue5592.pdf", "md5": "a0750f95afa80c880f7966df7062616c",