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