1 //========================================================================
5 // Copyright 1996-2002 Glyph & Cog, LLC
7 //========================================================================
10 #pragma implementation
25 #include "OutputDev.h"
27 #include "ErrorCodes.h"
32 //------------------------------------------------------------------------
34 #define headerSearchSize 1024 // read this many bytes at beginning of
35 // file to look for '%PDF'
37 //------------------------------------------------------------------------
39 //------------------------------------------------------------------------
41 PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
42 GString *userPassword, GBool printCommandsA) {
54 printCommands = printCommandsA;
60 if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
61 error(-1, "Couldn't open file '%s'", fileName->getCString());
62 errCode = errOpenFile;
66 if (!(file = fopen(fileName->getCString(), "rb"))) {
67 fileName2 = fileName->copy();
68 fileName2->lowerCase();
69 if (!(file = fopen(fileName2->getCString(), "rb"))) {
70 fileName2->upperCase();
71 if (!(file = fopen(fileName2->getCString(), "rb"))) {
72 error(-1, "Couldn't open file '%s'", fileName->getCString());
74 errCode = errOpenFile;
84 str = new FileStream(file, 0, gFalse, 0, &obj);
86 ok = setup(ownerPassword, userPassword);
89 PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
90 GString *userPassword, GBool printCommandsA) {
99 printCommands = printCommandsA;
100 ok = setup(ownerPassword, userPassword);
103 GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
108 xref = new XRef(str, ownerPassword, userPassword);
110 error(-1, "Couldn't read xref table");
111 errCode = xref->getErrorCode();
116 catalog = new Catalog(xref, printCommands);
117 if (!catalog->isOk()) {
118 error(-1, "Couldn't read page catalog");
119 errCode = errBadCatalog;
148 // Check for a PDF header on this stream. Skip past some garbage
150 void PDFDoc::checkHeader() {
151 char hdrBuf[headerSearchSize+1];
156 for (i = 0; i < headerSearchSize; ++i) {
157 hdrBuf[i] = str->getChar();
159 hdrBuf[headerSearchSize] = '\0';
160 for (i = 0; i < headerSearchSize - 5; ++i) {
161 if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
165 if (i >= headerSearchSize - 5) {
166 error(-1, "May not be a PDF file (continuing anyway)");
170 p = strtok(&hdrBuf[i+5], " \t\n\r");
171 pdfVersion = atof(p);
172 if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
173 pdfVersion > supportedPDFVersionNum + 0.0001) {
174 error(-1, "PDF version %s -- xpdf supports version %s"
175 " (continuing anyway)", p, supportedPDFVersionStr);
179 void PDFDoc::displayPage(OutputDev *out, int page, double zoom,
180 int rotate, GBool doLinks) {
184 printf("***** page %d *****\n", page);
186 p = catalog->getPage(page);
192 p->display(out, zoom, rotate, links, catalog);
194 p->display(out, zoom, rotate, NULL, catalog);
198 void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
199 int zoom, int rotate, GBool doLinks) {
202 for (page = firstPage; page <= lastPage; ++page) {
203 displayPage(out, page, zoom, rotate, doLinks);
207 GBool PDFDoc::isLinearized() {
209 Object obj1, obj2, obj3, obj4, obj5;
214 parser = new Parser(xref,
216 str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
217 parser->getObj(&obj1);
218 parser->getObj(&obj2);
219 parser->getObj(&obj3);
220 parser->getObj(&obj4);
221 if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
223 obj4.dictLookup("Linearized", &obj5);
224 if (obj5.isNum() && obj5.getNum() > 0) {
237 GBool PDFDoc::saveAs(GString *name) {
241 if (!(f = fopen(name->getCString(), "wb"))) {
242 error(-1, "Couldn't open file '%s'", name->getCString());
246 while ((c = str->getChar()) != EOF) {
254 void PDFDoc::getLinks(Page *page) {
257 links = new Links(page->getAnnots(&obj), catalog->getBaseURI());