New readXRefTable, working
This commit is contained in:
parent
4375bd2219
commit
0959cd3517
99
src/obj.js
99
src/obj.js
@ -298,9 +298,10 @@ var XRef = (function XRefClosure() {
|
|||||||
// ...
|
// ...
|
||||||
|
|
||||||
// Outer loop is over subsection headers
|
// Outer loop is over subsection headers
|
||||||
var first;
|
var obj;
|
||||||
while (!isCmd(first = parser.getObj(), 'trailer')) {
|
while (!isCmd(obj = parser.getObj(), 'trailer')) {
|
||||||
var count = parser.getObj();
|
var first = obj,
|
||||||
|
count = parser.getObj();
|
||||||
|
|
||||||
if (!isInt(first) || !isInt(count))
|
if (!isInt(first) || !isInt(count))
|
||||||
error('Invalid XRef table: wrong types in subsection header');
|
error('Invalid XRef table: wrong types in subsection header');
|
||||||
@ -320,46 +321,35 @@ var XRef = (function XRefClosure() {
|
|||||||
// Validate entry obj
|
// Validate entry obj
|
||||||
if ( !isInt(entry.offset) || !isInt(entry.gen) ||
|
if ( !isInt(entry.offset) || !isInt(entry.gen) ||
|
||||||
!(entry.free || entry.uncompressed) ) {
|
!(entry.free || entry.uncompressed) ) {
|
||||||
error('Invalid XRef table: ' + first + ', ' + count);
|
error('Invalid entry in XRef subsection: ' + first + ', ' + count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.entries[i + first])
|
if (!this.entries[i + first])
|
||||||
this.entries[i + first] = entry;
|
this.entries[i + first] = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No objects added?
|
|
||||||
if (!(i > 0))
|
|
||||||
error('Invalid XRef table: ' + first + ', ' + count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the trailer dictionary
|
// Sanity check: as per spec, first object must have these properties
|
||||||
var dict;
|
if ( this.entries[0] &&
|
||||||
if (!isDict(dict = parser.getObj()))
|
!(this.entries[0].gen === 65535 && this.entries[0].free) )
|
||||||
error('Invalid XRef table');
|
error('Invalid XRef table: unexpected first object');
|
||||||
|
|
||||||
// get the 'Prev' pointer
|
// Sanity check
|
||||||
var prev;
|
if (!isCmd(obj, 'trailer'))
|
||||||
var obj = dict.get('Prev');
|
error('Invalid XRef table: could not find trailer dictionary');
|
||||||
if (isInt(obj)) {
|
|
||||||
prev = obj;
|
|
||||||
} else if (isRef(obj)) {
|
|
||||||
// certain buggy PDF generators generate "/Prev NNN 0 R" instead
|
|
||||||
// of "/Prev NNN"
|
|
||||||
prev = obj.num;
|
|
||||||
}
|
|
||||||
if (prev) {
|
|
||||||
this.readXRef(prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for 'XRefStm' key
|
// Read trailer dictionary, e.g.
|
||||||
if (isInt(obj = dict.get('XRefStm'))) {
|
// trailer
|
||||||
var pos = obj;
|
// << /Size 22
|
||||||
// ignore previously loaded xref streams (possible infinite recursion)
|
// /Root 20R
|
||||||
if (!(pos in this.xrefstms)) {
|
// /Info 10R
|
||||||
this.xrefstms[pos] = 1;
|
// /ID [ <81b14aafa313db63dbd6f981e49f94f4> ]
|
||||||
this.readXRef(pos);
|
// >>
|
||||||
}
|
// The parser goes through the entire stream << ... >> and provides
|
||||||
}
|
// a getter interface for the key-value table
|
||||||
|
var dict = parser.getObj();
|
||||||
|
if (!isDict(dict))
|
||||||
|
error('Invalid XRef table: could not parse trailer dictionary');
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
},
|
},
|
||||||
@ -412,9 +402,6 @@ var XRef = (function XRefClosure() {
|
|||||||
}
|
}
|
||||||
range.splice(0, 2);
|
range.splice(0, 2);
|
||||||
}
|
}
|
||||||
var prev = streamParameters.get('Prev');
|
|
||||||
if (isInt(prev))
|
|
||||||
this.readXRef(prev);
|
|
||||||
return streamParameters;
|
return streamParameters;
|
||||||
},
|
},
|
||||||
indexObjects: function indexObjects() {
|
indexObjects: function indexObjects() {
|
||||||
@ -534,22 +521,48 @@ var XRef = (function XRefClosure() {
|
|||||||
try {
|
try {
|
||||||
var parser = new Parser(new Lexer(stream), true);
|
var parser = new Parser(new Lexer(stream), true);
|
||||||
var obj = parser.getObj();
|
var obj = parser.getObj();
|
||||||
|
var dict;
|
||||||
|
|
||||||
// parse an old-style xref table
|
// Get dictionary
|
||||||
if (isCmd(obj, 'xref'))
|
if (isCmd(obj, 'xref')) {
|
||||||
return this.readXRefTable(parser);
|
// Parse end-of-file XRef
|
||||||
|
dict = this.readXRefTable(parser);
|
||||||
|
|
||||||
// parse an xref stream
|
// Recursively get other XRefs 'XRefStm', if any
|
||||||
|
obj = dict.get('XRefStm');
|
||||||
if (isInt(obj)) {
|
if (isInt(obj)) {
|
||||||
|
var pos = obj;
|
||||||
|
// ignore previously loaded xref streams
|
||||||
|
// (possible infinite recursion)
|
||||||
|
if (!(pos in this.xrefstms)) {
|
||||||
|
this.xrefstms[pos] = 1;
|
||||||
|
this.readXRef(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isInt(obj)) {
|
||||||
|
// Parse in-stream XRef
|
||||||
if (!isInt(parser.getObj()) ||
|
if (!isInt(parser.getObj()) ||
|
||||||
!isCmd(parser.getObj(), 'obj') ||
|
!isCmd(parser.getObj(), 'obj') ||
|
||||||
!isStream(obj = parser.getObj())) {
|
!isStream(obj = parser.getObj())) {
|
||||||
error('Invalid XRef stream');
|
error('Invalid XRef stream');
|
||||||
}
|
}
|
||||||
return this.readXRefStream(obj);
|
dict = this.readXRefStream(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively get previous dictionary, if any
|
||||||
|
obj = dict.get('Prev');
|
||||||
|
if (isInt(obj))
|
||||||
|
this.readXRef(obj);
|
||||||
|
else if (isRef(obj)) {
|
||||||
|
// The spec says Prev must not be a reference, i.e. "/Prev NNN"
|
||||||
|
// This is a fallback for non-compliant PDFs, i.e. "/Prev NNN 0 R"
|
||||||
|
this.readXRef(obj.num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dict;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log('Reading of the xref table/stream failed: ' + e);
|
// log('(while reading XRef): ' + e);
|
||||||
|
error('(while reading XRef): ' + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
warn('Indexing all PDF objects');
|
warn('Indexing all PDF objects');
|
||||||
|
Loading…
Reference in New Issue
Block a user