LCOV - code coverage report
Current view: directory - frmts/pdf - pdfobject.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 611 505 82.7 %
Date: 2012-04-28 Functions: 134 98 73.1 %

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

Generated by: LCOV version 1.7