From f77070c4a4b6ae97a955f55e3b3e2b71e525bdaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wiercho=C5=82a?= Date: Fri, 30 Sep 2016 18:19:39 +0200 Subject: [PATCH 1/7] initial commit --- base/shared/util.js | 5 ++++- lib/imagedata.js | 13 +++++++++++++ lib/pdf.js | 4 +++- lib/pdfcanvas.js | 32 +++++++++++++++++++++++++++++--- 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 lib/imagedata.js diff --git a/base/shared/util.js b/base/shared/util.js index d7b3213d..95341827 100755 --- a/base/shared/util.js +++ b/base/shared/util.js @@ -145,8 +145,11 @@ var OPS = PDFJS.OPS = { //MQZ.Mar.22 Disabled Operators (to prevent image painting & annotation default appearance) //paintJpegXObject, paintImageMaskXObject, paintImageMaskXObjectGroup, paintImageXObject, paintInlineImageXObject, paintInlineImageXObjectGroup -var NO_OPS = PDFJS.NO_OPS = [82, 83, 84, 85, 86, 87]; +var NO_OPS = PDFJS.NO_OPS = []; // [82, 83, 84, 85, 86, 87]; var NO_OPS_RANGE = PDFJS.NO_OPS_RANGE = [78, 79, 80, 81]; //range pairs, all ops with each pair will be skipped. !important! +var HTMLElement = typeof HTMLElement === "undefined" ? + function() { } : HTMLElement; + // Use only for debugging purposes. This should not be used in any code that is // in mozilla master. diff --git a/lib/imagedata.js b/lib/imagedata.js new file mode 100644 index 00000000..2d02c0d7 --- /dev/null +++ b/lib/imagedata.js @@ -0,0 +1,13 @@ +function ImageData(width, height) { + if (width instanceof ImageData) { + this.width = width.width; + this.height = width.height; + this.data = width.data.slice(); + } else { + this.width = width; + this.height = height; + this.data = new Uint8Array(width * height * 4); + } +}; + +module.exports = ImageData; diff --git a/lib/pdf.js b/lib/pdf.js index d31a7626..fe1c35ca 100644 --- a/lib/pdf.js +++ b/lib/pdf.js @@ -5,6 +5,7 @@ let nodeUtil = require("util"), fs = require('fs'), _ = require('lodash'), DOMParser = require('xmldom').DOMParser, + ImageData = require('./imagedata.js'), PDFCanvas = require('./pdfcanvas.js'), PDFUnit = require('./pdfunit.js'), PDFField = require('./pdffield.js'), @@ -376,7 +377,8 @@ let PDFJSClass = (function () { // Content:pdfPage.getTextContent(), Texts: pageParser.Texts, Fields: pageParser.Fields, - Boxsets: pageParser.Boxsets + Boxsets: pageParser.Boxsets, + Images: pageParser.Images }; this.pages.push(page); diff --git a/lib/pdfcanvas.js b/lib/pdfcanvas.js index 6b94725e..c15df6d2 100644 --- a/lib/pdfcanvas.js +++ b/lib/pdfcanvas.js @@ -3,7 +3,8 @@ let nodeUtil = require("util"), _ = require('lodash'), PDFLine = require('./pdfline'), PDFFill = require('./pdffill'), - PDFFont = require('./pdffont'); + PDFFont = require('./pdffont'), + ImageData = require('./imagedata'); (function () { // private static @@ -144,6 +145,8 @@ let nodeUtil = require("util"), canvasTarget.Fills = []; if (!_.has(canvasTarget, "Texts") || !_.isArray(canvasTarget.Texts)) canvasTarget.Texts = []; + if (!_.has(canvasTarget, "Images") || !_.isArray(canvasTarget.Images)) + canvasTarget.Images = []; this.canvas = canvasTarget; @@ -387,8 +390,31 @@ let nodeUtil = require("util"), return gradient; }; - contextPrototype.drawImage = function (image, var_args) { - //MQZ. no image drawing support for now + contextPrototype.drawImage = function(image, sx, sy, swidth, sheight, x, y, width, height) { + if (image instanceof CanvasRenderingContext2D_) { + image.canvas.Images.forEach(oneImage => this.canvas.Images.push(oneImage)); + } else { + let oneImage = { + image: image, + width: width, + height: height + }; + this.canvas.Images.push(oneImage); + } + }; + + contextPrototype.putImageData = function(imgData, x, y, width, height) { + let oneImage = { + image: imgData, + width: width, + height: height + }; + this.canvas.Images.push(oneImage); + }; + + + contextPrototype.createImageData = function(width, height) { + return new ImageData(width, height); }; contextPrototype.getImageData = function (x, y, w, h) { From 8cd2fa78008550b88bc2fc5fecb03581bf1670fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wiercho=C5=82a?= Date: Wed, 5 Oct 2016 17:50:07 +0200 Subject: [PATCH 2/7] duplicates, invalid position but works --- base/display/api.js | 4 +-- base/shared/util.js | 4 +-- lib/pdfcanvas.js | 86 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/base/display/api.js b/base/display/api.js index 344cb20f..f1fd048f 100755 --- a/base/display/api.js +++ b/base/display/api.js @@ -862,8 +862,8 @@ var WorkerTransport = (function WorkerTransportClosure() { promise.resolve({ data: buf, width: width, height: height}); }).bind(this); //MQZ. Oct.17.2012 - disable image drawing -// img.src = imageUrl; - img.src = 'data:image/jpeg;base64,' + img.btoa(imageUrl); + img.src = imageUrl; +// img.src = 'data:image/jpeg;base64,' + img.btoa(imageUrl); }); }, diff --git a/base/shared/util.js b/base/shared/util.js index 95341827..573bdaf0 100755 --- a/base/shared/util.js +++ b/base/shared/util.js @@ -1232,9 +1232,9 @@ function loadJpegStream(id, imageUrl, objs) { img.onload = (function loadJpegStream_onloadClosure() { objs.resolve(id, img); }); -// img.src = imageUrl; + img.src = imageUrl; //MQZ. Apr.09.2013 calls windows.btoa safely - img.src = 'data:image/jpeg;base64,' + img.btoa(imageUrl); +// img.src = 'data:image/jpeg;base64,' + img.btoa(imageUrl); } //MQZ Oct.18.2013 expose util methods diff --git a/lib/pdfcanvas.js b/lib/pdfcanvas.js index c15df6d2..acafcd12 100644 --- a/lib/pdfcanvas.js +++ b/lib/pdfcanvas.js @@ -391,11 +391,68 @@ let nodeUtil = require("util"), }; contextPrototype.drawImage = function(image, sx, sy, swidth, sheight, x, y, width, height) { - if (image instanceof CanvasRenderingContext2D_) { - image.canvas.Images.forEach(oneImage => this.canvas.Images.push(oneImage)); + if (sx === undefined) { + sx = 0; + } + if (sy === undefined) { + sy = 0; + } + if (swidth === undefined) { + swidth = image.width; + } + if (sheight === undefined) { + sheight = image.height; + } + let crop = true; + if (x === undefined || y === undefined || width === undefined || height === undefined) { + x = sx; + y = sy; + width = swidth; + height = sheight; + crop = false; + } + if (image instanceof CanvasRenderingContext2D_) { + let canvasWidth = image.width, canvasHeight = image.height; + let scaleX = this.arcScaleX_ * canvasWidth / width, scaleY = this.arcScaleY_ * canvasHeight / height; + console.log("copy"); + image.canvas.Images.forEach(function(data) { + let oneImage = { + image: data.image, + crop: data.crop, + display: { + x: data.display.x * scaleX + x, + y: data.display.y * scaleY + y, + width: data.display.width * scaleX, + height: data.display.height * scaleY + }, + width: data.width, + height: data.height + }; + if (data.crop.crop && crop) { + data.crop = true; + data.crop.x = data.crop.x * scaleX + x, + data.crop.y = data.crop.y * scaleY + y, + data.crop.width = data.crop.width * scaleX, + data.crop.height = data.crop.height * scaleY + } + this.canvas.Images.push(oneImage) + }, this); } else { let oneImage = { image: image, + crop: { + crop: crop, + x: sx, + y: sy, + width: swidth, + height: sheight + }, + display: { + x: x, + y: y, + width: width, + height: height + }, width: width, height: height }; @@ -404,8 +461,33 @@ let nodeUtil = require("util"), }; contextPrototype.putImageData = function(imgData, x, y, width, height) { + if (x === undefined) { + x = 0; + } + if (y === undefined) { + y = 0; + } + if (width === undefined) { + width = imgData.width; + } + if (height === undefined) { + height = imgData.height; + } let oneImage = { image: imgData, + crop: { + crop: false, + x: 0, + y: 0, + width: width, + height: height + }, + display: { + x: x, + y: y, + width: width, + height: height + }, width: width, height: height }; From f23b32270c3478dfe09ae70795fe3d8d90720ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wiercho=C5=82a?= Date: Thu, 6 Oct 2016 13:53:25 +0200 Subject: [PATCH 3/7] KISS - minimal implementation, omit meta info --- base/display/canvas.js | 2 +- base/shared/util.js | 2 +- lib/imagedata.js | 2 +- lib/pdfcanvas.js | 123 ++++++++++------------------------------- 4 files changed, 31 insertions(+), 98 deletions(-) diff --git a/base/display/canvas.js b/base/display/canvas.js index 30fb0010..b9e9fac6 100755 --- a/base/display/canvas.js +++ b/base/display/canvas.js @@ -1847,7 +1847,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h); var tmpCtx = tmpCanvas.context; putBinaryImageData(tmpCtx, imgData); - + debugger; for (var i = 0, ii = map.length; i < ii; i++) { var entry = map[i]; ctx.save(); diff --git a/base/shared/util.js b/base/shared/util.js index 573bdaf0..a2a2de66 100755 --- a/base/shared/util.js +++ b/base/shared/util.js @@ -145,7 +145,7 @@ var OPS = PDFJS.OPS = { //MQZ.Mar.22 Disabled Operators (to prevent image painting & annotation default appearance) //paintJpegXObject, paintImageMaskXObject, paintImageMaskXObjectGroup, paintImageXObject, paintInlineImageXObject, paintInlineImageXObjectGroup -var NO_OPS = PDFJS.NO_OPS = []; // [82, 83, 84, 85, 86, 87]; +var NO_OPS = PDFJS.NO_OPS = [83, 84, 86, 87]; var NO_OPS_RANGE = PDFJS.NO_OPS_RANGE = [78, 79, 80, 81]; //range pairs, all ops with each pair will be skipped. !important! var HTMLElement = typeof HTMLElement === "undefined" ? function() { } : HTMLElement; diff --git a/lib/imagedata.js b/lib/imagedata.js index 2d02c0d7..a2351ea6 100644 --- a/lib/imagedata.js +++ b/lib/imagedata.js @@ -2,7 +2,7 @@ function ImageData(width, height) { if (width instanceof ImageData) { this.width = width.width; this.height = width.height; - this.data = width.data.slice(); + this.data = width.data; } else { this.width = width; this.height = height; diff --git a/lib/pdfcanvas.js b/lib/pdfcanvas.js index acafcd12..4079dcf6 100644 --- a/lib/pdfcanvas.js +++ b/lib/pdfcanvas.js @@ -106,6 +106,29 @@ let nodeUtil = require("util"), } } + function addImage(image, images) { + if(images.indexOf(image) !== -1) { + return; + } + if(images.find(function(im) { + if (im.src) { + return im.src === image.src; + } else if (image.data && im.data && im.data.length === image.data.length && im.width === image.width && im.height === image.height) { + if (image.data === im.data) { + return true; + } + return im.data.find(function(v,i) { + return v !== image.data[i]; + }) === undefined; + } else { + return false; + } + }) !== undefined) { + return; + } + images.push(image); + } + /** * This class implements CanvasRenderingContext2D interface as described by * the WHATWG. @@ -390,108 +413,18 @@ let nodeUtil = require("util"), return gradient; }; - contextPrototype.drawImage = function(image, sx, sy, swidth, sheight, x, y, width, height) { - if (sx === undefined) { - sx = 0; - } - if (sy === undefined) { - sy = 0; - } - if (swidth === undefined) { - swidth = image.width; - } - if (sheight === undefined) { - sheight = image.height; - } - let crop = true; - if (x === undefined || y === undefined || width === undefined || height === undefined) { - x = sx; - y = sy; - width = swidth; - height = sheight; - crop = false; - } + contextPrototype.drawImage = function(image) { if (image instanceof CanvasRenderingContext2D_) { - let canvasWidth = image.width, canvasHeight = image.height; - let scaleX = this.arcScaleX_ * canvasWidth / width, scaleY = this.arcScaleY_ * canvasHeight / height; - console.log("copy"); image.canvas.Images.forEach(function(data) { - let oneImage = { - image: data.image, - crop: data.crop, - display: { - x: data.display.x * scaleX + x, - y: data.display.y * scaleY + y, - width: data.display.width * scaleX, - height: data.display.height * scaleY - }, - width: data.width, - height: data.height - }; - if (data.crop.crop && crop) { - data.crop = true; - data.crop.x = data.crop.x * scaleX + x, - data.crop.y = data.crop.y * scaleY + y, - data.crop.width = data.crop.width * scaleX, - data.crop.height = data.crop.height * scaleY - } - this.canvas.Images.push(oneImage) + addImage(data, this.canvas.Images); }, this); } else { - let oneImage = { - image: image, - crop: { - crop: crop, - x: sx, - y: sy, - width: swidth, - height: sheight - }, - display: { - x: x, - y: y, - width: width, - height: height - }, - width: width, - height: height - }; - this.canvas.Images.push(oneImage); + addImage(image, this.canvas.Images); } }; - contextPrototype.putImageData = function(imgData, x, y, width, height) { - if (x === undefined) { - x = 0; - } - if (y === undefined) { - y = 0; - } - if (width === undefined) { - width = imgData.width; - } - if (height === undefined) { - height = imgData.height; - } - let oneImage = { - image: imgData, - crop: { - crop: false, - x: 0, - y: 0, - width: width, - height: height - }, - display: { - x: x, - y: y, - width: width, - height: height - }, - width: width, - height: height - }; - this.canvas.Images.push(oneImage); + contextPrototype.putImageData = function(image) { + addImage(image, this.canvas.Images); }; From 8cf780dfd3004c8c930569177379330758cbfc5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wiercho=C5=82a?= Date: Thu, 6 Oct 2016 13:56:00 +0200 Subject: [PATCH 4/7] remove debugger; --- base/display/canvas.js | 1 - 1 file changed, 1 deletion(-) diff --git a/base/display/canvas.js b/base/display/canvas.js index b9e9fac6..27d5fe6c 100755 --- a/base/display/canvas.js +++ b/base/display/canvas.js @@ -1847,7 +1847,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h); var tmpCtx = tmpCanvas.context; putBinaryImageData(tmpCtx, imgData); - debugger; for (var i = 0, ii = map.length; i < ii; i++) { var entry = map[i]; ctx.save(); From d1fa1dd4fd6ddc2444a1f819b21a0837fa71e1b8 Mon Sep 17 00:00:00 2001 From: webcarrot Date: Thu, 6 Oct 2016 14:02:17 +0200 Subject: [PATCH 5/7] format --- lib/pdfcanvas.js | 72 ++++++++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/pdfcanvas.js b/lib/pdfcanvas.js index 4079dcf6..8d2032d1 100644 --- a/lib/pdfcanvas.js +++ b/lib/pdfcanvas.js @@ -105,29 +105,35 @@ let nodeUtil = require("util"), return 'square'; } } - - function addImage(image, images) { - if(images.indexOf(image) !== -1) { - return; - } - if(images.find(function(im) { - if (im.src) { - return im.src === image.src; - } else if (image.data && im.data && im.data.length === image.data.length && im.width === image.width && im.height === image.height) { - if (image.data === im.data) { - return true; - } - return im.data.find(function(v,i) { - return v !== image.data[i]; - }) === undefined; - } else { - return false; - } - }) !== undefined) { - return; - } - images.push(image); - } + + function addImage(image, images) { + if(images.indexOf(image) !== -1) { + return; + } + if(images.find(function(im) { + if (im.src) { + return im.src === image.src; + } else if ( + image.data && + im.data && + im.data.length === image.data.length && + im.width === image.width && + im.height === image.height + ) { + if (image.data === im.data) { + return true; + } + return im.data.find(function(v,i) { + return v !== image.data[i]; + }) === undefined; + } else { + return false; + } + }) !== undefined) { + return; + } + images.push(image); + } /** * This class implements CanvasRenderingContext2D interface as described by @@ -169,7 +175,7 @@ let nodeUtil = require("util"), if (!_.has(canvasTarget, "Texts") || !_.isArray(canvasTarget.Texts)) canvasTarget.Texts = []; if (!_.has(canvasTarget, "Images") || !_.isArray(canvasTarget.Images)) - canvasTarget.Images = []; + canvasTarget.Images = []; this.canvas = canvasTarget; @@ -414,22 +420,22 @@ let nodeUtil = require("util"), }; contextPrototype.drawImage = function(image) { - if (image instanceof CanvasRenderingContext2D_) { - image.canvas.Images.forEach(function(data) { - addImage(data, this.canvas.Images); - }, this); - } else { - addImage(image, this.canvas.Images); - } + if (image instanceof CanvasRenderingContext2D_) { + image.canvas.Images.forEach(function(data) { + addImage(data, this.canvas.Images); + }, this); + } else { + addImage(image, this.canvas.Images); + } }; contextPrototype.putImageData = function(image) { - addImage(image, this.canvas.Images); + addImage(image, this.canvas.Images); }; contextPrototype.createImageData = function(width, height) { - return new ImageData(width, height); + return new ImageData(width, height); }; contextPrototype.getImageData = function (x, y, w, h) { From b46e1263111d31c7f66074623a64695069544600 Mon Sep 17 00:00:00 2001 From: webcarrot Date: Thu, 6 Oct 2016 14:05:13 +0200 Subject: [PATCH 6/7] add newline --- base/display/canvas.js | 1 + 1 file changed, 1 insertion(+) diff --git a/base/display/canvas.js b/base/display/canvas.js index 27d5fe6c..30fb0010 100755 --- a/base/display/canvas.js +++ b/base/display/canvas.js @@ -1847,6 +1847,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() { var tmpCanvas = CachedCanvases.getCanvas('inlineImage', w, h); var tmpCtx = tmpCanvas.context; putBinaryImageData(tmpCtx, imgData); + for (var i = 0, ii = map.length; i < ii; i++) { var entry = map[i]; ctx.save(); From 33c39da654b00deb366cf3c187b63a7a4481487b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Wiercho=C5=82a?= Date: Thu, 6 Oct 2016 14:34:20 +0200 Subject: [PATCH 7/7] no strict check --- lib/imagedata.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/imagedata.js b/lib/imagedata.js index a2351ea6..8f405b60 100644 --- a/lib/imagedata.js +++ b/lib/imagedata.js @@ -1,5 +1,5 @@ function ImageData(width, height) { - if (width instanceof ImageData) { + if (width && width instanceof Object) { this.width = width.width; this.height = width.height; this.data = width.data;