Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

PDFDoc.cc

Go to the documentation of this file.
00001 //========================================================================
00002 //
00003 // PDFDoc.cc
00004 //
00005 // Copyright 1996-2002 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #ifdef __GNUC__
00010 #pragma implementation
00011 #endif
00012 
00013 #include <aconf.h>
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <stddef.h>
00017 #include <string.h>
00018 #include "GString.h"
00019 #include "config.h"
00020 #include "Page.h"
00021 #include "Catalog.h"
00022 #include "Stream.h"
00023 #include "XRef.h"
00024 #include "Link.h"
00025 #include "OutputDev.h"
00026 #include "Error.h"
00027 #include "ErrorCodes.h"
00028 #include "Lexer.h"
00029 #include "Parser.h"
00030 #include "PDFDoc.h"
00031 
00032 //------------------------------------------------------------------------
00033 
00034 #define headerSearchSize 1024   // read this many bytes at beginning of
00035                                 //   file to look for '%PDF'
00036 
00037 //------------------------------------------------------------------------
00038 // PDFDoc
00039 //------------------------------------------------------------------------
00040 
00041 PDFDoc::PDFDoc(GString *fileNameA, GString *ownerPassword,
00042                GString *userPassword, GBool printCommandsA) {
00043   Object obj;
00044   GString *fileName2;
00045 
00046   ok = gFalse;
00047   errCode = errNone;
00048 
00049   file = NULL;
00050   str = NULL;
00051   xref = NULL;
00052   catalog = NULL;
00053   links = NULL;
00054   printCommands = printCommandsA;
00055 
00056   // try to open file
00057   fileName = fileNameA;
00058   fileName2 = NULL;
00059 #ifdef VMS
00060   if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) {
00061     error(-1, "Couldn't open file '%s'", fileName->getCString());
00062     errCode = errOpenFile;
00063     return;
00064   }
00065 #else
00066   if (!(file = fopen(fileName->getCString(), "rb"))) {
00067     fileName2 = fileName->copy();
00068     fileName2->lowerCase();
00069     if (!(file = fopen(fileName2->getCString(), "rb"))) {
00070       fileName2->upperCase();
00071       if (!(file = fopen(fileName2->getCString(), "rb"))) {
00072         error(-1, "Couldn't open file '%s'", fileName->getCString());
00073         delete fileName2;
00074         errCode = errOpenFile;
00075         return;
00076       }
00077     }
00078     delete fileName2;
00079   }
00080 #endif
00081 
00082   // create stream
00083   obj.initNull();
00084   str = new FileStream(file, 0, gFalse, 0, &obj);
00085 
00086   ok = setup(ownerPassword, userPassword);
00087 }
00088 
00089 PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword,
00090                GString *userPassword, GBool printCommandsA) {
00091   ok = gFalse;
00092   errCode = errNone;
00093   fileName = NULL;
00094   file = NULL;
00095   str = strA;
00096   xref = NULL;
00097   catalog = NULL;
00098   links = NULL;
00099   printCommands = printCommandsA;
00100   ok = setup(ownerPassword, userPassword);
00101 }
00102 
00103 GBool PDFDoc::setup(GString *ownerPassword, GString *userPassword) {
00104   // check header
00105   checkHeader();
00106 
00107   // read xref table
00108   xref = new XRef(str, ownerPassword, userPassword);
00109   if (!xref->isOk()) {
00110     error(-1, "Couldn't read xref table");
00111     errCode = xref->getErrorCode();
00112     return gFalse;
00113   }
00114 
00115   // read catalog
00116   catalog = new Catalog(xref, printCommands);
00117   if (!catalog->isOk()) {
00118     error(-1, "Couldn't read page catalog");
00119     errCode = errBadCatalog;
00120     return gFalse;
00121   }
00122 
00123   // done
00124   return gTrue;
00125 }
00126 
00127 PDFDoc::~PDFDoc() {
00128   if (catalog) {
00129     delete catalog;
00130   }
00131   if (xref) {
00132     delete xref;
00133   }
00134   if (str) {
00135     delete str;
00136   }
00137   if (file) {
00138     fclose(file);
00139   }
00140   if (fileName) {
00141     delete fileName;
00142   }
00143   if (links) {
00144     delete links;
00145   }
00146 }
00147 
00148 // Check for a PDF header on this stream.  Skip past some garbage
00149 // if necessary.
00150 void PDFDoc::checkHeader() {
00151   char hdrBuf[headerSearchSize+1];
00152   char *p;
00153   int i;
00154 
00155   pdfVersion = 0;
00156   for (i = 0; i < headerSearchSize; ++i) {
00157     hdrBuf[i] = str->getChar();
00158   }
00159   hdrBuf[headerSearchSize] = '\0';
00160   for (i = 0; i < headerSearchSize - 5; ++i) {
00161     if (!strncmp(&hdrBuf[i], "%PDF-", 5)) {
00162       break;
00163     }
00164   }
00165   if (i >= headerSearchSize - 5) {
00166     error(-1, "May not be a PDF file (continuing anyway)");
00167     return;
00168   }
00169   str->moveStart(i);
00170   p = strtok(&hdrBuf[i+5], " \t\n\r");
00171   pdfVersion = atof(p);
00172   if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') ||
00173       pdfVersion > supportedPDFVersionNum + 0.0001) {
00174     error(-1, "PDF version %s -- xpdf supports version %s"
00175           " (continuing anyway)", p, supportedPDFVersionStr);
00176   }
00177 }
00178 
00179 void PDFDoc::displayPage(OutputDev *out, int page, fouble zoom,
00180                          int rotate, GBool doLinks) {
00181   Page *p;
00182 
00183   if (printCommands) {
00184     printf("***** page %d *****\n", page);
00185   }
00186   p = catalog->getPage(page);
00187   if (doLinks) {
00188     if (links) {
00189       delete links;
00190     }
00191     getLinks(p);
00192     p->display(out, zoom, rotate, links, catalog);
00193   } else {
00194     p->display(out, zoom, rotate, NULL, catalog);
00195   }
00196 }
00197 
00198 void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage,
00199                           int zoom, int rotate, GBool doLinks) {
00200   int page;
00201 
00202   for (page = firstPage; page <= lastPage; ++page) {
00203     displayPage(out, page, zoom, rotate, doLinks);
00204   }
00205 }
00206 
00207 GBool PDFDoc::isLinearized() {
00208   Parser *parser;
00209   Object obj1, obj2, obj3, obj4, obj5;
00210   GBool lin;
00211 
00212   lin = gFalse;
00213   obj1.initNull();
00214   parser = new Parser(xref,
00215              new Lexer(xref,
00216                str->makeSubStream(str->getStart(), gFalse, 0, &obj1)));
00217   parser->getObj(&obj1);
00218   parser->getObj(&obj2);
00219   parser->getObj(&obj3);
00220   parser->getObj(&obj4);
00221   if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") &&
00222       obj4.isDict()) {
00223     obj4.dictLookup("Linearized", &obj5);
00224     if (obj5.isNum() && obj5.getNum() > 0) {
00225       lin = gTrue;
00226     }
00227     obj5.free();
00228   }
00229   obj4.free();
00230   obj3.free();
00231   obj2.free();
00232   obj1.free();
00233   delete parser;
00234   return lin;
00235 }
00236 
00237 GBool PDFDoc::saveAs(GString *name) {
00238   FILE *f;
00239   int c;
00240 
00241   if (!(f = fopen(name->getCString(), "wb"))) {
00242     error(-1, "Couldn't open file '%s'", name->getCString());
00243     return gFalse;
00244   }
00245   str->reset();
00246   while ((c = str->getChar()) != EOF) {
00247     fputc(c, f);
00248   }
00249   str->close();
00250   fclose(f);
00251   return gTrue;
00252 }
00253 
00254 void PDFDoc::getLinks(Page *page) {
00255   Object obj;
00256 
00257   links = new Links(page->getAnnots(&obj), catalog->getBaseURI());
00258   obj.free();
00259 }

Generated on Sat Nov 5 16:18:16 2005 for OPIE by  doxygen 1.4.2