summaryrefslogtreecommitdiff
path: root/source/fitz/filter-jbig2.c
diff options
context:
space:
mode:
authorSimon Bünzli <zeniko@gmail.com>2014-01-03 12:15:09 +0100
committerRobin Watts <robin.watts@artifex.com>2014-01-06 13:13:41 +0000
commit0bfa2ce884eed8bef83fb23cf2e25dae81a2207e (patch)
treedb83c056876db965b5625bef16990b6c6740257e /source/fitz/filter-jbig2.c
parent833c6a84bd7edf531b6074e9e13dd5ae57f21f12 (diff)
downloadmupdf-0bfa2ce884eed8bef83fb23cf2e25dae81a2207e.tar.xz
reuse JBIG2Globals
Certain optimized documents use a rather large common symbol dictionary for all JBIG2 images. Caching these JBIG2Globals speeds up loading and rendering of such documents.
Diffstat (limited to 'source/fitz/filter-jbig2.c')
-rw-r--r--source/fitz/filter-jbig2.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/source/fitz/filter-jbig2.c b/source/fitz/filter-jbig2.c
index 2771d070..592f7ab6 100644
--- a/source/fitz/filter-jbig2.c
+++ b/source/fitz/filter-jbig2.c
@@ -4,23 +4,35 @@
typedef struct fz_jbig2d_s fz_jbig2d;
+struct fz_jbig2_globals_s
+{
+ fz_storable storable;
+ Jbig2GlobalCtx *gctx;
+};
+
struct fz_jbig2d_s
{
fz_stream *chain;
Jbig2Ctx *ctx;
- Jbig2GlobalCtx *gctx;
+ fz_jbig2_globals *gctx;
Jbig2Image *page;
int idx;
};
static void
+fz_drop_jbig2_globals(fz_context *ctx, fz_jbig2_globals *globals)
+{
+ fz_drop_storable(ctx, &globals->storable);
+}
+
+static void
close_jbig2d(fz_context *ctx, void *state_)
{
fz_jbig2d *state = (fz_jbig2d *)state_;
if (state->page)
jbig2_release_page(state->ctx, state->page);
if (state->gctx)
- jbig2_global_ctx_free(state->gctx);
+ fz_drop_jbig2_globals(ctx, state->gctx);
jbig2_ctx_free(state->ctx);
fz_close(state->chain);
fz_free(ctx, state);
@@ -81,8 +93,30 @@ error_callback(void *data, const char *msg, Jbig2Severity severity, int32_t seg_
return 0;
}
+fz_jbig2_globals *
+fz_load_jbig2_globals(fz_context *ctx, unsigned char *data, int size)
+{
+ fz_jbig2_globals *globals = fz_malloc_struct(ctx, fz_jbig2_globals);
+
+ Jbig2Ctx *jctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, error_callback, ctx);
+ jbig2_data_in(jctx, data, size);
+
+ FZ_INIT_STORABLE(globals, 1, fz_free_jbig2_globals_imp);
+ globals->gctx = jbig2_make_global_ctx(jctx);
+
+ return globals;
+}
+
+void
+fz_free_jbig2_globals_imp(fz_context *ctx, fz_storable *globals_)
+{
+ fz_jbig2_globals *globals = (fz_jbig2_globals *)globals_;
+ jbig2_global_ctx_free(globals->gctx);
+ fz_free(ctx, globals);
+}
+
fz_stream *
-fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
+fz_open_jbig2d(fz_stream *chain, fz_jbig2_globals *globals)
{
fz_jbig2d *state = NULL;
fz_context *ctx = chain->ctx;
@@ -93,34 +127,24 @@ fz_open_jbig2d(fz_stream *chain, fz_buffer *globals)
{
state = fz_malloc_struct(chain->ctx, fz_jbig2d);
state->ctx = NULL;
- state->gctx = NULL;
+ state->gctx = globals;
state->chain = chain;
- state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, NULL, error_callback, ctx);
+ state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, globals ? globals->gctx : NULL, error_callback, ctx);
state->page = NULL;
state->idx = 0;
-
- if (globals)
- {
- jbig2_data_in(state->ctx, globals->data, globals->len);
- state->gctx = jbig2_make_global_ctx(state->ctx);
- state->ctx = jbig2_ctx_new(NULL, JBIG2_OPTIONS_EMBEDDED, state->gctx, error_callback, ctx);
- }
}
fz_catch(ctx)
{
if (state)
{
- if (state->gctx)
- jbig2_global_ctx_free(state->gctx);
+ fz_drop_jbig2_globals(ctx, state->gctx);
if (state->ctx)
jbig2_ctx_free(state->ctx);
}
- fz_drop_buffer(ctx, globals);
fz_free(ctx, state);
fz_close(chain);
fz_rethrow(ctx);
}
- fz_drop_buffer(ctx, globals);
return fz_new_stream(ctx, state, read_jbig2d, close_jbig2d, rebind_jbig2d);
}