LCOV - code coverage report
Current view: top level - frmts/pdf - pdfobject.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 60 64 93.8 %
Date: 2024-05-03 15:49:35 Functions: 25 27 92.6 %

          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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      19             :  * copy of this software and associated documentation files (the "Software"),
      20             :  * to deal in the Software without restriction, including without limitation
      21             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      22             :  * and/or sell copies of the Software, and to permit persons to whom the
      23             :  * Software is furnished to do so, subject to the following conditions:
      24             :  *
      25             :  * The above copyright notice and this permission notice shall be included
      26             :  * in all copies or substantial portions of the Software.
      27             :  *
      28             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      29             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      30             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      31             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      32             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      33             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      34             :  * DEALINGS IN THE SOFTWARE.
      35             :  ****************************************************************************/
      36             : 
      37             : #ifndef PDFOBJECT_H_INCLUDED
      38             : #define PDFOBJECT_H_INCLUDED
      39             : 
      40             : #include "pdfsdk_headers.h"
      41             : 
      42             : #include "cpl_string.h"
      43             : #include <map>
      44             : #include <vector>
      45             : 
      46             : #define DEFAULT_DPI (72.0)
      47             : #define USER_UNIT_IN_INCH (1.0 / DEFAULT_DPI)
      48             : 
      49             : double ROUND_TO_INT_IF_CLOSE(double x, double eps = 0);
      50             : 
      51             : typedef enum
      52             : {
      53             :     PDFObjectType_Unknown,
      54             :     PDFObjectType_Null,
      55             :     PDFObjectType_Bool,
      56             :     PDFObjectType_Int,
      57             :     PDFObjectType_Real,
      58             :     PDFObjectType_String,
      59             :     PDFObjectType_Name,
      60             :     PDFObjectType_Array,
      61             :     PDFObjectType_Dictionary
      62             : } GDALPDFObjectType;
      63             : 
      64             : class GDALPDFDictionary;
      65             : class GDALPDFArray;
      66             : class GDALPDFStream;
      67             : 
      68             : class GDALPDFObjectRW;
      69             : class GDALPDFDictionaryRW;
      70             : class GDALPDFArrayRW;
      71             : 
      72             : class GDALPDFObjectNum
      73             : {
      74             :     int m_nId;
      75             : 
      76             :   public:
      77       47529 :     explicit GDALPDFObjectNum(int nId = 0) : m_nId(nId)
      78             :     {
      79       47529 :     }
      80             : 
      81             :     GDALPDFObjectNum(const GDALPDFObjectNum &other) = default;
      82             :     GDALPDFObjectNum &operator=(const GDALPDFObjectNum &) = default;
      83             : 
      84        2674 :     GDALPDFObjectNum &operator=(int nId)
      85             :     {
      86        2674 :         m_nId = nId;
      87        2674 :         return *this;
      88             :     }
      89             : 
      90       16952 :     int toInt() const
      91             :     {
      92       16952 :         return m_nId;
      93             :     }
      94             : 
      95       19952 :     bool toBool() const
      96             :     {
      97       19952 :         return m_nId > 0;
      98             :     }
      99             : 
     100          29 :     bool operator==(const GDALPDFObjectNum &other) const
     101             :     {
     102          29 :         return m_nId == other.m_nId;
     103             :     }
     104             : 
     105           7 :     bool operator<(const GDALPDFObjectNum &other) const
     106             :     {
     107           7 :         return m_nId < other.m_nId;
     108             :     }
     109             : };
     110             : 
     111             : class GDALPDFObject
     112             : {
     113             :   protected:
     114             :     virtual const char *GetTypeNameNative() = 0;
     115             : 
     116             :   public:
     117             :     virtual ~GDALPDFObject();
     118             : 
     119             :     virtual GDALPDFObjectType GetType() = 0;
     120             :     virtual const char *GetTypeName();
     121             :     virtual int GetBool() = 0;
     122             :     virtual int GetInt() = 0;
     123             :     virtual double GetReal() = 0;
     124             : 
     125           0 :     virtual int CanRepresentRealAsString()
     126             :     {
     127           0 :         return FALSE;
     128             :     }
     129             : 
     130             :     virtual const std::string &GetString() = 0;
     131             :     virtual const std::string &GetName() = 0;
     132             :     virtual GDALPDFDictionary *GetDictionary() = 0;
     133             :     virtual GDALPDFArray *GetArray() = 0;
     134             :     virtual GDALPDFStream *GetStream() = 0;
     135             :     virtual GDALPDFObjectNum GetRefNum() = 0;
     136             :     virtual int GetRefGen() = 0;
     137             : 
     138           0 :     virtual int GetPrecision() const
     139             :     {
     140           0 :         return 16;
     141             :     }
     142             : 
     143             :     GDALPDFObject *LookupObject(const char *pszPath);
     144             : 
     145             :     void Serialize(CPLString &osStr, bool bEmitRef = true);
     146             : 
     147         852 :     CPLString Serialize()
     148             :     {
     149         852 :         CPLString osStr;
     150         852 :         Serialize(osStr);
     151         852 :         return osStr;
     152             :     }
     153             : 
     154             :     GDALPDFObjectRW *Clone();
     155             : };
     156             : 
     157             : class GDALPDFDictionary
     158             : {
     159             :   public:
     160             :     virtual ~GDALPDFDictionary();
     161             : 
     162             :     virtual GDALPDFObject *Get(const char *pszKey) = 0;
     163             :     virtual std::map<CPLString, GDALPDFObject *> &GetValues() = 0;
     164             : 
     165             :     GDALPDFObject *LookupObject(const char *pszPath);
     166             : 
     167             :     void Serialize(CPLString &osStr);
     168             : 
     169        1833 :     CPLString Serialize()
     170             :     {
     171        1833 :         CPLString osStr;
     172        1833 :         Serialize(osStr);
     173        1833 :         return osStr;
     174             :     }
     175             : 
     176             :     GDALPDFDictionaryRW *Clone();
     177             : };
     178             : 
     179             : class GDALPDFArray
     180             : {
     181             :   public:
     182             :     virtual ~GDALPDFArray();
     183             : 
     184             :     virtual int GetLength() = 0;
     185             :     virtual GDALPDFObject *Get(int nIndex) = 0;
     186             : 
     187             :     void Serialize(CPLString &osStr);
     188             : 
     189         124 :     CPLString Serialize()
     190             :     {
     191         124 :         CPLString osStr;
     192         124 :         Serialize(osStr);
     193         124 :         return osStr;
     194             :     }
     195             : 
     196             :     GDALPDFArrayRW *Clone();
     197             : };
     198             : 
     199             : class GDALPDFStream
     200             : {
     201             :   public:
     202             :     virtual ~GDALPDFStream();
     203             : 
     204             :     /** Return the uncompressed stream length, or 0 if empty or error.
     205             :      * If nMaxSize > 0, GetLength() will possibly stop the decompression once
     206             :      * the threshold is reached, and return INT64_MAX */
     207             :     virtual int64_t GetLength(int64_t nMaxSize = 0) = 0;
     208             :     virtual char *GetBytes() = 0;
     209             : 
     210             :     virtual int64_t GetRawLength() = 0;
     211             :     virtual char *GetRawBytes() = 0;
     212             : };
     213             : 
     214             : class GDALPDFObjectRW : public GDALPDFObject
     215             : {
     216             :   private:
     217             :     GDALPDFObjectType m_eType;
     218             :     int m_nVal;
     219             :     double m_dfVal;
     220             :     CPLString m_osVal;
     221             :     GDALPDFDictionaryRW *m_poDict;
     222             :     GDALPDFArrayRW *m_poArray;
     223             :     GDALPDFObjectNum m_nNum;
     224             :     int m_nGen;
     225             :     int m_bCanRepresentRealAsString;
     226             :     int m_nPrecision = 16;
     227             : 
     228             :     explicit GDALPDFObjectRW(GDALPDFObjectType eType);
     229             : 
     230             :   protected:
     231             :     virtual const char *GetTypeNameNative() override;
     232             : 
     233             :   public:
     234             :     static GDALPDFObjectRW *CreateIndirect(const GDALPDFObjectNum &nNum,
     235             :                                            int nGen);
     236             :     static GDALPDFObjectRW *CreateNull();
     237             :     static GDALPDFObjectRW *CreateBool(int bVal);
     238             :     static GDALPDFObjectRW *CreateInt(int nVal);
     239             :     static GDALPDFObjectRW *CreateReal(double dfVal,
     240             :                                        int bCanRepresentRealAsString = FALSE);
     241             :     static GDALPDFObjectRW *CreateRealWithPrecision(double dfVal,
     242             :                                                     int nPrecision);
     243             :     static GDALPDFObjectRW *CreateString(const char *pszStr);
     244             :     static GDALPDFObjectRW *CreateName(const char *pszName);
     245             :     static GDALPDFObjectRW *CreateDictionary(GDALPDFDictionaryRW *poDict);
     246             :     static GDALPDFObjectRW *CreateArray(GDALPDFArrayRW *poArray);
     247             :     virtual ~GDALPDFObjectRW();
     248             : 
     249             :     virtual GDALPDFObjectType GetType() override;
     250             :     virtual int GetBool() override;
     251             :     virtual int GetInt() override;
     252             :     virtual double GetReal() override;
     253             : 
     254         851 :     virtual int CanRepresentRealAsString() override
     255             :     {
     256         851 :         return m_bCanRepresentRealAsString;
     257             :     }
     258             : 
     259             :     virtual const CPLString &GetString() override;
     260             :     virtual const CPLString &GetName() override;
     261             :     virtual GDALPDFDictionary *GetDictionary() override;
     262             :     virtual GDALPDFArray *GetArray() override;
     263             :     virtual GDALPDFStream *GetStream() override;
     264             :     virtual GDALPDFObjectNum GetRefNum() override;
     265             :     virtual int GetRefGen() override;
     266             : 
     267         851 :     virtual int GetPrecision() const override
     268             :     {
     269         851 :         return m_nPrecision;
     270             :     }
     271             : };
     272             : 
     273             : class GDALPDFDictionaryRW : public GDALPDFDictionary
     274             : {
     275             :   private:
     276             :     std::map<CPLString, GDALPDFObject *> m_map;
     277             : 
     278             :   public:
     279             :     GDALPDFDictionaryRW();
     280             :     virtual ~GDALPDFDictionaryRW();
     281             : 
     282             :     virtual GDALPDFObject *Get(const char *pszKey) override;
     283             :     virtual std::map<CPLString, GDALPDFObject *> &GetValues() override;
     284             : 
     285             :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFObject *poVal);
     286             :     GDALPDFDictionaryRW &Remove(const char *pszKey);
     287             : 
     288        1076 :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFArrayRW *poArray)
     289             :     {
     290        1076 :         return Add(pszKey, GDALPDFObjectRW::CreateArray(poArray));
     291             :     }
     292             : 
     293         752 :     GDALPDFDictionaryRW &Add(const char *pszKey, GDALPDFDictionaryRW *poDict)
     294             :     {
     295         752 :         return Add(pszKey, GDALPDFObjectRW::CreateDictionary(poDict));
     296             :     }
     297             : 
     298         772 :     GDALPDFDictionaryRW &Add(const char *pszKey, const char *pszVal)
     299             :     {
     300         772 :         return Add(pszKey, GDALPDFObjectRW::CreateString(pszVal));
     301             :     }
     302             : 
     303        1466 :     GDALPDFDictionaryRW &Add(const char *pszKey, int nVal)
     304             :     {
     305        1466 :         return Add(pszKey, GDALPDFObjectRW::CreateInt(nVal));
     306             :     }
     307             : 
     308         255 :     GDALPDFDictionaryRW &Add(const char *pszKey, double dfVal,
     309             :                              int bCanRepresentRealAsString = FALSE)
     310             :     {
     311         255 :         return Add(pszKey, GDALPDFObjectRW::CreateReal(
     312         255 :                                dfVal, bCanRepresentRealAsString));
     313             :     }
     314             : 
     315        2331 :     GDALPDFDictionaryRW &Add(const char *pszKey, const GDALPDFObjectNum &nNum,
     316             :                              int nGen)
     317             :     {
     318        2331 :         return Add(pszKey, GDALPDFObjectRW::CreateIndirect(nNum, nGen));
     319             :     }
     320             : };
     321             : 
     322             : class GDALPDFArrayRW : public GDALPDFArray
     323             : {
     324             :   private:
     325             :     std::vector<GDALPDFObject *> m_array;
     326             : 
     327             :   public:
     328             :     GDALPDFArrayRW();
     329             :     virtual ~GDALPDFArrayRW();
     330             : 
     331             :     virtual int GetLength() override;
     332             :     virtual GDALPDFObject *Get(int nIndex) override;
     333             : 
     334             :     GDALPDFArrayRW &Add(GDALPDFObject *poObj);
     335             : 
     336          25 :     GDALPDFArrayRW &Add(GDALPDFArrayRW *poArray)
     337             :     {
     338          25 :         return Add(GDALPDFObjectRW::CreateArray(poArray));
     339             :     }
     340             : 
     341         194 :     GDALPDFArrayRW &Add(GDALPDFDictionaryRW *poDict)
     342             :     {
     343         194 :         return Add(GDALPDFObjectRW::CreateDictionary(poDict));
     344             :     }
     345             : 
     346           3 :     GDALPDFArrayRW &Add(const char *pszVal)
     347             :     {
     348           3 :         return Add(GDALPDFObjectRW::CreateString(pszVal));
     349             :     }
     350             : 
     351        1993 :     GDALPDFArrayRW &Add(int nVal)
     352             :     {
     353        1993 :         return Add(GDALPDFObjectRW::CreateInt(nVal));
     354             :     }
     355             : 
     356        1520 :     GDALPDFArrayRW &Add(double dfVal, int bCanRepresentRealAsString = FALSE)
     357             :     {
     358             :         return Add(
     359        1520 :             GDALPDFObjectRW::CreateReal(dfVal, bCanRepresentRealAsString));
     360             :     }
     361             : 
     362          64 :     GDALPDFArrayRW &AddWithPrecision(double dfVal, int nPrecision)
     363             :     {
     364          64 :         return Add(GDALPDFObjectRW::CreateRealWithPrecision(dfVal, nPrecision));
     365             :     }
     366             : 
     367             :     GDALPDFArrayRW &Add(double *padfVal, int nCount,
     368             :                         int bCanRepresentRealAsString = FALSE);
     369             : 
     370         476 :     GDALPDFArrayRW &Add(const GDALPDFObjectNum &nNum, int nGen)
     371             :     {
     372         476 :         return Add(GDALPDFObjectRW::CreateIndirect(nNum, nGen));
     373             :     }
     374             : };
     375             : 
     376             : #ifdef HAVE_POPPLER
     377             : 
     378             : class GDALPDFObjectPoppler : public GDALPDFObject
     379             : {
     380             :   private:
     381             :     Object *m_po;
     382             :     int m_bDestroy;
     383             :     GDALPDFDictionary *m_poDict;
     384             :     GDALPDFArray *m_poArray;
     385             :     GDALPDFStream *m_poStream;
     386             :     std::string osStr;
     387             :     GDALPDFObjectNum m_nRefNum;
     388             :     int m_nRefGen;
     389             : 
     390             :   protected:
     391             :     virtual const char *GetTypeNameNative() override;
     392             : 
     393             :   public:
     394       11943 :     GDALPDFObjectPoppler(Object *po, int bDestroy)
     395       11943 :         : m_po(po), m_bDestroy(bDestroy), m_poDict(nullptr), m_poArray(nullptr),
     396       11943 :           m_poStream(nullptr), m_nRefNum(0), m_nRefGen(0)
     397             :     {
     398       11943 :     }
     399             : 
     400             :     void SetRefNumAndGen(const GDALPDFObjectNum &nNum, int nGen);
     401             : 
     402             :     virtual ~GDALPDFObjectPoppler();
     403             : 
     404             :     virtual GDALPDFObjectType GetType() override;
     405             :     virtual int GetBool() override;
     406             :     virtual int GetInt() override;
     407             :     virtual double GetReal() override;
     408             :     virtual const std::string &GetString() override;
     409             :     virtual const std::string &GetName() override;
     410             :     virtual GDALPDFDictionary *GetDictionary() override;
     411             :     virtual GDALPDFArray *GetArray() override;
     412             :     virtual GDALPDFStream *GetStream() override;
     413             :     virtual GDALPDFObjectNum GetRefNum() override;
     414             :     virtual int GetRefGen() override;
     415             : };
     416             : 
     417             : GDALPDFArray *GDALPDFCreateArray(Array *array);
     418             : 
     419             : #endif  // HAVE_POPPLER
     420             : 
     421             : #ifdef HAVE_PODOFO
     422             : 
     423             : class GDALPDFObjectPodofo : public GDALPDFObject
     424             : {
     425             :   private:
     426             :     const PoDoFo::PdfObject *m_po;
     427             :     const PoDoFo::PdfVecObjects &m_poObjects;
     428             :     GDALPDFDictionary *m_poDict;
     429             :     GDALPDFArray *m_poArray;
     430             :     GDALPDFStream *m_poStream;
     431             :     std::string osStr;
     432             : 
     433             :   protected:
     434             :     virtual const char *GetTypeNameNative() override;
     435             : 
     436             :   public:
     437             :     GDALPDFObjectPodofo(const PoDoFo::PdfObject *po,
     438             :                         const PoDoFo::PdfVecObjects &poObjects);
     439             : 
     440             :     virtual ~GDALPDFObjectPodofo();
     441             : 
     442             :     virtual GDALPDFObjectType GetType() override;
     443             :     virtual int GetBool() override;
     444             :     virtual int GetInt() override;
     445             :     virtual double GetReal() override;
     446             :     virtual const std::string &GetString() override;
     447             :     virtual const std::string &GetName() override;
     448             :     virtual GDALPDFDictionary *GetDictionary() override;
     449             :     virtual GDALPDFArray *GetArray() override;
     450             :     virtual GDALPDFStream *GetStream() override;
     451             :     virtual GDALPDFObjectNum GetRefNum() override;
     452             :     virtual int GetRefGen() override;
     453             : };
     454             : 
     455             : #endif  // HAVE_PODOFO
     456             : 
     457             : #ifdef HAVE_PDFIUM
     458             : 
     459             : class GDALPDFObjectPdfium : public GDALPDFObject
     460             : {
     461             :   private:
     462             :     RetainPtr<const CPDF_Object> m_obj;
     463             :     GDALPDFDictionary *m_poDict;
     464             :     GDALPDFArray *m_poArray;
     465             :     GDALPDFStream *m_poStream;
     466             :     std::string osStr;
     467             : 
     468             :     GDALPDFObjectPdfium(RetainPtr<const CPDF_Object> obj);
     469             : 
     470             :   protected:
     471             :     virtual const char *GetTypeNameNative() override;
     472             : 
     473             :   public:
     474             :     static GDALPDFObjectPdfium *Build(RetainPtr<const CPDF_Object> obj);
     475             : 
     476             :     virtual ~GDALPDFObjectPdfium();
     477             : 
     478             :     virtual GDALPDFObjectType GetType() override;
     479             :     virtual int GetBool() override;
     480             :     virtual int GetInt() override;
     481             :     virtual double GetReal() override;
     482             :     virtual const std::string &GetString() override;
     483             :     virtual const std::string &GetName() override;
     484             :     virtual GDALPDFDictionary *GetDictionary() override;
     485             :     virtual GDALPDFArray *GetArray() override;
     486             :     virtual GDALPDFStream *GetStream() override;
     487             :     virtual GDALPDFObjectNum GetRefNum() override;
     488             :     virtual int GetRefGen() override;
     489             : };
     490             : 
     491             : #endif  // HAVE_PDFIUM
     492             : 
     493             : #endif  // PDFOBJECT_H_INCLUDED

Generated by: LCOV version 1.14