diff options
author | Robin Watts <robin.watts@artifex.com> | 2016-04-12 13:17:02 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-04-28 12:30:41 +0100 |
commit | 3dc16d54db4669415412bb44790d4653962747f6 (patch) | |
tree | f45096e35afbd29f22e4e2c7c2a16c61ec9da468 /source/fitz | |
parent | b944f16a564f8a31d9a064980318ad690be31f8e (diff) | |
download | mupdf-3dc16d54db4669415412bb44790d4653962747f6.tar.xz |
Introduce tuning context.
For now, just use it for controlling image decoding and image scaling.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/context.c | 44 | ||||
-rw-r--r-- | source/fitz/draw-device.c | 13 | ||||
-rw-r--r-- | source/fitz/image.c | 42 |
3 files changed, 84 insertions, 15 deletions
diff --git a/source/fitz/context.c b/source/fitz/context.c index 0f9a8b77..bfc7a1cd 100644 --- a/source/fitz/context.c +++ b/source/fitz/context.c @@ -76,6 +76,46 @@ const char *fz_user_css(fz_context *ctx) return ctx->style->user_css; } +static void fz_new_tuning_context(fz_context *ctx) +{ + if (ctx) + { + ctx->tuning = fz_malloc_struct(ctx, fz_tuning_context); + ctx->tuning->refs = 1; + ctx->tuning->image_decode = &fz_default_image_decode; + ctx->tuning->image_scale = &fz_default_image_scale; + } +} + +static fz_tuning_context *fz_keep_tuning_context(fz_context *ctx) +{ + if (!ctx) + return NULL; + return fz_keep_imp(ctx, ctx->tuning, &ctx->tuning->refs); +} + +static void fz_drop_tuning_context(fz_context *ctx) +{ + if (!ctx) + return; + if (fz_drop_imp(ctx, ctx->tuning, &ctx->tuning->refs)) + { + fz_free(ctx, ctx->tuning); + } +} + +void fz_tune_image_decode(fz_context *ctx, fz_tune_image_decode_fn *image_decode, void *arg) +{ + ctx->tuning->image_decode = image_decode ? image_decode : fz_default_image_decode; + ctx->tuning->image_decode_arg = arg; +} + +void fz_tune_image_scale(fz_context *ctx, fz_tune_image_scale_fn *image_scale, void *arg) +{ + ctx->tuning->image_scale = image_scale ? image_scale : fz_default_image_scale; + ctx->tuning->image_scale_arg = arg; +} + void fz_drop_context(fz_context *ctx) { @@ -88,6 +128,7 @@ fz_drop_context(fz_context *ctx) fz_drop_store_context(ctx); fz_drop_aa_context(ctx); fz_drop_style_context(ctx); + fz_drop_tuning_context(ctx); fz_drop_colorspace_context(ctx); fz_drop_font_context(ctx); fz_drop_id_context(ctx); @@ -188,6 +229,7 @@ fz_new_context_imp(const fz_alloc_context *alloc, const fz_locks_context *locks, fz_new_id_context(ctx); fz_new_document_handler_context(ctx); fz_new_style_context(ctx); + fz_new_tuning_context(ctx); } fz_catch(ctx) { @@ -237,6 +279,8 @@ fz_clone_context_internal(fz_context *ctx) new_ctx->style = fz_keep_style_context(new_ctx); new_ctx->id = ctx->id; new_ctx->id = fz_keep_id_context(new_ctx); + new_ctx->tuning = ctx->tuning; + new_ctx->tuning = fz_keep_tuning_context(new_ctx); new_ctx->handler = ctx->handler; new_ctx->handler = fz_keep_document_handler_context(new_ctx); diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 4108cf09..c32b8f60 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -1092,6 +1092,13 @@ fz_transform_pixmap(fz_context *ctx, fz_draw_device *dev, const fz_pixmap *image return NULL; } +int +fz_default_image_scale(void *arg, int dst_w, int dst_h, int src_w, int src_h) +{ + (void)arg; + return dst_w < src_w && dst_h < src_h; +} + static void fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, float alpha) { @@ -1182,7 +1189,7 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m pixmap = converted; } - if (dx < pixmap->w && dy < pixmap->h && !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)) + if (!(devp->hints & FZ_DONT_INTERPOLATE_IMAGES) && ctx->tuning->image_scale(ctx->tuning->image_scale_arg, dx, dy, pixmap->w, pixmap->h)) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); @@ -1300,7 +1307,7 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const if (state->blendmode & FZ_BLEND_KNOCKOUT) state = fz_knockout_begin(ctx, dev); - if (dx < pixmap->w && dy < pixmap->h) + if (ctx->tuning->image_scale(ctx->tuning->image_scale_arg, dx, dy, pixmap->w, pixmap->h)) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); @@ -1409,7 +1416,7 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; - if (dx < pixmap->w && dy < pixmap->h) + if (ctx->tuning->image_scale(ctx->tuning->image_scale_arg, dx, dy, pixmap->w, pixmap->h)) { int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); diff --git a/source/fitz/image.c b/source/fitz/image.c index 36026a19..c622c92b 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -381,6 +381,33 @@ update_ctm_for_subarea(fz_matrix *ctm, const fz_irect *subarea, int w, int h) fz_concat(ctm, &m, ctm); } +void fz_default_image_decode(void *arg, int w, int h, int l2factor, fz_irect *subarea) +{ + (void)arg; + + if ((subarea->x1-subarea->x0)*(subarea->y1-subarea->y0) >= (w*h/10)*9) + { + /* Either no subarea specified, or a subarea 90% or more of the + * whole area specified. Use the whole image. */ + subarea->x0 = 0; + subarea->y0 = 0; + subarea->x1 = w; + subarea->y1 = h; + } + else + { + /* Clip to the edges if they are within 1% */ + if (subarea->x0 <= w/100) + subarea->x0 = 0; + if (subarea->y0 <= h/100) + subarea->y0 = 0; + if (subarea->x1 >= w*99/100) + subarea->x1 = w; + if (subarea->y1 >= h*99/100) + subarea->y1 = h; + } +} + fz_pixmap * fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *ctm, int *dw, int *dh) { @@ -436,10 +463,8 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subar for (l2factor=0; image->w>>(l2factor+1) >= w+2 && image->h>>(l2factor+1) >= h+2 && l2factor < 6; l2factor++); /* Now figure out if we want to decode just a subarea */ - if (subarea == NULL || (subarea->x1-subarea->x0)*(subarea->y1-subarea->y0) >= (image->w*image->h/10)*9) + if (subarea == NULL) { - /* Either no subarea specified, or a subarea 90% or more of the - * whole area specified. Use the whole image. */ key.rect.x0 = 0; key.rect.y0 = 0; key.rect.x1 = image->w; @@ -447,18 +472,11 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subar } else { - /* Clip to the edges if they are within 1% */ key.rect = *subarea; - if (key.rect.x0 <= image->w/100) - key.rect.x0 = 0; - if (key.rect.y0 <= image->h/100) - key.rect.y0 = 0; - if (key.rect.x1 >= image->w*99/100) - key.rect.x1 = image->w; - if (key.rect.y1 >= image->h*99/100) - key.rect.y1 = image->h; + ctx->tuning->image_decode(ctx->tuning->image_decode_arg, image->w, image->h, l2factor, &key.rect); } + /* Based on that subarea, recalculate the extents */ if (ctm) { float frac_w = (key.rect.x1 - key.rect.x0) / (float)image->w; |