summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/pdf/document.h1
-rw-r--r--platform/gl/gl-annotate.c1
-rw-r--r--source/pdf/pdf-write.c57
-rw-r--r--source/tools/pdfclean.c3
4 files changed, 51 insertions, 11 deletions
diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h
index 7d2110b7..27e3d4f4 100644
--- a/include/mupdf/pdf/document.h
+++ b/include/mupdf/pdf/document.h
@@ -879,6 +879,7 @@ struct pdf_write_options_s
int do_linear; /* Write linearised. */
int do_clean; /* Clean content streams. */
int do_sanitize; /* Sanitize content streams. */
+ int do_decrypt; /* Save without decryption. */
int continue_on_error; /* If set, errors are (optionally) counted and writing continues. */
int *errors; /* Pointer to a place to store a count of errors */
};
diff --git a/platform/gl/gl-annotate.c b/platform/gl/gl-annotate.c
index 48f0555e..155cac24 100644
--- a/platform/gl/gl-annotate.c
+++ b/platform/gl/gl-annotate.c
@@ -39,6 +39,7 @@ static void save_pdf_options(void)
ui_checkbox("Compress images", &save_opts.do_compress_images);
ui_checkbox("Compress fonts", &save_opts.do_compress_fonts);
ui_checkbox("Decompress", &save_opts.do_decompress);
+ ui_checkbox("Decrypt", &save_opts.do_decrypt);
ui_checkbox("Garbage collect", &save_opts.do_garbage);
ui_checkbox("Linearize", &save_opts.do_linear);
ui_checkbox("Clean syntax", &save_opts.do_clean);
diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c
index 6417e2fa..0fe311c1 100644
--- a/source/pdf/pdf-write.c
+++ b/source/pdf/pdf-write.c
@@ -68,6 +68,7 @@ struct pdf_write_state_s
int do_garbage;
int do_linear;
int do_clean;
+ int do_decrypt;
int list_len;
int *use_list;
@@ -1705,13 +1706,25 @@ static void copystream(fz_context *ctx, pdf_document *doc, pdf_write_state *opts
addhexfilter(ctx, doc, obj);
}
- pdf_dict_put_int(ctx, obj, PDF_NAME(Length), pdf_encrypted_len(ctx, doc->crypt, num, gen, (int)len));
-
fz_write_printf(ctx, opts->out, "%d %d obj\n", num, gen);
- pdf_print_encrypted_obj(ctx, opts->out, obj, opts->do_tight, doc->crypt, num, gen);
- fz_write_string(ctx, opts->out, "\nstream\n");
- pdf_encrypt_data(ctx, doc->crypt, num, gen, write_data, opts->out, data, len);
+
+ if (opts->do_decrypt)
+ {
+ pdf_dict_put_int(ctx, obj, PDF_NAME(Length), len);
+ pdf_print_obj(ctx, opts->out, obj, opts->do_tight);
+ fz_write_string(ctx, opts->out, "\nstream\n");
+ fz_write_data(ctx, opts->out, data, len);
+ }
+ else
+ {
+ pdf_dict_put_int(ctx, obj, PDF_NAME(Length), pdf_encrypted_len(ctx, doc->crypt, num, gen, (int)len));
+ pdf_print_encrypted_obj(ctx, opts->out, obj, opts->do_tight, doc->crypt, num, gen);
+ fz_write_string(ctx, opts->out, "\nstream\n");
+ pdf_encrypt_data(ctx, doc->crypt, num, gen, write_data, opts->out, data, len);
+ }
+
fz_write_string(ctx, opts->out, "\nendstream\nendobj\n\n");
+
}
fz_always(ctx)
{
@@ -1769,12 +1782,23 @@ static void expandstream(fz_context *ctx, pdf_document *doc, pdf_write_state *op
addhexfilter(ctx, doc, obj);
}
- pdf_dict_put_int(ctx, obj, PDF_NAME(Length), pdf_encrypted_len(ctx, doc->crypt, num, gen, (int)len));
-
fz_write_printf(ctx, opts->out, "%d %d obj\n", num, gen);
- pdf_print_encrypted_obj(ctx, opts->out, obj, opts->do_tight, doc->crypt, num, gen);
- fz_write_string(ctx, opts->out, "\nstream\n");
- pdf_encrypt_data(ctx, doc->crypt, num, gen, write_data, opts->out, data, len);
+
+ if (opts->do_decrypt)
+ {
+ pdf_dict_put_int(ctx, obj, PDF_NAME(Length), len);
+ pdf_print_obj(ctx, opts->out, obj, opts->do_tight);
+ fz_write_string(ctx, opts->out, "\nstream\n");
+ fz_write_data(ctx, opts->out, data, len);
+ }
+ else
+ {
+ pdf_dict_put_int(ctx, obj, PDF_NAME(Length), pdf_encrypted_len(ctx, doc->crypt, num, gen, (int)len));
+ pdf_print_encrypted_obj(ctx, opts->out, obj, opts->do_tight, doc->crypt, num, gen);
+ fz_write_string(ctx, opts->out, "\nstream\n");
+ pdf_encrypt_data(ctx, doc->crypt, num, gen, write_data, opts->out, data, len);
+ }
+
fz_write_string(ctx, opts->out, "\nendstream\nendobj\n\n");
}
fz_always(ctx)
@@ -2800,6 +2824,7 @@ static void initialise_write_state(fz_context *ctx, pdf_document *doc, const pdf
opts->do_garbage = in_opts->do_garbage;
opts->do_linear = in_opts->do_linear;
opts->do_clean = in_opts->do_clean;
+ opts->do_decrypt = in_opts->do_decrypt;
opts->start = 0;
opts->main_xref_offset = INT_MIN;
@@ -2885,6 +2910,8 @@ pdf_parse_write_options(fz_context *ctx, pdf_write_options *opts, const char *ar
opts->do_incremental = fz_option_eq(val, "yes");
if (fz_has_option(ctx, args, "continue-on-error", &val))
opts->continue_on_error = fz_option_eq(val, "yes");
+ if (fz_has_option(ctx, args, "decrypt", &val))
+ opts->do_decrypt = fz_option_eq(val, "yes");
if (fz_has_option(ctx, args, "garbage", &val))
{
if (fz_option_eq(val, "yes"))
@@ -2966,6 +2993,12 @@ do_pdf_save_document(fz_context *ctx, pdf_document *doc, pdf_write_state *opts,
{
initialise_write_state(ctx, doc, in_opts, opts);
+ /* Remove encryption dictionary if saving without encryption. */
+ if (opts->do_decrypt)
+ {
+ pdf_dict_del(ctx, pdf_trailer(ctx, doc), PDF_NAME(Encrypt));
+ }
+
/* Make sure any objects hidden in compressed streams have been loaded */
if (!opts->do_incremental)
{
@@ -3157,6 +3190,8 @@ void pdf_write_document(fz_context *ctx, pdf_document *doc, fz_output *out, pdf_
fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with garbage collection");
if (in_opts->do_incremental && in_opts->do_linear)
fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with linearisation");
+ if (in_opts->do_incremental && in_opts->do_decrypt)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with decryption");
if (pdf_has_unsaved_sigs(ctx, doc) && !out->as_stream)
fz_throw(ctx, FZ_ERROR_GENERIC, "Can't write pdf that has unsaved sigs to a fz_output unless it supports fz_stream_from_output!");
@@ -3186,6 +3221,8 @@ void pdf_save_document(fz_context *ctx, pdf_document *doc, const char *filename,
fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with garbage collection");
if (in_opts->do_incremental && in_opts->do_linear)
fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with linearisation");
+ if (in_opts->do_incremental && in_opts->do_decrypt)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "Can't do incremental writes with decryption");
prepare_for_save(ctx, doc, in_opts);
diff --git a/source/tools/pdfclean.c b/source/tools/pdfclean.c
index 6d5a69be..0e7a464a 100644
--- a/source/tools/pdfclean.c
+++ b/source/tools/pdfclean.c
@@ -51,7 +51,7 @@ int pdfclean_main(int argc, char **argv)
opts.continue_on_error = 1;
opts.errors = &errors;
- while ((c = fz_getopt(argc, argv, "adfgilp:scz")) != -1)
+ while ((c = fz_getopt(argc, argv, "adfgilp:sczD")) != -1)
{
switch (c)
{
@@ -66,6 +66,7 @@ int pdfclean_main(int argc, char **argv)
case 'l': opts.do_linear += 1; break;
case 'c': opts.do_clean += 1; break;
case 's': opts.do_sanitize += 1; break;
+ case 'D': opts.do_decrypt += 1; break;
default: usage(); break;
}
}