diff --git a/include/mupdf/fitz.h b/include/mupdf/fitz.h index d00c44f..014bf6c 100644 --- a/include/mupdf/fitz.h +++ b/include/mupdf/fitz.h @@ -51,6 +51,8 @@ extern "C" { #include "mupdf/fitz/compressed-buffer.h" #include "mupdf/fitz/filter.h" #include "mupdf/fitz/archive.h" +#include "mupdf/fitz/heap.h" + /* Resources */ #include "mupdf/fitz/store.h" diff --git a/include/mupdf/fitz/archive.h b/include/mupdf/fitz/archive.h index 19571cd..407eef4 100644 --- a/include/mupdf/fitz/archive.h +++ b/include/mupdf/fitz/archive.h @@ -88,6 +88,9 @@ fz_archive *fz_open_directory(fz_context *ctx, const char *path); /** Determine if a given path is a directory. + + In the case of the path not existing, or having no access + we will return 0. */ int fz_is_directory(fz_context *ctx, const char *path); @@ -194,16 +197,30 @@ fz_buffer *fz_try_read_archive_entry(fz_context *ctx, fz_archive *arch, const ch */ /** - Detect if stream object is a tar achieve. + Detect if stream object is a tar archive. Assumes that the stream object is seekable. */ int fz_is_tar_archive(fz_context *ctx, fz_stream *file); +/** + Detect if stream object is an archive supported by libarchive. + + Assumes that the stream object is seekable. +*/ +int fz_is_libarchive_archive(fz_context *ctx, fz_stream *file); + +/** + Detect if stream object is a cfb archive. + + Assumes that the stream object is seekable. +*/ +int fz_is_cfb_archive(fz_context *ctx, fz_stream *file); + /** Open a tar archive file. - An exception is throw if the file is not a tar archive as + An exception is thrown if the file is not a tar archive as indicated by the presence of a tar signature. filename: a path to a tar archive file as it would be given to @@ -217,12 +234,52 @@ fz_archive *fz_open_tar_archive(fz_context *ctx, const char *filename); Open an archive using a seekable stream object rather than opening a file or directory on disk. - An exception is throw if the stream is not a tar archive as + An exception is thrown if the stream is not a tar archive as indicated by the presence of a tar signature. */ fz_archive *fz_open_tar_archive_with_stream(fz_context *ctx, fz_stream *file); +/** + Open an archive using libarchive. + + An exception is thrown if the file is not supported by libarchive. + + filename: a path to an archive file as it would be given to + open(2). +*/ +fz_archive *fz_open_libarchive_archive(fz_context *ctx, const char *filename); + +/** + Open an archive using libarchive. + + Open an archive using a seekable stream object rather than + opening a file or directory on disk. + + An exception is thrown if the stream is not supported by libarchive. +*/ +fz_archive *fz_open_libarchive_archive_with_stream(fz_context *ctx, fz_stream *file); + +/** + Open a cfb file as an archive. + + An exception is thrown if the file is not recognised as a cfb. + + filename: a path to an archive file as it would be given to + open(2). +*/ +fz_archive *fz_open_cfb_archive(fz_context *ctx, const char *filename); + +/** + Open a cfb file as an archive. + + Open an archive using a seekable stream object rather than + opening a file or directory on disk. + + An exception is thrown if the file is not recognised as a chm. +*/ +fz_archive *fz_open_cfb_archive_with_stream(fz_context *ctx, fz_stream *file); + /** fz_archive: zip implementation */ @@ -237,7 +294,7 @@ int fz_is_zip_archive(fz_context *ctx, fz_stream *file); /** Open a zip archive file. - An exception is throw if the file is not a zip archive as + An exception is thrown if the file is not a zip archive as indicated by the presence of a zip signature. filename: a path to a zip archive file as it would be given to @@ -251,7 +308,7 @@ fz_archive *fz_open_zip_archive(fz_context *ctx, const char *path); Open an archive using a seekable stream object rather than opening a file or directory on disk. - An exception is throw if the stream is not a zip archive as + An exception is thrown if the stream is not a zip archive as indicated by the presence of a zip signature. */ @@ -344,6 +401,20 @@ fz_archive *fz_new_multi_archive(fz_context *ctx); */ void fz_mount_multi_archive(fz_context *ctx, fz_archive *arch_, fz_archive *sub, const char *path); +typedef int (fz_recognize_archive_fn)(fz_context *, fz_stream *); +typedef fz_archive *(fz_open_archive_fn)(fz_context *, fz_stream *); + +typedef struct +{ + fz_recognize_archive_fn *recognize; + fz_open_archive_fn *open; +} +fz_archive_handler; + +FZ_DATA extern const fz_archive_handler fz_libarchive_archive_handler; + +void fz_register_archive_handler(fz_context *ctx, const fz_archive_handler *handler); + /** Implementation details: Subject to change. */ @@ -351,8 +422,8 @@ void fz_mount_multi_archive(fz_context *ctx, fz_archive *arch_, fz_archive *sub, struct fz_archive { int refs; - fz_stream *file; + const char *format; void (*drop_archive)(fz_context *ctx, fz_archive *arch); diff --git a/include/mupdf/fitz/bitmap.h b/include/mupdf/fitz/bitmap.h index 20175de..bf41035 100644 --- a/include/mupdf/fitz/bitmap.h +++ b/include/mupdf/fitz/bitmap.h @@ -60,6 +60,13 @@ fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit); */ void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit); +/** + Invert bitmap. + + Never throws exceptions. +*/ +void fz_invert_bitmap(fz_context *ctx, fz_bitmap *bmp); + /** A halftone is a set of threshold tiles, one per component. Each threshold tile is a pixmap, possibly of varying sizes and diff --git a/include/mupdf/fitz/compress.h b/include/mupdf/fitz/compress.h index d5907a1..9acf1cf 100644 --- a/include/mupdf/fitz/compress.h +++ b/include/mupdf/fitz/compress.h @@ -25,6 +25,7 @@ #include "mupdf/fitz/system.h" #include "mupdf/fitz/buffer.h" +#include "mupdf/fitz/pixmap.h" typedef enum { @@ -75,13 +76,13 @@ unsigned char *fz_new_deflated_data_from_buffer(fz_context *ctx, size_t *compres Creates a stream assuming the default PDF parameters, except the number of columns. */ -fz_buffer *fz_compress_ccitt_fax_g3(fz_context *ctx, const unsigned char *data, int columns, int rows); +fz_buffer *fz_compress_ccitt_fax_g3(fz_context *ctx, const unsigned char *data, int columns, int rows, ptrdiff_t stride); /** Compress bitmap data as CCITT Group 4 2D fax image. Creates a stream assuming the default PDF parameters, except K=-1 and the number of columns. */ -fz_buffer *fz_compress_ccitt_fax_g4(fz_context *ctx, const unsigned char *data, int columns, int rows); +fz_buffer *fz_compress_ccitt_fax_g4(fz_context *ctx, const unsigned char *data, int columns, int rows, ptrdiff_t stride); #endif diff --git a/include/mupdf/fitz/compressed-buffer.h b/include/mupdf/fitz/compressed-buffer.h index 924e0ef..5f88649 100644 --- a/include/mupdf/fitz/compressed-buffer.h +++ b/include/mupdf/fitz/compressed-buffer.h @@ -39,6 +39,7 @@ typedef struct union { struct { int color_transform; /* Use -1 for unset */ + int invert_cmyk; /* Use 1 for standalone JPEG files */ } jpeg; struct { int smask_in_data; @@ -82,10 +83,16 @@ typedef struct */ typedef struct { + int refs; fz_compression_params params; fz_buffer *buffer; } fz_compressed_buffer; +/** + Take a reference to an fz_compressed_buffer. +*/ +fz_compressed_buffer *fz_keep_compressed_buffer(fz_context *ctx, fz_compressed_buffer *cbuf); + /** Return the storage size used for a buffer and its data. Used in implementing store handling. @@ -170,4 +177,9 @@ enum */ void fz_drop_compressed_buffer(fz_context *ctx, fz_compressed_buffer *buf); +/** + Create a new, UNKNOWN format, compressed_buffer. +*/ +fz_compressed_buffer *fz_new_compressed_buffer(fz_context *ctx); + #endif diff --git a/include/mupdf/fitz/config.h b/include/mupdf/fitz/config.h index aee0c95..f0c139e 100644 --- a/include/mupdf/fitz/config.h +++ b/include/mupdf/fitz/config.h @@ -92,11 +92,11 @@ unwanted fonts. */ /* To avoid all noto fonts except CJK, enable: */ - #define TOFU +#define TOFU /* To skip the CJK font, enable: (this implicitly enables TOFU_CJK_EXT * and TOFU_CJK_LANG) */ - #define TOFU_CJK +#define TOFU_CJK /* To skip CJK Extension A, enable: (this implicitly enables * TOFU_CJK_LANG) */ diff --git a/include/mupdf/fitz/context.h b/include/mupdf/fitz/context.h index a000a53..8277c51 100644 --- a/include/mupdf/fitz/context.h +++ b/include/mupdf/fitz/context.h @@ -39,6 +39,7 @@ typedef struct fz_tuning_context fz_tuning_context; typedef struct fz_store fz_store; typedef struct fz_glyph_cache fz_glyph_cache; typedef struct fz_document_handler_context fz_document_handler_context; +typedef struct fz_archive_handler_context fz_archive_handler_context; typedef struct fz_output fz_output; typedef struct fz_context fz_context; @@ -137,6 +138,14 @@ const char *fz_caught_message(fz_context *ctx); */ int fz_caught(fz_context *ctx); +/* + Within an fz_catch() block, retrieve the errno code for + the current SYSTEM exception. + + Is undefined for non-SYSTEM errors. +*/ +int fz_caught_errno(fz_context *ctx); + /** Within an fz_catch() block, rethrow the current exception if the errcode of the current exception matches. @@ -144,6 +153,7 @@ int fz_caught(fz_context *ctx); This assumes no intervening use of fz_try/fz_catch. */ void fz_rethrow_if(fz_context *ctx, int errcode); +void fz_rethrow_unless(fz_context *ctx, int errcode); /** Format an error message, and log it to the registered @@ -174,9 +184,11 @@ void fz_end_throw_on_repair(fz_context *ctx); #define fz_vwarn(CTX, FMT, VA) fz_vwarnFL(CTX, __FILE__, __LINE__, FMT, VA) #define fz_warn(CTX, ...) fz_warnFL(CTX, __FILE__, __LINE__, __VA_ARGS__) #define fz_rethrow_if(CTX, ERRCODE) fz_rethrow_ifFL(CTX, __FILE__, __LINE__, ERRCODE) +#define fz_rethrow_unless(CTX, ERRCODE) fz_rethrow_unlessFL(CTX, __FILE__, __LINE__, ERRCODE) #define fz_log_error_printf(CTX, ...) fz_log_error_printfFL(CTX, __FILE__, __LINE__, __VA_ARGS__) #define fz_vlog_error_printf(CTX, FMT, VA) fz_log_error_printfFL(CTX, __FILE__, __LINE__, FMT, VA) #define fz_log_error(CTX, STR) fz_log_error_printfFL(CTX, __FILE__, __LINE__, STR) +#define fz_do_catch(CTX) fz_do_catchFL(CTX, __FILE__, __LINE__) FZ_NORETURN void fz_vthrowFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, va_list ap); FZ_NORETURN void fz_throwFL(fz_context *ctx, const char *file, int line, int errcode, const char *fmt, ...) FZ_PRINTFLIKE(5,6); FZ_NORETURN void fz_rethrowFL(fz_context *ctx, const char *file, int line); @@ -184,22 +196,44 @@ void fz_morph_errorFL(fz_context *ctx, const char *file, int line, int fromcode, void fz_vwarnFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap); void fz_warnFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5); void fz_rethrow_ifFL(fz_context *ctx, const char *file, int line, int errcode); +void fz_rethrow_unlessFL(fz_context *ctx, const char *file, int line, int errcode); void fz_log_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, ...) FZ_PRINTFLIKE(4,5); void fz_vlog_error_printfFL(fz_context *ctx, const char *file, int line, const char *fmt, va_list ap); void fz_log_errorFL(fz_context *ctx, const char *file, int line, const char *str); +int fz_do_catchFL(fz_context *ctx, const char *file, int line); #endif -enum +/* Report an error to the registered error callback. */ +void fz_report_error(fz_context *ctx); + +/* + * Swallow an error and ignore it completely. + * This should only be called to signal that you've handled a TRYLATER or ABORT error, + */ +void fz_ignore_error(fz_context *ctx); + +/* Convert an error into another runtime exception. + * For use when converting an exception from Fitz to a language binding exception. + */ +const char *fz_convert_error(fz_context *ctx, int *code); + +enum fz_error_type { - FZ_ERROR_NONE = 0, - FZ_ERROR_MEMORY = 1, - FZ_ERROR_GENERIC = 2, - FZ_ERROR_SYNTAX = 3, - FZ_ERROR_MINOR = 4, - FZ_ERROR_TRYLATER = 5, - FZ_ERROR_ABORT = 6, - FZ_ERROR_REPAIRED = 7, - FZ_ERROR_COUNT + FZ_ERROR_NONE, + FZ_ERROR_GENERIC, + + FZ_ERROR_SYSTEM, // fatal out of memory or syscall error + FZ_ERROR_LIBRARY, // unclassified error from third-party library + FZ_ERROR_ARGUMENT, // invalid or out-of-range arguments to functions + FZ_ERROR_LIMIT, // failed because of resource or other hard limits + FZ_ERROR_UNSUPPORTED, // tried to use an unsupported feature + FZ_ERROR_FORMAT, // syntax or format errors that are unrecoverable + FZ_ERROR_SYNTAX, // syntax errors that should be diagnosed and ignored + + // for internal use only + FZ_ERROR_TRYLATER, // try-later progressive loading signal + FZ_ERROR_ABORT, // user requested abort signal + FZ_ERROR_REPAIRED, // internal flag used when repairing a PDF to avoid cycles }; /** @@ -690,6 +724,34 @@ char *fz_strdup(fz_context *ctx, const char *s); */ void fz_memrnd(fz_context *ctx, uint8_t *block, int len); +/* + Reference counted malloced C strings. +*/ +typedef struct +{ + int refs; + char str[1]; +} fz_string; + +/* + Allocate a new string to hold a copy of str. + + Returns with a refcount of 1. +*/ +fz_string *fz_new_string(fz_context *ctx, const char *str); + +/* + Take another reference to a string. +*/ +fz_string *fz_keep_string(fz_context *ctx, fz_string *str); + +/* + Drop a reference to a string, freeing if the refcount + reaches 0. +*/ +void fz_drop_string(fz_context *ctx, fz_string *str); + +#define fz_cstring_from_string(A) ((A) == NULL ? NULL : (A)->str) /* Implementation details: subject to change. */ @@ -699,7 +761,7 @@ void fz_var_imp(void *); fz_jmp_buf *fz_push_try(fz_context *ctx); int fz_do_try(fz_context *ctx); int fz_do_always(fz_context *ctx); -int fz_do_catch(fz_context *ctx); +int (fz_do_catch)(fz_context *ctx); #ifndef FZ_JMPBUF_ALIGN #define FZ_JMPBUF_ALIGN 32 @@ -719,6 +781,7 @@ typedef struct fz_error_stack_slot padding; fz_error_stack_slot *stack_base; int errcode; + int errnum; /* errno for SYSTEM class errors */ void *print_user; void (*print)(void *user, const char *message); char message[256]; @@ -760,6 +823,7 @@ struct fz_context /* TODO: should these be unshared? */ fz_document_handler_context *handler; + fz_archive_handler_context *archive; fz_style_context *style; fz_tuning_context *tuning; diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h index b65fa3e..9f51c21 100644 --- a/include/mupdf/fitz/device.h +++ b/include/mupdf/fitz/device.h @@ -106,6 +106,63 @@ int fz_lookup_blendmode(const char *name); */ const char *fz_blendmode_name(int blendmode); +/* + Generic function type. + + Different function implementations will derive from this. +*/ +typedef struct fz_function fz_function; + +typedef void (fz_function_eval_fn)(fz_context *, fz_function *, const float *, float *); + +enum +{ + FZ_FUNCTION_MAX_N = FZ_MAX_COLORS, + FZ_FUNCTION_MAX_M = FZ_MAX_COLORS +}; + +struct fz_function +{ + fz_storable storable; + size_t size; + int m; /* number of input values */ + int n; /* number of output values */ + + fz_function_eval_fn *eval; +}; + +fz_function *fz_new_function_of_size(fz_context *ctx, int size, size_t size2, int m, int n, fz_function_eval_fn *eval, fz_store_drop_fn *drop); + +#define fz_new_derived_function(CTX,TYPE,SIZE,M,N,EVAL,DROP) \ + ((TYPE*)Memento_label(fz_new_function_of_size(CTX,sizeof(TYPE),SIZE,M,N,EVAL,DROP), #TYPE)) + +/* + Evaluate a function. + + Input vector = (in[0], ..., in[inlen-1]) + Output vector = (out[0], ..., out[outlen-1]) + + If inlen or outlen do not match that expected by the function, this + routine will truncate or extend the input/output (with 0's) as + required. +*/ +void fz_eval_function(fz_context *ctx, fz_function *func, const float *in, int inlen, float *out, int outlen); + +/* + Keep a function reference. +*/ +fz_function *fz_keep_function(fz_context *ctx, fz_function *func); + +/* + Drop a function reference. +*/ +void fz_drop_function(fz_context *ctx, fz_function *func); + +/* + Function size +*/ +size_t fz_function_size(fz_context *ctx, fz_function *func); + /** The device structure is public to allow devices to be implemented outside of fitz. @@ -259,7 +316,7 @@ struct fz_device void (*pop_clip)(fz_context *, fz_device *); void (*begin_mask)(fz_context *, fz_device *, fz_rect area, int luminosity, fz_colorspace *, const float *bc, fz_color_params ); - void (*end_mask)(fz_context *, fz_device *); + void (*end_mask)(fz_context *, fz_device *, fz_function *fn); void (*begin_group)(fz_context *, fz_device *, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha); void (*end_group)(fz_context *, fz_device *); @@ -272,7 +329,7 @@ struct fz_device void (*begin_layer)(fz_context *, fz_device *, const char *layer_name); void (*end_layer)(fz_context *, fz_device *); - void (*begin_structure)(fz_context *, fz_device *, fz_structure standard, const char *raw, int uid); + void (*begin_structure)(fz_context *, fz_device *, fz_structure standard, const char *raw, int idx); void (*end_structure)(fz_context *, fz_device *); void (*begin_metatext)(fz_context *, fz_device *, fz_metatext meta, const char *text); @@ -304,6 +361,7 @@ void fz_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_mat void fz_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, fz_matrix ctm, fz_rect scissor); void fz_begin_mask(fz_context *ctx, fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, const float *bc, fz_color_params color_params); void fz_end_mask(fz_context *ctx, fz_device *dev); +void fz_end_mask_tr(fz_context *ctx, fz_device *dev, fz_function *fn); void fz_begin_group(fz_context *ctx, fz_device *dev, fz_rect area, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha); void fz_end_group(fz_context *ctx, fz_device *dev); void fz_begin_tile(fz_context *ctx, fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm); @@ -313,7 +371,7 @@ void fz_render_flags(fz_context *ctx, fz_device *dev, int set, int clear); void fz_set_default_colorspaces(fz_context *ctx, fz_device *dev, fz_default_colorspaces *default_cs); void fz_begin_layer(fz_context *ctx, fz_device *dev, const char *layer_name); void fz_end_layer(fz_context *ctx, fz_device *dev); -void fz_begin_structure(fz_context *ctx, fz_device *dev, fz_structure standard, const char *raw, int uid); +void fz_begin_structure(fz_context *ctx, fz_device *dev, fz_structure standard, const char *raw, int idx); void fz_end_structure(fz_context *ctx, fz_device *dev); void fz_begin_metatext(fz_context *ctx, fz_device *dev, fz_metatext meta, const char *text); void fz_end_metatext(fz_context *ctx, fz_device *dev); @@ -374,6 +432,7 @@ enum /* Hints */ FZ_DONT_INTERPOLATE_IMAGES = 1, FZ_NO_CACHE = 2, + FZ_DONT_DECODE_IMAGES = 4 }; /** diff --git a/include/mupdf/fitz/document.h b/include/mupdf/fitz/document.h index b1e6dfa..eca2a70 100644 --- a/include/mupdf/fitz/document.h +++ b/include/mupdf/fitz/document.h @@ -216,7 +216,7 @@ typedef int (fz_document_lookup_metadata_fn)(fz_context *ctx, fz_document *doc, a document's metadata. See fz_set_metadata for more information. */ -typedef int (fz_document_set_metadata_fn)(fz_context *ctx, fz_document *doc, const char *key, const char *value); +typedef void (fz_document_set_metadata_fn)(fz_context *ctx, fz_document *doc, const char *key, const char *value); /** Return output intent color space if it exists @@ -228,6 +228,18 @@ typedef fz_colorspace *(fz_document_output_intent_fn)(fz_context *ctx, fz_docume */ typedef void (fz_document_output_accelerator_fn)(fz_context *ctx, fz_document *doc, fz_output *out); +/** + Send document structure to device +*/ +typedef void (fz_document_run_structure_fn)(fz_context *ctx, fz_document *doc, fz_device *dev, fz_cookie *cookie); + +/** + Get a handle to this document as PDF. + + Returns a borrowed handle. +*/ +typedef fz_document *(fz_document_as_pdf_fn)(fz_context *ctx, fz_document *doc); + /** Type for a function to make a bookmark. See fz_make_bookmark for more information. @@ -313,56 +325,36 @@ typedef fz_link *(fz_page_create_link_fn)(fz_context *ctx, fz_page *page, fz_rec */ typedef void (fz_page_delete_link_fn)(fz_context *ctx, fz_page *page, fz_link *link); -/** - Function type to open a document from a file. - - filename: file to open - - Pointer to opened document. Throws exception in case of error. -*/ -typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const char *filename); - /** Function type to open a document from a file. + handler: the document handler in use. + stream: fz_stream to read document data from. Must be seekable for formats that require it. - Pointer to opened document. Throws exception in case of error. -*/ -typedef fz_document *(fz_document_open_with_stream_fn)(fz_context *ctx, fz_stream *stream); - -/** - Function type to open a document from a - file, with accelerator data. - - filename: file to open - - accel: accelerator file - - Pointer to opened document. Throws exception in case of error. -*/ -typedef fz_document *(fz_document_open_accel_fn)(fz_context *ctx, const char *filename, const char *accel); - -/** - Function type to open a document from a file, - with accelerator data. + accel: fz_stream to read accelerator data from. May be + NULL. May be ignored. - stream: fz_stream to read document data from. Must be - seekable for formats that require it. + dir: 'Directory context' in which the document is loaded; + associated content from (like images for an html stream + will be loaded from this). Maybe NULL. May be ignored. - accel: fz_stream to read accelerator data from. Must be - seekable for formats that require it. + recognize_state: NULL, or a state pointer passed back from the call + to recognise_content_fn. Ownership does not pass in. The + caller remains responsible for freeing state. Pointer to opened document. Throws exception in case of error. */ -typedef fz_document *(fz_document_open_accel_with_stream_fn)(fz_context *ctx, fz_stream *stream, fz_stream *accel); +typedef fz_document *(fz_document_open_fn)(fz_context *ctx, const fz_document_handler *handler, fz_stream *stream, fz_stream *accel, fz_archive *dir, void *recognize_state); /** Recognize a document type from a magic string. + handler: the handler in use. + magic: string to recognise - typically a filename or mime type. @@ -370,18 +362,46 @@ typedef fz_document *(fz_document_open_accel_with_stream_fn)(fz_context *ctx, fz (fully recognized) based on how certain the recognizer is that this is of the required type. */ -typedef int (fz_document_recognize_fn)(fz_context *ctx, const char *magic); +typedef int (fz_document_recognize_fn)(fz_context *ctx, const fz_document_handler *handler, const char *magic); + +typedef void (fz_document_recognize_state_free_fn)(fz_context *ctx, void *state); /** Recognize a document type from stream contents. - stream: stream contents to recognise. + handler: the handler in use. + + stream: stream contents to recognise (may be NULL if document is + a directory). + + dir: directory context from which stream is loaded. + + recognize_state: pointer to retrieve opaque state that may be used + by the open routine, or NULL. + + free_recognize_state: pointer to retrieve a function pointer to + free the opaque state, or NULL. + + Note: state and free_state should either both be NULL or + both be non-NULL! Returns a number between 0 (not recognized) and 100 (fully recognized) based on how certain the recognizer is that this is of the required type. */ -typedef int (fz_document_recognize_content_fn)(fz_context *ctx, fz_stream *stream); +typedef int (fz_document_recognize_content_fn)(fz_context *ctx, const fz_document_handler *handler, fz_stream *stream, fz_archive *dir, void **recognize_state, fz_document_recognize_state_free_fn **free_recognize_state); + +/** + Finalise a document handler. + + This will be called on shutdown for a document handler to + release resources. This should cope with being called with NULL. + + opaque: The value previously returned by the init call. +*/ +typedef void fz_document_handler_fin_fn(fz_context *ctx, const fz_document_handler *handler); + + /** Type for a function to be called when processing an already opened page. @@ -392,13 +412,14 @@ typedef void *(fz_process_opened_page_fn)(fz_context *ctx, fz_page *page, void * /** Register a handler for a document type. - handler: The handler to register. + handler: The handler to register. This must live on for the duration of the + use of this handler. It will be passed back to the handler for calls so + the caller can use it to retrieve state. */ void fz_register_document_handler(fz_context *ctx, const fz_document_handler *handler); /** - Register handlers - for all the standard document types supported in + Register handlers for all the standard document types supported in this build. */ void fz_register_document_handlers(fz_context *ctx); @@ -425,13 +446,29 @@ const fz_document_handler *fz_recognize_document_content(fz_context *ctx, const Given a magic find a document handler that can handle a document of this type. - stream: the file stream to sample. + stream: the file stream to sample. May be NULL if the document is + a directory. magic: Can be a filename extension (including initial period) or a mimetype. */ const fz_document_handler *fz_recognize_document_stream_content(fz_context *ctx, fz_stream *stream, const char *magic); +/** + Given a magic find a document handler that can handle a + document of this type. + + stream: the file stream to sample. May be NULL if the document is + a directory. + + dir: an fz_archive representing the directory from which the + stream was opened (or NULL). + + magic: Can be a filename extension (including initial period) or + a mimetype. +*/ +const fz_document_handler *fz_recognize_document_stream_and_dir_content(fz_context *ctx, fz_stream *stream, fz_archive *dir, const char *magic); + /** Open a document file and read its basic structure so pages and objects can be located. MuPDF will try to repair broken @@ -462,9 +499,30 @@ fz_document *fz_open_accelerated_document(fz_context *ctx, const char *filename, magic: a string used to detect document type; either a file name or mime-type. + + stream: a stream representing the contents of the document file. + + NOTE: The caller retains ownership of 'stream' - the document will take its + own reference if required. */ fz_document *fz_open_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream); +/** + Open a document using the specified stream object rather than + opening a file on disk. + + magic: a string used to detect document type; either a file name + or mime-type. + + stream: a stream representing the contents of the document file. + + dir: a 'directory context' for those filetypes that need it. + + NOTE: The caller retains ownership of 'stream' and 'dir' - the document will + take its own references if required. +*/ +fz_document *fz_open_document_with_stream_and_dir(fz_context *ctx, const char *magic, fz_stream *stream, fz_archive *dir); + /** Open a document using a buffer rather than opening a file on disk. */ @@ -476,9 +534,34 @@ fz_document *fz_open_document_with_buffer(fz_context *ctx, const char *magic, fz magic: a string used to detect document type; either a file name or mime-type. + + stream: a stream of the document contents. + + accel: NULL, or a stream of the 'accelerator' contents for this document. + + NOTE: The caller retains ownership of 'stream' and 'accel' - the document will + take its own references if required. */ fz_document *fz_open_accelerated_document_with_stream(fz_context *ctx, const char *magic, fz_stream *stream, fz_stream *accel); +/** + Open a document using the specified stream object rather than + opening a file on disk. + + magic: a string used to detect document type; either a file name + or mime-type. + + stream: a stream of the document contents. + + accel: NULL, or a stream of the 'accelerator' contents for this document. + + dir: NULL, or the 'directory context' for the stream contents. + + NOTE: The caller retains ownership of 'stream', 'accel' and 'dir' - the document will + take its own references if required. +*/ +fz_document *fz_open_accelerated_document_with_stream_and_dir(fz_context *ctx, const char *magic, fz_stream *stream, fz_stream *accel, fz_archive *dir); + /** Query if the document supports the saving of accelerator data. */ @@ -619,6 +702,23 @@ char *fz_format_link_uri(fz_context *ctx, fz_document *doc, fz_link_dest dest); */ fz_location fz_resolve_link(fz_context *ctx, fz_document *doc, const char *uri, float *xp, float *yp); +/** + Run the document structure through a device. + + doc: Document in question. + + dev: Device obtained from fz_new_*_device. + + cookie: Communication mechanism between caller and library. + Intended for multi-threaded applications, while + single-threaded applications set cookie to NULL. The + caller may abort an ongoing rendering of a page. Cookie also + communicates progress information back to the caller. The + fields inside cookie are continually updated while the page is + rendering. +*/ +void fz_run_document_structure(fz_context *ctx, fz_document *doc, fz_device *dev, fz_cookie *cookie); + /** Function to get the location for the last page in the document. Using this can be far more efficient in some cases than calling @@ -977,6 +1077,8 @@ struct fz_document fz_document_set_metadata_fn *set_metadata; fz_document_output_intent_fn *get_output_intent; fz_document_output_accelerator_fn *output_accelerator; + fz_document_run_structure_fn *run_structure; + fz_document_as_pdf_fn *as_pdf; int did_layout; int is_reflowable; @@ -992,14 +1094,15 @@ struct fz_document struct fz_document_handler { + /* These fields are initialised by the handler when it is registered. */ fz_document_recognize_fn *recognize; fz_document_open_fn *open; - fz_document_open_with_stream_fn *open_with_stream; const char **extensions; const char **mimetypes; - fz_document_open_accel_fn *open_accel; - fz_document_open_accel_with_stream_fn *open_accel_with_stream; fz_document_recognize_content_fn *recognize_content; + int wants_dir; + int wants_file; + fz_document_handler_fin_fn *fin; }; #endif diff --git a/include/mupdf/fitz/filter.h b/include/mupdf/fitz/filter.h index 2926b56..bfa8f9d 100644 --- a/include/mupdf/fitz/filter.h +++ b/include/mupdf/fitz/filter.h @@ -101,11 +101,14 @@ fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain); dctd filter performs DCT (JPEG) decoding of data read from the chained filter. - color_transform implements the PDF color_transform option; + color_transform implements the PDF color_transform option + use -1 for default behavior use 0 to disable YUV-RGB / YCCK-CMYK transforms - use >0 to enable YUV-RGB / YCCK-CMYK transforms - use -1 (default) if not embedded in PDF - use -2 (default) if embedded in PDF + use 1 to enable YUV-RGB / YCCK-CMYK transforms + + invert_cmyk implements the necessary inversion for Photoshop CMYK images + use 0 if embedded in PDF + use 1 if not embedded in PDF For subsampling on decode, set l2factor to the log2 of the reduction required (therefore 0 = full size decode). @@ -113,7 +116,7 @@ fz_stream *fz_open_rld(fz_context *ctx, fz_stream *chain); jpegtables is an optional stream from which the JPEG tables can be read. Use NULL if not required. */ -fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int l2factor, fz_stream *jpegtables); +fz_stream *fz_open_dctd(fz_context *ctx, fz_stream *chain, int color_transform, int invert_cmyk, int l2factor, fz_stream *jpegtables); /** faxd filter performs FAX decoding of data read from @@ -151,6 +154,15 @@ fz_stream *fz_open_faxd(fz_context *ctx, fz_stream *chain, */ fz_stream *fz_open_flated(fz_context *ctx, fz_stream *chain, int window_bits); +/** + libarchived filter performs generic compressed decoding of data + in any format understood by libarchive from the chained filter. + + This will throw an exception if libarchive is not built in, or + if the compression format is not recognised. +*/ +fz_stream *fz_open_libarchived(fz_context *ctx, fz_stream *chain); + /** lzwd filter performs LZW decoding of data read from the chained filter. diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h index be22ee8..bcfe2d5 100644 --- a/include/mupdf/fitz/font.h +++ b/include/mupdf/fitz/font.h @@ -62,6 +62,44 @@ int fz_unicode_from_glyph_name_strict(const char *name); const char **fz_duplicate_glyph_names_from_unicode(int unicode); const char *fz_glyph_name_from_unicode_sc(int unicode); +/** + * A text decoder (to read arbitrary encodings and convert to unicode). + */ +typedef struct fz_text_decoder fz_text_decoder; + +struct fz_text_decoder { + // get maximum size estimate of converted text (fast) + int (*decode_bound)(fz_text_decoder *dec, unsigned char *input, int n); + + // get exact size of converted text (slow) + int (*decode_size)(fz_text_decoder *dec, unsigned char *input, int n); + + // convert text into output buffer + void (*decode)(fz_text_decoder *dec, char *output, unsigned char *input, int n); + + // for internal use only; do not touch! + void *table1; + void *table2; +}; + +/* Initialize a text decoder using an IANA encoding name. + * See source/fitz/text-decoder.c for the exact list of supported encodings. + * Will throw an exception if the requested encoding is not available. + * + * The following is a subset of the supported encodings (see source/fitz/text-decoder.c for the full list): + * iso-8859-1 + * iso-8859-7 + * koi8-r + * euc-jp + * shift_jis + * euc-kr + * euc-cn + * gb18030 + * euc-tw + * big5 + */ +void fz_init_text_decoder(fz_context *ctx, fz_text_decoder *dec, const char *encoding); + /** An abstract font handle. */ @@ -743,4 +781,35 @@ struct fz_font int subfont; }; +void fz_ft_lock(fz_context *ctx); + +void fz_ft_unlock(fz_context *ctx); + +/* Internal function. Must be called with FT_ALLOC_LOCK + * held. Returns 1 if this thread (context!) already holds + * the freeetype lock. */ +int fz_ft_lock_held(fz_context *ctx); + +/* Internal function: Extract a ttf from the ttc that underlies + * a given fz_font. Caller takes ownership of the returned + * buffer. + */ +fz_buffer *fz_extract_ttf_from_ttc(fz_context *ctx, fz_font *font); + +/* Internal function: Given a ttf in a buffer, create a subset + * ttf in a new buffer that only provides the required gids. + * Caller takes ownership of the returned buffer. + * + * EXPERIMENTAL AND VERY SUBJECT TO CHANGE. + */ +fz_buffer *fz_subset_ttf_for_gids(fz_context *ctx, fz_buffer *orig, int *gids, int num_gids, int symbolic, int cidfont); + +/* Internal function: Given a cff in a buffer, create a subset + * cff in a new buffer that only provides the required gids. + * Caller takes ownership of the returned buffer. + * + * EXPERIMENTAL AND VERY SUBJECT TO CHANGE. + */ +fz_buffer *fz_subset_cff_for_gids(fz_context *ctx, fz_buffer *orig, int *gids, int num_gids, int symbolic, int cidfont); + #endif diff --git a/include/mupdf/fitz/getopt.h b/include/mupdf/fitz/getopt.h index 13677d1..50409a0 100644 --- a/include/mupdf/fitz/getopt.h +++ b/include/mupdf/fitz/getopt.h @@ -25,11 +25,104 @@ #include "export.h" +typedef struct +{ + char *option; + int *flag; + void *opaque; +} fz_getopt_long_options; + /** Simple functions/variables for use in tools. + + ostr = option string. Comprises single letter options, followed by : if there + is an argument to the option. + + longopts: NULL (indicating no long options), or a pointer to an array of + longoptions, terminated by an entry with option == NULL. + + In the event of matching a single char option, this function will normally + return the char. The exception to this is when the option requires an + argument and none is supplied; in this case we return ':'. + + In the event of matching a long option, this function returns 0, with fz_optlong + set to point to the matching option. + + A long option entry may be followed with : to indicate there is an argument to the + option. If the need for an argument is specified in this way, and no argument is + given, an error will be displayed and argument processing will stop. If an argument + is given, and the long option record contains a non-null flag pointer, then the code + will decode the argument and fill in that flag pointer. Specifically, + case-insensitive matches to 'yes', 'no', 'true' and 'false' will cause a value of 0 + or 1 as appropriate to be written; failing this the arg will be interpreted as a + decimal integer using atoi. + + A long option entry may be followed by an list of options (e.g. myoption=foo|bar|baz) + and the option will be passed to fz_opt_from_list. The return value of that will be + placed in fz_optitem. If the return value of that function is -1, then an error will + be displayed and argument processing will stop. + + In the event of reaching the end of the arg list or '--', this function returns EOF. + + In the event of failing to match anything, an error is printed, and we return '?'. + + If an argument is expected for the option, then fz_optarg will be returned pointing + at the start of the argument. Examples of supported argument formats: '-r500', '-r 500', + '--resolution 500', '--resolution=500'. +*/ +extern int fz_getopt_long(int nargc, char * const *nargv, const char *ostr, const fz_getopt_long_options *longopts); + +/** + Identical to fz_getopt_long, but with a NULL longopts field, signifying no long + options. */ extern int fz_getopt(int nargc, char * const *nargv, const char *ostr); + +/** + fz_optind is updated to point to the current index being read from the + arguments. +*/ FZ_DATA extern int fz_optind; + +/** + fz_optarg is a pointer to the argument data for the most recently + read option. +*/ FZ_DATA extern char *fz_optarg; +/** + fz_optlong is a pointer to the record for the most recently + read long option. (i.e. if a long option is detected, this + will be set to point to the record for that option, otherwise + it will be NULL). +*/ +FZ_DATA extern const fz_getopt_long_options *fz_optlong; + +/** + The item number for the most recently matched item list. + + First item in the list is numbered 0. No match is -1. +*/ +FZ_DATA extern int fz_optitem; + +/** + Return the index of a (case-insensitive) option within an optlist. + + For instance for optlist = "Foo|Bar|Baz", and opt = "bar", + this would return 1. + + If the optlist ends with "|*" then that is a catch all case and + matches all options allowing the caller to process it itself. + fz_optarg will be set to point to the option, and the return + value will be the index of the '*' option within that list. + + If an optlist entry ends with ':' (e.g. "Foo:") then that option + may have suboptions appended to it (for example "JPG:80") and + fz_optarg will be set to point at "80". Otherwise fz_optarg will + be set to NULL. + + In the event of no-match found, prints an error and returns -1. +*/ +int fz_opt_from_list(char *opt, const char *optlist); + #endif diff --git a/include/mupdf/fitz/heap-imp.h b/include/mupdf/fitz/heap-imp.h new file mode 100644 index 0000000..5e042d9 --- /dev/null +++ b/include/mupdf/fitz/heap-imp.h @@ -0,0 +1,163 @@ +// Copyright (C) 2004-2022 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +/* This file has preprocessor magic in it to instantiate both + * protoypes and implementations for heap sorting structures + * of various different types. Effectively, it's templating for + * C. + * + * If you are including this file directly without intending to + * be instantiating a new set of heap sort functions, you are + * doing the wrong thing. + */ + +#ifndef MUPDF_FITZ_HEAP_I_KNOW_WHAT_IM_DOING +#error Do not include heap-imp.h unless you know what youre doing +#endif + +#define HEAP_XCAT(A,B) A##B +#define HEAP_CAT(A,B) HEAP_XCAT(A,B) + +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +typedef struct +{ + int max; + int len; + HEAP_CONTAINER_TYPE *heap; +} HEAP_TYPE_NAME; +#endif + +void HEAP_CAT(HEAP_TYPE_NAME,_insert)(fz_context *ctx, HEAP_TYPE_NAME *heap, HEAP_CONTAINER_TYPE v +#ifndef HEAP_CMP + , int (*HEAP_CMP)(HEAP_CONTAINER_TYPE *a, HEAP_CONTAINER_TYPE *b) +#endif + ) +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +; +#else +{ + int i; + HEAP_CONTAINER_TYPE *h; + + if (heap->max == heap->len) + { + int m = heap->max * 2; + + if (m == 0) + m = 32; + + heap->heap = (HEAP_CONTAINER_TYPE *)fz_realloc(ctx, heap->heap, sizeof(*heap->heap) * m); + heap->max = m; + } + h = heap->heap; + + /* Insert it into the heap. Consider inserting at position i, and + * then 'heapify' back. We can delay the actual insertion to the + * end of the process. */ + i = heap->len++; + while (i != 0) + { + int parent_idx = (i-1)/2; + HEAP_CONTAINER_TYPE *parent_val = &h[parent_idx]; + if (HEAP_CMP(parent_val, &v) > 0) + break; + h[i] = h[parent_idx]; + i = parent_idx; + } + h[i] = v; +} +#endif + +void HEAP_CAT(HEAP_TYPE_NAME,_sort)(fz_context *ctx, HEAP_TYPE_NAME *heap +#ifndef HEAP_CMP + , int (*HEAP_CMP)(HEAP_CONTAINER_TYPE *a, HEAP_CONTAINER_TYPE *b) +#endif + ) +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +; +#else +{ + int j; + HEAP_CONTAINER_TYPE *h = heap->heap; + + /* elements j to len are always sorted. 0 to j are always a valid heap. Gradually move j to 0. */ + for (j = heap->len-1; j > 0; j--) + { + int k; + HEAP_CONTAINER_TYPE val; + + /* Swap max element with j. Invariant valid for next value to j. */ + val = h[j]; + h[j] = h[0]; + /* Now reform the heap. 0 to k is a valid heap. */ + k = 0; + while (1) + { + int kid = k*2+1; + if (kid >= j) + break; + if (kid+1 < j && (HEAP_CMP(&h[kid+1], &h[kid])) > 0) + kid++; + if ((HEAP_CMP(&val, &h[kid])) > 0) + break; + h[k] = h[kid]; + k = kid; + } + h[k] = val; + } +} +#endif + +void HEAP_CAT(HEAP_TYPE_NAME,_uniq)(fz_context *ctx, HEAP_TYPE_NAME *heap +#ifndef HEAP_CMP + , int (*HEAP_CMP)(HEAP_CONTAINER_TYPE *a, HEAP_CONTAINER_TYPE *b) +#endif + ) +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +; +#else +{ + int n = heap->len; + int i, j = 0; + HEAP_CONTAINER_TYPE *h = heap->heap; + + if (n == 0) + return; + + j = 0; + for (i = 1; i < n; i++) + { + if (HEAP_CMP(&h[j], &h[i]) == 0) + continue; + j++; + if (i != j) + h[j] = h[i]; + } + heap->len = j+1; +} +#endif + +#undef HEAP_CONTAINER_TYPE +#undef HEAP_TYPE_NAME +#undef HEAP_CMP +#undef HEAP_XCAT +#undef HEAP_CAT diff --git a/include/mupdf/fitz/heap.h b/include/mupdf/fitz/heap.h new file mode 100644 index 0000000..97d98a8 --- /dev/null +++ b/include/mupdf/fitz/heap.h @@ -0,0 +1,140 @@ +// Copyright (C) 2004-2022 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +/* This file has preprocessor magic in it to instantiate both + * protoypes and implementations for heap sorting structures + * of various different types. Effectively, it's templating for + * C. + * + * If you are including this file directly without intending to + * be instantiating a new set of heap sort functions, you are + * doing the wrong thing. + */ + +/* This header file declares some useful heap functions. (Heap + * as in heap sort, not as in memory heap). It uses some + * clever (read "hacky") multiple inclusion techniques to allow + * us to generate multiple different versions of this code. + * This is kinda like 'templating' in C++, but without language + * support. + */ + +/* For every instance of this code, we end up a heap structure: + * + * typedef struct + * { + * int max; + * int len; + * *heap; + * } fz__heap; + * + * This can be created and initialised on the stack in user code using: + * + * fz__heap heap = { 0 }; + * + * and some functions. + * + * When is a simple int (or float or similar), the ordering required is + * obvious, and so the functions are simple (Form 1): + * + * First some to insert elements into the heap: + * + * void fz__heap_insert(fz_context *ctx, fz__heap *heap, v); + * + * Once all the elements have been inserted, the heap can be sorted: + * + * void fz__heap_sort(fz_context *ctx, fz__heap *heap); + * + * Once sorted, repeated elements can be removed: + * + * void fz__heap_uniq(fz_context *ctx, fz__heap *heap); + * + * + * For more complex TYPEs (such as pointers) the ordering may not be implicit within the , + * but rather depends upon the data found by dereferencing those pointers. For such types, + * the functions are modified with a function, of the form used by qsort etc: + * + * int (x, y) that returns 0 for x == y, +ve for x > y, and -ve for x < y. + * + * The functions are modified thus (Form 2): + * + * void fz__heap_insert(fz_context *ctx, fz__heap *heap, v, t); + * void fz__heap_sort(fz_context *ctx, fz__heap *heap, t); + * void fz__heap_uniq(fz_context *ctx, fz__heap *heap, t); + * + * Currently, we define: + * + * fz_int_heap Operates on 'int' values. Form 1. + * fz_ptr_heap Operates on 'void *' values. Form 2. + * fz_int2_heap Operates on 'typedef struct { int a; int b} fz_int2' values, + * with the sort/uniq being done based on 'a' alone. Form 1. + * fz_intptr_heap Operates on 'typedef struct { int a; void *b} fz_intptr' values, + * with the sort/uniq being done based on 'a' alone. Form 1. + */ + +/* Everything after this point is preprocessor magic. Ignore it, and just read the above + * unless you are wanting to instantiate a new set of functions. */ + +#ifndef MUPDF_FITZ_HEAP_H + +#define MUPDF_FITZ_HEAP_H + +#define MUPDF_FITZ_HEAP_I_KNOW_WHAT_IM_DOING + +/* Instantiate fz_int_heap */ +#define HEAP_TYPE_NAME fz_int_heap +#define HEAP_CONTAINER_TYPE int +#define HEAP_CMP(a,b) ((*a) - (*b)) +#include "mupdf/fitz/heap-imp.h" + +/* Instantiate fz_ptr_heap */ +#define HEAP_TYPE_NAME fz_ptr_heap +#define HEAP_CONTAINER_TYPE void * +#include "mupdf/fitz/heap-imp.h" + +/* Instantiate fz_int2_heap */ +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +typedef struct +{ + int a; + int b; +} fz_int2; +#endif +#define HEAP_TYPE_NAME fz_int2_heap +#define HEAP_CMP(A,B) (((A)->a) - ((B)->a)) +#define HEAP_CONTAINER_TYPE fz_int2 +#include "mupdf/fitz/heap-imp.h" + +/* Instantiate fz_intptr_heap */ +#ifndef MUPDF_FITZ_HEAP_IMPLEMENT +typedef struct +{ + int a; + int b; +} fz_intptr; +#endif +#define HEAP_TYPE_NAME fz_intptr_heap +#define HEAP_CONTAINER_TYPE fz_intptr +#define HEAP_CMP(A,B) (((A)->a) - ((B)->a)) +#include "mupdf/fitz/heap-imp.h" + +#endif /* MUPDF_FITZ_HEAP_H */ diff --git a/include/mupdf/fitz/image.h b/include/mupdf/fitz/image.h index 972f8fb..3f9dee1 100644 --- a/include/mupdf/fitz/image.h +++ b/include/mupdf/fitz/image.h @@ -199,8 +199,8 @@ fz_image *fz_new_image_of_size(fz_context *ctx, int yres, int interpolate, int imagemask, - float *decode, - int *colorkey, + const float *decode, + const int *colorkey, fz_image *mask, size_t size, fz_image_get_pixmap_fn *get_pixmap, @@ -243,7 +243,7 @@ fz_image *fz_new_image_of_size(fz_context *ctx, A new reference is taken to this image. Supplying a masked image as a mask to another image is illegal! */ -fz_image *fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, float *decode, int *colorkey, fz_compressed_buffer *buffer, fz_image *mask); +fz_image *fz_new_image_from_compressed_buffer(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace, int xres, int yres, int interpolate, int imagemask, const float *decode, const int *colorkey, fz_compressed_buffer *buffer, fz_image *mask); /** Create an image from the given @@ -315,6 +315,14 @@ fz_pixmap *fz_convert_separation_pixmap_to_base(fz_context *ctx, const fz_pixmap */ size_t fz_image_size(fz_context *ctx, fz_image *im); +/** + Return the type of a compressed image. + + Any non-compressed image will have the type returned as UNKNOWN. +*/ +int fz_compressed_image_type(fz_context *ctx, fz_image *image); + + /** Structure is public to allow other structures to be derived from it. Do not access members directly. @@ -413,6 +421,13 @@ void fz_set_pixmap_image_tile(fz_context *ctx, fz_pixmap_image *cimg, fz_pixmap */ fz_pixmap *fz_load_jpx(fz_context *ctx, const unsigned char *data, size_t size, fz_colorspace *cs); +/** + Exposed because compression and decompression need to share this. +*/ +void opj_lock(fz_context *ctx); +void opj_unlock(fz_context *ctx); + + /** Exposed for CBZ. */ diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h index 350b00b..ee3d099 100644 --- a/include/mupdf/fitz/output.h +++ b/include/mupdf/fitz/output.h @@ -54,7 +54,7 @@ typedef void (fz_output_write_fn)(fz_context *ctx, void *state, const void *data state: The output stream state to seek within. - offset, whence: as defined for fs_seek_output. + offset, whence: as defined for fz_seek(). */ typedef void (fz_output_seek_fn)(fz_context *ctx, void *state, int64_t offset, int whence); @@ -76,6 +76,14 @@ typedef int64_t (fz_output_tell_fn)(fz_context *ctx, void *state); */ typedef void (fz_output_close_fn)(fz_context *ctx, void *state); +/** + A function type for use when implementing + fz_outputs. The supplied function of this type is called + when the output stream is reset, and resets the state + to that when it was first initialised. +*/ +typedef void (fz_output_reset_fn)(fz_context *ctx, void *state); + /** A function type for use when implementing fz_outputs. The supplied function of this type is called @@ -107,8 +115,10 @@ struct fz_output fz_output_tell_fn *tell; fz_output_close_fn *close; fz_output_drop_fn *drop; + fz_output_reset_fn *reset; fz_stream_from_output_fn *as_stream; fz_truncate_fn *truncate; + int closed; char *bp, *wp, *ep; /* If buffered is non-zero, then we have that many * bits (1-7) waiting to be written in bits. */ @@ -140,6 +150,15 @@ fz_output *fz_new_output(fz_context *ctx, int bufsiz, void *state, fz_output_wri */ fz_output *fz_new_output_with_path(fz_context *, const char *filename, int append); +/** + Open an output stream that writes to a + given FILE *. + + file: The file pointers to write to. NULL is interpreted as effectively + meaning /dev/null or similar. +*/ +fz_output *fz_new_output_with_file_ptr(fz_context *ctx, FILE *file); + /** Open an output stream that appends to a buffer. @@ -222,6 +241,14 @@ void fz_flush_output(fz_context *ctx, fz_output *out); */ void fz_close_output(fz_context *, fz_output *); +/** + Reset a closed output stream. Returns state to + (broadly) that which it was in when opened. Not + all outputs can be reset, so this may throw an + exception. +*/ +void fz_reset_output(fz_context *, fz_output *); + /** Free an output stream. Don't forget to close it first! */ @@ -308,9 +335,14 @@ void fz_write_bits(fz_context *ctx, fz_output *out, unsigned int data, int num_b */ void fz_write_bits_sync(fz_context *ctx, fz_output *out); +/** + Copy the stream contents to the output. +*/ +void fz_write_stream(fz_context *ctx, fz_output *out, fz_stream *in); + /** Our customised 'printf'-like string formatter. - Takes %c, %d, %s, %u, %x, as usual. + Takes %c, %d, %s, %u, %x, %X as usual. Modifiers are not supported except for zero-padding ints (e.g. %02d, %03u, %04x, etc). %g output in "as short as possible hopefully lossless @@ -322,8 +354,8 @@ void fz_write_bits_sync(fz_context *ctx, fz_output *out); %P outputs a fz_point*. %n outputs a PDF name (with appropriate escaping). %q and %( output escaped strings in C/PDF syntax. - %l{d,u,x} indicates that the values are int64_t. - %z{d,u,x} indicates that the value is a size_t. + %l{d,u,x,X} indicates that the values are int64_t. + %z{d,u,x,X} indicates that the value is a size_t. user: An opaque pointer that is passed to the emit function. diff --git a/include/mupdf/fitz/pixmap.h b/include/mupdf/fitz/pixmap.h index 34460de..e1c1fab 100644 --- a/include/mupdf/fitz/pixmap.h +++ b/include/mupdf/fitz/pixmap.h @@ -65,6 +65,11 @@ int fz_pixmap_x(fz_context *ctx, const fz_pixmap *pix); */ int fz_pixmap_y(fz_context *ctx, const fz_pixmap *pix); +/** + Return sizeof fz_pixmap plus size of data, in bytes. +*/ +size_t fz_pixmap_size(fz_context *ctx, fz_pixmap *pix); + /** Create a new pixmap, with its origin at (0,0) @@ -471,4 +476,26 @@ fz_pixmap *fz_new_pixmap_from_alpha_channel(fz_context *ctx, fz_pixmap *src); */ fz_pixmap *fz_new_pixmap_from_color_and_mask(fz_context *ctx, fz_pixmap *color, fz_pixmap *mask); +/* + * Scale the pixmap up or down in size to fit the rectangle. Will return `NULL` + * if the scaling factors are out of range. This applies fancy filtering and + * will anti-alias the edges for subpixel positioning if using non-integer + * coordinates. If the clip rectangle is set, the returned pixmap may be subset + * to fit the clip rectangle. Pass `NULL` to the clip if you want the whole + * pixmap scaled. + */ +fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, const fz_irect *clip); + +/* + * Reduces size to: + * tile->w => (tile->w + 2^factor-1) / 2^factor + * tile->h => (tile->h + 2^factor-1) / 2^factor + */ +void fz_subsample_pixmap(fz_context *ctx, fz_pixmap *tile, int factor); + +/* + * Copies r (clipped to both src and dest) in src to dest. + */ +void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_irect r, const fz_default_colorspaces *default_cs); + #endif diff --git a/include/mupdf/fitz/shade.h b/include/mupdf/fitz/shade.h index 8acde99..bb0d70f 100644 --- a/include/mupdf/fitz/shade.h +++ b/include/mupdf/fitz/shade.h @@ -61,12 +61,14 @@ typedef struct float background[FZ_MAX_COLORS]; /* Just to be confusing, PDF Shadings of Type 1 (Function Based - * Shadings), do NOT use_function, but all the others do. This + * Shadings), do NOT use function, but all the others do. This * is because Type 1 shadings take 2 inputs, whereas all the * others (when used with a function take 1 input. The type 1 * data is in the 'f' field of the union below. */ - int use_function; - float function[256][FZ_MAX_COLORS + 1]; + /* If function_stride = 0, then function is not used. Otherwise + * function points to 256*function_stride entries. */ + int function_stride; + float *function; int type; /* function, linear, radial, mesh */ union diff --git a/include/mupdf/fitz/store.h b/include/mupdf/fitz/store.h index 027c145..452bb59 100644 --- a/include/mupdf/fitz/store.h +++ b/include/mupdf/fitz/store.h @@ -59,6 +59,14 @@ typedef struct fz_storable fz_storable; */ typedef void (fz_store_drop_fn)(fz_context *, fz_storable *); +/** + Function type for a function to check whether a storable + object can be dropped at the moment. + + Return 0 for 'cannot be dropped', 1 otherwise. +*/ +typedef int (fz_store_droppable_fn)(fz_context *, fz_storable *); + /** Any storable object should include an fz_storable structure at the start (by convention at least) of their structure. @@ -67,6 +75,7 @@ typedef void (fz_store_drop_fn)(fz_context *, fz_storable *); struct fz_storable { int refs; fz_store_drop_fn *drop; + fz_store_droppable_fn *droppable; }; /** @@ -81,11 +90,16 @@ typedef struct } fz_key_storable; /** - Macro to initialise a storable object. + Macros to initialise a storable object. */ #define FZ_INIT_STORABLE(S_,RC,DROP) \ do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ - S->drop = (DROP); \ + S->drop = (DROP); S->droppable = NULL; \ + } while (0) + +#define FZ_INIT_AWKWARD_STORABLE(S_,RC,DROP,DROPPABLE) \ + do { fz_storable *S = &(S_)->storable; S->refs = (RC); \ + S->drop = (DROP); S->droppable = (DROPPABLE); \ } while (0) /** diff --git a/include/mupdf/fitz/story-writer.h b/include/mupdf/fitz/story-writer.h index 6ecc132..70cbcd5 100644 --- a/include/mupdf/fitz/story-writer.h +++ b/include/mupdf/fitz/story-writer.h @@ -189,8 +189,8 @@ void fz_write_story( * story content has been written to the device). * pagefn_ref: * Passed to pagefn(). - * archive: - * NULL, or an archive to load images etc from. + * dir: + * NULL, or a directory context to load images etc from. */ void fz_write_stabilized_story( fz_context *ctx, @@ -203,7 +203,7 @@ void fz_write_stabilized_story( void *rectfn_ref, fz_write_story_pagefn pagefn, void *pagefn_ref, - fz_archive *archive + fz_archive *dir ); #endif diff --git a/include/mupdf/fitz/story.h b/include/mupdf/fitz/story.h index 5a31c56..248dd3b 100644 --- a/include/mupdf/fitz/story.h +++ b/include/mupdf/fitz/story.h @@ -56,11 +56,11 @@ typedef struct fz_story fz_story; Passing a NULL buffer will be treated as an empty document. Passing a NULL user_css will be treated as an empty CSS string. - A non-NULL archive will allow images etc to be loaded. The + A non-NULL dir will allow images etc to be loaded. The story keeps its own reference, so the caller can drop its reference after this call. */ -fz_story *fz_new_story(fz_context *ctx, fz_buffer *buf, const char *user_css, float em, fz_archive *archive); +fz_story *fz_new_story(fz_context *ctx, fz_buffer *buf, const char *user_css, float em, fz_archive *dir); /* Retrieve the warnings given from parsing this story. @@ -77,11 +77,21 @@ fz_story *fz_new_story(fz_context *ctx, fz_buffer *buf, const char *user_css, fl */ const char *fz_story_warnings(fz_context *ctx, fz_story *story); +/* + Equivalent to fz_place_story_flags with flags being 0. +*/ +int fz_place_story(fz_context *ctx, fz_story *story, fz_rect where, fz_rect *filled); + /* Place (or continue placing) a story into the supplied rectangle 'where', updating 'filled' with the actual area that was used. - Returns zero if all the content fitted, non-zero if there is - more to fit. + Returns zero (FZ_PLACE_STORY_RETURN_ALL_FITTED) if all the + content fitted, non-zero if there is more to fit. + + If the FZ_PLACE_STORY_FLAG_NO_OVERFLOW flag is set, then a + return code of FZ_PLACE_STORY_RETURN_OVERFLOW_WIDTH will be + returned when the next item (word) to be placed would not fit + in a rectangle of that given width. Note, that filled may not be returned as a strict subset of where, due to padding/margins at the bottom of pages, and @@ -95,8 +105,24 @@ const char *fz_story_warnings(fz_context *ctx, fz_story *story); After this function is called, the DOM is no longer accessible, and any fz_xml pointer retrieved from fz_story_document is no longer valid. + + flags: Additional flags controlling layout. Pass 0 if none + required. */ -int fz_place_story(fz_context *ctx, fz_story *story, fz_rect where, fz_rect *filled); +int fz_place_story_flags(fz_context *ctx, fz_story *story, fz_rect where, fz_rect *filled, int flags); + +enum +{ + /* Avoid the usual HTML behaviour of overflowing the box horizontally + * in some circumstances. We now abort the place in such cases and + * return with */ + FZ_PLACE_STORY_FLAG_NO_OVERFLOW = 1, + + /* Specific return codes from fz_place_story_flags. Also + * "non-zero" for 'more to fit'. */ + FZ_PLACE_STORY_RETURN_ALL_FITTED = 0, + FZ_PLACE_STORY_RETURN_OVERFLOW_WIDTH = 2 +}; /* Draw the placed story to the given device. diff --git a/include/mupdf/fitz/stream.h b/include/mupdf/fitz/stream.h index 93d9b1c..13d1c77 100644 --- a/include/mupdf/fitz/stream.h +++ b/include/mupdf/fitz/stream.h @@ -55,6 +55,11 @@ typedef struct fz_stream fz_stream; */ fz_stream *fz_open_file(fz_context *ctx, const char *filename); +/** + Do the same as fz_open_file, but delete the file upon close. +*/ +fz_stream *fz_open_file_autodelete(fz_context *ctx, const char *filename); + /** Open the named file and wrap it in a stream. @@ -76,6 +81,14 @@ fz_stream *fz_try_open_file(fz_context *ctx, const char *name); fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); #endif /* _WIN32 */ +/** + Return the filename (UTF-8 encoded) from which a stream was opened. + + Returns NULL if the filename is not available (or the stream was + opened from a source other than a file). +*/ +const char *fz_stream_filename(fz_context *ctx, fz_stream *stm); + /** Open a block of memory as a stream. @@ -145,6 +158,10 @@ int64_t fz_tell(fz_context *ctx, fz_stream *stm); offset: The offset to seek to. whence: From where the offset is measured (see fseek). + SEEK_SET - start of stream. + SEEK_CUR - current position. + SEEK_END - end of stream. + */ void fz_seek(fz_context *ctx, fz_stream *stm, int64_t offset, int whence); @@ -394,6 +411,7 @@ static inline size_t fz_available(fz_context *ctx, fz_stream *stm, size_t max) fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); fz_warn(ctx, "read error; treating as end of file"); stm->error = 1; c = EOF; @@ -428,6 +446,7 @@ static inline int fz_read_byte(fz_context *ctx, fz_stream *stm) fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); fz_warn(ctx, "read error; treating as end of file"); stm->error = 1; c = EOF; @@ -462,6 +481,7 @@ static inline int fz_peek_byte(fz_context *ctx, fz_stream *stm) fz_catch(ctx) { fz_rethrow_if(ctx, FZ_ERROR_TRYLATER); + fz_report_error(ctx); fz_warn(ctx, "read error; treating as end of file"); stm->error = 1; c = EOF; diff --git a/include/mupdf/fitz/string-util.h b/include/mupdf/fitz/string-util.h index d2bba64..4acc644 100644 --- a/include/mupdf/fitz/string-util.h +++ b/include/mupdf/fitz/string-util.h @@ -157,6 +157,14 @@ void fz_format_output_path(fz_context *ctx, char *path, size_t size, const char */ char *fz_cleanname(char *name); +/** + rewrite path to the shortest string that names the same path. + + Eliminates multiple and trailing slashes, interprets "." and + "..". Allocates a new string that the caller must free. +*/ +char *fz_cleanname_strdup(fz_context *ctx, const char *name); + /** Resolve a path to an absolute file name. The resolved path buffer must be of at least PATH_MAX size. @@ -241,6 +249,17 @@ const char *fz_runeptr(const char *str, int idx); */ int fz_utflen(const char *s); +/* + Convert a wchar string into a new heap allocated utf8 one. +*/ +char *fz_utf8_from_wchar(fz_context *ctx, const wchar_t *s); + +/* + Convert a utf8 string into a new heap allocated wchar one. +*/ +wchar_t *fz_wchar_from_utf8(fz_context *ctx, const char *path); + + /** Locale-independent decimal to binary conversion. On overflow return (-)INFINITY and set errno to ERANGE. On underflow return diff --git a/include/mupdf/fitz/structured-text.h b/include/mupdf/fitz/structured-text.h index b259517..ae108b4 100644 --- a/include/mupdf/fitz/structured-text.h +++ b/include/mupdf/fitz/structured-text.h @@ -133,6 +133,7 @@ enum FZ_STEXT_DEHYPHENATE = 16, FZ_STEXT_PRESERVE_SPANS = 32, FZ_STEXT_MEDIABOX_CLIP = 64, + FZ_STEXT_USE_CID_FOR_UNKNOWN_UNICODE = 128, }; /** @@ -185,7 +186,8 @@ struct fz_stext_line */ struct fz_stext_char { - int c; + int c; /* unicode character value */ + int bidi; /* even for LTR, odd for RTL */ int color; /* sRGB hex color */ fz_point origin; fz_quad quad; @@ -281,7 +283,7 @@ char *fz_copy_selection(fz_context *ctx, fz_stext_page *page, fz_point a, fz_poi char *fz_copy_rectangle(fz_context *ctx, fz_stext_page *page, fz_rect area, int crlf); /** - Options for creating a pixmap and draw device. + Options for creating structured text. */ typedef struct { diff --git a/include/mupdf/fitz/system.h b/include/mupdf/fitz/system.h index 7f8a564..6ca13ac 100644 --- a/include/mupdf/fitz/system.h +++ b/include/mupdf/fitz/system.h @@ -165,9 +165,6 @@ static __inline int signbit(double x) #ifdef _WIN32 -char *fz_utf8_from_wchar(const wchar_t *s); -wchar_t *fz_wchar_from_utf8(const char *s); - /* really a FILE* but we don't want to include stdio.h here */ void *fz_fopen_utf8(const char *name, const char *mode); int fz_remove_utf8(const char *name); @@ -184,6 +181,8 @@ void fz_free_argv(int argc, char **argv); int64_t fz_stat_ctime(const char *path); int64_t fz_stat_mtime(const char *path); +int fz_mkdir(char *path); + /* inline is standard in C++. For some compilers we can enable it within * C too. Some compilers think they know better than we do about when diff --git a/include/mupdf/fitz/text.h b/include/mupdf/fitz/text.h index 499a2ae..d7562f9 100644 --- a/include/mupdf/fitz/text.h +++ b/include/mupdf/fitz/text.h @@ -46,6 +46,7 @@ typedef struct float x, y; int gid; /* -1 for one gid to many ucs mappings */ int ucs; /* -1 for one ucs to many gid mappings */ + int cid; /* CID for CJK fonts, raw character code for other fonts; or unicode for non-PDF formats. */ } fz_text_item; #define FZ_LANG_TAG2(c1,c2) ((c1-'a'+1) + ((c2-'a'+1)*27)) @@ -118,6 +119,8 @@ void fz_drop_text(fz_context *ctx, const fz_text *text); unicode: The unicode character for the glyph. + cid: The CJK CID value or raw character code. + wmode: 1 for vertical mode, 0 for horizontal. bidi_level: The bidirectional level for this glyph. @@ -131,6 +134,7 @@ void fz_drop_text(fz_context *ctx, const fz_text *text); Throws exception on failure to allocate. */ void fz_show_glyph(fz_context *ctx, fz_text *text, fz_font *font, fz_matrix trm, int glyph, int unicode, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language language); +void fz_show_glyph_aux(fz_context *ctx, fz_text *text, fz_font *font, fz_matrix trm, int glyph, int unicode, int cid, int wmode, int bidi_level, fz_bidi_direction markup_dir, fz_text_language lang); /** Add a UTF8 string to a text object. diff --git a/include/mupdf/fitz/util.h b/include/mupdf/fitz/util.h index d8a3504..0048508 100644 --- a/include/mupdf/fitz/util.h +++ b/include/mupdf/fitz/util.h @@ -108,22 +108,22 @@ int fz_search_display_list(fz_context *ctx, fz_display_list *list, const char *n /** Parse an SVG document into a display-list. */ -fz_display_list *fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *zip, float *w, float *h); +fz_display_list *fz_new_display_list_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *dir, float *w, float *h); /** Create a scalable image from an SVG document. */ -fz_image *fz_new_image_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *zip); +fz_image *fz_new_image_from_svg(fz_context *ctx, fz_buffer *buf, const char *base_uri, fz_archive *dir); /** Parse an SVG document into a display-list. */ -fz_display_list *fz_new_display_list_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *zip, float *w, float *h); +fz_display_list *fz_new_display_list_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *dir, float *w, float *h); /** Create a scalable image from an SVG document. */ -fz_image *fz_new_image_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *zip); +fz_image *fz_new_image_from_svg_xml(fz_context *ctx, fz_xml_doc *xmldoc, fz_xml *xml, const char *base_uri, fz_archive *dir); /** Write image as a data URI (for HTML and SVG output). diff --git a/include/mupdf/fitz/version.h b/include/mupdf/fitz/version.h index 04226d5..8bf080b 100644 --- a/include/mupdf/fitz/version.h +++ b/include/mupdf/fitz/version.h @@ -1,4 +1,4 @@ -// Copyright (C) 2004-2022 Artifex Software, Inc. +// Copyright (C) 2004-2024 Artifex Software, Inc. // // This file is part of MuPDF. // @@ -23,9 +23,9 @@ #ifndef MUPDF_FITZ_VERSION_H #define MUPDF_FITZ_VERSION_H #ifndef FZ_VERSION -#define FZ_VERSION "1.23.7" +#define FZ_VERSION "1.24.9" #define FZ_VERSION_MAJOR 1 -#define FZ_VERSION_MINOR 23 -#define FZ_VERSION_PATCH 7 +#define FZ_VERSION_MINOR 24 +#define FZ_VERSION_PATCH 9 #endif #endif diff --git a/include/mupdf/fitz/write-pixmap.h b/include/mupdf/fitz/write-pixmap.h index 8d618f7..8ddb1ef 100644 --- a/include/mupdf/fitz/write-pixmap.h +++ b/include/mupdf/fitz/write-pixmap.h @@ -225,6 +225,11 @@ void fz_save_pixmap_as_pdfocr(fz_context *ctx, fz_pixmap *pixmap, char *filename */ void fz_save_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, const char *filename); +/** + Write a pixmap as a JPEG. +*/ +void fz_write_pixmap_as_jpeg(fz_context *ctx, fz_output *out, fz_pixmap *pix, int quality, int invert_cmyk); + /** Save a pixmap as a JPEG. */ @@ -235,6 +240,22 @@ void fz_save_pixmap_as_jpeg(fz_context *ctx, fz_pixmap *pixmap, const char *file */ void fz_write_pixmap_as_png(fz_context *ctx, fz_output *out, const fz_pixmap *pixmap); +/** + Pixmap data as JP2K with no subsampling. + + quality = 100 = lossless + otherwise for a factor of x compression use 100-x. (so 80 is 1:20 compression) +*/ +void fz_write_pixmap_as_jpx(fz_context *ctx, fz_output *out, fz_pixmap *pix, int quality); + +/** + Save pixmap data as JP2K with no subsampling. + + quality = 100 = lossless + otherwise for a factor of x compression use 100-x. (so 80 is 1:20 compression) +*/ +void fz_save_pixmap_as_jpx(fz_context *ctx, fz_pixmap *pixmap, const char *filename, int q); + /** Create a new png band writer (greyscale or RGB, with or without alpha). @@ -250,7 +271,8 @@ fz_buffer *fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image, fz_ fz_buffer *fz_new_buffer_from_image_as_pnm(fz_context *ctx, fz_image *image, fz_color_params color_params); fz_buffer *fz_new_buffer_from_image_as_pam(fz_context *ctx, fz_image *image, fz_color_params color_params); fz_buffer *fz_new_buffer_from_image_as_psd(fz_context *ctx, fz_image *image, fz_color_params color_params); -fz_buffer *fz_new_buffer_from_image_as_jpeg(fz_context *ctx, fz_image *image, fz_color_params color_params, int quality); +fz_buffer *fz_new_buffer_from_image_as_jpeg(fz_context *ctx, fz_image *image, fz_color_params color_params, int quality, int invert_cmyk); +fz_buffer *fz_new_buffer_from_image_as_jpx(fz_context *ctx, fz_image *image, fz_color_params color_params, int quality); /** Reencode a given pixmap as a PNG into a buffer. @@ -261,7 +283,8 @@ fz_buffer *fz_new_buffer_from_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap, fz_buffer *fz_new_buffer_from_pixmap_as_pnm(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params); fz_buffer *fz_new_buffer_from_pixmap_as_pam(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params); fz_buffer *fz_new_buffer_from_pixmap_as_psd(fz_context *ctx, fz_pixmap *pix, fz_color_params color_params); -fz_buffer *fz_new_buffer_from_pixmap_as_jpeg(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params, int quality); +fz_buffer *fz_new_buffer_from_pixmap_as_jpeg(fz_context *ctx, fz_pixmap *pixmap, fz_color_params color_params, int quality, int invert_cmyk); +fz_buffer *fz_new_buffer_from_pixmap_as_jpx(fz_context *ctx, fz_pixmap *pix, fz_color_params color_params, int quality); /** Save a pixmap as a pnm (greyscale or rgb, no alpha). diff --git a/include/mupdf/fitz/writer.h b/include/mupdf/fitz/writer.h index ed7f529..23b78fa 100644 --- a/include/mupdf/fitz/writer.h +++ b/include/mupdf/fitz/writer.h @@ -132,6 +132,7 @@ fz_new_document_writer_with_buffer(fz_context *ctx, fz_buffer *buf, const char * fz_document_writer *fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options); fz_document_writer *fz_new_pdf_writer_with_output(fz_context *ctx, fz_output *out, const char *options); fz_document_writer *fz_new_svg_writer(fz_context *ctx, const char *path, const char *options); +fz_document_writer *fz_new_svg_writer_with_output(fz_context *ctx, fz_output *out, const char *options); fz_document_writer *fz_new_text_writer(fz_context *ctx, const char *format, const char *path, const char *options); fz_document_writer *fz_new_text_writer_with_output(fz_context *ctx, const char *format, fz_output *out, const char *options); diff --git a/include/mupdf/fitz/xml.h b/include/mupdf/fitz/xml.h index 642249d..7792f4a 100644 --- a/include/mupdf/fitz/xml.h +++ b/include/mupdf/fitz/xml.h @@ -57,7 +57,7 @@ fz_xml *fz_parse_xml_stream(fz_context *ctx, fz_stream *stream, int preserve_whi preserve_white: whether to keep or delete all-whitespace nodes. */ -fz_xml *fz_parse_xml_archive_entry(fz_context *ctx, fz_archive *arch, const char *filename, int preserve_white); +fz_xml *fz_parse_xml_archive_entry(fz_context *ctx, fz_archive *dir, const char *filename, int preserve_white); /** Try and parse the contents of an archive entry into a tree of xml nodes. @@ -67,7 +67,7 @@ fz_xml *fz_parse_xml_archive_entry(fz_context *ctx, fz_archive *arch, const char Will return NULL if the archive entry can't be found. Otherwise behaves the same as fz_parse_xml_archive_entry. May throw exceptions. */ -fz_xml *fz_try_parse_xml_archive_entry(fz_context *ctx, fz_archive *arch, const char *filename, int preserve_white); +fz_xml *fz_try_parse_xml_archive_entry(fz_context *ctx, fz_archive *dir, const char *filename, int preserve_white); /** Parse the contents of a buffer into a tree of XML nodes, @@ -161,7 +161,13 @@ void fz_xml_add_att(fz_context *ctx, fz_pool *pool, fz_xml *node, const char *ke char *fz_xml_text(fz_xml *item); /** - Pretty-print an XML tree to stdout. + Pretty-print an XML tree to given output. +*/ +void fz_output_xml(fz_context *ctx, fz_output *out, fz_xml *item, int level); + +/** + Pretty-print an XML tree to stdout. (Deprecated, use + fz_output_xml in preference). */ void fz_debug_xml(fz_xml *item, int level); diff --git a/include/mupdf/html.h b/include/mupdf/html.h new file mode 100644 index 0000000..ce439b3 --- /dev/null +++ b/include/mupdf/html.h @@ -0,0 +1,53 @@ +// Copyright (C) 2023 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +// This header allows people to easily build HTML-based document handlers. + +#ifndef MUPDF_HTML_HTML_H +#define MUPDF_HTML_HTML_H + +#include "mupdf/fitz/system.h" +#include "mupdf/fitz/context.h" +#include "mupdf/fitz/document.h" + +/* + HTML types required +*/ +typedef struct fz_html_s fz_html; +typedef struct fz_html_font_set_s fz_html_font_set; + +typedef struct +{ + const char *format_name; + fz_buffer *(*convert_to_html)(fz_context *ctx, fz_html_font_set *set, fz_buffer *buf, fz_archive *dir, const char *user_css); + int try_xml; + int try_html5; + int patch_mobi; +} fz_htdoc_format_t; + +fz_document *fz_htdoc_open_document_with_buffer(fz_context *ctx, fz_archive *dir, fz_buffer *buf, const fz_htdoc_format_t *format); + +fz_document *fz_htdoc_open_document_with_stream_and_dir(fz_context *ctx, fz_stream *stm, fz_archive *dir, const fz_htdoc_format_t *format); + + + +#endif /* MUPDF_HTML_HTML_H */ diff --git a/include/mupdf/pdf.h b/include/mupdf/pdf.h index 52567d2..e160563 100644 --- a/include/mupdf/pdf.h +++ b/include/mupdf/pdf.h @@ -47,6 +47,8 @@ extern "C" { #include "mupdf/pdf/javascript.h" #include "mupdf/pdf/clean.h" +#include "mupdf/pdf/image-rewriter.h" + #ifdef __cplusplus } diff --git a/include/mupdf/pdf/annot.h b/include/mupdf/pdf/annot.h index dbc7909..cd3f8b6 100644 --- a/include/mupdf/pdf/annot.h +++ b/include/mupdf/pdf/annot.h @@ -112,6 +112,26 @@ enum PDF_ANNOT_Q_RIGHT = 2 }; +enum pdf_intent +{ + PDF_ANNOT_IT_DEFAULT = 0, + PDF_ANNOT_IT_FREETEXT_CALLOUT, + PDF_ANNOT_IT_FREETEXT_TYPEWRITER, + PDF_ANNOT_IT_LINE_ARROW, + PDF_ANNOT_IT_LINE_DIMENSION, + PDF_ANNOT_IT_POLYLINE_DIMENSION, + PDF_ANNOT_IT_POLYGON_CLOUD, + PDF_ANNOT_IT_POLYGON_DIMENSION, + PDF_ANNOT_IT_STAMP_IMAGE, + PDF_ANNOT_IT_STAMP_SNAPSHOT, + PDF_ANNOT_IT_UNKNOWN = 255, +}; + +const char *pdf_string_from_intent(fz_context *ctx, enum pdf_intent intent); +pdf_obj *pdf_name_from_intent(fz_context *ctx, enum pdf_intent intent); +enum pdf_intent pdf_intent_from_string(fz_context *ctx, const char *str); +enum pdf_intent pdf_intent_from_name(fz_context *ctx, pdf_obj *obj); + /* Map from a PDF name specifying an annotation line ending to an enumerated line ending value. @@ -428,6 +448,10 @@ int pdf_annot_has_interior_color(fz_context *ctx, pdf_annot *annot); */ int pdf_annot_has_line_ending_styles(fz_context *ctx, pdf_annot *annot); +/* + Check to see if an annotation has quadding. +*/ +int pdf_annot_has_quadding(fz_context *ctx, pdf_annot *annot); /* Check to see if an annotation has a border. */ @@ -465,6 +489,7 @@ fz_rect pdf_annot_rect(fz_context *ctx, pdf_annot *annot); /* Retrieve the annotation border line width in points. + DEPRECATED: Use pdf_annot_border_width instead. */ float pdf_annot_border(fz_context *ctx, pdf_annot *annot); @@ -577,7 +602,8 @@ void pdf_set_annot_stamp_image(fz_context *ctx, pdf_annot *annot, fz_image *imag void pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect rect); /* - Set the border width for an annotation, in points and remove any border effect. + Set the border width for an annotation, in points. + DEPRECATED: Use pdf_set_annot_border_width instead. */ void pdf_set_annot_border(fz_context *ctx, pdf_annot *annot, float width); @@ -733,12 +759,30 @@ void pdf_set_annot_modification_date(fz_context *ctx, pdf_annot *annot, int64_t int64_t pdf_annot_creation_date(fz_context *ctx, pdf_annot *annot); void pdf_set_annot_creation_date(fz_context *ctx, pdf_annot *annot, int64_t time); +int pdf_annot_has_intent(fz_context *ctx, pdf_annot *annot); +enum pdf_intent pdf_annot_intent(fz_context *ctx, pdf_annot *annot); +void pdf_set_annot_intent(fz_context *ctx, pdf_annot *annot, enum pdf_intent it); + void pdf_parse_default_appearance(fz_context *ctx, const char *da, const char **font, float *size, int *n, float color[4]); void pdf_print_default_appearance(fz_context *ctx, char *buf, int nbuf, const char *font, float size, int n, const float *color); void pdf_annot_default_appearance(fz_context *ctx, pdf_annot *annot, const char **font, float *size, int *n, float color[4]); void pdf_set_annot_default_appearance(fz_context *ctx, pdf_annot *annot, const char *font, float size, int n, const float *color); +/* + * Request that an appearance stream should be generated for an annotation if none is present. + * It will be created in future calls to pdf_update_annot or pdf_update_page. + */ +void pdf_annot_request_synthesis(fz_context *ctx, pdf_annot *annot); + +/* + * Request that an appearance stream should be re-generated for an annotation + * the next time pdf_annot_update or pdf_page_update is called. + * You usually won't need to call this, because changing any annotation attributes + * via the pdf_annot functions will do so automatically. + * It will be created in future calls to pdf_update_annot or pdf_update_page. + */ void pdf_annot_request_resynthesis(fz_context *ctx, pdf_annot *annot); + int pdf_annot_needs_resynthesis(fz_context *ctx, pdf_annot *annot); void pdf_set_annot_resynthesised(fz_context *ctx, pdf_annot *annot); void pdf_dirty_annot(fz_context *ctx, pdf_annot *annot); diff --git a/include/mupdf/pdf/clean.h b/include/mupdf/pdf/clean.h index 0525282..415059d 100644 --- a/include/mupdf/pdf/clean.h +++ b/include/mupdf/pdf/clean.h @@ -24,15 +24,25 @@ #define MUPDF_PDF_CLEAN_H #include "mupdf/pdf/document.h" +#include "mupdf/pdf/image-rewriter.h" + +typedef struct +{ + pdf_write_options write; + pdf_image_rewriter_options image; + + /* Experimental option. Subject to change. */ + int subset_fonts; +} pdf_clean_options; /* Read infile, and write selected pages to outfile with the given options. */ -void pdf_clean_file(fz_context *ctx, char *infile, char *outfile, char *password, pdf_write_options *opts, int retainlen, char *retainlist[]); +void pdf_clean_file(fz_context *ctx, char *infile, char *outfile, char *password, pdf_clean_options *opts, int retainlen, char *retainlist[]); /* Recreate page tree to include only the pages listed in the array, in the order listed. */ -void pdf_rearrange_pages(fz_context *ctx, pdf_document *doc, int count, int *pages); +void pdf_rearrange_pages(fz_context *ctx, pdf_document *doc, int count, const int *pages); #endif diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h index a711a70..faa9578 100644 --- a/include/mupdf/pdf/document.h +++ b/include/mupdf/pdf/document.h @@ -202,6 +202,26 @@ 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); +/* + Get a pdf_document handle from an fz_document handle. + + This is superfically similar to pdf_document_from_fz_document + (and the older pdf_specifics). + + For fz_documents that are actually pdf_documents, this will return + a kept version of the same pointer, just cast differently. + + For fz_documents that have a pdf_document representation internally, + then you may get a kept version of a different pointer. + + For fz_documents that have no pdf_document representation internally, + this will return NULL. + + Note that this returns a kept pointer that the caller is responsible + for freeing, unlike pdf_specifics or pdf_document_from_fz_document. +*/ +pdf_document *fz_new_pdf_document_from_fz_document(fz_context *ctx, fz_document *ptr); + int pdf_needs_password(fz_context *ctx, pdf_document *doc); /* @@ -218,7 +238,7 @@ 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); +int pdf_lookup_metadata(fz_context *ctx, pdf_document *doc, const char *key, char *ptr, size_t size); fz_outline *pdf_load_outline(fz_context *ctx, pdf_document *doc); @@ -403,6 +423,7 @@ struct pdf_document fz_stream *file; int version; + int is_fdf; int64_t startxref; int64_t file_size; pdf_crypt *crypt; @@ -715,6 +736,8 @@ typedef struct char upwd_utf8[128]; /* User password. */ int do_snapshot; /* Do not use directly. Use the snapshot functions. */ int do_preserve_metadata; /* When cleaning, preserve metadata unchanged. */ + int do_use_objstms; /* Use objstms if possible */ + int compression_effort; /* 0 for default. 100 = max, 1 = min. */ } pdf_write_options; FZ_DATA extern const pdf_write_options pdf_default_write_options; @@ -804,5 +827,16 @@ void pdf_read_journal(fz_context *ctx, pdf_document *doc, fz_stream *stm); */ void pdf_minimize_document(fz_context *ctx, pdf_document *doc); +/* + Map a pdf object representing a structure tag through + an optional role_map and convert to an fz_structure. +*/ +fz_structure pdf_structure_type(fz_context *ctx, pdf_obj *role_map, pdf_obj *tag); + +/* + Run the document structure to a device. +*/ +void pdf_run_document_structure(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_cookie *cookie); + #endif diff --git a/include/mupdf/pdf/font.h b/include/mupdf/pdf/font.h index 79f9d40..d1e0081 100644 --- a/include/mupdf/pdf/font.h +++ b/include/mupdf/pdf/font.h @@ -153,8 +153,16 @@ pdf_obj *pdf_add_cjk_font(fz_context *ctx, pdf_document *doc, fz_font *font, int */ pdf_obj *pdf_add_substitute_font(fz_context *ctx, pdf_document *doc, fz_font *font); -int pdf_font_writing_supported(fz_font *font); +int pdf_font_writing_supported(fz_context *ctx, fz_font *font); -fz_buffer *fz_extract_ttf_from_ttc(fz_context *ctx, fz_font *font); +/* + Subset fonts by scanning the document to establish usage, and then + rewriting the font files. + + Calling with pages_len == 0 means do the whole document. + + EXPERIMENTAL AND SUBJECT TO CHANGE. +*/ +void pdf_subset_fonts(fz_context *ctx, pdf_document *doc, int pages_len, const int *pages); #endif diff --git a/include/mupdf/pdf/form.h b/include/mupdf/pdf/form.h index 6bf30c7..2b8d30f 100644 --- a/include/mupdf/pdf/form.h +++ b/include/mupdf/pdf/form.h @@ -323,14 +323,6 @@ fz_pixmap *pdf_preview_signature_as_pixmap(fz_context *ctx, const char *reason, const char *location); -/* - check a signature's certificate chain and digest - - This is a helper function defined to provide compatibility with older - versions of mupdf -*/ -int pdf_check_signature(fz_context *ctx, pdf_pkcs7_verifier *verifier, pdf_document *doc, pdf_obj *signature, char *ebuf, size_t ebufsize); - void pdf_drop_signer(fz_context *ctx, pdf_pkcs7_signer *signer); void pdf_drop_verifier(fz_context *ctx, pdf_pkcs7_verifier *verifier); @@ -379,4 +371,10 @@ void pdf_annot_event_page_close(fz_context *ctx, pdf_annot *annot); void pdf_annot_event_page_visible(fz_context *ctx, pdf_annot *annot); void pdf_annot_event_page_invisible(fz_context *ctx, pdf_annot *annot); +/* + * Bake appearances of annotations and/or widgets into static page content, + * and remove the corresponding interactive PDF objects. + */ +void pdf_bake_document(fz_context *ctx, pdf_document *doc, int bake_annots, int bake_widgets); + #endif diff --git a/include/mupdf/pdf/image-rewriter.h b/include/mupdf/pdf/image-rewriter.h new file mode 100644 index 0000000..f24c872 --- /dev/null +++ b/include/mupdf/pdf/image-rewriter.h @@ -0,0 +1,78 @@ +// Copyright (C) 2004-2021 Artifex Software, Inc. +// +// This file is part of MuPDF. +// +// MuPDF is free software: you can redistribute it and/or modify it under the +// terms of the GNU Affero General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) +// any later version. +// +// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +// details. +// +// You should have received a copy of the GNU Affero General Public License +// along with MuPDF. If not, see +// +// Alternative licensing terms are available from the licensor. +// For commercial licensing, see or contact +// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, +// CA 94129, USA, for further information. + +#ifndef MUPDF_PDF_IMAGE_REWRITER_H +#define MUPDF_PDF_IMAGE_REWRITER_H + +#include "mupdf/pdf/document.h" + +enum +{ + FZ_SUBSAMPLE_AVERAGE, + FZ_SUBSAMPLE_BICUBIC +}; + +enum +{ + FZ_RECOMPRESS_NEVER, + FZ_RECOMPRESS_SAME, + FZ_RECOMPRESS_LOSSLESS, + FZ_RECOMPRESS_JPEG, + FZ_RECOMPRESS_J2K, + FZ_RECOMPRESS_FAX +}; + +typedef struct +{ + int color_lossless_image_subsample_method; + int color_lossy_image_subsample_method; + int color_lossless_image_subsample_threshold; /* 0, or the threshold dpi at which to subsample color images. */ + int color_lossless_image_subsample_to; /* 0, or the dpi to subsample to */ + int color_lossy_image_subsample_threshold; /* 0, or the threshold dpi at which to subsample color images. */ + int color_lossy_image_subsample_to; /* 0, or the dpi to subsample to */ + int color_lossless_image_recompress_method; /* Which compression method to use for losslessly compressed color images? */ + int color_lossy_image_recompress_method; /* Which compression method to use for lossy compressed color images? */ + char *color_lossy_image_recompress_quality; + char *color_lossless_image_recompress_quality; + int gray_lossless_image_subsample_method; + int gray_lossy_image_subsample_method; + int gray_lossless_image_subsample_threshold; /* 0, or the threshold at which to subsample gray images. */ + int gray_lossless_image_subsample_to; /* 0, or the dpi to subsample to */ + int gray_lossy_image_subsample_threshold; /* 0, or the threshold at which to subsample gray images. */ + int gray_lossy_image_subsample_to; /* 0, or the dpi to subsample to */ + int gray_lossless_image_recompress_method; /* Which compression method to use for losslessly compressed gray images? */ + int gray_lossy_image_recompress_method; /* Which compression method to use for lossy compressed gray images? */ + char *gray_lossy_image_recompress_quality; + char *gray_lossless_image_recompress_quality; + int bitonal_image_subsample_method; + int bitonal_image_subsample_threshold; /* 0, or the threshold at which to subsample bitonal images. */ + int bitonal_image_subsample_to; /* 0, or the dpi to subsample to */ + int bitonal_image_recompress_method; /* Which compression method to use for bitonal images? */ + char *bitonal_image_recompress_quality; +} pdf_image_rewriter_options; + +/* + Rewrite images within the given document. +*/ +void pdf_rewrite_images(fz_context *ctx, pdf_document *doc, pdf_image_rewriter_options *opts); + +#endif diff --git a/include/mupdf/pdf/interpret.h b/include/mupdf/pdf/interpret.h index 144d8ea..b9b1a78 100644 --- a/include/mupdf/pdf/interpret.h +++ b/include/mupdf/pdf/interpret.h @@ -35,13 +35,21 @@ pdf_processor *pdf_keep_processor(fz_context *ctx, pdf_processor *proc); void pdf_close_processor(fz_context *ctx, pdf_processor *proc); void pdf_drop_processor(fz_context *ctx, pdf_processor *proc); +typedef enum +{ + PDF_PROCESSOR_REQUIRES_DECODED_IMAGES = 1 +} pdf_processor_requirements; + struct pdf_processor { int refs; + int closed; + /* close the processor. Also closes any chained processors. */ void (*close_processor)(fz_context *ctx, pdf_processor *proc); void (*drop_processor)(fz_context *ctx, pdf_processor *proc); + void (*reset_processor)(fz_context *ctx, pdf_processor *proc); /* At any stage, we can have one set of resources in place. * This function gives us a set of resources to use. We remember @@ -68,7 +76,7 @@ struct pdf_processor void (*op_gs_BM)(fz_context *ctx, pdf_processor *proc, const char *blendmode); void (*op_gs_ca)(fz_context *ctx, pdf_processor *proc, float alpha); void (*op_gs_CA)(fz_context *ctx, pdf_processor *proc, float alpha); - void (*op_gs_SMask)(fz_context *ctx, pdf_processor *proc, pdf_obj *smask, float *bc, int luminosity); + void (*op_gs_SMask)(fz_context *ctx, pdf_processor *proc, pdf_obj *smask, float *bc, int luminosity, pdf_obj *tr); void (*op_gs_end)(fz_context *ctx, pdf_processor *proc); /* special graphics state */ @@ -176,6 +184,8 @@ struct pdf_processor /* interpreter state that persists across content streams */ const char *usage; int hidden; + + pdf_processor_requirements requirements; }; typedef struct @@ -201,6 +211,8 @@ typedef struct float stack[32]; } pdf_csi; +void pdf_count_q_balance(fz_context *ctx, pdf_document *doc, pdf_obj *res, pdf_obj *stm, int *prepend, int *append); + /* Functions to set up pdf_process structures */ pdf_processor *pdf_new_run_processor(fz_context *ctx, pdf_document *doc, fz_device *dev, fz_matrix ctm, int struct_parent, const char *usage, pdf_gstate *gstate, fz_default_colorspaces *default_cs, fz_cookie *cookie); @@ -215,8 +227,21 @@ pdf_processor *pdf_new_run_processor(fz_context *ctx, pdf_document *doc, fz_devi ahxencode: If 0, then image streams will be send as binary, otherwise they will be asciihexencoded. + + newlines: If 0, then minimal spacing will be sent. If 1 + then newlines will be sent after every operator. +*/ +pdf_processor *pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer, int ahxencode, int newlines); + +/* + Reopen a closed processor to be used again. + + This brings a processor back to life after a close. + Not all processors may support this, so this may throw + an exception. */ -pdf_processor *pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer, int ahxencode); +void pdf_reset_processor(fz_context *ctx, pdf_processor *proc); + /* Create an output processor. This @@ -226,8 +251,11 @@ pdf_processor *pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer, int ahxencode: If 0, then image streams will be send as binary, otherwise they will be asciihexencoded. + + newlines: If 0, then minimal spacing will be sent. If 1 + then newlines will be sent after every operator. */ -pdf_processor *pdf_new_output_processor(fz_context *ctx, fz_output *out, int ahxencode); +pdf_processor *pdf_new_output_processor(fz_context *ctx, fz_output *out, int ahxencode, int newlines); typedef struct pdf_filter_options pdf_filter_options; @@ -276,6 +304,9 @@ typedef struct Operators will be fed into the filter generated from the first factory function in the list, and from there go to the filter generated from the second factory in the list etc. + + newlines: If 0, then minimal whitespace will be produced. If 1, + then a newline will be sent after every operator. */ struct pdf_filter_options { @@ -285,9 +316,10 @@ struct pdf_filter_options int no_update; void *opaque; - void (*complete)(fz_context *ctx, fz_buffer *buffer, void *arg); + void (*complete)(fz_context *ctx, fz_buffer *buffer, void *opaque); pdf_filter_factory *filters; + int newlines; }; typedef enum @@ -318,7 +350,7 @@ typedef enum typedef struct { void *opaque; - fz_image *(*image_filter)(fz_context *ctx, void *opaque, fz_matrix ctm, const char *name, fz_image *image); + fz_image *(*image_filter)(fz_context *ctx, void *opaque, fz_matrix ctm, const char *name, fz_image *image, fz_rect scissor); int (*text_filter)(fz_context *ctx, void *opaque, int *ucsbuf, int ucslen, fz_matrix trm, fz_matrix ctm, fz_rect bbox); void (*after_text_object)(fz_context *ctx, void *opaque, pdf_document *doc, pdf_processor *chain, fz_matrix ctm); int (*culler)(fz_context *ctx, void *opaque, fz_rect bbox, fz_cull_type type); @@ -385,13 +417,20 @@ pdf_obj *pdf_processor_pop_resources(fz_context *ctx, pdf_processor *proc); *image either the same (for no change) or updated to be a new one. Reference must be dropped, and a new kept reference returned. + + share_rewrite: function pointer called to rewrite a shade + + repeated_image_rewrite: If 0, then each image is rewritten only once. + Otherwise, it is called for every instance (useful if gathering + information about the ctm). */ typedef struct { void *opaque; void (*color_rewrite)(fz_context *ctx, void *opaque, pdf_obj **cs, int *n, float color[FZ_MAX_COLORS]); - void (*image_rewrite)(fz_context *ctx, void *opaque, fz_image **image); + void (*image_rewrite)(fz_context *ctx, void *opaque, fz_image **image, fz_matrix ctm, pdf_obj *obj); pdf_shade_recolorer *shade_rewrite; + int repeated_image_rewrite; } pdf_color_filter_options; pdf_processor * @@ -400,7 +439,7 @@ pdf_new_color_filter(fz_context *ctx, pdf_document *doc, pdf_processor *chain, i /* Functions to actually process annotations, glyphs and general stream objects. */ -void pdf_process_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *obj, pdf_obj *res, fz_cookie *cookie, pdf_obj **out_res); +void pdf_process_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *res, pdf_obj *stm, fz_cookie *cookie, pdf_obj **out_res); void pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_annot *annot, fz_cookie *cookie); void pdf_process_glyph(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *resources, fz_buffer *contents); @@ -418,6 +457,7 @@ typedef struct float scale; float leading; pdf_font_desc *font; + fz_string *fontname; float size; int render; float rise; diff --git a/include/mupdf/pdf/name-table.h b/include/mupdf/pdf/name-table.h index fab2ea8..685a992 100644 --- a/include/mupdf/pdf/name-table.h +++ b/include/mupdf/pdf/name-table.h @@ -22,6 +22,7 @@ /* Alphabetically sorted list of all PDF names to be available as constants */ PDF_MAKE_NAME("1.2", 1_2) +PDF_MAKE_NAME("1.5", 1_5) PDF_MAKE_NAME("3D", 3D) PDF_MAKE_NAME("A", A) PDF_MAKE_NAME("A85", A85) @@ -247,6 +248,8 @@ PDF_MAKE_NAME("FormEx", FormEx) PDF_MAKE_NAME("FormType", FormType) PDF_MAKE_NAME("Formula", Formula) PDF_MAKE_NAME("FreeText", FreeText) +PDF_MAKE_NAME("FreeTextCallout", FreeTextCallout) +PDF_MAKE_NAME("FreeTextTypeWriter", FreeTextTypeWriter) PDF_MAKE_NAME("Function", Function) PDF_MAKE_NAME("FunctionType", FunctionType) PDF_MAKE_NAME("Functions", Functions) @@ -274,6 +277,7 @@ PDF_MAKE_NAME("ICCBased", ICCBased) PDF_MAKE_NAME("ID", ID) PDF_MAKE_NAME("IM", IM) PDF_MAKE_NAME("IRT", IRT) +PDF_MAKE_NAME("IT", IT) PDF_MAKE_NAME("Identity", Identity) PDF_MAKE_NAME("Identity-H", Identity_H) PDF_MAKE_NAME("Identity-V", Identity_V) @@ -325,6 +329,8 @@ PDF_MAKE_NAME("Length2", Length2) PDF_MAKE_NAME("Length3", Length3) PDF_MAKE_NAME("Limits", Limits) PDF_MAKE_NAME("Line", Line) +PDF_MAKE_NAME("LineArrow", LineArrow) +PDF_MAKE_NAME("LineDimension", LineDimension) PDF_MAKE_NAME("Linearized", Linearized) PDF_MAKE_NAME("Link", Link) PDF_MAKE_NAME("List", List) @@ -407,7 +413,10 @@ PDF_MAKE_NAME("Pattern", Pattern) PDF_MAKE_NAME("PatternType", PatternType) PDF_MAKE_NAME("Perms", Perms) PDF_MAKE_NAME("PolyLine", PolyLine) +PDF_MAKE_NAME("PolyLineDimension", PolyLineDimension) PDF_MAKE_NAME("Polygon", Polygon) +PDF_MAKE_NAME("PolygonCloud", PolygonCloud) +PDF_MAKE_NAME("PolygonDimension", PolygonDimension) PDF_MAKE_NAME("Popup", Popup) PDF_MAKE_NAME("PreRelease", PreRelease) PDF_MAKE_NAME("Predictor", Predictor) @@ -480,6 +489,8 @@ PDF_MAKE_NAME("Square", Square) PDF_MAKE_NAME("Squiggly", Squiggly) PDF_MAKE_NAME("St", St) PDF_MAKE_NAME("Stamp", Stamp) +PDF_MAKE_NAME("StampImage", StampImage) +PDF_MAKE_NAME("StampSnapshot", StampSnapshot) PDF_MAKE_NAME("Standard", Standard) PDF_MAKE_NAME("StdCF", StdCF) PDF_MAKE_NAME("StemV", StemV) diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h index e60dab3..18df8c7 100644 --- a/include/mupdf/pdf/object.h +++ b/include/mupdf/pdf/object.h @@ -127,6 +127,7 @@ typedef struct int pdf_mark_list_push(fz_context *ctx, pdf_mark_list *list, pdf_obj *obj); void pdf_mark_list_pop(fz_context *ctx, pdf_mark_list *list); +int pdf_mark_list_check(fz_context *ctx, pdf_mark_list *list, pdf_obj *obj); void pdf_mark_list_init(fz_context *ctx, pdf_mark_list *list); void pdf_mark_list_free(fz_context *ctx, pdf_mark_list *list); @@ -149,6 +150,10 @@ size_t pdf_to_str_len(fz_context *ctx, pdf_obj *obj); int pdf_to_num(fz_context *ctx, pdf_obj *obj); int pdf_to_gen(fz_context *ctx, pdf_obj *obj); +int pdf_to_bool_default(fz_context *ctx, pdf_obj *obj, int def); +int pdf_to_int_default(fz_context *ctx, pdf_obj *obj, int def); +float pdf_to_real_default(fz_context *ctx, pdf_obj *obj, float def); + int pdf_array_len(fz_context *ctx, pdf_obj *array); pdf_obj *pdf_array_get(fz_context *ctx, pdf_obj *array, int i); void pdf_array_put(fz_context *ctx, pdf_obj *array, int i, pdf_obj *obj); @@ -211,6 +216,21 @@ fz_rect pdf_dict_get_rect(fz_context *ctx, pdf_obj *dict, pdf_obj *key); fz_matrix pdf_dict_get_matrix(fz_context *ctx, pdf_obj *dict, pdf_obj *key); int64_t pdf_dict_get_date(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +int pdf_dict_get_bool_default(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int def); +int pdf_dict_get_int_default(fz_context *ctx, pdf_obj *dict, pdf_obj *key, int def); +float pdf_dict_get_real_default(fz_context *ctx, pdf_obj *dict, pdf_obj *key, float def); + +int pdf_dict_get_inheritable_bool(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +int pdf_dict_get_inheritable_int(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +int64_t pdf_dict_get_inheritable_int64(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +float pdf_dict_get_inheritable_real(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +const char *pdf_dict_get_inheritable_name(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +const char *pdf_dict_get_inheritable_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key, size_t *sizep); +const char *pdf_dict_get_inheritable_text_string(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +fz_rect pdf_dict_get_inheritable_rect(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +fz_matrix pdf_dict_get_inheritable_matrix(fz_context *ctx, pdf_obj *dict, pdf_obj *key); +int64_t pdf_dict_get_inheritable_date(fz_context *ctx, pdf_obj *dict, pdf_obj *key); + void pdf_array_push_bool(fz_context *ctx, pdf_obj *array, int x); void pdf_array_push_int(fz_context *ctx, pdf_obj *array, int64_t x); void pdf_array_push_real(fz_context *ctx, pdf_obj *array, double x); @@ -220,6 +240,15 @@ void pdf_array_push_text_string(fz_context *ctx, pdf_obj *array, const char *x); pdf_obj *pdf_array_push_array(fz_context *ctx, pdf_obj *array, int initial); pdf_obj *pdf_array_push_dict(fz_context *ctx, pdf_obj *array, int initial); +void pdf_array_put_bool(fz_context *ctx, pdf_obj *array, int i, int x); +void pdf_array_put_int(fz_context *ctx, pdf_obj *array, int i, int64_t x); +void pdf_array_put_real(fz_context *ctx, pdf_obj *array, int i, double x); +void pdf_array_put_name(fz_context *ctx, pdf_obj *array, int i, const char *x); +void pdf_array_put_string(fz_context *ctx, pdf_obj *array, int i, const char *x, size_t n); +void pdf_array_put_text_string(fz_context *ctx, pdf_obj *array, int i, const char *x); +pdf_obj *pdf_array_put_array(fz_context *ctx, pdf_obj *array, int i, int initial); +pdf_obj *pdf_array_put_dict(fz_context *ctx, pdf_obj *array, int i, int initial); + int pdf_array_get_bool(fz_context *ctx, pdf_obj *array, int index); int pdf_array_get_int(fz_context *ctx, pdf_obj *array, int index); float pdf_array_get_real(fz_context *ctx, pdf_obj *array, int index); @@ -237,7 +266,7 @@ int pdf_obj_parent_num(fz_context *ctx, pdf_obj *obj); char *pdf_sprint_obj(fz_context *ctx, char *buf, size_t cap, size_t *len, pdf_obj *obj, int tight, int ascii); void pdf_print_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight, int ascii); -void pdf_print_encrypted_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight, int ascii, pdf_crypt *crypt, int num, int gen); +void pdf_print_encrypted_obj(fz_context *ctx, fz_output *out, pdf_obj *obj, int tight, int ascii, pdf_crypt *crypt, int num, int gen, int *sep); void pdf_debug_obj(fz_context *ctx, pdf_obj *obj); void pdf_debug_ref(fz_context *ctx, pdf_obj *obj); diff --git a/include/mupdf/pdf/page.h b/include/mupdf/pdf/page.h index f20bf49..59afa80 100644 --- a/include/mupdf/pdf/page.h +++ b/include/mupdf/pdf/page.h @@ -25,10 +25,14 @@ #include "mupdf/pdf/interpret.h" +pdf_page *pdf_keep_page(fz_context *ctx, pdf_page *page); +void pdf_drop_page(fz_context *ctx, pdf_page *page); + int pdf_lookup_page_number(fz_context *ctx, pdf_document *doc, pdf_obj *pageobj); int pdf_count_pages(fz_context *ctx, pdf_document *doc); int pdf_count_pages_imp(fz_context *ctx, fz_document *doc, int chapter); pdf_obj *pdf_lookup_page_obj(fz_context *ctx, pdf_document *doc, int needle); +pdf_obj *pdf_lookup_page_loc(fz_context *ctx, pdf_document *doc, int needle, pdf_obj **parentp, int *indexp); /* Cache the page tree for fast forward/reverse page lookups. @@ -46,8 +50,12 @@ void pdf_load_page_tree(fz_context *ctx, pdf_document *doc); */ void pdf_drop_page_tree(fz_context *ctx, pdf_document *doc); -void pdf_drop_page_tree_internal(fz_context *ctx, pdf_document *doc); +/* + Internal function used to drop the page tree. + Library users should not call this directly. +*/ +void pdf_drop_page_tree_internal(fz_context *ctx, pdf_document *doc); /* Make page self sufficient. @@ -68,17 +76,87 @@ void pdf_flatten_inheritable_page_items(fz_context *ctx, pdf_obj *page); number: page number, where 0 is the first page of the document. */ pdf_page *pdf_load_page(fz_context *ctx, pdf_document *doc, int number); + +/* + Internal function to perform pdf_load_page. + + Do not call this directly. +*/ fz_page *pdf_load_page_imp(fz_context *ctx, fz_document *doc, int chapter, int number); + +/* + Enquire as to whether a given page uses transparency or not. +*/ int pdf_page_has_transparency(fz_context *ctx, pdf_page *page); -void pdf_page_obj_transform(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm); -void pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm); -void pdf_page_obj_transform_box(fz_context *ctx, pdf_obj *pageobj, fz_rect *page_mediabox, fz_matrix *page_ctm, fz_box_type box); +/* + Fetch the given box for a page, together with a transform that converts + from fitz coords to PDF coords. + + pageobj: The object that represents the page. + + outbox: If non-NULL, this will be filled in with the requested box + in fitz coordinates. + + outctm: A transform to map from fitz page space to PDF page space. + + box: Which box to return. +*/ +void pdf_page_obj_transform_box(fz_context *ctx, pdf_obj *pageobj, fz_rect *outbox, fz_matrix *out, fz_box_type box); + +/* + As for pdf_page_obj_transform_box, always requesting the + cropbox. +*/ +void pdf_page_obj_transform(fz_context *ctx, pdf_obj *pageobj, fz_rect *outbox, fz_matrix *outctm); + +/* + As for pdf_page_obj_transform_box, but working from a pdf_page + object rather than the pdf_obj representing the page. +*/ void pdf_page_transform_box(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm, fz_box_type box); + +/* + As for pdf_page_transform_box, always requesting the + cropbox. +*/ +void pdf_page_transform(fz_context *ctx, pdf_page *page, fz_rect *mediabox, fz_matrix *ctm); + +/* + Find the pdf object that represents the resources dictionary + for a page. + + This is a borrowed pointer that the caller should pdf_keep_obj + if. This may be NULL. +*/ pdf_obj *pdf_page_resources(fz_context *ctx, pdf_page *page); + +/* + Find the pdf object that represents the page contents + for a page. + + This is a borrowed pointer that the caller should pdf_keep_obj + if. This may be NULL. +*/ pdf_obj *pdf_page_contents(fz_context *ctx, pdf_page *page); + +/* + Find the pdf object that represents the transparency group + for a page. + + This is a borrowed pointer that the caller should pdf_keep_obj + if. This may be NULL. +*/ pdf_obj *pdf_page_group(fz_context *ctx, pdf_page *page); +/* + Modify the page boxes (using fitz space coordinates). + + Note that changing the CropBox will change the fitz coordinate space mapping, + invalidating all bounding boxes previously acquired. +*/ +void pdf_set_page_box(fz_context *ctx, pdf_page *page, fz_box_type box, fz_rect rect); + /* Get the separation details for a page. */ @@ -157,15 +235,53 @@ fz_pixmap *pdf_new_pixmap_from_page_contents_with_separations_and_usage(fz_conte fz_pixmap *pdf_new_pixmap_from_page_with_separations_and_usage(fz_context *ctx, pdf_page *page, fz_matrix ctm, fz_colorspace *cs, fz_separations *seps, int alpha, const char *usage, fz_box_type box); enum { + /* Do not change images at all */ PDF_REDACT_IMAGE_NONE, + + /* If the image intrudes across the redaction region (even if clipped), + * remove it. */ PDF_REDACT_IMAGE_REMOVE, + + /* If the image intrudes across the redaction region (even if clipped), + * replace the bit that intrudes with black pixels. */ PDF_REDACT_IMAGE_PIXELS, + + /* If the image, when clipped, intrudes across the redaction + * region, remove it completely. Note: clipped is a rough estimate + * based on the bbox of clipping paths. + * + * Essentially this says "remove any image that has visible parts + * that extend into the redaction region". + * + * This method can effectively 'leak' invisible information during + * the redaction phase, so should be used with caution. + */ + PDF_REDACT_IMAGE_REMOVE_UNLESS_INVISIBLE +}; + +enum { + PDF_REDACT_LINE_ART_NONE, + PDF_REDACT_LINE_ART_REMOVE_IF_COVERED, + PDF_REDACT_LINE_ART_REMOVE_IF_TOUCHED +}; + +enum { + /* Remove any text that overlaps with the redaction region, + * however slightly. This is the default option, and is the + * correct option for secure behaviour. */ + PDF_REDACT_TEXT_REMOVE, + /* Do not remove any text at all as part of this redaction + * operation. Using this option is INSECURE! Use at your own + * risk. */ + PDF_REDACT_TEXT_NONE }; typedef struct { int black_boxes; int image_method; + int line_art; + int text; } pdf_redact_options; int pdf_redact_page(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_redact_options *opts); diff --git a/include/mupdf/pdf/resource.h b/include/mupdf/pdf/resource.h index dee9748..230a65f 100644 --- a/include/mupdf/pdf/resource.h +++ b/include/mupdf/pdf/resource.h @@ -74,7 +74,7 @@ fz_colorspace *pdf_load_colorspace(fz_context *ctx, pdf_obj *obj); int pdf_is_tint_colorspace(fz_context *ctx, fz_colorspace *cs); fz_shade *pdf_load_shading(fz_context *ctx, pdf_document *doc, pdf_obj *obj); -void pdf_sample_shade_function(fz_context *ctx, float shade[256][FZ_MAX_COLORS+1], int n, int funcs, pdf_function **func, float t0, float t1); +void pdf_sample_shade_function(fz_context *ctx, float *samples, int n, int funcs, pdf_function **func, float t0, float t1); /** Function to recolor a single color from a shade. diff --git a/libs/libmupdf_android_arm64.a b/libs/libmupdf_android_arm64.a index 920f7fb..634ba8a 100644 Binary files a/libs/libmupdf_android_arm64.a and b/libs/libmupdf_android_arm64.a differ diff --git a/libs/libmupdf_darwin_amd64.a b/libs/libmupdf_darwin_amd64.a index 6dfd600..de8b642 100644 Binary files a/libs/libmupdf_darwin_amd64.a and b/libs/libmupdf_darwin_amd64.a differ diff --git a/libs/libmupdf_darwin_arm64.a b/libs/libmupdf_darwin_arm64.a index 21a7830..8dfab9b 100644 Binary files a/libs/libmupdf_darwin_arm64.a and b/libs/libmupdf_darwin_arm64.a differ diff --git a/libs/libmupdf_linux_amd64.a b/libs/libmupdf_linux_amd64.a index 9cc507b..54f43f5 100644 Binary files a/libs/libmupdf_linux_amd64.a and b/libs/libmupdf_linux_amd64.a differ diff --git a/libs/libmupdf_linux_amd64_musl.a b/libs/libmupdf_linux_amd64_musl.a index 35777de..7aa9373 100644 Binary files a/libs/libmupdf_linux_amd64_musl.a and b/libs/libmupdf_linux_amd64_musl.a differ diff --git a/libs/libmupdf_linux_arm64.a b/libs/libmupdf_linux_arm64.a index 3b8ee94..c542191 100644 Binary files a/libs/libmupdf_linux_arm64.a and b/libs/libmupdf_linux_arm64.a differ diff --git a/libs/libmupdf_linux_arm64_musl.a b/libs/libmupdf_linux_arm64_musl.a index 4a9fa5c..5180435 100644 Binary files a/libs/libmupdf_linux_arm64_musl.a and b/libs/libmupdf_linux_arm64_musl.a differ diff --git a/libs/libmupdf_windows_amd64.a b/libs/libmupdf_windows_amd64.a index a0ad9c9..2070f9f 100644 Binary files a/libs/libmupdf_windows_amd64.a and b/libs/libmupdf_windows_amd64.a differ diff --git a/libs/libmupdfthird_android_arm64.a b/libs/libmupdfthird_android_arm64.a index feb8c01..b3e58e6 100644 Binary files a/libs/libmupdfthird_android_arm64.a and b/libs/libmupdfthird_android_arm64.a differ diff --git a/libs/libmupdfthird_darwin_amd64.a b/libs/libmupdfthird_darwin_amd64.a index b6a9a8a..6d75616 100644 Binary files a/libs/libmupdfthird_darwin_amd64.a and b/libs/libmupdfthird_darwin_amd64.a differ diff --git a/libs/libmupdfthird_darwin_arm64.a b/libs/libmupdfthird_darwin_arm64.a index fa636e7..571215a 100644 Binary files a/libs/libmupdfthird_darwin_arm64.a and b/libs/libmupdfthird_darwin_arm64.a differ diff --git a/libs/libmupdfthird_linux_amd64.a b/libs/libmupdfthird_linux_amd64.a index a31bd9e..ced6552 100644 Binary files a/libs/libmupdfthird_linux_amd64.a and b/libs/libmupdfthird_linux_amd64.a differ diff --git a/libs/libmupdfthird_linux_amd64_musl.a b/libs/libmupdfthird_linux_amd64_musl.a index eb4315f..95d0244 100644 Binary files a/libs/libmupdfthird_linux_amd64_musl.a and b/libs/libmupdfthird_linux_amd64_musl.a differ diff --git a/libs/libmupdfthird_linux_arm64.a b/libs/libmupdfthird_linux_arm64.a index 6f6286e..9e5ea94 100644 Binary files a/libs/libmupdfthird_linux_arm64.a and b/libs/libmupdfthird_linux_arm64.a differ diff --git a/libs/libmupdfthird_linux_arm64_musl.a b/libs/libmupdfthird_linux_arm64_musl.a index ef7115e..5f0cf17 100644 Binary files a/libs/libmupdfthird_linux_arm64_musl.a and b/libs/libmupdfthird_linux_arm64_musl.a differ diff --git a/libs/libmupdfthird_windows_amd64.a b/libs/libmupdfthird_windows_amd64.a index 71cc32c..cf33623 100644 Binary files a/libs/libmupdfthird_windows_amd64.a and b/libs/libmupdfthird_windows_amd64.a differ