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