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 Brad Hards <bradh@frogmouth.net>
17 // Copyright (C) 2006, 2008, 2010-2013 Albert Astals Cid <aacid@kde.org>
18 // Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
19 // Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
20 // Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com>
21 // Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
22 // Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@kabelmail.de>
23 // Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
24 // Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
26 // To see a description of the changes please see the Changelog file that
27 // came with your tarball or type make ChangeLog if you are building from git
29 //========================================================================
34 #ifdef USE_GCC_PRAGMAS
38 #include "poppler-config.h"
39 #include "goo/gtypes.h"
40 #include "goo/GooMutex.h"
51 //------------------------------------------------------------------------
53 //------------------------------------------------------------------------
57 xrefEntryUncompressed
,
67 Object obj
; //if this entry was updated, obj will contains the updated object
71 Updated
, // Entry was modified
73 // Special flags -- available only after xref->scanSpecialFlags() is run
74 Unencrypted
, // Entry is stored in unencrypted form (meaningless in unencrypted documents)
75 DontRewrite
// Entry must not be written back in case of full rewrite
78 inline GBool
getFlag(Flag flag
) {
79 const int mask
= (1 << (int)flag
);
80 return (flags
& mask
) != 0;
83 inline void setFlag(Flag flag
, GBool value
) {
84 const int mask
= (1 << (int)flag
);
96 // Constructor, create an empty XRef, used for PDF writing
98 // Constructor, create an empty XRef but with info dict, used for PDF writing
99 XRef(Object
*trailerDictA
);
100 // Constructor. Read xref table from stream.
101 XRef(BaseStream
*strA
, Goffset pos
, Goffset mainXRefEntriesOffsetA
= 0, GBool
*wasReconstructed
= NULL
, GBool reconstruct
= false);
106 // Copy xref but with new base stream!
109 // Is xref table valid?
110 GBool
isOk() { return ok
; }
112 // Is the last XRef section a stream or a table?
113 GBool
isXRefStream() { return xRefStream
; }
115 // Get the error code (if isOk() returns false).
116 int getErrorCode() { return errCode
; }
118 // Set the encryption parameters.
119 void setEncryption(int permFlagsA
, GBool ownerPasswordOkA
,
120 Guchar
*fileKeyA
, int keyLengthA
,
121 int encVersionA
, int encRevisionA
,
122 CryptAlgorithm encAlgorithmA
);
123 // Mark Encrypt entry as Unencrypted
124 void markUnencrypted();
126 void getEncryptionParameters(Guchar
**fileKeyA
, CryptAlgorithm
*encAlgorithmA
, int *keyLengthA
);
128 // Is the file encrypted?
129 GBool
isEncrypted() { return encrypted
; }
131 // Check various permissions.
132 GBool
okToPrint(GBool ignoreOwnerPW
= gFalse
);
133 GBool
okToPrintHighRes(GBool ignoreOwnerPW
= gFalse
);
134 GBool
okToChange(GBool ignoreOwnerPW
= gFalse
);
135 GBool
okToCopy(GBool ignoreOwnerPW
= gFalse
);
136 GBool
okToAddNotes(GBool ignoreOwnerPW
= gFalse
);
137 GBool
okToFillForm(GBool ignoreOwnerPW
= gFalse
);
138 GBool
okToAccessibility(GBool ignoreOwnerPW
= gFalse
);
139 GBool
okToAssemble(GBool ignoreOwnerPW
= gFalse
);
140 int getPermFlags() { return permFlags
; }
142 // Get catalog object.
143 Object
*getCatalog(Object
*obj
);
145 // Fetch an indirect reference.
146 Object
*fetch(int num
, int gen
, Object
*obj
, int recursion
= 0);
148 // Return the document's Info dictionary (if any).
149 Object
*getDocInfo(Object
*obj
);
150 Object
*getDocInfoNF(Object
*obj
);
152 // Return the number of objects in the xref table.
153 int getNumObjects() { return size
; }
155 // Return the catalog object reference.
156 int getRootNum() { return rootNum
; }
157 int getRootGen() { return rootGen
; }
159 // Get end position for a stream in a damaged file.
160 // Returns false if unknown or file is not damaged.
161 GBool
getStreamEnd(Goffset streamStart
, Goffset
*streamEnd
);
163 // Retuns the entry that belongs to the offset
164 int getNumEntry(Goffset offset
);
166 // Scans the document and sets special flags in all xref entries. One of those
167 // flags is Unencrypted, which affects how the object is fetched. Therefore,
168 // this function must be called before fetching unencrypted objects (e.g.
169 // Encrypt dictionary, XRef streams). Note that the code that initializes
170 // decryption doesn't need to call this function, because it runs before
171 // decryption is enabled, and therefore the Unencrypted flag is ignored.
172 void scanSpecialFlags();
175 XRefEntry
*getEntry(int i
, GBool complainIfMissing
= gTrue
);
176 Object
*getTrailerDict() { return &trailerDict
; }
179 void setModifiedObject(Object
* o
, Ref r
);
180 Ref
addIndirectObject (Object
* o
);
181 void removeIndirectObject(Ref r
);
182 void add(int num
, int gen
, Goffset offs
, GBool used
);
184 // Output XRef table to stream
185 void writeTableToFile(OutStream
* outStr
, GBool writeAllEntries
);
186 // Output XRef stream contents to GooString and fill trailerDict fields accordingly
187 void writeStreamToBuffer(GooString
*stmBuf
, Dict
*xrefDict
, XRef
*xref
);
189 // to be thread safe during write where changes are not allowed
195 BaseStream
*str
; // input stream
196 Goffset start
; // offset in file (to allow for garbage
197 // at beginning of file)
198 XRefEntry
*entries
; // xref entries
199 int capacity
; // size of <entries> array
200 int size
; // number of entries
201 int rootNum
, rootGen
; // catalog dict
202 GBool ok
; // true if xref table is valid
203 int errCode
; // error code (if <ok> is false)
204 Object trailerDict
; // trailer dictionary
205 Goffset
*streamEnds
; // 'endstream' positions - only used in
207 int streamEndsLen
; // number of valid entries in streamEnds
208 PopplerCache
*objStrs
; // cached object streams
209 GBool encrypted
; // true if file is encrypted
211 int encVersion
; // encryption algorithm
212 CryptAlgorithm encAlgorithm
; // encryption algorithm
213 int keyLength
; // length of key, in bytes
214 int permFlags
; // permission bits
215 Guchar fileKey
[32]; // file decryption key
216 GBool ownerPasswordOk
; // true if owner password is correct
217 Goffset prevXRefOffset
; // position of prev XRef section (= next to read)
218 Goffset mainXRefEntriesOffset
; // offset of entries in main XRef table
219 GBool xRefStream
; // true if last XRef section is a stream
220 Goffset mainXRefOffset
; // position of the main XRef table/stream
221 GBool scannedSpecialFlags
; // true if scanSpecialFlags has been called
222 GBool strOwner
; // true if str is owned by the instance
228 int reserve(int newSize
);
229 int resize(int newSize
);
230 GBool
readXRef(Goffset
*pos
, std::vector
<Goffset
> *followedXRefStm
, std::vector
<int> *xrefStreamObjsNum
);
231 GBool
readXRefTable(Parser
*parser
, Goffset
*pos
, std::vector
<Goffset
> *followedXRefStm
, std::vector
<int> *xrefStreamObjsNum
);
232 GBool
readXRefStreamSection(Stream
*xrefStr
, int *w
, int first
, int n
);
233 GBool
readXRefStream(Stream
*xrefStr
, Goffset
*pos
);
234 GBool
constructXRef(GBool
*wasReconstructed
, GBool needCatalogDict
= gFalse
);
235 GBool
parseEntry(Goffset offset
, XRefEntry
*entry
);
236 void readXRefUntil(int untilEntryNum
, std::vector
<int> *xrefStreamObjsNum
= NULL
);
237 void markUnencrypted(Object
*obj
);
241 virtual void startSection(int first
, int count
) = 0;
242 virtual void writeEntry(Goffset offset
, int gen
, XRefEntryType type
) = 0;
243 virtual ~XRefWriter() {};
246 // XRefWriter subclass that writes a XRef table
247 class XRefTableWriter
: public XRefWriter
{
249 XRefTableWriter(OutStream
* outStrA
);
250 void startSection(int first
, int count
);
251 void writeEntry(Goffset offset
, int gen
, XRefEntryType type
);
256 // XRefWriter subclass that writes a XRef stream
257 class XRefStreamWriter
: public XRefWriter
{
259 XRefStreamWriter(Object
*index
, GooString
*stmBuf
, int offsetSize
);
260 void startSection(int first
, int count
);
261 void writeEntry(Goffset offset
, int gen
, XRefEntryType type
);
268 // Dummy XRefWriter subclass that only checks if all offsets fit in 4 bytes
269 class XRefPreScanWriter
: public XRefWriter
{
272 void startSection(int first
, int count
);
273 void writeEntry(Goffset offset
, int gen
, XRefEntryType type
);
275 GBool hasOffsetsBeyond4GB
;
278 void writeXRef(XRefWriter
*writer
, GBool writeAllEntries
);