Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: PDF driver
5 : * Purpose: GDALDataset driver for PDF dataset.
6 : * Author: Even Rouault, <even dot rouault at spatialys.com>
7 : *
8 : ******************************************************************************
9 : *
10 : * Support for open-source PDFium library
11 : *
12 : * Copyright (C) 2015 Klokan Technologies GmbH (http://www.klokantech.com/)
13 : * Author: Martin Mikita <martin.mikita@klokantech.com>, xmikit00 @ FIT VUT Brno
14 : *
15 : ******************************************************************************
16 : * Copyright (c) 2011-2014, Even Rouault <even dot rouault at spatialys.com>
17 : *
18 : * SPDX-License-Identifier: MIT
19 : ****************************************************************************/
20 :
21 : #ifndef PDFOBJECT_H_INCLUDED
22 : #define PDFOBJECT_H_INCLUDED
23 :
24 : #include "pdfsdk_headers_all.h"
25 :
26 : #include "cpl_string.h"
27 : #include <map>
28 : #include <vector>
29 :
30 : #define DEFAULT_DPI (72.0)
31 : #define USER_UNIT_IN_INCH (1.0 / DEFAULT_DPI)
32 :
33 : double ROUND_IF_CLOSE(double x, double eps = 0);
34 :
35 : typedef enum
36 : {
37 : PDFObjectType_Unknown,
38 : PDFObjectType_Null,
39 : PDFObjectType_Bool,
40 : PDFObjectType_Int,
41 : PDFObjectType_Real,
42 : PDFObjectType_String,
43 : PDFObjectType_Name,
44 : PDFObjectType_Array,
45 : PDFObjectType_Dictionary
46 : } GDALPDFObjectType;
47 :
48 : class GDALPDFDictionary;
49 : class GDALPDFArray;
50 : class GDALPDFStream;
51 :
52 : class GDALPDFObjectRW;
53 : class GDALPDFDictionaryRW;
54 : class GDALPDFArrayRW;
55 :
56 : class GDALPDFObjectNum
57 : {
58 : int m_nId;
59 :
60 : public:
61 51681 : explicit GDALPDFObjectNum(int nId = 0) : m_nId(nId)
62 : {
63 51681 : }
64 :
65 : GDALPDFObjectNum(const GDALPDFObjectNum &other) = default;
66 : GDALPDFObjectNum &operator=(const GDALPDFObjectNum &) = default;
67 :
68 2797 : GDALPDFObjectNum &operator=(int nId)
69 : {
70 2797 : m_nId = nId;
71 2797 : return *this;
72 : }
73 :
74 19242 : int toInt() const
75 : {
76 19242 : return m_nId;
77 : }
78 :
79 22513 : bool toBool() const
80 : {
81 22513 : return m_nId > 0;
82 : }
83 :
84 33 : bool operator==(const GDALPDFObjectNum &other) const
85 : {
86 33 : return m_nId == other.m_nId;
87 : }
88 :
89 7 : bool operator<(const GDALPDFObjectNum &other) const
90 : {
91 7 : return m_nId < other.m_nId;
92 : }
93 : };
94 :
95 : class GDALPDFObject
96 : {
97 : protected:
98 : virtual const char *GetTypeNameNative() = 0;
99 :
100 : public:
101 : virtual ~GDALPDFObject();
102 :
103 : virtual GDALPDFObjectType GetType() = 0;
104 : virtual const char *GetTypeName();
105 : virtual int GetBool() = 0;
106 : virtual int GetInt() = 0;
107 : virtual double GetReal() = 0;
108 :
109 0 : virtual int CanRepresentRealAsString()
110 : {
111 0 : return FALSE;
112 : }
113 :
114 : virtual const std::string &GetString() = 0;
115 : virtual const std::string &GetName() = 0;
116 : virtual GDALPDFDictionary *GetDictionary() = 0;
117 : virtual GDALPDFArray *GetArray() = 0;
118 : virtual GDALPDFStream *GetStream() = 0;
119 : virtual GDALPDFObjectNum GetRefNum() = 0;
120 : virtual int GetRefGen() = 0;
121 :
122 0 : virtual int GetPrecision() const
123 : {
124 0 : return 16;
125 : }
126 :
127 : GDALPDFObject *LookupObject(const char *pszPath);
128 :
129 : void Serialize(CPLString &osStr, bool bEmitRef = true);
130 :
131 852 : CPLString Serialize()
132 : {
133 852 : CPLString osStr;
134 852 : Serialize(osStr);
135 852 : return osStr;
136 : }
137 :
138 : GDALPDFObjectRW *Clone();
139 : };
140 :
141 : class GDALPDFDictionary
142 : {
143 : public:
144 : virtual ~GDALPDFDictionary();
145 :
146 : virtual GDALPDFObject *Get(const char *pszKey) = 0;
147 : virtual std::map<CPLString, GDALPDFObject *> &GetValues() = 0;
148 :
149 : GDALPDFObject *LookupObject(const char *pszPath);
150 :
151 : void Serialize(CPLString &osStr);
152 :
153 1977 : CPLString Serialize()
154 : {
155 1977 : CPLString osStr;
156 1977 : Serialize(osStr);
157 1977 : return osStr;
158 : }
159 :
160 : GDALPDFDictionaryRW *Clone();
161 : };
162 :
163 : class GDALPDFArray
164 : {
165 : public:
166 : virtual ~GDALPDFArray();
167 :
168 : virtual int GetLength() = 0;
169 : virtual GDALPDFObject *Get(int nIndex) = 0;
170 :
171 : void Serialize(CPLString &osStr);
172 :
173 128 : CPLString Serialize()
174 : {
175 128 : CPLString osStr;
176 128 : Serialize(osStr);
177 128 : return osStr;
178 : }
179 :
180 : GDALPDFArrayRW *Clone();
181 : };
182 :
183 811 : class GDALPDFStream
184 : {
185 : public:
186 : virtual ~GDALPDFStream();
187 :
188 : /** Return the uncompressed stream length, or 0 if empty or error.
189 : * If nMaxSize > 0, GetLength() will possibly stop the decompression once
190 : * the threshold is reached, and return INT64_MAX */
191 : virtual int64_t GetLength(int64_t nMaxSize = 0) = 0;
192 : virtual char *GetBytes() = 0;
193 :
194 : virtual int64_t GetRawLength() = 0;
195 : virtual char *GetRawBytes() = 0;
196 : };
197 :
198 : class GDALPDFObjectRW : public GDALPDFObject
199 : {
200 : private:
201 : const GDALPDFObjectType m_eType;
202 : int m_nVal = 0;
203 : double m_dfVal = 0;
204 : CPLString m_osVal{};
205 : GDALPDFDictionaryRW *m_poDict = nullptr;
206 : GDALPDFArrayRW *m_poArray = nullptr;
207 : GDALPDFObjectNum m_nNum{};
208 : int m_nGen = 0;
209 : int m_bCanRepresentRealAsString = FALSE;
210 : int m_nPrecision = 16;
211 :
212 : explicit GDALPDFObjectRW(GDALPDFObjectType eType);
213 :
214 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectRW)
215 :
216 : protected:
217 : virtual const char *GetTypeNameNative() override;
218 :
219 : public:
220 : static GDALPDFObjectRW *CreateIndirect(const GDALPDFObjectNum &nNum,
221 : int nGen);
222 : static GDALPDFObjectRW *CreateNull();
223 : static GDALPDFObjectRW *CreateBool(int bVal);
224 : static GDALPDFObjectRW *CreateInt(int nVal);
225 : static GDALPDFObjectRW *CreateReal(double dfVal,
226 : int bCanRepresentRealAsString = FALSE);
227 : static GDALPDFObjectRW *CreateRealWithPrecision(double dfVal,
228 : int nPrecision);
229 : static GDALPDFObjectRW *CreateString(const char *pszStr);
230 : static GDALPDFObjectRW *CreateName(const char *pszName);
231 : static GDALPDFObjectRW *CreateDictionary(GDALPDFDictionaryRW *poDict);
232 : static GDALPDFObjectRW *CreateArray(GDALPDFArrayRW *poArray);
233 : virtual ~GDALPDFObjectRW();
234 :
235 : virtual GDALPDFObjectType GetType() override;
236 : virtual int GetBool() override;
237 : virtual int GetInt() override;
238 : virtual double GetReal() override;
239 :
240 865 : virtual int CanRepresentRealAsString() override
241 : {
242 865 : return m_bCanRepresentRealAsString;
243 : }
244 :
245 : virtual const CPLString &GetString() override;
246 : virtual const CPLString &GetName() override;
247 : virtual GDALPDFDictionary *GetDictionary() override;
248 : virtual GDALPDFArray *GetArray() override;
249 : virtual GDALPDFStream *GetStream() override;
250 : virtual GDALPDFObjectNum GetRefNum() override;
251 : virtual int GetRefGen() override;
252 :
253 865 : virtual int GetPrecision() const override
254 : {
255 865 : return m_nPrecision;
256 : }
257 : };
258 :
259 3191 : class GDALPDFDictionaryRW : public GDALPDFDictionary
260 : {
261 : private:
262 : std::map<CPLString, GDALPDFObject *> m_map{};
263 :
264 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFDictionaryRW)
265 :
266 : public:
267 : GDALPDFDictionaryRW();
268 : virtual ~GDALPDFDictionaryRW();
269 :
270 : virtual GDALPDFObject *Get(const char *pszKey) override;
271 : virtual std::map<CPLString, GDALPDFObject *> &GetValues() override;
272 :
273 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFObject *poVal);
274 : GDALPDFDictionaryRW &Remove(const char *pszKey);
275 :
276 1216 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFArrayRW *poArray)
277 : {
278 1216 : return Add(pszKey, GDALPDFObjectRW::CreateArray(poArray));
279 : }
280 :
281 994 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFDictionaryRW *poDict)
282 : {
283 994 : return Add(pszKey, GDALPDFObjectRW::CreateDictionary(poDict));
284 : }
285 :
286 844 : GDALPDFDictionaryRW &Add(const char *pszKey, const char *pszVal)
287 : {
288 844 : return Add(pszKey, GDALPDFObjectRW::CreateString(pszVal));
289 : }
290 :
291 1528 : GDALPDFDictionaryRW &Add(const char *pszKey, int nVal)
292 : {
293 1528 : return Add(pszKey, GDALPDFObjectRW::CreateInt(nVal));
294 : }
295 :
296 273 : GDALPDFDictionaryRW &Add(const char *pszKey, double dfVal,
297 : int bCanRepresentRealAsString = FALSE)
298 : {
299 273 : return Add(pszKey, GDALPDFObjectRW::CreateReal(
300 273 : dfVal, bCanRepresentRealAsString));
301 : }
302 :
303 2567 : GDALPDFDictionaryRW &Add(const char *pszKey, const GDALPDFObjectNum &nNum,
304 : int nGen)
305 : {
306 2567 : return Add(pszKey, GDALPDFObjectRW::CreateIndirect(nNum, nGen));
307 : }
308 : };
309 :
310 : class GDALPDFArrayRW : public GDALPDFArray
311 : {
312 : private:
313 : std::vector<GDALPDFObject *> m_array{};
314 :
315 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFArrayRW)
316 :
317 : public:
318 : GDALPDFArrayRW();
319 : virtual ~GDALPDFArrayRW();
320 :
321 : virtual int GetLength() override;
322 : virtual GDALPDFObject *Get(int nIndex) override;
323 :
324 : GDALPDFArrayRW &Add(GDALPDFObject *poObj);
325 :
326 29 : GDALPDFArrayRW &Add(GDALPDFArrayRW *poArray)
327 : {
328 29 : return Add(GDALPDFObjectRW::CreateArray(poArray));
329 : }
330 :
331 206 : GDALPDFArrayRW &Add(GDALPDFDictionaryRW *poDict)
332 : {
333 206 : return Add(GDALPDFObjectRW::CreateDictionary(poDict));
334 : }
335 :
336 3 : GDALPDFArrayRW &Add(const char *pszVal)
337 : {
338 3 : return Add(GDALPDFObjectRW::CreateString(pszVal));
339 : }
340 :
341 2317 : GDALPDFArrayRW &Add(int nVal)
342 : {
343 2317 : return Add(GDALPDFObjectRW::CreateInt(nVal));
344 : }
345 :
346 1624 : GDALPDFArrayRW &Add(double dfVal, int bCanRepresentRealAsString = FALSE)
347 : {
348 : return Add(
349 1624 : GDALPDFObjectRW::CreateReal(dfVal, bCanRepresentRealAsString));
350 : }
351 :
352 64 : GDALPDFArrayRW &AddWithPrecision(double dfVal, int nPrecision)
353 : {
354 64 : return Add(GDALPDFObjectRW::CreateRealWithPrecision(dfVal, nPrecision));
355 : }
356 :
357 : GDALPDFArrayRW &Add(double *padfVal, int nCount,
358 : int bCanRepresentRealAsString = FALSE);
359 :
360 534 : GDALPDFArrayRW &Add(const GDALPDFObjectNum &nNum, int nGen)
361 : {
362 534 : return Add(GDALPDFObjectRW::CreateIndirect(nNum, nGen));
363 : }
364 : };
365 :
366 : #ifdef HAVE_POPPLER
367 :
368 : class GDALPDFObjectPoppler : public GDALPDFObject
369 : {
370 : private:
371 : Object *m_po;
372 : const bool m_bDestroy;
373 : GDALPDFDictionary *m_poDict = nullptr;
374 : GDALPDFArray *m_poArray = nullptr;
375 : GDALPDFStream *m_poStream = nullptr;
376 : std::string osStr{};
377 : GDALPDFObjectNum m_nRefNum{};
378 : int m_nRefGen = 0;
379 :
380 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPoppler)
381 :
382 : protected:
383 : virtual const char *GetTypeNameNative() override;
384 :
385 : public:
386 12403 : GDALPDFObjectPoppler(Object *po, bool bDestroy)
387 12403 : : m_po(po), m_bDestroy(bDestroy)
388 : {
389 12403 : }
390 :
391 : void SetRefNumAndGen(const GDALPDFObjectNum &nNum, int nGen);
392 :
393 : virtual ~GDALPDFObjectPoppler();
394 :
395 : virtual GDALPDFObjectType GetType() override;
396 : virtual int GetBool() override;
397 : virtual int GetInt() override;
398 : virtual double GetReal() override;
399 : virtual const std::string &GetString() override;
400 : virtual const std::string &GetName() override;
401 : virtual GDALPDFDictionary *GetDictionary() override;
402 : virtual GDALPDFArray *GetArray() override;
403 : virtual GDALPDFStream *GetStream() override;
404 : virtual GDALPDFObjectNum GetRefNum() override;
405 : virtual int GetRefGen() override;
406 : };
407 :
408 : GDALPDFArray *GDALPDFCreateArray(Array *array);
409 :
410 : #endif // HAVE_POPPLER
411 :
412 : #ifdef HAVE_PODOFO
413 :
414 : class GDALPDFObjectPodofo : public GDALPDFObject
415 : {
416 : private:
417 : const PoDoFo::PdfObject *m_po;
418 : const PoDoFo::PdfVecObjects &m_poObjects;
419 : GDALPDFDictionary *m_poDict = nullptr;
420 : GDALPDFArray *m_poArray = nullptr;
421 : GDALPDFStream *m_poStream = nullptr;
422 : std::string osStr{};
423 :
424 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPodofo)
425 :
426 : protected:
427 : virtual const char *GetTypeNameNative() override;
428 :
429 : public:
430 : GDALPDFObjectPodofo(const PoDoFo::PdfObject *po,
431 : const PoDoFo::PdfVecObjects &poObjects);
432 :
433 : virtual ~GDALPDFObjectPodofo();
434 :
435 : virtual GDALPDFObjectType GetType() override;
436 : virtual int GetBool() override;
437 : virtual int GetInt() override;
438 : virtual double GetReal() override;
439 : virtual const std::string &GetString() override;
440 : virtual const std::string &GetName() override;
441 : virtual GDALPDFDictionary *GetDictionary() override;
442 : virtual GDALPDFArray *GetArray() override;
443 : virtual GDALPDFStream *GetStream() override;
444 : virtual GDALPDFObjectNum GetRefNum() override;
445 : virtual int GetRefGen() override;
446 : };
447 :
448 : #endif // HAVE_PODOFO
449 :
450 : #ifdef HAVE_PDFIUM
451 :
452 : class GDALPDFObjectPdfium : public GDALPDFObject
453 : {
454 : private:
455 : RetainPtr<const CPDF_Object> m_obj;
456 : GDALPDFDictionary *m_poDict = nullptr;
457 : GDALPDFArray *m_poArray = nullptr;
458 : GDALPDFStream *m_poStream = nullptr;
459 : std::string osStr{};
460 :
461 : GDALPDFObjectPdfium(RetainPtr<const CPDF_Object> obj);
462 :
463 : CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPdfium)
464 :
465 : protected:
466 : virtual const char *GetTypeNameNative() override;
467 :
468 : public:
469 : static GDALPDFObjectPdfium *Build(RetainPtr<const CPDF_Object> obj);
470 :
471 : virtual ~GDALPDFObjectPdfium();
472 :
473 : virtual GDALPDFObjectType GetType() override;
474 : virtual int GetBool() override;
475 : virtual int GetInt() override;
476 : virtual double GetReal() override;
477 : virtual const std::string &GetString() override;
478 : virtual const std::string &GetName() override;
479 : virtual GDALPDFDictionary *GetDictionary() override;
480 : virtual GDALPDFArray *GetArray() override;
481 : virtual GDALPDFStream *GetStream() override;
482 : virtual GDALPDFObjectNum GetRefNum() override;
483 : virtual int GetRefGen() override;
484 : };
485 :
486 : #endif // HAVE_PDFIUM
487 :
488 : #endif // PDFOBJECT_H_INCLUDED
|