summaryrefslogtreecommitdiff
path: root/source/fitz/colorspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/colorspace.c')
-rw-r--r--source/fitz/colorspace.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c
index 33fa07fb..3426e26f 100644
--- a/source/fitz/colorspace.c
+++ b/source/fitz/colorspace.c
@@ -1274,3 +1274,85 @@ fz_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
return dst;
}
+
+typedef struct fz_cached_color_converter
+{
+ fz_color_converter base;
+ fz_hash_table *hash;
+
+}
+fz_cached_color_converter;
+
+static void fz_cached_color_convert(fz_color_converter *cc_, float *ds, float *ss)
+{
+ fz_cached_color_converter *cc = cc_->opaque;
+ fz_context *ctx = cc->base.ctx;
+ void *val = fz_hash_find(ctx, cc->hash, ss);
+ int n = cc->base.ds->n * sizeof(float);
+ fz_color_converter *base_cc = &cc->base;
+
+ if (val)
+ {
+ memcpy(ds, val, n);
+ return;
+ }
+
+ base_cc->convert(base_cc, ds, ss);
+ val = fz_malloc(ctx, n);
+ memcpy(val, ds, n);
+ fz_try(ctx)
+ {
+ fz_hash_insert(ctx, cc->hash, ss, val);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, val);
+ }
+}
+
+void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ds, fz_colorspace *ss)
+{
+ int n = ss->n;
+ fz_cached_color_converter *cached = fz_malloc_struct(ctx, fz_cached_color_converter);
+
+ fz_try(ctx)
+ {
+ fz_lookup_color_converter(&cached->base, ctx, ds, ss);
+ cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1);
+ cc->convert = fz_cached_color_convert;
+ cc->ctx = ctx;
+ cc->ds = ds;
+ cc->ss = ss;
+ cc->opaque = cached;
+ }
+ fz_catch(ctx)
+ {
+ fz_free_hash(ctx, cached->hash);
+ fz_rethrow(ctx);
+ }
+}
+
+void fz_fin_cached_color_converter(fz_color_converter *cc_)
+{
+ fz_cached_color_converter *cc;
+ fz_context *ctx;
+ int i, n;
+
+ if (cc_ == NULL)
+ return;
+ cc = cc_->opaque;
+ if (cc == NULL)
+ return;
+ cc_->opaque = NULL;
+ ctx = cc_->ctx;
+
+ n = fz_hash_len(ctx, cc->hash);
+ for (i = 0; i < n; i++)
+ {
+ void *v = fz_hash_get_val(ctx, cc->hash, i);
+ if (v)
+ fz_free(ctx, v);
+ }
+ fz_free_hash(ctx, cc->hash);
+ fz_free(ctx, cc);
+}