]> git.parisson.com Git - pdf.js.git/commitdiff
Implement paintReadyJpegXObject + add infrastructure to handle JpegStreams
authorJulian Viereck <julian.viereck@gmail.com>
Wed, 7 Sep 2011 21:45:38 +0000 (14:45 -0700)
committerJulian Viereck <julian.viereck@gmail.com>
Thu, 15 Sep 2011 15:24:29 +0000 (08:24 -0700)
pdf.js
worker.js
worker/handler.js

diff --git a/pdf.js b/pdf.js
index 7af3e6493197fd5f7f5fd6e9897d299efcff02aa..805122f9e695ebbaa2fa501864cfeff24ff89f19 100644 (file)
--- a/pdf.js
+++ b/pdf.js
@@ -859,6 +859,31 @@ var PredictorStream = (function() {
   return constructor;
 })();
 
+var JpegStreamIR = (function() {
+  function JpegStreamIR(objId, IR) {
+    var src = IR;
+
+    // create DOM image
+    var img = new Image();
+    img.onload = (function() {
+      this.loaded = true;
+      Objects[objId] = this;
+      if (this.onLoad)
+        this.onLoad();
+    }).bind(this);
+    img.src = src;
+    this.domImage = img;
+  }
+
+  JpegStreamIR.prototype = {
+    getImage: function() {
+      return this.domImage;
+    }
+  }
+
+  return JpegStreamIR;
+})()
+
 // A JpegStream can't be read directly. We use the platform to render
 // the underlying JPEG data for us.
 var JpegStream = (function() {
@@ -891,30 +916,23 @@ var JpegStream = (function() {
     newBytes.set(embedMarker, 2);
     return newBytes;
   }
-
+  
   function constructor(bytes, dict) {
     // TODO: per poppler, some images may have "junk" before that
     // need to be removed
     this.dict = dict;
-
+    
     if (isYcckImage(bytes))
       bytes = fixYcckImage(bytes);
 
-    // create DOM image
-    var img = new Image();
-    img.onload = (function() {
-      this.loaded = true;
-      if (this.onLoad)
-        this.onLoad();
-    }).bind(this);
-    img.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes));
-    this.domImage = img;
+    this.src = 'data:image/jpeg;base64,' + window.btoa(bytesToString(bytes)); 
   }
 
   constructor.prototype = {
-    getImage: function() {
-      return this.domImage;
+    getIR: function() {
+      return this.src;
     },
+
     getChar: function() {
       error('internal error: getChar is not valid on JpegStream');
     }
@@ -4100,6 +4118,8 @@ var EvalState = (function() {
 var FontsMap = {};
 var FontLoadedCounter = 0;
 
+var objIdCounter = 0;
+
 var PartialEvaluator = (function() {
   function constructor() {
     this.state = new EvalState();
@@ -4273,25 +4293,27 @@ var PartialEvaluator = (function() {
                                          fonts, images, uniquePrefix);
                 var matrix = xobj.dict.get('Matrix');
                 var bbox = xobj.dict.get('BBox');
-                args = [raw, matrix, bbox];
+                args = [ raw, matrix, bbox ];
                 fn = "paintReadyFormXObject";
-              }
-              if (xobj instanceof JpegStream) {
-                images.bind(xobj); // monitoring image load
-                // console.log("got xobj that is a JpegStream");
-              }
-              
-              if (xobj.dict.get('Subtype').name == "Image") {
-                // Check if we have an image that is not rendered by the platform.
-                // Needs to be rendered ourself.
-                if (!(xobj instanceof JpegStream)) {
-                  var image = xobj;
-                  var dict = image.dict;
-                  var w = dict.get('Width', 'W');
-                  var h = dict.get('Height', 'H');
-                  
+              } else if ('Image' == type.name) {
+                var image = xobj;
+                var dict = image.dict;
+                var w = dict.get('Width', 'W');
+                var h = dict.get('Height', 'H');
+
+                if (image instanceof JpegStream) {
+                  var objId = ++objIdCounter;
+                  images.push({
+                    id: objId,
+                    IR: image.getIR()
+                  });
+
+                  // TODO: Place dependency note in IR queue.
+                  fn = 'paintReadyJpegXObject';
+                  args = [ objId, w, h ];
+                } else {
+                  // Needs to be rendered ourself.
                   var inline = false;
-                  
                   var imageObj = new PDFImage(xref, resources, image, inline);
 
                   if (imageObj.imageMask) {
@@ -4308,12 +4330,10 @@ var PartialEvaluator = (function() {
                   
                   fn = "paintReadyImageXObject";
                   args = [ imgData ];
-                  
-                  // console.log("xobj subtype image", w, h, imageObj.imageMask);
                 }
+              } else {
+                error('Unhandled XObject subtype ' + type.name);
               }
-              // console.log("xobj subtype", xobj.dict.get('Subtype').name);
-
             }
           } else if (cmd == 'Tf') { // eagerly collect all fonts
             var fontName = args[0].name;
@@ -5533,6 +5553,24 @@ var CanvasGraphics = (function() {
       this.restore();
     },
 
+    paintReadyJpegXObject: function(objId, w, h) {
+      var image = Objects[objId];
+      if (!image) {
+        error("Dependent image isn't ready yet");
+      }
+
+      this.save();
+      
+      var ctx = this.ctx;
+      ctx.scale(1 / w, -1 / h);
+
+      var domImage = image.getImage();
+      ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height,
+                    0, -h, w, h);
+
+      this.restore();
+    },
+
     paintImageXObject: function(ref, image, inline) {
       this.save();
 
index dae87106cd6ecc0514b46f8e61077f6c05a5e068..55c18c8fc17836b07083e0984636b7ad8df5d64c 100644 (file)
--- a/worker.js
+++ b/worker.js
@@ -50,6 +50,9 @@ var WorkerPage = (function() {
   return constructor;
 })();
 
+// This holds a list of objects the IR queue depends on.
+var Objects = {};
+
 var WorkerPDFDoc = (function() {
   function constructor(data) {
     this.data = data;
@@ -60,7 +63,7 @@ var WorkerPDFDoc = (function() {
     
     this.pageCache = [];
     
-    var useWorker = true;
+    var useWorker = false;
     
     if (useWorker) {
       var worker = new Worker("../worker/boot.js");      
@@ -90,9 +93,27 @@ var WorkerPDFDoc = (function() {
                                   font.file.end - font.file.start, fontFileDict);
         font.file = new FlateStream(fontFile);
       }
-      
-      console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
-      page.startRenderingFromPreCompilation(data.preCompilation, data.fonts, data.images);
+    
+      var imageLoadingDone = function() {
+        console.log("startRenderingFromPreCompilation:", "numberOfFonts", fonts.length);
+        page.startRenderingFromPreCompilation(data.preCompilation, data.fonts, data.images);
+      }
+
+      var images = data.images;
+      if (images.length != 0) {
+        // Generate JpegStreams based on IR information and start rendering
+        // once the compilation is done.
+        var loader = new ImagesLoader();
+        loader.onLoad = imageLoadingDone;
+
+        for (var i = 0; i < images.length; i++) {
+          var image = images[i];
+          var stream = new JpegStreamIR(image.id, image.IR);
+          loader.bind(stream);
+        }
+      } else {
+        imageLoadingDone();
+      }
     }, this);
     
     if (!useWorker) {
index ca8413ede357abe130ae9c0de1d57791373c241b..4fcb8c1f7b307dee2247f1521124e6e25e0db25b 100644 (file)
@@ -22,8 +22,7 @@ var WorkerHandler = {
       // but stops at one point and sends the result back to the main thread.
       var gfx = new CanvasGraphics(null);
       var fonts = [];
-      // TODO: Figure out how image loading is handled inside the worker.
-      var images = new ImagesLoader();
+      var images = [];
 
       // Pre compile the pdf page and fetch the fonts/images.
       var preCompilation = page.preCompile(gfx, fonts, images);
@@ -76,9 +75,9 @@ var WorkerHandler = {
       handler.send("page", {
         pageNum:        pageNum,
         fonts:          fontsMin,
-        images:         [],
+        images:         images,
         preCompilation: preCompilation,
       });
     }, this);
   }
-}
\ No newline at end of file
+}