LCOV - code coverage report
Current view: directory - frmts/pdf - pdfobject.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 656 531 80.9 %
Date: 2013-03-30 Functions: 140 102 72.9 %

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

Generated by: LCOV version 1.7