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"
31 #include "xpdfconfig.h"
33 static void printInfoString(Dict *infoDict, char *key, char *text,
35 static void printInfoDate(Dict *infoDict, char *key, char *text);
36 static void printBox(char *text, PDFRectangle *box);
38 static int firstPage = 1;
39 static int lastPage = 0;
40 static GBool printBoxes = gFalse;
41 static GBool printMetadata = gFalse;
42 static char textEncName[128] = "";
43 static char ownerPassword[33] = "\001";
44 static char userPassword[33] = "\001";
45 static char cfgFileName[256] = "";
46 static GBool printVersion = gFalse;
47 static GBool printHelp = gFalse;
49 static ArgDesc argDesc[] = {
50 {"-f", argInt, &firstPage, 0,
51 "first page to convert"},
52 {"-l", argInt, &lastPage, 0,
53 "last page to convert"},
54 {"-box", argFlag, &printBoxes, 0,
55 "print the page bounding boxes"},
56 {"-meta", argFlag, &printMetadata, 0,
57 "print the document metadata (XML)"},
58 {"-enc", argString, textEncName, sizeof(textEncName),
59 "output text encoding name"},
60 {"-opw", argString, ownerPassword, sizeof(ownerPassword),
61 "owner password (for encrypted files)"},
62 {"-upw", argString, userPassword, sizeof(userPassword),
63 "user password (for encrypted files)"},
64 {"-cfg", argString, cfgFileName, sizeof(cfgFileName),
65 "configuration file to use in place of .xpdfrc"},
66 {"-v", argFlag, &printVersion, 0,
67 "print copyright and version info"},
68 {"-h", argFlag, &printHelp, 0,
69 "print usage information"},
70 {"-help", argFlag, &printHelp, 0,
71 "print usage information"},
72 {"--help", argFlag, &printHelp, 0,
73 "print usage information"},
74 {"-?", argFlag, &printHelp, 0,
75 "print usage information"},
79 int main(int argc, char *argv[]) {
82 GString *ownerPW, *userPW;
87 double w, h, wISO, hISO;
98 ok = parseArgs(argDesc, &argc, argv);
99 if (!ok || argc != 2 || printVersion || printHelp) {
100 fprintf(stderr, "pdfinfo version %s\n", xpdfVersion);
101 fprintf(stderr, "%s\n", xpdfCopyright);
103 printUsage("pdfinfo", "<PDF-file>", argDesc);
107 fileName = new GString(argv[1]);
110 globalParams = new GlobalParams(cfgFileName);
111 if (textEncName[0]) {
112 globalParams->setTextEncoding(textEncName);
115 // get mapping to output encoding
116 if (!(uMap = globalParams->getTextEncoding())) {
117 error(-1, "Couldn't get text encoding");
123 if (ownerPassword[0] != '\001') {
124 ownerPW = new GString(ownerPassword);
128 if (userPassword[0] != '\001') {
129 userPW = new GString(userPassword);
133 doc = new PDFDoc(fileName, ownerPW, userPW);
155 if (lastPage < 1 || lastPage > doc->getNumPages()) {
156 lastPage = doc->getNumPages();
160 doc->getDocInfo(&info);
162 printInfoString(info.getDict(), "Title", "Title: ", uMap);
163 printInfoString(info.getDict(), "Subject", "Subject: ", uMap);
164 printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap);
165 printInfoString(info.getDict(), "Author", "Author: ", uMap);
166 printInfoString(info.getDict(), "Creator", "Creator: ", uMap);
167 printInfoString(info.getDict(), "Producer", "Producer: ", uMap);
168 printInfoDate(info.getDict(), "CreationDate", "CreationDate: ");
169 printInfoDate(info.getDict(), "ModDate", "ModDate: ");
173 // print tagging info
174 printf("Tagged: %s\n",
175 doc->getStructTreeRoot()->isDict() ? "yes" : "no");
178 printf("Pages: %d\n", doc->getNumPages());
180 // print encryption info
181 printf("Encrypted: ");
182 if (doc->isEncrypted()) {
183 printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
184 doc->okToPrint(gTrue) ? "yes" : "no",
185 doc->okToCopy(gTrue) ? "yes" : "no",
186 doc->okToChange(gTrue) ? "yes" : "no",
187 doc->okToAddNotes(gTrue) ? "yes" : "no");
193 for (pg = firstPage; pg <= lastPage; ++pg) {
194 w = doc->getPageWidth(pg);
195 h = doc->getPageHeight(pg);
197 printf("Page %4d size: %g x %g pts", pg, w, h);
199 printf("Page size: %g x %g pts", w, h);
201 if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) ||
202 (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) {
205 hISO = sqrt(sqrt(2.0)) * 7200 / 2.54;
206 wISO = hISO / sqrt(2.0);
207 for (i = 0; i <= 6; ++i) {
208 if ((fabs(w - wISO) < 1 && fabs(h - hISO) < 1) ||
209 (fabs(w - hISO) < 1 && fabs(h - wISO) < 1)) {
223 for (pg = firstPage; pg <= lastPage; ++pg) {
224 page = doc->getCatalog()->getPage(pg);
225 sprintf(buf, "Page %4d MediaBox: ", pg);
226 printBox(buf, page->getMediaBox());
227 sprintf(buf, "Page %4d CropBox: ", pg);
228 printBox(buf, page->getCropBox());
229 sprintf(buf, "Page %4d BleedBox: ", pg);
230 printBox(buf, page->getBleedBox());
231 sprintf(buf, "Page %4d TrimBox: ", pg);
232 printBox(buf, page->getTrimBox());
233 sprintf(buf, "Page %4d ArtBox: ", pg);
234 printBox(buf, page->getArtBox());
237 page = doc->getCatalog()->getPage(firstPage);
238 printBox("MediaBox: ", page->getMediaBox());
239 printBox("CropBox: ", page->getCropBox());
240 printBox("BleedBox: ", page->getBleedBox());
241 printBox("TrimBox: ", page->getTrimBox());
242 printBox("ArtBox: ", page->getArtBox());
248 f = fopen(fileName->getCString(), "rb", "ctx=stm");
250 f = fopen(fileName->getCString(), "rb");
254 fseeko(f, 0, SEEK_END);
255 printf("File size: %u bytes\n", (Guint)ftello(f));
257 fseek64(f, 0, SEEK_END);
258 printf("File size: %u bytes\n", (Guint)ftell64(f));
260 fseek(f, 0, SEEK_END);
261 printf("File size: %d bytes\n", (int)ftell(f));
266 // print linearization info
267 printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no");
270 printf("PDF version: %.1f\n", doc->getPDFVersion());
272 // print the metadata
273 if (printMetadata && (metadata = doc->readMetadata())) {
274 fputs("Metadata:\n", stdout);
275 fputs(metadata->getCString(), stdout);
290 // check for memory leaks
291 Object::memCheck(stderr);
297 static void printInfoString(Dict *infoDict, char *key, char *text,
306 if (infoDict->lookup(key, &obj)->isString()) {
308 s1 = obj.getString();
309 if ((s1->getChar(0) & 0xff) == 0xfe &&
310 (s1->getChar(1) & 0xff) == 0xff) {
317 while (i < obj.getString()->getLength()) {
319 u = ((s1->getChar(i) & 0xff) << 8) |
320 (s1->getChar(i+1) & 0xff);
323 u = s1->getChar(i) & 0xff;
326 n = uMap->mapUnicode(u, buf, sizeof(buf));
327 fwrite(buf, 1, n, stdout);
334 static void printInfoDate(Dict *infoDict, char *key, char *text) {
337 int year, mon, day, hour, min, sec;
341 if (infoDict->lookup(key, &obj)->isString()) {
343 s = obj.getString()->getCString();
344 if (s[0] == 'D' && s[1] == ':') {
347 if (sscanf(s, "%4d%2d%2d%2d%2d%2d",
348 &year, &mon, &day, &hour, &min, &sec) == 6) {
349 tmStruct.tm_year = year - 1900;
350 tmStruct.tm_mon = mon - 1;
351 tmStruct.tm_mday = day;
352 tmStruct.tm_hour = hour;
353 tmStruct.tm_min = min;
354 tmStruct.tm_sec = sec;
355 tmStruct.tm_wday = -1;
356 tmStruct.tm_yday = -1;
357 tmStruct.tm_isdst = -1;
358 // compute the tm_wday and tm_yday fields
359 if (mktime(&tmStruct) != (time_t)-1 &&
360 strftime(buf, sizeof(buf), "%c", &tmStruct)) {
373 static void printBox(char *text, PDFRectangle *box) {
374 printf("%s%8.2f %8.2f %8.2f %8.2f\n",
375 text, box->x1, box->y1, box->x2, box->y2);