diff options
-rw-r--r-- | docs/mutool/examples/pdf-create.js | 2 | ||||
-rw-r--r-- | docs/mutool/examples/pdf-merge.js | 2 | ||||
-rw-r--r-- | docs/mutool/run.html | 22 | ||||
-rw-r--r-- | include/mupdf/fitz/writer.h | 5 | ||||
-rw-r--r-- | source/fitz/output-cbz.c | 18 | ||||
-rw-r--r-- | source/fitz/writer.c | 41 | ||||
-rw-r--r-- | source/pdf/pdf-write.c | 64 | ||||
-rw-r--r-- | source/tools/muconvert.c | 4 | ||||
-rw-r--r-- | source/tools/murun.c | 2 | ||||
-rw-r--r-- | source/tools/pdfcreate.c | 10 | ||||
-rw-r--r-- | source/tools/pdfmerge.c | 7 |
11 files changed, 136 insertions, 41 deletions
diff --git a/docs/mutool/examples/pdf-create.js b/docs/mutool/examples/pdf-create.js index 131e72b3..290d1737 100644 --- a/docs/mutool/examples/pdf-create.js +++ b/docs/mutool/examples/pdf-create.js @@ -32,4 +32,4 @@ var page = pdf.addPage([0,0,300,350], 0, resources, contents) pdf.insertPage(-1, page) // Save the document to file. -pdf.save("out.pdf", "paif") +pdf.save("out.pdf", "pretty,ascii,compress-images,compress-fonts") diff --git a/docs/mutool/examples/pdf-merge.js b/docs/mutool/examples/pdf-merge.js index 6f5d4692..dd5fb2a5 100644 --- a/docs/mutool/examples/pdf-merge.js +++ b/docs/mutool/examples/pdf-merge.js @@ -57,7 +57,7 @@ function pdfmerge() { srcDoc = new PDFDocument(argv[i]) copyAllPages(dstDoc, srcDoc) } - dstDoc.save(argv[1], "z") + dstDoc.save(argv[1], "compress") } if (argv.length < 3) diff --git a/docs/mutool/run.html b/docs/mutool/run.html index f9278b2b..ac76a7f5 100644 --- a/docs/mutool/run.html +++ b/docs/mutool/run.html @@ -483,16 +483,18 @@ using low level access to the objects and streams contained in a PDF file. <dd>Cast the PDF document to a Document. <dt>PDFDocument#save(fileName, options) <dd>Write the PDF document to file. -The write options are a string of flag characters: -<br>l: linearize, -<br>g: garbage collect, gg: ...and compact, ggg: ...and de-duplicate, -<br>p: pretty-print objects, -<br>a: ascii hex encode streams, -<br>f: compress fonts, -<br>i: compress images, -<br>z: compress all streams, -<br>d: decompress all streams (except fonts or images if 'f' or 'i'), -<br>s: sanitize content streams. +The write options are a string of comma separated options: +<br>linearize (optimize for "web"), +<br>garbage (remove unused objects), +<br>or garbage=compact (... and compact xref table), +<br>or garbage=deduplicate (... and remove duplicate objects), +<br>pretty (pretty-print objects), +<br>ascii (ascii hex encode streams), +<br>compress-fonts (compress embedded font data), +<br>compress-images (compress image data), +<br>compress (compress all streams), +<br>decompress (decompress all streams (except fonts or images if compress-fonts/images)), +<br>sanitize (sanitize content streams). </dl> <h3> diff --git a/include/mupdf/fitz/writer.h b/include/mupdf/fitz/writer.h index e318568e..5d2b06ba 100644 --- a/include/mupdf/fitz/writer.h +++ b/include/mupdf/fitz/writer.h @@ -16,6 +16,8 @@ struct fz_document_writer_s void (*drop_imp)(fz_context *ctx, fz_document_writer *wri); }; +int fz_has_option(fz_context *ctx, const char *opts, const char *key, const char **val); + fz_document_writer *fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options); fz_device *fz_begin_page(fz_context *ctx, fz_document_writer *wri, const fz_rect *mediabox, fz_matrix *ctm); @@ -25,4 +27,7 @@ void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri); fz_document_writer *fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options); fz_document_writer *fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options); +extern const char *fz_cbz_write_options_usage; +extern const char *fz_pdf_write_options_usage; + #endif diff --git a/source/fitz/output-cbz.c b/source/fitz/output-cbz.c index df5c0640..d6f1e07c 100644 --- a/source/fitz/output-cbz.c +++ b/source/fitz/output-cbz.c @@ -8,11 +8,16 @@ struct fz_cbz_writer_s { fz_document_writer super; fz_zip_writer *zip; - int resolution; + float resolution; fz_pixmap *pixmap; int count; }; +const char *fz_cbz_write_options_usage = + "CBZ output options:\n" + "\tresolution=N: resolution of rendered pages in pixels per inch (default 96)\n" + ; + static fz_device * cbz_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox, fz_matrix *ctm) { @@ -69,8 +74,10 @@ cbz_drop_imp(fz_context *ctx, fz_document_writer *wri_) fz_document_writer * fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options) { - fz_cbz_writer *wri = fz_malloc_struct(ctx, fz_cbz_writer); + const char *val; + fz_cbz_writer *wri; + wri = fz_malloc_struct(ctx, fz_cbz_writer); wri->super.begin_page = cbz_begin_page; wri->super.end_page = cbz_end_page; wri->super.drop_imp = cbz_drop_imp; @@ -83,11 +90,10 @@ fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options) fz_rethrow(ctx); } - // TODO: getopt-like comma separated list of options - if (options) - wri->resolution = atoi(options); + if (fz_has_option(ctx, options, "resolution", &val)) + wri->resolution = fz_atof(val); - if (wri->resolution == 0) + if (wri->resolution <= 0) wri->resolution = 96; return (fz_document_writer*)wri; diff --git a/source/fitz/writer.c b/source/fitz/writer.c index c25ff2f9..b015b5bb 100644 --- a/source/fitz/writer.c +++ b/source/fitz/writer.c @@ -1,5 +1,46 @@ #include "mupdf/fitz.h" +/* Return non-null terminated pointers to key/value entries in comma separated + * option string. A plain key has the default value 'yes'. Use strncmp to compare + * key/value strings. */ +static const char * +fz_get_option(fz_context *ctx, const char **key, const char **val, const char *opts) +{ + if (!opts || *opts == 0) + return NULL; + + if (*opts == ',') + ++opts; + + *key = opts; + while (*opts != 0 && *opts != ',' && *opts != '=') + ++opts; + + if (*opts == '=') + { + *val = ++opts; + while (*opts != 0 && *opts != ',') + ++opts; + } + else + { + *val = "yes"; + } + + return opts; +} + +int +fz_has_option(fz_context *ctx, const char *opts, const char *key, const char **val) +{ + const char *straw; + int n = strlen(key); + while ((opts = fz_get_option(ctx, &straw, val, opts))) + if (!strncmp(straw, key, n) && (straw[n] == '=' || straw[n] == ',' || straw[n] == 0)) + return 1; + return 0; +} + fz_document_writer * fz_new_document_writer(fz_context *ctx, const char *path, const char *format, const char *options) { diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c index b50e5db3..b4c565cf 100644 --- a/source/pdf/pdf-write.c +++ b/source/pdf/pdf-write.c @@ -2748,27 +2748,59 @@ static void finalise_write_state(fz_context *ctx, pdf_write_state *opts) fz_drop_output(ctx, opts->out); } +static int opteq(const char *a, const char *b) +{ + int n = strlen(b); + return !strncmp(a, b, n) && (a[n] == ',' || a[n] == 0); +} + +const char *fz_pdf_write_options_usage = + "PDF output options:\n" + "\tdecompress: decompress all streams (except when compress-fonts or compress-images)\n" + "\tcompress: compress all streams\n" + "\tcompress-fonts: compress embedded fonts\n" + "\tcompress-images: compress images\n" + "\tascii: ASCII hex encode binary streams\n" + "\tpretty: pretty-print objects with indentation\n" + "\tlinearize: optimize for web browsers\n" + "\tsanitize: clean up graphics commands in content streams\n" + "\tgarbage: garbage collect unused objects\n" + "\tor garbage=compact: ... and compact cross reference table\n" + "\tor garbage=deduplicate: ... and remove duplicate objects\n" + ; + void pdf_parse_write_options(fz_context *ctx, pdf_write_options *opts, const char *args) { - int c; + const char *val; memset(opts, 0, sizeof *opts); - while ((c = *args++)) - { - switch (c) - { - case 'd': opts->do_decompress += 1; break; - case 'z': opts->do_compress += 1; break; - case 'f': opts->do_compress_fonts += 1; break; - case 'i': opts->do_compress_images += 1; break; - case 'p': opts->do_pretty += 1; break; - case 'a': opts->do_ascii += 1; break; - case 'g': opts->do_garbage += 1; break; - case 'l': opts->do_linear += 1; break; - case 's': opts->do_clean += 1; break; - default: fz_warn(ctx, "unrecognized pdf-write option: '%c'", c); - } + if (fz_has_option(ctx, args, "decompress", &val)) + opts->do_decompress = opteq(val, "yes"); + if (fz_has_option(ctx, args, "compress", &val)) + opts->do_compress = opteq(val, "yes"); + if (fz_has_option(ctx, args, "compress-fonts", &val)) + opts->do_compress_fonts = opteq(val, "yes"); + if (fz_has_option(ctx, args, "compress-images", &val)) + opts->do_compress_images = opteq(val, "yes"); + if (fz_has_option(ctx, args, "ascii", &val)) + opts->do_ascii = opteq(val, "yes"); + if (fz_has_option(ctx, args, "pretty", &val)) + opts->do_pretty = opteq(val, "yes"); + if (fz_has_option(ctx, args, "linearize", &val)) + opts->do_linear = opteq(val, "yes"); + if (fz_has_option(ctx, args, "sanitize", &val)) + opts->do_clean = opteq(val, "yes"); + if (fz_has_option(ctx, args, "garbage", &val)) + { + if (opteq(val, "yes")) + opts->do_garbage = 1; + else if (opteq(val, "compact")) + opts->do_garbage = 2; + else if (opteq(val, "deduplicate")) + opts->do_garbage = 3; + else + opts->do_garbage = atoi(val); } } diff --git a/source/tools/muconvert.c b/source/tools/muconvert.c index 5e72b5d3..18bbd46b 100644 --- a/source/tools/muconvert.c +++ b/source/tools/muconvert.c @@ -37,10 +37,12 @@ static void usage(void) "\t-o -\toutput file name (%%d for page number)\n" "\t-F -\toutput format (default inferred from output file name)\n" "\t\tcbz, pdf\n" - "\t-O -\toutput format options\n" + "\t-O -\tcomma separated list of options for output format\n" "\n" "\tpages\tcomma separated list of page numbers and ranges\n" + "\n" ); + fprintf(stderr, "%s\n", fz_cbz_write_options_usage); exit(1); } diff --git a/source/tools/murun.c b/source/tools/murun.c index 6d9881a2..9b52558f 100644 --- a/source/tools/murun.c +++ b/source/tools/murun.c @@ -2511,7 +2511,7 @@ static void ffi_PDFDocument_save(js_State *J) fz_context *ctx = js_getcontext(J); pdf_document *pdf = js_touserdata(J, 0, "pdf_document"); const char *filename = js_tostring(J, 1); - const char *options = js_isdefined(J, 2) ? js_tostring(J, 2) : "ga"; + const char *options = js_isdefined(J, 2) ? js_tostring(J, 2) : NULL; pdf_write_options pwo; fz_try(ctx) { diff --git a/source/tools/pdfcreate.c b/source/tools/pdfcreate.c index 839e493e..77f0c819 100644 --- a/source/tools/pdfcreate.c +++ b/source/tools/pdfcreate.c @@ -11,9 +11,15 @@ static void usage(void) fprintf(stderr, "usage: mutool create [-o output.pdf] [-O options] page.txt [page2.txt ...]\n" "\t-o\tname of PDF file to create\n" - "\t-O\tPDF write options\n" - "\tpage.txt file defines page size, fonts, images and contents\n" + "\t-O\tcomma separated list of output options\n" + "\tpage.txt\tcontent stream with annotations for creating resources\n\n" + "Content stream special commands:\n" + "\t%%%%MediaBox LLX LLY URX URY\n" + "\t%%%%Rotate Angle\n" + "\t%%%%Font Name Filename (or base 14 font name)\n" + "\t%%%%Image Name Filename\n\n" ); + fprintf(stderr, "%s\n", fz_pdf_write_options_usage); exit(1); } diff --git a/source/tools/pdfmerge.c b/source/tools/pdfmerge.c index f63a90c7..597bd4ce 100644 --- a/source/tools/pdfmerge.c +++ b/source/tools/pdfmerge.c @@ -11,10 +11,11 @@ static void usage(void) fprintf(stderr, "usage: mutool merge [-o output.pdf] [-O options] input.pdf [pages] [input2.pdf] [pages2] ...\n" "\t-o\tname of PDF file to create\n" - "\t-O\tPDF write options\n" - "\tinput.pdf\tname of first PDF file from which we are copying pages\n" - "\tpages: comma separated list of page ranges (for example: 1-5,6,10-)\n" + "\t-O\tcomma separated list of output options\n" + "\tinput.pdf\tname of input file from which to copy pages\n" + "\tpages\tcomma separated list of page ranges to copy (for example: 1-5,6,10-)\n\n" ); + fprintf(stderr, "%s\n", fz_pdf_write_options_usage); exit(1); } |