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

Generated by: LCOV version 1.14