]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/PDFDoc.cc
Clean some redundant code.
[evince.git] / pdf / xpdf / PDFDoc.cc
index 1537c6a32272da6f3dc87194751d9962619e8fda..06b1cd7926f3e5f5fb64bae980544862a5e691d0 100644 (file)
@@ -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"
 #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;
 }