1 : /******************************************************************************
2 : * $Id: pdfobject.cpp 24107 2012-03-10 22:04:47Z 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 24107 2012-03-10 22:04:47Z rouault $");
38 :
39 : /************************************************************************/
40 : /* ROUND_TO_INT_IF_CLOSE() */
41 : /************************************************************************/
42 :
43 5608 : double ROUND_TO_INT_IF_CLOSE(double x, double eps)
44 : {
45 5608 : if( eps == 0.0 )
46 4932 : eps = fabs(x) < 1 ? 1e-10 : 1e-8;
47 5608 : int nClosestInt = (int)floor(x + 0.5);
48 5608 : if ( fabs(x - nClosestInt) < eps )
49 4374 : return nClosestInt;
50 : else
51 1234 : return x;
52 : }
53 :
54 : /************************************************************************/
55 : /* GDALPDFGetPDFString() */
56 : /************************************************************************/
57 :
58 344 : static CPLString GDALPDFGetPDFString(const char* pszStr)
59 : {
60 344 : GByte* pabyData = (GByte*)pszStr;
61 : int i;
62 : GByte ch;
63 32608 : for(i=0;(ch = pabyData[i]) != '\0';i++)
64 : {
65 32274 : if (ch < 32 || ch > 127 ||
66 : ch == '(' || ch == ')' ||
67 : ch == '\\' || ch == '%' || ch == '#')
68 10 : break;
69 : }
70 344 : CPLString osStr;
71 344 : if (ch == 0)
72 : {
73 334 : osStr = "(";
74 334 : osStr += pszStr;
75 334 : osStr += ")";
76 334 : return osStr;
77 : }
78 :
79 10 : wchar_t* pwszDest = CPLRecodeToWChar( pszStr, CPL_ENC_UTF8, CPL_ENC_UCS2 );
80 10 : osStr = "<FEFF";
81 652 : for(i=0;pwszDest[i] != 0;i++)
82 : {
83 : #ifndef _WIN32
84 642 : if (pwszDest[i] >= 0x10000 /* && pwszDest[i] <= 0x10FFFF */)
85 : {
86 : /* Generate UTF-16 surrogate pairs (on Windows, CPLRecodeToWChar does it for us) */
87 0 : int nHeadSurrogate = ((pwszDest[i] - 0x10000) >> 10) | 0xd800;
88 0 : int nTrailSurrogate = ((pwszDest[i] - 0x10000) & 0x3ff) | 0xdc00;
89 0 : osStr += CPLSPrintf("%02X", (nHeadSurrogate >> 8) & 0xff);
90 0 : osStr += CPLSPrintf("%02X", (nHeadSurrogate) & 0xff);
91 0 : osStr += CPLSPrintf("%02X", (nTrailSurrogate >> 8) & 0xff);
92 0 : osStr += CPLSPrintf("%02X", (nTrailSurrogate) & 0xff);
93 : }
94 : else
95 : #endif
96 : {
97 642 : osStr += CPLSPrintf("%02X", (pwszDest[i] >> 8) & 0xff);
98 642 : osStr += CPLSPrintf("%02X", (pwszDest[i]) & 0xff);
99 : }
100 : }
101 10 : osStr += ">";
102 10 : CPLFree(pwszDest);
103 10 : return osStr;
104 : }
105 :
106 : /************************************************************************/
107 : /* ==================================================================== */
108 : /* GDALPDFObject */
109 : /* ==================================================================== */
110 : /************************************************************************/
111 :
112 : /************************************************************************/
113 : /* ~GDALPDFObject() */
114 : /************************************************************************/
115 :
116 32594 : GDALPDFObject::~GDALPDFObject()
117 : {
118 32594 : }
119 :
120 : /************************************************************************/
121 : /* GetTypeName() */
122 : /************************************************************************/
123 :
124 0 : const char* GDALPDFObject::GetTypeName()
125 : {
126 0 : switch(GetType())
127 : {
128 0 : case PDFObjectType_Unknown: return GetTypeNameNative();
129 0 : case PDFObjectType_Null: return "null";
130 0 : case PDFObjectType_Bool: return "bool";
131 0 : case PDFObjectType_Int: return "int";
132 0 : case PDFObjectType_Real: return "real";
133 0 : case PDFObjectType_String: return "string";
134 0 : case PDFObjectType_Name: return "name";
135 0 : case PDFObjectType_Array: return "array";
136 0 : case PDFObjectType_Dictionary: return "dictionary";
137 0 : default: return GetTypeNameNative();
138 : }
139 : }
140 :
141 : /************************************************************************/
142 : /* Serialize() */
143 : /************************************************************************/
144 :
145 8670 : void GDALPDFObject::Serialize(CPLString& osStr)
146 : {
147 8670 : int nRefNum = GetRefNum();
148 8670 : if( nRefNum )
149 : {
150 1430 : int nRefGen = GetRefGen();
151 1430 : osStr.append(CPLSPrintf("%d %d R", nRefNum, nRefGen));
152 1430 : return;
153 : }
154 :
155 7240 : switch(GetType())
156 : {
157 0 : case PDFObjectType_Null: osStr.append("null"); return;
158 4 : case PDFObjectType_Bool: osStr.append(GetBool() ? "true": "false"); return;
159 2452 : case PDFObjectType_Int: osStr.append(CPLSPrintf("%d", GetInt())); return;
160 : case PDFObjectType_Real:
161 : {
162 : char szReal[256];
163 2050 : double dfRealNonRounded = GetReal();
164 2050 : double dfReal = ROUND_TO_INT_IF_CLOSE(dfRealNonRounded);
165 2050 : if (dfReal == (double)(int)dfReal)
166 1294 : sprintf(szReal, "%d", (int)dfReal);
167 756 : else if (CanRepresentRealAsString())
168 : {
169 : /* Used for OGC BP numeric values */
170 78 : sprintf(szReal, "(%.16g)", dfReal);
171 : }
172 : else
173 : {
174 678 : sprintf(szReal, "%.16f", dfReal);
175 :
176 : /* Remove non significant trailing zeroes */
177 678 : char* pszDot = strchr(szReal, '.');
178 678 : if (pszDot)
179 : {
180 678 : int iDot = (int)(pszDot - szReal);
181 678 : int nLen = (int)strlen(szReal);
182 1536 : for(int i=nLen-1; i > iDot; i ++)
183 : {
184 768 : if (szReal[i] == '0')
185 90 : szReal[i] = '\0';
186 : else
187 678 : break;
188 : }
189 : }
190 : }
191 2050 : osStr.append(szReal);
192 2050 : return;
193 : }
194 344 : case PDFObjectType_String: osStr.append(GDALPDFGetPDFString(GetString())); return;
195 1452 : case PDFObjectType_Name: osStr.append("/"); osStr.append(GetName()); return;
196 702 : case PDFObjectType_Array: GetArray()->Serialize(osStr); return;
197 236 : case PDFObjectType_Dictionary: GetDictionary()->Serialize(osStr); return;
198 : case PDFObjectType_Unknown:
199 0 : default: fprintf(stderr, "Serializing unknown object !\n"); return;
200 : }
201 : }
202 :
203 : /************************************************************************/
204 : /* Clone() */
205 : /************************************************************************/
206 :
207 542 : GDALPDFObjectRW* GDALPDFObject::Clone()
208 : {
209 542 : int nRefNum = GetRefNum();
210 542 : if( nRefNum )
211 : {
212 188 : int nRefGen = GetRefGen();
213 188 : return GDALPDFObjectRW::CreateIndirect(nRefNum, nRefGen);
214 : }
215 :
216 354 : switch(GetType())
217 : {
218 0 : case PDFObjectType_Null: return GDALPDFObjectRW::CreateNull();
219 0 : case PDFObjectType_Bool: return GDALPDFObjectRW::CreateBool(GetBool());
220 196 : case PDFObjectType_Int: return GDALPDFObjectRW::CreateInt(GetInt());
221 24 : case PDFObjectType_Real: return GDALPDFObjectRW::CreateReal(GetReal());
222 0 : case PDFObjectType_String: return GDALPDFObjectRW::CreateString(GetString());
223 56 : case PDFObjectType_Name: return GDALPDFObjectRW::CreateName(GetName());
224 78 : case PDFObjectType_Array: return GDALPDFObjectRW::CreateArray(GetArray()->Clone());
225 0 : case PDFObjectType_Dictionary: return GDALPDFObjectRW::CreateDictionary(GetDictionary()->Clone());
226 : case PDFObjectType_Unknown:
227 0 : default: fprintf(stderr, "Cloning unknown object !\n"); return NULL;
228 : }
229 : }
230 :
231 : /************************************************************************/
232 : /* ==================================================================== */
233 : /* GDALPDFDictionary */
234 : /* ==================================================================== */
235 : /************************************************************************/
236 :
237 : /************************************************************************/
238 : /* ~GDALPDFDictionary() */
239 : /************************************************************************/
240 :
241 6992 : GDALPDFDictionary::~GDALPDFDictionary()
242 : {
243 6992 : }
244 :
245 : /************************************************************************/
246 : /* Serialize() */
247 : /************************************************************************/
248 :
249 1326 : void GDALPDFDictionary::Serialize(CPLString& osStr)
250 : {
251 1326 : osStr.append("<< ");
252 1326 : std::map<CPLString, GDALPDFObject*>& oMap = GetValues();
253 1326 : std::map<CPLString, GDALPDFObject*>::iterator oIter = oMap.begin();
254 1326 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = oMap.end();
255 6190 : for(;oIter != oEnd;++oIter)
256 : {
257 4864 : const char* pszKey = oIter->first.c_str();
258 4864 : GDALPDFObject* poObj = oIter->second;
259 4864 : osStr.append("/");
260 4864 : osStr.append(pszKey);
261 4864 : osStr.append(" ");
262 4864 : poObj->Serialize(osStr);
263 4864 : osStr.append(" ");
264 : }
265 1326 : osStr.append(">>");
266 1326 : }
267 :
268 : /************************************************************************/
269 : /* Clone() */
270 : /************************************************************************/
271 :
272 56 : GDALPDFDictionaryRW* GDALPDFDictionary::Clone()
273 : {
274 56 : GDALPDFDictionaryRW* poDict = new GDALPDFDictionaryRW();
275 56 : std::map<CPLString, GDALPDFObject*>& oMap = GetValues();
276 56 : std::map<CPLString, GDALPDFObject*>::iterator oIter = oMap.begin();
277 56 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = oMap.end();
278 388 : for(;oIter != oEnd;++oIter)
279 : {
280 332 : const char* pszKey = oIter->first.c_str();
281 332 : GDALPDFObject* poObj = oIter->second;
282 332 : poDict->Add(pszKey, poObj->Clone());
283 : }
284 56 : return poDict;
285 : }
286 :
287 : /************************************************************************/
288 : /* ==================================================================== */
289 : /* GDALPDFArray */
290 : /* ==================================================================== */
291 : /************************************************************************/
292 :
293 : /************************************************************************/
294 : /* ~GDALPDFArray() */
295 : /************************************************************************/
296 :
297 3018 : GDALPDFArray::~GDALPDFArray()
298 : {
299 3018 : }
300 :
301 : /************************************************************************/
302 : /* Serialize() */
303 : /************************************************************************/
304 :
305 704 : void GDALPDFArray::Serialize(CPLString& osStr)
306 : {
307 704 : int nLength = GetLength();
308 : int i;
309 :
310 704 : osStr.append("[ ");
311 3998 : for(i=0;i<nLength;i++)
312 : {
313 3294 : Get(i)->Serialize(osStr);
314 3294 : osStr.append(" ");
315 : }
316 704 : osStr.append("]");
317 704 : }
318 :
319 : /************************************************************************/
320 : /* Clone() */
321 : /************************************************************************/
322 :
323 78 : GDALPDFArrayRW* GDALPDFArray::Clone()
324 : {
325 78 : GDALPDFArrayRW* poArray = new GDALPDFArrayRW();
326 78 : int nLength = GetLength();
327 : int i;
328 288 : for(i=0;i<nLength;i++)
329 : {
330 210 : poArray->Add(Get(i)->Clone());
331 : }
332 78 : return poArray;
333 : }
334 :
335 : /************************************************************************/
336 : /* ==================================================================== */
337 : /* GDALPDFStream */
338 : /* ==================================================================== */
339 : /************************************************************************/
340 :
341 : /************************************************************************/
342 : /* ~GDALPDFStream() */
343 : /************************************************************************/
344 :
345 32 : GDALPDFStream::~GDALPDFStream()
346 : {
347 32 : }
348 :
349 : /************************************************************************/
350 : /* ==================================================================== */
351 : /* GDALPDFObjectRW */
352 : /* ==================================================================== */
353 : /************************************************************************/
354 :
355 : /************************************************************************/
356 : /* GDALPDFObjectRW() */
357 : /************************************************************************/
358 :
359 8988 : GDALPDFObjectRW::GDALPDFObjectRW(GDALPDFObjectType eType)
360 : {
361 8988 : m_eType = eType;
362 8988 : m_nVal = 0;
363 8988 : m_dfVal = 0.0;
364 : //m_osVal;
365 8988 : m_poDict = NULL;
366 8988 : m_poArray = NULL;
367 8988 : m_nNum = 0;
368 8988 : m_nGen = 0;
369 8988 : m_bCanRepresentRealAsString = FALSE;
370 8988 : }
371 :
372 : /************************************************************************/
373 : /* ~GDALPDFObjectRW() */
374 : /************************************************************************/
375 :
376 8988 : GDALPDFObjectRW::~GDALPDFObjectRW()
377 : {
378 8988 : delete m_poDict;
379 8988 : delete m_poArray;
380 8988 : }
381 :
382 : /************************************************************************/
383 : /* CreateIndirect() */
384 : /************************************************************************/
385 :
386 1546 : GDALPDFObjectRW* GDALPDFObjectRW::CreateIndirect(int nNum, int nGen)
387 : {
388 1546 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Unknown);
389 1546 : poObj->m_nNum = nNum;
390 1546 : poObj->m_nGen = nGen;
391 1546 : return poObj;
392 : }
393 :
394 : /************************************************************************/
395 : /* CreateNull() */
396 : /************************************************************************/
397 :
398 0 : GDALPDFObjectRW* GDALPDFObjectRW::CreateNull()
399 : {
400 0 : return new GDALPDFObjectRW(PDFObjectType_Null);
401 : }
402 :
403 : /************************************************************************/
404 : /* CreateBool() */
405 : /************************************************************************/
406 :
407 4 : GDALPDFObjectRW* GDALPDFObjectRW::CreateBool(int bVal)
408 : {
409 4 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Bool);
410 4 : poObj->m_nVal = bVal;
411 4 : return poObj;
412 : }
413 :
414 : /************************************************************************/
415 : /* CreateInt() */
416 : /************************************************************************/
417 :
418 2572 : GDALPDFObjectRW* GDALPDFObjectRW::CreateInt(int nVal)
419 : {
420 2572 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Int);
421 2572 : poObj->m_nVal = nVal;
422 2572 : return poObj;
423 : }
424 :
425 : /************************************************************************/
426 : /* CreateReal() */
427 : /************************************************************************/
428 :
429 2050 : GDALPDFObjectRW* GDALPDFObjectRW::CreateReal(double dfVal,
430 : int bCanRepresentRealAsString)
431 : {
432 2050 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Real);
433 2050 : poObj->m_dfVal = dfVal;
434 2050 : poObj->m_bCanRepresentRealAsString = bCanRepresentRealAsString;
435 2050 : return poObj;
436 : }
437 :
438 : /************************************************************************/
439 : /* CreateString() */
440 : /************************************************************************/
441 :
442 344 : GDALPDFObjectRW* GDALPDFObjectRW::CreateString(const char* pszStr)
443 : {
444 344 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_String);
445 688 : poObj->m_osVal = pszStr;
446 344 : return poObj;
447 : }
448 :
449 : /************************************************************************/
450 : /* CreateName() */
451 : /************************************************************************/
452 :
453 1476 : GDALPDFObjectRW* GDALPDFObjectRW::CreateName(const char* pszName)
454 : {
455 1476 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Name);
456 2952 : poObj->m_osVal = pszName;
457 1476 : return poObj;
458 : }
459 :
460 : /************************************************************************/
461 : /* CreateDictionary() */
462 : /************************************************************************/
463 :
464 236 : GDALPDFObjectRW* GDALPDFObjectRW::CreateDictionary(GDALPDFDictionaryRW* poDict)
465 : {
466 236 : CPLAssert(poDict);
467 236 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Dictionary);
468 236 : poObj->m_poDict = poDict;
469 236 : return poObj;
470 : }
471 :
472 : /************************************************************************/
473 : /* CreateArray() */
474 : /************************************************************************/
475 :
476 760 : GDALPDFObjectRW* GDALPDFObjectRW::CreateArray(GDALPDFArrayRW* poArray)
477 : {
478 760 : CPLAssert(poArray);
479 760 : GDALPDFObjectRW* poObj = new GDALPDFObjectRW(PDFObjectType_Array);
480 760 : poObj->m_poArray = poArray;
481 760 : return poObj;
482 : }
483 :
484 : /************************************************************************/
485 : /* GetTypeNameNative() */
486 : /************************************************************************/
487 :
488 0 : const char* GDALPDFObjectRW::GetTypeNameNative()
489 : {
490 0 : fprintf(stderr, "Should not go here");
491 0 : return "";
492 : }
493 :
494 : /************************************************************************/
495 : /* GetType() */
496 : /************************************************************************/
497 :
498 7240 : GDALPDFObjectType GDALPDFObjectRW::GetType()
499 : {
500 7240 : return m_eType;
501 : }
502 :
503 : /************************************************************************/
504 : /* GetBool() */
505 : /************************************************************************/
506 :
507 4 : int GDALPDFObjectRW::GetBool()
508 : {
509 4 : if (m_eType == PDFObjectType_Bool)
510 4 : return m_nVal;
511 :
512 0 : return FALSE;
513 : }
514 :
515 : /************************************************************************/
516 : /* GetInt() */
517 : /************************************************************************/
518 :
519 2452 : int GDALPDFObjectRW::GetInt()
520 : {
521 2452 : if (m_eType == PDFObjectType_Int)
522 2452 : return m_nVal;
523 :
524 0 : return 0;
525 : }
526 :
527 : /************************************************************************/
528 : /* GetReal() */
529 : /************************************************************************/
530 :
531 2050 : double GDALPDFObjectRW::GetReal()
532 : {
533 2050 : return m_dfVal;
534 : }
535 :
536 : /************************************************************************/
537 : /* GetString() */
538 : /************************************************************************/
539 :
540 344 : const CPLString& GDALPDFObjectRW::GetString()
541 : {
542 344 : return m_osVal;
543 : }
544 :
545 : /************************************************************************/
546 : /* GetName() */
547 : /************************************************************************/
548 :
549 1452 : const CPLString& GDALPDFObjectRW::GetName()
550 : {
551 1452 : return m_osVal;
552 : }
553 :
554 : /************************************************************************/
555 : /* GetDictionary() */
556 : /************************************************************************/
557 :
558 236 : GDALPDFDictionary* GDALPDFObjectRW::GetDictionary()
559 : {
560 236 : return m_poDict;
561 : }
562 :
563 : /************************************************************************/
564 : /* GetArray() */
565 : /************************************************************************/
566 :
567 702 : GDALPDFArray* GDALPDFObjectRW::GetArray()
568 : {
569 702 : return m_poArray;
570 : }
571 :
572 : /************************************************************************/
573 : /* GetStream() */
574 : /************************************************************************/
575 :
576 0 : GDALPDFStream* GDALPDFObjectRW::GetStream()
577 : {
578 0 : return NULL;
579 : }
580 :
581 : /************************************************************************/
582 : /* GetRefNum() */
583 : /************************************************************************/
584 :
585 8678 : int GDALPDFObjectRW::GetRefNum()
586 : {
587 8678 : return m_nNum;
588 : }
589 :
590 : /************************************************************************/
591 : /* GetRefGen() */
592 : /************************************************************************/
593 :
594 1438 : int GDALPDFObjectRW::GetRefGen()
595 : {
596 1438 : return m_nGen;
597 : }
598 :
599 : /************************************************************************/
600 : /* ==================================================================== */
601 : /* GDALPDFDictionaryRW */
602 : /* ==================================================================== */
603 : /************************************************************************/
604 :
605 : /************************************************************************/
606 : /* GDALPDFDictionaryRW() */
607 : /************************************************************************/
608 :
609 1350 : GDALPDFDictionaryRW::GDALPDFDictionaryRW()
610 : {
611 1350 : }
612 :
613 : /************************************************************************/
614 : /* ~GDALPDFDictionaryRW() */
615 : /************************************************************************/
616 :
617 1350 : GDALPDFDictionaryRW::~GDALPDFDictionaryRW()
618 : {
619 1350 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
620 1350 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
621 6382 : for(; oIter != oEnd; ++oIter)
622 5032 : delete oIter->second;
623 1350 : }
624 :
625 : /************************************************************************/
626 : /* Get() */
627 : /************************************************************************/
628 :
629 12 : GDALPDFObject* GDALPDFDictionaryRW::Get(const char* pszKey)
630 : {
631 12 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
632 12 : if (oIter != m_map.end())
633 8 : return oIter->second;
634 4 : return NULL;
635 : }
636 :
637 : /************************************************************************/
638 : /* GetValues() */
639 : /************************************************************************/
640 :
641 1326 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryRW::GetValues()
642 : {
643 1326 : return m_map;
644 : }
645 :
646 : /************************************************************************/
647 : /* Add() */
648 : /************************************************************************/
649 :
650 5052 : GDALPDFDictionaryRW& GDALPDFDictionaryRW::Add(const char* pszKey, GDALPDFObject* poVal)
651 : {
652 5052 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
653 5052 : if (oIter != m_map.end())
654 : {
655 0 : delete oIter->second;
656 0 : oIter->second = poVal;
657 : }
658 : else
659 5052 : m_map[pszKey] = poVal;
660 :
661 5052 : return *this;
662 : }
663 :
664 : /************************************************************************/
665 : /* Remove() */
666 : /************************************************************************/
667 :
668 52 : GDALPDFDictionaryRW& GDALPDFDictionaryRW::Remove(const char* pszKey)
669 : {
670 52 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
671 52 : if (oIter != m_map.end())
672 : {
673 20 : delete oIter->second;
674 20 : m_map.erase(pszKey);
675 : }
676 :
677 52 : return *this;
678 : }
679 :
680 : /************************************************************************/
681 : /* ==================================================================== */
682 : /* GDALPDFArrayRW */
683 : /* ==================================================================== */
684 : /************************************************************************/
685 :
686 : /************************************************************************/
687 : /* GDALPDFArrayRW() */
688 : /************************************************************************/
689 :
690 762 : GDALPDFArrayRW::GDALPDFArrayRW()
691 : {
692 762 : }
693 :
694 : /************************************************************************/
695 : /* ~GDALPDFArrayRW() */
696 : /************************************************************************/
697 :
698 762 : GDALPDFArrayRW::~GDALPDFArrayRW()
699 : {
700 4186 : for(int i=0; i < (int)m_array.size(); i++)
701 3424 : delete m_array[i];
702 762 : }
703 :
704 : /************************************************************************/
705 : /* GetLength() */
706 : /************************************************************************/
707 :
708 3998 : int GDALPDFArrayRW::GetLength()
709 : {
710 3998 : return (int)m_array.size();
711 : }
712 :
713 : /************************************************************************/
714 : /* Get() */
715 : /************************************************************************/
716 :
717 3294 : GDALPDFObject* GDALPDFArrayRW::Get(int nIndex)
718 : {
719 3294 : if (nIndex < 0 || nIndex >= GetLength())
720 0 : return NULL;
721 3294 : return m_array[nIndex];
722 : }
723 :
724 : /************************************************************************/
725 : /* Add() */
726 : /************************************************************************/
727 :
728 3336 : GDALPDFArrayRW& GDALPDFArrayRW::Add(GDALPDFObject* poObj)
729 : {
730 3336 : m_array.push_back(poObj);
731 3336 : return *this;
732 : }
733 :
734 : /************************************************************************/
735 : /* Add() */
736 : /************************************************************************/
737 :
738 14 : GDALPDFArrayRW& GDALPDFArrayRW::Add(double* padfVal, int nCount,
739 : int bCanRepresentRealAsString)
740 : {
741 102 : for(int i=0;i<nCount;i++)
742 88 : m_array.push_back(GDALPDFObjectRW::CreateReal(padfVal[i], bCanRepresentRealAsString));
743 14 : return *this;
744 : }
745 :
746 : #ifdef HAVE_POPPLER
747 :
748 : /************************************************************************/
749 : /* ==================================================================== */
750 : /* GDALPDFDictionaryPoppler */
751 : /* ==================================================================== */
752 : /************************************************************************/
753 :
754 : class GDALPDFDictionaryPoppler: public GDALPDFDictionary
755 : {
756 : private:
757 : Dict* m_poDict;
758 : std::map<CPLString, GDALPDFObject*> m_map;
759 :
760 : public:
761 4706 : GDALPDFDictionaryPoppler(Dict* poDict) : m_poDict(poDict) {}
762 : virtual ~GDALPDFDictionaryPoppler();
763 :
764 : virtual GDALPDFObject* Get(const char* pszKey);
765 : virtual std::map<CPLString, GDALPDFObject*>& GetValues();
766 : };
767 :
768 : /************************************************************************/
769 : /* ==================================================================== */
770 : /* GDALPDFArrayPoppler */
771 : /* ==================================================================== */
772 : /************************************************************************/
773 :
774 : class GDALPDFArrayPoppler : public GDALPDFArray
775 : {
776 : private:
777 : Array* m_poArray;
778 : std::vector<GDALPDFObject*> m_v;
779 :
780 : public:
781 1976 : GDALPDFArrayPoppler(Array* poArray) : m_poArray(poArray) {}
782 : virtual ~GDALPDFArrayPoppler();
783 :
784 : virtual int GetLength();
785 : virtual GDALPDFObject* Get(int nIndex);
786 : };
787 :
788 : /************************************************************************/
789 : /* ==================================================================== */
790 : /* GDALPDFStreamPoppler */
791 : /* ==================================================================== */
792 : /************************************************************************/
793 :
794 : class GDALPDFStreamPoppler : public GDALPDFStream
795 : {
796 : private:
797 : int m_nLength;
798 : Stream* m_poStream;
799 :
800 : public:
801 24 : GDALPDFStreamPoppler(Stream* poStream) : m_nLength(-1), m_poStream(poStream) {}
802 24 : virtual ~GDALPDFStreamPoppler() {}
803 :
804 : virtual int GetLength();
805 : virtual char* GetBytes();
806 : };
807 :
808 : /************************************************************************/
809 : /* ==================================================================== */
810 : /* GDALPDFObjectPoppler */
811 : /* ==================================================================== */
812 : /************************************************************************/
813 :
814 : /************************************************************************/
815 : /* ~GDALPDFObjectPoppler() */
816 : /************************************************************************/
817 :
818 19606 : GDALPDFObjectPoppler::~GDALPDFObjectPoppler()
819 : {
820 19606 : m_po->free();
821 19606 : if (m_bDestroy)
822 19072 : delete m_po;
823 19606 : delete m_poDict;
824 19606 : delete m_poArray;
825 19606 : delete m_poStream;
826 19606 : }
827 :
828 : /************************************************************************/
829 : /* GetType() */
830 : /************************************************************************/
831 :
832 83966 : GDALPDFObjectType GDALPDFObjectPoppler::GetType()
833 : {
834 83966 : switch(m_po->getType())
835 : {
836 226 : case objNull: return PDFObjectType_Null;
837 0 : case objBool: return PDFObjectType_Bool;
838 18440 : case objInt: return PDFObjectType_Int;
839 6496 : case objReal: return PDFObjectType_Real;
840 20036 : case objString: return PDFObjectType_String;
841 1108 : case objName: return PDFObjectType_Name;
842 18716 : case objArray: return PDFObjectType_Array;
843 18858 : case objDict: return PDFObjectType_Dictionary;
844 86 : case objStream: return PDFObjectType_Dictionary;
845 0 : default: return PDFObjectType_Unknown;
846 : }
847 : }
848 :
849 : /************************************************************************/
850 : /* GetTypeNameNative() */
851 : /************************************************************************/
852 :
853 0 : const char* GDALPDFObjectPoppler::GetTypeNameNative()
854 : {
855 0 : return m_po->getTypeName();
856 : }
857 :
858 : /************************************************************************/
859 : /* GetBool() */
860 : /************************************************************************/
861 :
862 0 : int GDALPDFObjectPoppler::GetBool()
863 : {
864 0 : if (GetType() == PDFObjectType_Bool)
865 0 : return m_po->getBool();
866 : else
867 0 : return 0;
868 : }
869 :
870 : /************************************************************************/
871 : /* GetInt() */
872 : /************************************************************************/
873 :
874 6418 : int GDALPDFObjectPoppler::GetInt()
875 : {
876 6418 : if (GetType() == PDFObjectType_Int)
877 6418 : return m_po->getInt();
878 : else
879 0 : return 0;
880 : }
881 :
882 : /************************************************************************/
883 : /* GetReal() */
884 : /************************************************************************/
885 :
886 1608 : double GDALPDFObjectPoppler::GetReal()
887 : {
888 1608 : if (GetType() == PDFObjectType_Real)
889 1608 : return m_po->getReal();
890 : else
891 0 : return 0.0;
892 : }
893 :
894 : /************************************************************************/
895 : /* GDALPDFPopplerGetUTF8() */
896 : /************************************************************************/
897 :
898 7288 : static CPLString GDALPDFPopplerGetUTF8(GooString* poStr)
899 : {
900 7288 : GByte* pabySrc = (GByte*)poStr->getCString();
901 7288 : int nLen = poStr->getLength();
902 7288 : int bBEUnicodeMarker = nLen > 2 && pabySrc[0] == 0xFF && pabySrc[1] == 0xFE;
903 7288 : if (!poStr->hasUnicodeMarker() && !bBEUnicodeMarker)
904 : {
905 7214 : const char* pszStr = poStr->getCString();
906 7214 : if (CPLIsUTF8(pszStr, -1))
907 7214 : return pszStr;
908 : else
909 : {
910 0 : char* pszUTF8 = CPLRecode( pszStr, CPL_ENC_ISO8859_1, CPL_ENC_UTF8 );
911 0 : CPLString osRet = pszUTF8;
912 0 : CPLFree(pszUTF8);
913 0 : return osRet;
914 : }
915 : }
916 :
917 : /* This is UTF-16 content */
918 74 : pabySrc += 2;
919 74 : nLen = (nLen - 2) / 2;
920 74 : wchar_t *pwszSource = new wchar_t[nLen + 1];
921 74 : int j = 0;
922 862 : for(int i=0; i<nLen; i++, j++)
923 : {
924 788 : if (!bBEUnicodeMarker)
925 4 : pwszSource[j] = (pabySrc[2 * i] << 8) + pabySrc[2 * i + 1];
926 : else
927 784 : pwszSource[j] = (pabySrc[2 * i + 1] << 8) + pabySrc[2 * i];
928 : #ifndef _WIN32
929 : /* Is there a surrogate pair ? See http://en.wikipedia.org/wiki/UTF-16 */
930 : /* On Windows, CPLRecodeFromWChar does this for us, because wchar_t is only */
931 : /* 2 bytes wide, whereas on Unix it is 32bits */
932 788 : if (pwszSource[j] >= 0xD800 && pwszSource[j] <= 0xDBFF && i + 1 < nLen)
933 : {
934 : /* should be in the range 0xDC00... 0xDFFF */
935 : wchar_t nTrailSurrogate;
936 0 : if (!bBEUnicodeMarker)
937 0 : nTrailSurrogate = (pabySrc[2 * (i+1)] << 8) + pabySrc[2 * (i+1) + 1];
938 : else
939 0 : nTrailSurrogate = (pabySrc[2 * (i+1) + 1] << 8) + pabySrc[2 * (i+1)];
940 0 : if (nTrailSurrogate >= 0xDC00 && nTrailSurrogate <= 0xDFFF)
941 : {
942 0 : pwszSource[j] = ((pwszSource[j] - 0xD800) << 10) + (nTrailSurrogate - 0xDC00) + 0x10000;
943 0 : i++;
944 : }
945 : }
946 : #endif
947 : }
948 74 : pwszSource[j] = 0;
949 :
950 74 : char* pszUTF8 = CPLRecodeFromWChar( pwszSource, CPL_ENC_UCS2, CPL_ENC_UTF8 );
951 74 : delete[] pwszSource;
952 74 : CPLString osStrUTF8(pszUTF8);
953 74 : CPLFree(pszUTF8);
954 74 : return osStrUTF8;
955 : }
956 :
957 : /************************************************************************/
958 : /* GetString() */
959 : /************************************************************************/
960 :
961 7288 : const CPLString& GDALPDFObjectPoppler::GetString()
962 : {
963 7288 : if (GetType() == PDFObjectType_String)
964 7288 : return (osStr = GDALPDFPopplerGetUTF8(m_po->getString()));
965 : else
966 0 : return (osStr = "");
967 : }
968 :
969 : /************************************************************************/
970 : /* GetName() */
971 : /************************************************************************/
972 :
973 562 : const CPLString& GDALPDFObjectPoppler::GetName()
974 : {
975 562 : if (GetType() == PDFObjectType_Name)
976 562 : return (osStr = m_po->getName());
977 : else
978 0 : return (osStr = "");
979 : }
980 :
981 : /************************************************************************/
982 : /* GetDictionary() */
983 : /************************************************************************/
984 :
985 11930 : GDALPDFDictionary* GDALPDFObjectPoppler::GetDictionary()
986 : {
987 11930 : if (GetType() != PDFObjectType_Dictionary)
988 0 : return NULL;
989 :
990 11930 : if (m_poDict)
991 7224 : return m_poDict;
992 :
993 4706 : Dict* poDict = (m_po->getType() == objStream) ? m_po->getStream()->getDict() : m_po->getDict();
994 4706 : if (poDict == NULL)
995 0 : return NULL;
996 4706 : m_poDict = new GDALPDFDictionaryPoppler(poDict);
997 4706 : return m_poDict;
998 : }
999 :
1000 : /************************************************************************/
1001 : /* GetArray() */
1002 : /************************************************************************/
1003 :
1004 9350 : GDALPDFArray* GDALPDFObjectPoppler::GetArray()
1005 : {
1006 9350 : if (GetType() != PDFObjectType_Array)
1007 0 : return NULL;
1008 :
1009 9350 : if (m_poArray)
1010 7400 : return m_poArray;
1011 :
1012 1950 : Array* poArray = m_po->getArray();
1013 1950 : if (poArray == NULL)
1014 0 : return NULL;
1015 1950 : m_poArray = new GDALPDFArrayPoppler(poArray);
1016 1950 : return m_poArray;
1017 : }
1018 :
1019 : /************************************************************************/
1020 : /* GetStream() */
1021 : /************************************************************************/
1022 :
1023 24 : GDALPDFStream* GDALPDFObjectPoppler::GetStream()
1024 : {
1025 24 : if (m_po->getType() != objStream)
1026 0 : return NULL;
1027 :
1028 24 : if (m_poStream)
1029 0 : return m_poStream;
1030 24 : m_poStream = new GDALPDFStreamPoppler(m_po->getStream());
1031 24 : return m_poStream;
1032 : }
1033 :
1034 : /************************************************************************/
1035 : /* SetRefNumAndGen() */
1036 : /************************************************************************/
1037 :
1038 19334 : void GDALPDFObjectPoppler::SetRefNumAndGen(int nNum, int nGen)
1039 : {
1040 19334 : m_nRefNum = nNum;
1041 19334 : m_nRefGen = nGen;
1042 19334 : }
1043 :
1044 : /************************************************************************/
1045 : /* GetRefNum() */
1046 : /************************************************************************/
1047 :
1048 688 : int GDALPDFObjectPoppler::GetRefNum()
1049 : {
1050 688 : return m_nRefNum;
1051 : }
1052 :
1053 : /************************************************************************/
1054 : /* GetRefGen() */
1055 : /************************************************************************/
1056 :
1057 482 : int GDALPDFObjectPoppler::GetRefGen()
1058 : {
1059 482 : return m_nRefGen;
1060 : }
1061 :
1062 : /************************************************************************/
1063 : /* ==================================================================== */
1064 : /* GDALPDFDictionaryPoppler */
1065 : /* ==================================================================== */
1066 : /************************************************************************/
1067 :
1068 : /************************************************************************/
1069 : /* ~GDALPDFDictionaryPoppler() */
1070 : /************************************************************************/
1071 :
1072 4706 : GDALPDFDictionaryPoppler::~GDALPDFDictionaryPoppler()
1073 : {
1074 4706 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
1075 4706 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
1076 14374 : for(; oIter != oEnd; ++oIter)
1077 9668 : delete oIter->second;
1078 4706 : }
1079 :
1080 : /************************************************************************/
1081 : /* Get() */
1082 : /************************************************************************/
1083 :
1084 15416 : GDALPDFObject* GDALPDFDictionaryPoppler::Get(const char* pszKey)
1085 : {
1086 15416 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
1087 15416 : if (oIter != m_map.end())
1088 4416 : return oIter->second;
1089 :
1090 11000 : Object* po = new Object;
1091 22000 : if (m_poDict->lookupNF((char*)pszKey, po) && !po->isNull())
1092 : {
1093 9668 : int nRefNum = 0, nRefGen = 0;
1094 9668 : if( po->isRef())
1095 : {
1096 572 : nRefNum = po->getRefNum();
1097 572 : nRefGen = po->getRefGen();
1098 : }
1099 9668 : if( !po->isRef() || (m_poDict->lookup((char*)pszKey, po) && !po->isNull()) )
1100 : {
1101 9668 : GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
1102 9668 : poObj->SetRefNumAndGen(nRefNum, nRefGen);
1103 19336 : m_map[pszKey] = poObj;
1104 9668 : return poObj;
1105 : }
1106 : else
1107 : {
1108 0 : delete po;
1109 0 : return NULL;
1110 : }
1111 : }
1112 : else
1113 : {
1114 1332 : delete po;
1115 1332 : return NULL;
1116 : }
1117 : }
1118 :
1119 : /************************************************************************/
1120 : /* GetValues() */
1121 : /************************************************************************/
1122 :
1123 32 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPoppler::GetValues()
1124 : {
1125 32 : int i = 0;
1126 32 : int nLength = m_poDict->getLength();
1127 224 : for(i=0;i<nLength;i++)
1128 : {
1129 192 : const char* pszKey = (const char*)m_poDict->getKey(i);
1130 192 : Get(pszKey);
1131 : }
1132 32 : return m_map;
1133 : }
1134 :
1135 : /************************************************************************/
1136 : /* ==================================================================== */
1137 : /* GDALPDFArrayPoppler */
1138 : /* ==================================================================== */
1139 : /************************************************************************/
1140 :
1141 : /************************************************************************/
1142 : /* GDALPDFCreateArray() */
1143 : /************************************************************************/
1144 :
1145 26 : GDALPDFArray* GDALPDFCreateArray(Array* array)
1146 : {
1147 26 : return new GDALPDFArrayPoppler(array);
1148 : }
1149 :
1150 : /************************************************************************/
1151 : /* ~GDALPDFArrayPoppler() */
1152 : /************************************************************************/
1153 :
1154 1976 : GDALPDFArrayPoppler::~GDALPDFArrayPoppler()
1155 : {
1156 11388 : for(int i=0;i<(int)m_v.size();i++)
1157 : {
1158 9412 : delete m_v[i];
1159 : }
1160 1976 : }
1161 :
1162 : /************************************************************************/
1163 : /* GetLength() */
1164 : /************************************************************************/
1165 :
1166 20760 : int GDALPDFArrayPoppler::GetLength()
1167 : {
1168 20760 : return m_poArray->getLength();
1169 : }
1170 :
1171 : /************************************************************************/
1172 : /* Get() */
1173 : /************************************************************************/
1174 :
1175 12914 : GDALPDFObject* GDALPDFArrayPoppler::Get(int nIndex)
1176 : {
1177 12914 : if (nIndex < 0 || nIndex >= GetLength())
1178 0 : return NULL;
1179 :
1180 12914 : int nOldSize = (int)m_v.size();
1181 12914 : if (nIndex >= nOldSize)
1182 : {
1183 9404 : m_v.resize(nIndex+1);
1184 18816 : for(int i=nOldSize;i<=nIndex;i++)
1185 : {
1186 9412 : m_v[i] = NULL;
1187 : }
1188 : }
1189 :
1190 12914 : if (m_v[nIndex] != NULL)
1191 3510 : return m_v[nIndex];
1192 :
1193 9404 : Object* po = new Object;
1194 9404 : if (m_poArray->getNF(nIndex, po))
1195 : {
1196 9404 : int nRefNum = 0, nRefGen = 0;
1197 9404 : if( po->isRef())
1198 : {
1199 1092 : nRefNum = po->getRefNum();
1200 1092 : nRefGen = po->getRefGen();
1201 : }
1202 9404 : if( !po->isRef() || (m_poArray->get(nIndex, po)) )
1203 : {
1204 9404 : GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(po, TRUE);
1205 9404 : poObj->SetRefNumAndGen(nRefNum, nRefGen);
1206 9404 : m_v[nIndex] = poObj;
1207 9404 : return poObj;
1208 : }
1209 : else
1210 : {
1211 0 : delete po;
1212 0 : return NULL;
1213 : }
1214 : }
1215 : else
1216 : {
1217 0 : delete po;
1218 0 : return NULL;
1219 : }
1220 : }
1221 :
1222 : /************************************************************************/
1223 : /* ==================================================================== */
1224 : /* GDALPDFStreamPoppler */
1225 : /* ==================================================================== */
1226 : /************************************************************************/
1227 :
1228 : /************************************************************************/
1229 : /* GetLength() */
1230 : /************************************************************************/
1231 :
1232 32 : int GDALPDFStreamPoppler::GetLength()
1233 : {
1234 32 : if (m_nLength >= 0)
1235 8 : return m_nLength;
1236 :
1237 24 : m_poStream->reset();
1238 24 : m_nLength = 0;
1239 3386680 : while(m_poStream->getChar() != EOF)
1240 3386632 : m_nLength ++;
1241 24 : return m_nLength;
1242 : }
1243 :
1244 : /************************************************************************/
1245 : /* GetBytes() */
1246 : /************************************************************************/
1247 :
1248 24 : char* GDALPDFStreamPoppler::GetBytes()
1249 : {
1250 : int i;
1251 24 : int nLength = GetLength();
1252 24 : char* pszContent = (char*) VSIMalloc(nLength + 1);
1253 24 : if (!pszContent)
1254 0 : return NULL;
1255 24 : m_poStream->reset();
1256 3386656 : for(i=0;i<nLength;i++)
1257 : {
1258 3386632 : int nVal = m_poStream->getChar();
1259 3386632 : if (nVal == EOF)
1260 0 : break;
1261 3386632 : pszContent[i] = (GByte)nVal;
1262 : }
1263 24 : pszContent[i] = '\0';
1264 24 : return pszContent;
1265 : }
1266 :
1267 : #endif // HAVE_POPPLER
1268 :
1269 : #ifdef HAVE_PODOFO
1270 :
1271 : /************************************************************************/
1272 : /* ==================================================================== */
1273 : /* GDALPDFDictionaryPodofo */
1274 : /* ==================================================================== */
1275 : /************************************************************************/
1276 :
1277 : class GDALPDFDictionaryPodofo: public GDALPDFDictionary
1278 : {
1279 : private:
1280 : PoDoFo::PdfDictionary* m_poDict;
1281 : PoDoFo::PdfVecObjects& m_poObjects;
1282 : std::map<CPLString, GDALPDFObject*> m_map;
1283 :
1284 : public:
1285 936 : GDALPDFDictionaryPodofo(PoDoFo::PdfDictionary* poDict, PoDoFo::PdfVecObjects& poObjects) : m_poDict(poDict), m_poObjects(poObjects) {}
1286 : virtual ~GDALPDFDictionaryPodofo();
1287 :
1288 : virtual GDALPDFObject* Get(const char* pszKey);
1289 : virtual std::map<CPLString, GDALPDFObject*>& GetValues();
1290 : };
1291 :
1292 : /************************************************************************/
1293 : /* ==================================================================== */
1294 : /* GDALPDFArrayPodofo */
1295 : /* ==================================================================== */
1296 : /************************************************************************/
1297 :
1298 : class GDALPDFArrayPodofo : public GDALPDFArray
1299 : {
1300 : private:
1301 : PoDoFo::PdfArray* m_poArray;
1302 : PoDoFo::PdfVecObjects& m_poObjects;
1303 : std::vector<GDALPDFObject*> m_v;
1304 :
1305 : public:
1306 280 : GDALPDFArrayPodofo(PoDoFo::PdfArray* poArray, PoDoFo::PdfVecObjects& poObjects) : m_poArray(poArray), m_poObjects(poObjects) {}
1307 : virtual ~GDALPDFArrayPodofo();
1308 :
1309 : virtual int GetLength();
1310 : virtual GDALPDFObject* Get(int nIndex);
1311 : };
1312 :
1313 : /************************************************************************/
1314 : /* ==================================================================== */
1315 : /* GDALPDFStreamPodofo */
1316 : /* ==================================================================== */
1317 : /************************************************************************/
1318 :
1319 : class GDALPDFStreamPodofo : public GDALPDFStream
1320 : {
1321 : private:
1322 : int m_nLength;
1323 : PoDoFo::PdfMemStream* m_pStream;
1324 :
1325 : public:
1326 8 : GDALPDFStreamPodofo(PoDoFo::PdfMemStream* pStream) : m_nLength(-1), m_pStream(pStream) { }
1327 8 : virtual ~GDALPDFStreamPodofo() {}
1328 :
1329 : virtual int GetLength();
1330 : virtual char* GetBytes();
1331 : };
1332 :
1333 : /************************************************************************/
1334 : /* ==================================================================== */
1335 : /* GDALPDFObjectPodofo */
1336 : /* ==================================================================== */
1337 : /************************************************************************/
1338 :
1339 : /************************************************************************/
1340 : /* GDALPDFObjectPodofo() */
1341 : /************************************************************************/
1342 :
1343 4000 : GDALPDFObjectPodofo::GDALPDFObjectPodofo(PoDoFo::PdfObject* po, PoDoFo::PdfVecObjects& poObjects) :
1344 4000 : m_po(po), m_poObjects(poObjects), m_poDict(NULL), m_poArray(NULL), m_poStream(NULL)
1345 : {
1346 : try
1347 : {
1348 4000 : if (m_po->GetDataType() == PoDoFo::ePdfDataType_Reference)
1349 : {
1350 220 : PoDoFo::PdfObject* poObj = m_poObjects.GetObject(m_po->GetReference());
1351 220 : if (poObj)
1352 220 : m_po = poObj;
1353 : }
1354 : }
1355 0 : catch(PoDoFo::PdfError& oError)
1356 : {
1357 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid PDF : %s", oError.what());
1358 : }
1359 4000 : }
1360 :
1361 : /************************************************************************/
1362 : /* ~GDALPDFObjectPodofo() */
1363 : /************************************************************************/
1364 :
1365 4000 : GDALPDFObjectPodofo::~GDALPDFObjectPodofo()
1366 : {
1367 4000 : delete m_poDict;
1368 4000 : delete m_poArray;
1369 4000 : delete m_poStream;
1370 4000 : }
1371 :
1372 : /************************************************************************/
1373 : /* GetType() */
1374 : /************************************************************************/
1375 :
1376 12252 : GDALPDFObjectType GDALPDFObjectPodofo::GetType()
1377 : {
1378 : try
1379 : {
1380 12252 : switch(m_po->GetDataType())
1381 : {
1382 0 : case PoDoFo::ePdfDataType_Null: return PDFObjectType_Null;
1383 0 : case PoDoFo::ePdfDataType_Bool: return PDFObjectType_Bool;
1384 3244 : case PoDoFo::ePdfDataType_Number: return PDFObjectType_Int;
1385 1344 : case PoDoFo::ePdfDataType_Real: return PDFObjectType_Real;
1386 0 : case PoDoFo::ePdfDataType_HexString: return PDFObjectType_String;
1387 332 : case PoDoFo::ePdfDataType_String: return PDFObjectType_String;
1388 1216 : case PoDoFo::ePdfDataType_Name: return PDFObjectType_Name;
1389 4156 : case PoDoFo::ePdfDataType_Array: return PDFObjectType_Array;
1390 1960 : case PoDoFo::ePdfDataType_Dictionary: return PDFObjectType_Dictionary;
1391 0 : default: return PDFObjectType_Unknown;
1392 : }
1393 : }
1394 0 : catch(PoDoFo::PdfError& oError)
1395 : {
1396 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid PDF : %s", oError.what());
1397 0 : return PDFObjectType_Unknown;
1398 : }
1399 : }
1400 :
1401 : /************************************************************************/
1402 : /* GetTypeNameNative() */
1403 : /************************************************************************/
1404 :
1405 0 : const char* GDALPDFObjectPodofo::GetTypeNameNative()
1406 : {
1407 : try
1408 : {
1409 0 : return m_po->GetDataTypeString();
1410 : }
1411 0 : catch(PoDoFo::PdfError& oError)
1412 : {
1413 0 : CPLError(CE_Failure, CPLE_AppDefined, "Invalid PDF : %s", oError.what());
1414 0 : return "unknown";
1415 : }
1416 : }
1417 :
1418 : /************************************************************************/
1419 : /* GetBool() */
1420 : /************************************************************************/
1421 :
1422 0 : int GDALPDFObjectPodofo::GetBool()
1423 : {
1424 0 : if (m_po->GetDataType() == PoDoFo::ePdfDataType_Bool)
1425 0 : return m_po->GetBool();
1426 : else
1427 0 : return 0;
1428 : }
1429 :
1430 : /************************************************************************/
1431 : /* GetInt() */
1432 : /************************************************************************/
1433 :
1434 1602 : int GDALPDFObjectPodofo::GetInt()
1435 : {
1436 1602 : if (m_po->GetDataType() == PoDoFo::ePdfDataType_Number)
1437 1602 : return (int)m_po->GetNumber();
1438 : else
1439 0 : return 0;
1440 : }
1441 :
1442 : /************************************************************************/
1443 : /* GetReal() */
1444 : /************************************************************************/
1445 :
1446 336 : double GDALPDFObjectPodofo::GetReal()
1447 : {
1448 336 : if (GetType() == PDFObjectType_Real)
1449 336 : return m_po->GetReal();
1450 : else
1451 0 : return 0.0;
1452 : }
1453 :
1454 : /************************************************************************/
1455 : /* GetString() */
1456 : /************************************************************************/
1457 :
1458 142 : const CPLString& GDALPDFObjectPodofo::GetString()
1459 : {
1460 142 : if (GetType() == PDFObjectType_String)
1461 142 : return (osStr = m_po->GetString().GetStringUtf8());
1462 : else
1463 0 : return (osStr = "");
1464 : }
1465 :
1466 : /************************************************************************/
1467 : /* GetName() */
1468 : /************************************************************************/
1469 :
1470 608 : const CPLString& GDALPDFObjectPodofo::GetName()
1471 : {
1472 608 : if (GetType() == PDFObjectType_Name)
1473 608 : return (osStr = m_po->GetName().GetName());
1474 : else
1475 0 : return (osStr = "");
1476 : }
1477 :
1478 : /************************************************************************/
1479 : /* GetDictionary() */
1480 : /************************************************************************/
1481 :
1482 1010 : GDALPDFDictionary* GDALPDFObjectPodofo::GetDictionary()
1483 : {
1484 1010 : if (GetType() != PDFObjectType_Dictionary)
1485 0 : return NULL;
1486 :
1487 1010 : if (m_poDict)
1488 74 : return m_poDict;
1489 :
1490 936 : m_poDict = new GDALPDFDictionaryPodofo(&m_po->GetDictionary(), m_poObjects);
1491 936 : return m_poDict;
1492 : }
1493 :
1494 : /************************************************************************/
1495 : /* GetArray() */
1496 : /************************************************************************/
1497 :
1498 2078 : GDALPDFArray* GDALPDFObjectPodofo::GetArray()
1499 : {
1500 2078 : if (GetType() != PDFObjectType_Array)
1501 0 : return NULL;
1502 :
1503 2078 : if (m_poArray)
1504 1798 : return m_poArray;
1505 :
1506 280 : m_poArray = new GDALPDFArrayPodofo(&m_po->GetArray(), m_poObjects);
1507 280 : return m_poArray;
1508 : }
1509 :
1510 : /************************************************************************/
1511 : /* GetStream() */
1512 : /************************************************************************/
1513 :
1514 8 : GDALPDFStream* GDALPDFObjectPodofo::GetStream()
1515 : {
1516 8 : if (!m_po->HasStream())
1517 0 : return NULL;
1518 :
1519 8 : if (m_poStream)
1520 0 : return m_poStream;
1521 8 : PoDoFo::PdfMemStream* pStream = NULL;
1522 : try
1523 : {
1524 8 : pStream = dynamic_cast<PoDoFo::PdfMemStream*>(m_po->GetStream());
1525 8 : pStream->Uncompress();
1526 : }
1527 0 : catch( const PoDoFo::PdfError & e )
1528 : {
1529 0 : e.PrintErrorMsg();
1530 0 : pStream = NULL;
1531 : }
1532 8 : if (pStream)
1533 : {
1534 8 : m_poStream = new GDALPDFStreamPodofo(pStream);
1535 8 : return m_poStream;
1536 : }
1537 : else
1538 0 : return NULL;
1539 : }
1540 :
1541 : /************************************************************************/
1542 : /* GetRefNum() */
1543 : /************************************************************************/
1544 :
1545 288 : int GDALPDFObjectPodofo::GetRefNum()
1546 : {
1547 288 : return m_po->Reference().ObjectNumber();
1548 : }
1549 :
1550 : /************************************************************************/
1551 : /* GetRefGen() */
1552 : /************************************************************************/
1553 :
1554 140 : int GDALPDFObjectPodofo::GetRefGen()
1555 : {
1556 140 : return m_po->Reference().GenerationNumber();
1557 : }
1558 :
1559 : /************************************************************************/
1560 : /* ==================================================================== */
1561 : /* GDALPDFDictionaryPodofo */
1562 : /* ==================================================================== */
1563 : /************************************************************************/
1564 :
1565 : /************************************************************************/
1566 : /* ~GDALPDFDictionaryPodofo() */
1567 : /************************************************************************/
1568 :
1569 936 : GDALPDFDictionaryPodofo::~GDALPDFDictionaryPodofo()
1570 : {
1571 936 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.begin();
1572 936 : std::map<CPLString, GDALPDFObject*>::iterator oEnd = m_map.end();
1573 2436 : for(; oIter != oEnd; ++oIter)
1574 1500 : delete oIter->second;
1575 936 : }
1576 :
1577 : /************************************************************************/
1578 : /* Get() */
1579 : /************************************************************************/
1580 :
1581 2864 : GDALPDFObject* GDALPDFDictionaryPodofo::Get(const char* pszKey)
1582 : {
1583 2864 : std::map<CPLString, GDALPDFObject*>::iterator oIter = m_map.find(pszKey);
1584 2864 : if (oIter != m_map.end())
1585 84 : return oIter->second;
1586 :
1587 2780 : PoDoFo::PdfObject* poVal = m_poDict->GetKey(PoDoFo::PdfName(pszKey));
1588 2780 : if (poVal)
1589 : {
1590 1500 : GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(poVal, m_poObjects);
1591 3000 : m_map[pszKey] = poObj;
1592 1500 : return poObj;
1593 : }
1594 : else
1595 : {
1596 1280 : return NULL;
1597 : }
1598 : }
1599 :
1600 : /************************************************************************/
1601 : /* GetValues() */
1602 : /************************************************************************/
1603 :
1604 24 : std::map<CPLString, GDALPDFObject*>& GDALPDFDictionaryPodofo::GetValues()
1605 : {
1606 24 : PoDoFo::TKeyMap::iterator oIter = m_poDict->GetKeys().begin();
1607 24 : PoDoFo::TKeyMap::iterator oEnd = m_poDict->GetKeys().end();
1608 164 : for( ; oIter != oEnd; ++oIter)
1609 : {
1610 140 : const char* pszKey = oIter->first.GetName().c_str();
1611 140 : Get(pszKey);
1612 : }
1613 :
1614 24 : return m_map;
1615 : }
1616 :
1617 : /************************************************************************/
1618 : /* ==================================================================== */
1619 : /* GDALPDFArrayPodofo */
1620 : /* ==================================================================== */
1621 : /************************************************************************/
1622 :
1623 280 : GDALPDFArrayPodofo::~GDALPDFArrayPodofo()
1624 : {
1625 1886 : for(int i=0;i<(int)m_v.size();i++)
1626 : {
1627 1606 : delete m_v[i];
1628 : }
1629 280 : }
1630 :
1631 : /************************************************************************/
1632 : /* GetLength() */
1633 : /************************************************************************/
1634 :
1635 2266 : int GDALPDFArrayPodofo::GetLength()
1636 : {
1637 2266 : return (int)m_poArray->GetSize();
1638 : }
1639 :
1640 : /************************************************************************/
1641 : /* Get() */
1642 : /************************************************************************/
1643 :
1644 1920 : GDALPDFObject* GDALPDFArrayPodofo::Get(int nIndex)
1645 : {
1646 1920 : if (nIndex < 0 || nIndex >= GetLength())
1647 0 : return NULL;
1648 :
1649 1920 : int nOldSize = (int)m_v.size();
1650 1920 : if (nIndex >= nOldSize)
1651 : {
1652 1606 : m_v.resize(nIndex+1);
1653 3212 : for(int i=nOldSize;i<=nIndex;i++)
1654 : {
1655 1606 : m_v[i] = NULL;
1656 : }
1657 : }
1658 :
1659 1920 : if (m_v[nIndex] != NULL)
1660 314 : return m_v[nIndex];
1661 :
1662 1606 : PoDoFo::PdfObject& oVal = (*m_poArray)[nIndex];
1663 1606 : GDALPDFObjectPodofo* poObj = new GDALPDFObjectPodofo(&oVal, m_poObjects);
1664 1606 : m_v[nIndex] = poObj;
1665 1606 : return poObj;
1666 : }
1667 :
1668 : /************************************************************************/
1669 : /* ==================================================================== */
1670 : /* GDALPDFStreamPodofo */
1671 : /* ==================================================================== */
1672 : /************************************************************************/
1673 :
1674 : /************************************************************************/
1675 : /* GetLength() */
1676 : /************************************************************************/
1677 :
1678 16 : int GDALPDFStreamPodofo::GetLength()
1679 : {
1680 16 : return (int)m_pStream->GetLength();
1681 : }
1682 :
1683 : /************************************************************************/
1684 : /* GetBytes() */
1685 : /************************************************************************/
1686 :
1687 8 : char* GDALPDFStreamPodofo::GetBytes()
1688 : {
1689 8 : int nLength = GetLength();
1690 8 : char* pszContent = (char*) VSIMalloc(nLength + 1);
1691 8 : if (!pszContent)
1692 0 : return NULL;
1693 8 : memcpy(pszContent, m_pStream->Get(), nLength);
1694 8 : pszContent[nLength] = '\0';
1695 8 : return pszContent;
1696 : }
1697 :
1698 : #endif // HAVE_PODOFO
|