LCOV - code coverage report
Current view: top level - frmts/pdf - pdfobject.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 61 65 93.8 %
Date: 2025-02-20 10:14:44 Functions: 27 30 90.0 %

          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       48005 :     explicit GDALPDFObjectNum(int nId = 0) : m_nId(nId)
      61             :     {
      62       48005 :     }
      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       18315 :     int toInt() const
      74             :     {
      75       18315 :         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         715 :     virtual int CanRepresentRealAsString() override
     240             :     {
     241         715 :         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         715 :     virtual int GetPrecision() const override
     253             :     {
     254         715 :         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_po;
     371             :     const bool m_bDestroy;
     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       11365 :     GDALPDFObjectPoppler(Object *po, bool bDestroy)
     386       11365 :         : m_po(po), m_bDestroy(bDestroy)
     387             :     {
     388       11365 :     }
     389             : 
     390             :     void SetRefNumAndGen(const GDALPDFObjectNum &nNum, int nGen);
     391             : 
     392             :     virtual ~GDALPDFObjectPoppler();
     393             : 
     394             :     virtual GDALPDFObjectType GetType() override;
     395             :     virtual int GetBool() override;
     396             :     virtual int GetInt() override;
     397             :     virtual double GetReal() override;
     398             :     virtual const std::string &GetString() override;
     399             :     virtual const std::string &GetName() override;
     400             :     virtual GDALPDFDictionary *GetDictionary() override;
     401             :     virtual GDALPDFArray *GetArray() override;
     402             :     virtual GDALPDFStream *GetStream() override;
     403             :     virtual GDALPDFObjectNum GetRefNum() override;
     404             :     virtual int GetRefGen() override;
     405             : };
     406             : 
     407             : GDALPDFArray *GDALPDFCreateArray(const Array *array);
     408             : 
     409             : #endif  // HAVE_POPPLER
     410             : 
     411             : #ifdef HAVE_PODOFO
     412             : 
     413             : class GDALPDFObjectPodofo : public GDALPDFObject
     414             : {
     415             :   private:
     416             :     const PoDoFo::PdfObject *m_po;
     417             :     const PoDoFo::PdfVecObjects &m_poObjects;
     418             :     GDALPDFDictionary *m_poDict = nullptr;
     419             :     GDALPDFArray *m_poArray = nullptr;
     420             :     GDALPDFStream *m_poStream = nullptr;
     421             :     std::string osStr{};
     422             : 
     423             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPodofo)
     424             : 
     425             :   protected:
     426             :     virtual const char *GetTypeNameNative() override;
     427             : 
     428             :   public:
     429             :     GDALPDFObjectPodofo(const PoDoFo::PdfObject *po,
     430             :                         const PoDoFo::PdfVecObjects &poObjects);
     431             : 
     432             :     virtual ~GDALPDFObjectPodofo();
     433             : 
     434             :     virtual GDALPDFObjectType GetType() override;
     435             :     virtual int GetBool() override;
     436             :     virtual int GetInt() override;
     437             :     virtual double GetReal() override;
     438             :     virtual const std::string &GetString() override;
     439             :     virtual const std::string &GetName() override;
     440             :     virtual GDALPDFDictionary *GetDictionary() override;
     441             :     virtual GDALPDFArray *GetArray() override;
     442             :     virtual GDALPDFStream *GetStream() override;
     443             :     virtual GDALPDFObjectNum GetRefNum() override;
     444             :     virtual int GetRefGen() override;
     445             : };
     446             : 
     447             : #endif  // HAVE_PODOFO
     448             : 
     449             : #ifdef HAVE_PDFIUM
     450             : 
     451             : class GDALPDFObjectPdfium : public GDALPDFObject
     452             : {
     453             :   private:
     454             :     RetainPtr<const CPDF_Object> m_obj;
     455             :     GDALPDFDictionary *m_poDict = nullptr;
     456             :     GDALPDFArray *m_poArray = nullptr;
     457             :     GDALPDFStream *m_poStream = nullptr;
     458             :     std::string osStr{};
     459             : 
     460             :     GDALPDFObjectPdfium(RetainPtr<const CPDF_Object> obj);
     461             : 
     462             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFObjectPdfium)
     463             : 
     464             :   protected:
     465             :     virtual const char *GetTypeNameNative() override;
     466             : 
     467             :   public:
     468             :     static GDALPDFObjectPdfium *Build(RetainPtr<const CPDF_Object> obj);
     469             : 
     470             :     virtual ~GDALPDFObjectPdfium();
     471             : 
     472             :     virtual GDALPDFObjectType GetType() override;
     473             :     virtual int GetBool() override;
     474             :     virtual int GetInt() override;
     475             :     virtual double GetReal() override;
     476             :     virtual const std::string &GetString() override;
     477             :     virtual const std::string &GetName() override;
     478             :     virtual GDALPDFDictionary *GetDictionary() override;
     479             :     virtual GDALPDFArray *GetArray() override;
     480             :     virtual GDALPDFStream *GetStream() override;
     481             :     virtual GDALPDFObjectNum GetRefNum() override;
     482             :     virtual int GetRefGen() override;
     483             : };
     484             : 
     485             : #endif  // HAVE_PDFIUM
     486             : 
     487             : #endif  // PDFOBJECT_H_INCLUDED

Generated by: LCOV version 1.14