diff --git a/src/canvas.js b/src/canvas.js index 128f4fbc9..5ec9435c7 100644 --- a/src/canvas.js +++ b/src/canvas.js @@ -1036,6 +1036,23 @@ var CanvasGraphics = (function canvasGraphics() { this.restore(); }, + paintJpegXObject: function canvasGraphicsPaintJpegXObject(objId, w, h) { + var domImage = this.objs.get(objId); + if (!domImage) { + error('Dependent image isn\'t ready yet'); + } + + this.save(); + + var ctx = this.ctx; + // scale the image to the unit square + ctx.scale(1 / w, -1 / h); + + ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, + 0, -h, w, h); + + this.restore(); + }, paintImageMaskXObject: function canvasGraphicsPaintImageMaskXObject( imgArray, inverseDecode, width, height) { function applyStencilMask(buffer, inverseDecode) { diff --git a/src/core.js b/src/core.js index 29bc56e32..cbe4d0fa5 100644 --- a/src/core.js +++ b/src/core.js @@ -563,6 +563,10 @@ var PDFDoc = (function pdfDoc() { var type = data[1]; switch (type) { + case 'JpegStream': + var imageData = data[2]; + loadJpegStream(id, imageData, this.objs); + break; case 'Image': var imageData = data[2]; this.objs.resolve(id, imageData); diff --git a/src/evaluator.js b/src/evaluator.js index a53d15c50..cb46d1b3b 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -208,26 +208,31 @@ var PartialEvaluator = (function partialEvaluator() { // of image processing can be done here. var objId = 'img_' + uniquePrefix + (++self.objIdCounter); insertDependency([objId]); - fn = 'paintImageXObject'; args = [objId, w, h]; - var resolve = (function(objId) { - return function resolve(data) { - handler.send('obj', [objId, 'Image', data]); - }; - })(objId); + var softMask = dict.get('SMask', 'IM') || false; + if (!softMask && image instanceof JpegStream && image.isNative) { + // These JPEGs don't need any more processing so we can just send it. + fn = 'paintJpegXObject'; + handler.send('obj', [objId, 'JpegStream', image.getIR()]); + return; + } + + fn = 'paintImageXObject'; var imageObj = new PDFImage(xref, resources, image, inline, handler); - imageObj.ready(function() { - var imgData = { - width: w, - height: h, - data: new Uint8Array(w * h * 4) + imageObj.ready((function() { + return function(data) { + var imgData = { + width: w, + height: h, + data: new Uint8Array(w * h * 4) + }; + var pixels = imgData.data; + imageObj.fillRgbaBuffer(pixels, imageObj.decode); + handler.send('obj', [objId, 'Image', imgData]); }; - var pixels = imgData.data; - imageObj.fillRgbaBuffer(pixels, imageObj.decode); - resolve(imgData); - }); + })(objId)); } uniquePrefix = uniquePrefix || ''; diff --git a/src/image.js b/src/image.js index c1eaf1c8f..7b9b12c18 100644 --- a/src/image.js +++ b/src/image.js @@ -151,6 +151,8 @@ var PDFImage = (function pdfImage() { var buf = new Uint8Array(width * height); if (smask) { + if (!smask.isReady()) + error('Soft mask is not ready.'); var sw = smask.width; var sh = smask.height; if (sw != this.width || sh != this.height) @@ -168,8 +170,7 @@ var PDFImage = (function pdfImage() { applyStencilMask: function applyStencilMask(buffer, inverseDecode) { var width = this.width, height = this.height; var bitStrideLength = (width + 7) >> 3; - this.image.reset(); - var imgArray = this.image.getBytes(bitStrideLength * height); + var imgArray = this.getImageBytes(bitStrideLength * height); var imgArrayPos = 0; var i, j, mask, buf; // removing making non-masked pixels transparent @@ -197,8 +198,7 @@ var PDFImage = (function pdfImage() { // rows start at byte boundary; var rowBytes = (width * numComps * bpc + 7) >> 3; - this.image.reset(); - var imgArray = this.image.getBytes(height * rowBytes); + var imgArray = this.getImageBytes(height * rowBytes); var comps = this.colorSpace.getRgbBuffer( this.getComponents(imgArray, decodeMap), bpc); @@ -225,8 +225,7 @@ var PDFImage = (function pdfImage() { // rows start at byte boundary; var rowBytes = (width * numComps * bpc + 7) >> 3; - this.image.reset(); - var imgArray = this.image.getBytes(height * rowBytes); + var imgArray = this.getImageBytes(height * rowBytes); var comps = this.getComponents(imgArray); var length = width * height; @@ -234,6 +233,12 @@ var PDFImage = (function pdfImage() { for (var i = 0; i < length; ++i) buffer[i] = comps[i]; }, + getImageBytes: function getImageBytes(length) { + if (!this.isReady()) + error('Image is not ready to be read.'); + this.image.reset(); + return this.image.getBytes(length); + }, isReady: function isReady() { return this.imageReady && this.smaskReady; }, @@ -250,3 +255,10 @@ var PDFImage = (function pdfImage() { }; return constructor; })(); +function loadJpegStream(id, imageData, objs) { + var img = new Image(); + img.onload = (function jpegImageLoaderOnload() { + objs.resolve(id, img); + }); + img.src = 'data:image/jpeg;base64,' + window.btoa(imageData); +} diff --git a/src/stream.js b/src/stream.js index e4732d87a..559fb2ca2 100644 --- a/src/stream.js +++ b/src/stream.js @@ -804,8 +804,6 @@ var JpegStream = (function jpegStream() { this.colorTransform = -1; - this.bytes = bytes; - 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