1 //========================================================================
5 // Copyright 1998-2003 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;
75 double w, h, wISO, hISO;
85 ok = parseArgs(argDesc, &argc, argv);
86 if (!ok || argc != 2 || printVersion || printHelp) {
87 fprintf(stderr, "pdfinfo version %s\n", xpdfVersion);
88 fprintf(stderr, "%s\n", xpdfCopyright);
90 printUsage("pdfinfo", "<PDF-file>", argDesc);
94 fileName = new GString(argv[1]);
97 globalParams = new GlobalParams(cfgFileName);
99 globalParams->setTextEncoding(textEncName);
102 // get mapping to output encoding
103 if (!(uMap = globalParams->getTextEncoding())) {
104 error(-1, "Couldn't get text encoding");
110 if (ownerPassword[0]) {
111 ownerPW = new GString(ownerPassword);
115 if (userPassword[0]) {
116 userPW = new GString(userPassword);
120 doc = new PDFDoc(fileName, ownerPW, userPW);
133 doc->getDocInfo(&info);
135 printInfoString(info.getDict(), "Title", "Title: ", uMap);
136 printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
137 printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
138 printInfoString(info.getDict(), "Author", "Author: ", uMap);
139 printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
140 printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
141 printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
142 printInfoDate(info.getDict(), "ModDate", "ModDate: ");
146 // print tagging info
147 printf("Tagged: %s\n",
148 doc->getStructTreeRoot()->isDict() ? "yes" : "no");
151 printf("Pages: %d\n", doc->getNumPages());
153 // print encryption info
154 printf("Encrypted: ");
155 if (doc->isEncrypted()) {
156 printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
157 doc->okToPrint(gTrue) ? "yes" : "no",
158 doc->okToCopy(gTrue) ? "yes" : "no",
159 doc->okToChange(gTrue) ? "yes" : "no",
160 doc->okToAddNotes(gTrue) ? "yes" : "no");
166 if (doc->getNumPages() >= 1) {
167 w = doc->getPageWidth(1);
168 h = doc->getPageHeight(1);
169 printf("Page size: %g x %g pts", w, h);
170 if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
171 (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) {
174 hISO = sqrt(sqrt(2)) * 7200 / 2.54;
175 wISO = hISO / sqrt(2);
176 for (i = 0; i <= 6; ++i) {
177 if ((fabs(w - wISO) < 1 && fabs(h - hISO) < 1) ||
178 (fabs(w - hISO) < 1 && fabs(h - wISO) < 1)) {
191 f = fopen(fileName->getCString(), "rb", "ctx=stm");
193 f = fopen(fileName->getCString(), "rb");
197 fseeko(f, 0, SEEK_END);
198 printf("File size: %u bytes\n", (Guint)ftello(f));
200 fseek64(f, 0, SEEK_END);
201 printf("File size: %u bytes\n", (Guint)ftell64(f));
203 fseek(f, 0, SEEK_END);
204 printf("File size: %d bytes\n", (int)ftell(f));
209 // print linearization info
210 printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
213 printf("PDF version: %.1f\n", doc->getPDFVersion());
215 // print the metadata
216 if (printMetadata && (metadata = doc->readMetadata())) {
217 fputs("Metadata:\n", stdout);
218 fputs(metadata->getCString(), stdout);
233 // check for memory leaks
234 Object::memCheck(stderr);
240 static void printInfoString(Dict *infoDict, char *key, char *text,
249 if (infoDict->lookup(key, &obj)->isString()) {
251 s1 = obj.getString();
252 if ((s1->getChar(0) & 0xff) == 0xfe &&
253 (s1->getChar(1) & 0xff) == 0xff) {
260 while (i < obj.getString()->getLength()) {
262 u = ((s1->getChar(i) & 0xff) << 8) |
263 (s1->getChar(i+1) & 0xff);
266 u = s1->getChar(i) & 0xff;
269 n = uMap->mapUnicode(u, buf, sizeof(buf));
270 fwrite(buf, 1, n, stdout);
277 static void printInfoDate(Dict *infoDict, char *key, char *text) {
280 int year, mon, day, hour, min, sec;
284 if (infoDict->lookup(key, &obj)->isString()) {
286 s = obj.getString()->getCString();
287 if (s[0] == 'D' && s[1] == ':') {
290 if (sscanf(s, "%4d%2d%2d%2d%2d%2d",
291 &year, &mon, &day, &hour, &min, &sec) == 6) {
292 tmStruct.tm_year = year - 1900;
293 tmStruct.tm_mon = mon - 1;
294 tmStruct.tm_mday = day;
295 tmStruct.tm_hour = hour;
296 tmStruct.tm_min = min;
297 tmStruct.tm_sec = sec;
298 tmStruct.tm_wday = -1;
299 tmStruct.tm_yday = -1;
300 tmStruct.tm_isdst = -1;
301 // compute the tm_wday and tm_yday fields
302 if (mktime(&tmStruct) != (time_t)-1 &&
303 strftime(buf, sizeof(buf), "%c", &tmStruct)) {