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;
}
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);
}