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 int firstPage = 1;
38 static int lastPage = 0;
39 static GBool printMetadata = gFalse;
40 static char textEncName[128] = "";
41 static char ownerPassword[33] = "\001";
42 static char userPassword[33] = "\001";
43 static char cfgFileName[256] = "";
44 static GBool printVersion = gFalse;
45 static GBool printHelp = gFalse;
47 static ArgDesc argDesc[] = {
48 {"-f", argInt, &firstPage, 0,
49 "first page to convert"},
50 {"-l", argInt, &lastPage, 0,
51 "last page to convert"},
52 {"-meta", argFlag, &printMetadata, 0,
53 "print the document metadata (XML)"},
54 {"-enc", argString, textEncName, sizeof(textEncName),
55 "output text encoding name"},
56 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
57 "owner password (for encrypted files)"},
58 {"-upw", argString, userPassword, sizeof(userPassword),
59 "user password (for encrypted files)"},
60 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
61 "configuration file to use in place of .xpdfrc"},
62 {"-v", argFlag, &printVersion, 0,
63 "print copyright and version info"},
64 {"-h", argFlag, &printHelp, 0,
65 "print usage information"},
66 {"-help", argFlag, &printHelp, 0,
67 "print usage information"},
68 {"--help", argFlag, &printHelp, 0,
69 "print usage information"},
70 {"-?", argFlag, &printHelp, 0,
71 "print usage information"},
75 int main(int argc, char *argv[]) {
78 GString *ownerPW, *userPW;
81 double w, h, wISO, hISO;
92 ok = parseArgs(argDesc, &argc, argv);
93 if (!ok || argc != 2 || printVersion || printHelp) {
94 fprintf(stderr, "pdfinfo version %s\n", xpdfVersion);
95 fprintf(stderr, "%s\n", xpdfCopyright);
97 printUsage("pdfinfo", "<PDF-file>", argDesc);
101 fileName = new GString(argv[1]);
104 globalParams = new GlobalParams(cfgFileName);
105 if (textEncName[0]) {
106 globalParams->setTextEncoding(textEncName);
109 // get mapping to output encoding
110 if (!(uMap = globalParams->getTextEncoding())) {
111 error(-1, "Couldn't get text encoding");
117 if (ownerPassword[0] != '\001') {
118 ownerPW = new GString(ownerPassword);
122 if (userPassword[0] != '\001') {
123 userPW = new GString(userPassword);
127 doc = new PDFDoc(fileName, ownerPW, userPW);
149 if (lastPage < 1 || lastPage > doc->getNumPages()) {
150 lastPage = doc->getNumPages();
154 doc->getDocInfo(&info);
156 printInfoString(info.getDict(), "Title", "Title: ", uMap);
157 printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
158 printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
159 printInfoString(info.getDict(), "Author", "Author: ", uMap);
160 printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
161 printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
162 printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
163 printInfoDate(info.getDict(), "ModDate", "ModDate: ");
167 // print tagging info
168 printf("Tagged: %s\n",
169 doc->getStructTreeRoot()->isDict() ? "yes" : "no");
172 printf("Pages: %d\n", doc->getNumPages());
174 // print encryption info
175 printf("Encrypted: ");
176 if (doc->isEncrypted()) {
177 printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
178 doc->okToPrint(gTrue) ? "yes" : "no",
179 doc->okToCopy(gTrue) ? "yes" : "no",
180 doc->okToChange(gTrue) ? "yes" : "no",
181 doc->okToAddNotes(gTrue) ? "yes" : "no");
187 for (pg = firstPage; pg <= lastPage; ++pg) {
188 w = doc->getPageWidth(pg);
189 h = doc->getPageHeight(pg);
191 printf("Page %4d size: %g x %g pts", pg, w, h);
193 printf("Page size: %g x %g pts", w, h);
195 if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
196 (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) {
199 hISO = sqrt(sqrt(2.0)) * 7200 / 2.54;
200 wISO = hISO / sqrt(2.0);
201 for (i = 0; i <= 6; ++i) {
202 if ((fabs(w - wISO) < 1 && fabs(h - hISO) < 1) ||
203 (fabs(w - hISO) < 1 && fabs(h - wISO) < 1)) {
216 f = fopen(fileName->getCString(), "rb", "ctx=stm");
218 f = fopen(fileName->getCString(), "rb");
222 fseeko(f, 0, SEEK_END);
223 printf("File size: %u bytes\n", (Guint)ftello(f));
225 fseek64(f, 0, SEEK_END);
226 printf("File size: %u bytes\n", (Guint)ftell64(f));
228 fseek(f, 0, SEEK_END);
229 printf("File size: %d bytes\n", (int)ftell(f));
234 // print linearization info
235 printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
238 printf("PDF version: %.1f\n", doc->getPDFVersion());
240 // print the metadata
241 if (printMetadata && (metadata = doc->readMetadata())) {
242 fputs("Metadata:\n", stdout);
243 fputs(metadata->getCString(), stdout);
258 // check for memory leaks
259 Object::memCheck(stderr);
265 static void printInfoString(Dict *infoDict, char *key, char *text,
274 if (infoDict->lookup(key, &obj)->isString()) {
276 s1 = obj.getString();
277 if ((s1->getChar(0) & 0xff) == 0xfe &&
278 (s1->getChar(1) & 0xff) == 0xff) {
285 while (i < obj.getString()->getLength()) {
287 u = ((s1->getChar(i) & 0xff) << 8) |
288 (s1->getChar(i+1) & 0xff);
291 u = s1->getChar(i) & 0xff;
294 n = uMap->mapUnicode(u, buf, sizeof(buf));
295 fwrite(buf, 1, n, stdout);
302 static void printInfoDate(Dict *infoDict, char *key, char *text) {
305 int year, mon, day, hour, min, sec;
309 if (infoDict->lookup(key, &obj)->isString()) {
311 s = obj.getString()->getCString();
312 if (s[0] == 'D' && s[1] == ':') {
315 if (sscanf(s, "%4d%2d%2d%2d%2d%2d",
316 &year, &mon, &day, &hour, &min, &sec) == 6) {
317 tmStruct.tm_year = year - 1900;
318 tmStruct.tm_mon = mon - 1;
319 tmStruct.tm_mday = day;
320 tmStruct.tm_hour = hour;
321 tmStruct.tm_min = min;
322 tmStruct.tm_sec = sec;
323 tmStruct.tm_wday = -1;
324 tmStruct.tm_yday = -1;
325 tmStruct.tm_isdst = -1;
326 // compute the tm_wday and tm_yday fields
327 if (mktime(&tmStruct) != (time_t)-1 &&
328 strftime(buf, sizeof(buf), "%c", &tmStruct)) {