From c8f83d6487a1a4080c7373ad78d16811cfafa045 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 14 Oct 2016 17:19:50 +0200 Subject: [PATCH] Let `Parser_makeFilter` pass in the `DecodeParms` data to various image `Stream`s, instead of re-fetching it in various `[...]Stream.prototype.ensureBuffer` methods In `Parser_filter` the `DecodeParms` data is fetched and passed to `Parser_makeFilter`, where we also make sure that a `Ref` is resolved to a direct object. We can thus pass this along to the various image `Stream` constructors, to avoid the current situation where we lookup/resolve data that is already available. Note also that we currently do *not* handle the case where `DecodeParms` is an Array entirely correct in the various image `Stream`s, and this patch fixes that for free. --- src/core/parser.js | 9 ++++++--- src/core/stream.js | 34 ++++++++++++++-------------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/core/parser.js b/src/core/parser.js index 1b710f18d..050509e90 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -539,6 +539,9 @@ var Parser = (function ParserClosure() { var filter = dict.get('Filter', 'F'); var params = dict.get('DecodeParms', 'DP'); if (isName(filter)) { + if (isArray(params)) { + params = params[0]; + } return this.makeFilter(stream, filter.name, length, params); } @@ -599,11 +602,11 @@ var Parser = (function ParserClosure() { } if (name === 'DCTDecode' || name === 'DCT') { xrefStreamStats[StreamType.DCT] = true; - return new JpegStream(stream, maybeLength, stream.dict); + return new JpegStream(stream, maybeLength, stream.dict, params); } if (name === 'JPXDecode' || name === 'JPX') { xrefStreamStats[StreamType.JPX] = true; - return new JpxStream(stream, maybeLength, stream.dict); + return new JpxStream(stream, maybeLength, stream.dict, params); } if (name === 'ASCII85Decode' || name === 'A85') { xrefStreamStats[StreamType.A85] = true; @@ -623,7 +626,7 @@ var Parser = (function ParserClosure() { } if (name === 'JBIG2Decode') { xrefStreamStats[StreamType.JBIG] = true; - return new Jbig2Stream(stream, maybeLength, stream.dict); + return new Jbig2Stream(stream, maybeLength, stream.dict, params); } warn('filter "' + name + '" not supported yet'); return stream; diff --git a/src/core/stream.js b/src/core/stream.js index 1f569e90a..9d8f14850 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -42,6 +42,7 @@ var warn = sharedUtil.warn; var isSpace = sharedUtil.isSpace; var Dict = corePrimitives.Dict; var isDict = corePrimitives.isDict; +var isStream = corePrimitives.isStream; var Jbig2Image = coreJbig2.Jbig2Image; var JpegImage = coreJpg.JpegImage; var JpxImage = coreJpx.JpxImage; @@ -892,7 +893,7 @@ var PredictorStream = (function PredictorStreamClosure() { * DecodeStreams. */ var JpegStream = (function JpegStreamClosure() { - function JpegStream(stream, maybeLength, dict) { + function JpegStream(stream, maybeLength, dict, params) { // Some images may contain 'junk' before the SOI (start-of-image) marker. // Note: this seems to mainly affect inline images. var ch; @@ -905,6 +906,7 @@ var JpegStream = (function JpegStreamClosure() { this.stream = stream; this.maybeLength = maybeLength; this.dict = dict; + this.params = params; DecodeStream.call(this, maybeLength); } @@ -945,9 +947,8 @@ var JpegStream = (function JpegStreamClosure() { } } // Fetching the 'ColorTransform' entry, if it exists. - var decodeParams = this.dict.get('DecodeParms', 'DP'); - if (isDict(decodeParams)) { - var colorTransform = decodeParams.get('ColorTransform'); + if (isDict(this.params)) { + var colorTransform = this.params.get('ColorTransform'); if (isInt(colorTransform)) { jpegImage.colorTransform = colorTransform; } @@ -978,10 +979,11 @@ var JpegStream = (function JpegStreamClosure() { * the stream behaves like all the other DecodeStreams. */ var JpxStream = (function JpxStreamClosure() { - function JpxStream(stream, maybeLength, dict) { + function JpxStream(stream, maybeLength, dict, params) { this.stream = stream; this.maybeLength = maybeLength; this.dict = dict; + this.params = params; DecodeStream.call(this, maybeLength); } @@ -1047,10 +1049,11 @@ var JpxStream = (function JpxStreamClosure() { * the stream behaves like all the other DecodeStreams. */ var Jbig2Stream = (function Jbig2StreamClosure() { - function Jbig2Stream(stream, maybeLength, dict) { + function Jbig2Stream(stream, maybeLength, dict, params) { this.stream = stream; this.maybeLength = maybeLength; this.dict = dict; + this.params = params; DecodeStream.call(this, maybeLength); } @@ -1073,21 +1076,12 @@ var Jbig2Stream = (function Jbig2StreamClosure() { var jbig2Image = new Jbig2Image(); var chunks = []; - var decodeParams = this.dict.getArray('DecodeParms', 'DP'); - - // According to the PDF specification, DecodeParms can be either - // a dictionary, or an array whose elements are dictionaries. - if (isArray(decodeParams)) { - if (decodeParams.length > 1) { - warn('JBIG2 - \'DecodeParms\' array with multiple elements ' + - 'not supported.'); + if (isDict(this.params)) { + var globalsStream = this.params.get('JBIG2Globals'); + if (isStream(globalsStream)) { + var globals = globalsStream.getBytes(); + chunks.push({data: globals, start: 0, end: globals.length}); } - decodeParams = decodeParams[0]; - } - if (decodeParams && decodeParams.has('JBIG2Globals')) { - var globalsStream = decodeParams.get('JBIG2Globals'); - var globals = globalsStream.getBytes(); - chunks.push({data: globals, start: 0, end: globals.length}); } chunks.push({data: this.bytes, start: 0, end: this.bytes.length}); var data = jbig2Image.parseChunks(chunks);