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