diff options
Diffstat (limited to 'fitz')
-rw-r--r-- | fitz/base_context.c | 2 | ||||
-rw-r--r-- | fitz/fitz.h | 178 | ||||
-rw-r--r-- | fitz/res_store.c | 4 |
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; |