diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2018-11-12 17:55:39 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2018-11-12 17:56:22 +0100 |
commit | 24092ea1f4ac9cc128c73f1c4c6b947686bf8e8c (patch) | |
tree | cb5c936d80ae3262db4212263b944f775b858b8c | |
parent | 984ae2a4484c8cf4177349efdfe3aeaa469ba152 (diff) | |
download | mupdf-24092ea1f4ac9cc128c73f1c4c6b947686bf8e8c.tar.xz |
Remove bitrotted and not working PDF portfolio code.
Extracting embedded files can be trivially done with 'mutool show'
or a simple mutool run script.
The portfolio creation code is incomplete, and would require a lot of
work and testing with Adobe in order to be useful.
-rw-r--r-- | docs/index.html | 2 | ||||
-rw-r--r-- | docs/manual-mutool-portfolio.html | 57 | ||||
-rw-r--r-- | include/mupdf/pdf/document.h | 212 | ||||
-rw-r--r-- | platform/win32/libmupdf.vcproj | 4 | ||||
-rw-r--r-- | platform/win32/libmutool.vcproj | 4 | ||||
-rw-r--r-- | source/pdf/pdf-imp.h | 2 | ||||
-rw-r--r-- | source/pdf/pdf-portfolio.c | 716 | ||||
-rw-r--r-- | source/pdf/pdf-xref.c | 1 | ||||
-rw-r--r-- | source/tools/mutool.c | 2 | ||||
-rw-r--r-- | source/tools/pdfportfolio.c | 318 |
10 files changed, 0 insertions, 1318 deletions
diff --git a/docs/index.html b/docs/index.html index b31c42de..f860b19b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -76,8 +76,6 @@ There are also several tools specifically for working with PDF files: <dd>Merge pages from multiple input files into a new PDF. <dt><a href="manual-mutool-create.html">mutool create</a> <dd>Create a new PDF file from a text file with graphics commands. -<dt><a href="manual-mutool-portfolio.html">mutool portfolio</a> -<dd>Manipulate PDF portfolios. </dl> <p> diff --git a/docs/manual-mutool-portfolio.html b/docs/manual-mutool-portfolio.html deleted file mode 100644 index c65b1296..00000000 --- a/docs/manual-mutool-portfolio.html +++ /dev/null @@ -1,57 +0,0 @@ -<!DOCTYPE html> -<html> -<head> -<title>mutool portfolio</title> -<link rel="stylesheet" href="style.css" type="text/css"> -</head> -<body> - -<header> -<h1>mutool portfolio</h1> -</header> - -<article> - -<p> -The portfolio tool can list files in, extract files from, and add files to PDF portfolios. - -<pre> -mutool portfolio [options] portfolio.pdf [actions] -</pre> - -<p> -Options are: - -<dl> -<dt> -p password -<dd> password -<dt> -o filename -<dd> output (defaults to input file) -<dt> -O options -<dd> PDF output options (see <a href="manual-mutool-create.html">mutool create</a>) -</dl> - -<p> -Actions are: - -<dl> -<dt> t -<dd> Display a table listing the contents of the portfolio. -<dt> x <i>N file</i> -<dd> Extract <i>Nth</i> entry to <i>file</i>. -<dt> a <i>file name</i> -<dd> Add contents of <i>file</i> as an entry named <i>name</i>. -</dl> - -<p> -For safety, only use ASCII characters in entry names for now. - -</article> - -<footer> -<a href="http://www.artifex.com/"><img src="artifex-logo.png" align="right"></a> -Copyright © 2006-2018 Artifex Software Inc. -</footer> - -</body> -</html> diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index fb62c739..962440bd 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -5,7 +5,6 @@ typedef struct pdf_lexbuf_s pdf_lexbuf; typedef struct pdf_lexbuf_large_s pdf_lexbuf_large; typedef struct pdf_xref_s pdf_xref; typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor; -typedef struct pdf_portfolio_s pdf_portfolio; typedef struct pdf_page_s pdf_page; typedef struct pdf_annot_s pdf_annot; @@ -259,216 +258,6 @@ void pdf_layer_config_ui_info(fz_context *ctx, pdf_document *doc, int ui, pdf_la void pdf_set_layer_config_as_default(fz_context *ctx, pdf_document *doc); /* - PDF portfolios (or collections) are embedded files. They can - be thought of as tables of information, with an embedded - file per row. For instance a PDF portfolio of an email box might - contain: - - From To Cc Date - message1.pdf ... ... ... ... - message2.pdf ... ... ... ... - - etc. The details of the 'column headings' are known as the Schema. - This includes the order to use for the headings. - - Each row in the table is a portfolio (or collection) entry. -*/ - -/* - pdf_count_portfolio_schema: Get the number of entries in the - portfolio schema used in this document. - - doc: The document in question. -*/ -int pdf_count_portfolio_schema(fz_context *ctx, pdf_document *doc); - -typedef enum -{ - PDF_SCHEMA_NUMBER, - PDF_SCHEMA_SIZE, - PDF_SCHEMA_TEXT, - PDF_SCHEMA_DATE, - PDF_SCHEMA_DESC, - PDF_SCHEMA_MODDATE, - PDF_SCHEMA_CREATIONDATE, - PDF_SCHEMA_FILENAME, - PDF_SCHEMA_UNKNOWN -} pdf_portfolio_schema_type; - -typedef struct -{ - pdf_portfolio_schema_type type; - int visible; - int editable; - pdf_obj *name; -} pdf_portfolio_schema; - -/* - pdf_portfolio_schema_info: Fetch information about a given - portfolio schema entry. - - doc: The document in question. - - entry: A value in the 0..n-1 range, where n is the - value returned from pdf_count_portfolio_schema. - - info: Pointer to structure to fill in. Pointers within - this structure may be set to NULL if no information is - available. -*/ -void pdf_portfolio_schema_info(fz_context *ctx, pdf_document *doc, int entry, pdf_portfolio_schema *info); - -/* - pdf_reorder_portfolio_schema: Reorder the portfolio schema. - - doc: The document in question. - - entry: A value in the 0..n-1 range, where n is the - value returned from pdf_count_portfolio_schema - the - position of the entry to move. - - new_pos: A value in the 0..n-1 range, where n is the - value returned from pdf_count_portfolio_schema - the - position to move the entry to. -*/ -void pdf_reorder_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, int new_pos); - -/* - pdf_rename_portfolio_schema: rename a given portfolio - schema entry. - - doc: The document in question. - - entry: The entry to renumber. - - name: The new name for the portfolio schema - - name_len: The byte length of the name. -*/ -void pdf_rename_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, const char *name, int name_len); - -/* - pdf_delete_portfolio_schema: delete a given portfolio - schema entry. - - doc: The document in question. - - entry: The entry to delete. -*/ -void pdf_delete_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry); - -/* - pdf_add_portfolio_schema: Add a new portfolio schema - entry. - - doc: The document in question. - - entry: The point in the ordering at which to insert the new - schema entry. - - info: Details of the schema entry. -*/ -void pdf_add_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, const pdf_portfolio_schema *info); - -/* - pdf_count_portfolio_entries: Get the number of portfolio entries - in this document. - - doc: The document in question. -*/ -int pdf_count_portfolio_entries(fz_context *ctx, pdf_document *doc); - -/* - pdf_portfolio_entry: Create a buffer containing - a decoded portfolio entry. - - doc: The document in question. - - entry: A value in the 0..m-1 range, where m is the - value returned from pdf_count_portfolio_entries. - - Returns a buffer containing the decoded portfolio - entry. Ownership of the buffer passes to the caller. -*/ -fz_buffer *pdf_portfolio_entry(fz_context *ctx, pdf_document *doc, int entry); - -/* - pdf_portfolio_entry_name: Retrieve the name of - a given portfolio entry. - - doc: The document in question. - - entry: A value in the 0..m-1 range, where m is the - value returned from pdf_count_portfolio_entries. - - name: Pointer to a place to store the pointer to the - object representing the name. This is a borrowed - reference - do not drop it. - - Returns a pointer to the pdf_object representing the - name of the entry. This is a borrowed reference - do not drop - it. -*/ -pdf_obj *pdf_portfolio_entry_name(fz_context *ctx, pdf_document *doc, int entry); - -/* - pdf_portfolio_entry_info: Fetch information about a given - portfolio entry. - - doc: The document in question. - - entry: A value in the 0..m-1 range, where m is the - value returned from pdf_count_portfolio_entries. - - info: Pointer to structure to fill in. Pointers within - this structure may be set to NULL if no information is - available. -*/ -pdf_obj *pdf_portfolio_entry_info(fz_context *ctx, pdf_document *doc, int entry, int schema_entry); - -/* - pdf_add_portfolio_entry: Add a new portfolio entry. - - doc: The document in question. - - name: The name to use for this entry (as used in the - PDF name tree for the collection). - - desc: The description to use for this entry (as used - in the 'Desc' entry in the Collection entry). - - filename: The filename to use for this entry (as used - in the 'F' and 'UF' entries in the collection entry). - - buf: The buffer containing the embedded file to add. - - Returns the entry number for this new entry. -*/ -int pdf_add_portfolio_entry(fz_context *ctx, pdf_document *doc, - const char *name, - const char *desc, - const char *filename, - fz_buffer *buf); - -/* - pdf_set_portfolio_entry_info: Set part of the entry - information for a given portfolio entry. - - doc: The document in question. - - entry: The portfolio entry to set information for. - In the range 0..m-1, where m is the value returned - from pdf_count_portfolio_entries. - - schema_entry: Which schema entry to set (in the - range 0..n-1, where n is the value returned from - pdf_count_portfolio_schema. - - data: The value to set. -*/ -void pdf_set_portfolio_entry_info(fz_context *ctx, pdf_document *doc, int entry, int schema_entry, pdf_obj *data); - -/* Determine whether changes have been made since the document was opened or last saved. */ @@ -559,7 +348,6 @@ struct pdf_document_s int64_t file_size; pdf_crypt *crypt; pdf_ocg_descriptor *ocg; - pdf_portfolio *portfolio; pdf_hotspot hotspot; fz_colorspace *oi; diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj index 50284284..18823802 100644 --- a/platform/win32/libmupdf.vcproj +++ b/platform/win32/libmupdf.vcproj @@ -2388,10 +2388,6 @@ > </File> <File - RelativePath="..\..\source\pdf\pdf-portfolio.c" - > - </File> - <File RelativePath="..\..\source\pdf\pdf-repair.c" > </File> diff --git a/platform/win32/libmutool.vcproj b/platform/win32/libmutool.vcproj index 3a5522ea..0fdb6ada 100644 --- a/platform/win32/libmutool.vcproj +++ b/platform/win32/libmutool.vcproj @@ -833,10 +833,6 @@ > </File> <File - RelativePath="..\..\source\tools\pdfportfolio.c" - > - </File> - <File RelativePath="..\..\source\tools\pdfposter.c" > </File> diff --git a/source/pdf/pdf-imp.h b/source/pdf/pdf-imp.h index 74010a2c..32e39fc9 100644 --- a/source/pdf/pdf-imp.h +++ b/source/pdf/pdf-imp.h @@ -16,6 +16,4 @@ void pdf_drop_ocg(fz_context *ctx, pdf_document *doc); int pdf_is_hidden_ocg(fz_context *ctx, pdf_ocg_descriptor *desc, pdf_obj *rdb, const char *usage, pdf_obj *ocg); -void pdf_drop_portfolio(fz_context *ctx, pdf_document *doc); - #endif diff --git a/source/pdf/pdf-portfolio.c b/source/pdf/pdf-portfolio.c deleted file mode 100644 index eb33643b..00000000 --- a/source/pdf/pdf-portfolio.c +++ /dev/null @@ -1,716 +0,0 @@ -#include "mupdf/fitz.h" -#include "mupdf/pdf.h" -#include "pdf-imp.h" - -#include <string.h> - -/* - PDF Portfolio is just a sorted list of schema entries. -*/ -struct pdf_portfolio_s -{ - pdf_obj *key; - pdf_obj *val; - int sort; - pdf_portfolio_schema entry; - pdf_portfolio *next; -}; - -static void -load_portfolio(fz_context *ctx, pdf_document *doc) -{ - pdf_obj *obj; - int i, n; - pdf_portfolio **pp; - - if (doc->portfolio) - return; - - obj = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Collection), PDF_NAME(Schema), NULL); - - n = pdf_dict_len(ctx, obj); - for (i = 0; i < n; i++) - { - pdf_obj *k = pdf_dict_get_key(ctx, obj, i); - pdf_obj *v = pdf_dict_get_val(ctx, obj, i); - int sort = pdf_dict_get_int(ctx, v, PDF_NAME(O)); - pdf_obj *eo = pdf_dict_get(ctx, v, PDF_NAME(E)); - int editable = eo ? pdf_to_bool(ctx, eo) : 0; - pdf_obj *vo = pdf_dict_get(ctx, v, PDF_NAME(V)); - int visible = vo ? pdf_to_bool(ctx, vo) : 1; - const char *subtype = pdf_to_name(ctx, pdf_dict_get(ctx, v, PDF_NAME(Subtype))); - pdf_obj *name = pdf_dict_get(ctx, v, PDF_NAME(N)); - pdf_portfolio *p = fz_malloc_struct(ctx, pdf_portfolio); - p->key = pdf_keep_obj(ctx, k); - p->val = pdf_keep_obj(ctx, v); - p->sort = sort; - p->entry.visible = visible; - p->entry.editable = editable; - p->entry.name = pdf_keep_obj(ctx, name); - if (!strcmp(subtype, "S")) - p->entry.type = PDF_SCHEMA_TEXT; - else if (!strcmp(subtype, "D")) - p->entry.type = PDF_SCHEMA_DATE; - else if (!strcmp(subtype, "N")) - p->entry.type = PDF_SCHEMA_NUMBER; - else if (!strcmp(subtype, "F")) - p->entry.type = PDF_SCHEMA_FILENAME; - else if (!strcmp(subtype, "Desc")) - p->entry.type = PDF_SCHEMA_DESC; - else if (!strcmp(subtype, "ModDate")) - p->entry.type = PDF_SCHEMA_MODDATE; - else if (!strcmp(subtype, "CreationDate")) - p->entry.type = PDF_SCHEMA_CREATIONDATE; - else if (!strcmp(subtype, "Size")) - p->entry.type = PDF_SCHEMA_SIZE; - else - p->entry.type = PDF_SCHEMA_UNKNOWN; - - /* Now insert p */ - pp = &doc->portfolio; - - while (*pp && (*pp)->sort <= p->sort) - pp = &(*pp)->next; - - p->next = *pp; - *pp = p; - } -} - -int pdf_count_portfolio_schema(fz_context *ctx, pdf_document *doc) -{ - pdf_portfolio *port; - int n; - - load_portfolio(ctx, doc); - - n = 0; - for (port = doc->portfolio; port; port = port->next) - ++n; - - return n; -} - -/* - pdf_portfolio_schema_info: Fetch information about a given - portfolio schema entry. - - doc: The document in question. - - entry: A value in the 0..n-1 range, where n is the - value returned from pdf_count_portfolio_schema. - - info: Pointer to structure to fill in. Pointers within - this structure may be set to NULL if no information is - available. -*/ -void pdf_portfolio_schema_info(fz_context *ctx, pdf_document *doc, int entry, pdf_portfolio_schema *info) -{ - pdf_portfolio *p; - - load_portfolio(ctx, doc); - - p = doc->portfolio; - while (p && entry > 0) - p = p->next, entry--; - - if (p == NULL || entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "entry out of range in pdf_portfolio_schema_info"); - - *info = p->entry; -} - -void pdf_reorder_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, int new_pos) -{ - pdf_portfolio **pp; - pdf_portfolio *p; - - load_portfolio(ctx, doc); - - /* Take p out */ - pp = &doc->portfolio; - while (*pp && entry > 0) - pp = &(*pp)->next, entry--; - p = *pp; - if (p == NULL || entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "entry out of range in pdf_reorder_portfolio_schema"); - *pp = p->next; - - /* Put p back in */ - pp = &doc->portfolio; - while (*pp && new_pos > 0) - pp = &(*pp)->next, new_pos--; - p->next = *pp; - *pp = p; - - /* Rewrite the underlying orderings */ - for (p = doc->portfolio, entry = 0; p; p = p->next, entry++) - pdf_dict_put_int(ctx, p->val, PDF_NAME(O), entry); -} - -void pdf_rename_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, const char *name, int name_len) -{ - pdf_portfolio *p; - pdf_obj *s; - - load_portfolio(ctx, doc); - - p = doc->portfolio; - while (p && entry > 0) - p = p->next, entry--; - - if (p == NULL || entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "entry out of range in pdf_rename_portfolio_schema"); - - s = pdf_new_string(ctx, name, name_len); - pdf_drop_obj(ctx, p->entry.name); - p->entry.name = s; - pdf_dict_put(ctx, p->val, PDF_NAME(N), s); -} - -typedef int (pdf_name_tree_map_fn)(fz_context *ctx, pdf_obj *container, pdf_obj *key, pdf_obj *val, void *arg); - -static int -do_name_tree_map(fz_context *ctx, pdf_obj *tree, pdf_name_tree_map_fn *fn, void *arg) -{ - int i; - int n = 0; - int m = 0; - - fz_var(n); - fz_var(m); - - if (pdf_mark_obj(ctx, tree)) - fz_throw(ctx, FZ_ERROR_GENERIC, "Recursive name tree!"); - - fz_try(ctx) - { - pdf_obj *arr = pdf_dict_get(ctx, tree, PDF_NAME(Kids)); - n = pdf_array_len(ctx, arr); - - for (i = n; i > 0;) - { - i--; - if (do_name_tree_map(ctx, pdf_array_get(ctx, arr, i), fn, arg)) - { - pdf_array_delete(ctx, arr, i); - n--; - } - } - - arr = pdf_dict_get(ctx, tree, PDF_NAME(Names)); - m = pdf_array_len(ctx, arr); - - if (m & 1) - fz_throw(ctx, FZ_ERROR_GENERIC, "Malformed Names array"); - - for (i = m; i > 0;) - { - i -= 2; - if (fn(ctx, tree, pdf_array_get(ctx, arr, i), pdf_array_get(ctx, arr, i+1), arg)) - { - pdf_array_delete(ctx, arr, i+1); - pdf_array_delete(ctx, arr, i); - m -= 2; - } - } - } - fz_always(ctx) - pdf_unmark_obj(ctx, tree); - fz_catch(ctx) - fz_rethrow(ctx); - - return n == 0 && m == 0; -} - -void pdf_name_tree_map(fz_context *ctx, pdf_obj *tree, pdf_name_tree_map_fn *fn, void *arg) -{ - (void)do_name_tree_map(ctx, tree, fn, arg); -} - -static int delete_from_node(fz_context *ctx, pdf_obj *container, pdf_obj *key, pdf_obj *val, void *arg) -{ - pdf_obj *delete_key = (pdf_obj *)arg; - - pdf_dict_del(ctx, pdf_dict_get(ctx, val, PDF_NAME(CI)), delete_key); - - return 0; -} - -void pdf_delete_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry) -{ - pdf_portfolio **pp; - pdf_portfolio *p; - pdf_obj *s; - - load_portfolio(ctx, doc); - - pp = &doc->portfolio; - while (*pp && entry > 0) - pp = &(*pp)->next, entry--; - - p = *pp; - if (p == NULL || entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "entry out of range in pdf_delete_portfolio_schema"); - *pp = p->next; - - /* Delete the key from the schema */ - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Collection), PDF_NAME(Schema), NULL); - pdf_dict_del(ctx, s, p->key); - - /* Delete this entry from all the collection entries */ - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Names), PDF_NAME(EmbeddedFiles), NULL); - pdf_name_tree_map(ctx, s, delete_from_node, p->key); - - pdf_drop_obj(ctx, p->entry.name); - pdf_drop_obj(ctx, p->key); - pdf_drop_obj(ctx, p->val); - fz_free(ctx, p); -} - -void pdf_add_portfolio_schema(fz_context *ctx, pdf_document *doc, int entry, const pdf_portfolio_schema *info) -{ - pdf_portfolio **pp; - pdf_portfolio *p; - pdf_obj *s; - pdf_obj *sc = NULL; - int num; - char str_name[32]; - pdf_obj *num_name = NULL; - - load_portfolio(ctx, doc); - - fz_var(num_name); - fz_var(sc); - - pp = &doc->portfolio; - while (*pp && entry > 0) - pp = &(*pp)->next, entry--; - - fz_try(ctx) - { - /* Find a name for the new schema entry */ - num = 0; - do - { - pdf_drop_obj(ctx, num_name); - num_name = NULL; - num++; - fz_snprintf(str_name, sizeof str_name, "%d", num); - num_name = pdf_new_name(ctx, str_name); - p = doc->portfolio; - for (p = doc->portfolio; p; p = p->next) - if (pdf_name_eq(ctx, num_name, p->key)) - break; - } - while (p); - - sc = pdf_new_dict(ctx, doc, 4); - pdf_dict_put_bool(ctx, sc, PDF_NAME(E), !!info->editable); - pdf_dict_put_bool(ctx, sc, PDF_NAME(V), !!info->visible); - pdf_dict_put_drop(ctx, sc, PDF_NAME(N), info->name); - pdf_dict_put(ctx, sc, PDF_NAME(Subtype), PDF_NAME(S)); - - /* Add to our linked list (in the correct sorted place) */ - p = fz_malloc_struct(ctx, pdf_portfolio); - p->entry = *info; - p->sort = 0; /* Will be rewritten in a mo */ - p->key = pdf_keep_obj(ctx, num_name); - p->val = pdf_keep_obj(ctx, sc); - p->next = *pp; - *pp = p; - - /* Add the key to the schema */ - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Collection), PDF_NAME(Schema), NULL); - pdf_dict_put(ctx, s, num_name, sc); - - /* Renumber the schema entries */ - for (num = 0, p = doc->portfolio; p; num++, p = p->next) - { - pdf_dict_put_int(ctx, p->val, PDF_NAME(O), num); - p->sort = num; - } - } - fz_always(ctx) - { - pdf_drop_obj(ctx, num_name); - pdf_drop_obj(ctx, sc); - } - fz_catch(ctx) - fz_rethrow(ctx); -} - -static int count_nodes(fz_context *ctx, pdf_obj *container, pdf_obj *key, pdf_obj *val, void *arg) -{ - int *count = (int *)arg; - - *count += 1; - - return 0; -} - -/* - pdf_count_portfolio_entries: Get the number of portfolio entries - in this document. - - doc: The document in question. -*/ -int pdf_count_portfolio_entries(fz_context *ctx, pdf_document *doc) -{ - pdf_obj *s; - int count; - - load_portfolio(ctx, doc); - - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Names), PDF_NAME(EmbeddedFiles), NULL); - count = 0; - pdf_name_tree_map(ctx, s, count_nodes, &count); - - return count; -} - -struct find_data { - pdf_obj *key; - pdf_obj *val; - int count; -}; - -static int find_entry(fz_context *ctx, pdf_obj *container, pdf_obj *key, pdf_obj *val, void *arg) -{ - struct find_data *data = (struct find_data *)arg; - - if (data->count == 0) - { - data->key = key; - data->val = val; - } - data->count--; - - return 0; -} - -/* - pdf_portfolio_entry_info: Fetch information about a given - portfolio entry. - - doc: The document in question. - - entry: A value in the 0..n-1 range, where n is the - value returned from pdf_count_portfolio. - - Returns pdf_object representing this entry. This reference - is borrowed, so call pdf_keep_obj on it if you wish to keep - it. -*/ -static pdf_obj *pdf_portfolio_entry_obj_name(fz_context *ctx, pdf_document *doc, int entry, pdf_obj **name) -{ - struct find_data data; - pdf_obj *s; - - if (name) - *name = NULL; - - load_portfolio(ctx, doc); - - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Names), PDF_NAME(EmbeddedFiles), NULL); - data.count = entry; - data.key = NULL; - data.val = NULL; - pdf_name_tree_map(ctx, s, find_entry, &data); - - if (name) - *name = data.key; - return data.val; -} - -static pdf_obj *pdf_portfolio_entry_obj(fz_context *ctx, pdf_document *doc, int entry) -{ - pdf_obj *name; - - return pdf_portfolio_entry_obj_name(ctx, doc, entry, &name); -} - -pdf_obj *pdf_portfolio_entry_name(fz_context *ctx, pdf_document *doc, int entry) -{ - pdf_obj *name; - - (void)pdf_portfolio_entry_obj_name(ctx, doc, entry, &name); - return name; -} - -fz_buffer *pdf_portfolio_entry(fz_context *ctx, pdf_document *doc, int entry) -{ - pdf_obj *obj = pdf_portfolio_entry_obj(ctx, doc, entry); - - return pdf_load_stream(ctx, pdf_dict_getl(ctx, obj, PDF_NAME(EF), PDF_NAME(F), NULL)); -} - -pdf_obj *pdf_portfolio_entry_info(fz_context *ctx, pdf_document *doc, int entry, int schema_entry) -{ - pdf_obj *obj = pdf_portfolio_entry_obj_name(ctx, doc, entry, NULL); - pdf_portfolio *p; - pdf_obj *lookup; - int ef = 0; - - if (!obj) - return NULL; - - for (p = doc->portfolio; p != NULL && schema_entry > 0; p = p->next, schema_entry--); - - if (schema_entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "schema_entry out of range"); - - switch (p->entry.type) - { - default: - case PDF_SCHEMA_TEXT: - case PDF_SCHEMA_DATE: - case PDF_SCHEMA_NUMBER: - lookup = NULL; - break; - case PDF_SCHEMA_FILENAME: - lookup = PDF_NAME(UF); - break; - case PDF_SCHEMA_DESC: - lookup = PDF_NAME(Desc); - break; - case PDF_SCHEMA_MODDATE: - lookup = PDF_NAME(ModDate); - ef = 1; - break; - case PDF_SCHEMA_CREATIONDATE: - lookup = PDF_NAME(CreationDate); - ef = 1; - break; - case PDF_SCHEMA_SIZE: - lookup = PDF_NAME(Size); - ef = 1; - break; - } - if (lookup) - { - pdf_obj *res; - - if (ef) - obj = pdf_dict_getl(ctx, obj, PDF_NAME(EF), PDF_NAME(F), PDF_NAME(Params), NULL); - res = pdf_dict_get(ctx, obj, lookup); - if (res == NULL && pdf_name_eq(ctx, lookup, PDF_NAME(UF))) - res = pdf_dict_get(ctx, obj, PDF_NAME(F)); - return res; - } - return pdf_dict_getl(ctx, obj, PDF_NAME(CI), p->key, NULL); -} - -typedef struct -{ - pdf_obj *key; - pdf_obj *found; - int found_index; - pdf_obj *last; - int last_index; - int entry; -} find_data; - -static int -find_position(fz_context *ctx, pdf_obj *container, pdf_obj *key, pdf_obj *val, void *arg) -{ - find_data *data = (find_data *)arg; - - if (data->found) - return 0; - data->entry++; - if (data->last != container) - { - data->last = container; - data->last_index = 0; - } - else - data->last_index++; - if (pdf_objcmp(ctx, key, data->key) > 0) - { - data->found = container; - data->found_index = data->last_index; - } - return 0; -} - -static int -pdf_name_tree_insert(fz_context *ctx, pdf_document *doc, pdf_obj *tree, pdf_obj *key, pdf_obj *val) -{ - find_data data; - pdf_obj *names, *limits, *limit0, *limit1; - - data.key = key; - data.found = NULL; - data.found_index = 0; - data.last = NULL; - data.last_index = 0; - data.entry = 0; - pdf_name_tree_map(ctx, tree, find_position, &data); - - if (!data.found) - { - data.found = data.last; - data.found_index = data.last_index; - } - if (!data.found) - { - /* Completely empty name tree! */ - pdf_dict_put_array(ctx, tree, PDF_NAME(Names), 2); - pdf_dict_put_array(ctx, tree, PDF_NAME(Limits), 2); - data.found = tree; - data.found_index = 0; - } - - names = pdf_dict_get(ctx, data.found, PDF_NAME(Names)); - if (names == NULL) - names = pdf_dict_put_array(ctx, data.found, PDF_NAME(Names), 2); - pdf_array_insert(ctx, names, key, 2*data.found_index); - pdf_array_insert(ctx, names, val, 2*data.found_index+1); - - limits = pdf_dict_get(ctx, data.found, PDF_NAME(Limits)); - if (limits == NULL) - limits = pdf_dict_put_array(ctx, data.found, PDF_NAME(Limits), 2); - limit0 = pdf_array_get(ctx, limits, 0); - limit1 = pdf_array_get(ctx, limits, 1); - if (!pdf_is_string(ctx, limit0) || data.found_index == 0) - pdf_array_put(ctx, limits, 0, key); - if (!pdf_is_string(ctx, limit1) || 2 * (data.found_index+1) == pdf_array_len(ctx, limits)) - pdf_array_put(ctx, limits, 1, key); - - return data.entry; -} - -int pdf_add_portfolio_entry(fz_context *ctx, pdf_document *doc, - const char *name, - const char *desc, - const char *filename, - fz_buffer *buf) -{ - int len, entry = 0; - pdf_obj *ef, *f, *params, *s; - pdf_obj *key; - pdf_obj *val = NULL; - - fz_var(val); - - load_portfolio(ctx, doc); - - /* Portfolios were introduced in PDF 1.7. */ - if (doc->version < 17) - doc->version = 17; - - key = pdf_new_text_string(ctx, name); - fz_try(ctx) - { - val = pdf_new_dict(ctx, doc, 6); - pdf_dict_put_dict(ctx, val, PDF_NAME(CI), 4); - ef = pdf_dict_put_dict(ctx, val, PDF_NAME(EF), 4); - pdf_dict_put_string(ctx, val, PDF_NAME(F), filename, strlen(filename)); - pdf_dict_put_text_string(ctx, val, PDF_NAME(UF), filename); - pdf_dict_put_text_string(ctx, val, PDF_NAME(Desc), desc); - pdf_dict_put(ctx, val, PDF_NAME(Type), PDF_NAME(Filespec)); - pdf_dict_put_drop(ctx, ef, PDF_NAME(F), (f = pdf_add_stream(ctx, doc, buf, NULL, 0))); - len = fz_buffer_storage(ctx, buf, NULL); - pdf_dict_put_int(ctx, f, PDF_NAME(DL), len); - pdf_dict_put_int(ctx, f, PDF_NAME(Length), len); - params = pdf_dict_put_dict(ctx, f, PDF_NAME(Params), 4); - pdf_dict_put_int(ctx, params, PDF_NAME(Size), len); - - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Collection), NULL); - if (s == NULL) - { - s = pdf_new_dict(ctx, doc, 4); - pdf_dict_putl_drop(ctx, pdf_trailer(ctx, doc), s, PDF_NAME(Root), PDF_NAME(Collection), NULL); - } - - s = pdf_dict_getl(ctx, pdf_trailer(ctx, doc), PDF_NAME(Root), PDF_NAME(Names), PDF_NAME(EmbeddedFiles), NULL); - if (s == NULL) - { - s = pdf_new_dict(ctx, doc, 4); - pdf_dict_putl_drop(ctx, pdf_trailer(ctx, doc), s, PDF_NAME(Root), PDF_NAME(Names), PDF_NAME(EmbeddedFiles), NULL); - } - entry = pdf_name_tree_insert(ctx, doc, s, key, val); - } - fz_always(ctx) - { - pdf_drop_obj(ctx, key); - pdf_drop_obj(ctx, val); - } - fz_catch(ctx) - fz_rethrow(ctx); - - return entry; -} - -void pdf_set_portfolio_entry_info(fz_context *ctx, pdf_document *doc, int entry, int schema_entry, pdf_obj *data) -{ - pdf_portfolio *p; - pdf_obj *obj, *lookup; - int ef = 0; - - load_portfolio(ctx, doc); - - obj = pdf_portfolio_entry_obj_name(ctx, doc, entry, NULL); - if (!obj) - fz_throw(ctx, FZ_ERROR_GENERIC, "Can't set info on non existent portfolio entry"); - - for (p = doc->portfolio; p != NULL && schema_entry > 0; p = p->next, schema_entry--); - - if (schema_entry) - fz_throw(ctx, FZ_ERROR_GENERIC, "schema_entry out of range"); - - switch (p->entry.type) - { - default: - case PDF_SCHEMA_TEXT: - case PDF_SCHEMA_DATE: - case PDF_SCHEMA_NUMBER: - lookup = NULL; - break; - case PDF_SCHEMA_FILENAME: - lookup = PDF_NAME(UF); - break; - case PDF_SCHEMA_DESC: - lookup = PDF_NAME(Desc); - break; - case PDF_SCHEMA_MODDATE: - lookup = PDF_NAME(ModDate); - ef = 1; - break; - case PDF_SCHEMA_CREATIONDATE: - lookup = PDF_NAME(CreationDate); - ef = 1; - break; - case PDF_SCHEMA_SIZE: - fz_throw(ctx, FZ_ERROR_GENERIC, "Can't set size!"); - break; - } - if (lookup) - { - if (ef) - obj = pdf_dict_getl(ctx, obj, PDF_NAME(EF), PDF_NAME(F), PDF_NAME(Params), NULL); - pdf_dict_put(ctx, obj, lookup, data); - if (pdf_name_eq(ctx, lookup, PDF_NAME(UF))) - pdf_dict_put(ctx, obj, PDF_NAME(F), data); - return; - } - pdf_dict_putl(ctx, obj, data, PDF_NAME(CI), p->key, NULL); -} - -void pdf_drop_portfolio(fz_context *ctx, pdf_document *doc) -{ - if (!doc) - return; - - while (doc->portfolio) - { - pdf_portfolio *p = doc->portfolio; - doc->portfolio = p->next; - - pdf_drop_obj(ctx, p->entry.name); - pdf_drop_obj(ctx, p->key); - pdf_drop_obj(ctx, p->val); - fz_free(ctx, p); - } -} diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 4409681e..911ff249 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -1538,7 +1538,6 @@ pdf_drop_document_imp(fz_context *ctx, pdf_document *doc) fz_free(ctx, doc->type3_fonts); pdf_drop_ocg(ctx, doc); - pdf_drop_portfolio(ctx, doc); pdf_empty_store(ctx, doc); diff --git a/source/tools/mutool.c b/source/tools/mutool.c index 892e7c6c..8eca9b17 100644 --- a/source/tools/mutool.c +++ b/source/tools/mutool.c @@ -24,7 +24,6 @@ int pdfshow_main(int argc, char *argv[]); int pdfpages_main(int argc, char *argv[]); int pdfcreate_main(int argc, char *argv[]); int pdfmerge_main(int argc, char *argv[]); -int pdfportfolio_main(int argc, char *argv[]); int pdfsign_main(int argc, char *argv[]); int cmapdump_main(int argc, char *argv[]); @@ -50,7 +49,6 @@ static struct { { pdfinfo_main, "info", "show information about pdf resources" }, { pdfmerge_main, "merge", "merge pages from multiple pdf sources into a new pdf" }, { pdfpages_main, "pages", "show information about pdf pages" }, - { pdfportfolio_main, "portfolio", "manipulate PDF portfolios" }, { pdfposter_main, "poster", "split large page into many tiles" }, { pdfsign_main, "sign", "manipulate PDF digital signatures" }, #endif diff --git a/source/tools/pdfportfolio.c b/source/tools/pdfportfolio.c deleted file mode 100644 index 1ffa2242..00000000 --- a/source/tools/pdfportfolio.c +++ /dev/null @@ -1,318 +0,0 @@ -/* - * pdfportfolio -- manipulate embedded files in a PDF - */ - -#include "mupdf/fitz.h" -#include "mupdf/pdf.h" - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> - -static pdf_document *doc = NULL; -static fz_context *ctx = NULL; - -static void usage(void) -{ - fprintf(stderr, "usage: mutool portfolio [options] portfolio.pdf [actions]\n"); - fprintf(stderr, "\nOptions 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, "\nActions are:\n"); - fprintf(stderr, "\tt\tdisplay a table listing the contents of the portfolio\n"); - fprintf(stderr, "\tx N <file>\n\t\textract Nth entry to <file>\n"); - fprintf(stderr, "\ta <file> <name>\n\t\tadd contents of <file> as an entry named <name>\n"); - fprintf(stderr, "\nFor safety, only use ASCII characters in entry names for now.\n"); - exit(1); -} - -static void -safe_print_pdf_string(fz_context *ctx, unsigned char *str, int len) -{ - int c; - - if (len > 1 && str[0] == 0xFE && str[1] == 0xFF) - { - str += 2; - len -= 2; - while (len) - { - c = (*str++<<8); - c += *str++; - if (c >= 32 && c != 127 && c < 256) - fprintf(stderr, "%c", c); - else - fprintf(stderr, "<%04x>", c); - len -= 2; - }; - } - else - { - while (len) - { - c = *str++; - if (c >= 32 && c != 127 && c < 256) - fprintf(stderr, "%c", c); - else - fprintf(stderr, "<%02x>", c); - len--; - }; - } -} - -static void -safe_print_pdf_obj(fz_context *ctx, pdf_obj *obj, const char *dflt) -{ - if (obj == NULL) - fprintf(stderr, "%s", dflt); - else if (pdf_is_string(ctx, obj)) - safe_print_pdf_string(ctx, (unsigned char *)pdf_to_str_buf(ctx, obj), pdf_to_str_len(ctx, obj)); - else - pdf_print_obj(ctx, fz_stderr(ctx), obj, 1); -} - -static void -pdfportfolio_list(void) -{ - /* 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, /* name */ - ename, /* desc */ - filename, /* filename */ - buf); - fz_drop_buffer(ctx, buf); -} - -int pdfportfolio_main(int argc, char **argv) -{ - char *password = ""; - char *outfile = NULL; - char *outopts = "compress"; - char *infile; - int exit_code = 0; - int do_save = 0; - int has_old_file = 0; - int c; - - 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; - } - } - - if (fz_optind == argc) - usage(); - - infile = argv[fz_optind++]; - if (!outfile) - outfile = infile; - - ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); - if (!ctx) - { - fprintf(stderr, "cannot initialise context\n"); - exit(1); - } - - 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); - has_old_file = 1; - } - 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 unsigned 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, PDF_SIMPLE_ENCODING_LATIN); - fz_drop_font(ctx, font); - - resources = pdf_add_new_dict(ctx, doc, 1); - pdf_dict_putp_drop(ctx, resources, "Font/Tm", font_obj); - - contents = fz_new_buffer_from_shared_data(ctx, (const unsigned char *)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); - pdf_drop_obj(ctx, resources); - fz_drop_buffer(ctx, contents); - } - } - - if (fz_optind == argc) - usage(); - - while (fz_optind < argc) - { - fz_optarg = argv[fz_optind++]; - fz_try(ctx) - { - switch (*fz_optarg) - { - default: - usage(); - break; - case 't': - pdfportfolio_list(); - break; - case 'x': - pdfportfolio_extract(argc, argv); - break; - case 'a': - pdfportfolio_add(argc, argv); - do_save = 1; - break; - } - } - fz_catch(ctx) - { - /* Swallow any errors */ - exit_code = 1; - } - } - - if (do_save && !exit_code) - { - pdf_write_options opts; - pdf_parse_write_options(ctx, &opts, outopts); - if (has_old_file && infile == outfile) - opts.do_incremental = 1; - pdf_save_document(ctx, doc, outfile, &opts); - } - - pdf_drop_document(ctx, doc); - fz_flush_warnings(ctx); - fz_drop_context(ctx); - return exit_code; -} |