LCOV - code coverage report
Current view: top level - frmts/pdf - pdfcreatecopy.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 5 5 100.0 %
Date: 2025-02-20 10:14:44 Functions: 3 3 100.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 dot com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2012-2019, Even Rouault <even dot rouault at spatialys dot com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #ifndef PDFCREATECOPY_H_INCLUDED
      14             : #define PDFCREATECOPY_H_INCLUDED
      15             : 
      16             : #include "pdfobject.h"
      17             : #include "gdal_priv.h"
      18             : #include <vector>
      19             : #include <map>
      20             : 
      21             : #include "ogr_api.h"
      22             : #include "ogr_spatialref.h"
      23             : 
      24             : /* Cf PDF reference v1.7, Appendix C, page 993 */
      25             : #define MAXIMUM_SIZE_IN_UNITS 14400
      26             : 
      27             : #define APPLY_GT_X(gt, x, y) ((gt)[0] + (x) * (gt)[1] + (y) * (gt)[2])
      28             : #define APPLY_GT_Y(gt, x, y) ((gt)[3] + (x) * (gt)[4] + (y) * (gt)[5])
      29             : 
      30             : typedef enum
      31             : {
      32             :     COMPRESS_NONE,
      33             :     COMPRESS_DEFLATE,
      34             :     COMPRESS_JPEG,
      35             :     COMPRESS_JPEG2000,
      36             :     COMPRESS_DEFAULT
      37             : } PDFCompressMethod;
      38             : 
      39             : struct PDFMargins
      40             : {
      41             :     int nLeft = 0;
      42             :     int nRight = 0;
      43             :     int nTop = 0;
      44             :     int nBottom = 0;
      45             : };
      46             : 
      47             : class GDALFakePDFDataset final : public GDALDataset
      48             : {
      49             :   public:
      50          10 :     GDALFakePDFDataset() = default;
      51             : };
      52             : 
      53             : /************************************************************************/
      54             : /*                          GDALPDFWriter                               */
      55             : /************************************************************************/
      56             : 
      57             : class GDALXRefEntry
      58             : {
      59             :   public:
      60             :     vsi_l_offset nOffset = 0;
      61             :     int nGen = 0;
      62             :     int bFree = FALSE;
      63             : 
      64        2720 :     GDALXRefEntry() = default;
      65             : 
      66             :     explicit GDALXRefEntry(vsi_l_offset nOffsetIn, int nGenIn = 0)
      67             :         : nOffset(nOffsetIn), nGen(nGenIn)
      68             :     {
      69             :     }
      70             : 
      71        5614 :     GDALXRefEntry(const GDALXRefEntry &oOther)
      72        5614 :         : nOffset(oOther.nOffset), nGen(oOther.nGen), bFree(oOther.bFree)
      73             :     {
      74        5614 :     }
      75             : 
      76             :     GDALXRefEntry &operator=(const GDALXRefEntry &oOther)
      77             :     {
      78             :         nOffset = oOther.nOffset;
      79             :         nGen = oOther.nGen;
      80             :         bFree = oOther.bFree;
      81             :         return *this;
      82             :     }
      83             : };
      84             : 
      85             : class GDALPDFImageDesc
      86             : {
      87             :   public:
      88             :     GDALPDFObjectNum nImageId{};
      89             :     double dfXOff = 0;
      90             :     double dfYOff = 0;
      91             :     double dfXSize = 0;
      92             :     double dfYSize = 0;
      93             : };
      94             : 
      95             : class GDALPDFLayerDesc
      96             : {
      97             :   public:
      98             :     GDALPDFObjectNum nOCGId{};
      99             :     GDALPDFObjectNum nOCGTextId{};
     100             :     GDALPDFObjectNum nFeatureLayerId{};
     101             :     CPLString osLayerName{};
     102             :     int bWriteOGRAttributes{false};
     103             :     std::vector<GDALPDFObjectNum> aIds{};
     104             :     std::vector<GDALPDFObjectNum> aIdsText{};
     105             :     std::vector<GDALPDFObjectNum> aUserPropertiesIds{};
     106             :     std::vector<CPLString> aFeatureNames{};
     107             :     std::vector<CPLString> aosIncludedFields{};
     108             : };
     109             : 
     110             : class GDALPDFRasterDesc
     111             : {
     112             :   public:
     113             :     GDALPDFObjectNum nOCGRasterId{};
     114             :     std::vector<GDALPDFImageDesc> asImageDesc{};
     115             : };
     116             : 
     117             : class GDALPDFPageContext
     118             : {
     119             :   public:
     120             :     GDALDataset *poClippingDS = nullptr;
     121             :     PDFCompressMethod eStreamCompressMethod = COMPRESS_NONE;
     122             :     double dfDPI{0};
     123             :     PDFMargins sMargins{};
     124             :     GDALPDFObjectNum nPageId{};
     125             :     GDALPDFObjectNum nContentId{};
     126             :     GDALPDFObjectNum nResourcesId{};
     127             :     std::vector<GDALPDFLayerDesc> asVectorDesc{};
     128             :     std::vector<GDALPDFRasterDesc> asRasterDesc{};
     129             :     GDALPDFObjectNum nAnnotsId{};
     130             :     std::vector<GDALPDFObjectNum> anAnnotationsId{};
     131             : };
     132             : 
     133             : class GDALPDFOCGDesc
     134             : {
     135             :   public:
     136             :     GDALPDFObjectNum nId{};
     137             :     GDALPDFObjectNum nParentId{};
     138             :     CPLString osLayerName{};
     139             : };
     140             : 
     141             : class GDALPDFBaseWriter
     142             : {
     143             :   protected:
     144             :     VSILFILE *m_fp = nullptr;
     145             :     bool m_bInWriteObj = false;
     146             :     std::vector<GDALXRefEntry> m_asXRefEntries{};
     147             :     GDALPDFObjectNum m_nPageResourceId{};
     148             :     GDALPDFObjectNum m_nCatalogId{};
     149             :     int m_nCatalogGen = 0;
     150             :     GDALPDFObjectNum m_nInfoId{};
     151             :     int m_nInfoGen = 0;
     152             :     GDALPDFObjectNum m_nXMPId{};
     153             :     int m_nXMPGen = 0;
     154             :     GDALPDFObjectNum m_nStructTreeRootId{};
     155             :     GDALPDFObjectNum m_nNamesId{};
     156             : 
     157             :     GDALPDFObjectNum m_nContentLengthId{};
     158             :     VSILFILE *m_fpBack = nullptr;
     159             :     VSILFILE *m_fpGZip = nullptr;
     160             :     vsi_l_offset m_nStreamStart = 0;
     161             : 
     162             :     std::vector<GDALPDFObjectNum> m_asPageId{};
     163             :     std::vector<GDALPDFOCGDesc> m_asOCGs{};
     164             :     std::map<CPLString, GDALPDFImageDesc> m_oMapSymbolFilenameToDesc{};
     165             : 
     166             :   public:
     167             :     struct ObjectStyle
     168             :     {
     169             :         unsigned int nPenR = 0;
     170             :         unsigned int nPenG = 0;
     171             :         unsigned int nPenB = 0;
     172             :         unsigned int nPenA = 255;
     173             :         unsigned int nBrushR = 127;
     174             :         unsigned int nBrushG = 127;
     175             :         unsigned int nBrushB = 127;
     176             :         unsigned int nBrushA = 127;
     177             :         unsigned int nTextR = 0;
     178             :         unsigned int nTextG = 0;
     179             :         unsigned int nTextB = 0;
     180             :         unsigned int nTextA = 255;
     181             :         int bSymbolColorDefined = FALSE;
     182             :         unsigned int nSymbolR = 0;
     183             :         unsigned int nSymbolG = 0;
     184             :         unsigned int nSymbolB = 0;
     185             :         unsigned int nSymbolA = 255;
     186             :         bool bHasPenBrushOrSymbol = false;
     187             :         CPLString osTextFont{};
     188             :         bool bTextBold = false;
     189             :         bool bTextItalic = false;
     190             :         double dfTextSize = 12.0;
     191             :         double dfTextAngle = 0.0;
     192             :         double dfTextStretch = 1.0;
     193             :         double dfTextDx = 0.0;
     194             :         double dfTextDy = 0.0;
     195             :         int nTextAnchor = 1;
     196             :         double dfPenWidth = 1.0;
     197             :         double dfSymbolSize = 5.0;
     198             :         CPLString osDashArray{};
     199             :         CPLString osLabelText{};
     200             :         CPLString osSymbolId{};
     201             :         GDALPDFObjectNum nImageSymbolId{};
     202             :         int nImageWidth = 0;
     203             :         int nImageHeight = 0;
     204             :     };
     205             : 
     206             :   protected:
     207             :     explicit GDALPDFBaseWriter(VSILFILE *fp);
     208             :     ~GDALPDFBaseWriter();
     209             : 
     210             :     GDALPDFObjectNum AllocNewObject();
     211             : 
     212             :     void StartObj(const GDALPDFObjectNum &nObjectId, int nGen = 0);
     213             :     void EndObj();
     214             : 
     215             :     void StartObjWithStream(const GDALPDFObjectNum &nObjectId,
     216             :                             GDALPDFDictionaryRW &oDict, bool bDeflate);
     217             :     void EndObjWithStream();
     218             : 
     219             :     void StartNewDoc();
     220             :     void Close();
     221             : 
     222             :     void WriteXRefTableAndTrailer(bool bUpdate, vsi_l_offset nLastStartXRef);
     223             : 
     224             :     GDALPDFObjectNum WriteSRS_ISO32000(GDALDataset *poSrcDS, double dfUserUnit,
     225             :                                        const char *pszNEATLINE,
     226             :                                        PDFMargins *psMargins,
     227             :                                        int bWriteViewport);
     228             : 
     229             :     GDALPDFObjectNum
     230             :     WriteOCG(const char *pszLayerName,
     231             :              const GDALPDFObjectNum &nParentId = GDALPDFObjectNum());
     232             : 
     233             :     GDALPDFObjectNum
     234             :     WriteBlock(GDALDataset *poSrcDS, int nXOff, int nYOff, int nReqXSize,
     235             :                int nReqYSize, const GDALPDFObjectNum &nColorTableIdIn,
     236             :                PDFCompressMethod eCompressMethod, int nPredictor,
     237             :                int nJPEGQuality, const char *pszJPEG2000_DRIVER,
     238             :                GDALProgressFunc pfnProgress, void *pProgressData);
     239             :     GDALPDFObjectNum WriteMask(GDALDataset *poSrcDS, int nXOff, int nYOff,
     240             :                                int nReqXSize, int nReqYSize,
     241             :                                PDFCompressMethod eCompressMethod);
     242             : 
     243             :     GDALPDFObjectNum WriteColorTable(GDALDataset *poSrcDS);
     244             : 
     245             :     void GetObjectStyle(
     246             :         const char *pszStyleString, OGRFeatureH hFeat,
     247             :         const double adfMatrix[4],
     248             :         std::map<CPLString, GDALPDFImageDesc> oMapSymbolFilenameToDesc,
     249             :         ObjectStyle &os);
     250             :     static CPLString GenerateDrawingStream(OGRGeometryH hGeom,
     251             :                                            const double adfMatrix[4],
     252             :                                            ObjectStyle &os, double dfRadius);
     253             :     GDALPDFObjectNum
     254             :     WriteAttributes(OGRFeatureH hFeat,
     255             :                     const std::vector<CPLString> &aosIncludedFields,
     256             :                     const char *pszOGRDisplayField, int nMCID,
     257             :                     const GDALPDFObjectNum &oParent,
     258             :                     const GDALPDFObjectNum &oPage, CPLString &osOutFeatureName);
     259             : 
     260             :     GDALPDFObjectNum WriteLabel(OGRGeometryH hGeom, const double adfMatrix[4],
     261             :                                 ObjectStyle &os,
     262             :                                 PDFCompressMethod eStreamCompressMethod,
     263             :                                 double bboxXMin, double bboxYMin,
     264             :                                 double bboxXMax, double bboxYMax);
     265             : 
     266             :     GDALPDFObjectNum WriteLink(OGRFeatureH hFeat, const char *pszOGRLinkField,
     267             :                                const double adfMatrix[4], int bboxXMin,
     268             :                                int bboxYMin, int bboxXMax, int bboxYMax);
     269             : 
     270             :     static void ComputeIntBBox(OGRGeometryH hGeom, const OGREnvelope &sEnvelope,
     271             :                                const double adfMatrix[4], const ObjectStyle &os,
     272             :                                double dfRadius, int &bboxXMin, int &bboxYMin,
     273             :                                int &bboxXMax, int &bboxYMax);
     274             : 
     275             :     GDALPDFObjectNum WriteJavascript(const char *pszJavascript, bool bDeflate);
     276             : 
     277             :   public:
     278             :     GDALPDFObjectNum SetInfo(GDALDataset *poSrcDS, char **papszOptions);
     279             :     GDALPDFObjectNum SetInfo(const char *pszAUTHOR, const char *pszPRODUCER,
     280             :                              const char *pszCREATOR,
     281             :                              const char *pszCREATION_DATE,
     282             :                              const char *pszSUBJECT, const char *pszTITLE,
     283             :                              const char *pszKEYWORDS);
     284             :     GDALPDFObjectNum SetXMP(GDALDataset *poSrcDS, const char *pszXMP);
     285             : 
     286             :   private:
     287             :     CPL_DISALLOW_COPY_ASSIGN(GDALPDFBaseWriter)
     288             : };
     289             : 
     290             : class GDALPDFUpdateWriter final : public GDALPDFBaseWriter
     291             : {
     292             :     bool m_bUpdateNeeded = false;
     293             :     vsi_l_offset m_nLastStartXRef = 0;
     294             :     int m_nLastXRefSize = 0;
     295             : 
     296             :   public:
     297             :     explicit GDALPDFUpdateWriter(VSILFILE *fpIn);
     298             :     ~GDALPDFUpdateWriter();
     299             : 
     300             :     void Close();
     301             : 
     302             :     const GDALPDFObjectNum &GetCatalogNum() const
     303             :     {
     304             :         return m_nCatalogId;
     305             :     }
     306             : 
     307             :     int GetCatalogGen() const
     308             :     {
     309             :         return m_nCatalogGen;
     310             :     }
     311             : 
     312             :     int ParseTrailerAndXRef();
     313             :     void UpdateProj(GDALDataset *poSrcDS, double dfDPI,
     314             :                     GDALPDFDictionaryRW *poPageDict,
     315             :                     const GDALPDFObjectNum &nPageId, int nPageGen);
     316             :     void UpdateInfo(GDALDataset *poSrcDS);
     317             :     void UpdateXMP(GDALDataset *poSrcDS, GDALPDFDictionaryRW *poCatalogDict);
     318             : };
     319             : 
     320             : class GDALPDFWriter final : public GDALPDFBaseWriter
     321             : {
     322             :     GDALPDFPageContext oPageContext{};
     323             : 
     324             :     CPLString m_osOffLayers{};
     325             :     CPLString m_osExclusiveLayers{};
     326             : 
     327             :     void WritePages();
     328             : 
     329             :   public:
     330             :     explicit GDALPDFWriter(VSILFILE *fpIn);
     331             :     ~GDALPDFWriter();
     332             : 
     333             :     void Close();
     334             : 
     335             :     bool StartPage(GDALDataset *poSrcDS, double dfDPI, bool bWriteUserUnit,
     336             :                    const char *pszGEO_ENCODING, const char *pszNEATLINE,
     337             :                    PDFMargins *psMargins,
     338             :                    PDFCompressMethod eStreamCompressMethod, int bHasOGRData);
     339             : 
     340             :     bool WriteImagery(GDALDataset *poDS, const char *pszLayerName,
     341             :                       PDFCompressMethod eCompressMethod, int nPredictor,
     342             :                       int nJPEGQuality, const char *pszJPEG2000_DRIVER,
     343             :                       int nBlockXSize, int nBlockYSize,
     344             :                       GDALProgressFunc pfnProgress, void *pProgressData);
     345             : 
     346             :     bool WriteClippedImagery(GDALDataset *poDS, const char *pszLayerName,
     347             :                              PDFCompressMethod eCompressMethod, int nPredictor,
     348             :                              int nJPEGQuality, const char *pszJPEG2000_DRIVER,
     349             :                              int nBlockXSize, int nBlockYSize,
     350             :                              GDALProgressFunc pfnProgress, void *pProgressData);
     351             :     bool WriteOGRDataSource(const char *pszOGRDataSource,
     352             :                             const char *pszOGRDisplayField,
     353             :                             const char *pszOGRDisplayLayerNames,
     354             :                             const char *pszOGRLinkField,
     355             :                             int bWriteOGRAttributes);
     356             : 
     357             :     GDALPDFLayerDesc StartOGRLayer(const std::string &osLayerName,
     358             :                                    int bWriteOGRAttributes);
     359             :     void EndOGRLayer(GDALPDFLayerDesc &osVectorDesc);
     360             : 
     361             :     int WriteOGRLayer(GDALDatasetH hDS, int iLayer,
     362             :                       const char *pszOGRDisplayField,
     363             :                       const char *pszOGRLinkField,
     364             :                       const std::string &osLayerName, int bWriteOGRAttributes,
     365             :                       int &iObj);
     366             : 
     367             :     int WriteOGRFeature(GDALPDFLayerDesc &osVectorDesc, OGRFeatureH hFeat,
     368             :                         OGRCoordinateTransformationH hCT,
     369             :                         const char *pszOGRDisplayField,
     370             :                         const char *pszOGRLinkField, int bWriteOGRAttributes,
     371             :                         int &iObj);
     372             : 
     373             :     GDALPDFObjectNum WriteJavascript(const char *pszJavascript);
     374             :     GDALPDFObjectNum WriteJavascriptFile(const char *pszJavascriptFile);
     375             : 
     376             :     int EndPage(const char *pszExtraImages, const char *pszExtraStream,
     377             :                 const char *pszExtraLayerName, const char *pszOffLayers,
     378             :                 const char *pszExclusiveLayers);
     379             : };
     380             : 
     381             : GDALDataset *GDALPDFCreateCopy(const char *, GDALDataset *, int, char **,
     382             :                                GDALProgressFunc pfnProgress,
     383             :                                void *pProgressData);
     384             : 
     385             : #endif  // PDFCREATECOPY_H_INCLUDED

Generated by: LCOV version 1.14