summaryrefslogtreecommitdiff
path: root/draw/draw_device.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-12-19 20:50:46 +0000
committerRobin Watts <robin.watts@artifex.com>2011-12-19 20:50:46 +0000
commitdfa245914d586889b4786d9b006d3ff5dac41840 (patch)
treefe56fc7ea9be4a7788244476bf270512bdc35ab1 /draw/draw_device.c
parentbd0ebd25aad6abd19d98221caefc4d6566ec1e64 (diff)
downloadmupdf-dfa245914d586889b4786d9b006d3ff5dac41840.tar.xz
More memsqueezing fixes.
Diffstat (limited to 'draw/draw_device.c')
-rw-r--r--draw/draw_device.c187
1 files changed, 125 insertions, 62 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c
index 5ee84d4f..060558b4 100644
--- a/draw/draw_device.c
+++ b/draw/draw_device.c
@@ -915,6 +915,9 @@ fz_draw_fill_image(fz_device *devp, fz_pixmap *image, fz_matrix ctm, float alpha
fz_pixmap *scaled = NULL;
int after;
int dx, dy;
+ fz_context *ctx = dev->ctx;
+
+ fz_var(scaled);
if (!model)
{
@@ -938,50 +941,59 @@ fz_draw_fill_image(fz_device *devp, fz_pixmap *image, fz_matrix ctm, float alpha
if (image->colorspace != model && !after)
{
- converted = fz_new_pixmap_with_rect(dev->ctx, model, fz_bound_pixmap(image));
- fz_convert_pixmap(dev->ctx, image, converted);
+ converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image));
+ fz_convert_pixmap(ctx, image, converted);
image = converted;
}
- dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
- dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w && dy < image->h)
+ fz_try(ctx)
{
- int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
- scaled = fz_transform_pixmap(dev->ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit);
- if (!scaled)
+ dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
+ dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
+ if (dx < image->w && dy < image->h)
{
- if (dx < 1)
- dx = 1;
- if (dy < 1)
- dy = 1;
- scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy);
+ int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
+ scaled = fz_transform_pixmap(ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit);
+ if (!scaled)
+ {
+ if (dx < 1)
+ dx = 1;
+ if (dy < 1)
+ dy = 1;
+ scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy);
+ }
+ if (scaled)
+ image = scaled;
}
- if (scaled)
- image = scaled;
- }
- if (image->colorspace != model)
- {
- if ((image->colorspace == fz_device_gray && model == fz_device_rgb) ||
- (image->colorspace == fz_device_gray && model == fz_device_bgr))
- {
- /* We have special case rendering code for gray -> rgb/bgr */
- }
- else
+ if (image->colorspace != model)
{
- converted = fz_new_pixmap_with_rect(dev->ctx, model, fz_bound_pixmap(image));
- fz_convert_pixmap(dev->ctx, image, converted);
- image = converted;
+ if ((image->colorspace == fz_device_gray && model == fz_device_rgb) ||
+ (image->colorspace == fz_device_gray && model == fz_device_bgr))
+ {
+ /* We have special case rendering code for gray -> rgb/bgr */
+ }
+ else
+ {
+ converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image));
+ fz_convert_pixmap(ctx, image, converted);
+ image = converted;
+ }
}
- }
- fz_paint_image(dev->dest, dev->scissor, dev->shape, image, ctm, alpha * 255);
+ fz_paint_image(dev->dest, dev->scissor, dev->shape, image, ctm, alpha * 255);
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, scaled);
+ fz_drop_pixmap(ctx, converted);
+ fz_rethrow(ctx);
+ }
if (scaled)
- fz_drop_pixmap(dev->ctx, scaled);
+ fz_drop_pixmap(ctx, scaled);
if (converted)
- fz_drop_pixmap(dev->ctx, converted);
+ fz_drop_pixmap(ctx, converted);
if (dev->blendmode & FZ_BLEND_KNOCKOUT)
fz_knockout_end(dev);
@@ -1042,11 +1054,18 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
{
fz_draw_device *dev = devp->user;
fz_colorspace *model = dev->dest->colorspace;
+ fz_context *ctx = dev->ctx;
fz_bbox bbox;
- fz_pixmap *mask, *dest, *shape;
+ fz_pixmap *mask = NULL;
+ fz_pixmap *dest = NULL;
+ fz_pixmap *shape = NULL;
fz_pixmap *scaled = NULL;
int dx, dy;
+ fz_var(mask);
+ fz_var(dest);
+ fz_var(shape);
+
if (dev->top == dev->stack_max)
fz_grow_stack(dev);
@@ -1072,33 +1091,43 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
fz_clear_pixmap(mask);
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
- /* FIXME: See note #1 */
- fz_clear_pixmap(dest);
- if (dev->shape)
+ fz_try(ctx)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
- fz_clear_pixmap(shape);
- }
- else
- shape = NULL;
+ dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ /* FIXME: See note #1 */
+ fz_clear_pixmap(dest);
+ if (dev->shape)
+ {
+ shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ fz_clear_pixmap(shape);
+ }
+ else
+ shape = NULL;
- dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
- dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w && dy < image->h)
- {
- int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
- scaled = fz_transform_pixmap(dev->ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit);
- if (!scaled)
+ dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
+ dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
+ if (dx < image->w && dy < image->h)
{
- if (dx < 1)
- dx = 1;
- if (dy < 1)
- dy = 1;
- scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy);
+ int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
+ scaled = fz_transform_pixmap(dev->ctx, image, &ctm, dev->dest->x, dev->dest->y, dx, dy, gridfit);
+ if (!scaled)
+ {
+ if (dx < 1)
+ dx = 1;
+ if (dy < 1)
+ dy = 1;
+ scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy);
+ }
+ if (scaled)
+ image = scaled;
}
- if (scaled)
- image = scaled;
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, shape);
+ fz_drop_pixmap(ctx, dest);
+ fz_drop_pixmap(ctx, mask);
+ fz_rethrow(ctx);
}
fz_paint_image(mask, bbox, dev->shape, image, ctm, 255);
@@ -1299,10 +1328,11 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
fz_colorspace *model = dev->dest->colorspace;
fz_bbox bbox;
fz_pixmap *dest, *shape;
+ fz_context *ctx = dev->ctx;
if (dev->top == dev->stack_max)
{
- fz_warn(dev->ctx, "assert: too many buffers on stack");
+ fz_warn(ctx, "assert: too many buffers on stack");
return;
}
@@ -1311,7 +1341,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
bbox = fz_round_rect(rect);
bbox = fz_intersect_bbox(bbox, dev->scissor);
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ dest = fz_new_pixmap_with_rect(ctx, model, bbox);
#ifndef ATTEMPT_KNOCKOUT_AND_ISOLATED
knockout = 0;
@@ -1335,8 +1365,16 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
}
else
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
- fz_clear_pixmap(shape);
+ fz_try(ctx)
+ {
+ shape = fz_new_pixmap_with_rect(ctx, NULL, bbox);
+ fz_clear_pixmap(shape);
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, dest);
+ fz_rethrow(ctx);
+ }
}
dev->stack[dev->top].alpha = alpha;
@@ -1519,13 +1557,38 @@ static void
fz_draw_free_user(fz_device *devp)
{
fz_draw_device *dev = devp->user;
+ fz_context *ctx = dev->ctx;
/* TODO: pop and free the stacks */
if (dev->top > 0)
- fz_warn(dev->ctx, "items left on stack in draw device: %d", dev->top);
+ {
+ fz_warn(ctx, "items left on stack in draw device: %d", dev->top);
+ dev->top--;
+ if (dev->dest != dev->stack[dev->top].dest)
+ fz_drop_pixmap(ctx, dev->dest);
+ if (dev->shape != dev->stack[dev->top].shape)
+ fz_drop_pixmap(ctx, dev->shape);
+ while(dev->top > 0)
+ {
+ fz_pixmap *mask = dev->stack[dev->top].mask;
+ fz_pixmap *dest = dev->stack[dev->top].dest;
+ fz_pixmap *shape = dev->stack[dev->top].shape;
+
+ dev->top--;
+ if (mask != dev->stack[dev->top].mask)
+ fz_drop_pixmap(ctx, mask);
+ if (dest != dev->stack[dev->top].dest)
+ fz_drop_pixmap(ctx, dest);
+ if (shape != dev->stack[dev->top].shape)
+ fz_drop_pixmap(ctx, shape);
+ }
+ fz_drop_pixmap(ctx, dev->stack[0].mask);
+ fz_drop_pixmap(ctx, dev->stack[0].dest);
+ fz_drop_pixmap(ctx, dev->stack[0].shape);
+ }
if (dev->stack != &dev->init_stack[0])
- fz_free(dev->ctx, dev->stack);
+ fz_free(ctx, dev->stack);
fz_free_gel(dev->gel);
- fz_free(devp->ctx, dev);
+ fz_free(ctx, dev);
}
fz_device *