LCOV - code coverage report
Current view: top level - frmts/pdf - pdfobject.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 64 68 94.1 %
Date: 2025-06-08 21:14:40 Functions: 28 31 90.3 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PDF driver
       4             :  * Purpose:  GDALDataset driver for PDF dataset.
       5             :  * Author:   Even Rouault, <even dot rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  *
       9             :  * Support for open-source PDFium library
      10             :  *
      11             :  * Copyright (C) 2015 Klokan Technologies GmbH (http://www.klokantech.com/)
      12             :  * Author: Martin Mikita <martin.mikita@klokantech.com>, xmikit00 @ FIT VUT Brno
      13             :  *
      14             :  ******************************************************************************
      15             :  * Copyright (c) 2011-2014, Even Rouault <even dot rouault at spatialys.com>
      16             :  *
      17             :  * SPDX-License-Identifier: MIT
      18             :  ****************************************************************************/
      19             : 
      20             : #ifndef PDFOBJECT_H_INCLUDED
      21             : #define PDFOBJECT_H_INCLUDED
      22             : 
      23             : #include "pdfsdk_headers_all.h"
      24             : 
      25             : #include "cpl_string.h"
      26             : #include <map>
      27             : #include <vector>
      28             : 
      29             : #define DEFAULT_DPI (72.0)
      30             : #define USER_UNIT_IN_INCH (1.0 / DEFAULT_DPI)
      31             : 
      32             : double ROUND_IF_CLOSE(double x, double eps = 0);
      33             : 
      34             : typedef enum
      35             : {
      36             :     PDFObjectType_Unknown,
      37             :     PDFObjectType_Null,
      38             :     PDFObjectType_Bool,
      39             :     PDFObjectType_Int,
      40             :     PDFObjectType_Real,
      41             :     PDFObjectType_String,
      42             :     PDFObjectType_Name,
      43             :     PDFObjectType_Array,
      44             :     PDFObjectType_Dictionary
      45             : } GDALPDFObjectType;
      46             : 
      47             : class GDALPDFDictionary;
      48             : class GDALPDFArray;
      49             : class GDALPDFStream;
      50             : 
      51             : class GDALPDFObjectRW;
      52             : class GDALPDFDictionaryRW;
      53             : class GDALPDFArrayRW;
      54             : 
      55             : class GDALPDFObjectNum
      56             : {
      57             :     int m_nId;
      58             : 
      59             :   public:
      60       48027 :     explicit GDALPDFObjectNum(int nId = 0) : m_nId(nId)
      61             :     {
      62       48027 :     }
      63             : 
      64             :     GDALPDFObjectNum(const GDALPDFObjectNum &other) = default;
      65             :     GDALPDFObjectNum &operator=(const GDALPDFObjectNum &) = default;
      66             : 
      67        2608 :     GDALPDFObjectNum &operator=(int nId)
      68             :     {
      69        2608 :         m_nId = nId;
      70        2608 :         return *this;
      71             :     }
      72             : 
      73       18327 :     int toInt() const
      74             :     {
      75       18327 :         return m_nId;
      76             :     }
      77             : 
      78       21151 :     bool toBool() const
      79             :     {
      80       21151 :         return m_nId > 0;
      81             :     }
      82             : 
      83          33 :     bool operator==(const GDALPDFObjectNum &other) const
      84             :     {
      85          33 :         return m_nId == other.m_nId;
      86             :     }
      87             : 
      88           7 :     bool operator<(const GDALPDFObjectNum &other) const
      89             :     {
      90           7 :         return m_nId < other.m_nId;
      91             :     }
      92             : };
      93             : 
      94             : class GDALPDFObject
      95             : {
      96             :   protected:
      97             :     virtual const char *GetTypeNameNative() = 0;
      98             : 
      99             :   public:
     100             :     virtual ~GDALPDFObject();
     101             : 
     102             :     virtual GDALPDFObjectType GetType() = 0;
     103             :     virtual const char *GetTypeName();
     104             :     virtual int GetBool() = 0;
     105             :     virtual int GetInt() = 0;
     106             :     virtual double GetReal() = 0;
     107             : 
     108           0 :     virtual int CanRepresentRealAsString()
     109             :     {
     110           0 :         return FALSE;
     111             :     }
     112             : 
     113             :     virtual const std::string &GetString() = 0;
     114             :     virtual const std::string &GetName() = 0;
     115             :     virtual GDALPDFDictionary *GetDictionary() = 0;
     116             :     virtual GDALPDFArray *GetArray() = 0;
     117             :     virtual GDALPDFStream *GetStream() = 0;
     118             :     virtual GDALPDFObjectNum GetRefNum() = 0;
     119             :     virtual int GetRefGen() = 0;
     120             : 
     121           0 :     virtual int GetPrecision() const
     122             :     {
     123           0 :         return 16;
     124             :     }
     125             : 
     126             :     GDALPDFObject *LookupObject(const char *pszPath);
     127             : 
     128             :     void Serialize(CPLString &osStr, bool bEmitRef = true);
     129             : 
     130         800 :     CPLString Serialize()
     131             :     {
     132         800 :         CPLString osStr;
     133         800 :         Serialize(osStr);
     134         800 :         return osStr;
     135             :     }
     136             : 
     137             :     GDALPDFObjectRW *Clone();
     138             : };
     139             : 
     140             : class GDALPDFDictionary
     141             : {
     142             :   public:
     143             :     virtual ~GDALPDFDictionary();
     144             : 
     145             :     virtual GDALPDFObject *Get(const char *pszKey) = 0;
     146             :     virtual std::map<CPLString, GDALPDFObject *> &GetValues() = 0;
     147             : 
     148             :     GDALPDFObject *LookupObject(const char *pszPath);
     149             : 
     150             :     void Serialize(CPLString &osStr);
     151             : 
     152        1861 :     CPLString Serialize()
     153             :     {
     154        1861 :         CPLString osStr;
     155        1861 :         Serialize(osStr);
     156        1861 :         return osStr;
     157             :     }
     158             : 
     159             :     GDALPDFDictionaryRW *Clone();
     160             : };
     161             : 
     162             : class GDALPDFArray
     163             : {
     164             :   public:
     165             :     virtual ~GDALPDFArray();
     166             : 
     167             :     virtual int GetLength() = 0;
     168             :     virtual GDALPDFObject *Get(int nIndex) = 0;
     169             : 
     170             :     void Serialize(CPLString &osStr);
     171             : 
     172         115 :     CPLString Serialize()
     173             :     {
     174         115 :         CPLString osStr;
     175         115 :         Serialize(osStr);
     176         115 :         return osStr;
     177             :     }
     178             : 
     179             :     GDALPDFArrayRW *Clone();
     180             : };
     181             : 
     182         769 : class GDALPDFStream
     183             : {
     184             :   public:
     185             :     virtual ~GDALPDFStream();
     186             : 
     187             :     /** Return the uncompressed stream length, or 0 if empty or error.
     188             :      * If nMaxSize > 0, GetLength() will possibly stop the decompression once
     189             :      * the threshold is reached, and return INT64_MAX */
     190             :     virtual int64_t GetLength(int64_t nMaxSize = 0) = 0;
     191             :     virtual char *GetBytes() = 0;
     192             : 
     193             :     virtual int64_t GetRawLength() = 0;
     194             :     virtual char *GetRawBytes() = 0;
     195             : };
     196             : 
     197             : class GDALPDFObjectRW : public GDALPDFObject
     198             : {
     199             :   private:
     200             :     const GDALPDFObjectType m_eType;
     201             :     int m_nVal = 0;
     202             :     double m_dfVal = 0;
     203             :     CPLString m_osVal{};
     204             :     GDALPDFDictionaryRW *m_poDict = nullptr;
     205             :     GDALPDFArrayRW *m_poArray = nullptr;
     206             :     GDALPDFObjectNum m_nNum{};
     207             :     int m_nGen = 0;
     208             :     int m_bCanRepresentRealAsString = FALSE;
     209             :     int m_nPrecision = 16;
     210             : 
     211             :     explicit GDALPDFObjectRW(GDALPDFObjectType eType);
     212             : 
     213             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectRW)
     214             : 
     215             :   protected:
     216             :     virtual const char *GetTypeNameNative() override;
     217             : 
     218             :   public:
     219             :     static GDALPDFObjectRW *CreateIndirect(const GDALPDFObjectNum &nNum,
     220             :                                            int nGen);
     221             :     static GDALPDFObjectRW *CreateNull();
     222             :     static GDALPDFObjectRW *CreateBool(int bVal);
     223             :     static GDALPDFObjectRW *CreateInt(int nVal);
     224             :     static GDALPDFObjectRW *CreateReal(double dfVal,
     225             :                                        int bCanRepresentRealAsString = FALSE);
     226             :     static GDALPDFObjectRW *CreateRealWithPrecision(double dfVal,
     227             :                                                     int nPrecision);
     228             :     static GDALPDFObjectRW *CreateString(const char *pszStr);
     229             :     static GDALPDFObjectRW *CreateName(const char *pszName);
     230             :     static GDALPDFObjectRW *CreateDictionary(GDALPDFDictionaryRW *poDict);
     231             :     static GDALPDFObjectRW *CreateArray(GDALPDFArrayRW *poArray);
     232             :     virtual ~GDALPDFObjectRW();
     233             : 
     234             :     virtual GDALPDFObjectType GetType() override;
     235             :     virtual int GetBool() override;
     236             :     virtual int GetInt() override;
     237             :     virtual double GetReal() override;
     238             : 
     239         713 :     virtual int CanRepresentRealAsString() override
     240             :     {
     241         713 :         return m_bCanRepresentRealAsString;
     242             :     }
     243             : 
     244             :     virtual const CPLString &GetString() override;
     245             :     virtual const CPLString &GetName() override;
     246             :     virtual GDALPDFDictionary *GetDictionary() override;
     247             :     virtual GDALPDFArray *GetArray() override;
     248             :     virtual GDALPDFStream *GetStream() override;
     249             :     virtual GDALPDFObjectNum GetRefNum() override;
     250             :     virtual int GetRefGen() override;
     251             : 
     252         713 :     virtual int GetPrecision() const override
     253             :     {
     254         713 :         return m_nPrecision;
     255             :     }
     256             : };
     257             : 
     258        3049 : class GDALPDFDictionaryRW : public GDALPDFDictionary
     259             : {
     260             :   private:
     261             :     std::map<CPLString, GDALPDFObject *> m_map{};
     262             : 
     263             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFDictionaryRW)
     264             : 
     265             :   public:
     266             :     GDALPDFDictionaryRW();
     267             :     virtual ~GDALPDFDictionaryRW();
     268             : 
     269             :     virtual GDALPDFObject *Get(const char *pszKey) override;
     270             :     virtual std::map<CPLString, GDALPDFObject *> &GetValues() override;
     271             : 
     272             :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFObject *poVal);
     273             :     GDALPDFDictionaryRW &Remove(const char *pszKey);
     274             : 
     275        1154 :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFArrayRW *poArray)
     276             :     {
     277        1154 :         return Add(pszKey, GDALPDFObjectRW::CreateArray(poArray));
     278             :     }
     279             : 
     280         968 :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFDictionaryRW *poDict)
     281             :     {
     282         968 :         return Add(pszKey, GDALPDFObjectRW::CreateDictionary(poDict));
     283             :     }
     284             : 
     285         775 :     GDALPDFDictionaryRW &Add(const char *pszKey, const char *pszVal)
     286             :     {
     287         775 :         return Add(pszKey, GDALPDFObjectRW::CreateString(pszVal));
     288             :     }
     289             : 
     290        1450 :     GDALPDFDictionaryRW &Add(const char *pszKey, int nVal)
     291             :     {
     292        1450 :         return Add(pszKey, GDALPDFObjectRW::CreateInt(nVal));
     293             :     }
     294             : 
     295         265 :     GDALPDFDictionaryRW &Add(const char *pszKey, double dfVal,
     296             :                              int bCanRepresentRealAsString = FALSE)
     297             :     {
     298         265 :         return Add(pszKey, GDALPDFObjectRW::CreateReal(
     299         265 :                                dfVal, bCanRepresentRealAsString));
     300             :     }
     301             : 
     302        2430 :     GDALPDFDictionaryRW &Add(const char *pszKey, const GDALPDFObjectNum &nNum,
     303             :                              int nGen)
     304             :     {
     305        2430 :         return Add(pszKey, GDALPDFObjectRW::CreateIndirect(nNum, nGen));
     306             :     }
     307             : };
     308             : 
     309             : class GDALPDFArrayRW : public GDALPDFArray
     310             : {
     311             :   private:
     312             :     std::vector<GDALPDFObject *> m_array{};
     313             : 
     314             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFArrayRW)
     315             : 
     316             :   public:
     317             :     GDALPDFArrayRW();
     318             :     virtual ~GDALPDFArrayRW();
     319             : 
     320             :     virtual int GetLength() override;
     321             :     virtual GDALPDFObject *Get(int nIndex) override;
     322             : 
     323             :     GDALPDFArrayRW &Add(GDALPDFObject *poObj);
     324             : 
     325          15 :     GDALPDFArrayRW &Add(GDALPDFArrayRW *poArray)
     326             :     {
     327          15 :         return Add(GDALPDFObjectRW::CreateArray(poArray));
     328             :     }
     329             : 
     330         206 :     GDALPDFArrayRW &Add(GDALPDFDictionaryRW *poDict)
     331             :     {
     332         206 :         return Add(GDALPDFObjectRW::CreateDictionary(poDict));
     333             :     }
     334             : 
     335           3 :     GDALPDFArrayRW &Add(const char *pszVal)
     336             :     {
     337           3 :         return Add(GDALPDFObjectRW::CreateString(pszVal));
     338             :     }
     339             : 
     340        2259 :     GDALPDFArrayRW &Add(int nVal)
     341             :     {
     342        2259 :         return Add(GDALPDFObjectRW::CreateInt(nVal));
     343             :     }
     344             : 
     345        1420 :     GDALPDFArrayRW &Add(double dfVal, int bCanRepresentRealAsString = FALSE)
     346             :     {
     347             :         return Add(
     348        1420 :             GDALPDFObjectRW::CreateReal(dfVal, bCanRepresentRealAsString));
     349             :     }
     350             : 
     351          64 :     GDALPDFArrayRW &AddWithPrecision(double dfVal, int nPrecision)
     352             :     {
     353          64 :         return Add(GDALPDFObjectRW::CreateRealWithPrecision(dfVal, nPrecision));
     354             :     }
     355             : 
     356             :     GDALPDFArrayRW &Add(double *padfVal, int nCount,
     357             :                         int bCanRepresentRealAsString = FALSE);
     358             : 
     359         519 :     GDALPDFArrayRW &Add(const GDALPDFObjectNum &nNum, int nGen)
     360             :     {
     361         519 :         return Add(GDALPDFObjectRW::CreateIndirect(nNum, nGen));
     362             :     }
     363             : };
     364             : 
     365             : #ifdef HAVE_POPPLER
     366             : 
     367             : class GDALPDFObjectPoppler : public GDALPDFObject
     368             : {
     369             :   private:
     370             :     Object *m_poToDestroy;
     371             :     const Object *m_poConst;
     372             :     GDALPDFDictionary *m_poDict = nullptr;
     373             :     GDALPDFArray *m_poArray = nullptr;
     374             :     GDALPDFStream *m_poStream = nullptr;
     375             :     std::string osStr{};
     376             :     GDALPDFObjectNum m_nRefNum{};
     377             :     int m_nRefGen = 0;
     378             : 
     379             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPoppler)
     380             : 
     381             :   protected:
     382             :     virtual const char *GetTypeNameNative() override;
     383             : 
     384             :   public:
     385       11198 :     GDALPDFObjectPoppler(Object *po, bool bDestroy)
     386       11198 :         : m_poToDestroy(bDestroy ? po : nullptr), m_poConst(po)
     387             :     {
     388       11198 :     }
     389             : 
     390         167 :     GDALPDFObjectPoppler(const Object *po)
     391         167 :         : m_poToDestroy(nullptr), m_poConst(po)
     392             :     {
     393         167 :     }
     394             : 
     395             :     void SetRefNumAndGen(const GDALPDFObjectNum &nNum, int nGen);
     396             : 
     397             :     virtual ~GDALPDFObjectPoppler();
     398             : 
     399             :     virtual GDALPDFObjectType GetType() override;
     400             :     virtual int GetBool() override;
     401             :     virtual int GetInt() override;
     402             :     virtual double GetReal() override;
     403             :     virtual const std::string &GetString() override;
     404             :     virtual const std::string &GetName() override;
     405             :     virtual GDALPDFDictionary *GetDictionary() override;
     406             :     virtual GDALPDFArray *GetArray() override;
     407             :     virtual GDALPDFStream *GetStream() override;
     408             :     virtual GDALPDFObjectNum GetRefNum() override;
     409             :     virtual int GetRefGen() override;
     410             : };
     411             : 
     412             : GDALPDFArray *GDALPDFCreateArray(const Array *array);
     413             : 
     414             : #endif  // HAVE_POPPLER
     415             : 
     416             : #ifdef HAVE_PODOFO
     417             : 
     418             : class GDALPDFObjectPodofo : public GDALPDFObject
     419             : {
     420             :   private:
     421             :     const PoDoFo::PdfObject *m_po;
     422             :     const PoDoFo::PdfVecObjects &m_poObjects;
     423             :     GDALPDFDictionary *m_poDict = nullptr;
     424             :     GDALPDFArray *m_poArray = nullptr;
     425             :     GDALPDFStream *m_poStream = nullptr;
     426             :     std::string osStr{};
     427             : 
     428             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPodofo)
     429             : 
     430             :   protected:
     431             :     virtual const char *GetTypeNameNative() override;
     432             : 
     433             :   public:
     434             :     GDALPDFObjectPodofo(const PoDoFo::PdfObject *po,
     435             :                         const PoDoFo::PdfVecObjects &poObjects);
     436             : 
     437             :     virtual ~GDALPDFObjectPodofo();
     438             : 
     439             :     virtual GDALPDFObjectType GetType() override;
     440             :     virtual int GetBool() override;
     441             :     virtual int GetInt() override;
     442             :     virtual double GetReal() override;
     443             :     virtual const std::string &GetString() override;
     444             :     virtual const std::string &GetName() override;
     445             :     virtual GDALPDFDictionary *GetDictionary() override;
     446             :     virtual GDALPDFArray *GetArray() override;
     447             :     virtual GDALPDFStream *GetStream() override;
     448             :     virtual GDALPDFObjectNum GetRefNum() override;
     449             :     virtual int GetRefGen() override;
     450             : };
     451             : 
     452             : #endif  // HAVE_PODOFO
     453             : 
     454             : #ifdef HAVE_PDFIUM
     455             : 
     456             : class GDALPDFObjectPdfium : public GDALPDFObject
     457             : {
     458             :   private:
     459             :     RetainPtr<const CPDF_Object> m_obj;
     460             :     GDALPDFDictionary *m_poDict = nullptr;
     461             :     GDALPDFArray *m_poArray = nullptr;
     462             :     GDALPDFStream *m_poStream = nullptr;
     463             :     std::string osStr{};
     464             : 
     465             :     GDALPDFObjectPdfium(RetainPtr<const CPDF_Object> obj);
     466             : 
     467             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPdfium)
     468             : 
     469             :   protected:
     470             :     virtual const char *GetTypeNameNative() override;
     471             : 
     472             :   public:
     473             :     static GDALPDFObjectPdfium *Build(RetainPtr<const CPDF_Object> obj);
     474             : 
     475             :     virtual ~GDALPDFObjectPdfium();
     476             : 
     477             :     virtual GDALPDFObjectType GetType() override;
     478             :     virtual int GetBool() override;
     479             :     virtual int GetInt() override;
     480             :     virtual double GetReal() override;
     481             :     virtual const std::string &GetString() override;
     482             :     virtual const std::string &GetName() override;
     483             :     virtual GDALPDFDictionary *GetDictionary() override;
     484             :     virtual GDALPDFArray *GetArray() override;
     485             :     virtual GDALPDFStream *GetStream() override;
     486             :     virtual GDALPDFObjectNum GetRefNum() override;
     487             :     virtual int GetRefGen() override;
     488             : };
     489             : 
     490             : #endif  // HAVE_PDFIUM
     491             : 
     492             : #endif  // PDFOBJECT_H_INCLUDED

Generated by: LCOV version 1.14