1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
21 #include "GlobalParams.h"
27 #include "OutputDev.h"
29 #include "ErrorCodes.h"
32 #ifndef DISABLE_OUTLINE
37 //------------------------------------------------------------------------
39 #define headerSearchSize 1024 // read this many bytes at beginning of
40 // file to look for '%PDF'
42 //------------------------------------------------------------------------
44 //------------------------------------------------------------------------
46 PDFDoc::PDFDoc(GString
*fileNameA
, GString
*ownerPassword
,
47 GString
*userPassword
) {
49 GString
*fileName1
, *fileName2
;
59 #ifndef DISABLE_OUTLINE
70 if (!(file
= fopen(fileName1
->getCString(), "rb", "ctx=stm"))) {
71 error(-1, "Couldn't open file '%s'", fileName1
->getCString());
72 errCode
= errOpenFile
;
76 if (!(file
= fopen(fileName1
->getCString(), "rb"))) {
77 fileName2
= fileName
->copy();
78 fileName2
->lowerCase();
79 if (!(file
= fopen(fileName2
->getCString(), "rb"))) {
80 fileName2
->upperCase();
81 if (!(file
= fopen(fileName2
->getCString(), "rb"))) {
82 error(-1, "Couldn't open file '%s'", fileName
->getCString());
84 errCode
= errOpenFile
;
94 str
= new FileStream(file
, 0, gFalse
, 0, &obj
);
96 ok
= setup(ownerPassword
, userPassword
);
99 PDFDoc::PDFDoc(BaseStream
*strA
, GString
*ownerPassword
,
100 GString
*userPassword
) {
109 #ifndef DISABLE_OUTLINE
112 ok
= setup(ownerPassword
, userPassword
);
115 GBool
PDFDoc::setup(GString
*ownerPassword
, GString
*userPassword
) {
122 xref
= new XRef(str
, ownerPassword
, userPassword
);
124 error(-1, "Couldn't read xref table");
125 errCode
= xref
->getErrorCode();
130 catalog
= new Catalog(xref
);
131 if (!catalog
->isOk()) {
132 error(-1, "Couldn't read page catalog");
133 errCode
= errBadCatalog
;
137 #ifndef DISABLE_OUTLINE
139 outline
= new Outline(catalog
->getOutline(), xref
);
147 #ifndef DISABLE_OUTLINE
172 // Check for a PDF header on this stream. Skip past some garbage
174 void PDFDoc::checkHeader() {
175 char hdrBuf
[headerSearchSize
+1];
180 for (i
= 0; i
< headerSearchSize
; ++i
) {
181 hdrBuf
[i
] = str
->getChar();
183 hdrBuf
[headerSearchSize
] = '\0';
184 for (i
= 0; i
< headerSearchSize
- 5; ++i
) {
185 if (!strncmp(&hdrBuf
[i
], "%PDF-", 5)) {
189 if (i
>= headerSearchSize
- 5) {
190 error(-1, "May not be a PDF file (continuing anyway)");
194 p
= strtok(&hdrBuf
[i
+5], " \t\n\r");
195 pdfVersion
= atof(p
);
196 if (!(hdrBuf
[i
+5] >= '0' && hdrBuf
[i
+5] <= '9') ||
197 pdfVersion
> supportedPDFVersionNum
+ 0.0001) {
198 error(-1, "PDF version %s -- xpdf supports version %s"
199 " (continuing anyway)", p
, supportedPDFVersionStr
);
203 void PDFDoc::displayPage(OutputDev
*out
, int page
, double hDPI
, double vDPI
,
204 int rotate
, GBool crop
, GBool doLinks
,
205 GBool (*abortCheckCbk
)(void *data
),
206 void *abortCheckCbkData
) {
209 if (globalParams
->getPrintCommands()) {
210 printf("***** page %d *****\n", page
);
212 p
= catalog
->getPage(page
);
218 p
->display(out
, hDPI
, vDPI
, rotate
, crop
, links
, catalog
,
219 abortCheckCbk
, abortCheckCbkData
);
221 p
->display(out
, hDPI
, vDPI
, rotate
, crop
, NULL
, catalog
,
222 abortCheckCbk
, abortCheckCbkData
);
226 void PDFDoc::displayPages(OutputDev
*out
, int firstPage
, int lastPage
,
227 double hDPI
, double vDPI
, int rotate
,
228 GBool crop
, GBool doLinks
,
229 GBool (*abortCheckCbk
)(void *data
),
230 void *abortCheckCbkData
) {
233 for (page
= firstPage
; page
<= lastPage
; ++page
) {
234 displayPage(out
, page
, hDPI
, vDPI
, rotate
, crop
, doLinks
,
235 abortCheckCbk
, abortCheckCbkData
);
239 void PDFDoc::displayPageSlice(OutputDev
*out
, int page
,
240 double hDPI
, double vDPI
,
241 int rotate
, GBool crop
,
242 int sliceX
, int sliceY
, int sliceW
, int sliceH
,
243 GBool (*abortCheckCbk
)(void *data
),
244 void *abortCheckCbkData
) {
247 p
= catalog
->getPage(page
);
248 p
->displaySlice(out
, hDPI
, vDPI
, rotate
, crop
,
249 sliceX
, sliceY
, sliceW
, sliceH
,
250 NULL
, catalog
, abortCheckCbk
, abortCheckCbkData
);
253 GBool
PDFDoc::isLinearized() {
255 Object obj1
, obj2
, obj3
, obj4
, obj5
;
260 parser
= new Parser(xref
,
262 str
->makeSubStream(str
->getStart(), gFalse
, 0, &obj1
)));
263 parser
->getObj(&obj1
);
264 parser
->getObj(&obj2
);
265 parser
->getObj(&obj3
);
266 parser
->getObj(&obj4
);
267 if (obj1
.isInt() && obj2
.isInt() && obj3
.isCmd("obj") &&
269 obj4
.dictLookup("Linearized", &obj5
);
270 if (obj5
.isNum() && obj5
.getNum() > 0) {
283 GBool
PDFDoc::saveAs(GString
*name
) {
287 if (!(f
= fopen(name
->getCString(), "wb"))) {
288 error(-1, "Couldn't open file '%s'", name
->getCString());
292 while ((c
= str
->getChar()) != EOF
) {
300 void PDFDoc::getLinks(Page
*page
) {
303 links
= new Links(page
->getAnnots(&obj
), catalog
->getBaseURI());