LCOV - code coverage report
Current view: top level - frmts/pdf - gdal_pdf.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 14 16 87.5 %
Date: 2026-02-03 21:43:34 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  PDF Translator
       4             :  * Purpose:  Definition of classes for OGR .pdf driver.
       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) 2010-2014, Even Rouault <even dot rouault at spatialys.com>
      16             :  *
      17             :  * SPDX-License-Identifier: MIT
      18             :  ****************************************************************************/
      19             : 
      20             : #ifndef GDAL_PDF_H_INCLUDED
      21             : #define GDAL_PDF_H_INCLUDED
      22             : 
      23             : /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef
      24             :  * bool GBool" */
      25             : /* in include/poppler/goo/gtypes.h with the one defined in cpl_port.h */
      26             : #define CPL_GBOOL_DEFINED
      27             : #define OGR_FEATURESTYLE_INCLUDE
      28             : #include "cpl_port.h"
      29             : 
      30             : #include <array>
      31             : #include <map>
      32             : #include <set>
      33             : #include <stack>
      34             : #include <utility>
      35             : #include <bitset>  // For detecting usage of PDF library
      36             : #include <algorithm>
      37             : 
      38             : #include "pdfsdk_headers_all.h"
      39             : 
      40             : #include "pdfdrivercore.h"
      41             : 
      42             : #include "cpl_vsi_virtual.h"
      43             : 
      44             : #include "gdal_pam.h"
      45             : #include "ogrsf_frmts.h"
      46             : 
      47             : #include "memdataset.h"
      48             : #include "pdfobject.h"
      49             : 
      50             : #define PDFLIB_POPPLER 0
      51             : #define PDFLIB_PODOFO 1
      52             : #define PDFLIB_PDFIUM 2
      53             : #define PDFLIB_COUNT 3
      54             : 
      55             : /************************************************************************/
      56             : /*                             OGRPDFLayer                              */
      57             : /************************************************************************/
      58             : 
      59             : #ifdef HAVE_PDF_READ_SUPPORT
      60             : 
      61             : class PDFDataset;
      62             : 
      63             : class OGRPDFLayer final : public OGRMemLayer
      64             : {
      65             :     PDFDataset *poDS;
      66             :     int bGeomTypeSet;
      67             :     int bGeomTypeMixed;
      68             : 
      69             :     CPL_DISALLOW_COPY_ASSIGN(OGRPDFLayer)
      70             : 
      71             :   public:
      72             :     OGRPDFLayer(PDFDataset *poDS, const char *pszName,
      73             :                 OGRSpatialReference *poSRS, OGRwkbGeometryType eGeomType);
      74             : 
      75             :     void Fill(GDALPDFArray *poArray);
      76             : 
      77             :     int TestCapability(const char *) const override;
      78             : 
      79             :     GDALDataset *GetDataset() override;
      80             : };
      81             : 
      82             : #endif
      83             : 
      84             : /************************************************************************/
      85             : /*                         OGRPDFWritableLayer                          */
      86             : /************************************************************************/
      87             : 
      88             : class PDFWritableVectorDataset;
      89             : 
      90             : class OGRPDFWritableLayer final : public OGRMemLayer
      91             : {
      92             :     PDFWritableVectorDataset *poDS;
      93             : 
      94             :     CPL_DISALLOW_COPY_ASSIGN(OGRPDFWritableLayer)
      95             : 
      96             :   public:
      97             :     OGRPDFWritableLayer(PDFWritableVectorDataset *poDS, const char *pszName,
      98             :                         OGRSpatialReference *poSRS,
      99             :                         OGRwkbGeometryType eGeomType);
     100             : 
     101             :     int TestCapability(const char *) const override;
     102             :     OGRErr ICreateFeature(OGRFeature *poFeature) override;
     103             : 
     104             :     GDALDataset *GetDataset() override;
     105             : };
     106             : 
     107             : /************************************************************************/
     108             : /*                           GDALPDFTileDesc                            */
     109             : /************************************************************************/
     110             : 
     111             : typedef struct
     112             : {
     113             :     GDALPDFObject *poImage;
     114             :     double adfCM[6];
     115             :     double dfWidth;
     116             :     double dfHeight;
     117             :     int nBands;
     118             : } GDALPDFTileDesc;
     119             : 
     120             : #ifdef HAVE_PDFIUM
     121             : /**
     122             :  * Structures for Document and Document's Page for PDFium library,
     123             :  *  which does not support multi-threading.
     124             :  * Structures keeps objects for PDFium library and exclusive mutex locks
     125             :  *  for one-per-time access of PDFium library methods with multi-threading GDAL
     126             :  * Structures also keeps only one object per each opened PDF document
     127             :  *  - this saves time for opening and memory for opened objects
     128             :  * Document is closed after closing all pages object.
     129             :  */
     130             : 
     131             : /************************************************************************/
     132             : /*                          TPdfiumPageStruct                           */
     133             : /************************************************************************/
     134             : 
     135             : // Map of Pdfium pages in following structure
     136             : typedef struct
     137             : {
     138             :     int pageNum;
     139             :     CPDF_Page *page;
     140             :     CPLMutex *readMutex;
     141             :     int sharedNum;
     142             : } TPdfiumPageStruct;
     143             : 
     144             : typedef std::map<int, TPdfiumPageStruct *> TMapPdfiumPages;
     145             : 
     146             : /************************************************************************/
     147             : /*                        TPdfiumDocumentStruct                         */
     148             : /************************************************************************/
     149             : 
     150             : // Structure for Mutex on File
     151             : struct TPdfiumDocumentStruct
     152             : {
     153             :     char *filename = nullptr;
     154             :     CPDF_Document *doc = nullptr;
     155             :     TMapPdfiumPages pages{};
     156             :     FPDF_FILEACCESS *psFileAccess = nullptr;
     157             : };
     158             : 
     159             : #endif  // ~ HAVE_PDFIUM
     160             : 
     161             : /************************************************************************/
     162             : /* ==================================================================== */
     163             : /*                              PDFDataset                              */
     164             : /* ==================================================================== */
     165             : /************************************************************************/
     166             : 
     167             : class PDFRasterBand;
     168             : class PDFImageRasterBand;
     169             : 
     170             : #ifdef HAVE_POPPLER
     171             : class ObjectAutoFree;
     172             : #endif
     173             : 
     174             : #define MAX_TOKEN_SIZE 256
     175             : #define TOKEN_STACK_SIZE 8
     176             : 
     177             : #define GDAL_DEFAULT_DPI 150.0
     178             : 
     179             : #ifdef HAVE_PDF_READ_SUPPORT
     180             : 
     181             : class PDFDataset final : public GDALPamDataset
     182             : {
     183             :     friend class PDFRasterBand;
     184             :     friend class PDFImageRasterBand;
     185             : 
     186             :     VSIVirtualHandleUniquePtr m_fp{};
     187             :     bool m_bIsOvrDS = false;
     188             : 
     189             :     CPLString m_osFilename{};
     190             :     CPLString m_osUserPwd{};
     191             :     OGRSpatialReference m_oSRS{};
     192             :     double m_dfDPI = GDAL_DEFAULT_DPI;
     193             :     bool m_bHasCTM = false;
     194             :     std::array<double, 6> m_adfCTM = {{0, 0, 0, 0, 0, 0}};
     195             :     GDALGeoTransform m_gt{};
     196             :     bool m_bGeoTransformValid = false;
     197             :     int m_nGCPCount = 0;
     198             :     GDAL_GCP *m_pasGCPList = nullptr;
     199             :     bool m_bProjDirty = false;
     200             :     bool m_bNeatLineDirty = false;
     201             : 
     202             :     GDALMultiDomainMetadata m_oMDMD_PDF{};
     203             :     bool m_bInfoDirty = false;
     204             :     bool m_bXMPDirty = false;
     205             : 
     206             :     std::bitset<PDFLIB_COUNT> m_bUseLib{};
     207             : #ifdef HAVE_POPPLER
     208             :     PDFDoc *m_poDocPoppler = nullptr;
     209             : #endif
     210             : #ifdef HAVE_PODOFO
     211             :     PoDoFo::PdfMemDocument *m_poDocPodofo = nullptr;
     212             :     bool m_bPdfToPpmFailed = false;
     213             : #endif
     214             : #ifdef HAVE_PDFIUM
     215             :     TPdfiumDocumentStruct *m_poDocPdfium = nullptr;
     216             :     TPdfiumPageStruct *m_poPagePdfium = nullptr;
     217             : #endif
     218             :     std::vector<std::unique_ptr<PDFDataset>> m_apoOvrDS{};
     219             :     std::vector<std::unique_ptr<PDFDataset>> m_apoOvrDSBackup{};
     220             :     GDALPDFObject *m_poPageObj = nullptr;
     221             : 
     222             :     int m_iPage = -1;
     223             : 
     224             :     GDALPDFObject *m_poImageObj = nullptr;
     225             : 
     226             :     double m_dfMaxArea = 0;
     227             :     int ParseLGIDictObject(GDALPDFObject *poLGIDict);
     228             :     int ParseLGIDictDictFirstPass(GDALPDFDictionary *poLGIDict,
     229             :                                   int *pbIsBestCandidate = nullptr);
     230             :     int ParseLGIDictDictSecondPass(GDALPDFDictionary *poLGIDict);
     231             :     int ParseProjDict(GDALPDFDictionary *poProjDict);
     232             :     int ParseVP(GDALPDFObject *poVP, double dfMediaBoxWidth,
     233             :                 double dfMediaBoxHeight);
     234             :     int ParseMeasure(GDALPDFObject *poMeasure, double dfMediaBoxWidth,
     235             :                      double dfMediaBoxHeight, double dfULX, double dfULY,
     236             :                      double dfLRX, double dfLRY);
     237             : 
     238             :     bool m_bTried = false;
     239             :     GByte *m_pabyCachedData = nullptr;
     240             :     int m_nLastBlockXOff = -1;
     241             :     int m_nLastBlockYOff = -1;
     242             :     bool m_bCacheBlocksForOtherBands = false;
     243             : 
     244             :     OGRPolygon *m_poNeatLine = nullptr;
     245             : 
     246             :     std::vector<GDALPDFTileDesc> m_asTiles{}; /* in the order of the PDF file */
     247             :     std::vector<int> m_aiTiles{};             /* in the order of blocks */
     248             :     int m_nBlockXSize = 0;
     249             :     int m_nBlockYSize = 0;
     250             :     int CheckTiledRaster();
     251             : 
     252             :     void GuessDPIAndBandCount(GDALPDFDictionary *poPageDict, double &dfPI,
     253             :                               int &nBandsGuessed);
     254             :     void FindXMP(GDALPDFObject *poObj);
     255             :     void ParseInfo(GDALPDFObject *poObj);
     256             : 
     257             :     CPL_DISALLOW_COPY_ASSIGN(PDFDataset)
     258             : 
     259             : #ifdef HAVE_POPPLER
     260             :     std::unique_ptr<Object> m_poCatalogObjectPoppler{};
     261             : #endif
     262             :     GDALPDFObject *m_poCatalogObject = nullptr;
     263             :     GDALPDFObject *GetCatalog();
     264             :     GDALPDFArray *GetPagesKids();
     265             : 
     266             : #if defined(HAVE_POPPLER) || defined(HAVE_PDFIUM)
     267             :     void AddLayer(const std::string &osName, int iPage);
     268             :     void CreateLayerList();
     269             :     std::string
     270             :     BuildPostfixedLayerNameAndAddLayer(const std::string &osName,
     271             :                                        const std::pair<int, int> &oOCGRef,
     272             :                                        int iPageOfInterest, int nPageCount);
     273             : #endif
     274             : 
     275             : #if defined(HAVE_POPPLER)
     276             :     void ExploreLayersPoppler(GDALPDFArray *poArray, int iPageOfInterest,
     277             :                               int nPageCount, CPLString osTopLayer,
     278             :                               int nRecLevel, int &nVisited, bool &bStop);
     279             :     void FindLayersPoppler(int iPageOfInterest);
     280             :     void TurnLayersOnOffPoppler();
     281             :     std::vector<std::pair<CPLString, OptionalContentGroup *>>
     282             :         m_oLayerOCGListPoppler{};
     283             : #endif
     284             : 
     285             : #ifdef HAVE_PDFIUM
     286             :     void ExploreLayersPdfium(GDALPDFArray *poArray, int iPageOfInterest,
     287             :                              int nPageCount, int nRecLevel,
     288             :                              CPLString osTopLayer = "");
     289             :     void FindLayersPdfium(int iPageOfInterest);
     290             :     void PDFiumRenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x,
     291             :                                 int start_y, int size_x, int size_y,
     292             :                                 const char *pszRenderingOptions);
     293             :     void TurnLayersOnOffPdfium();
     294             : 
     295             :   public:
     296             :     typedef enum
     297             :     {
     298             :         VISIBILITY_DEFAULT,
     299             :         VISIBILITY_ON,
     300             :         VISIBILITY_OFF
     301             :     } VisibilityState;
     302             : 
     303             :     VisibilityState GetVisibilityStateForOGCPdfium(int nNum, int nGen);
     304             : 
     305             :   private:
     306             :     std::map<CPLString, std::pair<int, int>> m_oMapLayerNameToOCGNumGenPdfium{};
     307             :     std::map<std::pair<int, int>, VisibilityState>
     308             :         m_oMapOCGNumGenToVisibilityStatePdfium{};
     309             : #endif
     310             : 
     311             :     // Map OCGs identified by their (number, generation) to the list of pages
     312             :     // where they are referenced from.
     313             :     std::map<std::pair<int, int>, std::vector<int>> m_oMapOCGNumGenToPages{};
     314             : 
     315             :     struct LayerStruct
     316             :     {
     317             :         std::string osName{};
     318             :         int nInsertIdx = 0;
     319             :         int iPage = 0;
     320             :     };
     321             : 
     322             :     std::vector<LayerStruct> m_oLayerNameSet{};
     323             :     CPLStringList m_aosLayerNames{};
     324             : 
     325             :     void SortLayerList();
     326             : 
     327             :     struct LayerWithRef
     328             :     {
     329             :         CPLString osName{};
     330             :         GDALPDFObjectNum nOCGNum{};
     331             :         int nOCGGen = 0;
     332             : 
     333         368 :         LayerWithRef(const CPLString &osNameIn,
     334             :                      const GDALPDFObjectNum &nOCGNumIn, int nOCGGenIn)
     335         368 :             : osName(osNameIn), nOCGNum(nOCGNumIn), nOCGGen(nOCGGenIn)
     336             :         {
     337         368 :         }
     338             :     };
     339             : 
     340             :     std::vector<LayerWithRef> m_aoLayerWithRef{};
     341             : 
     342             :     CPLString FindLayerOCG(GDALPDFDictionary *poPageDict,
     343             :                            const char *pszLayerName);
     344             :     void FindLayersGeneric(GDALPDFDictionary *poPageDict);
     345             : 
     346             :     void MapOCGsToPages();
     347             : 
     348             :     bool m_bUseOCG = false;
     349             : 
     350             :     static const char *GetOption(char **papszOpenOptions,
     351             :                                  const char *pszOptionName,
     352             :                                  const char *pszDefaultVal);
     353             : 
     354             :     bool m_bHasLoadedLayers = false;
     355             :     std::vector<std::unique_ptr<OGRPDFLayer>> m_apoLayers{};
     356             : 
     357             :     double m_dfPageWidth = 0;
     358             :     double m_dfPageHeight = 0;
     359             :     void PDFCoordsToSRSCoords(double x, double y, double &X, double &Y);
     360             : 
     361             :     std::map<int, std::unique_ptr<OGRGeometry>> m_oMapMCID{};
     362             :     void CleanupIntermediateResources();
     363             : 
     364             :     std::map<CPLString, int> m_oMapOperators{};
     365             :     void InitMapOperators();
     366             : 
     367             :     bool m_bSetStyle = false;
     368             : 
     369             :     bool ExploreTree(GDALPDFObject *poObj,
     370             :                      std::set<std::pair<int, int>> &aoSetAlreadyVisited,
     371             :                      int nRecLevel, bool bDryRun);
     372             :     void ExploreContents(GDALPDFObject *poObj, GDALPDFObject *poResources,
     373             :                          int nDepth, int &nVisited, bool &bStop);
     374             : 
     375             :     void ExploreContentsNonStructuredInternal(
     376             :         GDALPDFObject *poContents, GDALPDFObject *poResources,
     377             :         const std::map<CPLString, OGRPDFLayer *> &oMapPropertyToLayer,
     378             :         const std::map<std::pair<int, int>, OGRPDFLayer *> &oMapNumGenToLayer,
     379             :         OGRPDFLayer *poSingleLayer);
     380             :     void ExploreContentsNonStructured(GDALPDFObject *poObj,
     381             :                                       GDALPDFObject *poResources);
     382             : 
     383             :     int UnstackTokens(const char *pszToken, int nRequiredArgs,
     384             :                       char aszTokenStack[TOKEN_STACK_SIZE][MAX_TOKEN_SIZE],
     385             :                       int &nTokenStackSize, double *adfCoords);
     386             : 
     387             :     struct GraphicState
     388             :     {
     389             :         std::array<double, 6> adfCM = {1, 0, 0, 1, 0, 0};
     390             :         std::array<double, 3> adfStrokeColor = {0.0, 0.0, 0.0};
     391             :         std::array<double, 3> adfFillColor = {1.0, 1.0, 1.0};
     392             : 
     393             :         void PreMultiplyBy(double adfMatrix[6]);
     394             :         void ApplyMatrix(double adfCoords[2]) const;
     395             :     };
     396             : 
     397             :     OGRGeometry *ParseContent(
     398             :         const char *pszContent, GDALPDFObject *poResources,
     399             :         bool bCollectAllObjects, bool bInitBDCStack, bool bMatchQ,
     400             :         const std::map<CPLString, OGRPDFLayer *> &oMapPropertyToLayer,
     401             :         const std::map<std::pair<int, int>, OGRPDFLayer *> &oMapNumGenToLayer,
     402             :         const GraphicState &graphicStateIn, OGRPDFLayer *poCurLayer,
     403             :         int nRecLevel);
     404             :     std::unique_ptr<OGRGeometry> BuildGeometry(std::vector<double> &oCoords,
     405             :                                                int bHasFoundFill,
     406             :                                                int bHasMultiPart);
     407             : 
     408             :     bool OpenVectorLayers(GDALPDFDictionary *poPageDict);
     409             : 
     410             :     void InitOverviews();
     411             : 
     412             :   public:
     413             :     PDFDataset(PDFDataset *poParentDS = nullptr, int nXSize = 0,
     414             :                int nYSize = 0);
     415             :     ~PDFDataset() override;
     416             : 
     417             :     CPLErr GetGeoTransform(GDALGeoTransform &gt) const override;
     418             : 
     419             :     CPLErr SetGeoTransform(const GDALGeoTransform &gt) override;
     420             : 
     421             :     const OGRSpatialReference *GetSpatialRef() const override;
     422             :     CPLErr SetSpatialRef(const OGRSpatialReference *poSRS) override;
     423             : 
     424             :     char **GetMetadataDomainList() override;
     425             :     CSLConstList GetMetadata(const char *pszDomain = "") override;
     426             :     CPLErr SetMetadata(CSLConstList papszMetadata,
     427             :                        const char *pszDomain = "") override;
     428             :     virtual const char *GetMetadataItem(const char *pszName,
     429             :                                         const char *pszDomain = "") override;
     430             :     CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     431             :                            const char *pszDomain = "") override;
     432             : 
     433             :     CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     434             :                      GDALDataType, int, BANDMAP_TYPE, GSpacing nPixelSpace,
     435             :                      GSpacing nLineSpace, GSpacing nBandSpace,
     436             :                      GDALRasterIOExtraArg *psExtraArg) override;
     437             : 
     438             :     int GetGCPCount() override;
     439             :     const OGRSpatialReference *GetGCPSpatialRef() const override;
     440             :     const GDAL_GCP *GetGCPs() override;
     441             :     CPLErr SetGCPs(int nGCPCountIn, const GDAL_GCP *pasGCPListIn,
     442             :                    const OGRSpatialReference *poSRS) override;
     443             : 
     444             :     CPLErr ReadPixels(int nReqXOff, int nReqYOff, int nReqXSize, int nReqYSize,
     445             :                       GSpacing nPixelSpace, GSpacing nLineSpace,
     446             :                       GSpacing nBandSpace, GByte *pabyData);
     447             : 
     448             :     int GetLayerCount() const override;
     449             :     const OGRLayer *GetLayer(int) const override;
     450             : 
     451             :     int TestCapability(const char *) const override;
     452             : 
     453             :     OGRGeometry *GetGeometryFromMCID(int nMCID);
     454             : 
     455           4 :     GDALPDFObject *GetPageObj()
     456             :     {
     457           4 :         return m_poPageObj;
     458             :     }
     459             : 
     460           4 :     double GetPageWidth() const
     461             :     {
     462           4 :         return m_dfPageWidth;
     463             :     }
     464             : 
     465           4 :     double GetPageHeight() const
     466             :     {
     467           4 :         return m_dfPageHeight;
     468             :     }
     469             : 
     470             :     static PDFDataset *Open(GDALOpenInfo *);
     471             : 
     472         174 :     static GDALDataset *OpenWrapper(GDALOpenInfo *poOpenInfo)
     473             :     {
     474         174 :         return Open(poOpenInfo);
     475             :     }
     476             : 
     477             :     CPLErr IBuildOverviews(const char *, int, const int *, int, const int *,
     478             :                            GDALProgressFunc, void *,
     479             :                            CSLConstList papszOptions) override;
     480             : 
     481             : #ifdef HAVE_PDFIUM
     482             :     static bool g_bPdfiumInit;
     483             : #endif
     484             : };
     485             : 
     486             : /************************************************************************/
     487             : /* ==================================================================== */
     488             : /*                         PDFRasterBand                                */
     489             : /* ==================================================================== */
     490             : /************************************************************************/
     491             : 
     492             : class PDFRasterBand CPL_NON_FINAL : public GDALPamRasterBand
     493             : {
     494             :     friend class PDFDataset;
     495             : 
     496             :     int nResolutionLevel;
     497             : 
     498             :     CPLErr IReadBlockFromTile(int, int, void *);
     499             : 
     500             :     void SetSize(int nXSize, int nYSize);
     501             : 
     502             :   public:
     503             :     PDFRasterBand(PDFDataset *, int, int);
     504             :     ~PDFRasterBand() override;
     505             : 
     506             :     virtual GDALSuggestedBlockAccessPattern
     507             :     GetSuggestedBlockAccessPattern() const override;
     508             : 
     509             :     int GetOverviewCount() override;
     510             :     GDALRasterBand *GetOverview(int) override;
     511             : 
     512             :     CPLErr IReadBlock(int, int, void *) override;
     513             :     GDALColorInterp GetColorInterpretation() override;
     514             : 
     515             :     CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
     516             :                      GDALDataType, GSpacing nPixelSpace, GSpacing nLineSpace,
     517             :                      GDALRasterIOExtraArg *psExtraArg) override;
     518             : };
     519             : 
     520             : #endif /* HAVE_PDF_READ_SUPPORT */
     521             : 
     522             : /************************************************************************/
     523             : /*                          PDFWritableDataset                          */
     524             : /************************************************************************/
     525             : 
     526             : class PDFWritableVectorDataset final : public GDALDataset
     527             : {
     528             :     char **papszOptions;
     529             : 
     530             :     int nLayers;
     531             :     OGRLayer **papoLayers;
     532             : 
     533             :     int bModified;
     534             : 
     535             :     CPL_DISALLOW_COPY_ASSIGN(PDFWritableVectorDataset)
     536             : 
     537             :   public:
     538             :     PDFWritableVectorDataset();
     539             :     ~PDFWritableVectorDataset() override;
     540             : 
     541           0 :     bool CanReopenWithCurrentDescription() const override
     542             :     {
     543             : #ifdef HAVE_PDF_READ_SUPPORT
     544           0 :         return true;
     545             : #else
     546             :         return false;
     547             : #endif
     548             :     }
     549             : 
     550             :     virtual OGRLayer *ICreateLayer(const char *pszName,
     551             :                                    const OGRGeomFieldDefn *poGeomFieldDefn,
     552             :                                    CSLConstList papszOptions) override;
     553             : 
     554             :     CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override;
     555             :     CPLErr FlushCache(bool bAtClosing) override;
     556             : 
     557             :     int GetLayerCount() const override;
     558             :     const OGRLayer *GetLayer(int) const override;
     559             : 
     560             :     int TestCapability(const char *) const override;
     561             : 
     562             :     static GDALDataset *Create(const char *pszName, int nXSize, int nYSize,
     563             :                                int nBands, GDALDataType eType,
     564             :                                CSLConstList papszOptions);
     565             : 
     566         141 :     void SetModified()
     567             :     {
     568         141 :         bModified = TRUE;
     569         141 :     }
     570             : };
     571             : 
     572             : GDALDataset *GDALPDFOpen(const char *pszFilename, GDALAccess eAccess);
     573             : CPLString PDFSanitizeLayerName(const char *pszName);
     574             : 
     575             : #endif /* ndef GDAL_PDF_H_INCLUDED */

Generated by: LCOV version 1.14