diff --git a/src/parser.js b/src/parser.js index e50b12b9b..047416027 100644 --- a/src/parser.js +++ b/src/parser.js @@ -249,6 +249,9 @@ var Parser = (function ParserClosure() { if (name == 'CCITTFaxDecode' || name == 'CCF') { return new CCITTFaxStream(stream, params); } + if (name == 'RunLengthDecode') { + return new RunLengthStream(stream); + } warn('filter "' + name + '" not supported yet'); return stream; } diff --git a/src/stream.js b/src/stream.js index 69748b5f2..ded6c37ef 100644 --- a/src/stream.js +++ b/src/stream.js @@ -1041,6 +1041,51 @@ var AsciiHexStream = (function AsciiHexStreamClosure() { return AsciiHexStream; })(); +var RunLengthStream = (function RunLengthStreamClosure() { + function RunLengthStream(str) { + this.str = str; + this.dict = str.dict; + + DecodeStream.call(this); + } + + RunLengthStream.prototype = Object.create(DecodeStream.prototype); + + RunLengthStream.prototype.readBlock = function runLengthStreamReadBlock() { + // The repeatHeader has following format. The first byte defines type of run + // and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes + // (in addition to the second byte from the header), n = 129 through 255 - + // duplicate the second byte from the header (257 - n) times, n = 128 - end. + var repeatHeader = this.str.getBytes(2); + if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) { + this.eof = true; + return; + } + + var bufferLength = this.bufferLength; + var n = repeatHeader[0]; + if (n < 128) { + // copy n bytes + var buffer = this.ensureBuffer(bufferLength + n + 1); + buffer[bufferLength++] = repeatHeader[1]; + if (n > 0) { + var source = this.str.getBytes(n); + buffer.set(source, bufferLength); + bufferLength += n; + } + } else { + n = 257 - n; + var b = repeatHeader[1]; + var buffer = this.ensureBuffer(bufferLength + n + 1); + for (var i = 0; i < n; i++) + buffer[bufferLength++] = b; + } + this.bufferLength = bufferLength; + }; + + return RunLengthStream; +})(); + var CCITTFaxStream = (function CCITTFaxStreamClosure() { var ccittEOL = -2;