start working on stream decoding
This commit is contained in:
parent
d971dfa01b
commit
65a35fcabf
85
pdf.js
85
pdf.js
@ -22,6 +22,8 @@ var Stream = (function() {
|
|||||||
},
|
},
|
||||||
getChar: function() {
|
getChar: function() {
|
||||||
var ch = this.lookChar();
|
var ch = this.lookChar();
|
||||||
|
if (!ch)
|
||||||
|
return ch;
|
||||||
this.pos++;
|
this.pos++;
|
||||||
return ch;
|
return ch;
|
||||||
},
|
},
|
||||||
@ -367,10 +369,10 @@ var Lexer = (function() {
|
|||||||
} else if (!ch) {
|
} else if (!ch) {
|
||||||
this.error("Unterminated hex string");
|
this.error("Unterminated hex string");
|
||||||
break;
|
break;
|
||||||
} else if (specialChars[ch.toCharCode()] != 1) {
|
} else if (specialChars[ch.charCodeAt(0)] != 1) {
|
||||||
var x, x2;
|
var x, x2;
|
||||||
if (((x = ToHexDigit(ch)) == -1) ||
|
if (((x = ToHexDigit(ch)) == -1) ||
|
||||||
((x2 = ToHexDigit(this.getChar())) == -1)) {
|
((x2 = ToHexDigit(stream.getChar())) == -1)) {
|
||||||
error("Illegal character in hex string");
|
error("Illegal character in hex string");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -452,6 +454,19 @@ var Lexer = (function() {
|
|||||||
if (str == "null")
|
if (str == "null")
|
||||||
return null;
|
return null;
|
||||||
return new Cmd(str);
|
return new Cmd(str);
|
||||||
|
},
|
||||||
|
skipToNextLine: function() {
|
||||||
|
var stream = this.stream;
|
||||||
|
while (true) {
|
||||||
|
var ch = stream.getChar();
|
||||||
|
if (!ch || ch == "\n")
|
||||||
|
return;
|
||||||
|
if (ch == "\r") {
|
||||||
|
if ((ch = stream.lookChar()) == "\n")
|
||||||
|
stream.getChar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -523,7 +538,7 @@ var Parser = (function() {
|
|||||||
// stream objects are not allowed inside content streams or
|
// stream objects are not allowed inside content streams or
|
||||||
// object streams
|
// object streams
|
||||||
if (this.allowStreams && IsCmd(this.buf2, "stream")) {
|
if (this.allowStreams && IsCmd(this.buf2, "stream")) {
|
||||||
return this.makeStream();
|
return this.makeStream(dict);
|
||||||
} else {
|
} else {
|
||||||
this.shift();
|
this.shift();
|
||||||
}
|
}
|
||||||
@ -554,8 +569,23 @@ var Parser = (function() {
|
|||||||
// TODO
|
// TODO
|
||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
makeStream: function() {
|
makeStream: function(dict) {
|
||||||
|
var lexer = this.lexer;
|
||||||
|
var stream = lexer.stream;
|
||||||
|
|
||||||
|
// get stream start position
|
||||||
|
lexer.skipToNextLine();
|
||||||
|
var pos = stream.pos;
|
||||||
|
|
||||||
|
// get length
|
||||||
|
var length;
|
||||||
|
if (!IsInt(length = dict.get("Length"))) {
|
||||||
|
error("Bad 'Length' attribute in stream");
|
||||||
|
lenght = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -641,14 +671,16 @@ var Linearization = (function () {
|
|||||||
|
|
||||||
var XRef = (function () {
|
var XRef = (function () {
|
||||||
function constructor(stream, startXRef, mainXRefEntriesOffset) {
|
function constructor(stream, startXRef, mainXRefEntriesOffset) {
|
||||||
|
this.stream = stream;
|
||||||
this.entries = [];
|
this.entries = [];
|
||||||
this.readXRef(stream, startXRef);
|
this.xrefstms = {};
|
||||||
|
this.readXRef(startXRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
readXRefTable: function(parser) {
|
readXRefTable: function(parser) {
|
||||||
|
var obj;
|
||||||
while (true) {
|
while (true) {
|
||||||
var obj;
|
|
||||||
if (IsCmd(obj = parser.getObj(), "trailer"))
|
if (IsCmd(obj = parser.getObj(), "trailer"))
|
||||||
break;
|
break;
|
||||||
if (!IsInt(obj))
|
if (!IsInt(obj))
|
||||||
@ -686,18 +718,49 @@ var XRef = (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the trailer dictionary
|
// read the trailer dictionary
|
||||||
this.ok = true;
|
var dict;
|
||||||
return true;
|
if (!IsDict(dict = parser.getObj()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// get the 'Prev' pointer
|
||||||
|
var more = false;
|
||||||
|
obj = dict.get("Prev");
|
||||||
|
if (IsInt(obj)) {
|
||||||
|
this.prev = obj;
|
||||||
|
more = true;
|
||||||
|
} else if (IsRef(obj)) {
|
||||||
|
// certain buggy PDF generators generate "/Prev NNN 0 R" instead
|
||||||
|
// of "/Prev NNN"
|
||||||
|
this.prev = obj.num;
|
||||||
|
more = true;
|
||||||
|
}
|
||||||
|
if (!this.trailer)
|
||||||
|
this.trailer = dict;
|
||||||
|
|
||||||
|
// check for 'XRefStm' key
|
||||||
|
if (IsInt(obj = dict.get("XRefStm"))) {
|
||||||
|
var pos = obj;
|
||||||
|
if (pos in this.xrefstms)
|
||||||
|
return false;
|
||||||
|
this.xrefstms[pos] = 1; // avoid infinite recursion
|
||||||
|
this.readXRef(pos);
|
||||||
|
} else {
|
||||||
|
this.ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return more;
|
||||||
},
|
},
|
||||||
readXRefStream: function(parser) {
|
readXRefStream: function(parser) {
|
||||||
// TODO
|
// TODO
|
||||||
this.ok = true;
|
this.ok = true;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
readXRef: function(stream, startXRef) {
|
readXRef: function(startXRef) {
|
||||||
|
var stream = this.stream;
|
||||||
stream.pos = startXRef;
|
stream.pos = startXRef;
|
||||||
var parser = new Parser(new Lexer(stream), false);
|
var parser = new Parser(new Lexer(stream), true);
|
||||||
var obj = parser.getObj();
|
var obj = parser.getObj();
|
||||||
// parse an old-style xref table
|
// parse an old-style xref table
|
||||||
if (IsCmd(obj, "xref"))
|
if (IsCmd(obj, "xref"))
|
||||||
@ -876,6 +939,8 @@ var Interpreter = (function() {
|
|||||||
this.error("Unknown command '" + cmd + "'");
|
this.error("Unknown command '" + cmd + "'");
|
||||||
args.length = 0;
|
args.length = 0;
|
||||||
} else {
|
} else {
|
||||||
|
if (args.length > 33)
|
||||||
|
this.error("Too many arguments '" + cmd + "'");
|
||||||
args.push(obj);
|
args.push(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user