1 /******************************************************************************
2  * $Id: pdfcreatecopy.h 27044 2014-03-16 23:41:27Z rouault $
3  *
4  * Project:  PDF driver
5  * Purpose:  GDALDataset driver for PDF dataset.
6  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
7  *
8  ******************************************************************************
9  * Copyright (c) 2012-2013, Even Rouault <even dot rouault at mines-paris dot org>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #ifndef PDFCREATECOPY_H_INCLUDED
31 #define PDFCREATECOPY_H_INCLUDED
32 
33 #include "pdfobject.h"
34 #include "gdal_priv.h"
35 #include <vector>
36 #include <map>
37 
38 #ifdef OGR_ENABLED
39 #include "ogr_api.h"
40 #endif
41 
42 typedef enum
43 {
44     COMPRESS_NONE,
45     COMPRESS_DEFLATE,
46     COMPRESS_JPEG,
47     COMPRESS_JPEG2000,
48     COMPRESS_DEFAULT
49 } PDFCompressMethod;
50 
51 typedef struct
52 {
53     int nLeft;
54     int nRight;
55     int nTop;
56     int nBottom;
57 } PDFMargins;
58 
59 /************************************************************************/
60 /*                          GDALPDFWriter                               */
61 /************************************************************************/
62 
63 class GDALXRefEntry
64 {
65     public:
66         vsi_l_offset    nOffset;
67         int             nGen;
68         int             bFree;
69 
GDALXRefEntry()70         GDALXRefEntry() : nOffset(0), nGen(0), bFree(FALSE) {}
nOffset(nOffsetIn)71         GDALXRefEntry(vsi_l_offset nOffsetIn, int nGenIn = 0) : nOffset(nOffsetIn), nGen(nGenIn), bFree(FALSE) {}
GDALXRefEntry(const GDALXRefEntry & oOther)72         GDALXRefEntry(const GDALXRefEntry& oOther) : nOffset(oOther.nOffset), nGen(oOther.nGen), bFree(oOther.bFree) {}
73         GDALXRefEntry& operator= (const GDALXRefEntry& oOther) { nOffset = oOther.nOffset; nGen = oOther.nGen; bFree = oOther.bFree; return *this; }
74 };
75 
76 class GDALPDFImageDesc
77 {
78     public:
79         int          nImageId;
80         double       dfXOff;
81         double       dfYOff;
82         double       dfXSize;
83         double       dfYSize;
84 };
85 
86 class GDALPDFLayerDesc
87 {
88     public:
89         int          nOGCId;
90         int          nOCGTextId;
91         int          nFeatureLayerId;
92         CPLString    osLayerName;
93         int          bWriteOGRAttributes;
94         std::vector<int> aIds;
95         std::vector<int> aIdsText;
96         std::vector<int> aUserPropertiesIds;
97         std::vector<CPLString> aFeatureNames;
98 };
99 
100 class GDALPDFRasterDesc
101 {
102     public:
103         int          nOCGRasterId;
104         std::vector<GDALPDFImageDesc> asImageDesc;
105 };
106 
107 class GDALPDFPageContext
108 {
109     public:
110         GDALDataset* poClippingDS;
111         PDFCompressMethod eStreamCompressMethod;
112         double       dfDPI;
113         PDFMargins   sMargins;
114         int          nPageId;
115         int          nContentId;
116         int          nResourcesId;
117         std::vector<GDALPDFLayerDesc> asVectorDesc;
118         std::vector<GDALPDFRasterDesc> asRasterDesc;
119         int          nAnnotsId;
120         std::vector<int> anAnnotationsId;
121 };
122 
123 class GDALPDFOCGDesc
124 {
125     public:
126         int          nId;
127         int          nParentId;
128         CPLString    osLayerName;
129 };
130 
131 class GDALPDFWriter
132 {
133     VSILFILE* fp;
134     std::vector<GDALXRefEntry> asXRefEntries;
135     std::vector<int> asPageId;
136     std::vector<GDALPDFOCGDesc> asOCGs;
137     std::map<CPLString,GDALPDFImageDesc> oMapSymbolFilenameToDesc;
138 
139     int nInfoId;
140     int nInfoGen;
141     int nPageResourceId;
142     int nStructTreeRootId;
143     int nCatalogId;
144     int nCatalogGen;
145     int nXMPId;
146     int nXMPGen;
147     int nNamesId;
148     int bInWriteObj;
149 
150     vsi_l_offset nLastStartXRef;
151     int nLastXRefSize;
152     int bCanUpdate;
153 
154     GDALPDFPageContext oPageContext;
155 
156     CPLString    osOffLayers;
157     CPLString    osExclusiveLayers;
158 
159     void    Init();
160 
161     void    StartObj(int nObjectId, int nGen = 0);
162     void    EndObj();
163     void    WriteXRefTableAndTrailer();
164     void    WritePages();
165     int     WriteBlock( GDALDataset* poSrcDS,
166                         int nXOff, int nYOff, int nReqXSize, int nReqYSize,
167                         int nColorTableId,
168                         PDFCompressMethod eCompressMethod,
169                         int nPredictor,
170                         int nJPEGQuality,
171                         const char* pszJPEG2000_DRIVER,
172                         GDALProgressFunc pfnProgress,
173                         void * pProgressData );
174     int     WriteMask(GDALDataset* poSrcDS,
175                       int nXOff, int nYOff, int nReqXSize, int nReqYSize,
176                       PDFCompressMethod eCompressMethod);
177     int     WriteOCG(const char* pszLayerName, int nParentId = 0);
178 
179     int     WriteColorTable(GDALDataset* poSrcDS);
180 
181     int     AllocNewObject();
182 
183     public:
184         GDALPDFWriter(VSILFILE* fpIn, int bAppend = FALSE);
185        ~GDALPDFWriter();
186 
187        void Close();
188 
GetCatalogNum()189        int  GetCatalogNum() { return nCatalogId; }
GetCatalogGen()190        int  GetCatalogGen() { return nCatalogGen; }
191 
192        int  ParseTrailerAndXRef();
193        void UpdateProj(GDALDataset* poSrcDS,
194                        double dfDPI,
195                        GDALPDFDictionaryRW* poPageDict,
196                        int nPageNum, int nPageGen);
197        void UpdateInfo(GDALDataset* poSrcDS);
198        void UpdateXMP (GDALDataset* poSrcDS,
199                        GDALPDFDictionaryRW* poCatalogDict);
200 
201        int     WriteSRS_ISO32000(GDALDataset* poSrcDS,
202                                  double dfUserUnit,
203                                  const char* pszNEATLINE,
204                                  PDFMargins* psMargins,
205                                  int bWriteViewport);
206        int     WriteSRS_OGC_BP(GDALDataset* poSrcDS,
207                                 double dfUserUnit,
208                                 const char* pszNEATLINE,
209                                 PDFMargins* psMargins);
210 
211        int  StartPage(GDALDataset* poSrcDS,
212                       double dfDPI,
213                       const char* pszGEO_ENCODING,
214                       const char* pszNEATLINE,
215                       PDFMargins* psMargins,
216                       PDFCompressMethod eStreamCompressMethod,
217                       int bHasOGRData);
218 
219        int WriteImagery(GDALDataset* poDS,
220                         const char* pszLayerName,
221                         PDFCompressMethod eCompressMethod,
222                         int nPredictor,
223                         int nJPEGQuality,
224                         const char* pszJPEG2000_DRIVER,
225                         int nBlockXSize, int nBlockYSize,
226                         GDALProgressFunc pfnProgress,
227                         void * pProgressData);
228 
229        int WriteClippedImagery(GDALDataset* poDS,
230                                const char* pszLayerName,
231                                PDFCompressMethod eCompressMethod,
232                                int nPredictor,
233                                int nJPEGQuality,
234                                const char* pszJPEG2000_DRIVER,
235                                int nBlockXSize, int nBlockYSize,
236                                GDALProgressFunc pfnProgress,
237                                void * pProgressData);
238 #ifdef OGR_ENABLED
239        int WriteOGRDataSource(const char* pszOGRDataSource,
240                               const char* pszOGRDisplayField,
241                               const char* pszOGRDisplayLayerNames,
242                               const char* pszOGRLinkField,
243                               int bWriteOGRAttributes);
244 
245        GDALPDFLayerDesc StartOGRLayer(CPLString osLayerName,
246                                       int bWriteOGRAttributes);
247        void EndOGRLayer(GDALPDFLayerDesc& osVectorDesc);
248 
249        int WriteOGRLayer(OGRDataSourceH hDS,
250                          int iLayer,
251                          const char* pszOGRDisplayField,
252                          const char* pszOGRLinkField,
253                          CPLString osLayerName,
254                          int bWriteOGRAttributes,
255                          int& iObj);
256 
257        int WriteOGRFeature(GDALPDFLayerDesc& osVectorDesc,
258                            OGRFeatureH hFeat,
259                            OGRCoordinateTransformationH hCT,
260                            const char* pszOGRDisplayField,
261                            const char* pszOGRLinkField,
262                            int bWriteOGRAttributes,
263                            int& iObj,
264                            int& iObjLayer);
265 #endif
266 
267        int  WriteJavascript(const char* pszJavascript);
268        int  WriteJavascriptFile(const char* pszJavascriptFile);
269 
270        int  EndPage(const char* pszExtraImages,
271                     const char* pszExtraStream,
272                     const char* pszExtraLayerName,
273                     const char* pszOffLayers,
274                     const char* pszExclusiveLayers);
275 
276        int  SetInfo(GDALDataset* poSrcDS,
277                     char** papszOptions);
278        int  SetXMP(GDALDataset* poSrcDS,
279                    const char* pszXMP);
280 };
281 
282 GDALDataset         *GDALPDFCreateCopy( const char *, GDALDataset *,
283                                         int, char **,
284                                         GDALProgressFunc pfnProgress,
285                                         void * pProgressData );
286 
287 #endif // PDFCREATECOPY_H_INCLUDED
288