00001
00002
00003
00004
00005
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
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
00096 globalParams = new GlobalParams(cfgFileName);
00097 if (textEncName[0]) {
00098 globalParams->setTextEncoding(textEncName);
00099 }
00100
00101
00102 if (!(uMap = globalParams->getTextEncoding())) {
00103 error(-1, "Couldn't get text encoding");
00104 delete fileName;
00105 goto err1;
00106 }
00107
00108
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
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
00146 printf("Tagged: %s\n",
00147 doc->getStructTreeRoot()->isDict() ? "yes" : "no");
00148
00149
00150 printf("Pages: %d\n", doc->getNumPages());
00151
00152
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
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
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
00200 printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
00201
00202
00203 printf("PDF version: %.1f\n", doc->getPDFVersion());
00204
00205
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
00216 err2:
00217 uMap->decRefCnt();
00218 delete doc;
00219 err1:
00220 delete globalParams;
00221 err0:
00222
00223
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
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 }