summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-12-09 14:30:30 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-12-12 13:40:40 +0100
commitfd8157ead4e10985e1ad1d996e2452bac4dca784 (patch)
tree79b41d2d623de7ac030df0ce93517f8e75aa9f18
parentfd2cb625e77cf71eec9d37bdd034cee6ef184d62 (diff)
downloadmupdf-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.
-rw-r--r--source/tools/pdfportfolio.c334
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);