summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/colorspace.h4
-rw-r--r--source/fitz/colorspace.c82
-rw-r--r--source/fitz/draw-mesh.c8
3 files changed, 92 insertions, 2 deletions
diff --git a/include/mupdf/fitz/colorspace.h b/include/mupdf/fitz/colorspace.h
index ee53e487..9b66ee9e 100644
--- a/include/mupdf/fitz/colorspace.h
+++ b/include/mupdf/fitz/colorspace.h
@@ -104,8 +104,12 @@ struct fz_color_converter_s
fz_context *ctx;
fz_colorspace *ds;
fz_colorspace *ss;
+ void *opaque;
};
void fz_lookup_color_converter(fz_color_converter *cc, fz_context *ctx, fz_colorspace *ds, fz_colorspace *ss);
+void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ds, fz_colorspace *ss);
+void fz_fin_cached_color_converter(fz_color_converter *cc);
+
#endif
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);
+}
diff --git a/source/fitz/draw-mesh.c b/source/fitz/draw-mesh.c
index 26d496d2..1bb93369 100644
--- a/source/fitz/draw-mesh.c
+++ b/source/fitz/draw-mesh.c
@@ -205,7 +205,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap
fz_pixmap *temp = NULL;
fz_pixmap *conv = NULL;
float color[FZ_MAX_COLORS];
- struct paint_tri_data ptd;
+ struct paint_tri_data ptd = { 0 };
int i, k;
fz_matrix local_ctm;
@@ -241,7 +241,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap
ptd.shade = shade;
ptd.bbox = bbox;
- fz_lookup_color_converter(&ptd.cc, ctx, temp->colorspace, shade->colorspace);
+ fz_init_cached_color_converter(ctx, &ptd.cc, temp->colorspace, shade->colorspace);
fz_process_mesh(ctx, shade, &local_ctm, &prepare_vertex, &do_paint_tri, &ptd);
if (shade->use_function)
@@ -262,6 +262,10 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap
fz_drop_pixmap(ctx, temp);
}
}
+ fz_always(ctx)
+ {
+ fz_fin_cached_color_converter(&ptd.cc);
+ }
fz_catch(ctx)
{
fz_drop_pixmap(ctx, conv);