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 : * Permission is hereby granted, free of charge, to any person obtaining a
19 : * copy of this software and associated documentation files (the "Software"),
20 : * to deal in the Software without restriction, including without limitation
21 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
22 : * and/or sell copies of the Software, and to permit persons to whom the
23 : * Software is furnished to do so, subject to the following conditions:
24 : *
25 : * The above copyright notice and this permission notice shall be included
26 : * in all copies or substantial portions of the Software.
27 : *
28 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
29 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
31 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
33 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 : * DEALINGS IN THE SOFTWARE.
35 : ****************************************************************************/
36 :
37 : #ifndef PDFOBJECT_H_INCLUDED
38 : #define PDFOBJECT_H_INCLUDED
39 :
40 : #include "pdfsdk_headers.h"
41 :
42 : #include "cpl_string.h"
43 : #include <map>
44 : #include <vector>
45 :
46 : #define DEFAULT_DPI (72.0)
47 : #define USER_UNIT_IN_INCH (1.0 / DEFAULT_DPI)
48 :
49 : double ROUND_TO_INT_IF_CLOSE(double x, double eps = 0);
50 :
51 : typedef enum
52 : {
53 : PDFObjectType_Unknown,
54 : PDFObjectType_Null,
55 : PDFObjectType_Bool,
56 : PDFObjectType_Int,
57 : PDFObjectType_Real,
58 : PDFObjectType_String,
59 : PDFObjectType_Name,
60 : PDFObjectType_Array,
61 : PDFObjectType_Dictionary
62 : } GDALPDFObjectType;
63 :
64 : class GDALPDFDictionary;
65 : class GDALPDFArray;
66 : class GDALPDFStream;
67 :
68 : class GDALPDFObjectRW;
69 : class GDALPDFDictionaryRW;
70 : class GDALPDFArrayRW;
71 :
72 : class GDALPDFObjectNum
73 : {
74 : int m_nId;
75 :
76 : public:
77 47529 : explicit GDALPDFObjectNum(int nId = 0) : m_nId(nId)
78 : {
79 47529 : }
80 :
81 : GDALPDFObjectNum(const GDALPDFObjectNum &other) = default;
82 : GDALPDFObjectNum &operator=(const GDALPDFObjectNum &) = default;
83 :
84 2674 : GDALPDFObjectNum &operator=(int nId)
85 : {
86 2674 : m_nId = nId;
87 2674 : return *this;
88 : }
89 :
90 16952 : int toInt() const
91 : {
92 16952 : return m_nId;
93 : }
94 :
95 19952 : bool toBool() const
96 : {
97 19952 : return m_nId > 0;
98 : }
99 :
100 29 : bool operator==(const GDALPDFObjectNum &other) const
101 : {
102 29 : return m_nId == other.m_nId;
103 : }
104 :
105 7 : bool operator<(const GDALPDFObjectNum &other) const
106 : {
107 7 : return m_nId < other.m_nId;
108 : }
109 : };
110 :
111 : class GDALPDFObject
112 : {
113 : protected:
114 : virtual const char *GetTypeNameNative() = 0;
115 :
116 : public:
117 : virtual ~GDALPDFObject();
118 :
119 : virtual GDALPDFObjectType GetType() = 0;
120 : virtual const char *GetTypeName();
121 : virtual int GetBool() = 0;
122 : virtual int GetInt() = 0;
123 : virtual double GetReal() = 0;
124 :
125 0 : virtual int CanRepresentRealAsString()
126 : {
127 0 : return FALSE;
128 : }
129 :
130 : virtual const std::string &GetString() = 0;
131 : virtual const std::string &GetName() = 0;
132 : virtual GDALPDFDictionary *GetDictionary() = 0;
133 : virtual GDALPDFArray *GetArray() = 0;
134 : virtual GDALPDFStream *GetStream() = 0;
135 : virtual GDALPDFObjectNum GetRefNum() = 0;
136 : virtual int GetRefGen() = 0;
137 :
138 0 : virtual int GetPrecision() const
139 : {
140 0 : return 16;
141 : }
142 :
143 : GDALPDFObject *LookupObject(const char *pszPath);
144 :
145 : void Serialize(CPLString &osStr, bool bEmitRef = true);
146 :
147 852 : CPLString Serialize()
148 : {
149 852 : CPLString osStr;
150 852 : Serialize(osStr);
151 852 : return osStr;
152 : }
153 :
154 : GDALPDFObjectRW *Clone();
155 : };
156 :
157 : class GDALPDFDictionary
158 : {
159 : public:
160 : virtual ~GDALPDFDictionary();
161 :
162 : virtual GDALPDFObject *Get(const char *pszKey) = 0;
163 : virtual std::map<CPLString, GDALPDFObject *> &GetValues() = 0;
164 :
165 : GDALPDFObject *LookupObject(const char *pszPath);
166 :
167 : void Serialize(CPLString &osStr);
168 :
169 1833 : CPLString Serialize()
170 : {
171 1833 : CPLString osStr;
172 1833 : Serialize(osStr);
173 1833 : return osStr;
174 : }
175 :
176 : GDALPDFDictionaryRW *Clone();
177 : };
178 :
179 : class GDALPDFArray
180 : {
181 : public:
182 : virtual ~GDALPDFArray();
183 :
184 : virtual int GetLength() = 0;
185 : virtual GDALPDFObject *Get(int nIndex) = 0;
186 :
187 : void Serialize(CPLString &osStr);
188 :
189 124 : CPLString Serialize()
190 : {
191 124 : CPLString osStr;
192 124 : Serialize(osStr);
193 124 : return osStr;
194 : }
195 :
196 : GDALPDFArrayRW *Clone();
197 : };
198 :
199 : class GDALPDFStream
200 : {
201 : public:
202 : virtual ~GDALPDFStream();
203 :
204 : /** Return the uncompressed stream length, or 0 if empty or error.
205 : * If nMaxSize > 0, GetLength() will possibly stop the decompression once
206 : * the threshold is reached, and return INT64_MAX */
207 : virtual int64_t GetLength(int64_t nMaxSize = 0) = 0;
208 : virtual char *GetBytes() = 0;
209 :
210 : virtual int64_t GetRawLength() = 0;
211 : virtual char *GetRawBytes() = 0;
212 : };
213 :
214 : class GDALPDFObjectRW : public GDALPDFObject
215 : {
216 : private:
217 : GDALPDFObjectType m_eType;
218 : int m_nVal;
219 : double m_dfVal;
220 : CPLString m_osVal;
221 : GDALPDFDictionaryRW *m_poDict;
222 : GDALPDFArrayRW *m_poArray;
223 : GDALPDFObjectNum m_nNum;
224 : int m_nGen;
225 : int m_bCanRepresentRealAsString;
226 : int m_nPrecision = 16;
227 :
228 : explicit GDALPDFObjectRW(GDALPDFObjectType eType);
229 :
230 : protected:
231 : virtual const char *GetTypeNameNative() override;
232 :
233 : public:
234 : static GDALPDFObjectRW *CreateIndirect(const GDALPDFObjectNum &nNum,
235 : int nGen);
236 : static GDALPDFObjectRW *CreateNull();
237 : static GDALPDFObjectRW *CreateBool(int bVal);
238 : static GDALPDFObjectRW *CreateInt(int nVal);
239 : static GDALPDFObjectRW *CreateReal(double dfVal,
240 : int bCanRepresentRealAsString = FALSE);
241 : static GDALPDFObjectRW *CreateRealWithPrecision(double dfVal,
242 : int nPrecision);
243 : static GDALPDFObjectRW *CreateString(const char *pszStr);
244 : static GDALPDFObjectRW *CreateName(const char *pszName);
245 : static GDALPDFObjectRW *CreateDictionary(GDALPDFDictionaryRW *poDict);
246 : static GDALPDFObjectRW *CreateArray(GDALPDFArrayRW *poArray);
247 : virtual ~GDALPDFObjectRW();
248 :
249 : virtual GDALPDFObjectType GetType() override;
250 : virtual int GetBool() override;
251 : virtual int GetInt() override;
252 : virtual double GetReal() override;
253 :
254 851 : virtual int CanRepresentRealAsString() override
255 : {
256 851 : return m_bCanRepresentRealAsString;
257 : }
258 :
259 : virtual const CPLString &GetString() override;
260 : virtual const CPLString &GetName() override;
261 : virtual GDALPDFDictionary *GetDictionary() override;
262 : virtual GDALPDFArray *GetArray() override;
263 : virtual GDALPDFStream *GetStream() override;
264 : virtual GDALPDFObjectNum GetRefNum() override;
265 : virtual int GetRefGen() override;
266 :
267 851 : virtual int GetPrecision() const override
268 : {
269 851 : return m_nPrecision;
270 : }
271 : };
272 :
273 : class GDALPDFDictionaryRW : public GDALPDFDictionary
274 : {
275 : private:
276 : std::map<CPLString, GDALPDFObject *> m_map;
277 :
278 : public:
279 : GDALPDFDictionaryRW();
280 : virtual ~GDALPDFDictionaryRW();
281 :
282 : virtual GDALPDFObject *Get(const char *pszKey) override;
283 : virtual std::map<CPLString, GDALPDFObject *> &GetValues() override;
284 :
285 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFObject *poVal);
286 : GDALPDFDictionaryRW &Remove(const char *pszKey);
287 :
288 1076 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFArrayRW *poArray)
289 : {
290 1076 : return Add(pszKey, GDALPDFObjectRW::CreateArray(poArray));
291 : }
292 :
293 752 : GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFDictionaryRW *poDict)
294 : {
295 752 : return Add(pszKey, GDALPDFObjectRW::CreateDictionary(poDict));
296 : }
297 :
298 772 : GDALPDFDictionaryRW &Add(const char *pszKey, const char *pszVal)
299 : {
300 772 : return Add(pszKey, GDALPDFObjectRW::CreateString(pszVal));
301 : }
302 :
303 1466 : GDALPDFDictionaryRW &Add(const char *pszKey, int nVal)
304 : {
305 1466 : return Add(pszKey, GDALPDFObjectRW::CreateInt(nVal));
306 : }
307 :
308 255 : GDALPDFDictionaryRW &Add(const char *pszKey, double dfVal,
309 : int bCanRepresentRealAsString = FALSE)
310 : {
311 255 : return Add(pszKey, GDALPDFObjectRW::CreateReal(
312 255 : dfVal, bCanRepresentRealAsString));
313 : }
314 :
315 2331 : GDALPDFDictionaryRW &Add(const char *pszKey, const GDALPDFObjectNum &nNum,
316 : int nGen)
317 : {
318 2331 : return Add(pszKey, GDALPDFObjectRW::CreateIndirect(nNum, nGen));
319 : }
320 : };
321 :
322 : class GDALPDFArrayRW : public GDALPDFArray
323 : {
324 : private:
325 : std::vector<GDALPDFObject *> m_array;
326 :
327 : public:
328 : GDALPDFArrayRW();
329 : virtual ~GDALPDFArrayRW();
330 :
331 : virtual int GetLength() override;
332 : virtual GDALPDFObject *Get(int nIndex) override;
333 :
334 : GDALPDFArrayRW &Add(GDALPDFObject *poObj);
335 :
336 25 : GDALPDFArrayRW &Add(GDALPDFArrayRW *poArray)
337 : {
338 25 : return Add(GDALPDFObjectRW::CreateArray(poArray));
339 : }
340 :
341 194 : GDALPDFArrayRW &Add(GDALPDFDictionaryRW *poDict)
342 : {
343 194 : return Add(GDALPDFObjectRW::CreateDictionary(poDict));
344 : }
345 :
346 3 : GDALPDFArrayRW &Add(const char *pszVal)
347 : {
348 3 : return Add(GDALPDFObjectRW::CreateString(pszVal));
349 : }
350 :
351 1993 : GDALPDFArrayRW &Add(int nVal)
352 : {
353 1993 : return Add(GDALPDFObjectRW::CreateInt(nVal));
354 : }
355 :
356 1520 : GDALPDFArrayRW &Add(double dfVal, int bCanRepresentRealAsString = FALSE)
357 : {
358 : return Add(
359 1520 : GDALPDFObjectRW::CreateReal(dfVal, bCanRepresentRealAsString));
360 : }
361 :
362 64 : GDALPDFArrayRW &AddWithPrecision(double dfVal, int nPrecision)
363 : {
364 64 : return Add(GDALPDFObjectRW::CreateRealWithPrecision(dfVal, nPrecision));
365 : }
366 :
367 : GDALPDFArrayRW &Add(double *padfVal, int nCount,
368 : int bCanRepresentRealAsString = FALSE);
369 :
370 476 : GDALPDFArrayRW &Add(const GDALPDFObjectNum &nNum, int nGen)
371 : {
372 476 : return Add(GDALPDFObjectRW::CreateIndirect(nNum, nGen));
373 : }
374 : };
375 :
376 : #ifdef HAVE_POPPLER
377 :
378 : class GDALPDFObjectPoppler : public GDALPDFObject
379 : {
380 : private:
381 : Object *m_po;
382 : int m_bDestroy;
383 : GDALPDFDictionary *m_poDict;
384 : GDALPDFArray *m_poArray;
385 : GDALPDFStream *m_poStream;
386 : std::string osStr;
387 : GDALPDFObjectNum m_nRefNum;
388 : int m_nRefGen;
389 :
390 : protected:
391 : virtual const char *GetTypeNameNative() override;
392 :
393 : public:
394 11943 : GDALPDFObjectPoppler(Object *po, int bDestroy)
395 11943 : : m_po(po), m_bDestroy(bDestroy), m_poDict(nullptr), m_poArray(nullptr),
396 11943 : m_poStream(nullptr), m_nRefNum(0), m_nRefGen(0)
397 : {
398 11943 : }
399 :
400 : void SetRefNumAndGen(const GDALPDFObjectNum &nNum, int nGen);
401 :
402 : virtual ~GDALPDFObjectPoppler();
403 :
404 : virtual GDALPDFObjectType GetType() override;
405 : virtual int GetBool() override;
406 : virtual int GetInt() override;
407 : virtual double GetReal() override;
408 : virtual const std::string &GetString() override;
409 : virtual const std::string &GetName() override;
410 : virtual GDALPDFDictionary *GetDictionary() override;
411 : virtual GDALPDFArray *GetArray() override;
412 : virtual GDALPDFStream *GetStream() override;
413 : virtual GDALPDFObjectNum GetRefNum() override;
414 : virtual int GetRefGen() override;
415 : };
416 :
417 : GDALPDFArray *GDALPDFCreateArray(Array *array);
418 :
419 : #endif // HAVE_POPPLER
420 :
421 : #ifdef HAVE_PODOFO
422 :
423 : class GDALPDFObjectPodofo : public GDALPDFObject
424 : {
425 : private:
426 : const PoDoFo::PdfObject *m_po;
427 : const PoDoFo::PdfVecObjects &m_poObjects;
428 : GDALPDFDictionary *m_poDict;
429 : GDALPDFArray *m_poArray;
430 : GDALPDFStream *m_poStream;
431 : std::string osStr;
432 :
433 : protected:
434 : virtual const char *GetTypeNameNative() override;
435 :
436 : public:
437 : GDALPDFObjectPodofo(const PoDoFo::PdfObject *po,
438 : const PoDoFo::PdfVecObjects &poObjects);
439 :
440 : virtual ~GDALPDFObjectPodofo();
441 :
442 : virtual GDALPDFObjectType GetType() override;
443 : virtual int GetBool() override;
444 : virtual int GetInt() override;
445 : virtual double GetReal() override;
446 : virtual const std::string &GetString() override;
447 : virtual const std::string &GetName() override;
448 : virtual GDALPDFDictionary *GetDictionary() override;
449 : virtual GDALPDFArray *GetArray() override;
450 : virtual GDALPDFStream *GetStream() override;
451 : virtual GDALPDFObjectNum GetRefNum() override;
452 : virtual int GetRefGen() override;
453 : };
454 :
455 : #endif // HAVE_PODOFO
456 :
457 : #ifdef HAVE_PDFIUM
458 :
459 : class GDALPDFObjectPdfium : public GDALPDFObject
460 : {
461 : private:
462 : RetainPtr<const CPDF_Object> m_obj;
463 : GDALPDFDictionary *m_poDict;
464 : GDALPDFArray *m_poArray;
465 : GDALPDFStream *m_poStream;
466 : std::string osStr;
467 :
468 : GDALPDFObjectPdfium(RetainPtr<const CPDF_Object> obj);
469 :
470 : protected:
471 : virtual const char *GetTypeNameNative() override;
472 :
473 : public:
474 : static GDALPDFObjectPdfium *Build(RetainPtr<const CPDF_Object> obj);
475 :
476 : virtual ~GDALPDFObjectPdfium();
477 :
478 : virtual GDALPDFObjectType GetType() override;
479 : virtual int GetBool() override;
480 : virtual int GetInt() override;
481 : virtual double GetReal() override;
482 : virtual const std::string &GetString() override;
483 : virtual const std::string &GetName() override;
484 : virtual GDALPDFDictionary *GetDictionary() override;
485 : virtual GDALPDFArray *GetArray() override;
486 : virtual GDALPDFStream *GetStream() override;
487 : virtual GDALPDFObjectNum GetRefNum() override;
488 : virtual int GetRefGen() override;
489 : };
490 :
491 : #endif // HAVE_PDFIUM
492 :
493 : #endif // PDFOBJECT_H_INCLUDED
|