]> git.parisson.com Git - pdf.js.git/commitdiff
Merge branch 'master' into predictor
authorsbarman <sbarman@L3CWZ5T.(none)>
Tue, 21 Jun 2011 00:51:38 +0000 (17:51 -0700)
committersbarman <sbarman@L3CWZ5T.(none)>
Tue, 21 Jun 2011 00:51:38 +0000 (17:51 -0700)
Conflicts:
pdf.js

1  2 
pdf.js

diff --cc pdf.js
index e086b82c48ac8ae67a7e987093ee21bd97e7e200,40044300cd0ce6b35356f20e2ce52eae7544952e..488db9a9a4998a57cba7d3f1d7aa4b992492a44e
--- 1/pdf.js
--- 2/pdf.js
+++ b/pdf.js
@@@ -509,224 -525,69 +526,273 @@@ var FlateStream = (function() 
  
      return constructor;
  })();
++/*
 +var FilterPredictor = (function() {
 +    function constructor(str, type, width, colors, bits) {
 +        this.str = str;
 +        this.dict = str.dict;
 +
 +        this.type = type;
 +        this.width = width;
 +        this.colors = colors;
 +        this.bits = bits;
 +        
 +        this.nVals = width * colors;
 +        var pixBytes = (colors * bits + 7) >> 3;
 +        this.pixBytes = pixBytes;
 +        var rowBytes = ((width * colors * bits + 7) >> 3) + pixBytes;
 +        this.rowBytes = rowBytes;
 +
 +        if (width < 0 || colors < 0 || bits < 0 ||bits > 16)
 +            error("Invalid predictor");
 +        
 +        var prevLine = [];
 +        for (var i = 0; i < rowBytes; ++i)
 +            prevLine.push(0);
 +        this.prevLine = prevLine;
 +        this.prevIdx = rowBytes;
 +    }
 +
 +    constructor.prototype = {
 +        getByte: function() {
 +            if (this.prevIdx >= this.rowBytes) {
 +                if(!this.getNextLine())
 +                    return;
 +            }
 +            return this.prevLine[this.prevIdx++];
 +        },
 +        getBytes: function(length) {
 +            var buf = new Uint8Array(length);
 +            for (var i = 0; i < length; ++i)
 +                buf[i] = this.getByte();
 +            return buf;
 +        },
 +        getNextLine: function() {
 +            if (this.type >= 10) {
 +                var curType = this.str.getByte();
 +                if (!curType)
 +                    return;
 +                curType += 10;
 +            } else {
 +                var curType = this.type;
 +            }
 +
 +            var line = [];
 +            for (var i = 0; i < this.rowBytes - this.pixBytes; i++)
 +                line.push(this.str.getByte());
 +
 +            var pixBytes = this.pixBytes;
 +            var rowBytes = this.rowBytes;
 +            var prevLine = this.prevLine;
 +
 +            var upLeftBuf = [];
 +            for (var i = 0, ii = pixBytes + 1; i < ii; ++i)
 +                upLeftBuf.push(0);
 +            
 +            for (var i = pixBytes, ii = rowBytes + pixBytes + 1; i < ii; ++i) {
 +                for (var j = pixBytes; j > 0; --j) {
 +                    upLeftBuf[j] = upLeftBuf[j - 1];
 +                }
 +                upLeftBuf[0] = prevLine[i];
 +
 +                var c = line[i - pixBytes];
 +                if (c == undefined) {
 +                    if (i > pixBytes)
 +                        break;
 +                    return;
 +                }
 +                switch (curType) {
 +                case 11:
 +                    prevLine[i] = prevLine[i - pixBytes] + c;
 +                    break;
 +                case 12:
 +                    prevLine[i] = prevLine[i] + c;
 +                    break;
 +                case 13:
 +                    prevLine[i] = ((prevLine[i - pixBytes] 
 +                                + prevLine[i]) >> 1) + c;
 +                    break;
 +                case 14:
 +                    var left = prevLine[i - pixBytes];
 +                    var up = prevLine[i];
 +                    var upLeft = upLeftBuf[pixBytes];
 +                    var p = left + up - upLeft;
 +
 +                    var pa = p - left;
 +                    if (pa < 0)
 +                        pa = -pa;
 +                    var pb = p - up;
 +                    if (pb < 0)
 +                        pb = -pb;
 +                    var pc = p - upLeft;
 +                    if (pc < 0)
 +                        pc = -pc;
 +
 +                    if (pa <= pb && pa <= pc)
 +                        prevLine[i] = left + c;
 +                    else if (pb <= pc)
 +                        prevLine[i] = up + c;
 +                    else
 +                        prevLine[i] = upLeft + c;
 +                    break;
 +                case 10:
 +                default:
 +                    prevLine[i] = c;
 +                    break;
 +                }
 +            }
 +            var bits = this.bits;
 +            var colors = this.colors;
  
 +            if (curType === 2) {
 +                if (bits === 1) {
 +                    var inbuf = prevLine[pixBytes - 1];
 +                    for (var i = pixBytes; i < rowBytes; i+= 8) {
 +                        inBuf = (inBuf << 8) | prevLine[i];
 +                        prevLine[i] ^= inBuf >> colors; 
 +                    }
 +                } else if (bits === 8) {
 +                    for (var i = pixBytes; i < rowBytes; ++i)
 +                        prevLine[i] += prevLine[i - colors];
 +                } else {
 +                    for (var i = 0, ii = colors + 1; i < ii; ++i)
 +                        upLeftBuf[i] = 0;
 +                    var bitMask = (1 << bits) - 1;
 +                    var inbuf = 0, outbut = 0;
 +                    var inbits = 0, outbits = 0;
 +                    var j = pixBytes, k = pixBytes;
 +                    var width = this.width;
 +                    for (var i = 0; i < width; ++i) {
 +                        for (var kk = 0; kk < colors; ++kk) {
 +                            if (inbits < bits) {
 +                                inbuf = (inbuf << 8) | (prevLine[j++] & 255);
 +                                inbits += 8;
 +                            }
 +                            upLeftBuf[kk] = (upLeftBuf[kk] + (inbuf >> 
 +                                        (inbits - bits))) & bitMask;
 +                            inbits -= bits;
 +                            outbuf = (outbuf << bits) | upLeftBuf[kk];
 +                            outbits += bits;
 +                            if (outbits >= 8) {
 +                                prevLine[k++] = (outbuf >> (outbits - 8));
 +                                outbits -= 8;
 +                            }
 +                        }
 +                    }
 +                    if (outbits > 0) {
 +                        prevLine[k++] = (outbuf << (8 - outbits)) +
 +                            (inbuf & ((1 << (8 - outbits)) - 1))
 +                    }
 +                }
 +            }
 +            this.prevIdx = pixBytes;
 +            return true;
 +        }
 +    };
 +    return constructor;
 +})();
++*/
+ // A JpegStream can't be read directly. We use the platform to render the underlying
+ // JPEG data for us.
+ var JpegStream = (function() {
+     function constructor(bytes, dict) {
+         // TODO: per poppler, some images may have "junk" before that need to be removed
+         this.dict = dict;
+         // create DOM image
+         var img = new Image();
+         img.src = "data:image/jpeg;base64," + window.btoa(bytesToString(bytes));
+         this.domImage = img;
+     }
+     constructor.prototype = {
++        getByte: function() {
++            // dummy method to pass IsStream test
++            error("shouldnt be called");
++        },
+         getImage: function() {
+             return this.domImage;
+         }
+     };
+     return constructor;
+ })();
  var PredictorStream = (function() {
      function constructor(stream, params) {
-         this.stream = stream;
-         this.predictor = params.get("Predictor") || 1;
-         if (this.predictor <= 1) {
++        var predictor = params.get("Predictor") || 1;
++        this.predictor = predictor;
++    
++        if (predictor <= 1)
 +            return stream; // no prediction
-         }
++        if (predictor !== 2 && (predictor < 10 || predictor > 15))
++            error("Unsupported predictor");
++        
++        if (predictor === 2)
++            this.readRow = this.readRowTiff;
++        else
++            this.readRow = this.readRowPng;
++
+         this.stream = stream;
+         this.dict = stream.dict;
 -        this.predictor = params.get("Predictor") || 1;
 -        if (this.predictor <= 1) {
 -            return stream; // no prediction
 -        }
          if (params.has("EarlyChange")) {
              error("EarlyChange predictor parameter is not supported");
          }
--        this.colors = params.get("Colors") || 1;
--        this.bitsPerComponent = params.get("BitsPerComponent") || 8;
--        this.columns = params.get("Columns") || 1;
-         if (this.bitsPerComponent !== 8) {
-             error("Multi-byte predictors are not supported");
 -        if (this.colors !== 1 || this.bitsPerComponent !== 8) {
 -            error("Multi-color and multi-byte predictors are not supported");
--        }
--        if (this.predictor < 10 || this.predictor > 15) {
--            error("Unsupported predictor");
--        }
-         this.currentRow = new Uint8Array(this.columns * this.colors);
 -        this.currentRow = new Uint8Array(this.columns);
--        this.pos = 0;
--        this.bufferLength = 0;
++        var colors = params.get("Colors") || 1;
++        this.colors = colors;
++        var bits = params.get("BitsPerComponent") || 8;
++        this.bits = bits;
++        var columns = params.get("Columns") || 1;
++        this.columns = columns;
++        
++        var pixBytes = (colors * bits + 7) >> 3;
++        this.pixBytes = pixBytes;
++        // add an extra pixByte to represent the pixel left column 0
++        var rowBytes = ((columns * colors * bits + 7) >> 3) + pixBytes;
++        this.rowBytes = rowBytes;
++
++        this.currentRow = new Uint8Array(rowBytes);
++        this.pos = rowBytes;
      }
  
      constructor.prototype = {
--        readRow : function() {
--            var lastRow = this.currentRow;
-             var colors = this.colors;
++        readRowTiff : function() {
++        },
++        readRowPng : function() {
++            // swap the buffers
++            var currentRow = this.currentRow;
++
++            var rowBytes = this.rowBytes;
++            var pixBytes = this.pixBytes;
++
              var predictor = this.stream.getByte();
-             var currentRow = this.stream.getBytes(this.columns * colors), i;
 -            var currentRow = this.stream.getBytes(this.columns), i;
++            var rawBytes = this.stream.getBytes(rowBytes - pixBytes);
++            var i;
++
              switch (predictor) {
--            default:
--                error("Unsupported predictor");
--                break;
              case 0:
                  break;
-                 for (i = colors; i < currentRow.length; ++i) {
-                   currentRow[i] = (currentRow[i - colors] + currentRow[i]) & 0xFF;
-                 }
 +            case 1:
++                for (i = pixBytes; i < rowBytes; ++i)
++                  currentRow[i] = (currentRow[i - pixBytes] + rawBytes[i]) & 0xFF;
 +                break;
              case 2:
--                for (i = 0; i < currentRow.length; ++i) {
--                  currentRow[i] = (lastRow[i] + currentRow[i]) & 0xFF;
-                 }
++                for (i = pixBytes; i < rowBytes; ++i)
++                  currentRow[i] = (currentRow[i] + rawBytes[i]) & 0xFF;
 +                break;
 +            case 3:
-                 for (i = 0; i < color; ++i) {
-                   currentRow[i] = ((lastRow[i] >> 1) + currentRow[i]) & 0xFF;
-                 }
-                 for (; i < currentRow.length; ++i) {
-                   currentRow[i] = (((lastRow[i] + currentRow[i]) >> 1) + currentRow[i]) & 0xFF;
++                for (i = pixBytes; i < rowBytes; ++i)
++                  currentRow[i] = (((currentRow[i] + currentRow[i - pixBytes])
++                              >> 1) + rawBytes[i]) & 0xFF;
++                break;
++            case 4:
++                for (i = pixBytes; i < rowBytes; ++i) {
++                    var left = currentRow[i - pixBytes];
++                    var up = currentRow[i];
++                    var upLeft = 
                  }
++            default:
++                error("Unsupported predictor");
                  break;
              }
              this.pos = 0;
@@@ -1387,29 -1242,8 +1453,29 @@@ var Parser = (function() 
              }
              return stream;
          },
-         makeFilter: function(stream, name, params) {
+         makeFilter: function(stream, name, length, params) {
              if (name == "FlateDecode" || name == "Fl") {
-                 var flateStr = new FlateStream(stream);
++/*                var flateStr = new FlateStream(stream);
 +                if (IsDict(params)) {
 +                    var predType = params.get("Predictor");
 +                    if (predType && predType > 1) {
 +                        var colors = params.get("Colors");
 +                        if (!colors)
 +                            colors = 1;
 +                        var bpc = params.get("BitsPerComponent");
 +                        if (!bpc)
 +                            bpc = 8;
 +                        var cols = params.get("Columns");
 +                        if (!cols)
 +                            cols = 1;
 +
 +                        log("Predictor being used");
 +                        flateStr = new FilterPredictor(flateStr, predType, cols,      
 +                                colors, bpc);
 +                    }
 +                }
 +                return flateStr;
-                 /*
++*/              
                  if (params) {
                      return new PredictorStream(new FlateStream(stream), params);
                  }