LCOV - code coverage report
Current view: directory - frmts/pdf - pdfobject.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 621 514 82.8 %
Date: 2012-12-26 Functions: 138 101 73.2 %

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

Generated by: LCOV version 1.7