| //======================================================================== |
| // |
| // Linearization.cc |
| // |
| // This file is licensed under the GPLv2 or later |
| // |
| // Copyright 2010, 2012 Hib Eris <hib@hiberis.nl> |
| // |
| //======================================================================== |
| |
| #include "Linearization.h" |
| #include "Parser.h" |
| #include "Lexer.h" |
| |
| //------------------------------------------------------------------------ |
| // Linearization |
| //------------------------------------------------------------------------ |
| |
| Linearization::Linearization (BaseStream *str) |
| { |
| Parser *parser; |
| Object obj1, obj2, obj3, obj5; |
| |
| linDict.initNull(); |
| |
| str->reset(); |
| obj1.initNull(); |
| parser = new Parser(NULL, |
| new Lexer(NULL, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), |
| gFalse); |
| parser->getObj(&obj1); |
| parser->getObj(&obj2); |
| parser->getObj(&obj3); |
| parser->getObj(&linDict); |
| if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && linDict.isDict()) { |
| linDict.dictLookup("Linearized", &obj5); |
| if (!(obj5.isNum() && obj5.getNum() > 0)) { |
| linDict.free(); |
| linDict.initNull(); |
| } |
| obj5.free(); |
| } |
| obj3.free(); |
| obj2.free(); |
| obj1.free(); |
| delete parser; |
| } |
| |
| Linearization:: ~Linearization() |
| { |
| linDict.free(); |
| } |
| |
| Guint Linearization::getLength() |
| { |
| if (!linDict.isDict()) return 0; |
| |
| int length; |
| if (linDict.getDict()->lookupInt("L", NULL, &length) && |
| length > 0) { |
| return length; |
| } else { |
| error(errSyntaxWarning, -1, "Length in linearization table is invalid"); |
| return 0; |
| } |
| } |
| |
| Guint Linearization::getHintsOffset() |
| { |
| int hintsOffset; |
| |
| Object obj1, obj2; |
| if (linDict.isDict() && |
| linDict.dictLookup("H", &obj1)->isArray() && |
| obj1.arrayGetLength()>=2 && |
| obj1.arrayGet(0, &obj2)->isInt() && |
| obj2.getInt() > 0) { |
| hintsOffset = obj2.getInt(); |
| } else { |
| error(errSyntaxWarning, -1, "Hints table offset in linearization table is invalid"); |
| hintsOffset = 0; |
| } |
| obj2.free(); |
| obj1.free(); |
| |
| return hintsOffset; |
| } |
| |
| Guint Linearization::getHintsLength() |
| { |
| int hintsLength; |
| |
| Object obj1, obj2; |
| if (linDict.isDict() && |
| linDict.dictLookup("H", &obj1)->isArray() && |
| obj1.arrayGetLength()>=2 && |
| obj1.arrayGet(1, &obj2)->isInt() && |
| obj2.getInt() > 0) { |
| hintsLength = obj2.getInt(); |
| } else { |
| error(errSyntaxWarning, -1, "Hints table length in linearization table is invalid"); |
| hintsLength = 0; |
| } |
| obj2.free(); |
| obj1.free(); |
| |
| return hintsLength; |
| } |
| |
| Guint Linearization::getHintsOffset2() |
| { |
| int hintsOffset2 = 0; // default to 0 |
| |
| Object obj1, obj2; |
| if (linDict.isDict() && |
| linDict.dictLookup("H", &obj1)->isArray() && |
| obj1.arrayGetLength()>=4) { |
| if (obj1.arrayGet(2, &obj2)->isInt() && |
| obj2.getInt() > 0) { |
| hintsOffset2 = obj2.getInt(); |
| } else { |
| error(errSyntaxWarning, -1, "Second hints table offset in linearization table is invalid"); |
| hintsOffset2 = 0; |
| } |
| } |
| obj2.free(); |
| obj1.free(); |
| |
| return hintsOffset2; |
| } |
| |
| Guint Linearization::getHintsLength2() |
| { |
| int hintsLength2 = 0; // default to 0 |
| |
| Object obj1, obj2; |
| if (linDict.isDict() && |
| linDict.dictLookup("H", &obj1)->isArray() && |
| obj1.arrayGetLength()>=4) { |
| if (obj1.arrayGet(3, &obj2)->isInt() && |
| obj2.getInt() > 0) { |
| hintsLength2 = obj2.getInt(); |
| } else { |
| error(errSyntaxWarning, -1, "Second hints table length in linearization table is invalid"); |
| hintsLength2 = 0; |
| } |
| } |
| obj2.free(); |
| obj1.free(); |
| |
| return hintsLength2; |
| } |
| |
| int Linearization::getObjectNumberFirst() |
| { |
| int objectNumberFirst = 0; |
| if (linDict.isDict() && |
| linDict.getDict()->lookupInt("O", NULL, &objectNumberFirst) && |
| objectNumberFirst > 0) { |
| return objectNumberFirst; |
| } else { |
| error(errSyntaxWarning, -1, "Object number of first page in linearization table is invalid"); |
| return 0; |
| } |
| } |
| |
| Guint Linearization::getEndFirst() |
| { |
| int pageEndFirst = 0; |
| if (linDict.isDict() && |
| linDict.getDict()->lookupInt("E", NULL, &pageEndFirst) && |
| pageEndFirst > 0) { |
| return pageEndFirst; |
| } else { |
| error(errSyntaxWarning, -1, "First page end offset in linearization table is invalid"); |
| return 0; |
| } |
| } |
| |
| int Linearization::getNumPages() |
| { |
| int numPages = 0; |
| if (linDict.isDict() && |
| linDict.getDict()->lookupInt("N", NULL, &numPages) && |
| numPages > 0) { |
| return numPages; |
| } else { |
| error(errSyntaxWarning, -1, "Page count in linearization table is invalid"); |
| return 0; |
| } |
| } |
| |
| Guint Linearization::getMainXRefEntriesOffset() |
| { |
| int mainXRefEntriesOffset = 0; |
| if (linDict.isDict() && |
| linDict.getDict()->lookupInt("T", NULL, &mainXRefEntriesOffset) && |
| mainXRefEntriesOffset > 0) { |
| return mainXRefEntriesOffset; |
| } else { |
| error(errSyntaxWarning, -1, "Main Xref offset in linearization table is invalid"); |
| return 0; |
| } |
| } |
| |
| int Linearization::getPageFirst() |
| { |
| int pageFirst = 0; // Optional, defaults to 0. |
| |
| if (linDict.isDict()) { |
| linDict.getDict()->lookupInt("P", NULL, &pageFirst); |
| } |
| |
| if ((pageFirst < 0) || (pageFirst > getNumPages())) { |
| error(errSyntaxWarning, -1, "First page in linearization table is invalid"); |
| return 0; |
| } |
| |
| return pageFirst; |
| } |
| |
| |