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