summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'fitz')
-rw-r--r--fitz/base_context.c2
-rw-r--r--fitz/fitz.h178
-rw-r--r--fitz/res_store.c4
3 files changed, 162 insertions, 22 deletions
diff --git a/fitz/base_context.c b/fitz/base_context.c
index d1ce63ae..2eeb6683 100644
--- a/fitz/base_context.c
+++ b/fitz/base_context.c
@@ -122,7 +122,7 @@ fz_clone_context_internal(fz_context *ctx)
if (ctx == NULL || ctx->alloc == NULL)
return NULL;
new_ctx = new_context_phase1(ctx->alloc, ctx->locks);
- new_ctx->store = fz_store_keep(ctx);
+ new_ctx->store = fz_keep_store_context(ctx);
new_ctx->glyph_cache = fz_keep_glyph_cache(ctx);
new_ctx->font = fz_keep_font_context(ctx);
return new_ctx;
diff --git a/fitz/fitz.h b/fitz/fitz.h
index f72aecb9..594bc4e9 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -936,13 +936,28 @@ void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
/*
- * Resource store
+ Resource store
+
+ MuPDF stores decoded "objects" into a store for potential reuse.
+ If the size of the store gets too big, objects stored within it can
+ be evicted and freed to recover space. When MuPDF comes to decode
+ such an object, it will check to see if a version of this object is
+ already in the store - if it is, it will simply reuse it. If not, it
+ will decode it and place it into the store.
+
+ All objects that can be placed into the store are derived from the
+ fz_storable type (i.e. this should be the first component of the
+ objects structure). This allows for consistent (thread safe)
+ reference counting, and includes a function that will be called to
+ free the object as soon as the reference count reaches zero.
+
+ Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived
+ from fz_keep_storable/fz_drop_storable. Creation of such objects
+ includes a call to FZ_INIT_STORABLE to set up the fz_storable header.
*/
typedef struct fz_storable_s fz_storable;
-typedef struct fz_item_s fz_item;
-
typedef void (fz_store_free_fn)(fz_context *, fz_storable *);
struct fz_storable_s {
@@ -955,6 +970,9 @@ struct fz_storable_s {
S->free = (FREE); \
} while (0)
+void *fz_keep_storable(fz_context *, fz_storable *);
+void fz_drop_storable(fz_context *, fz_storable *);
+
/*
Specifies the maximum size in bytes of the resource store in
fz_context. Given as argument to fz_new_context.
@@ -969,6 +987,22 @@ enum {
FZ_STORE_DEFAULT = 256 << 20,
};
+/*
+ The store can be seen as a dictionary that maps keys to fz_storable
+ values. In order to allow keys of different types to be stored, we
+ have a structure full of functions for each key 'type'; this
+ fz_store_type pointer is stored with each key, and tells the store
+ how to perform certain operations (like taking/dropping a reference,
+ comparing two keys, outputting details for debugging etc).
+
+ The store uses a hash table internally for speed where possible. In
+ order for this to work, we need a mechanism for turning a generic
+ 'key' into 'a hashable string'. For this purpose the type structure
+ contains a make_hash_key function pointer that maps from a void *
+ to an fz_store_hash structure. If make_hash_key function returns 0,
+ then the key is determined not to be hashable, and the value is
+ not stored in the hash table.
+*/
typedef struct fz_store_hash_s fz_store_hash;
struct fz_store_hash_s
@@ -1000,18 +1034,95 @@ struct fz_store_type_s
void (*debug)(void *);
};
+/*
+ fz_store_new_context: Create a new store inside the context
+
+ max: The maximum size (in bytes) that the store is allowed to grow
+ to. FZ_STORE_UNLIMITED means no limit.
+*/
void fz_new_store_context(fz_context *ctx, unsigned int max);
+
+/*
+ fz_drop_store_context: Drop a reference to the store.
+*/
void fz_drop_store_context(fz_context *ctx);
-fz_store *fz_store_keep(fz_context *ctx);
+
+/*
+ fz_keep_store_context: Take a reference to the store.
+*/
+fz_store *fz_keep_store_context(fz_context *ctx);
+
+/*
+ fz_debug_store: Dump the contents of the store for debugging.
+*/
void fz_debug_store(fz_context *ctx);
-void *fz_keep_storable(fz_context *, fz_storable *);
-void fz_drop_storable(fz_context *, fz_storable *);
+/*
+ fz_store_item: Add an item to the store.
+
+ Add an item into the store, returning NULL for success. If an item
+ with the same key is found in the store, then our item will not be
+ inserted, and the function will return a pointer to that value
+ instead. This function takes its own reference to val, as required
+ (i.e. the caller maintains ownership of its own reference).
+ key: The key to use to index the item.
+
+ val: The value to store.
+
+ itemsize: The size in bytes of the value (as counted towards the
+ store size).
+
+ type: Functions used to manipulate the key.
+*/
void *fz_store_item(fz_context *ctx, void *key, void *val, unsigned int itemsize, fz_store_type *type);
+
+/*
+ fz_find_item: Find an item within the store.
+
+ free: The function used to free the value (to ensure we get a value
+ of the correct type).
+
+ key: The key to use to index the item.
+
+ type: Functions used to manipulate the key.
+
+ Returns NULL for not found, otherwise returns a pointer to the value
+ indexed by key to which a reference has been taken.
+*/
void *fz_find_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type);
+
+/*
+ fz_remove_item: Remove an item from the store.
+
+ If an item indexed by the given key exists in the store, remove it.
+
+ free: The function used to free the value (to ensure we get a value
+ of the correct type).
+
+ key: The key to use to find the item to remove.
+
+ type: Functions used to manipulate the key.
+*/
void fz_remove_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type);
+
+/*
+ fz_empty_store: Evict everything from the store.
+*/
void fz_empty_store(fz_context *ctx);
+
+/*
+ fz_store_scavenge: Internal function used as part of the scavenging
+ allocator; when we fail to allocate memory, before returning a
+ failure to the caller, we try to scavenge space within the store by
+ evicting at least 'size' bytes. The allocator then retries.
+
+ size: The number of bytes we are trying to have free.
+
+ phase: What phase of the scavenge we are in. Updated on exit.
+
+ Returns non zero if we managed to free any memory.
+*/
int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase);
/*
@@ -1340,10 +1451,10 @@ void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int saveal
void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha);
/*
- * Images are either a reference to a pixmap, or details of how to make
- * a pixmap. To know how to make a pixmap we need a block of compressed
- * data (typically a stream decoded all the way until the image filter)
- * and then the details of the params for the filter to do the final step.
+ Images are storable objects from which we can obtain fz_pixmaps.
+ These may be implemented as simple wrappers around a pixmap, or as
+ more complex things that decode at different subsample settings on
+ demand.
*/
typedef struct fz_image_s fz_image;
@@ -1356,8 +1467,37 @@ struct fz_image_s
fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h);
};
-fz_pixmap *fz_image_to_pixmap(fz_context *, fz_image *, int w, int h);
+/*
+ fz_image_to_pixmap: Called to get a handle to a pixmap from an image.
+
+ image: The image to retrieve a pixmap from.
+
+ w: The desired width (in pixels). This may be completely ignored, but
+ may serve as an indication of a suitable subsample factor to use for
+ image types that support this.
+
+ h: The desired height (in pixels). This may be completely ignored, but
+ may serve as an indication of a suitable subsample factor to use for
+ image types that support this.
+
+ Returns a non NULL pixmap pointer. May throw exceptions.
+*/
+fz_pixmap *fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h);
+
+/*
+ fz_drop_image: Drop a reference to an image.
+
+ image: The image to drop a reference to.
+*/
void fz_drop_image(fz_context *ctx, fz_image *image);
+
+/*
+ fz_keep_image: Increment the reference count of an image.
+
+ image: The image to take a reference to.
+
+ Returns a pointer to the image.
+*/
fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs);
@@ -1366,11 +1506,10 @@ fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size);
fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size);
/*
- * Bitmaps have 1 bit per component. Only used for creating halftoned versions
- * of contone buffers, and saving out. Samples are stored msb first, akin to
- * pbms.
- */
-
+ Bitmaps have 1 bit per component. Only used for creating halftoned
+ versions of contone buffers, and saving out. Samples are stored msb
+ first, akin to pbms.
+*/
typedef struct fz_bitmap_s fz_bitmap;
struct fz_bitmap_s
@@ -1388,10 +1527,9 @@ void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit);
void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename);
/*
- * A halftone is a set of threshold tiles, one per component. Each threshold
- * tile is a pixmap, possibly of varying sizes and phases.
- */
-
+ A halftone is a set of threshold tiles, one per component. Each
+ threshold tile is a pixmap, possibly of varying sizes and phases.
+*/
typedef struct fz_halftone_s fz_halftone;
struct fz_halftone_s
diff --git a/fitz/res_store.c b/fitz/res_store.c
index 0e3e7214..2a7680e3 100644
--- a/fitz/res_store.c
+++ b/fitz/res_store.c
@@ -1,5 +1,7 @@
#include "fitz.h"
+typedef struct fz_item_s fz_item;
+
struct fz_item_s
{
void *key;
@@ -420,7 +422,7 @@ fz_empty_store(fz_context *ctx)
}
fz_store *
-fz_store_keep(fz_context *ctx)
+fz_keep_store_context(fz_context *ctx)
{
if (ctx == NULL || ctx->store == NULL)
return NULL;