diff --git a/src/evaluator.js b/src/evaluator.js index 0f4cc101e..198659201 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 8d3f0f5bb..69748b5f2 100644 --- a/src/stream.js +++ b/src/stream.js @@ -803,29 +803,16 @@ 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.isAdobeImage = false; + this.colorTransform = dict.get('ColorTransform') || -1; 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); } @@ -835,7 +822,8 @@ var JpegStream = (function JpegStreamClosure() { if (this.bufferLength) return; var jpegImage = new JpegImage(); - jpegImage.colorTransform = this.colorTransform; + if (this.colorTransform != -1) + jpegImage.colorTransform = this.colorTransform; jpegImage.parse(this.bytes); var width = jpegImage.width; var height = jpegImage.height; @@ -844,11 +832,39 @@ 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); + // when bug 674619 lands, let's check if browser can do + // normal cmyk and then we won't need to decode in JS + 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); + var numComps = cs.numComps; + if (numComps == 1 || numComps == 3) + return true; + + return false; + }; return JpegStream; })(); diff --git a/web/viewer.js b/web/viewer.js index d9ef9b646..ac3fbff0c 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -781,9 +781,13 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, div.appendChild(canvas); this.canvas = canvas; - var textLayer = document.createElement('div'); - textLayer.className = 'textLayer'; - div.appendChild(textLayer); + var textLayerDiv = null; + if (!PDFJS.disableTextLayer) { + textLayerDiv = document.createElement('div'); + textLayerDiv.className = 'textLayer'; + div.appendChild(textLayerDiv); + } + var textLayer = textLayerDiv ? new TextLayerBuilder(textLayerDiv) : null; var scale = this.scale; canvas.width = pageWidth * scale; @@ -807,7 +811,7 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight, cache.push(this); callback(); - }).bind(this), new TextLayerBuilder(textLayer) + }).bind(this), textLayer ); setupAnnotations(this.content, this.scale); @@ -878,6 +882,10 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { return ctx; } + this.drawingRequired = function thumbnailViewDrawingRequired() { + return !this.hasImage; + }; + this.draw = function thumbnailViewDraw(callback) { if (this.hasImage) { callback(); @@ -1003,7 +1011,10 @@ window.addEventListener('load', function webViewerLoad(evt) { document.getElementById('fileInput').value = null; if ('disableWorker' in params) - PDFJS.disableWorker = params['disableWorker'] === 'true' ? true : false; + PDFJS.disableWorker = (params['disableWorker'] === 'true'); + + if ('disableTextLayer' in params) + PDFJS.disableTextLayer = (params['disableTextLayer'] === 'true'); var sidebarScrollView = document.getElementById('sidebarScrollView'); sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true);