]> git.parisson.com Git - pdf.js.git/commitdiff
inline images working
authorsbarman <sbarman@L3CWZ5T.(none)>
Thu, 4 Aug 2011 04:11:57 +0000 (21:11 -0700)
committersbarman <sbarman@L3CWZ5T.(none)>
Thu, 4 Aug 2011 04:11:57 +0000 (21:11 -0700)
pdf.js

diff --git a/pdf.js b/pdf.js
index fd92f41408df14418e1b307252cdefac26993438..b2aa776945fe569020abacfa105906bb7f565f1f 100644 (file)
--- a/pdf.js
+++ b/pdf.js
@@ -228,6 +228,13 @@ var DecodeStream = (function() {
       }
       return String.fromCharCode(this.buffer[this.pos++]);
     },
+    makeSubStream: function decodestream_makeSubstream(start, length, dict) {
+      var end = start + length;
+      while (this.bufferLength <= end && !this.eof) {
+        this.readBlock();
+      }
+      return new Stream(this.buffer, start, length, dict);
+    },
     skip: function decodestream_skip(n) {
       if (!n)
         n = 1;
@@ -2436,28 +2443,21 @@ var Parser = (function() {
       this.buf2 = this.lexer.getObj();
     },
     shift: function() {
-      if (this.inlineImg > 0) {
-        if (this.inlineImg < 2) {
-          this.inlineImg++;
-        } else {
-          // in a damaged content stream, if 'ID' shows up in the middle
-          // of a dictionary, we need to reset
-          this.inlineImg = 0;
-        }
-      } else if (IsCmd(this.buf2, 'ID')) {
-        this.lexer.skip(); // skip char after 'ID' command
-        this.inlineImg = 1;
-      }
-      this.buf1 = this.buf2;
-      // don't buffer inline image data
-      this.buf2 = (this.inlineImg > 0) ? null : this.lexer.getObj();
+      if (IsCmd(this.buf2, 'ID')) {
+        this.buf1 = this.buf2;
+        this.buf2 = null;
+        // skip byte after ID
+        this.lexer.skip();
+      } else {
+        this.buf1 = this.buf2;
+        this.buf2 = this.lexer.getObj();
+     }
     },
     getObj: function(cipherTransform) {
-      // refill buffer after inline image data
-      if (this.inlineImg == 2)
-        this.refill();
-
-      if (IsCmd(this.buf1, '[')) { // array
+      if (IsCmd(this.buf1, 'BI')) { // inline image
+        this.shift();
+        return this.makeInlineImage(cipherTransform);
+      } else if (IsCmd(this.buf1, '[')) { // array
         this.shift();
         var array = [];
         while (!IsCmd(this.buf1, ']') && !IsEOF(this.buf1))
@@ -2472,7 +2472,6 @@ var Parser = (function() {
         while (!IsCmd(this.buf1, '>>') && !IsEOF(this.buf1)) {
           if (!IsName(this.buf1)) {
             error('Dictionary key must be a name object');
-            shift();
           } else {
             var key = this.buf1.name;
             this.shift();
@@ -2492,7 +2491,6 @@ var Parser = (function() {
           this.shift();
         }
         return dict;
-
       } else if (IsInt(this.buf1)) { // indirect reference or integer
         var num = this.buf1;
         this.shift();
@@ -2516,6 +2514,46 @@ var Parser = (function() {
       this.shift();
       return obj;
     },
+    makeInlineImage: function(cipherTransform) {
+      var lexer = this.lexer;
+      var stream = lexer.stream;
+
+      // parse dictionary
+      var dict = new Dict();
+      while (!IsCmd(this.buf1, 'ID') && !IsEOF(this.buf1)) {
+        if (!IsName(this.buf1)) {
+          error('Dictionary key must be a name object');
+        } else {
+          var key = this.buf1.name;
+          this.shift();
+          if (IsEOF(this.buf1))
+            break;
+          dict.set(key, this.getObj(cipherTransform));
+        }
+      }
+
+      // parse image stream
+      var startPos = stream.pos;
+
+      var c1 = stream.getChar();
+      var c2 = stream.getChar();
+      while (!(c1 == 'E' && c2 == 'I') && c2 != null) {
+        c1 = c2;
+        c2 = stream.getChar();
+      }
+
+      var length = (stream.pos - 2) - startPos;
+      var imageStream = stream.makeSubStream(startPos, length, dict);
+      if (cipherTransform)
+        imageStream = cipherTransform.createStream(imageStream);
+      imageStream = this.filter(imageStream, dict, length);
+      imageStream.parameters = dict;
+
+      this.buf2 = new Cmd('EI');
+      this.shift();
+
+      return imageStream;
+    },
     makeStream: function(dict, cipherTransform) {
       var lexer = this.lexer;
       var stream = lexer.stream;
@@ -2577,15 +2615,14 @@ var Parser = (function() {
           return new PredictorStream(new FlateStream(stream), params);
         }
         return new FlateStream(stream);
-      } else if (name == 'DCTDecode') {
+      } else if (name == 'DCTDecode' || name == 'DCT') {
         var bytes = stream.getBytes(length);
         return new JpegStream(bytes, stream.dict);
-      } else if (name == 'ASCII85Decode') {
+      } else if (name == 'ASCII85Decode' || name == 'A85') {
         return new Ascii85Stream(stream);
-      } else if (name == 'ASCIIHexDecode') {
+      } else if (name == 'ASCIIHexDecode' || name == 'AHx') {
         return new AsciiHexStream(stream);
-      } else if (name == 'CCITTFaxDecode') {
-        TODO('implement fax stream');
+      } else if (name == 'CCITTFaxDecode' || name == 'CCF') {
         return new CCITTFaxStream(stream, params);
       } else {
         error("filter '" + name + "' not supported yet");
@@ -3551,6 +3588,8 @@ var PartialEvaluator = (function() {
 
     // Images
     BI: 'beginInlineImage',
+    ID: 'beginImageData',
+    EI: 'endInlineImage',
 
     // XObjects
     Do: 'paintXObject',
@@ -3579,6 +3618,9 @@ var PartialEvaluator = (function() {
         if (IsCmd(obj)) {
           var cmd = obj.cmd;
           var fn = OP_MAP[cmd];
+          if (!fn) {
+            log('blah');
+          }
           assertWellFormed(fn, "Unknown command '" + cmd + "'");
           // TODO figure out how to type-check vararg functions
 
@@ -4438,11 +4480,13 @@ var CanvasGraphics = (function() {
 
     // Images
     beginInlineImage: function() {
-      TODO('inline images');
-      error('(Stream will not be parsed properly, bailing now)');
-      // Like an inline stream:
-      //  - key/value pairs up to Cmd(ID)
-      //  - then image data up to Cmd(EI)
+      error('Should not call beginInlineImage');
+    },
+    beginImageData: function() {
+      error('Should not call beginImageData');
+    },
+    endInlineImage: function(image) {
+      this.paintImageXObject(null, image, true);
     },
 
     // XObjects