1 //========================================================================
5 // Copyright 1998-2002 Glyph & Cog, LLC
7 //========================================================================
16 #include "parseargs.h"
19 #include "GlobalParams.h"
28 #include "CharTypes.h"
29 #include "UnicodeMap.h"
33 static void printInfoString(Dict *infoDict, char *key, char *text,
35 static void printInfoDate(Dict *infoDict, char *key, char *text);
37 static GBool printMetadata = gFalse;
38 static char textEncName[128] = "";
39 static char ownerPassword[33] = "";
40 static char userPassword[33] = "";
41 static char cfgFileName[256] = "";
42 static GBool printVersion = gFalse;
43 static GBool printHelp = gFalse;
45 static ArgDesc argDesc[] = {
46 {"-meta", argFlag, &printMetadata, 0,
47 "print the document metadata (XML)"},
48 {"-enc", argString, textEncName, sizeof(textEncName),
49 "output text encoding name"},
50 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
51 "owner password (for encrypted files)"},
52 {"-upw", argString, userPassword, sizeof(userPassword),
53 "user password (for encrypted files)"},
54 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
55 "configuration file to use in place of .xpdfrc"},
56 {"-v", argFlag, &printVersion, 0,
57 "print copyright and version info"},
58 {"-h", argFlag, &printHelp, 0,
59 "print usage information"},
60 {"-help", argFlag, &printHelp, 0,
61 "print usage information"},
62 {"--help", argFlag, &printHelp, 0,
63 "print usage information"},
64 {"-?", argFlag, &printHelp, 0,
65 "print usage information"},
69 int main(int argc, char *argv[]) {
72 GString *ownerPW, *userPW;
81 ok = parseArgs(argDesc, &argc, argv);
82 if (!ok || argc != 2 || printVersion || printHelp) {
83 fprintf(stderr, "pdfinfo version %s\n", xpdfVersion);
84 fprintf(stderr, "%s\n", xpdfCopyright);
86 printUsage("pdfinfo", "<PDF-file>", argDesc);
90 fileName = new GString(argv[1]);
93 globalParams = new GlobalParams(cfgFileName);
95 globalParams->setTextEncoding(textEncName);
98 // get mapping to output encoding
99 if (!(uMap = globalParams->getTextEncoding())) {
100 error(-1, "Couldn't get text encoding");
106 if (ownerPassword[0]) {
107 ownerPW = new GString(ownerPassword);
111 if (userPassword[0]) {
112 userPW = new GString(userPassword);
116 doc = new PDFDoc(fileName, ownerPW, userPW);
128 doc->getDocInfo(&info);
130 printInfoString(info.getDict(), "Title", "Title: ", uMap);
131 printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
132 printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
133 printInfoString(info.getDict(), "Author", "Author: ", uMap);
134 printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
135 printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
136 printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
137 printInfoDate(info.getDict(), "ModDate", "ModDate: ");
141 // print tagging info
142 printf("Tagged: %s\n",
143 doc->getStructTreeRoot()->isDict() ? "yes" : "no");
146 printf("Pages: %d\n", doc->getNumPages());
148 // print encryption info
149 printf("Encrypted: ");
150 if (doc->isEncrypted()) {
151 printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
152 doc->okToPrint(gTrue) ? "yes" : "no",
153 doc->okToCopy(gTrue) ? "yes" : "no",
154 doc->okToChange(gTrue) ? "yes" : "no",
155 doc->okToAddNotes(gTrue) ? "yes" : "no");
161 if (doc->getNumPages() >= 1) {
162 w = doc->getPageWidth(1);
163 h = doc->getPageHeight(1);
164 printf("Page size: %g x %g pts", w, h);
165 if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
166 (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) {
168 } else if ((fabs(w - 595) < 0.1 && fabs(h - 842) < 0.1) ||
169 (fabs(w - 842) < 0.1 && fabs(h - 595) < 0.1)) {
177 f = fopen(fileName->getCString(), "rb", "ctx=stm");
179 f = fopen(fileName->getCString(), "rb");
183 fseek64(f, 0, SEEK_END);
184 printf("File size: %u bytes\n", (Guint)ftell64(f));
186 fseek(f, 0, SEEK_END);
187 printf("File size: %d bytes\n", (int)ftell(f));
192 // print linearization info
193 printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
196 printf("PDF version: %.1f\n", doc->getPDFVersion());
198 // print the metadata
199 if (printMetadata && (metadata = doc->readMetadata())) {
200 fputs("Metadata:\n", stdout);
201 fputs(metadata->getCString(), stdout);
213 // check for memory leaks
214 Object::memCheck(stderr);
220 static void printInfoString(Dict *infoDict, char *key, char *text,
229 if (infoDict->lookup(key, &obj)->isString()) {
231 s1 = obj.getString();
232 if ((s1->getChar(0) & 0xff) == 0xfe &&
233 (s1->getChar(1) & 0xff) == 0xff) {
240 while (i < obj.getString()->getLength()) {
242 u = ((s1->getChar(i) & 0xff) << 8) |
243 (s1->getChar(i+1) & 0xff);
246 u = s1->getChar(i) & 0xff;
249 n = uMap->mapUnicode(u, buf, sizeof(buf));
250 fwrite(buf, 1, n, stdout);
257 static void printInfoDate(Dict *infoDict, char *key, char *text) {
260 int year, mon, day, hour, min, sec;
264 if (infoDict->lookup(key, &obj)->isString()) {
266 s = obj.getString()->getCString();
267 if (s[0] == 'D' && s[1] == ':') {
270 if (sscanf(s, "%4d%2d%2d%2d%2d%2d",
271 &year, &mon, &day, &hour, &min, &sec) == 6) {
272 tmStruct.tm_year = year - 1900;
273 tmStruct.tm_mon = mon - 1;
274 tmStruct.tm_mday = day;
275 tmStruct.tm_hour = hour;
276 tmStruct.tm_min = min;
277 tmStruct.tm_sec = sec;
278 tmStruct.tm_wday = -1;
279 tmStruct.tm_yday = -1;
280 tmStruct.tm_isdst = -1;
281 mktime(&tmStruct); // compute the tm_wday and tm_yday fields
282 if (strftime(buf, sizeof(buf), "%c", &tmStruct)) {