362 lines
10 KiB
C
362 lines
10 KiB
C
#ifndef MUPDF_PDF_DOCUMENT_H
|
|
#define MUPDF_PDF_DOCUMENT_H
|
|
|
|
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_page_s pdf_page;
|
|
typedef struct pdf_annot_s pdf_annot;
|
|
typedef struct pdf_annot_s pdf_widget;
|
|
typedef struct pdf_js_s pdf_js;
|
|
|
|
enum
|
|
{
|
|
PDF_LEXBUF_SMALL = 256,
|
|
PDF_LEXBUF_LARGE = 65536
|
|
};
|
|
|
|
struct pdf_lexbuf_s
|
|
{
|
|
size_t size;
|
|
size_t base_size;
|
|
size_t len;
|
|
int64_t i;
|
|
float f;
|
|
char *scratch;
|
|
char buffer[PDF_LEXBUF_SMALL];
|
|
};
|
|
|
|
struct pdf_lexbuf_large_s
|
|
{
|
|
pdf_lexbuf base;
|
|
char buffer[PDF_LEXBUF_LARGE - PDF_LEXBUF_SMALL];
|
|
};
|
|
|
|
/*
|
|
Document event structures are mostly opaque to the app. Only the type
|
|
is visible to the app.
|
|
*/
|
|
typedef struct pdf_doc_event_s pdf_doc_event;
|
|
|
|
/*
|
|
the type of function via which the app receives
|
|
document events.
|
|
*/
|
|
typedef void (pdf_doc_event_cb)(fz_context *ctx, pdf_document *doc, pdf_doc_event *event, void *data);
|
|
|
|
pdf_document *pdf_open_document(fz_context *ctx, const char *filename);
|
|
|
|
pdf_document *pdf_open_document_with_stream(fz_context *ctx, fz_stream *file);
|
|
|
|
void pdf_drop_document(fz_context *ctx, pdf_document *doc);
|
|
|
|
pdf_document *pdf_keep_document(fz_context *ctx, pdf_document *doc);
|
|
|
|
pdf_document *pdf_specifics(fz_context *ctx, fz_document *doc);
|
|
|
|
pdf_document *pdf_document_from_fz_document(fz_context *ctx, fz_document *ptr);
|
|
pdf_page *pdf_page_from_fz_page(fz_context *ctx, fz_page *ptr);
|
|
|
|
int pdf_needs_password(fz_context *ctx, pdf_document *doc);
|
|
|
|
int pdf_authenticate_password(fz_context *ctx, pdf_document *doc, const char *pw);
|
|
|
|
int pdf_has_permission(fz_context *ctx, pdf_document *doc, fz_permission p);
|
|
int pdf_lookup_metadata(fz_context *ctx, pdf_document *doc, const char *key, char *ptr, int size);
|
|
|
|
fz_outline *pdf_load_outline(fz_context *ctx, pdf_document *doc);
|
|
|
|
int pdf_count_layer_configs(fz_context *ctx, pdf_document *doc);
|
|
|
|
typedef struct
|
|
{
|
|
const char *name;
|
|
const char *creator;
|
|
} pdf_layer_config;
|
|
|
|
void pdf_layer_config_info(fz_context *ctx, pdf_document *doc, int config_num, pdf_layer_config *info);
|
|
|
|
void pdf_select_layer_config(fz_context *ctx, pdf_document *doc, int config_num);
|
|
|
|
int pdf_count_layer_config_ui(fz_context *ctx, pdf_document *doc);
|
|
|
|
void pdf_select_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
|
|
|
|
void pdf_deselect_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
|
|
|
|
void pdf_toggle_layer_config_ui(fz_context *ctx, pdf_document *doc, int ui);
|
|
|
|
typedef enum
|
|
{
|
|
PDF_LAYER_UI_LABEL = 0,
|
|
PDF_LAYER_UI_CHECKBOX = 1,
|
|
PDF_LAYER_UI_RADIOBOX = 2
|
|
} pdf_layer_config_ui_type;
|
|
|
|
typedef struct
|
|
{
|
|
const char *text;
|
|
int depth;
|
|
pdf_layer_config_ui_type type;
|
|
int selected;
|
|
int locked;
|
|
} pdf_layer_config_ui;
|
|
|
|
void pdf_layer_config_ui_info(fz_context *ctx, pdf_document *doc, int ui, pdf_layer_config_ui *info);
|
|
|
|
void pdf_set_layer_config_as_default(fz_context *ctx, pdf_document *doc);
|
|
|
|
int pdf_has_unsaved_changes(fz_context *ctx, pdf_document *doc);
|
|
|
|
enum pdf_signature_error
|
|
{
|
|
PDF_SIGNATURE_ERROR_OKAY,
|
|
PDF_SIGNATURE_ERROR_NO_SIGNATURES,
|
|
PDF_SIGNATURE_ERROR_NO_CERTIFICATE,
|
|
PDF_SIGNATURE_ERROR_DIGEST_FAILURE,
|
|
PDF_SIGNATURE_ERROR_SELF_SIGNED,
|
|
PDF_SIGNATURE_ERROR_SELF_SIGNED_IN_CHAIN,
|
|
PDF_SIGNATURE_ERROR_NOT_TRUSTED,
|
|
PDF_SIGNATURE_ERROR_UNKNOWN
|
|
};
|
|
|
|
typedef struct pdf_pkcs7_designated_name_s
|
|
{
|
|
char *cn;
|
|
char *o;
|
|
char *ou;
|
|
char *email;
|
|
char *c;
|
|
}
|
|
pdf_pkcs7_designated_name;
|
|
|
|
/* Object that can perform the cryptographic operation necessary for document signing */
|
|
typedef struct pdf_pkcs7_signer_s pdf_pkcs7_signer;
|
|
|
|
/* Increment the reference count for a signer object */
|
|
typedef pdf_pkcs7_signer *(pdf_pkcs7_keep_fn)(pdf_pkcs7_signer *signer);
|
|
|
|
/* Drop a reference for a signer object */
|
|
typedef void (pdf_pkcs7_drop_fn)(pdf_pkcs7_signer *signer);
|
|
|
|
/* Obtain the designated name information from a signer object */
|
|
typedef pdf_pkcs7_designated_name *(pdf_pkcs7_designated_name_fn)(pdf_pkcs7_signer *signer);
|
|
|
|
/* Free the resources associated with previously obtained designated name information */
|
|
typedef void (pdf_pkcs7_drop_designated_name_fn)(pdf_pkcs7_signer *signer, pdf_pkcs7_designated_name *name);
|
|
|
|
/* Predict the size of the digest. The actual digest returned by create_digest will be no greater in size */
|
|
typedef int (pdf_pkcs7_max_digest_size_fn)(pdf_pkcs7_signer *signer);
|
|
|
|
/* Create a signature based on ranges of bytes drawn from a stream */
|
|
typedef int (pdf_pkcs7_create_digest_fn)(pdf_pkcs7_signer *signer, fz_stream *in, unsigned char *digest, int *digest_len);
|
|
|
|
struct pdf_pkcs7_signer_s
|
|
{
|
|
pdf_pkcs7_keep_fn *keep;
|
|
pdf_pkcs7_drop_fn *drop;
|
|
pdf_pkcs7_designated_name_fn *designated_name;
|
|
pdf_pkcs7_drop_designated_name_fn *drop_designated_name;
|
|
pdf_pkcs7_max_digest_size_fn *max_digest_size;
|
|
pdf_pkcs7_create_digest_fn *create_digest;
|
|
};
|
|
|
|
/* Unsaved signature fields */
|
|
typedef struct pdf_unsaved_sig_s pdf_unsaved_sig;
|
|
|
|
struct pdf_unsaved_sig_s
|
|
{
|
|
pdf_obj *field;
|
|
int byte_range_start;
|
|
int byte_range_end;
|
|
int contents_start;
|
|
int contents_end;
|
|
pdf_pkcs7_signer *signer;
|
|
pdf_unsaved_sig *next;
|
|
};
|
|
|
|
typedef struct pdf_rev_page_map_s pdf_rev_page_map;
|
|
struct pdf_rev_page_map_s
|
|
{
|
|
int page;
|
|
int object;
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
int number; /* Page object number */
|
|
int64_t offset; /* Offset of page object */
|
|
int64_t index; /* Index into shared hint_shared_ref */
|
|
} pdf_hint_page;
|
|
|
|
typedef struct
|
|
{
|
|
int number; /* Object number of first object */
|
|
int64_t offset; /* Offset of first object */
|
|
} pdf_hint_shared;
|
|
|
|
struct pdf_document_s
|
|
{
|
|
fz_document super;
|
|
|
|
fz_stream *file;
|
|
|
|
int version;
|
|
int64_t startxref;
|
|
int64_t file_size;
|
|
pdf_crypt *crypt;
|
|
pdf_ocg_descriptor *ocg;
|
|
fz_colorspace *oi;
|
|
|
|
int max_xref_len;
|
|
int num_xref_sections;
|
|
int saved_num_xref_sections;
|
|
int num_incremental_sections;
|
|
int xref_base;
|
|
int disallow_new_increments;
|
|
pdf_xref *xref_sections;
|
|
pdf_xref *saved_xref_sections;
|
|
int *xref_index;
|
|
int save_in_progress;
|
|
int has_xref_streams;
|
|
int has_old_style_xrefs;
|
|
|
|
int rev_page_count;
|
|
pdf_rev_page_map *rev_page_map;
|
|
|
|
int repair_attempted;
|
|
|
|
/* State indicating which file parsing method we are using */
|
|
int file_reading_linearly;
|
|
int64_t file_length;
|
|
|
|
int linear_page_count;
|
|
pdf_obj *linear_obj; /* Linearized object (if used) */
|
|
pdf_obj **linear_page_refs; /* Page objects for linear loading */
|
|
int linear_page1_obj_num;
|
|
|
|
/* The state for the pdf_progressive_advance parser */
|
|
int64_t linear_pos;
|
|
int linear_page_num;
|
|
|
|
int hint_object_offset;
|
|
int hint_object_length;
|
|
int hints_loaded; /* Set to 1 after the hints loading has completed,
|
|
* whether successful or not! */
|
|
/* Page n references shared object references:
|
|
* hint_shared_ref[i]
|
|
* where
|
|
* i = s to e-1
|
|
* s = hint_page[n]->index
|
|
* e = hint_page[n+1]->index
|
|
* Shared object reference r accesses objects:
|
|
* rs to re-1
|
|
* where
|
|
* rs = hint_shared[r]->number
|
|
* re = hint_shared[r]->count + rs
|
|
* These are guaranteed to lie within the region starting at
|
|
* hint_shared[r]->offset of length hint_shared[r]->length
|
|
*/
|
|
pdf_hint_page *hint_page;
|
|
int *hint_shared_ref;
|
|
pdf_hint_shared *hint_shared;
|
|
int hint_obj_offsets_max;
|
|
int64_t *hint_obj_offsets;
|
|
|
|
int resources_localised;
|
|
|
|
pdf_lexbuf_large lexbuf;
|
|
|
|
pdf_js *js;
|
|
|
|
int recalculate;
|
|
int dirty;
|
|
int redacted;
|
|
|
|
pdf_doc_event_cb *event_cb;
|
|
void *event_cb_data;
|
|
|
|
int num_type3_fonts;
|
|
int max_type3_fonts;
|
|
fz_font **type3_fonts;
|
|
|
|
struct {
|
|
fz_hash_table *images;
|
|
fz_hash_table *fonts;
|
|
} resources;
|
|
|
|
int orphans_max;
|
|
int orphans_count;
|
|
pdf_obj **orphans;
|
|
};
|
|
|
|
pdf_document *pdf_create_document(fz_context *ctx);
|
|
|
|
typedef struct pdf_graft_map_s pdf_graft_map;
|
|
|
|
pdf_obj *pdf_graft_object(fz_context *ctx, pdf_document *dst, pdf_obj *obj);
|
|
|
|
pdf_graft_map *pdf_new_graft_map(fz_context *ctx, pdf_document *dst);
|
|
|
|
pdf_graft_map *pdf_keep_graft_map(fz_context *ctx, pdf_graft_map *map);
|
|
void pdf_drop_graft_map(fz_context *ctx, pdf_graft_map *map);
|
|
|
|
pdf_obj *pdf_graft_mapped_object(fz_context *ctx, pdf_graft_map *map, pdf_obj *obj);
|
|
|
|
fz_device *pdf_page_write(fz_context *ctx, pdf_document *doc, fz_rect mediabox, pdf_obj **presources, fz_buffer **pcontents);
|
|
|
|
pdf_obj *pdf_add_page(fz_context *ctx, pdf_document *doc, fz_rect mediabox, int rotate, pdf_obj *resources, fz_buffer *contents);
|
|
|
|
void pdf_insert_page(fz_context *ctx, pdf_document *doc, int at, pdf_obj *page);
|
|
|
|
void pdf_delete_page(fz_context *ctx, pdf_document *doc, int number);
|
|
|
|
void pdf_delete_page_range(fz_context *ctx, pdf_document *doc, int start, int end);
|
|
|
|
void pdf_finish_edit(fz_context *ctx, pdf_document *doc);
|
|
|
|
int pdf_recognize(fz_context *doc, const char *magic);
|
|
|
|
typedef struct pdf_write_options_s pdf_write_options;
|
|
|
|
/*
|
|
In calls to fz_save_document, the following options structure can be used
|
|
to control aspects of the writing process. This structure may grow
|
|
in the future, and should be zero-filled to allow forwards compatibility.
|
|
*/
|
|
struct pdf_write_options_s
|
|
{
|
|
int do_incremental; /* Write just the changed objects. */
|
|
int do_pretty; /* Pretty-print dictionaries and arrays. */
|
|
int do_ascii; /* ASCII hex encode binary streams. */
|
|
int do_compress; /* Compress streams. */
|
|
int do_compress_images; /* Compress (or leave compressed) image streams. */
|
|
int do_compress_fonts; /* Compress (or leave compressed) font streams. */
|
|
int do_decompress; /* Decompress streams (except when compressing images/fonts). */
|
|
int do_garbage; /* Garbage collect objects before saving; 1=gc, 2=re-number, 3=de-duplicate. */
|
|
int do_linear; /* Write linearised. */
|
|
int do_clean; /* Clean content streams. */
|
|
int do_sanitize; /* Sanitize content streams. */
|
|
int do_appearance; /* (Re)create appearance streams. */
|
|
int do_encrypt; /* Encryption method to use: keep, none, rc4-40, etc. */
|
|
int permissions; /* Document encryption permissions. */
|
|
char opwd_utf8[128]; /* Owner password. */
|
|
char upwd_utf8[128]; /* User password. */
|
|
};
|
|
|
|
extern const pdf_write_options pdf_default_write_options;
|
|
|
|
pdf_write_options *pdf_parse_write_options(fz_context *ctx, pdf_write_options *opts, const char *args);
|
|
|
|
int pdf_has_unsaved_sigs(fz_context *ctx, pdf_document *doc);
|
|
|
|
void pdf_write_document(fz_context *ctx, pdf_document *doc, fz_output *out, pdf_write_options *opts);
|
|
|
|
void pdf_save_document(fz_context *ctx, pdf_document *doc, const char *filename, pdf_write_options *opts);
|
|
|
|
int pdf_can_be_saved_incrementally(fz_context *ctx, pdf_document *doc);
|
|
|
|
#endif
|