]> git.parisson.com Git - pdf.js.git/commitdiff
initial implementation of predictor
authorsbarman <sbarman@L3CWZ5T.(none)>
Fri, 17 Jun 2011 00:03:15 +0000 (17:03 -0700)
committersbarman <sbarman@L3CWZ5T.(none)>
Fri, 17 Jun 2011 00:03:15 +0000 (17:03 -0700)
pdf.js

diff --git a/pdf.js b/pdf.js
index 904ff3906fdaa9937a364690cff151251b3817a5..c2b8f160fb0d9cd91c36d6845d67da450f4fb841 100644 (file)
--- a/pdf.js
+++ b/pdf.js
@@ -230,7 +230,24 @@ var FlateStream = (function() {
         0x50007, 0x50017, 0x5000f, 0x00000
     ]), 5];
 
-    function constructor(stream) {
+    function constructor(stream, params) {
+        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;
+
+                this.pred = new FilterPredictor(this, predType, cols,      
+                        colors, bpc);
+            }
+        }
         this.stream = stream;
         this.dict = stream.dict;
         var cmf = stream.getByte();
@@ -506,6 +523,163 @@ var FlateStream = (function() {
     return constructor;
 })();
 
+var FilterPredictor = (function() {
+    function constructor(str, type, width, colors, bits) {
+        this.str = str;
+        this.type = type;
+        this.width = width;
+        this.colors = colors;
+        this.bits = bits;
+        
+        this.nVals = width * colors;
+        this.pixBytes = (colors * bits + 7) >> 3;
+        var rowBytes = (width * colors * bits + 7) >> 3;
+        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];
+        },
+        getNextLine: function() {
+            if (this.type >= 10) {
+                var curType = this.str.getRawByte();
+                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.getRawByte());
+
+            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 = rowBybtes; 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) {
+                        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 (curPred === 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))
+                    }
+                }
+            }
+            prevIdx = pixBytes;
+            return true;
+        }
+    };
+
+    return constructor;
+})();
+
 var DecryptStream = (function() {
     function constructor(str, fileKey, encAlgorithm, keyLength) {
         // TODO