Skip to content

Commit

Permalink
Convert src/core/jpg.js to use the readUint16 helper function in …
Browse files Browse the repository at this point in the history
…`src/core/core_utils.js`, rather than re-implementing it twice

The other image decoders, i.e. the JBIG2 and JPEG 2000 ones, are using the common helper function `readUint16`. Most likely, the only reason that the JPEG decoder is doing it this way is because it originated *outside* of the PDF.js library.
Hence we can simply re-factor `src/core/jpg.js` to use the common `readUint16` helper function, which is especially nice given that the functionality was essentially *duplicated* in the code.
  • Loading branch information
Snuffleupagus committed Jan 10, 2020
1 parent 2767db3 commit 2fdb324
Showing 1 changed file with 35 additions and 29 deletions.
64 changes: 35 additions & 29 deletions src/core/jpg.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

import { assert, BaseException, warn } from "../shared/util.js";
import { readUint16 } from "./core_utils.js";

class JpegError extends BaseException {
constructor(msg) {
Expand Down Expand Up @@ -148,8 +149,9 @@ var JpegImage = (function JpegImageClosure() {
var nextByte = data[offset++];
if (nextByte) {
if (nextByte === 0xdc && parseDNLMarker) {
offset += 2; // Skip data length.
const scanLines = (data[offset++] << 8) | data[offset++];
offset += 2; // Skip marker length.

const scanLines = readUint16(data, offset);
if (scanLines > 0 && scanLines !== frame.scanLines) {
throw new DNLMarkerError(
"Found DNL marker (0xFFDC) while parsing scan data",
Expand Down Expand Up @@ -652,30 +654,26 @@ var JpegImage = (function JpegImageClosure() {
}

function findNextFileMarker(data, currentPos, startPos = currentPos) {
function peekUint16(pos) {
return (data[pos] << 8) | data[pos + 1];
}

const maxPos = data.length - 1;
var newPos = startPos < currentPos ? startPos : currentPos;

if (currentPos >= maxPos) {
return null; // Don't attempt to read non-existent data and just return.
}
var currentMarker = peekUint16(currentPos);
var currentMarker = readUint16(data, currentPos);
if (currentMarker >= 0xffc0 && currentMarker <= 0xfffe) {
return {
invalid: null,
marker: currentMarker,
offset: currentPos,
};
}
var newMarker = peekUint16(newPos);
var newMarker = readUint16(data, newPos);
while (!(newMarker >= 0xffc0 && newMarker <= 0xfffe)) {
if (++newPos >= maxPos) {
return null; // Don't attempt to read non-existent data and just return.
}
newMarker = peekUint16(newPos);
newMarker = readUint16(data, newPos);
}
return {
invalid: currentMarker.toString(16),
Expand All @@ -686,15 +684,10 @@ var JpegImage = (function JpegImageClosure() {

JpegImage.prototype = {
parse(data, { dnlScanLines = null } = {}) {
function readUint16() {
var value = (data[offset] << 8) | data[offset + 1];
offset += 2;
return value;
}

function readDataBlock() {
var length = readUint16();
var endOffset = offset + length - 2;
const length = readUint16(data, offset);
offset += 2;
let endOffset = offset + length - 2;

var fileMarker = findNextFileMarker(data, endOffset, offset);
if (fileMarker && fileMarker.invalid) {
Expand Down Expand Up @@ -742,12 +735,15 @@ var JpegImage = (function JpegImageClosure() {
var quantizationTables = [];
var huffmanTablesAC = [],
huffmanTablesDC = [];
var fileMarker = readUint16();

let fileMarker = readUint16(data, offset);
offset += 2;
if (fileMarker !== /* SOI (Start of Image) = */ 0xffd8) {
throw new JpegError("SOI not found");
}
fileMarker = readUint16(data, offset);
offset += 2;

fileMarker = readUint16();
markerLoop: while (fileMarker !== /* EOI (End of Image) = */ 0xffd9) {
var i, j, l;
switch (fileMarker) {
Expand Down Expand Up @@ -814,7 +810,8 @@ var JpegImage = (function JpegImageClosure() {
break;

case 0xffdb: // DQT (Define Quantization Tables)
var quantizationTablesLength = readUint16();
const quantizationTablesLength = readUint16(data, offset);
offset += 2;
var quantizationTablesEnd = quantizationTablesLength + offset - 2;
var z;
while (offset < quantizationTablesEnd) {
Expand All @@ -830,7 +827,8 @@ var JpegImage = (function JpegImageClosure() {
// 16 bit values
for (j = 0; j < 64; j++) {
z = dctZigZag[j];
tableData[z] = readUint16();
tableData[z] = readUint16(data, offset);
offset += 2;
}
} else {
throw new JpegError("DQT - invalid table spec");
Expand All @@ -845,14 +843,17 @@ var JpegImage = (function JpegImageClosure() {
if (frame) {
throw new JpegError("Only single frame JPEGs supported");
}
readUint16(); // skip data length
offset += 2; // Skip marker length.

frame = {};
frame.extended = fileMarker === 0xffc1;
frame.progressive = fileMarker === 0xffc2;
frame.precision = data[offset++];
const sofScanLines = readUint16();
const sofScanLines = readUint16(data, offset);
offset += 2;
frame.scanLines = dnlScanLines || sofScanLines;
frame.samplesPerLine = readUint16();
frame.samplesPerLine = readUint16(data, offset);
offset += 2;
frame.components = [];
frame.componentIds = {};
var componentsCount = data[offset++],
Expand Down Expand Up @@ -885,7 +886,8 @@ var JpegImage = (function JpegImageClosure() {
break;

case 0xffc4: // DHT (Define Huffman Tables)
var huffmanLength = readUint16();
const huffmanLength = readUint16(data, offset);
offset += 2;
for (i = 2; i < huffmanLength; ) {
var huffmanTableSpec = data[offset++];
var codeLengths = new Uint8Array(16);
Expand All @@ -906,8 +908,10 @@ var JpegImage = (function JpegImageClosure() {
break;

case 0xffdd: // DRI (Define Restart Interval)
readUint16(); // skip data length
resetInterval = readUint16();
offset += 2; // Skip marker length.

resetInterval = readUint16(data, offset);
offset += 2;
break;

case 0xffda: // SOS (Start of Scan)
Expand All @@ -917,7 +921,8 @@ var JpegImage = (function JpegImageClosure() {
// parse DNL markers during re-parsing of the JPEG scan data.
const parseDNLMarker = ++numSOSMarkers === 1 && !dnlScanLines;

readUint16(); // scanLength
offset += 2; // Skip marker length.

var selectorsCount = data[offset++];
var components = [],
component;
Expand Down Expand Up @@ -1001,7 +1006,8 @@ var JpegImage = (function JpegImageClosure() {
"JpegImage.parse - unknown marker: " + fileMarker.toString(16)
);
}
fileMarker = readUint16();
fileMarker = readUint16(data, offset);
offset += 2;
}

this.width = frame.samplesPerLine;
Expand Down

0 comments on commit 2fdb324

Please sign in to comment.