diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fitz/colorspace.c | 82 | ||||
-rw-r--r-- | source/fitz/draw-mesh.c | 8 |
2 files changed, 88 insertions, 2 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); +} 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); |