blob: 7cf9eda104438ab6b4774f836afde79d18c403f2 [file] [log] [blame]
//========================================================================
//
// Linearization.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2010, 2012 Hib Eris <hib@hiberis.nl>
// Copyright 2015 Jason Crain <jason@aquaticape.us>
// Copyright 2017, 2019 Albert Astals Cid <aacid@kde.org>
// Copyright 2019 Adam Reichold <adam.reichold@t-online.de>
// Copyright 2019 Even Rouault <even.rouault@spatialys.com>
//
//========================================================================
#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;
}