1 : /******************************************************************************
2 : * $Id: pdfobject.cpp 22503 2011-06-04 22:08:34Z rouault $
3 : *
4 : * Project: PDF driver
5 : * Purpose: GDALDataset driver for PDF dataset.
6 : * Author: Even Rouault, <even dot rouault at mines dash paris dot org>
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2011, Even Rouault
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef bool GBool" */
31 : /* in include/poppler/goo/gtypes.h with the one defined in cpl_port.h */
32 : #define CPL_GBOOL_DEFINED
33 :
34 : #include <vector>
35 : #include "pdfobject.h"
36 :
37 : CPL_CVSID("$Id: pdfobject.cpp 22503 2011-06-04 22:08:34Z rouault $");
38 :
39 142 : GDALPDFObject::~GDALPDFObject()
40 : {
41 142 : }
42 :
43 16 : GDALPDFDictionary::~GDALPDFDictionary()
44 : {
45 16 : }
46 :
47 18 : GDALPDFArray::~GDALPDFArray()
48 : {
49 18 : }
50 :
51 : #ifdef USE_POPPLER
52 :
53 : class GDALPDFDictionaryPoppler: public GDALPDFDictionary
54 : {
55 : private:
56 : Dict* m_poDict;
57 : std::map<CPLString, GDALPDFObject*> m_map;
58 :
59 : public:
60 16 : GDALPDFDictionaryPoppler(Dict* poDict) : m_poDict(poDict) {}
61 : virtual ~GDALPDFDictionaryPoppler();
62 :
63 : virtual GDALPDFObject* Get(const char* pszKey);
64 : virtual std::map<CPLString, GDALPDFObject*>& GetValues();
65 : };
66 :
67 : class GDALPDFArrayPoppler : public GDALPDFArray
68 : {
69 : private:
70 : Array* m_poArray;
71 : std::vector<GDALPDFObject*> m_v;
72 :
73 : public:
74 18 : GDALPDFArrayPoppler(Array* poArray) : m_poArray(poArray) {}
75 : virtual ~GDALPDFArrayPoppler();
76 :
77 : virtual int GetLength();
78 : virtual GDALPDFObject* Get(int nIndex);
79 : };
80 :
81 142 : GDALPDFObjectPoppler::~GDALPDFObjectPoppler()
82 : {
83 142 : m_po->free();
84 142 : if (m_bDestroy)
85 138 : delete m_po;
86 142 : delete m_poDict;
87 142 : delete m_poArray;
88 142 : }
89 :
90 792 : GDALPDFObjectType GDALPDFObjectPoppler::GetType()
91 : {
92 792 : switch(m_po->getType())
93 : {
94 172 : case objInt: return PDFObjectType_Int;
95 64 : case objReal: return PDFObjectType_Real;
96 234 : case objString: return PDFObjectType_String;
97 16 : case objName: return PDFObjectType_Name;
98 272 : case objArray: return PDFObjectType_Array;
99 34 : case objDict: return PDFObjectType_Dictionary;
100 0 : case objStream: return PDFObjectType_Dictionary;
101 0 : default: return PDFObjectType_Unknown;
102 : }
103 : }
104 :
105 0 : const char* GDALPDFObjectPoppler::GetTypeName()
106 : {
107 0 : return m_po->getTypeName();
108 : }
109 :
110 56 : int GDALPDFObjectPoppler::GetInt()
111 : {
112 56 : if (GetType() == PDFObjectType_Int)
113 56 : return m_po->getInt();
114 : else
115 0 : return 0;
116 : }
117 :
118 16 : double GDALPDFObjectPoppler::GetReal()
119 : {
120 16 : if (GetType() == PDFObjectType_Real)
121 16 : return m_po->getReal();
122 : else
123 0 : return 0.0;
124 : }
125 :
126 54 : const CPLString& GDALPDFObjectPoppler::GetString()
127 : {
128 54 : if (GetType() == PDFObjectType_String)
129 52 : return (osStr = m_po->getString()->getCString());
130 : else
131 2 : return (osStr = "");
132 : }
133 :
134 8 : const CPLString& GDALPDFObjectPoppler::GetName()
135 : {
136 8 : if (GetType() == PDFObjectType_Name)
137 8 : return (osStr = m_po->getName());
138 : else
139 0 : return (osStr = "");
140 : }
141 :
142 20 : GDALPDFDictionary* GDALPDFObjectPoppler::GetDictionary()
143 : {
144 20 : if (GetType() != PDFObjectType_Dictionary)
145 0 : return NULL;
146 :
147 20 : if (m_poDict)
148 4 : return m_poDict;
149 :
150 16 : Dict* poDict = (m_po->getType() == objStream) ? m_po->getStream()->getDict() : m_po->getDict();
151 16 : if (poDict == NULL)
152 0 : return NULL;
153 16 : m_poDict = new GDALPDFDictionaryPoppler(poDict);
154 16 : return m_poDict;
155 : }
156 :
157 136 : GDALPDFArray* GDALPDFObjectPoppler::GetArray()
158 : {
159 136 : if (GetType() != PDFObjectType_Array)
160 0 : return NULL;
161 :
162 136 : if (m_poArray)
163 118 : return m_poArray;
164 :
165 18 : Array* poArray = m_po->getArray();
166 18 : if (poArray == NULL)
167 0 : return NULL;
168 18 : m_poArray = new GDALPDFArrayPoppler(poArray);
169 18 : return m_poArray;
170 : }
171 :
172 16 : GDALPDFDictionaryPoppler::~GDALPDFDictionaryPoppler()
173 : {
174 16 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
175 16 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
176 56 : for(; oIter != oEnd; ++oIter)
177 40 : delete oIter->second;
178 16 : }
179 :
180 56 : GDALPDFObject* GDALPDFDictionaryPoppler::Get(const char* pszKey)
181 : {
182 56 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
183 56 : if (oIter != m_map.end())
184 2 : return oIter->second;
185 :
186 54 : Object* po = new Object;
187 108 : if (m_poDict->lookup((char*)pszKey, po) && !po->isNull())
188 : {
189 40 : GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
190 80 : m_map[pszKey] = poObj;
191 40 : return poObj;
192 : }
193 : else
194 : {
195 14 : delete po;
196 14 : return NULL;
197 : }
198 : }
199 :
200 0 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPoppler::GetValues()
201 : {
202 0 : int i = 0;
203 0 : int nLength = m_poDict->getLength();
204 0 : for(i=0;i<nLength;i++)
205 : {
206 0 : Get((const char*)m_poDict->getKey(i));
207 : }
208 0 : return m_map;
209 : }
210 :
211 18 : GDALPDFArrayPoppler::~GDALPDFArrayPoppler()
212 : {
213 116 : for(int i=0;i<(int)m_v.size();i++)
214 : {
215 98 : delete m_v[i];
216 : }
217 18 : }
218 :
219 146 : int GDALPDFArrayPoppler::GetLength()
220 : {
221 146 : return m_poArray->getLength();
222 : }
223 :
224 126 : GDALPDFObject* GDALPDFArrayPoppler::Get(int nIndex)
225 : {
226 126 : if (nIndex < 0 || nIndex >= GetLength())
227 0 : return NULL;
228 :
229 126 : int nOldSize = (int)m_v.size();
230 126 : if (nIndex >= nOldSize)
231 : {
232 98 : m_v.resize(nIndex+1);
233 196 : for(int i=nOldSize;i<=nIndex;i++)
234 : {
235 98 : m_v[i] = NULL;
236 : }
237 : }
238 :
239 126 : if (m_v[nIndex] != NULL)
240 28 : return m_v[nIndex];
241 :
242 98 : Object* po = new Object;
243 196 : if (m_poArray->get(nIndex, po) && !po->isNull())
244 : {
245 98 : GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
246 98 : m_v[nIndex] = poObj;
247 98 : return poObj;
248 : }
249 : else
250 : {
251 0 : delete po;
252 0 : return NULL;
253 : }
254 : }
255 :
256 : #else
257 :
258 : class GDALPDFDictionaryPodofo: public GDALPDFDictionary
259 : {
260 : private:
261 : PoDoFo::PdfDictionary* m_poDict;
262 : PoDoFo::PdfVecObjects& m_poObjects;
263 : std::map<CPLString, GDALPDFObject*> m_map;
264 :
265 : public:
266 : GDALPDFDictionaryPodofo(PoDoFo::PdfDictionary* poDict, PoDoFo::PdfVecObjects& poObjects) : m_poDict(poDict), m_poObjects(poObjects) {}
267 : virtual ~GDALPDFDictionaryPodofo();
268 :
269 : virtual GDALPDFObject* Get(const char* pszKey);
270 : virtual std::map<CPLString, GDALPDFObject*>& GetValues();
271 : };
272 :
273 : class GDALPDFArrayPodofo : public GDALPDFArray
274 : {
275 : private:
276 : PoDoFo::PdfArray* m_poArray;
277 : PoDoFo::PdfVecObjects& m_poObjects;
278 : std::vector<GDALPDFObject*> m_v;
279 :
280 : public:
281 : GDALPDFArrayPodofo(PoDoFo::PdfArray* poArray, PoDoFo::PdfVecObjects& poObjects) : m_poArray(poArray), m_poObjects(poObjects) {}
282 : virtual ~GDALPDFArrayPodofo();
283 :
284 : virtual int GetLength();
285 : virtual GDALPDFObject* Get(int nIndex);
286 : };
287 :
288 : GDALPDFObjectPodofo::GDALPDFObjectPodofo(PoDoFo::PdfObject* po, PoDoFo::PdfVecObjects& poObjects) :
289 : m_po(po), m_poObjects(poObjects), m_poDict(NULL), m_poArray(NULL)
290 : {
291 : if (m_po->GetDataType() == PoDoFo::ePdfDataType_Reference)
292 : {
293 : PoDoFo::PdfObject* poObj = m_poObjects.GetObject(m_po->GetReference());
294 : if (poObj)
295 : m_po = poObj;
296 : }
297 : }
298 :
299 : GDALPDFObjectPodofo::~GDALPDFObjectPodofo()
300 : {
301 : delete m_poDict;
302 : delete m_poArray;
303 : }
304 :
305 : GDALPDFObjectType GDALPDFObjectPodofo::GetType()
306 : {
307 : switch(m_po->GetDataType())
308 : {
309 : case PoDoFo::ePdfDataType_Bool: return PDFObjectType_Int;
310 : case PoDoFo::ePdfDataType_Number: return PDFObjectType_Int;
311 : case PoDoFo::ePdfDataType_Real: return PDFObjectType_Real;
312 : case PoDoFo::ePdfDataType_String: return PDFObjectType_String;
313 : case PoDoFo::ePdfDataType_Name: return PDFObjectType_Name;
314 : case PoDoFo::ePdfDataType_Array: return PDFObjectType_Array;
315 : case PoDoFo::ePdfDataType_Dictionary: return PDFObjectType_Dictionary;
316 : default: return PDFObjectType_Unknown;
317 : }
318 : }
319 :
320 : const char* GDALPDFObjectPodofo::GetTypeName()
321 : {
322 : return m_po->GetDataTypeString();
323 : }
324 :
325 : int GDALPDFObjectPodofo::GetInt()
326 : {
327 : if (m_po->GetDataType() == PoDoFo::ePdfDataType_Bool)
328 : return m_po->GetBool();
329 : else if (m_po->GetDataType() == PoDoFo::ePdfDataType_Number)
330 : return (int)m_po->GetNumber();
331 : else
332 : return 0;
333 : }
334 :
335 : double GDALPDFObjectPodofo::GetReal()
336 : {
337 : if (GetType() == PDFObjectType_Real)
338 : return m_po->GetReal();
339 : else
340 : return 0.0;
341 : }
342 :
343 : const CPLString& GDALPDFObjectPodofo::GetString()
344 : {
345 : if (GetType() == PDFObjectType_String)
346 : return (osStr = m_po->GetString().GetStringUtf8());
347 : else
348 : return (osStr = "");
349 : }
350 :
351 : const CPLString& GDALPDFObjectPodofo::GetName()
352 : {
353 : if (GetType() == PDFObjectType_Name)
354 : return (osStr = m_po->GetName().GetName());
355 : else
356 : return (osStr = "");
357 : }
358 :
359 : GDALPDFDictionary* GDALPDFObjectPodofo::GetDictionary()
360 : {
361 : if (GetType() != PDFObjectType_Dictionary)
362 : return NULL;
363 :
364 : if (m_poDict)
365 : return m_poDict;
366 :
367 : m_poDict = new GDALPDFDictionaryPodofo(&m_po->GetDictionary(), m_poObjects);
368 : return m_poDict;
369 : }
370 :
371 : GDALPDFArray* GDALPDFObjectPodofo::GetArray()
372 : {
373 : if (GetType() != PDFObjectType_Array)
374 : return NULL;
375 :
376 : if (m_poArray)
377 : return m_poArray;
378 :
379 : m_poArray = new GDALPDFArrayPodofo(&m_po->GetArray(), m_poObjects);
380 : return m_poArray;
381 : }
382 :
383 : GDALPDFDictionaryPodofo::~GDALPDFDictionaryPodofo()
384 : {
385 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
386 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
387 : for(; oIter != oEnd; ++oIter)
388 : delete oIter->second;
389 : }
390 :
391 : GDALPDFObject* GDALPDFDictionaryPodofo::Get(const char* pszKey)
392 : {
393 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
394 : if (oIter != m_map.end())
395 : return oIter->second;
396 :
397 : PoDoFo::PdfObject* poVal = m_poDict->GetKey(PoDoFo::PdfName(pszKey));
398 : if (poVal)
399 : {
400 : GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(poVal, m_poObjects);
401 : m_map[pszKey] = poObj;
402 : return poObj;
403 : }
404 : else
405 : {
406 : return NULL;
407 : }
408 : }
409 :
410 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPodofo::GetValues()
411 : {
412 : PoDoFo::TKeyMap::iterator oIter = m_poDict->GetKeys().begin();
413 : PoDoFo::TKeyMap::iterator oEnd = m_poDict->GetKeys().end();
414 : for( ; oIter != oEnd; ++oIter)
415 : {
416 : const char* pszKey = oIter->first.GetName().c_str();
417 : Get(pszKey);
418 : }
419 :
420 : return m_map;
421 : }
422 :
423 : GDALPDFArrayPodofo::~GDALPDFArrayPodofo()
424 : {
425 : for(int i=0;i<(int)m_v.size();i++)
426 : {
427 : delete m_v[i];
428 : }
429 : }
430 :
431 : int GDALPDFArrayPodofo::GetLength()
432 : {
433 : return (int)m_poArray->GetSize();
434 : }
435 :
436 : GDALPDFObject* GDALPDFArrayPodofo::Get(int nIndex)
437 : {
438 : if (nIndex < 0 || nIndex >= GetLength())
439 : return NULL;
440 :
441 : int nOldSize = (int)m_v.size();
442 : if (nIndex >= nOldSize)
443 : {
444 : m_v.resize(nIndex+1);
445 : for(int i=nOldSize;i<=nIndex;i++)
446 : {
447 : m_v[i] = NULL;
448 : }
449 : }
450 :
451 : if (m_v[nIndex] != NULL)
452 : return m_v[nIndex];
453 :
454 : PoDoFo::PdfObject& oVal = (*m_poArray)[nIndex];
455 : GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(&oVal, m_poObjects);
456 : m_v[nIndex] = poObj;
457 : return poObj;
458 : }
459 :
460 : #endif
|