1//========================================================================
2//
3// Linearization.cc
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2010, 2012 Hib Eris <hib@hiberis.nl>
8// Copyright 2015 Jason Crain <jason@aquaticape.us>
9// Copyright 2017, 2019 Albert Astals Cid <aacid@kde.org>
10// Copyright 2019 Adam Reichold <adam.reichold@t-online.de>
11// Copyright 2019 Even Rouault <even.rouault@spatialys.com>
12//
13//========================================================================
14
15#include "Linearization.h"
16#include "Parser.h"
17#include "Lexer.h"
18
19//------------------------------------------------------------------------
20// Linearization
21//------------------------------------------------------------------------
22
23Linearization::Linearization(BaseStream *str)
24{
25 Parser *parser;
26
27 str->reset();
28 parser = new Parser(nullptr, str->makeSubStream(start: str->getStart(), limited: false, length: 0, dict: Object(objNull)), false);
29 Object obj1 = parser->getObj();
30 Object obj2 = parser->getObj();
31 Object obj3 = parser->getObj();
32 linDict = parser->getObj();
33 if (obj1.isInt() && obj2.isInt() && obj3.isCmd(cmdA: "obj") && linDict.isDict()) {
34 Object obj5 = linDict.dictLookup(key: "Linearized");
35 if (!(obj5.isNum() && obj5.getNum() > 0)) {
36 linDict.setToNull();
37 }
38 } else {
39 linDict.setToNull();
40 }
41 delete parser;
42}
43
44Linearization::~Linearization() { }
45
46unsigned int Linearization::getLength() const
47{
48 if (!linDict.isDict()) {
49 return 0;
50 }
51
52 int length;
53 if (linDict.getDict()->lookupInt(key: "L", alt_key: nullptr, value: &length) && length > 0) {
54 return length;
55 } else {
56 error(category: errSyntaxWarning, pos: -1, msg: "Length in linearization table is invalid");
57 return 0;
58 }
59}
60
61unsigned int Linearization::getHintsOffset() const
62{
63 int hintsOffset;
64
65 Object obj1, obj2;
66 if (linDict.isDict() && (obj1 = linDict.dictLookup(key: "H"), obj1.isArray()) && obj1.arrayGetLength() >= 2 && (obj2 = obj1.arrayGet(i: 0), obj2.isInt()) && obj2.getInt() > 0) {
67 hintsOffset = obj2.getInt();
68 } else {
69 error(category: errSyntaxWarning, pos: -1, msg: "Hints table offset in linearization table is invalid");
70 hintsOffset = 0;
71 }
72
73 return hintsOffset;
74}
75
76unsigned int Linearization::getHintsLength() const
77{
78 int hintsLength;
79
80 Object obj1, obj2;
81 if (linDict.isDict() && (obj1 = linDict.dictLookup(key: "H"), obj1.isArray()) && obj1.arrayGetLength() >= 2 && (obj2 = obj1.arrayGet(i: 1), obj2.isInt()) && obj2.getInt() > 0) {
82 hintsLength = obj2.getInt();
83 } else {
84 error(category: errSyntaxWarning, pos: -1, msg: "Hints table length in linearization table is invalid");
85 hintsLength = 0;
86 }
87
88 return hintsLength;
89}
90
91unsigned int Linearization::getHintsOffset2() const
92{
93 int hintsOffset2 = 0; // default to 0
94
95 Object obj1;
96 if (linDict.isDict() && (obj1 = linDict.dictLookup(key: "H"), obj1.isArray()) && obj1.arrayGetLength() >= 4) {
97 Object obj2 = obj1.arrayGet(i: 2);
98 if (obj2.isInt() && obj2.getInt() > 0) {
99 hintsOffset2 = obj2.getInt();
100 } else {
101 error(category: errSyntaxWarning, pos: -1, msg: "Second hints table offset in linearization table is invalid");
102 hintsOffset2 = 0;
103 }
104 }
105
106 return hintsOffset2;
107}
108
109unsigned int Linearization::getHintsLength2() const
110{
111 int hintsLength2 = 0; // default to 0
112
113 Object obj1;
114 if (linDict.isDict() && (obj1 = linDict.dictLookup(key: "H"), obj1.isArray()) && obj1.arrayGetLength() >= 4) {
115 Object obj2 = obj1.arrayGet(i: 3);
116 if (obj2.isInt() && obj2.getInt() > 0) {
117 hintsLength2 = obj2.getInt();
118 } else {
119 error(category: errSyntaxWarning, pos: -1, msg: "Second hints table length in linearization table is invalid");
120 hintsLength2 = 0;
121 }
122 }
123
124 return hintsLength2;
125}
126
127int Linearization::getObjectNumberFirst() const
128{
129 int objectNumberFirst = 0;
130 if (linDict.isDict() && linDict.getDict()->lookupInt(key: "O", alt_key: nullptr, value: &objectNumberFirst) && objectNumberFirst > 0) {
131 return objectNumberFirst;
132 } else {
133 error(category: errSyntaxWarning, pos: -1, msg: "Object number of first page in linearization table is invalid");
134 return 0;
135 }
136}
137
138unsigned int Linearization::getEndFirst() const
139{
140 int pageEndFirst = 0;
141 if (linDict.isDict() && linDict.getDict()->lookupInt(key: "E", alt_key: nullptr, value: &pageEndFirst) && pageEndFirst > 0) {
142 return pageEndFirst;
143 } else {
144 error(category: errSyntaxWarning, pos: -1, msg: "First page end offset in linearization table is invalid");
145 return 0;
146 }
147}
148
149int Linearization::getNumPages() const
150{
151 int numPages = 0;
152 if (linDict.isDict() && linDict.getDict()->lookupInt(key: "N", alt_key: nullptr, value: &numPages) && numPages > 0) {
153 return numPages;
154 } else {
155 error(category: errSyntaxWarning, pos: -1, msg: "Page count in linearization table is invalid");
156 return 0;
157 }
158}
159
160unsigned int Linearization::getMainXRefEntriesOffset() const
161{
162 int mainXRefEntriesOffset = 0;
163 if (linDict.isDict() && linDict.getDict()->lookupInt(key: "T", alt_key: nullptr, value: &mainXRefEntriesOffset) && mainXRefEntriesOffset > 0) {
164 return mainXRefEntriesOffset;
165 } else {
166 error(category: errSyntaxWarning, pos: -1, msg: "Main Xref offset in linearization table is invalid");
167 return 0;
168 }
169}
170
171int Linearization::getPageFirst() const
172{
173 int pageFirst = 0; // Optional, defaults to 0.
174
175 if (linDict.isDict()) {
176 linDict.getDict()->lookupInt(key: "P", alt_key: nullptr, value: &pageFirst);
177 }
178
179 if ((pageFirst < 0) || (pageFirst >= getNumPages())) {
180 error(category: errSyntaxWarning, pos: -1, msg: "First page in linearization table is invalid");
181 return 0;
182 }
183
184 return pageFirst;
185}
186

source code of poppler/poppler/Linearization.cc