Merge pull request #5023 from Snuffleupagus/linearization-refactor

Re-factor parsing of the Linearization dictionary
This commit is contained in:
Yury Delendik 2014-07-28 10:34:37 -05:00
commit 2e47b58281
2 changed files with 49 additions and 80 deletions

View File

@ -358,22 +358,15 @@ var PDFDocument = (function PDFDocumentClosure() {
}, },
get linearization() { get linearization() {
var length = this.stream.length; var linearization = null;
var linearization = false; if (this.stream.length) {
if (length) {
try { try {
linearization = new Linearization(this.stream); linearization = Linearization.create(this.stream);
if (linearization.length != length) {
linearization = false;
}
} catch (err) { } catch (err) {
if (err instanceof MissingDataException) { if (err instanceof MissingDataException) {
throw err; throw err;
} }
info(err);
info('The linearization data is not available ' +
'or unreadable PDF data is found');
linearization = false;
} }
} }
// shadow the prototype getter with a data property // shadow the prototype getter with a data property

View File

@ -823,75 +823,51 @@ var Lexer = (function LexerClosure() {
return Lexer; return Lexer;
})(); })();
var Linearization = (function LinearizationClosure() { var Linearization = {
function Linearization(stream) { create: function LinearizationCreate(stream) {
this.parser = new Parser(new Lexer(stream), false, null); function getInt(name, allowZeroValue) {
var obj1 = this.parser.getObj(); var obj = linDict.get(name);
var obj2 = this.parser.getObj(); if (isInt(obj) && (allowZeroValue ? obj >= 0 : obj > 0)) {
var obj3 = this.parser.getObj();
this.linDict = this.parser.getObj();
if (isInt(obj1) && isInt(obj2) && isCmd(obj3, 'obj') &&
isDict(this.linDict)) {
var obj = this.linDict.get('Linearized');
if (!(isNum(obj) && obj > 0)) {
this.linDict = null;
}
}
}
Linearization.prototype = {
getInt: function Linearization_getInt(name) {
var linDict = this.linDict;
var obj;
if (isDict(linDict) && isInt(obj = linDict.get(name)) && obj > 0) {
return obj; return obj;
} }
error('"' + name + '" field in linearization table is invalid'); throw new Error('The "' + name + '" parameter in the linearization ' +
}, 'dictionary is invalid.');
getHint: function Linearization_getHint(index) {
var linDict = this.linDict;
var obj1, obj2;
if (isDict(linDict) && isArray(obj1 = linDict.get('H')) &&
obj1.length >= 2 && isInt(obj2 = obj1[index]) && obj2 > 0) {
return obj2;
} }
error('Hints table in linearization table is invalid: ' + index); function getHints() {
}, var hints = linDict.get('H'), hintsLength, item;
get length() { if (isArray(hints) &&
if (!isDict(this.linDict)) { ((hintsLength = hints.length) === 2 || hintsLength === 4)) {
return 0; for (var index = 0; index < hintsLength; index++) {
if (!(isInt(item = hints[index]) && item > 0)) {
throw new Error('Hint (' + index +
') in the linearization dictionary is invalid.');
} }
return this.getInt('L'); }
}, return hints;
get hintsOffset() { }
return this.getHint(0); throw new Error('Hint array in the linearization dictionary is invalid.');
}, }
get hintsLength() { var parser = new Parser(new Lexer(stream), false, null);
return this.getHint(1); var obj1 = parser.getObj();
}, var obj2 = parser.getObj();
get hintsOffset2() { var obj3 = parser.getObj();
return this.getHint(2); var linDict = parser.getObj();
}, var obj, length;
get hintsLenth2() { if (!(isInt(obj1) && isInt(obj2) && isCmd(obj3, 'obj') && isDict(linDict) &&
return this.getHint(3); isNum(obj = linDict.get('Linearized')) && obj > 0)) {
}, return null; // No valid linearization dictionary found.
get objectNumberFirst() { } else if ((length = getInt('L')) !== stream.length) {
return this.getInt('O'); throw new Error('The "L" parameter in the linearization dictionary ' +
}, 'does not equal the stream length.');
get endFirst() { }
return this.getInt('E'); return {
}, length: length,
get numPages() { hints: getHints(),
return this.getInt('N'); objectNumberFirst: getInt('O'),
}, endFirst: getInt('E'),
get mainXRefEntriesOffset() { numPages: getInt('N'),
return this.getInt('T'); mainXRefEntriesOffset: getInt('T'),
}, pageFirst: (linDict.has('P') ? getInt('P', true) : 0)
get pageFirst() { };
return this.getInt('P');
} }
}; };
return Linearization;
})();