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