1 /******************************************************************************
2  * $Id$
3  *
4  * Project:  PDF Translator
5  * Purpose:  Definition of classes for OGR .pdf driver.
6  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
7  *
8  ******************************************************************************
9  * Copyright (c) 2010-2014, 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 _GDAL_PDF_H_INCLUDED
31 #define _GDAL_PDF_H_INCLUDED
32 
33 #ifdef HAVE_POPPLER
34 
35 /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef bool GBool" */
36 /* in include/poppler/goo/gtypes.h with the one defined in cpl_port.h */
37 #define CPL_GBOOL_DEFINED
38 #define OGR_FEATURESTYLE_INCLUDE
39 
40 #include <goo/gtypes.h>
41 #endif
42 
43 #include "gdal_pam.h"
44 #include "ogrsf_frmts.h"
45 
46 #include "ogr_mem.h"
47 #include "pdfobject.h"
48 
49 #include <map>
50 #include <stack>
51 
52 /************************************************************************/
53 /*                             OGRPDFLayer                              */
54 /************************************************************************/
55 
56 #if defined(HAVE_POPPLER) || defined(HAVE_PODOFO)
57 
58 class PDFDataset;
59 
60 class OGRPDFLayer : public OGRMemLayer
61 {
62     PDFDataset       *poDS;
63     int               bGeomTypeSet;
64     int               bGeomTypeMixed;
65 
66 public:
67         OGRPDFLayer(PDFDataset* poDS,
68                     const char * pszName,
69                     OGRSpatialReference *poSRS,
70                     OGRwkbGeometryType eGeomType);
71 
72     void                Fill( GDALPDFArray* poArray );
73 
74     virtual int                 TestCapability( const char * );
75 };
76 
77 #endif
78 
79 /************************************************************************/
80 /*                          OGRPDFWritableLayer                         */
81 /************************************************************************/
82 
83 class PDFWritableVectorDataset;
84 
85 class OGRPDFWritableLayer : public OGRMemLayer
86 {
87     PDFWritableVectorDataset       *poDS;
88 
89 public:
90         OGRPDFWritableLayer(PDFWritableVectorDataset* poDS,
91                     const char * pszName,
92                     OGRSpatialReference *poSRS,
93                     OGRwkbGeometryType eGeomType);
94 
95     virtual int                 TestCapability( const char * );
96     virtual OGRErr              ICreateFeature( OGRFeature *poFeature );
97 };
98 
99 /************************************************************************/
100 /*                            GDALPDFTileDesc                           */
101 /************************************************************************/
102 
103 typedef struct
104 {
105     GDALPDFObject* poImage;
106     double         adfCM[6];
107     double         dfWidth;
108     double         dfHeight;
109     int            nBands;
110 } GDALPDFTileDesc;
111 
112 /************************************************************************/
113 /* ==================================================================== */
114 /*                              PDFDataset                              */
115 /* ==================================================================== */
116 /************************************************************************/
117 
118 class PDFRasterBand;
119 class PDFImageRasterBand;
120 
121 #ifdef HAVE_POPPLER
122 class ObjectAutoFree;
123 #endif
124 
125 #define MAX_TOKEN_SIZE 256
126 #define TOKEN_STACK_SIZE 8
127 
128 #if defined(HAVE_POPPLER) || defined(HAVE_PODOFO)
129 
130 class PDFDataset : public GDALPamDataset
131 {
132     friend class PDFRasterBand;
133     friend class PDFImageRasterBand;
134 
135     CPLString    osFilename;
136     CPLString    osUserPwd;
137     char        *pszWKT;
138     double       dfDPI;
139     int          bHasCTM;
140     double       adfCTM[6];
141     double       adfGeoTransform[6];
142     int          bGeoTransformValid;
143     int          nGCPCount;
144     GDAL_GCP    *pasGCPList;
145     int          bProjDirty;
146     int          bNeatLineDirty;
147 
148     GDALMultiDomainMetadata oMDMD;
149     int          bInfoDirty;
150     int          bXMPDirty;
151 
152     int          bUsePoppler;
153 #ifdef HAVE_POPPLER
154     PDFDoc*      poDocPoppler;
155 #endif
156 #ifdef HAVE_PODOFO
157     PoDoFo::PdfMemDocument* poDocPodofo;
158     int          bPdfToPpmFailed;
159 #endif
160     GDALPDFObject* poPageObj;
161 
162     int          iPage;
163 
164     GDALPDFObject *poImageObj;
165 
166     double       dfMaxArea;
167     int          ParseLGIDictObject(GDALPDFObject* poLGIDict);
168     int          ParseLGIDictDictFirstPass(GDALPDFDictionary* poLGIDict, int* pbIsBestCandidate = NULL);
169     int          ParseLGIDictDictSecondPass(GDALPDFDictionary* poLGIDict);
170     int          ParseProjDict(GDALPDFDictionary* poProjDict);
171     int          ParseVP(GDALPDFObject* poVP, double dfMediaBoxWidth, double dfMediaBoxHeight);
172     int          ParseMeasure(GDALPDFObject* poMeasure,
173                               double dfMediaBoxWidth, double dfMediaBoxHeight,
174                               double dfULX, double dfULY, double dfLRX, double dfLRY);
175 
176     int          bTried;
177     GByte       *pabyCachedData;
178     int          nLastBlockXOff, nLastBlockYOff;
179 
180     OGRPolygon*  poNeatLine;
181 
182     std::vector<GDALPDFTileDesc> asTiles; /* in the order of the PDF file */
183     std::vector<int> aiTiles; /* in the order of blocks */
184     int          nBlockXSize;
185     int          nBlockYSize;
186     int          CheckTiledRaster();
187 
188     void         GuessDPI(GDALPDFDictionary* poPageDict, int* pnBands);
189     void         FindXMP(GDALPDFObject* poObj);
190     void         ParseInfo(GDALPDFObject* poObj);
191 
192 #ifdef HAVE_POPPLER
193     ObjectAutoFree* poCatalogObjectPoppler;
194 #endif
195     GDALPDFObject* poCatalogObject;
196     GDALPDFObject* GetCatalog();
197 
198 #ifdef HAVE_POPPLER
199     void         AddLayer(const char* pszLayerName, OptionalContentGroup* ocg);
200     void         ExploreLayers(GDALPDFArray* poArray, int nRecLevel, CPLString osTopLayer = "");
201     void         FindLayers();
202     void         TurnLayersOnOff();
203     CPLStringList osLayerList;
204     std::map<CPLString, OptionalContentGroup*> oLayerOCGMap;
205 #endif
206 
207     CPLStringList osLayerWithRefList;
208     CPLString     FindLayerOCG(GDALPDFDictionary* poPageDict,
209                                const char* pszLayerName);
210     void          FindLayersGeneric(GDALPDFDictionary* poPageDict);
211 
212     int          bUseOCG;
213 
214     char       **papszOpenOptions;
215     static const char*  GetOption(char** papszOpenOptions,
216                                   const char* pszOptionName,
217                                   const char* pszDefaultVal);
218 
219     int                 nLayers;
220     OGRLayer          **papoLayers;
221 
222     double              dfPageWidth;
223     double              dfPageHeight;
224     void                PDFCoordsToSRSCoords(double x, double y,
225                                              double& X, double &Y);
226 
227     std::map<int,OGRGeometry*> oMapMCID;
228     void                CleanupIntermediateResources();
229 
230     std::map<CPLString, int> oMapOperators;
231     void                InitMapOperators();
232 
233     int                 bSetStyle;
234 
235     void                ExploreTree(GDALPDFObject* poObj, int nRecLevel);
236     void                ExploreContents(GDALPDFObject* poObj, GDALPDFObject* poResources);
237 
238     void                ExploreContentsNonStructuredInternal(GDALPDFObject* poContents,
239                                                              GDALPDFObject* poResources,
240                                                              std::map<CPLString, OGRPDFLayer*>& oMapPropertyToLayer);
241     void                ExploreContentsNonStructured(GDALPDFObject* poObj, GDALPDFObject* poResources);
242 
243     int                 UnstackTokens(const char* pszToken,
244                                       int nRequiredArgs,
245                                       char aszTokenStack[TOKEN_STACK_SIZE][MAX_TOKEN_SIZE],
246                                       int& nTokenStackSize,
247                                       double* adfCoords);
248     OGRGeometry*        ParseContent(const char* pszContent,
249                                      GDALPDFObject* poResources,
250                                      int bInitBDCStack,
251                                      int bMatchQ,
252                                      std::map<CPLString, OGRPDFLayer*>& oMapPropertyToLayer,
253                                      OGRPDFLayer* poCurLayer);
254     OGRGeometry*        BuildGeometry(std::vector<double>& oCoords,
255                                       int bHasFoundFill,
256                                       int bHasMultiPart);
257 
258     int                 OpenVectorLayers(GDALPDFDictionary* poPageDict);
259 
260   public:
261                  PDFDataset();
262     virtual     ~PDFDataset();
263 
264     virtual const char* GetProjectionRef();
265     virtual CPLErr GetGeoTransform( double * );
266 
267     virtual CPLErr      SetProjection(const char* pszWKTIn);
268     virtual CPLErr      SetGeoTransform(double* padfGeoTransform);
269 
270     virtual char      **GetMetadataDomainList();
271     virtual char      **GetMetadata( const char * pszDomain = "" );
272     virtual CPLErr      SetMetadata( char ** papszMetadata,
273                                      const char * pszDomain = "" );
274     virtual const char *GetMetadataItem( const char * pszName,
275                                          const char * pszDomain = "" );
276     virtual CPLErr      SetMetadataItem( const char * pszName,
277                                          const char * pszValue,
278                                          const char * pszDomain = "" );
279 
280     virtual CPLErr IRasterIO( GDALRWFlag, int, int, int, int,
281                               void *, int, int, GDALDataType,
282                               int, int *,
283                               GSpacing nPixelSpace, GSpacing nLineSpace,
284                               GSpacing nBandSpace,
285                               GDALRasterIOExtraArg* psExtraArg);
286 
287     virtual int    GetGCPCount();
288     virtual const char *GetGCPProjection();
289     virtual const GDAL_GCP *GetGCPs();
290     virtual CPLErr SetGCPs( int nGCPCount, const GDAL_GCP *pasGCPList,
291                             const char *pszGCPProjection );
292 
293     CPLErr ReadPixels( int nReqXOff, int nReqYOff,
294                        int nReqXSize, int nReqYSize,
295                        GSpacing nPixelSpace,
296                        GSpacing nLineSpace,
297                        GSpacing nBandSpace,
298                        GByte* pabyData );
299 
300     virtual int                 GetLayerCount();
301     virtual OGRLayer*           GetLayer( int );
302 
303     virtual int                 TestCapability( const char * );
304 
305     OGRGeometry        *GetGeometryFromMCID(int nMCID);
306 
307     static GDALDataset *Open( GDALOpenInfo * );
308     static int          Identify( GDALOpenInfo * );
309 };
310 
311 /************************************************************************/
312 /* ==================================================================== */
313 /*                         PDFRasterBand                                */
314 /* ==================================================================== */
315 /************************************************************************/
316 
317 class PDFRasterBand : public GDALPamRasterBand
318 {
319     friend class PDFDataset;
320 
321     CPLErr IReadBlockFromTile( int, int, void * );
322 
323   public:
324 
325                 PDFRasterBand( PDFDataset *, int );
326 
327     virtual CPLErr IReadBlock( int, int, void * );
328     virtual GDALColorInterp GetColorInterpretation();
329 };
330 
331 #endif /*  defined(HAVE_POPPLER) || defined(HAVE_PODOFO) */
332 
333 /************************************************************************/
334 /*                          PDFWritableDataset                          */
335 /************************************************************************/
336 
337 class PDFWritableVectorDataset : public GDALDataset
338 {
339         char**              papszOptions;
340 
341         int                 nLayers;
342         OGRLayer          **papoLayers;
343 
344         int                 bModified;
345 
346     public:
347                             PDFWritableVectorDataset();
348                            ~PDFWritableVectorDataset();
349 
350         virtual OGRLayer*           ICreateLayer( const char * pszLayerName,
351                                                 OGRSpatialReference *poSRS,
352                                                 OGRwkbGeometryType eType,
353                                                 char ** papszOptions );
354 
355         virtual OGRErr              SyncToDisk();
356 
357         virtual int                 GetLayerCount();
358         virtual OGRLayer*           GetLayer( int );
359 
360         virtual int                 TestCapability( const char * );
361 
362         static GDALDataset* Create( const char * pszName,
363                                  int nXSize, int nYSize, int nBands,
364                                  GDALDataType eType, char ** papszOptions );
365 
SetModified()366         void                SetModified() { bModified = TRUE; }
367 };
368 
369 GDALDataset* GDALPDFOpen(const char* pszFilename, GDALAccess eAccess);
370 CPLString PDFSanitizeLayerName(const char* pszName);
371 
372 #endif /* ndef _GDAL_PDF_H_INCLUDED */
373