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, 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 // Copyright (C) 2016 Jakub Kucharski <jakubkucharski97@gmail.com>
34 // To see a description of the changes please see the Changelog file that
35 // came with your tarball or type make ChangeLog if you are building from git
37 //========================================================================
42 #ifdef USE_GCC_PRAGMAS
46 #include "poppler-config.h"
48 #include "goo/GooMutex.h"
54 #include "OptionalContent.h"
66 class SecurityHandler
;
76 //------------------------------------------------------------------------
78 //------------------------------------------------------------------------
83 PDFDoc(GooString
*fileNameA
, GooString
*ownerPassword
= NULL
,
84 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
87 PDFDoc(wchar_t *fileNameA
, int fileNameLen
, GooString
*ownerPassword
= NULL
,
88 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
91 PDFDoc(BaseStream
*strA
, GooString
*ownerPassword
= NULL
,
92 GooString
*userPassword
= NULL
, void *guiDataA
= NULL
);
95 static PDFDoc
*ErrorPDFDoc(int errorCode
, GooString
*fileNameA
= NULL
);
97 // Was PDF document successfully opened?
98 GBool
isOk() { return ok
; }
100 // Get the error code (if isOk() returns false).
101 int getErrorCode() { return errCode
; }
103 // Get the error code returned by fopen() (if getErrorCode() ==
105 int getFopenErrno() { return fopenErrno
; }
108 GooString
*getFileName() { return fileName
; }
110 wchar_t *getFileNameU() { return fileNameU
; }
113 // Get the linearization table.
114 Linearization
*getLinearization();
115 GBool
checkLinearization();
117 // Get the xref table.
118 XRef
*getXRef() { return xref
; }
121 Catalog
*getCatalog() { return catalog
; }
123 // Get optional content configuration
124 OCGs
*getOptContentConfig() { return catalog
->getOptContentConfig(); }
127 BaseStream
*getBaseStream() { return str
; }
129 // Get page parameters.
130 double getPageMediaWidth(int page
)
131 { return getPage(page
) ? getPage(page
)->getMediaWidth() : 0.0 ; }
132 double getPageMediaHeight(int page
)
133 { return getPage(page
) ? getPage(page
)->getMediaHeight() : 0.0 ; }
134 double getPageCropWidth(int page
)
135 { return getPage(page
) ? getPage(page
)->getCropWidth() : 0.0 ; }
136 double getPageCropHeight(int page
)
137 { return getPage(page
) ? getPage(page
)->getCropHeight() : 0.0 ; }
138 int getPageRotate(int page
)
139 { return getPage(page
) ? getPage(page
)->getRotate() : 0 ; }
141 // Get number of pages.
144 // Return the contents of the metadata stream, or NULL if there is
146 GooString
*readMetadata() { return catalog
->readMetadata(); }
148 // Return the structure tree root object.
149 StructTreeRoot
*getStructTreeRoot() { return catalog
->getStructTreeRoot(); }
152 Page
*getPage(int 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
);
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
);
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
);
182 // Find a page, given its object ID. Returns page number, or 0 if
184 int findPage(int num
, int gen
) { return catalog
->findPage(num
, gen
); }
186 // Returns the links for the current page, transferring ownership to
188 Links
*getLinks(int page
);
190 // Find a named destination. Returns the link destination, or
191 // NULL if <name> is not a destination.
192 LinkDest
*findDest(GooString
*name
)
193 { return catalog
->findDest(name
); }
195 // Process the links for a page.
196 void processLinks(OutputDev
*out
, int page
);
199 #ifndef DISABLE_OUTLINE
200 // Return the outline object.
201 Outline
*getOutline();
204 // Is the file encrypted?
205 GBool
isEncrypted() { return xref
->isEncrypted(); }
207 std::vector
<FormWidgetSignature
*> getSignatureWidgets();
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
); }
228 // Is this document linearized?
229 GBool
isLinearized(GBool tryingToReconstruct
= gFalse
);
231 // Return the document's Info dictionary (if any).
232 Object
*getDocInfo(Object
*obj
) { return xref
->getDocInfo(obj
); }
233 Object
*getDocInfoNF(Object
*obj
) { return xref
->getDocInfoNF(obj
); }
235 // Create and return the document's Info dictionary if none exists.
236 // Otherwise return the existing one.
237 Object
*createDocInfoIfNoneExists(Object
*obj
) { return xref
->createDocInfoIfNoneExists(obj
); }
239 // Remove the document's Info dictionary and update the trailer dictionary.
240 void removeDocInfo() { xref
->removeDocInfo(); }
242 // Set doc info string entry. NULL or empty value will cause a removal.
243 // Takes ownership of value.
244 void setDocInfoStringEntry(const char *key
, GooString
*value
);
246 // Set document's properties in document's Info dictionary.
247 // NULL or empty value will cause a removal.
248 // Takes ownership of value.
249 void setDocInfoTitle(GooString
*title
) { setDocInfoStringEntry("Title", title
); }
250 void setDocInfoAuthor(GooString
*author
) { setDocInfoStringEntry("Author", author
); }
251 void setDocInfoSubject(GooString
*subject
) { setDocInfoStringEntry("Subject", subject
); }
252 void setDocInfoKeywords(GooString
*keywords
) { setDocInfoStringEntry("Keywords", keywords
); }
253 void setDocInfoCreator(GooString
*creator
) { setDocInfoStringEntry("Creator", creator
); }
254 void setDocInfoProducer(GooString
*producer
) { setDocInfoStringEntry("Producer", producer
); }
255 void setDocInfoCreatDate(GooString
*creatDate
) { setDocInfoStringEntry("CreationDate", creatDate
); }
256 void setDocInfoModDate(GooString
*modDate
) { setDocInfoStringEntry("ModDate", modDate
); }
258 // Get document's properties from document's Info dictionary.
259 // Returns NULL on fail.
260 // Returned GooStrings should be freed by the caller.
261 GooString
*getDocInfoStringEntry(const char *key
);
263 GooString
*getDocInfoTitle() { return getDocInfoStringEntry("Title"); }
264 GooString
*getDocInfoAuthor() { return getDocInfoStringEntry("Author"); }
265 GooString
*getDocInfoSubject() { return getDocInfoStringEntry("Subject"); }
266 GooString
*getDocInfoKeywords() { return getDocInfoStringEntry("Keywords"); }
267 GooString
*getDocInfoCreator() { return getDocInfoStringEntry("Creator"); }
268 GooString
*getDocInfoProducer() { return getDocInfoStringEntry("Producer"); }
269 GooString
*getDocInfoCreatDate() { return getDocInfoStringEntry("CreationDate"); }
270 GooString
*getDocInfoModDate() { return getDocInfoStringEntry("ModDate"); }
272 // Return the PDF version specified by the file.
273 int getPDFMajorVersion() { return pdfMajorVersion
; }
274 int getPDFMinorVersion() { return pdfMinorVersion
; }
276 //Return the PDF ID in the trailer dictionary (if any).
277 GBool
getID(GooString
*permanent_id
, GooString
*update_id
);
279 // Save one page with another name.
280 int savePageAs(GooString
*name
, int pageNo
);
281 // Save this file with another name.
282 int saveAs(GooString
*name
, PDFWriteMode mode
=writeStandard
);
283 // Save this file in the given output stream.
284 int saveAs(OutStream
*outStr
, PDFWriteMode mode
=writeStandard
);
285 // Save this file with another name without saving changes
286 int saveWithoutChangesAs(GooString
*name
);
287 // Save this file in the given output stream without saving changes
288 int saveWithoutChangesAs(OutStream
*outStr
);
290 // Return a pointer to the GUI (XPDFCore or WinPDFCore object).
291 void *getGUIData() { return guiData
; }
293 // rewrite pageDict with MediaBox, CropBox and new page CTM
294 void replacePageDict(int pageNo
, int rotate
, PDFRectangle
*mediaBox
, PDFRectangle
*cropBox
);
295 void markPageObjects(Dict
*pageDict
, XRef
*xRef
, XRef
*countRef
, Guint numOffset
, int oldRefNum
, int newRefNum
);
296 GBool
markAnnotations(Object
*annots
, XRef
*xRef
, XRef
*countRef
, Guint numOffset
, int oldPageNum
, int newPageNum
);
297 void markAcroForm(Object
*acrpForm
, XRef
*xRef
, XRef
*countRef
, Guint numOffset
, int oldPageNum
, int newPageNum
);
298 // write all objects used by pageDict to outStr
299 Guint
writePageObjects(OutStream
*outStr
, XRef
*xRef
, Guint numOffset
, GBool combine
= gFalse
);
300 static void writeObject (Object
*obj
, OutStream
* outStr
, XRef
*xref
, Guint numOffset
, Guchar
*fileKey
,
301 CryptAlgorithm encAlgorithm
, int keyLength
, int objNum
, int objGen
);
302 static void writeHeader(OutStream
*outStr
, int major
, int minor
);
304 // Ownership goes to the caller
305 static Dict
*createTrailerDict (int uxrefSize
, GBool incrUpdate
, Goffset startxRef
,
306 Ref
*root
, XRef
*xRef
, const char *fileName
, Goffset fileSize
);
307 static void writeXRefTableTrailer (Dict
*trailerDict
, XRef
*uxref
, GBool writeAllEntries
,
308 Goffset uxrefOffset
, OutStream
* outStr
, XRef
*xRef
);
309 static void writeXRefStreamTrailer (Dict
*trailerDict
, XRef
*uxref
, Ref
*uxrefStreamRef
,
310 Goffset uxrefOffset
, OutStream
* outStr
, XRef
*xRef
);
313 // insert referenced objects in XRef
314 void markDictionnary (Dict
* dict
, XRef
*xRef
, XRef
*countRef
, Guint numOffset
, int oldRefNum
, int newRefNum
);
315 void markObject (Object
*obj
, XRef
*xRef
, XRef
*countRef
, Guint numOffset
, int oldRefNum
, int newRefNum
);
316 static void writeDictionnary (Dict
* dict
, OutStream
* outStr
, XRef
*xRef
, Guint numOffset
, Guchar
*fileKey
,
317 CryptAlgorithm encAlgorithm
, int keyLength
, int objNum
, int objGen
);
319 // Write object header to current file stream and return its offset
320 static Goffset
writeObjectHeader (Ref
*ref
, OutStream
* outStr
);
321 static void writeObjectFooter (OutStream
* outStr
);
323 void writeObject (Object
*obj
, OutStream
* outStr
, Guchar
*fileKey
, CryptAlgorithm encAlgorithm
,
324 int keyLength
, int objNum
, int objGen
)
325 { writeObject(obj
, outStr
, getXRef(), 0, fileKey
, encAlgorithm
, keyLength
, objNum
, objGen
); }
326 void writeDictionnary (Dict
* dict
, OutStream
* outStr
, Guchar
*fileKey
, CryptAlgorithm encAlgorithm
,
327 int keyLength
, int objNum
, int objGen
)
328 { writeDictionnary(dict
, outStr
, getXRef(), 0, fileKey
, encAlgorithm
, keyLength
, objNum
, objGen
); }
329 static void writeStream (Stream
* str
, OutStream
* outStr
);
330 static void writeRawStream (Stream
* str
, OutStream
* outStr
);
331 void writeXRefTableTrailer (Goffset uxrefOffset
, XRef
*uxref
, GBool writeAllEntries
,
332 int uxrefSize
, OutStream
* outStr
, GBool incrUpdate
);
333 static void writeString (GooString
* s
, OutStream
* outStr
, Guchar
*fileKey
,
334 CryptAlgorithm encAlgorithm
, int keyLength
, int objNum
, int objGen
);
335 void saveIncrementalUpdate (OutStream
* outStr
);
336 void saveCompleteRewrite (OutStream
* outStr
);
338 Page
*parsePage(int page
);
345 GBool
setup(GooString
*ownerPassword
, GooString
*userPassword
);
348 GBool
checkEncryption(GooString
*ownerPassword
, GooString
*userPassword
);
349 // Get the offset of the start xref table.
350 Goffset
getStartXRef(GBool tryingToReconstruct
= gFalse
);
351 // Get the offset of the entries in the main XRef table of a
352 // linearized document (0 for non linearized documents).
353 Goffset
getMainXRefEntriesOffset(GBool tryingToReconstruct
= gFalse
);
354 long long strToLongLong(char *s
);
356 // Mark the document's Info dictionary as modified.
357 void setDocInfoModified(Object
*infoObj
);
368 Linearization
*linearization
;
369 // linearizationState = 0: unchecked
370 // linearizationState = 1: checked and valid
371 // linearizationState = 2: checked and invalid
372 int linearizationState
;
374 SecurityHandler
*secHdlr
;
377 #ifndef DISABLE_OUTLINE
384 //If there is an error opening the PDF file with fopen() in the constructor,
385 //then the POSIX errno will be here.
388 Goffset startXRefPos
; // offset of last xref table