From 3c2a0f11b1f63595d08458f31e4c21738cd4ca5d Mon Sep 17 00:00:00 2001 From: Brendan Dahl Date: Tue, 3 Jan 2012 14:26:19 -0800 Subject: [PATCH] Decode more jpegs using the browser if possible. --- src/evaluator.js | 3 ++- src/image.js | 2 +- src/stream.js | 53 ++++++++++++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/evaluator.js b/src/evaluator.js index 2905565da..3daf97da9 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -211,7 +211,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { args = [objId, w, h]; var softMask = dict.get('SMask', 'IM') || false; - if (!softMask && image instanceof JpegStream && image.isNative) { + if (!softMask && image instanceof JpegStream && + image.isNativelySupported(xref, resources)) { // These JPEGs don't need any more processing so we can just send it. fn = 'paintJpegXObject'; handler.send('obj', [objId, 'JpegStream', image.getIR()]); diff --git a/src/image.js b/src/image.js index 29bad4d8a..6e7ab2020 100644 --- a/src/image.js +++ b/src/image.js @@ -9,7 +9,7 @@ var PDFImage = (function PDFImageClosure() { * when the image data is ready. */ function handleImageData(handler, xref, res, image, promise) { - if (image instanceof JpegStream && image.isNative) { + 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'); diff --git a/src/stream.js b/src/stream.js index d996f5c91..3367636b4 100644 --- a/src/stream.js +++ b/src/stream.js @@ -803,35 +803,23 @@ var JpegStream = (function JpegStreamClosure() { // need to be removed this.dict = dict; - // Flag indicating wether the image can be natively loaded. - this.isNative = true; - - this.colorTransform = -1; + this.colorTransform = dict.get('ColorTransform') || -1; + this.isAdobeImage = false; if (isAdobeImage(bytes)) { - // when bug 674619 land, let's check if browser can do - // normal cmyk and then we won't have to the following - var cs = xref.fetchIfRef(dict.get('ColorSpace')); - - // DeviceRGB and DeviceGray are the only Adobe images that work natively - if (isName(cs) && (cs.name === 'DeviceRGB' || cs.name === 'DeviceGray')) { - bytes = fixAdobeImage(bytes); - this.src = bytesToString(bytes); - } else { - this.colorTransform = dict.get('ColorTransform'); - this.isNative = false; - this.bytes = bytes; - } - } else { - this.src = bytesToString(bytes); + this.isAdobeImage = true; + bytes = fixAdobeImage(bytes); } + this.bytes = bytes; + DecodeStream.call(this); } JpegStream.prototype = Object.create(DecodeStream.prototype); JpegStream.prototype.ensureBuffer = function jpegStreamEnsureBuffer(req) { + // todo make sure this isn't called on natively supported jpegs if (this.bufferLength) return; var jpegImage = new JpegImage(); @@ -844,11 +832,36 @@ var JpegStream = (function JpegStreamClosure() { this.bufferLength = data.length; }; JpegStream.prototype.getIR = function jpegStreamGetIR() { - return this.src; + return bytesToString(this.bytes); }; JpegStream.prototype.getChar = function jpegStreamGetChar() { error('internal error: getChar is not valid on JpegStream'); }; + /** + * 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 isNativelySupported(xref, + res) { + var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res); + if (cs.name === 'DeviceGray' || cs.name === 'DeviceRGB') + return true; + if (cs.name === 'DeviceCMYK' && !this.isAdobeImage && + this.colorTransform < 1) + return true; + return false; + }; + /** + * Checks if the image can be decoded by the browser. + */ + JpegStream.prototype.isNativelyDecodable = function isNativelyDecodable(xref, + res) { + var cs = ColorSpace.parse(this.dict.get('ColorSpace'), xref, res); + if (cs.numComps == 1 || cs.numComps == 3) + return true; + + return false; + }; return JpegStream; })();