1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
9 //========================================================================
11 // Modified under the Poppler project - http://poppler.freedesktop.org
13 // All changes made under the Poppler project to this file are licensed
14 // under GPL version 2 or later
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>
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
34 //========================================================================
39 #ifdef USE_GCC_PRAGMAS
43 #include "poppler-config.h"
45 #include "goo/GooMutex.h"
50 #include "OptionalContent.h"
62 class SecurityHandler
;
72 //------------------------------------------------------------------------
74 //------------------------------------------------------------------------
79 PDFDoc(GooString
*fileNameA
, GooString
*ownerPassword
= NULL
,
80 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
83 PDFDoc(wchar_t *fileNameA
, int fileNameLen
, GooString
*ownerPassword
= NULL
,
84 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
87 PDFDoc(BaseStream
*strA
, GooString
*ownerPassword
= NULL
,
88 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
91 static PDFDoc
*ErrorPDFDoc(int errorCode
, GooString
*fileNameA
= NULL
);
93 // Was PDF document successfully opened?
94 GBool
isOk() { return ok
; }
96 // Get the error code (if isOk() returns false).
97 int getErrorCode() { return errCode
; }
99 // Get the error code returned by fopen() (if getErrorCode() ==
101 int getFopenErrno() { return fopenErrno
; }
104 GooString
*getFileName() { return fileName
; }
106 wchar_t *getFileNameU() { return fileNameU
; }
109 // Get the linearization table.
110 Linearization
*getLinearization();
112 // Get the xref table.
113 XRef
*getXRef() { return xref
; }
116 Catalog
*getCatalog() { return catalog
; }
118 // Get optional content configuration
119 OCGs
*getOptContentConfig() { return catalog
->getOptContentConfig(); }
122 BaseStream
*getBaseStream() { return str
; }
124 // Get page parameters.
125 double getPageMediaWidth(int page
)
126 { return getPage(page
) ? getPage(page
)->getMediaWidth() : 0.0 ; }
127 double getPageMediaHeight(int page
)
128 { return getPage(page
) ? getPage(page
)->getMediaHeight() : 0.0 ; }
129 double getPageCropWidth(int page
)
130 { return getPage(page
) ? getPage(page
)->getCropWidth() : 0.0 ; }
131 double getPageCropHeight(int page
)
132 { return getPage(page
) ? getPage(page
)->getCropHeight() : 0.0 ; }
133 int getPageRotate(int page
)
134 { return getPage(page
) ? getPage(page
)->getRotate() : 0 ; }
136 // Get number of pages.
139 // Return the contents of the metadata stream, or NULL if there is
141 GooString
*readMetadata() { return catalog
->readMetadata(); }
143 // Return the structure tree root object.
144 StructTreeRoot
*getStructTreeRoot() { return catalog
->getStructTreeRoot(); }
147 Page
*getPage(int 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
);
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
);
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
);
177 // Find a page, given its object ID. Returns page number, or 0 if
179 int findPage(int num
, int gen
) { return catalog
->findPage(num
, gen
); }
181 // Returns the links for the current page, transferring ownership to
183 Links
*getLinks(int page
);
185 // Find a named destination. Returns the link destination, or
186 // NULL if <name> is not a destination.
187 LinkDest
*findDest(GooString
*name
)
188 { return catalog
->findDest(name
); }
190 // Process the links for a page.
191 void processLinks(OutputDev
*out
, int page
);
194 #ifndef DISABLE_OUTLINE
195 // Return the outline object.
196 Outline
*getOutline();
199 // Is the file encrypted?
200 GBool
isEncrypted() { return xref
->isEncrypted(); }
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
); }
221 // Is this document linearized?
222 GBool
isLinearized(GBool tryingToReconstruct
= gFalse
);
224 // Return the document's Info dictionary (if any).
225 Object
*getDocInfo(Object
*obj
) { return xref
->getDocInfo(obj
); }
226 Object
*getDocInfoNF(Object
*obj
) { return xref
->getDocInfoNF(obj
); }
228 // Return the PDF version specified by the file.
229 int getPDFMajorVersion() { return pdfMajorVersion
; }
230 int getPDFMinorVersion() { return pdfMinorVersion
; }
232 //Return the PDF ID in the trailer dictionary (if any).
233 GBool
getID(GooString
*permanent_id
, GooString
*update_id
);
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
);
246 // Return a pointer to the GUI (XPDFCore or WinPDFCore object).
247 void *getGUIData() { return guiData
; }
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
);
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
);
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
);
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
);
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
); }
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
);
294 Page
*parsePage(int page
);
301 GBool
setup(GooString
*ownerPassword
, GooString
*userPassword
);
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
);
321 Linearization
*linearization
;
323 SecurityHandler
*secHdlr
;
326 #ifndef DISABLE_OUTLINE
333 //If there is an error opening the PDF file with fopen() in the constructor,
334 //then the POSIX errno will be here.
337 Goffset startXRefPos
; // offset of last xref table