diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2016-12-09 14:30:30 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2016-12-12 13:40:40 +0100 |
commit | fd8157ead4e10985e1ad1d996e2452bac4dca784 (patch) | |
tree | 79b41d2d623de7ac030df0ce93517f8e75aa9f18 /source | |
parent | fd2cb625e77cf71eec9d37bdd034cee6ef184d62 (diff) | |
download | mupdf-fd8157ead4e10985e1ad1d996e2452bac4dca784.tar.xz |
Tweak pdf portfolio to create blank portfolios and add multiple entries.
Will overwrite input file unless a separate output file is specified.
Diffstat (limited to 'source')
-rw-r--r-- | source/tools/pdfportfolio.c | 334 |
1 files changed, 199 insertions, 135 deletions
diff --git a/source/tools/pdfportfolio.c b/source/tools/pdfportfolio.c index 51b43ae3..ff119bf8 100644 --- a/source/tools/pdfportfolio.c +++ b/source/tools/pdfportfolio.c @@ -9,13 +9,15 @@ static fz_context *ctx = NULL; static void usage(void) { - fprintf(stderr, "usage: mutool portfolio [options] infile.pdf [actions]\n"); + fprintf(stderr, "usage: mutool portfolio [options] portfolio.pdf [actions]\n"); fprintf(stderr, "\tOptions are:\n"); fprintf(stderr, "\t-p -\tpassword\n"); + fprintf(stderr, "\t-o -\toutput (defaults to input file)\n"); + fprintf(stderr, "\t-O -\tPDF output options (see mutool create)\n"); fprintf(stderr, "Actions are:\n"); - fprintf(stderr, "\tl\tlist embedded files\n"); + fprintf(stderr, "\tt\tlist embedded files\n"); fprintf(stderr, "\tx N <filename>\n\t\textract Nth embedded file as <filename>\n"); - fprintf(stderr, "\te outfile.pdf <filename> <embed>\n\t\tembed <filename> as <embed>, saving the result as outfile.pdf\n"); + fprintf(stderr, "\ta <filename> <entry>\n\t\tembed contents of <filename> named as <entry>\n"); fprintf(stderr, "\nFor safety, keep all filenames as 7 bit clean for now.\n"); exit(1); } @@ -65,18 +67,145 @@ safe_print_pdf_obj(fz_context *ctx, pdf_obj *obj, const char *dflt) pdf_print_obj(ctx, fz_stderr(ctx), obj, 1); } +static void +pdfportfolio_list() +{ + /* List files */ + int m = pdf_count_portfolio_schema(ctx, doc); + int n = pdf_count_portfolio_entries(ctx, doc); + int i, j; + + for (i = 0; i < n; i++) + { + pdf_obj *name = pdf_portfolio_entry_name(ctx, doc, i); + + fprintf(stderr, " %s%d: ", i < 10 ? " " : "", i); + safe_print_pdf_obj(ctx, name, "(Unnamed)"); + fprintf(stderr, "\n"); + for (j = 0; j < m; j++) + { + pdf_portfolio_schema info; + pdf_obj *obj; + char *type; + + pdf_portfolio_schema_info(ctx, doc, j, &info); + obj = pdf_portfolio_entry_info(ctx, doc, i, j); + fprintf(stderr, " "); + safe_print_pdf_obj(ctx, info.name, "(Unnamed)"); + switch(info.type) + { + case PDF_SCHEMA_TEXT: + type = "T"; + break; + case PDF_SCHEMA_DATE: + type = "D"; + break; + case PDF_SCHEMA_NUMBER: + type = "N"; + break; + case PDF_SCHEMA_FILENAME: + type = "F"; + break; + case PDF_SCHEMA_DESC: + type = "E"; + break; + case PDF_SCHEMA_MODDATE: + type = "M"; + break; + case PDF_SCHEMA_CREATIONDATE: + type = "C"; + break; + case PDF_SCHEMA_SIZE: + type = "S"; + break; + default: + type = "?"; + break; + } + fprintf(stderr, ":%s:", type); + safe_print_pdf_obj(ctx, obj, ""); + if (info.editable) + fprintf(stderr, " (Editable)"); + if (info.visible) + fprintf(stderr, " (Visible)"); + fprintf(stderr, "\n"); + } + } +} + +static void +pdfportfolio_extract(int argc, char **argv) +{ + int entry; + const char *filename; + fz_buffer *buf; + unsigned char *data; + int len; + FILE *file; + + if (fz_optind > argc-2) + usage(); + + entry = fz_atoi(argv[fz_optind++]); + filename = argv[fz_optind++]; + + buf = pdf_portfolio_entry(ctx, doc, entry); + len = fz_buffer_storage(ctx, buf, &data); + + file = fopen(filename, "wb"); + if (file == NULL) + { + fprintf(stderr, "Failed to open '%s' for writing\n", filename); + exit(1); + } + fwrite(data, 1, len, file); + fclose(file); + fz_drop_buffer(ctx, buf); +} + +static void +pdfportfolio_add(int argc, char **argv) +{ + const char *filename; + const char *ename; + fz_buffer *buf; + + if (fz_optind > argc-2) + usage(); + + filename = argv[fz_optind++]; + ename = argv[fz_optind++]; + + if (ename == NULL) + ename = filename; + + buf = fz_read_file(ctx, filename); + pdf_add_portfolio_entry(ctx, doc, + ename, strlen(ename), /* name */ + ename, strlen(ename), /* desc */ + ename, strlen(ename), /* filename */ + ename, strlen(ename), /* unifile */ + buf); + fz_drop_buffer(ctx, buf); +} + int pdfportfolio_main(int argc, char **argv) { - char *infile; char *password = ""; - int c; + char *outfile = NULL; + char *outopts = "compress"; + char *infile; int exit_code = 0; + int do_save = 0; + int c; - while ((c = fz_getopt(argc, argv, "p:")) != -1) + while ((c = fz_getopt(argc, argv, "p:o:O:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; + case 'o': outfile = fz_optarg; break; + case 'O': outopts = fz_optarg; break; default: usage(); break; } } @@ -85,6 +214,8 @@ int pdfportfolio_main(int argc, char **argv) usage(); infile = argv[fz_optind++]; + if (!outfile) + outfile = infile; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) @@ -93,149 +224,82 @@ int pdfportfolio_main(int argc, char **argv) exit(1); } - doc = pdf_open_document(ctx, infile); - if (pdf_needs_password(ctx, doc)) - if (!pdf_authenticate_password(ctx, doc, password)) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); + if (fz_file_exists(ctx, infile)) + { + doc = pdf_open_document(ctx, infile); + if (pdf_needs_password(ctx, doc)) + if (!pdf_authenticate_password(ctx, doc, password)) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); + } + else + { + doc = pdf_create_document(ctx); + + /* add a blank page */ + { + const char *template = "BT /Tm 16 Tf 50 434 TD (This is a portfolio document.) Tj ET\n"; + const char *data; + int size; + fz_font *font; + pdf_obj *font_obj, *page_obj; + pdf_obj *resources; + fz_buffer *contents; + fz_rect mediabox = { 0, 0, 400, 500 }; + + data = fz_lookup_base14_font(ctx, "Times-Roman", &size); + font = fz_new_font_from_memory(ctx, "Times-Roman", data, size, 0, 0); + font_obj = pdf_add_simple_font(ctx, doc, font); + fz_drop_font(ctx, font); + + resources = pdf_add_object_drop(ctx, doc, pdf_new_dict(ctx, doc, 1)); + pdf_dict_putp_drop(ctx, resources, "Font/Tm", font_obj); + + contents = fz_new_buffer_from_shared_data(ctx, template, strlen(template)); + + page_obj = pdf_add_page(ctx, doc, &mediabox, 0, resources, contents); + pdf_insert_page(ctx, doc, -1, page_obj); + pdf_drop_obj(ctx, page_obj); + fz_drop_buffer(ctx, contents); + } + } if (fz_optind == argc) usage(); - fz_optarg = argv[fz_optind++]; - if (*fz_optarg == 0 || (*fz_optarg != 'l' && *fz_optarg != 'x' && *fz_optarg != 'e') || fz_optarg[1] != 0) - usage(); - fz_try(ctx) + while (fz_optind < argc) { - switch (*fz_optarg) + fz_optarg = argv[fz_optind++]; + fz_try(ctx) { - case 'l': - { - /* List files */ - int m = pdf_count_portfolio_schema(ctx, doc); - int n = pdf_count_portfolio_entries(ctx, doc); - int i, j; - - for (i = 0; i < n; i++) + switch (*fz_optarg) { - pdf_obj *name = pdf_portfolio_entry_name(ctx, doc, i); - - fprintf(stderr, " %s%d: ", i < 10 ? " " : "", i); - safe_print_pdf_obj(ctx, name, "(Unnamed)"); - fprintf(stderr, "\n"); - for (j = 0; j < m; j++) - { - pdf_portfolio_schema info; - pdf_obj *obj; - char *type; - - pdf_portfolio_schema_info(ctx, doc, j, &info); - obj = pdf_portfolio_entry_info(ctx, doc, i, j); - fprintf(stderr, " "); - safe_print_pdf_obj(ctx, info.name, "(Unnamed)"); - switch(info.type) - { - case PDF_SCHEMA_TEXT: - type = "T"; - break; - case PDF_SCHEMA_DATE: - type = "D"; - break; - case PDF_SCHEMA_NUMBER: - type = "N"; - break; - case PDF_SCHEMA_FILENAME: - type = "F"; - break; - case PDF_SCHEMA_DESC: - type = "E"; - break; - case PDF_SCHEMA_MODDATE: - type = "M"; - break; - case PDF_SCHEMA_CREATIONDATE: - type = "C"; - break; - case PDF_SCHEMA_SIZE: - type = "S"; - break; - default: - type = "?"; - break; - } - fprintf(stderr, ":%s:", type); - safe_print_pdf_obj(ctx, obj, ""); - if (info.editable) - fprintf(stderr, " (Editable)"); - if (info.visible) - fprintf(stderr, " (Visible)"); - fprintf(stderr, "\n"); - } - } - break; - } - case 'x': - { - int entry; - char *filename; - fz_buffer *buf; - unsigned char *data; - int len; - FILE *file; - - if (fz_optind > argc-2) + default: usage(); - - entry = fz_atoi(argv[fz_optind++]); - filename = argv[fz_optind++]; - - buf = pdf_portfolio_entry(ctx, doc, entry); - len = fz_buffer_storage(ctx, buf, &data); - - file = fopen(filename, "wb"); - if (file == NULL) - { - fprintf(stderr, "Failed to open '%s' for writing\n", filename); - exit(1); + break; + case 't': + pdfportfolio_list(); + break; + case 'x': + pdfportfolio_extract(argc, argv); + break; + case 'a': + pdfportfolio_add(argc, argv); + do_save = 1; + break; } - fwrite(data, 1, len, file); - fclose(file); - fz_drop_buffer(ctx, buf); - break; } - case 'e': + fz_catch(ctx) { - char *outfile; - char *filename; - char *ename; - fz_buffer *buf; - - if (fz_optind > argc-3) - usage(); - - outfile = argv[fz_optind++]; - filename = argv[fz_optind++]; - ename = argv[fz_optind++]; - - if (ename == NULL) - ename = filename; - - buf = fz_read_file(ctx, filename); - pdf_add_portfolio_entry(ctx, doc, - ename, strlen(ename), /* name */ - ename, strlen(ename), /* desc */ - ename, strlen(ename), /* filename */ - ename, strlen(ename), /* unifile */ - buf); - fz_drop_buffer(ctx, buf); - pdf_save_document(ctx, doc, outfile, NULL); - break; - } + /* Swallow any errors */ + exit_code = 1; } } - fz_catch(ctx) + + if (do_save && !exit_code) { - /* Swallow any errors */ - exit_code = 1; + pdf_write_options opts; + pdf_parse_write_options(ctx, &opts, outopts); + pdf_save_document(ctx, doc, outfile, &opts); } pdf_drop_document(ctx, doc); |