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: 2024-11-21 22:18:42 Functions: 27 30 90.0 %

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

Generated by: LCOV version 1.14