1 //======================================================================== 2 // 3 // PDFDoc.h 4 // 5 // Copyright 1996-2003 Glyph & Cog, LLC 6 // 7 //======================================================================== 8 9 //======================================================================== 10 // 11 // Modified under the Poppler project - http://poppler.freedesktop.org 12 // 13 // All changes made under the Poppler project to this file are licensed 14 // under GPL version 2 or later 15 // 16 // Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net> 17 // Copyright (C) 2005, 2009, 2014, 2015 Albert Astals Cid <aacid@kde.org> 18 // Copyright (C) 2008 Julien Rebetez <julienr@svn.gnome.org> 19 // Copyright (C) 2008 Pino Toscano <pino@kde.org> 20 // Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org> 21 // Copyright (C) 2009 Eric Toombs <ewtoombs@uwaterloo.ca> 22 // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net> 23 // Copyright (C) 2010, 2014 Hib Eris <hib@hiberis.nl> 24 // Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla@geodesic.com> 25 // Copyright (C) 2011, 2013, 2014, 2016 Thomas Freitag <Thomas.Freitag@alfa.de> 26 // Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it> 27 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com> 28 // Copyright (C) 2013 Adam Reichold <adamreichold@myopera.com> 29 // Copyright (C) 2013 Adrian Perez de Castro <aperez@igalia.com> 30 // Copyright (C) 2015 André Guerreiro <aguerreiro1985@gmail.com> 31 // Copyright (C) 2015 André Esser <bepandre@hotmail.com> 32 // 33 // To see a description of the changes please see the Changelog file that 34 // came with your tarball or type make ChangeLog if you are building from git 35 // 36 //======================================================================== 37 38 #ifndef PDFDOC_H 39 #define PDFDOC_H 40 41 #ifdef USE_GCC_PRAGMAS 42 #pragma interface 43 #endif 44 45 #include "poppler-config.h" 46 #include <stdio.h> 47 #include "goo/GooMutex.h" 48 #include "XRef.h" 49 #include "Catalog.h" 50 #include "Page.h" 51 #include "Annot.h" 52 #include "Form.h" 53 #include "OptionalContent.h" 54 #include "Stream.h" 55 56 class GooString; 57 class GooFile; 58 class BaseStream; 59 class OutputDev; 60 class Links; 61 class LinkAction; 62 class LinkDest; 63 class Outline; 64 class Linearization; 65 class SecurityHandler; 66 class Hints; 67 class StructTreeRoot; 68 class FormWidgetSignature; 69 70 enum PDFWriteMode { 71 writeStandard, 72 writeForceRewrite, 73 writeForceIncremental 74 }; 75 76 //------------------------------------------------------------------------ 77 // PDFDoc 78 //------------------------------------------------------------------------ 79 80 class PDFDoc { 81 public: 82 83 PDFDoc(GooString *fileNameA, GooString *ownerPassword = NULL, 84 GooString *userPassword = NULL, void *guiDataA = NULL); 85 86 #ifdef _WIN32 87 PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword = NULL, 88 GooString *userPassword = NULL, void *guiDataA = NULL); 89 #endif 90 91 PDFDoc(BaseStream *strA, GooString *ownerPassword = NULL, 92 GooString *userPassword = NULL, void *guiDataA = NULL); 93 ~PDFDoc(); 94 95 static PDFDoc *ErrorPDFDoc(int errorCode, GooString *fileNameA = NULL); 96 97 // Was PDF document successfully opened? isOk()98 GBool isOk() { return ok; } 99 100 // Get the error code (if isOk() returns false). getErrorCode()101 int getErrorCode() { return errCode; } 102 103 // Get the error code returned by fopen() (if getErrorCode() == 104 // errOpenFile). getFopenErrno()105 int getFopenErrno() { return fopenErrno; } 106 107 // Get file name. getFileName()108 GooString *getFileName() { return fileName; } 109 #ifdef _WIN32 getFileNameU()110 wchar_t *getFileNameU() { return fileNameU; } 111 #endif 112 113 // Get the linearization table. 114 Linearization *getLinearization(); 115 GBool checkLinearization(); 116 117 // Get the xref table. getXRef()118 XRef *getXRef() { return xref; } 119 120 // Get catalog. getCatalog()121 Catalog *getCatalog() { return catalog; } 122 123 // Get optional content configuration getOptContentConfig()124 OCGs *getOptContentConfig() { return catalog->getOptContentConfig(); } 125 126 // Get base stream. getBaseStream()127 BaseStream *getBaseStream() { return str; } 128 129 // Get page parameters. getPageMediaWidth(int page)130 double getPageMediaWidth(int page) 131 { return getPage(page) ? getPage(page)->getMediaWidth() : 0.0 ; } getPageMediaHeight(int page)132 double getPageMediaHeight(int page) 133 { return getPage(page) ? getPage(page)->getMediaHeight() : 0.0 ; } getPageCropWidth(int page)134 double getPageCropWidth(int page) 135 { return getPage(page) ? getPage(page)->getCropWidth() : 0.0 ; } getPageCropHeight(int page)136 double getPageCropHeight(int page) 137 { return getPage(page) ? getPage(page)->getCropHeight() : 0.0 ; } getPageRotate(int page)138 int getPageRotate(int page) 139 { return getPage(page) ? getPage(page)->getRotate() : 0 ; } 140 141 // Get number of pages. 142 int getNumPages(); 143 144 // Return the contents of the metadata stream, or NULL if there is 145 // no metadata. readMetadata()146 GooString *readMetadata() { return catalog->readMetadata(); } 147 148 // Return the structure tree root object. getStructTreeRoot()149 StructTreeRoot *getStructTreeRoot() { return catalog->getStructTreeRoot(); } 150 151 // Get page. 152 Page *getPage(int page); 153 154 // Display a page. 155 void displayPage(OutputDev *out, int page, 156 double hDPI, double vDPI, int rotate, 157 GBool useMediaBox, GBool crop, GBool printing, 158 GBool (*abortCheckCbk)(void *data) = NULL, 159 void *abortCheckCbkData = NULL, 160 GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, 161 void *annotDisplayDecideCbkData = NULL, GBool copyXRef = gFalse); 162 163 // Display a range of pages. 164 void displayPages(OutputDev *out, int firstPage, int lastPage, 165 double hDPI, double vDPI, int rotate, 166 GBool useMediaBox, GBool crop, GBool printing, 167 GBool (*abortCheckCbk)(void *data) = NULL, 168 void *abortCheckCbkData = NULL, 169 GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, 170 void *annotDisplayDecideCbkData = NULL); 171 172 // Display part of a page. 173 void displayPageSlice(OutputDev *out, int page, 174 double hDPI, double vDPI, int rotate, 175 GBool useMediaBox, GBool crop, GBool printing, 176 int sliceX, int sliceY, int sliceW, int sliceH, 177 GBool (*abortCheckCbk)(void *data) = NULL, 178 void *abortCheckCbkData = NULL, 179 GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = NULL, 180 void *annotDisplayDecideCbkData = NULL, GBool copyXRef = gFalse); 181 182 // Find a page, given its object ID. Returns page number, or 0 if 183 // not found. findPage(int num,int gen)184 int findPage(int num, int gen) { return catalog->findPage(num, gen); } 185 186 // Returns the links for the current page, transferring ownership to 187 // the caller. 188 Links *getLinks(int page); 189 190 // Find a named destination. Returns the link destination, or 191 // NULL if <name> is not a destination. findDest(GooString * name)192 LinkDest *findDest(GooString *name) 193 { return catalog->findDest(name); } 194 195 // Process the links for a page. 196 void processLinks(OutputDev *out, int page); 197 198 199 #ifndef DISABLE_OUTLINE 200 // Return the outline object. 201 Outline *getOutline(); 202 #endif 203 204 // Is the file encrypted? isEncrypted()205 GBool isEncrypted() { return xref->isEncrypted(); } 206 207 std::vector<FormWidgetSignature*> getSignatureWidgets(); 208 209 // Check various permissions. 210 GBool okToPrint(GBool ignoreOwnerPW = gFalse) 211 { return xref->okToPrint(ignoreOwnerPW); } 212 GBool okToPrintHighRes(GBool ignoreOwnerPW = gFalse) 213 { return xref->okToPrintHighRes(ignoreOwnerPW); } 214 GBool okToChange(GBool ignoreOwnerPW = gFalse) 215 { return xref->okToChange(ignoreOwnerPW); } 216 GBool okToCopy(GBool ignoreOwnerPW = gFalse) 217 { return xref->okToCopy(ignoreOwnerPW); } 218 GBool okToAddNotes(GBool ignoreOwnerPW = gFalse) 219 { return xref->okToAddNotes(ignoreOwnerPW); } 220 GBool okToFillForm(GBool ignoreOwnerPW = gFalse) 221 { return xref->okToFillForm(ignoreOwnerPW); } 222 GBool okToAccessibility(GBool ignoreOwnerPW = gFalse) 223 { return xref->okToAccessibility(ignoreOwnerPW); } 224 GBool okToAssemble(GBool ignoreOwnerPW = gFalse) 225 { return xref->okToAssemble(ignoreOwnerPW); } 226 227 228 // Is this document linearized? 229 GBool isLinearized(GBool tryingToReconstruct = gFalse); 230 231 // Return the document's Info dictionary (if any). getDocInfo(Object * obj)232 Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); } getDocInfoNF(Object * obj)233 Object *getDocInfoNF(Object *obj) { return xref->getDocInfoNF(obj); } 234 235 // Return the PDF version specified by the file. getPDFMajorVersion()236 int getPDFMajorVersion() { return pdfMajorVersion; } getPDFMinorVersion()237 int getPDFMinorVersion() { return pdfMinorVersion; } 238 239 //Return the PDF ID in the trailer dictionary (if any). 240 GBool getID(GooString *permanent_id, GooString *update_id); 241 242 // Save one page with another name. 243 int savePageAs(GooString *name, int pageNo); 244 // Save this file with another name. 245 int saveAs(GooString *name, PDFWriteMode mode=writeStandard); 246 // Save this file in the given output stream. 247 int saveAs(OutStream *outStr, PDFWriteMode mode=writeStandard); 248 // Save this file with another name without saving changes 249 int saveWithoutChangesAs(GooString *name); 250 // Save this file in the given output stream without saving changes 251 int saveWithoutChangesAs(OutStream *outStr); 252 253 // Return a pointer to the GUI (XPDFCore or WinPDFCore object). getGUIData()254 void *getGUIData() { return guiData; } 255 256 // rewrite pageDict with MediaBox, CropBox and new page CTM 257 void replacePageDict(int pageNo, int rotate, PDFRectangle *mediaBox, PDFRectangle *cropBox); 258 void markPageObjects(Dict *pageDict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum); 259 GBool markAnnotations(Object *annots, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum); 260 void markAcroForm(Object *acrpForm, XRef *xRef, XRef *countRef, Guint numOffset, int oldPageNum, int newPageNum); 261 // write all objects used by pageDict to outStr 262 Guint writePageObjects(OutStream *outStr, XRef *xRef, Guint numOffset, GBool combine = gFalse); 263 static void writeObject (Object *obj, OutStream* outStr, XRef *xref, Guint numOffset, Guchar *fileKey, 264 CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen); 265 static void writeHeader(OutStream *outStr, int major, int minor); 266 267 // Ownership goes to the caller 268 static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Goffset startxRef, 269 Ref *root, XRef *xRef, const char *fileName, Goffset fileSize); 270 static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries, 271 Goffset uxrefOffset, OutStream* outStr, XRef *xRef); 272 static void writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, 273 Goffset uxrefOffset, OutStream* outStr, XRef *xRef); 274 275 private: 276 // insert referenced objects in XRef 277 void markDictionnary (Dict* dict, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum); 278 void markObject (Object *obj, XRef *xRef, XRef *countRef, Guint numOffset, int oldRefNum, int newRefNum); 279 static void writeDictionnary (Dict* dict, OutStream* outStr, XRef *xRef, Guint numOffset, Guchar *fileKey, 280 CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen); 281 282 // Write object header to current file stream and return its offset 283 static Goffset writeObjectHeader (Ref *ref, OutStream* outStr); 284 static void writeObjectFooter (OutStream* outStr); 285 writeObject(Object * obj,OutStream * outStr,Guchar * fileKey,CryptAlgorithm encAlgorithm,int keyLength,int objNum,int objGen)286 void writeObject (Object *obj, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm, 287 int keyLength, int objNum, int objGen) 288 { writeObject(obj, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); } writeDictionnary(Dict * dict,OutStream * outStr,Guchar * fileKey,CryptAlgorithm encAlgorithm,int keyLength,int objNum,int objGen)289 void writeDictionnary (Dict* dict, OutStream* outStr, Guchar *fileKey, CryptAlgorithm encAlgorithm, 290 int keyLength, int objNum, int objGen) 291 { writeDictionnary(dict, outStr, getXRef(), 0, fileKey, encAlgorithm, keyLength, objNum, objGen); } 292 static void writeStream (Stream* str, OutStream* outStr); 293 static void writeRawStream (Stream* str, OutStream* outStr); 294 void writeXRefTableTrailer (Goffset uxrefOffset, XRef *uxref, GBool writeAllEntries, 295 int uxrefSize, OutStream* outStr, GBool incrUpdate); 296 static void writeString (GooString* s, OutStream* outStr, Guchar *fileKey, 297 CryptAlgorithm encAlgorithm, int keyLength, int objNum, int objGen); 298 void saveIncrementalUpdate (OutStream* outStr); 299 void saveCompleteRewrite (OutStream* outStr); 300 301 Page *parsePage(int page); 302 303 // Get hints. 304 Hints *getHints(); 305 306 PDFDoc(); 307 void init(); 308 GBool setup(GooString *ownerPassword, GooString *userPassword); 309 GBool checkFooter(); 310 void checkHeader(); 311 GBool checkEncryption(GooString *ownerPassword, GooString *userPassword); 312 // Get the offset of the start xref table. 313 Goffset getStartXRef(GBool tryingToReconstruct = gFalse); 314 // Get the offset of the entries in the main XRef table of a 315 // linearized document (0 for non linearized documents). 316 Goffset getMainXRefEntriesOffset(GBool tryingToReconstruct = gFalse); 317 long long strToLongLong(char *s); 318 319 GooString *fileName; 320 #ifdef _WIN32 321 wchar_t *fileNameU; 322 #endif 323 GooFile *file; 324 BaseStream *str; 325 void *guiData; 326 int pdfMajorVersion; 327 int pdfMinorVersion; 328 Linearization *linearization; 329 // linearizationState = 0: unchecked 330 // linearizationState = 1: checked and valid 331 // linearizationState = 2: checked and invalid 332 int linearizationState; 333 XRef *xref; 334 SecurityHandler *secHdlr; 335 Catalog *catalog; 336 Hints *hints; 337 #ifndef DISABLE_OUTLINE 338 Outline *outline; 339 #endif 340 Page **pageCache; 341 342 GBool ok; 343 int errCode; 344 //If there is an error opening the PDF file with fopen() in the constructor, 345 //then the POSIX errno will be here. 346 int fopenErrno; 347 348 Goffset startXRefPos; // offset of last xref table 349 #if MULTITHREADED 350 GooMutex mutex; 351 #endif 352 }; 353 354 #endif 355