From 35cbf74b129c7d2672ec0954978539d5a29a9096 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Fri, 1 Apr 2016 07:36:16 -0500 Subject: [PATCH] Refactors to remove stream.js dependency on colorspace.js --- src/core/colorspace.js | 12 +++------ src/core/evaluator.js | 58 ++++++++++++++++++++++++++++++++++++++++-- src/core/image.js | 31 ++++++---------------- src/core/stream.js | 29 --------------------- 4 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/core/colorspace.js b/src/core/colorspace.js index 63a0e5cbb..f3759df1a 100644 --- a/src/core/colorspace.js +++ b/src/core/colorspace.js @@ -18,17 +18,16 @@ (function (root, factory) { if (typeof define === 'function' && define.amd) { define('pdfjs/core/colorspace', ['exports', 'pdfjs/shared/util', - 'pdfjs/core/primitives', 'pdfjs/core/function', 'pdfjs/core/stream'], + 'pdfjs/core/primitives', 'pdfjs/core/function'], factory); } else if (typeof exports !== 'undefined') { factory(exports, require('../shared/util.js'), require('./primitives.js'), - require('./function.js'), require('./stream.js')); + require('./function.js')); } else { factory((root.pdfjsCoreColorSpace = {}), root.pdfjsSharedUtil, - root.pdfjsCorePrimitives, root.pdfjsCoreFunction, root.pdfjsCoreStream); + root.pdfjsCorePrimitives, root.pdfjsCoreFunction); } -}(this, function (exports, sharedUtil, corePrimitives, coreFunction, - coreStream) { +}(this, function (exports, sharedUtil, corePrimitives, coreFunction) { var error = sharedUtil.error; var info = sharedUtil.info; @@ -1299,7 +1298,4 @@ function _setCoreImage(coreImage_) { exports._setCoreImage = _setCoreImage; exports.ColorSpace = ColorSpace; - -// TODO refactor to remove dependency on colorspace.js -coreStream._setCoreColorSpace(exports); })); diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 34e6ff711..0e6757699 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -72,6 +72,7 @@ var isRef = corePrimitives.isRef; var isStream = corePrimitives.isStream; var DecodeStream = coreStream.DecodeStream; var JpegStream = coreStream.JpegStream; +var Stream = coreStream.Stream; var Lexer = coreParser.Lexer; var Parser = coreParser.Parser; var isEOF = coreParser.isEOF; @@ -114,6 +115,51 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { cMapOptions: { url: null, packed: false } }; + function NativeImageDecoder(xref, resources, handler, forceDataSchema) { + this.xref = xref; + this.resources = resources; + this.handler = handler; + this.forceDataSchema = forceDataSchema; + } + NativeImageDecoder.prototype = { + canDecode: function (image) { + return image instanceof JpegStream && + NativeImageDecoder.isDecodable(image, this.xref, this.resources); + }, + decode: function (image) { + // For natively supported JPEGs send them to the main thread for decoding. + var dict = image.dict; + var colorSpace = dict.get('ColorSpace', 'CS'); + colorSpace = ColorSpace.parse(colorSpace, this.xref, this.resources); + var numComps = colorSpace.numComps; + var decodePromise = this.handler.sendWithPromise('JpegDecode', + [image.getIR(this.forceDataSchema), numComps]); + return decodePromise.then(function (message) { + var data = message.data; + return new Stream(data, 0, data.length, image.dict); + }); + } + }; + /** + * Checks if the image can be decoded and displayed by the browser without any + * further processing such as color space conversions. + */ + NativeImageDecoder.isSupported = + function NativeImageDecoder_isSupported(image, xref, res) { + var cs = ColorSpace.parse(image.dict.get('ColorSpace', 'CS'), xref, res); + return (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB') && + cs.isDefaultDecode(image.dict.get('Decode', 'D')); + }; + /** + * Checks if the image can be decoded by the browser. + */ + NativeImageDecoder.isDecodable = + function NativeImageDecoder_isDecodable(image, xref, res) { + var cs = ColorSpace.parse(image.dict.get('ColorSpace', 'CS'), xref, res); + return (cs.numComps === 1 || cs.numComps === 3) && + cs.isDefaultDecode(image.dict.get('Decode', 'D')); + }; + function PartialEvaluator(pdfManager, xref, handler, pageIndex, uniquePrefix, idCounters, fontCache, options) { this.pdfManager = pdfManager; @@ -343,7 +389,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { args = [objId, w, h]; if (!softMask && !mask && image instanceof JpegStream && - image.isNativelySupported(this.xref, resources)) { + NativeImageDecoder.isSupported(image, this.xref, resources)) { // These JPEGs don't need any more processing so we can just send it. operatorList.addOp(OPS.paintJpegXObject, args); this.handler.send('obj', @@ -352,8 +398,16 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { return; } + // Creates native image decoder only if a JPEG image or mask is present. + var nativeImageDecoder = null; + if (image instanceof JpegStream || mask instanceof JpegStream || + softMask instanceof JpegStream) { + nativeImageDecoder = new NativeImageDecoder(self.xref, resources, + self.handler, self.options.forceDataSchema); + } + PDFImage.buildImage(self.handler, self.xref, resources, image, inline, - this.options.forceDataSchema). + nativeImageDecoder). then(function(imageObj) { var imgData = imageObj.createImageData(/* forceRGBA = */ false); self.handler.send('obj', [objId, self.pageIndex, 'Image', imgData], diff --git a/src/core/image.js b/src/core/image.js index 40009aef2..1e641ff0a 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -42,29 +42,17 @@ var Name = corePrimitives.Name; var isStream = corePrimitives.isStream; var ColorSpace = coreColorSpace.ColorSpace; var DecodeStream = coreStream.DecodeStream; -var Stream = coreStream.Stream; var JpegStream = coreStream.JpegStream; var JpxImage = coreJpx.JpxImage; var PDFImage = (function PDFImageClosure() { /** - * Decode the image in the main thread if it supported. Resovles the promise + * Decodes the image using native decoder if possible. Resolves the promise * when the image data is ready. */ - function handleImageData(handler, xref, res, image, forceDataSchema) { - if (image instanceof JpegStream && image.isNativelyDecodable(xref, res)) { - // For natively supported jpegs send them to the main thread for decoding. - var dict = image.dict; - var colorSpace = dict.get('ColorSpace', 'CS'); - colorSpace = ColorSpace.parse(colorSpace, xref, res); - var numComps = colorSpace.numComps; - var decodePromise = handler.sendWithPromise('JpegDecode', - [image.getIR(forceDataSchema), - numComps]); - return decodePromise.then(function (message) { - var data = message.data; - return new Stream(data, 0, data.length, image.dict); - }); + function handleImageData(image, nativeDecoder) { + if (nativeDecoder && nativeDecoder.canDecode(image)) { + return nativeDecoder.decode(image); } else { return Promise.resolve(image); } @@ -186,9 +174,8 @@ var PDFImage = (function PDFImageClosure() { */ PDFImage.buildImage = function PDFImage_buildImage(handler, xref, res, image, inline, - forceDataSchema) { - var imagePromise = handleImageData(handler, xref, res, image, - forceDataSchema); + nativeDecoder) { + var imagePromise = handleImageData(image, nativeDecoder); var smaskPromise; var maskPromise; @@ -196,15 +183,13 @@ var PDFImage = (function PDFImageClosure() { var mask = image.dict.get('Mask'); if (smask) { - smaskPromise = handleImageData(handler, xref, res, smask, - forceDataSchema); + smaskPromise = handleImageData(smask, nativeDecoder); maskPromise = Promise.resolve(null); } else { smaskPromise = Promise.resolve(null); if (mask) { if (isStream(mask)) { - maskPromise = handleImageData(handler, xref, res, mask, - forceDataSchema); + maskPromise = handleImageData(mask, nativeDecoder); } else if (isArray(mask)) { maskPromise = Promise.resolve(mask); } else { diff --git a/src/core/stream.js b/src/core/stream.js index ddbaa747e..7fd092496 100644 --- a/src/core/stream.js +++ b/src/core/stream.js @@ -43,9 +43,6 @@ var Jbig2Image = coreJbig2.Jbig2Image; var JpegImage = coreJpg.JpegImage; var JpxImage = coreJpx.JpxImage; -var coreColorSpace; // see _setCoreColorSpace below -var ColorSpace; // = coreColorSpace.ColorSpace; - var Stream = (function StreamClosure() { function Stream(arrayBuffer, start, length, dict) { this.bytes = (arrayBuffer instanceof Uint8Array ? @@ -962,25 +959,6 @@ var JpegStream = (function JpegStreamClosure() { JpegStream.prototype.getIR = function JpegStream_getIR(forceDataSchema) { return createObjectURL(this.bytes, 'image/jpeg', forceDataSchema); }; - /** - * Checks if the image can be decoded and displayed by the browser without any - * further processing such as color space conversions. - */ - JpegStream.prototype.isNativelySupported = - function JpegStream_isNativelySupported(xref, res) { - var cs = ColorSpace.parse(this.dict.get('ColorSpace', 'CS'), xref, res); - return (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB') && - cs.isDefaultDecode(this.dict.get('Decode', 'D')); - }; - /** - * Checks if the image can be decoded by the browser. - */ - JpegStream.prototype.isNativelyDecodable = - function JpegStream_isNativelyDecodable(xref, res) { - var cs = ColorSpace.parse(this.dict.get('ColorSpace', 'CS'), xref, res); - return (cs.numComps === 1 || cs.numComps === 3) && - cs.isDefaultDecode(this.dict.get('Decode', 'D')); - }; return JpegStream; })(); @@ -2500,13 +2478,6 @@ var NullStream = (function NullStreamClosure() { return NullStream; })(); -// TODO refactor to remove dependency on colorspace.js -function _setCoreColorSpace(coreColorSpace_) { - coreColorSpace = coreColorSpace_; - ColorSpace = coreColorSpace_.ColorSpace; -} -exports._setCoreColorSpace = _setCoreColorSpace; - exports.Ascii85Stream = Ascii85Stream; exports.AsciiHexStream = AsciiHexStream; exports.CCITTFaxStream = CCITTFaxStream;