From beb048b2178fd85c539962fb8dd0631a7dc91082 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 13:34:35 -0700 Subject: [PATCH 1/7] initial impl of ASCII85 Decoding --- pdf.js | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/pdf.js b/pdf.js index fff135816..dfb47ea16 100644 --- a/pdf.js +++ b/pdf.js @@ -750,6 +750,116 @@ var DecryptStream = (function() { return constructor; })(); +var Ascii85Stream = (function() { + function constructor(str) { + this.str = str; + this.dict = str.dict; + this.eof = false; + this.pos = 0; + this.bufferLength = 0; + this.buffer = new Uint8Array(4); + } + constructor.prototype = { + getByte: function() { + if (this.pos >= this.bufferLength) + this.readBlock(); + return this.buffer[this.pos++]; + }, + getBytes: function(n) { + var i, bytes; + bytes = new Uint8Array(n); + for (i = 0; i < n; ++i) { + if (this.pos >= this.bufferLength) + this.readBlock(); + if (this.eof) + break; + bytes[i] = this.buffer[this.pos++]; + } + return bytes; + }, + getChar : function() { + return String.fromCharCode(this.getByte()); + }, + lookChar : function() { + if (this.pos >= this.bufferLength) + this.readRow(); + return String.fromCharCode(this.currentRow[this.pos]); + }, + skip : function(n) { + var i; + if (!n) { + n = 1; + } + while (n > this.bufferLength - this.pos) { + n -= this.bufferLength - this.pos; + this.readBlock(); + if (this.bufferLength === 0) break; + } + this.pos += n; + }, + readBlock: function() { + if (this.eof) { + this.bufferLength = 0; + this.buffer = []; + this.pos = 0; + return; + } + + const tildaCode = "~".charCodeAt(0); + const zCode = "z".charCodeAt(0); + var str = this.str; + + var c = str.getByte(); + while (Lexer.isSpace(String.fromCharCode(c))) + c = str.getByte(); + if (!c || c === tildaCode) { + this.eof = true; + return; + } + + var buffer = this.buffer; + // special code for z + if (c == zCode) { + buffer[0] = 0; + buffer[1] = 0; + buffer[2] = 0; + buffer[3] = 0; + this.bufferLength = 4; + } else { + var input = new Uint8Array(5); + input[0] = c; + for (var i = 1; i < 5; ++i){ + c = str.getByte(); + while (Lexer.isSpace(String.fromCharCode(c))) + c = str.getByte(); + + input[i] = c; + + if (!c || c == tildaCode) + break; + } + this.bufferLength = i - 1; + // partial ending; + if (i < 5) { + for (++i; i < 5; ++i) + input[i] = 0x21 + 84; + this.eof = true; + } + var t = 0; + for (var i = 0; i < 5; ++i) + t = t * 85 + (input[i] - 0x21); + + for (var i = 3; i >= 0; --i){ + buffer[i] = t & 0xFF; + t >>= 8; + } + } + } + }; + + return constructor; +})(); + var Name = (function() { function constructor(name) { this.name = name; @@ -1354,6 +1464,8 @@ var Parser = (function() { } else if (name == "DCTDecode") { var bytes = stream.getBytes(length); return new JpegStream(bytes, stream.dict); + } else if (name == "ASCII85Decode") { + return new Ascii85Stream(stream); } else { error("filter '" + name + "' not supported yet"); } From 240fcf650b28e3495ffdb79677c4e019a9e3796c Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 14:34:13 -0700 Subject: [PATCH 2/7] fixed getBytes in Ascii85Stream --- pdf.js | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/pdf.js b/pdf.js index dfb47ea16..5ff97fa91 100644 --- a/pdf.js +++ b/pdf.js @@ -766,16 +766,38 @@ var Ascii85Stream = (function() { return this.buffer[this.pos++]; }, getBytes: function(n) { - var i, bytes; - bytes = new Uint8Array(n); - for (i = 0; i < n; ++i) { - if (this.pos >= this.bufferLength) - this.readBlock(); - if (this.eof) - break; - bytes[i] = this.buffer[this.pos++]; + if (n) { + var i, bytes; + bytes = new Uint8Array(n); + for (i = 0; i < n; ++i) { + if (this.pos >= this.bufferLength) + this.readBlock(); + if (this.eof) + break; + bytes[i] = this.buffer[this.pos++]; + } + return bytes; + } else { + var length = 0; + var size = 1 << 8; + var bytes = new Uint8Array(size); + while (true) { + if (this.pos >= this.bufferLength) + this.readBlock(); + if (this.eof) + break; + if (length == size) { + var oldSize = size; + size <<= 1; + var oldBytes = bytes; + bytes = new Uint8Array(size); + for (var i = 0; i < oldSize; ++i) + bytes[i] = oldBytes[i]; + } + bytes[length++] = this.buffer[this.pos++]; + } + return bytes.subarray(0, length); } - return bytes; }, getChar : function() { return String.fromCharCode(this.getByte()); @@ -1441,8 +1463,8 @@ var Parser = (function() { if (IsArray(filter)) { var filterArray = filter; var paramsArray = params; - for (var i = 0, ii = filter.length; i < ii; ++i) { - filter = filter[i]; + for (var i = 0, ii = filterArray.length; i < ii; ++i) { + filter = filterArray[i]; if (!IsName(filter)) error("Bad filter name"); else { From 3603981581eb245258ab3169dc53eaee74f847c5 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 21:12:50 -0700 Subject: [PATCH 3/7] modified Ascii85Stream to be more like other streams --- pdf.js | 100 ++++++++++++++++++++------------------------------------- 1 file changed, 34 insertions(+), 66 deletions(-) diff --git a/pdf.js b/pdf.js index 5ff97fa91..ed456a69b 100644 --- a/pdf.js +++ b/pdf.js @@ -757,76 +757,39 @@ var Ascii85Stream = (function() { this.eof = false; this.pos = 0; this.bufferLength = 0; - this.buffer = new Uint8Array(4); + this.buffer = null; } constructor.prototype = { + ensureBuffer: function(requested) { + var buffer = this.buffer; + var current = buffer ? buffer.byteLength : 0; + if (requested < current) + return buffer; + var size = 512; + while (size < requested) + size <<= 1; + var buffer2 = Uint8Array(size); + for (var i = 0; i < current; ++i) + buffer2[i] = buffer[i]; + return this.buffer = buffer2; + }, getByte: function() { - if (this.pos >= this.bufferLength) + while (this.pos >= this.bufferLength) this.readBlock(); return this.buffer[this.pos++]; }, getBytes: function(n) { if (n) { - var i, bytes; - bytes = new Uint8Array(n); - for (i = 0; i < n; ++i) { - if (this.pos >= this.bufferLength) - this.readBlock(); - if (this.eof) - break; - bytes[i] = this.buffer[this.pos++]; - } - return bytes; + while (this.bufferLength < n || !this.eof) + this.readBlock(); + return this.buffer.subarray(0, n); } else { - var length = 0; - var size = 1 << 8; - var bytes = new Uint8Array(size); - while (true) { - if (this.pos >= this.bufferLength) - this.readBlock(); - if (this.eof) - break; - if (length == size) { - var oldSize = size; - size <<= 1; - var oldBytes = bytes; - bytes = new Uint8Array(size); - for (var i = 0; i < oldSize; ++i) - bytes[i] = oldBytes[i]; - } - bytes[length++] = this.buffer[this.pos++]; - } - return bytes.subarray(0, length); + while (!this.eof) + this.readBlock(); + return this.buffer; } }, - getChar : function() { - return String.fromCharCode(this.getByte()); - }, - lookChar : function() { - if (this.pos >= this.bufferLength) - this.readRow(); - return String.fromCharCode(this.currentRow[this.pos]); - }, - skip : function(n) { - var i; - if (!n) { - n = 1; - } - while (n > this.bufferLength - this.pos) { - n -= this.bufferLength - this.pos; - this.readBlock(); - if (this.bufferLength === 0) break; - } - this.pos += n; - }, readBlock: function() { - if (this.eof) { - this.bufferLength = 0; - this.buffer = []; - this.pos = 0; - return; - } - const tildaCode = "~".charCodeAt(0); const zCode = "z".charCodeAt(0); var str = this.str; @@ -839,14 +802,17 @@ var Ascii85Stream = (function() { return; } - var buffer = this.buffer; + var bufferLength = this.bufferLength; + // special code for z if (c == zCode) { - buffer[0] = 0; - buffer[1] = 0; - buffer[2] = 0; - buffer[3] = 0; - this.bufferLength = 4; + this.ensureBuffer(bufferLength + 4); + var buffer = this.buffer; + buffer[bufferLength++] = 0; + buffer[bufferLength++] = 0; + buffer[bufferLength++] = 0; + buffer[bufferLength++] = 0; + this.bufferLength += 4; } else { var input = new Uint8Array(5); input[0] = c; @@ -860,7 +826,9 @@ var Ascii85Stream = (function() { if (!c || c == tildaCode) break; } - this.bufferLength = i - 1; + this.ensureBuffer(bufferLength + i - 1); + var buffer = this.buffer; + this.bufferLength += i - 1; // partial ending; if (i < 5) { for (++i; i < 5; ++i) @@ -872,7 +840,7 @@ var Ascii85Stream = (function() { t = t * 85 + (input[i] - 0x21); for (var i = 3; i >= 0; --i){ - buffer[i] = t & 0xFF; + buffer[bufferLength++] = t & 0xFF; t >>= 8; } } From 745745ccd082e30bb7007f1608cafb0381c6cc0b Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 21:26:48 -0700 Subject: [PATCH 4/7] work in progress on ascii85 --- pdf.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/pdf.js b/pdf.js index ed456a69b..c186f0cdf 100644 --- a/pdf.js +++ b/pdf.js @@ -774,20 +774,57 @@ var Ascii85Stream = (function() { return this.buffer = buffer2; }, getByte: function() { - while (this.pos >= this.bufferLength) - this.readBlock(); + var pos = this.pos; + while (this.bufferLength <= pos) { + if (this.eof) + return; + this.readBlock(); + } return this.buffer[this.pos++]; }, - getBytes: function(n) { - if (n) { - while (this.bufferLength < n || !this.eof) + getBytes: function(length) { + var pos = this.pos; + + this.ensureBuffer(pos + length); + if (length) { + while (!this.eof && this.bufferLength < pos + length) this.readBlock(); - return this.buffer.subarray(0, n); + + var end = pos + length; + var bufEnd = this.bufferLength; + + if (end > bufEnd) + end = bufEnd; } else { - while (!this.eof) + while(!this.eof) this.readBlock(); - return this.buffer; + var end = this.bufferLength; } + this.pos = end; + return this.buffer.subarray(pos, end) + }, + lookChar: function() { + var pos = this.pos; + while (this.bufferLength <= pos) { + if (this.eof) + return; + this.readBlock(); + } + return String.fromCharCode(this.buffer[this.pos]); + }, + getChar: function() { + var pos = this.pos; + while (this.bufferLength <= pos) { + if (this.eof) + return; + this.readBlock(); + } + return String.fromCharCode(this.buffer[this.pos++]); + }, + skip: function(n) { + if (!n) + n = 1; + this.pos += n; }, readBlock: function() { const tildaCode = "~".charCodeAt(0); @@ -840,7 +877,7 @@ var Ascii85Stream = (function() { t = t * 85 + (input[i] - 0x21); for (var i = 3; i >= 0; --i){ - buffer[bufferLength++] = t & 0xFF; + buffer[bufferLength + i] = t & 0xFF; t >>= 8; } } @@ -1712,6 +1749,8 @@ var XRef = (function() { return this.fetch(obj); }, fetch: function(ref) { + if (!ref) + console.trace(); var num = ref.num; var e = this.cache[num]; if (e) From f0a580e1e784ff17ee64c53ba3f54401fd4424b1 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 22:39:38 -0700 Subject: [PATCH 5/7] made Ascii85Stream be a child of DecodeStream --- pdf.js | 196 ++++++++++++++++++++------------------------------------- 1 file changed, 68 insertions(+), 128 deletions(-) diff --git a/pdf.js b/pdf.js index e955c25ea..5ed0eb59d 100644 --- a/pdf.js +++ b/pdf.js @@ -171,15 +171,22 @@ var DecodeStream = (function() { getBytes: function(length) { var pos = this.pos; - this.ensureBuffer(pos + length); - while (!this.eof && this.bufferLength < pos + length) - this.readBlock(); + if (length) { + this.ensureBuffer(pos + length); + var end = pos + length; - var end = pos + length; - var bufEnd = this.bufferLength; + while (!this.eof && this.bufferLength < end) + this.readBlock(); - if (end > bufEnd) - end = bufEnd; + var bufEnd = this.bufferLength; + if (end > bufEnd) + end = bufEnd; + } else { + while (!this.eof) + this.readBlock(); + + var end = this.bufferLength; + } this.pos = end; return this.buffer.subarray(pos, end) @@ -763,132 +770,64 @@ var Ascii85Stream = (function() { function constructor(str) { this.str = str; this.dict = str.dict; - this.eof = false; - this.pos = 0; - this.bufferLength = 0; - this.buffer = null; + + DecodeStream.call(this); } - constructor.prototype = { - ensureBuffer: function(requested) { + + constructor.prototype = Object.create(DecodeStream.prototype); + constructor.prototype.readBlock = function() { + const tildaCode = "~".charCodeAt(0); + const zCode = "z".charCodeAt(0); + var str = this.str; + + var c = str.getByte(); + while (Lexer.isSpace(String.fromCharCode(c))) + c = str.getByte(); + + if (!c || c === tildaCode) { + this.eof = true; + return; + } + + var bufferLength = this.bufferLength; + + // special code for z + if (c == zCode) { + this.ensureBuffer(bufferLength + 4); var buffer = this.buffer; - var current = buffer ? buffer.byteLength : 0; - if (requested < current) - return buffer; - var size = 512; - while (size < requested) - size <<= 1; - var buffer2 = Uint8Array(size); - for (var i = 0; i < current; ++i) - buffer2[i] = buffer[i]; - return this.buffer = buffer2; - }, - getByte: function() { - var pos = this.pos; - while (this.bufferLength <= pos) { - if (this.eof) - return; - this.readBlock(); - } - return this.buffer[this.pos++]; - }, - getBytes: function(length) { - var pos = this.pos; - - this.ensureBuffer(pos + length); - if (length) { - while (!this.eof && this.bufferLength < pos + length) - this.readBlock(); - - var end = pos + length; - var bufEnd = this.bufferLength; - - if (end > bufEnd) - end = bufEnd; - } else { - while(!this.eof) - this.readBlock(); - var end = this.bufferLength; - } - this.pos = end; - return this.buffer.subarray(pos, end) - }, - lookChar: function() { - var pos = this.pos; - while (this.bufferLength <= pos) { - if (this.eof) - return; - this.readBlock(); - } - return String.fromCharCode(this.buffer[this.pos]); - }, - getChar: function() { - var pos = this.pos; - while (this.bufferLength <= pos) { - if (this.eof) - return; - this.readBlock(); - } - return String.fromCharCode(this.buffer[this.pos++]); - }, - skip: function(n) { - if (!n) - n = 1; - this.pos += n; - }, - readBlock: function() { - const tildaCode = "~".charCodeAt(0); - const zCode = "z".charCodeAt(0); - var str = this.str; - - var c = str.getByte(); - while (Lexer.isSpace(String.fromCharCode(c))) + for (var i = 0; i < 4; ++i) + buffer[bufferLength + i] = 0; + this.bufferLength += 4; + } else { + var input = new Uint8Array(5); + input[0] = c; + for (var i = 1; i < 5; ++i){ c = str.getByte(); - if (!c || c === tildaCode) { - this.eof = true; - return; - } - - var bufferLength = this.bufferLength; - - // special code for z - if (c == zCode) { - this.ensureBuffer(bufferLength + 4); - var buffer = this.buffer; - buffer[bufferLength++] = 0; - buffer[bufferLength++] = 0; - buffer[bufferLength++] = 0; - buffer[bufferLength++] = 0; - this.bufferLength += 4; - } else { - var input = new Uint8Array(5); - input[0] = c; - for (var i = 1; i < 5; ++i){ + while (Lexer.isSpace(String.fromCharCode(c))) c = str.getByte(); - while (Lexer.isSpace(String.fromCharCode(c))) - c = str.getByte(); - input[i] = c; - - if (!c || c == tildaCode) - break; - } - this.ensureBuffer(bufferLength + i - 1); - var buffer = this.buffer; - this.bufferLength += i - 1; - // partial ending; - if (i < 5) { - for (++i; i < 5; ++i) - input[i] = 0x21 + 84; - this.eof = true; - } - var t = 0; - for (var i = 0; i < 5; ++i) - t = t * 85 + (input[i] - 0x21); - - for (var i = 3; i >= 0; --i){ - buffer[bufferLength + i] = t & 0xFF; - t >>= 8; - } + input[i] = c; + + if (!c || c == tildaCode) + break; + } + this.ensureBuffer(bufferLength + i - 1); + var buffer = this.buffer; + this.bufferLength += i - 1; + + // partial ending; + if (i < 5) { + for (; i < 5; ++i) + input[i] = 0x21 + 84; + this.eof = true; + } + var t = 0; + for (var i = 0; i < 5; ++i) + t = t * 85 + (input[i] - 0x21); + + for (var i = 3; i >= 0; --i){ + buffer[bufferLength + i] = t & 0xFF; + t >>= 8; } } }; @@ -2402,6 +2341,7 @@ var CanvasGraphics = (function() { constructor.prototype = { translateFont: function(fontDict, xref, resources) { + return; var descriptor = xref.fetch(fontDict.get("FontDescriptor")); var fontName = descriptor.get("FontName"); From ec19935ffb39b67d1d5f965e80cf0d5c504466af Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 22:43:03 -0700 Subject: [PATCH 6/7] clean up code --- pdf.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/pdf.js b/pdf.js index 5ed0eb59d..766ea3b28 100644 --- a/pdf.js +++ b/pdf.js @@ -1700,8 +1700,6 @@ var XRef = (function() { return this.fetch(obj); }, fetch: function(ref) { - if (!ref) - console.trace(); var num = ref.num; var e = this.cache[num]; if (e) @@ -2341,7 +2339,6 @@ var CanvasGraphics = (function() { constructor.prototype = { translateFont: function(fontDict, xref, resources) { - return; var descriptor = xref.fetch(fontDict.get("FontDescriptor")); var fontName = descriptor.get("FontName"); From 02dc50532e48e6b30b5644c69db2d8636643b193 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 21 Jun 2011 22:53:47 -0700 Subject: [PATCH 7/7] moved array allocation to consturctor --- pdf.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 766ea3b28..852eb03e7 100644 --- a/pdf.js +++ b/pdf.js @@ -770,6 +770,7 @@ var Ascii85Stream = (function() { function constructor(str) { this.str = str; this.dict = str.dict; + this.input = new Uint8Array(5); DecodeStream.call(this); } @@ -799,7 +800,7 @@ var Ascii85Stream = (function() { buffer[bufferLength + i] = 0; this.bufferLength += 4; } else { - var input = new Uint8Array(5); + var input = this.input; input[0] = c; for (var i = 1; i < 5; ++i){ c = str.getByte();