mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-04-10 19:15:13 +00:00
186 lines
5.5 KiB
Plaintext
186 lines
5.5 KiB
Plaintext
//========================================================================
|
|
//
|
|
// 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;
|
|
}
|