diff --git a/pdf.js b/pdf.js index e357732f2..593137aee 100644 --- a/pdf.js +++ b/pdf.js @@ -904,6 +904,74 @@ var Ascii85Stream = (function() { return constructor; })(); +var AsciiHexStream = (function() { + function constructor(str) { + this.str = str; + this.dict = str.dict; + + DecodeStream.call(this); + } + + var hexvalueMap = { + 9: -1, // \t + 32: -1, // space + 48: 0, + 49: 1, + 50: 2, + 51: 3, + 52: 4, + 53: 5, + 54: 6, + 55: 7, + 56: 8, + 57: 9, + 65: 10, + 66: 11, + 67: 12, + 68: 13, + 69: 14, + 70: 15, + 97: 10, + 98: 11, + 99: 12, + 100: 13, + 101: 14, + 102: 15 + }; + + constructor.prototype = Object.create(DecodeStream.prototype); + + constructor.prototype.readBlock = function() { + var gtCode = '>'.charCodeAt(0), bytes = this.str.getBytes(), c, n, + decodeLength, buffer, bufferLength, i, length; + + decodeLength = (bytes.length + 1) >> 1; + buffer = this.ensureBuffer(this.bufferLength + decodeLength); + bufferLength = this.bufferLength; + + for(i = 0, length = bytes.length; i < length; i++) { + c = hexvalueMap[bytes[i]]; + while (c == -1 && (i+1) < length) { + c = hexvalueMap[bytes[++i]]; + } + + if((i+1) < length && (bytes[i+1] !== gtCode)) { + n = hexvalueMap[bytes[++i]]; + buffer[bufferLength++] = c*16+n; + } else { + if(bytes[i] !== gtCode) { // EOD marker at an odd number, behave as if a 0 followed the last digit. + buffer[bufferLength++] = c*16; + } + } + } + + this.bufferLength = bufferLength; + this.eof = true; + }; + + return constructor; +})(); + var CCITTFaxStream = (function() { var ccittEOL = -2; @@ -1943,7 +2011,7 @@ var Dict = (function() { forEach: function(callback) { for (var key in this.map) { - callback.call(null, key, this.map[key]); + callback(key, this.map[key]); } } }; @@ -2496,6 +2564,8 @@ var Parser = (function() { return new JpegStream(bytes, stream.dict); } else if (name == 'ASCII85Decode') { return new Ascii85Stream(stream); + } else if (name == 'ASCIIHexDecode') { + return new AsciiHexStream(stream); } else if (name == 'CCITTFaxDecode') { TODO('implement fax stream'); return new CCITTFaxStream(stream, params); diff --git a/test/pdfs/asciihexdecode.pdf b/test/pdfs/asciihexdecode.pdf new file mode 100644 index 000000000..f3bd457ec --- /dev/null +++ b/test/pdfs/asciihexdecode.pdf @@ -0,0 +1,55 @@ +%PDF-1.0 +1 0 obj +<< + /Pages 2 0 R + /Type /Catalog +>> +endobj +2 0 obj +<< + /Count 1 + /Kids [ 3 0 R ] + /Type /Pages +>> +endobj +3 0 obj +<< + /MediaBox [ 0 0 795 842 ] + /Parent 2 0 R + /Contents 4 0 R + /Resources << + /Font << + /F1 << + /Name /F1 + /BaseFont /Helvetica + /Subtype /Type1 + /Type /Font + >> + >> + >> + /Type /Page +>> +endobj +4 0 obj +<< + /Filter /ASCIIHexDecode + /Length 111 +>>stream +42540A2F46312033302054660A333530203735302054640A323020544C0A312054720A2848656C6C6F20776F726C642920546A0A45540A> +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000010 00000 n +0000000067 00000 n +0000000136 00000 n +0000000373 00000 n +trailer +<< + /Root 1 0 R + /Size 5 +>> +startxref +568 +%%EOF