Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert src/core/jpg.js to use the readUint16 helper function in src/core/core_utils.js, rather than re-implementing it twice #11482

Merged
merged 2 commits into from
Jan 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/core/core_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,49 @@ function toRomanNumerals(number, lowerCase = false) {
return lowerCase ? romanStr.toLowerCase() : romanStr;
}

// Calculate the base 2 logarithm of the number `x`. This differs from the
// native function in the sense that it returns the ceiling value and that it
// returns 0 instead of `Infinity`/`NaN` for `x` values smaller than/equal to 0.
function log2(x) {
if (x <= 0) {
return 0;
}
return Math.ceil(Math.log2(x));
}

function readInt8(data, offset) {
return (data[offset] << 24) >> 24;
}

function readUint16(data, offset) {
return (data[offset] << 8) | data[offset + 1];
}

function readUint32(data, offset) {
return (
((data[offset] << 24) |
(data[offset + 1] << 16) |
(data[offset + 2] << 8) |
data[offset + 3]) >>>
0
);
}

// Checks if ch is one of the following characters: SPACE, TAB, CR or LF.
function isSpace(ch) {
return ch === 0x20 || ch === 0x09 || ch === 0x0d || ch === 0x0a;
}

export {
getLookupTableFactory,
MissingDataException,
XRefEntryException,
XRefParseException,
getInheritableProperty,
toRomanNumerals,
log2,
readInt8,
readUint16,
readUint32,
isSpace,
};
2 changes: 1 addition & 1 deletion src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
isArrayEqual,
isBool,
isNum,
isSpace,
isString,
OPS,
shadow,
Expand All @@ -36,6 +35,7 @@ import { Catalog, ObjectLoader, XRef } from "./obj.js";
import { Dict, isDict, isName, isStream, Ref } from "./primitives.js";
import {
getInheritableProperty,
isSpace,
MissingDataException,
XRefEntryException,
XRefParseException,
Expand Down
4 changes: 1 addition & 3 deletions src/core/fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import {
FormatError,
info,
isNum,
isSpace,
readUint32,
shadow,
string32,
unreachable,
Expand Down Expand Up @@ -60,9 +58,9 @@ import {
getUnicodeRangeFor,
mapSpecialUnicodeValues,
} from "./unicode.js";
import { isSpace, MissingDataException, readUint32 } from "./core_utils.js";
import { FontRendererFactory } from "./font_renderer.js";
import { IdentityCMap } from "./cmap.js";
import { MissingDataException } from "./core_utils.js";
import { Stream } from "./stream.js";
import { Type1Parser } from "./type1_parser.js";

Expand Down
10 changes: 2 additions & 8 deletions src/core/jbig2.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@
* limitations under the License.
*/

import {
BaseException,
log2,
readInt8,
readUint16,
readUint32,
shadow,
} from "../shared/util.js";
import { BaseException, shadow } from "../shared/util.js";
import { log2, readInt8, readUint16, readUint32 } from "./core_utils.js";
import { ArithmeticDecoder } from "./arithmetic_decoder.js";
import { CCITTFaxDecoder } from "./ccitt.js";

Expand Down
65 changes: 36 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,10 @@ 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);
offset += 2;
if (scanLines > 0 && scanLines !== frame.scanLines) {
throw new DNLMarkerError(
"Found DNL marker (0xFFDC) while parsing scan data",
Expand Down Expand Up @@ -706,30 +709,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 @@ -740,15 +739,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 @@ -796,12 +790,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 @@ -868,7 +865,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 @@ -884,7 +882,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 @@ -899,14 +898,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 @@ -939,7 +941,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 @@ -960,8 +963,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 @@ -971,7 +976,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 @@ -1055,7 +1061,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
10 changes: 2 additions & 8 deletions src/core/jpx.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,8 @@
* limitations under the License.
*/

import {
BaseException,
info,
log2,
readUint16,
readUint32,
warn,
} from "../shared/util.js";
import { BaseException, info, warn } from "../shared/util.js";
import { log2, readUint16, readUint32 } from "./core_utils.js";
import { ArithmeticDecoder } from "./arithmetic_decoder.js";

class JpxError extends BaseException {
Expand Down
3 changes: 1 addition & 2 deletions src/core/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
FormatError,
info,
isNum,
isSpace,
StreamType,
warn,
} from "../shared/util.js";
Expand All @@ -44,11 +43,11 @@ import {
Name,
Ref,
} from "./primitives.js";
import { isSpace, MissingDataException } from "./core_utils.js";
import { CCITTFaxStream } from "./ccitt_stream.js";
import { Jbig2Stream } from "./jbig2_stream.js";
import { JpegStream } from "./jpeg_stream.js";
import { JpxStream } from "./jpx_stream.js";
import { MissingDataException } from "./core_utils.js";

const MAX_LENGTH_TO_CACHE = 1000;
const MAX_ADLER32_LENGTH = 5552;
Expand Down
3 changes: 2 additions & 1 deletion src/core/ps_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
*/
/* eslint no-var: error */

import { FormatError, isSpace, shadow } from "../shared/util.js";
import { FormatError, shadow } from "../shared/util.js";
import { EOF } from "./primitives.js";
import { isSpace } from "./core_utils.js";

class PostScriptParser {
constructor(lexer) {
Expand Down
8 changes: 2 additions & 6 deletions src/core/stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@
* license.
*/

import {
FormatError,
isSpace,
stringToBytes,
unreachable,
} from "../shared/util.js";
import { FormatError, stringToBytes, unreachable } from "../shared/util.js";
import { isDict } from "./primitives.js";
import { isSpace } from "./core_utils.js";

var Stream = (function StreamClosure() {
function Stream(arrayBuffer, start, length, dict) {
Expand Down
3 changes: 2 additions & 1 deletion src/core/type1_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
* limitations under the License.
*/

import { isSpace, warn } from "../shared/util.js";
import { getEncoding } from "./encodings.js";
import { isSpace } from "./core_utils.js";
import { Stream } from "./stream.js";
import { warn } from "../shared/util.js";

// Hinting is currently disabled due to unknown problems on windows
// in tracemonkey and various other pdfs with type1 fonts.
Expand Down
Loading