X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=pdf%2Fxpdf%2FPDFDoc.cc;h=06b1cd7926f3e5f5fb64bae980544862a5e691d0;hb=97e4ebaf0f2ac8e8f2bb43d12b017861fae5dfc6;hp=1537c6a32272da6f3dc87194751d9962619e8fda;hpb=50e9d31c05e9ca11ad43cc570556094782c1b956;p=evince.git diff --git a/pdf/xpdf/PDFDoc.cc b/pdf/xpdf/PDFDoc.cc index 1537c6a3..06b1cd79 100644 --- a/pdf/xpdf/PDFDoc.cc +++ b/pdf/xpdf/PDFDoc.cc @@ -18,6 +18,7 @@ #include "config.h" #include "Page.h" #include "Catalog.h" +#include "Stream.h" #include "XRef.h" #include "Link.h" #include "OutputDev.h" @@ -25,22 +26,23 @@ #include "Error.h" #include "PDFDoc.h" +//------------------------------------------------------------------------ + +#define headerSearchSize 1024 // read this many bytes at beginning of + // file to look for '%PDF' + //------------------------------------------------------------------------ // PDFDoc //------------------------------------------------------------------------ PDFDoc::PDFDoc(GString *fileName1) { - FileStream *str; - Object catObj; Object obj; GString *fileName2; - // setup ok = gFalse; - catalog = NULL; - xref = NULL; + file = NULL; - links = NULL; + str = NULL; // try to open file fileName = fileName1; @@ -70,15 +72,32 @@ PDFDoc::PDFDoc(GString *fileName1) { obj.initNull(); str = new FileStream(file, 0, -1, &obj); + ok = setup(); +} + +PDFDoc::PDFDoc(BaseStream *str) { + ok = gFalse; + fileName = NULL; + file = NULL; + this->str = str; + ok = setup(); +} + +GBool PDFDoc::setup() { + Object catObj; + + xref = NULL; + catalog = NULL; + links = NULL; + // check header - str->checkHeader(); + checkHeader(); // read xref table xref = new XRef(str); - delete str; if (!xref->isOk()) { error(-1, "Couldn't read xref table"); - return; + return gFalse; } // read catalog @@ -86,25 +105,63 @@ PDFDoc::PDFDoc(GString *fileName1) { catObj.free(); if (!catalog->isOk()) { error(-1, "Couldn't read page catalog"); - return; + return gFalse; } // done - ok = gTrue; - return; + return gTrue; } PDFDoc::~PDFDoc() { - if (catalog) + if (catalog) { delete catalog; - if (xref) + } + if (xref) { delete xref; - if (file) + } + if (str) { + delete str; + } + if (file) { fclose(file); - if (fileName) + } + if (fileName) { delete fileName; - if (links) + } + if (links) { delete links; + } +} + +// Check for a PDF header on this stream. Skip past some garbage +// if necessary. +void PDFDoc::checkHeader() { + char hdrBuf[headerSearchSize+1]; + char *p; + double version; + int i; + + for (i = 0; i < headerSearchSize; ++i) { + hdrBuf[i] = str->getChar(); + } + hdrBuf[headerSearchSize] = '\0'; + for (i = 0; i < headerSearchSize - 5; ++i) { + if (!strncmp(&hdrBuf[i], "%PDF-", 5)) { + break; + } + } + if (i >= headerSearchSize - 5) { + error(-1, "May not be a PDF file (continuing anyway)"); + return; + } + str->moveStart(i); + p = strtok(&hdrBuf[i+5], " \t\n\r"); + version = atof(p); + if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') || + version > pdfVersionNum + 0.0001) { + error(-1, "PDF version %s -- xpdf supports version %s" + " (continuing anyway)", p, pdfVersion); + } } void PDFDoc::displayPage(OutputDev *out, int page, int zoom, int rotate, @@ -146,16 +203,16 @@ void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, GBool PDFDoc::saveAs(GString *name) { FILE *f; - char buf[4096]; - int n; + int c; if (!(f = fopen(name->getCString(), "wb"))) { error(-1, "Couldn't open file '%s'", name->getCString()); return gFalse; } - rewind(file); - while ((n = fread(buf, 1, sizeof(buf), file)) > 0) - fwrite(buf, 1, n, f); + str->reset(); + while ((c = str->getChar()) != EOF) { + fputc(c, f); + } fclose(f); return gTrue; }