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