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