filters

pdfinfo.cc

00001 //========================================================================
00002 //
00003 // pdfinfo.cc
00004 //
00005 // Copyright 1998-2002 Glyph & Cog, LLC
00006 //
00007 //========================================================================
00008 
00009 #include <aconf.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <stddef.h>
00013 #include <string.h>
00014 #include <time.h>
00015 #include <math.h>
00016 #include "parseargs.h"
00017 #include "GString.h"
00018 #include "gmem.h"
00019 #include "GlobalParams.h"
00020 #include "Object.h"
00021 #include "Stream.h"
00022 #include "Array.h"
00023 #include "Dict.h"
00024 #include "XRef.h"
00025 #include "Catalog.h"
00026 #include "Page.h"
00027 #include "PDFDoc.h"
00028 #include "CharTypes.h"
00029 #include "UnicodeMap.h"
00030 #include "Error.h"
00031 #include "config.h"
00032 
00033 static void printInfoString(Dict *infoDict, char *key, char *text,
00034                 UnicodeMap *uMap);
00035 static void printInfoDate(Dict *infoDict, char *key, char *text);
00036 
00037 static GBool printMetadata = gFalse;
00038 static char textEncName[128] = "";
00039 static char ownerPassword[33] = "";
00040 static char userPassword[33] = "";
00041 static char cfgFileName[256] = "";
00042 static GBool printVersion = gFalse;
00043 static GBool printHelp = gFalse;
00044 
00045 static ArgDesc argDesc[] = {
00046   {"-meta",   argFlag,     &printMetadata,    0,
00047    "print the document metadata (XML)"},
00048   {"-enc",    argString,   textEncName,    sizeof(textEncName),
00049    "output text encoding name"},
00050   {"-opw",    argString,   ownerPassword,  sizeof(ownerPassword),
00051    "owner password (for encrypted files)"},
00052   {"-upw",    argString,   userPassword,   sizeof(userPassword),
00053    "user password (for encrypted files)"},
00054   {"-cfg",        argString,      cfgFileName,    sizeof(cfgFileName),
00055    "configuration file to use in place of .xpdfrc"},
00056   {"-v",      argFlag,     &printVersion,  0,
00057    "print copyright and version info"},
00058   {"-h",      argFlag,     &printHelp,     0,
00059    "print usage information"},
00060   {"-help",   argFlag,     &printHelp,     0,
00061    "print usage information"},
00062   {"--help",  argFlag,     &printHelp,     0,
00063    "print usage information"},
00064   {"-?",      argFlag,     &printHelp,     0,
00065    "print usage information"},
00066   {NULL}
00067 };
00068 
00069 int main(int argc, char *argv[]) {
00070   PDFDoc *doc;
00071   GString *fileName;
00072   GString *ownerPW, *userPW;
00073   UnicodeMap *uMap;
00074   Object info;
00075   double w, h;
00076   FILE *f;
00077   GString *metadata;
00078   GBool ok;
00079   int exitCode;
00080 
00081   exitCode = 99;
00082 
00083   // parse args
00084   ok = parseArgs(argDesc, &argc, argv);
00085   if (!ok || argc != 2 || printVersion || printHelp) {
00086     fprintf(stderr, "pdfinfo version %s\n", xpdfVersion);
00087     fprintf(stderr, "%s\n", xpdfCopyright);
00088     if (!printVersion) {
00089       printUsage("pdfinfo", "<PDF-file>", argDesc);
00090     }
00091     goto err0;
00092   }
00093   fileName = new GString(argv[1]);
00094 
00095   // read config file
00096   globalParams = new GlobalParams(cfgFileName);
00097   if (textEncName[0]) {
00098     globalParams->setTextEncoding(textEncName);
00099   }
00100 
00101   // get mapping to output encoding
00102   if (!(uMap = globalParams->getTextEncoding())) {
00103     error(-1, "Couldn't get text encoding");
00104     delete fileName;
00105     goto err1;
00106   }
00107 
00108   // open PDF file
00109   if (ownerPassword[0]) {
00110     ownerPW = new GString(ownerPassword);
00111   } else {
00112     ownerPW = NULL;
00113   }
00114   if (userPassword[0]) {
00115     userPW = new GString(userPassword);
00116   } else {
00117     userPW = NULL;
00118   }
00119   doc = new PDFDoc(fileName, ownerPW, userPW);
00120   if (userPW) {
00121     delete userPW;
00122   }
00123   if (ownerPW) {
00124     delete ownerPW;
00125   }
00126   if (!doc->isOk()) {
00127     exitCode = 1;
00128     goto err2;
00129   }
00130 
00131   // print doc info
00132   doc->getDocInfo(&info);
00133   if (info.isDict()) {
00134     printInfoString(info.getDict(), "Title",        "Title:        ", uMap);
00135     printInfoString(info.getDict(), "Subject",      "Subject:      ", uMap);
00136     printInfoString(info.getDict(), "Keywords",     "Keywords:     ", uMap);
00137     printInfoString(info.getDict(), "Author",       "Author:       ", uMap);
00138     printInfoString(info.getDict(), "Creator",      "Creator:      ", uMap);
00139     printInfoString(info.getDict(), "Producer",     "Producer:     ", uMap);
00140     printInfoDate(info.getDict(),   "CreationDate", "CreationDate: ");
00141     printInfoDate(info.getDict(),   "ModDate",      "ModDate:      ");
00142   }
00143   info.free();
00144 
00145   // print tagging info
00146   printf("Tagged:       %s\n",
00147      doc->getStructTreeRoot()->isDict() ? "yes" : "no");
00148 
00149   // print page count
00150   printf("Pages:        %d\n", doc->getNumPages());
00151 
00152   // print encryption info
00153   printf("Encrypted:    ");
00154   if (doc->isEncrypted()) {
00155     printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
00156        doc->okToPrint(gTrue) ? "yes" : "no",
00157        doc->okToCopy(gTrue) ? "yes" : "no",
00158        doc->okToChange(gTrue) ? "yes" : "no",
00159        doc->okToAddNotes(gTrue) ? "yes" : "no");
00160   } else {
00161     printf("no\n");
00162   }
00163 
00164   // print page size
00165   if (doc->getNumPages() >= 1) {
00166     w = doc->getPageWidth(1);
00167     h = doc->getPageHeight(1);
00168     printf("Page size:    %g x %g pts", w, h);
00169     if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
00170     (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) {
00171       printf(" (letter)");
00172     } else if ((fabs(w - 595) < 0.1 && fabs(h - 842) < 0.1) ||
00173            (fabs(w - 842) < 0.1 && fabs(h - 595) < 0.1)) {
00174       printf(" (A4)");
00175     }
00176     printf("\n");
00177   }
00178 
00179   // print file size
00180 #ifdef VMS
00181   f = fopen(fileName->getCString(), "rb", "ctx=stm");
00182 #else
00183   f = fopen(fileName->getCString(), "rb");
00184 #endif
00185   if (f) {
00186 #ifdef HAVE_FSEEKO
00187     fseeko(f, 0, SEEK_END);
00188     printf("File size:    %u bytes\n", (Guint)ftello(f));
00189 #elif defined(HAVE_FSEEK64) && defined(HAVE_FTELL64)
00190     fseek64(f, 0, SEEK_END);
00191     printf("File size:    %u bytes\n", (Guint)ftell64(f));
00192 #else
00193     fseek(f, 0, SEEK_END);
00194     printf("File size:    %d bytes\n", (int)ftell(f));
00195 #endif
00196     fclose(f);
00197   }
00198 
00199   // print linearization info
00200   printf("Optimized:    %s\n", doc->isLinearized() ? "yes" : "no");
00201 
00202   // print PDF version
00203   printf("PDF version:  %.1f\n", doc->getPDFVersion());
00204 
00205   // print the metadata
00206   if (printMetadata && (metadata = doc->readMetadata())) {
00207     fputs("Metadata:\n", stdout);
00208     fputs(metadata->getCString(), stdout);
00209     fputc('\n', stdout);
00210     delete metadata;
00211   }
00212 
00213   exitCode = 0;
00214 
00215   // clean up
00216  err2:
00217   uMap->decRefCnt();
00218   delete doc;
00219  err1:
00220   delete globalParams;
00221  err0:
00222 
00223   // check for memory leaks
00224   Object::memCheck(stderr);
00225   gMemReport(stderr);
00226 
00227   return exitCode;
00228 }
00229 
00230 static void printInfoString(Dict *infoDict, char *key, char *text,
00231                 UnicodeMap *uMap) {
00232   Object obj;
00233   GString *s1;
00234   GBool isUnicode;
00235   Unicode u;
00236   char buf[8];
00237   int i, n;
00238 
00239   if (infoDict->lookup(key, &obj)->isString()) {
00240     fputs(text, stdout);
00241     s1 = obj.getString();
00242     if ((s1->getChar(0) & 0xff) == 0xfe &&
00243     (s1->getChar(1) & 0xff) == 0xff) {
00244       isUnicode = gTrue;
00245       i = 2;
00246     } else {
00247       isUnicode = gFalse;
00248       i = 0;
00249     }
00250     while (i < obj.getString()->getLength()) {
00251       if (isUnicode) {
00252     u = ((s1->getChar(i) & 0xff) << 8) |
00253         (s1->getChar(i+1) & 0xff);
00254     i += 2;
00255       } else {
00256     u = s1->getChar(i) & 0xff;
00257     ++i;
00258       }
00259       n = uMap->mapUnicode(u, buf, sizeof(buf));
00260       fwrite(buf, 1, n, stdout);
00261     }
00262     fputc('\n', stdout);
00263   }
00264   obj.free();
00265 }
00266 
00267 static void printInfoDate(Dict *infoDict, char *key, char *text) {
00268   Object obj;
00269   char *s;
00270   int year, mon, day, hour, min, sec;
00271   struct tm tmStruct;
00272   char buf[256];
00273 
00274   if (infoDict->lookup(key, &obj)->isString()) {
00275     fputs(text, stdout);
00276     s = obj.getString()->getCString();
00277     if (s[0] == 'D' && s[1] == ':') {
00278       s += 2;
00279     }
00280     if (sscanf(s, "%4d%2d%2d%2d%2d%2d",
00281            &year, &mon, &day, &hour, &min, &sec) == 6) {
00282       tmStruct.tm_year = year - 1900;
00283       tmStruct.tm_mon = mon - 1;
00284       tmStruct.tm_mday = day;
00285       tmStruct.tm_hour = hour;
00286       tmStruct.tm_min = min;
00287       tmStruct.tm_sec = sec;
00288       tmStruct.tm_wday = -1;
00289       tmStruct.tm_yday = -1;
00290       tmStruct.tm_isdst = -1;
00291       // compute the tm_wday and tm_yday fields
00292       if (mktime(&tmStruct) != (time_t)-1 &&
00293       strftime(buf, sizeof(buf), "%c", &tmStruct)) {
00294     fputs(buf, stdout);
00295       } else {
00296     fputs(s, stdout);
00297       }
00298     } else {
00299       fputs(s, stdout);
00300     }
00301     fputc('\n', stdout);
00302   }
00303   obj.free();
00304 }
KDE Home | KDE Accessibility Home | Description of Access Keys