From 60989ee3b9e9fc590de5153490e4d288eb61b3ae Mon Sep 17 00:00:00 2001 From: sbarman Date: Thu, 16 Jun 2011 17:03:15 -0700 Subject: [PATCH 01/11] initial implementation of predictor --- pdf.js | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 904ff3906..c2b8f160f 100644 --- 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 From ce09870e2b9e1420d33af3be3b2bc076383ed233 Mon Sep 17 00:00:00 2001 From: sbarman Date: Fri, 17 Jun 2011 13:32:26 -0700 Subject: [PATCH 02/11] Rearranged predictor interface --- pdf.js | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/pdf.js b/pdf.js index 256e56adf..b591c20f1 100644 --- a/pdf.js +++ b/pdf.js @@ -232,23 +232,6 @@ var FlateStream = (function() { ]), 5]; 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(); @@ -1297,9 +1280,25 @@ var Parser = (function() { }, makeFilter: function(stream, name, params) { if (name == "FlateDecode" || name == "Fl") { - if (params) - error("params not supported yet for FlateDecode"); - return 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; + + flateStr = new FilterPredictor(flateStr, predType, cols, + colors, bpc); + } + } + return flateStr; } else { error("filter '" + name + "' not supported yet"); } From 3da5245abfa43482e2ebe55dad67ef3d99bb102a Mon Sep 17 00:00:00 2001 From: sbarman Date: Fri, 17 Jun 2011 16:06:02 -0700 Subject: [PATCH 03/11] Working version of predictors --- pdf.js | 154 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 72 deletions(-) diff --git a/pdf.js b/pdf.js index b591c20f1..e39fcf6ff 100644 --- a/pdf.js +++ b/pdf.js @@ -18,6 +18,7 @@ function warn(msg) { } function error(msg) { + console.trace(); throw new Error(msg); } @@ -231,7 +232,7 @@ var FlateStream = (function() { 0x50007, 0x50017, 0x5000f, 0x00000 ]), 5]; - function constructor(stream, params) { + function constructor(stream) { this.stream = stream; this.dict = stream.dict; var cmf = stream.getByte(); @@ -510,6 +511,8 @@ var FlateStream = (function() { 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; @@ -536,11 +539,17 @@ var FilterPredictor = (function() { if(!this.getNextLine()) return; } - return this.prevLine[this.prevIdx]; + 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.getRawByte(); + var curType = this.str.getByte(); if (!curType) return; curType += 10; @@ -550,7 +559,7 @@ var FilterPredictor = (function() { var line = []; for (var i = 0; i < this.rowBytes - this.pixBytes; i++) - line.push(this.str.getRawByte()); + line.push(this.str.getByte()); var pixBytes = this.pixBytes; var rowBytes = this.rowBytes; @@ -560,62 +569,62 @@ var FilterPredictor = (function() { for (var i = 0, ii = pixBytes + 1; i < ii; ++i) upLeftBuf.push(0); - for (var i = pixBytes, ii = rowBybtes; i < ii; ++i) { + for (var i = pixBytes, ii = rowBytes; i < ii; ++i) { for (var j = pixBytes; j > 0; --j) { upLeftBuf[j] = upLeftBuf[j - 1]; - upLeftBuf[0] = prevLine[i]; + } + 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; + var c = line[i - pixBytes]; + if (c == undefined) { + if (i > pixBytes) 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; + 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) + 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; + 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; - } + 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 (curType === 2) { if (bits === 1) { var inbuf = prevLine[pixBytes - 1]; for (var i = pixBytes; i < rowBytes; i+= 8) { @@ -656,7 +665,7 @@ var FilterPredictor = (function() { } } } - prevIdx = pixBytes; + this.prevIdx = pixBytes; return true; } }; @@ -680,9 +689,9 @@ var Name = (function() { } constructor.prototype = { - toString: function() { - return this.name; - } + toString: function() { + return this.name; + } }; return constructor; @@ -694,9 +703,9 @@ var Cmd = (function() { } constructor.prototype = { - toString: function() { - return this.cmd; - } + toString: function() { + return this.cmd; + } }; return constructor; @@ -709,18 +718,18 @@ var Dict = (function() { constructor.prototype = { get: function(key) { - return this.map[key]; - }, - get2: function(key1, key2) { - return this.get(key1) || this.get(key2); - }, - has: function(key) { - return key in this.map; - }, - set: function(key, value) { - this.map[key] = value; - }, - forEach: function(aCallback) { + return this.map[key]; + }, + get2: function(key1, key2) { + return this.get(key1) || this.get(key2); + }, + has: function(key) { + return key in this.map; + }, + set: function(key, value) { + this.map[key] = value; + }, + forEach: function(aCallback) { for (var key in this.map) aCallback(key, this.map[key]); }, @@ -784,7 +793,7 @@ function IsArray(v) { } function IsStream(v) { - return typeof v == "object" && "getChar" in v; + return typeof v == "object" && "getByte" in v; } function IsRef(v) { @@ -1294,6 +1303,7 @@ var Parser = (function() { if (!cols) cols = 1; + log("Predictor being used"); flateStr = new FilterPredictor(flateStr, predType, cols, colors, bpc); } @@ -2529,7 +2539,7 @@ var CanvasGraphics = (function() { var smask = image.dict.get("SMask"); smask = xref.fetchIfRef(smask); - if (IsStream(smask)) { + if (smask) { if (inline) error("cannot combine smask and inlining"); @@ -2559,8 +2569,6 @@ var CanvasGraphics = (function() { if (maskDecode) TODO("Handle mask decode"); // handle matte object - } else { - smask = null; } var tmpCanvas = document.createElement("canvas"); @@ -2573,7 +2581,7 @@ var CanvasGraphics = (function() { if (bitsPerComponent != 8) error("unhandled number of bits per component"); - if (smask) { + if (false && smask) { if (maskColorSpace.numComps != 1) error("Incorrect number of components in smask"); @@ -2711,6 +2719,8 @@ var ColorSpace = (function() { case "DeviceGray": case "G": this.numComps = 1; + case "DeviceRGB": + this.numComps = 3; break; } TODO("fill in color space constructor"); From ab6ff77b41a463f89507018ad4ddf3eacc18e93b Mon Sep 17 00:00:00 2001 From: sbarman Date: Sat, 18 Jun 2011 13:06:54 -0700 Subject: [PATCH 04/11] Fixed predictor --- pdf.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/pdf.js b/pdf.js index b75ce91ec..6a1589dde 100644 --- a/pdf.js +++ b/pdf.js @@ -519,8 +519,9 @@ var FilterPredictor = (function() { this.bits = bits; this.nVals = width * colors; - this.pixBytes = (colors * bits + 7) >> 3; - var rowBytes = (width * colors * bits + 7) >> 3; + 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) @@ -569,7 +570,7 @@ var FilterPredictor = (function() { for (var i = 0, ii = pixBytes + 1; i < ii; ++i) upLeftBuf.push(0); - for (var i = pixBytes, ii = rowBytes; i < ii; ++i) { + for (var i = pixBytes, ii = rowBytes + pixBytes + 1; i < ii; ++i) { for (var j = pixBytes; j > 0; --j) { upLeftBuf[j] = upLeftBuf[j - 1]; } @@ -2118,7 +2119,7 @@ var CanvasGraphics = (function() { var widths = xref.fetchIfRef(fontDict.get("Widths")); var firstChar = xref.fetchIfRef(fontDict.get("FirstChar")); - assertWellFormed(IsArray(widths) && IsInteger(firstChar), + assertWellFormed(IsArray(widths) && IsInt(firstChar), "invalid font Widths or FirstChar"); var charset = []; for (var j = 0; j < widths.length; j++) { @@ -2775,9 +2776,9 @@ var CanvasGraphics = (function() { if (bitsPerComponent != 8) error("unhandled number of bits per component"); - if (false && smask) { - if (maskColorSpace.numComps != 1) - error("Incorrect number of components in smask"); + if (smask) { + //if (maskColorSpace.numComps != 1) + // error("Incorrect number of components in smask"); var numComps = colorSpace.numComps; var imgArray = image.getBytes(numComps * w * h); From 11408201180c25f45071c3527aac7b66049edaa3 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Sun, 19 Jun 2011 23:23:21 -0500 Subject: [PATCH 05/11] Multi-color predictor; row predictor for sub and average --- pdf.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/pdf.js b/pdf.js index a051e57f3..f22d7c70d 100644 --- a/pdf.js +++ b/pdf.js @@ -522,13 +522,13 @@ var PredictorStream = (function() { this.colors = params.get("Colors") || 1; this.bitsPerComponent = params.get("BitsPerComponent") || 8; this.columns = params.get("Columns") || 1; - if (this.colors !== 1 || this.bitsPerComponent !== 8) { - error("Multi-color and multi-byte predictors are not supported"); + if (this.bitsPerComponent !== 8) { + error("Multi-byte predictors are not supported"); } if (this.predictor < 10 || this.predictor > 15) { error("Unsupported predictor"); } - this.currentRow = new Uint8Array(this.columns); + this.currentRow = new Uint8Array(this.columns * this.colors); this.pos = 0; this.bufferLength = 0; } @@ -536,19 +536,33 @@ var PredictorStream = (function() { constructor.prototype = { readRow : function() { var lastRow = this.currentRow; + var colors = this.colors; var predictor = this.stream.getByte(); - var currentRow = this.stream.getBytes(this.columns), i; + var currentRow = this.stream.getBytes(this.columns * colors), i; switch (predictor) { default: error("Unsupported predictor"); break; case 0: break; + case 1: + for (i = colors; i < currentRow.length; ++i) { + currentRow[i] = (currentRow[i - colors] + currentRow[i]) & 0xFF; + } + break; case 2: for (i = 0; i < currentRow.length; ++i) { currentRow[i] = (lastRow[i] + currentRow[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; + } + break; } this.pos = 0; this.bufferLength = currentRow.length; From 4635091c43d714a136b4d1752a7c249b34074bff Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 19:51:36 -0700 Subject: [PATCH 06/11] working implementation of png and tiff predictors --- pdf.js | 105 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 14 deletions(-) diff --git a/pdf.js b/pdf.js index 488db9a9a..1e112e9ee 100644 --- a/pdf.js +++ b/pdf.js @@ -752,14 +752,66 @@ var PredictorStream = (function() { this.rowBytes = rowBytes; this.currentRow = new Uint8Array(rowBytes); + this.bufferLength = rowBytes; this.pos = rowBytes; } constructor.prototype = { readRowTiff : function() { + var currentRow = this.currentRow; + var rowBytes = this.rowBytes; + var pixBytes = this.pixBytes; + var bits = this.bits; + var colors = this.colors; + + var rawBytes = this.stream.getBytes(rowBytes - pixBytes); + + if (bits === 1) { + var inbuf = 0; + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) { + var c = rawBytes[j]; + inBuf = (inBuf << 8) | c; + // bitwise addition is exclusive or + // first shift inBuf and then add + currentRow[i] = (c ^ (inBuf >> colors)) & 0xFF; + // truncate inBuf (assumes colors < 16) + inBuf &= 0xFFFF; + } + } else if (bits === 8) { + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) + currentRow[i] = currentRow[i - colors] + rawBytes[j]; + } else { + var compArray = new Uint8Array(colors + 1); + var bitMask = (1 << bits) - 1; + var inbuf = 0, outbut = 0; + var inbits = 0, outbits = 0; + var j = 0, k = pixBytes; + var columns = this.columns; + for (var i = 0; i < columns; ++i) { + for (var kk = 0; kk < colors; ++kk) { + if (inbits < bits) { + inbuf = (inbuf << 8) | (rawBytes[j++] & 0xFF); + inbits += 8; + } + compArray[kk] = (compArray[kk] + (inbuf >> + (inbits - bits))) & bitMask; + inbits -= bits; + outbuf = (outbuf << bits) | compArray[kk]; + outbits += bits; + if (outbits >= 8) { + currentRow[k++] = (outbuf >> (outbits - 8)) & 0xFF; + outbits -= 8; + } + } + } + if (outbits > 0) { + currentRow[k++] = (outbuf << (8 - outbits)) + + (inbuf & ((1 << (8 - outbits)) - 1)) + } + } + this.pos = pixBytes; }, readRowPng : function() { - // swap the buffers var currentRow = this.currentRow; var rowBytes = this.rowBytes; @@ -773,31 +825,56 @@ var PredictorStream = (function() { case 0: break; case 1: - for (i = pixBytes; i < rowBytes; ++i) - currentRow[i] = (currentRow[i - pixBytes] + rawBytes[i]) & 0xFF; + // set the first pixel + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) + currentRow[i] = (currentRow[i - pixBytes] + rawBytes[j]) & 0xFF; break; case 2: - for (i = pixBytes; i < rowBytes; ++i) - currentRow[i] = (currentRow[i] + rawBytes[i]) & 0xFF; + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) + currentRow[i] = (currentRow[i] + rawBytes[j]) & 0xFF; break; case 3: - for (i = pixBytes; i < rowBytes; ++i) - currentRow[i] = (((currentRow[i] + currentRow[i - pixBytes]) - >> 1) + rawBytes[i]) & 0xFF; + // set the first pixel + for (i = pixBytes, j = 0; i < rowBytes; ++i, ++j) + currentRow[i] = (((currentRow[i] + currentRow[i - pixBytes]) + >> 1) + rawBytes[j]) & 0xFF; break; case 4: - for (i = pixBytes; i < rowBytes; ++i) { + // we need to save the up left pixels values. the simplest way + // is to create a new buffer + var lastRow = currentRow; + var currentRow = new Uint8Array(rowBytes); + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) { + var up = lastRow[i]; + var upLeft = lastRow[i - pixBytes]; var left = currentRow[i - pixBytes]; - var up = currentRow[i]; - var upLeft = + 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; + + var c = rawBytes[j]; + if (pa <= pb && pa <= pc) + currentRow[i] = left + c; + else if (pb <= pc) + currentRow[i] = up + c; + else + currentRow[i] = upLeft + c; + break; + this.currentRow = currentRow; } default: error("Unsupported predictor"); break; } - this.pos = 0; - this.bufferLength = currentRow.length; - this.currentRow = currentRow; + this.pos = pixBytes; }, getByte : function() { if (this.pos >= this.bufferLength) { From 2fbd6859f22fd84c7708eebc9f18c26f3489bfd7 Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 20:19:13 -0700 Subject: [PATCH 07/11] Bug fix when an array of filters is passed in --- pdf.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 40044300c..00e504a6c 100644 --- a/pdf.js +++ b/pdf.js @@ -1229,7 +1229,8 @@ var Parser = (function() { if (IsArray(filter)) { var filterArray = filter; var paramsArray = params; - for (filter in filterArray) { + for (var i = 0, ii = filter.length; i < ii; ++i) { + filter = filter[i]; if (!IsName(filter)) error("Bad filter name"); else { From 75bffdd61366c1c21697f0597eadb8aeb731fc37 Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 20:28:48 -0700 Subject: [PATCH 08/11] cleaned up code --- pdf.js | 170 +-------------------------------------------------------- 1 file changed, 1 insertion(+), 169 deletions(-) diff --git a/pdf.js b/pdf.js index 1e112e9ee..91d6476a2 100644 --- a/pdf.js +++ b/pdf.js @@ -526,172 +526,6 @@ 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() { @@ -747,7 +581,7 @@ var PredictorStream = (function() { var pixBytes = (colors * bits + 7) >> 3; this.pixBytes = pixBytes; - // add an extra pixByte to represent the pixel left column 0 + // add an extra pixByte to represent the pixel left of column 0 var rowBytes = ((columns * colors * bits + 7) >> 3) + pixBytes; this.rowBytes = rowBytes; @@ -825,7 +659,6 @@ var PredictorStream = (function() { case 0: break; case 1: - // set the first pixel for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) currentRow[i] = (currentRow[i - pixBytes] + rawBytes[j]) & 0xFF; break; @@ -834,7 +667,6 @@ var PredictorStream = (function() { currentRow[i] = (currentRow[i] + rawBytes[j]) & 0xFF; break; case 3: - // set the first pixel for (i = pixBytes, j = 0; i < rowBytes; ++i, ++j) currentRow[i] = (((currentRow[i] + currentRow[i - pixBytes]) >> 1) + rawBytes[j]) & 0xFF; From 3b38313b7a88a91961cd61d857d9e96088262d03 Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 20:41:24 -0700 Subject: [PATCH 09/11] cleaned up code --- pdf.js | 73 +++++++++++++++++----------------------------------------- 1 file changed, 21 insertions(+), 52 deletions(-) diff --git a/pdf.js b/pdf.js index 91d6476a2..96c0c5438 100644 --- a/pdf.js +++ b/pdf.js @@ -19,7 +19,6 @@ function warn(msg) { } function error(msg) { - console.trace(); throw new Error(msg); } @@ -540,10 +539,9 @@ var JpegStream = (function() { } constructor.prototype = { - getByte: function() { - // dummy method to pass IsStream test - error("shouldnt be called"); - }, + getChar: function() { + }, + getImage: function() { return this.domImage; } @@ -653,7 +651,6 @@ var PredictorStream = (function() { var predictor = this.stream.getByte(); var rawBytes = this.stream.getBytes(rowBytes - pixBytes); - var i; switch (predictor) { case 0: @@ -667,7 +664,7 @@ var PredictorStream = (function() { currentRow[i] = (currentRow[i] + rawBytes[j]) & 0xFF; break; case 3: - for (i = pixBytes, j = 0; i < rowBytes; ++i, ++j) + for (var i = pixBytes, j = 0; i < rowBytes; ++i, ++j) currentRow[i] = (((currentRow[i] + currentRow[i - pixBytes]) >> 1) + rawBytes[j]) & 0xFF; break; @@ -767,9 +764,6 @@ var Name = (function() { } constructor.prototype = { - toString: function() { - return this.name; - } }; return constructor; @@ -781,9 +775,6 @@ var Cmd = (function() { } constructor.prototype = { - toString: function() { - return this.cmd; - } }; return constructor; @@ -796,23 +787,22 @@ var Dict = (function() { constructor.prototype = { get: function(key) { - return this.map[key]; - }, - get2: function(key1, key2) { - return this.get(key1) || this.get(key2); - }, - has: function(key) { - return key in this.map; - }, - set: function(key, value) { - this.map[key] = value; - }, - forEach: function(aCallback) { - for (var key in this.map) - aCallback(key, this.map[key]); + return this.map[key]; + }, + get2: function(key1, key2) { + return this.get(key1) || this.get(key2); + }, + has: function(key) { + return key in this.map; + }, + set: function(key, value) { + this.map[key] = value; + }, + forEach: function(aCallback) { + for (var key in this.map) + aCallback(key, this.map[key]); } }; - return constructor; })(); @@ -865,7 +855,7 @@ function IsArray(v) { } function IsStream(v) { - return typeof v == "object" && "getByte" in v; + return typeof v == "object" && "getChar" in v; } function IsRef(v) { @@ -1364,27 +1354,6 @@ var Parser = (function() { }, makeFilter: function(stream, name, length, params) { if (name == "FlateDecode" || name == "Fl") { -/* 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); } @@ -3096,8 +3065,8 @@ var CanvasGraphics = (function() { error("unhandled number of bits per component"); if (smask) { - //if (maskColorSpace.numComps != 1) - // error("Incorrect number of components in smask"); + if (maskColorSpace.numComps != 1) + error("Incorrect number of components in smask"); var numComps = colorSpace.numComps; var imgArray = image.getBytes(numComps * w * h); From 7a3cdcdd06fdd3f41383042bde199939681936f9 Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 20:45:29 -0700 Subject: [PATCH 10/11] working implementation of png and tiff predictors --- pdf.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 96c0c5438..7a38b9729 100644 --- a/pdf.js +++ b/pdf.js @@ -539,8 +539,9 @@ var JpegStream = (function() { } constructor.prototype = { + // Needed to pass IsStream test getChar: function() { - }, + }, getImage: function() { return this.domImage; @@ -3022,7 +3023,7 @@ var CanvasGraphics = (function() { var smask = image.dict.get("SMask"); smask = xref.fetchIfRef(smask); - if (smask) { + if (IsStream(smask)) { if (inline) error("cannot combine smask and inlining"); From a96c7830a3da452d18d6e6eb09d341b7fa390bd0 Mon Sep 17 00:00:00 2001 From: sbarman Date: Mon, 20 Jun 2011 22:44:08 -0700 Subject: [PATCH 11/11] removed redundant getChar --- pdf.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pdf.js b/pdf.js index be324d54f..fe52b5c4e 100644 --- a/pdf.js +++ b/pdf.js @@ -540,10 +540,6 @@ var JpegStream = (function() { } constructor.prototype = { - // Needed to pass IsStream test - getChar: function() { - }, - getImage: function() { return this.domImage; },