X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=inline;f=pdf%2Fxpdf%2Fpdfinfo.cc;h=f856a6d41e24b728354cf903a459baf60b113495;hb=884f739665dc56e66f51e104350f2affd33f2dd8;hp=2c183c8385d77f288e8719b93f79a2102d656fcc;hpb=50e9d31c05e9ca11ad43cc570556094782c1b956;p=evince.git diff --git a/pdf/xpdf/pdfinfo.cc b/pdf/xpdf/pdfinfo.cc index 2c183c83..f856a6d4 100644 --- a/pdf/xpdf/pdfinfo.cc +++ b/pdf/xpdf/pdfinfo.cc @@ -2,17 +2,21 @@ // // pdfinfo.cc // -// Copyright 1998 Derek B. Noonburg +// Copyright 1998-2003 Glyph & Cog, LLC // //======================================================================== +#include #include #include #include #include +#include +#include #include "parseargs.h" #include "GString.h" #include "gmem.h" +#include "GlobalParams.h" #include "Object.h" #include "Stream.h" #include "Array.h" @@ -21,108 +25,290 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" -#include "Params.h" +#include "CharTypes.h" +#include "UnicodeMap.h" #include "Error.h" #include "config.h" -GBool printCommands = gFalse; +static void printInfoString(Dict *infoDict, char *key, char *text, + UnicodeMap *uMap); +static void printInfoDate(Dict *infoDict, char *key, char *text); + +static GBool printMetadata = gFalse; +static char textEncName[128] = ""; +static char ownerPassword[33] = ""; +static char userPassword[33] = ""; +static char cfgFileName[256] = ""; +static GBool printVersion = gFalse; static GBool printHelp = gFalse; static ArgDesc argDesc[] = { + {"-meta", argFlag, &printMetadata, 0, + "print the document metadata (XML)"}, + {"-enc", argString, textEncName, sizeof(textEncName), + "output text encoding name"}, + {"-opw", argString, ownerPassword, sizeof(ownerPassword), + "owner password (for encrypted files)"}, + {"-upw", argString, userPassword, sizeof(userPassword), + "user password (for encrypted files)"}, + {"-cfg", argString, cfgFileName, sizeof(cfgFileName), + "configuration file to use in place of .xpdfrc"}, + {"-v", argFlag, &printVersion, 0, + "print copyright and version info"}, {"-h", argFlag, &printHelp, 0, "print usage information"}, {"-help", argFlag, &printHelp, 0, "print usage information"}, + {"--help", argFlag, &printHelp, 0, + "print usage information"}, + {"-?", argFlag, &printHelp, 0, + "print usage information"}, {NULL} }; int main(int argc, char *argv[]) { PDFDoc *doc; GString *fileName; - Object info, obj; - char *s; + GString *ownerPW, *userPW; + UnicodeMap *uMap; + Object info; + double w, h, wISO, hISO; + FILE *f; + GString *metadata; GBool ok; + int exitCode; + int i; + + exitCode = 99; // parse args ok = parseArgs(argDesc, &argc, argv); - if (!ok || argc != 2 || printHelp) { + if (!ok || argc != 2 || printVersion || printHelp) { fprintf(stderr, "pdfinfo version %s\n", xpdfVersion); fprintf(stderr, "%s\n", xpdfCopyright); - printUsage("pdfinfo", "", argDesc); - exit(1); + if (!printVersion) { + printUsage("pdfinfo", "", argDesc); + } + goto err0; } fileName = new GString(argv[1]); - // init error file - errorInit(); - // read config file - initParams(xpdfConfigFile); + globalParams = new GlobalParams(cfgFileName); + if (textEncName[0]) { + globalParams->setTextEncoding(textEncName); + } + + // get mapping to output encoding + if (!(uMap = globalParams->getTextEncoding())) { + error(-1, "Couldn't get text encoding"); + delete fileName; + goto err1; + } // open PDF file - xref = NULL; - doc = new PDFDoc(fileName); - if (!doc->isOk()) - exit(1); + if (ownerPassword[0]) { + ownerPW = new GString(ownerPassword); + } else { + ownerPW = NULL; + } + if (userPassword[0]) { + userPW = new GString(userPassword); + } else { + userPW = NULL; + } + doc = new PDFDoc(fileName, ownerPW, userPW); + if (userPW) { + delete userPW; + } + if (ownerPW) { + delete ownerPW; + } + if (!doc->isOk()) { + exitCode = 1; + goto err2; + } // print doc info doc->getDocInfo(&info); if (info.isDict()) { - if (info.dictLookup("Title", &obj)->isString()) - printf("Title: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("Subject", &obj)->isString()) - printf("Subject: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("Keywords", &obj)->isString()) - printf("Keywords: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("Author", &obj)->isString()) - printf("Author: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("Creator", &obj)->isString()) - printf("Creator: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("Producer", &obj)->isString()) - printf("Producer: %s\n", obj.getString()->getCString()); - obj.free(); - if (info.dictLookup("CreationDate", &obj)->isString()) { - s = obj.getString()->getCString(); - if (s[0] == 'D' && s[1] == ':') - s += 2; - printf("CreationDate: %s\n", s); - } - obj.free(); - if (info.dictLookup("ModDate", &obj)->isString()) { - s = obj.getString()->getCString(); - if (s[0] == 'D' && s[1] == ':') - s += 2; - printf("ModDate: %s\n", s); - } - obj.free(); + printInfoString(info.getDict(), "Title", "Title: ", uMap); + printInfoString(info.getDict(), "Subject", "Subject: ", uMap); + printInfoString(info.getDict(), "Keywords", "Keywords: ", uMap); + printInfoString(info.getDict(), "Author", "Author: ", uMap); + printInfoString(info.getDict(), "Creator", "Creator: ", uMap); + printInfoString(info.getDict(), "Producer", "Producer: ", uMap); + printInfoDate(info.getDict(), "CreationDate", "CreationDate: "); + printInfoDate(info.getDict(), "ModDate", "ModDate: "); } info.free(); + // print tagging info + printf("Tagged: %s\n", + doc->getStructTreeRoot()->isDict() ? "yes" : "no"); + // print page count printf("Pages: %d\n", doc->getNumPages()); // print encryption info printf("Encrypted: "); if (doc->isEncrypted()) { - printf("yes (print:%s copy:%s)\n", - doc->okToPrint() ? "yes" : "no", - doc->okToCopy() ? "yes" : "no"); + printf("yes (print:%s copy:%s change:%s addNotes:%s)\n", + doc->okToPrint(gTrue) ? "yes" : "no", + doc->okToCopy(gTrue) ? "yes" : "no", + doc->okToChange(gTrue) ? "yes" : "no", + doc->okToAddNotes(gTrue) ? "yes" : "no"); } else { printf("no\n"); } + // print page size + if (doc->getNumPages() >= 1) { + w = doc->getPageWidth(1); + h = doc->getPageHeight(1); + printf("Page size: %g x %g pts", w, h); + if ((fabs(w - 612) < 0.1 && fabs(h - 792) < 0.1) || + (fabs(w - 792) < 0.1 && fabs(h - 612) < 0.1)) { + printf(" (letter)"); + } else { + hISO = sqrt(sqrt(2)) * 7200 / 2.54; + wISO = hISO / sqrt(2); + for (i = 0; i <= 6; ++i) { + if ((fabs(w - wISO) < 1 && fabs(h - hISO) < 1) || + (fabs(w - hISO) < 1 && fabs(h - wISO) < 1)) { + printf(" (A%d)", i); + break; + } + hISO = wISO; + wISO /= sqrt(2); + } + } + printf("\n"); + } + + // print file size +#ifdef VMS + f = fopen(fileName->getCString(), "rb", "ctx=stm"); +#else + f = fopen(fileName->getCString(), "rb"); +#endif + if (f) { +#if HAVE_FSEEKO + fseeko(f, 0, SEEK_END); + printf("File size: %u bytes\n", (Guint)ftello(f)); +#elif HAVE_FSEEK64 + fseek64(f, 0, SEEK_END); + printf("File size: %u bytes\n", (Guint)ftell64(f)); +#else + fseek(f, 0, SEEK_END); + printf("File size: %d bytes\n", (int)ftell(f)); +#endif + fclose(f); + } + + // print linearization info + printf("Optimized: %s\n", doc->isLinearized() ? "yes" : "no"); + + // print PDF version + printf("PDF version: %.1f\n", doc->getPDFVersion()); + + // print the metadata + if (printMetadata && (metadata = doc->readMetadata())) { + fputs("Metadata:\n", stdout); + fputs(metadata->getCString(), stdout); + fputc('\n', stdout); + delete metadata; + } + + exitCode = 0; + // clean up + err2: + uMap->decRefCnt(); delete doc; - freeParams(); + err1: + delete globalParams; + err0: // check for memory leaks Object::memCheck(stderr); gMemReport(stderr); - return 0; + return exitCode; +} + +static void printInfoString(Dict *infoDict, char *key, char *text, + UnicodeMap *uMap) { + Object obj; + GString *s1; + GBool isUnicode; + Unicode u; + char buf[8]; + int i, n; + + if (infoDict->lookup(key, &obj)->isString()) { + fputs(text, stdout); + s1 = obj.getString(); + if ((s1->getChar(0) & 0xff) == 0xfe && + (s1->getChar(1) & 0xff) == 0xff) { + isUnicode = gTrue; + i = 2; + } else { + isUnicode = gFalse; + i = 0; + } + while (i < obj.getString()->getLength()) { + if (isUnicode) { + u = ((s1->getChar(i) & 0xff) << 8) | + (s1->getChar(i+1) & 0xff); + i += 2; + } else { + u = s1->getChar(i) & 0xff; + ++i; + } + n = uMap->mapUnicode(u, buf, sizeof(buf)); + fwrite(buf, 1, n, stdout); + } + fputc('\n', stdout); + } + obj.free(); +} + +static void printInfoDate(Dict *infoDict, char *key, char *text) { + Object obj; + char *s; + int year, mon, day, hour, min, sec; + struct tm tmStruct; + char buf[256]; + + if (infoDict->lookup(key, &obj)->isString()) { + fputs(text, stdout); + s = obj.getString()->getCString(); + if (s[0] == 'D' && s[1] == ':') { + s += 2; + } + if (sscanf(s, "%4d%2d%2d%2d%2d%2d", + &year, &mon, &day, &hour, &min, &sec) == 6) { + tmStruct.tm_year = year - 1900; + tmStruct.tm_mon = mon - 1; + tmStruct.tm_mday = day; + tmStruct.tm_hour = hour; + tmStruct.tm_min = min; + tmStruct.tm_sec = sec; + tmStruct.tm_wday = -1; + tmStruct.tm_yday = -1; + tmStruct.tm_isdst = -1; + // compute the tm_wday and tm_yday fields + if (mktime(&tmStruct) != (time_t)-1 && + strftime(buf, sizeof(buf), "%c", &tmStruct)) { + fputs(buf, stdout); + } else { + fputs(s, stdout); + } + } else { + fputs(s, stdout); + } + fputc('\n', stdout); + } + obj.free(); }