summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-12-19 15:19:40 +0000
committerRobin Watts <robin.watts@artifex.com>2011-12-19 15:19:40 +0000
commit3028fbf00d2d571b6f67001b5c09c15e3e2cfa26 (patch)
tree7be7037d3a0c4d093d1861a15cae812ae8377d54
parentda81dc0f28246b37a487e8ace9443f2689f855c0 (diff)
downloadmupdf-3028fbf00d2d571b6f67001b5c09c15e3e2cfa26.tar.xz
More Memory squeezing fixes
-rw-r--r--draw/draw_glyph.c14
-rw-r--r--draw/draw_simple_scale.c58
-rw-r--r--fitz/res_path.c10
-rw-r--r--fitz/res_pixmap.c19
-rw-r--r--fitz/res_text.c21
-rw-r--r--fitz/stm_read.c2
-rw-r--r--pdf/pdf_colorspace.c101
-rw-r--r--pdf/pdf_image.c3
-rw-r--r--pdf/pdf_interpret.c105
9 files changed, 209 insertions, 124 deletions
diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c
index 328b79f7..6b83af74 100644
--- a/draw/draw_glyph.c
+++ b/draw/draw_glyph.c
@@ -133,10 +133,18 @@ fz_render_glyph(fz_context *ctx, fz_glyph_cache *cache, fz_font *font, int gid,
{
if (cache->total + val->w * val->h > MAX_CACHE_SIZE)
fz_evict_glyph_cache(ctx, cache);
- fz_keep_font(key.font);
- fz_hash_insert(cache->hash, &key, val);
+ fz_try(ctx)
+ {
+ fz_hash_insert(cache->hash, &key, val);
+ fz_keep_font(key.font);
+ val = fz_keep_pixmap(val);
+ }
+ fz_catch(ctx)
+ {
+ fz_warn(ctx, "Failed to encache glyph - continuing");
+ }
cache->total += val->w * val->h;
- return fz_keep_pixmap(val);
+ return val;
}
return val;
}
diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c
index cd8ac2b9..6c8e451d 100644
--- a/draw/draw_simple_scale.c
+++ b/draw/draw_simple_scale.c
@@ -1178,6 +1178,9 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa
int dst_w_int, dst_h_int, dst_x_int, dst_y_int;
int flip_x, flip_y;
+ fz_var(contrib_cols);
+ fz_var(contrib_rows);
+
DBUG(("Scale: (%d,%d) to (%g,%g) at (%g,%g)\n",src->w,src->h,w,h,x,y));
/* Find the destination bbox, width/height, and sub pixel offset,
@@ -1240,35 +1243,30 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa
DBUG(("Result image: (%d,%d) at (%d,%d) (subpix=%g,%g)\n", dst_w_int, dst_h_int, dst_x_int, dst_y_int, x, y));
- /* Step 1: Calculate the weights for columns and rows */
-#ifdef SINGLE_PIXEL_SPECIALS
- if (src->w == 1)
+ fz_try(ctx)
{
- contrib_cols = NULL;
- }
- else
+ /* Step 1: Calculate the weights for columns and rows */
+#ifdef SINGLE_PIXEL_SPECIALS
+ if (src->w == 1)
+ contrib_cols = NULL;
+ else
#endif /* SINGLE_PIXEL_SPECIALS */
- {
- contrib_cols = make_weights(ctx, src->w, x, w, filter, 0, dst_w_int, src->n, flip_x);
- if (!contrib_cols)
- goto cleanup;
- }
+ contrib_cols = make_weights(ctx, src->w, x, w, filter, 0, dst_w_int, src->n, flip_x);
#ifdef SINGLE_PIXEL_SPECIALS
- if (src->h == 1)
- {
- contrib_rows = NULL;
- }
- else
+ if (src->h == 1)
+ contrib_rows = NULL;
+ else
#endif /* SINGLE_PIXEL_SPECIALS */
+ contrib_rows = make_weights(ctx, src->h, y, h, filter, 1, dst_h_int, src->n, flip_y);
+
+ output = fz_new_pixmap(ctx, src->colorspace, dst_w_int, dst_h_int);
+ }
+ fz_catch(ctx)
{
- contrib_rows = make_weights(ctx, src->h, y, h, filter, 1, dst_h_int, src->n, flip_y);
- if (!contrib_rows)
- goto cleanup;
+ fz_free(ctx, contrib_cols);
+ fz_free(ctx, contrib_rows);
+ fz_rethrow(ctx);
}
-
- assert(!contrib_cols || contrib_cols->count == dst_w_int);
- assert(!contrib_rows || contrib_rows->count == dst_h_int);
- output = fz_new_pixmap(ctx, src->colorspace, dst_w_int, dst_h_int);
output->x = dst_x_int;
output->y = dst_y_int;
@@ -1302,9 +1300,17 @@ fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, floa
temp_rows = contrib_rows->max_len;
if (temp_span <= 0 || temp_rows > INT_MAX / temp_span)
goto cleanup;
- temp = fz_calloc(ctx, temp_span*temp_rows, sizeof(unsigned char));
- if (!temp)
- goto cleanup;
+ fz_try(ctx)
+ {
+ temp = fz_calloc(ctx, temp_span*temp_rows, sizeof(unsigned char));
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, output);
+ fz_free(ctx, contrib_cols);
+ fz_free(ctx, contrib_rows);
+ fz_rethrow(ctx);
+ }
switch (src->n)
{
default:
diff --git a/fitz/res_path.c b/fitz/res_path.c
index 054b3c1f..bf61cff6 100644
--- a/fitz/res_path.c
+++ b/fitz/res_path.c
@@ -49,11 +49,13 @@ fz_free_path(fz_context *ctx, fz_path *path)
static void
grow_path(fz_context *ctx, fz_path *path, int n)
{
- if (path->len + n < path->cap)
+ int newcap = path->cap;
+ if (path->len + n <= path->cap)
return;
- while (path->len + n > path->cap)
- path->cap = path->cap + 36;
- path->items = fz_resize_array(ctx, path->items, path->cap, sizeof(fz_path_item));
+ while (path->len + n > newcap)
+ newcap = newcap + 36;
+ path->items = fz_resize_array(ctx, path->items, newcap, sizeof(fz_path_item));
+ path->cap = newcap;
}
void
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
index 99132a31..2ab95678 100644
--- a/fitz/res_pixmap.c
+++ b/fitz/res_pixmap.c
@@ -446,12 +446,17 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha)
static const unsigned char pngsig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
FILE *fp;
unsigned char head[13];
- unsigned char *udata, *cdata, *sp, *dp;
+ unsigned char *udata = NULL;
+ unsigned char *cdata = NULL;
+ unsigned char *sp, *dp;
uLong usize, csize;
int y, x, k, sn, dn;
int color;
int err;
+ fz_var(udata);
+ fz_var(cdata);
+
if (pixmap->n != 1 && pixmap->n != 2 && pixmap->n != 4)
fz_throw(ctx, "pixmap must be grayscale or rgb to write as png");
@@ -471,8 +476,16 @@ fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha)
usize = (pixmap->w * dn + 1) * pixmap->h;
csize = compressBound(usize);
- udata = fz_malloc(ctx, usize);
- cdata = fz_malloc(ctx, csize);
+ fz_try(ctx)
+ {
+ udata = fz_malloc(ctx, usize);
+ cdata = fz_malloc(ctx, csize);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, udata);
+ fz_rethrow(ctx);
+ }
sp = pixmap->samples;
dp = udata;
diff --git a/fitz/res_text.c b/fitz/res_text.c
index b8c5c5fd..63338435 100644
--- a/fitz/res_text.c
+++ b/fitz/res_text.c
@@ -19,8 +19,11 @@ fz_new_text(fz_context *ctx, fz_font *font, fz_matrix trm, int wmode)
void
fz_free_text(fz_context *ctx, fz_text *text)
{
- fz_drop_font(ctx, text->font);
- fz_free(ctx, text->items);
+ if (text != NULL)
+ {
+ fz_drop_font(ctx, text->font);
+ fz_free(ctx, text->items);
+ }
fz_free(ctx, text);
}
@@ -30,13 +33,21 @@ fz_clone_text(fz_context *ctx, fz_text *old)
fz_text *text;
text = fz_malloc_struct(ctx, fz_text);
+ text->len = old->len;
+ fz_try(ctx)
+ {
+ text->items = fz_malloc_array(ctx, text->len, sizeof(fz_text_item));
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, text);
+ fz_rethrow(ctx);
+ }
+ memcpy(text->items, old->items, text->len * sizeof(fz_text_item));
text->font = fz_keep_font(old->font);
text->trm = old->trm;
text->wmode = old->wmode;
- text->len = old->len;
text->cap = text->len;
- text->items = fz_malloc_array(ctx, text->len, sizeof(fz_text_item));
- memcpy(text->items, old->items, text->len * sizeof(fz_text_item));
return text;
}
diff --git a/fitz/stm_read.c b/fitz/stm_read.c
index 3d76d51a..2066b14c 100644
--- a/fitz/stm_read.c
+++ b/fitz/stm_read.c
@@ -90,7 +90,7 @@ fz_fill_buffer(fz_stream *stm)
fz_buffer *
fz_read_all(fz_stream *stm, int initial)
{
- fz_buffer *buf;
+ fz_buffer *buf = NULL;
int n;
fz_context *ctx = stm->ctx;
diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c
index 9d2f87ed..b2f42b8f 100644
--- a/pdf/pdf_colorspace.c
+++ b/pdf/pdf_colorspace.c
@@ -220,63 +220,82 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
static fz_colorspace *
load_indexed(pdf_xref *xref, fz_obj *array)
{
- struct indexed *idx;
+ struct indexed *idx = NULL;
fz_context *ctx = xref->ctx;
fz_obj *baseobj = fz_array_get(array, 1);
fz_obj *highobj = fz_array_get(array, 2);
fz_obj *lookup = fz_array_get(array, 3);
- fz_colorspace *base, *cs;
+ fz_colorspace *base = NULL;
+ fz_colorspace *cs = NULL;
int i, n;
- base = pdf_load_colorspace(xref, baseobj);
- /* "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */
-
- idx = fz_malloc_struct(ctx, struct indexed);
- idx->base = base;
- idx->high = fz_to_int(highobj);
- idx->high = CLAMP(idx->high, 0, 255);
- n = base->n * (idx->high + 1);
- idx->lookup = fz_malloc_array(ctx, 1, n);
-
- cs = fz_new_colorspace(ctx, "Indexed", 1);
- cs->to_rgb = indexed_to_rgb;
- cs->free_data = free_indexed;
- cs->data = idx;
- cs->size += sizeof(*idx) + n + (base ? base->size : 0);
-
- if (fz_is_string(lookup) && fz_to_str_len(lookup) == n)
- {
- unsigned char *buf = (unsigned char *) fz_to_str_buf(lookup);
- for (i = 0; i < n; i++)
- idx->lookup[i] = buf[i];
- }
- else if (fz_is_indirect(lookup))
- {
- fz_stream *file;
+ fz_var(idx);
+ fz_var(base);
+ fz_var(cs);
- fz_try(ctx)
+ fz_try(ctx)
+ {
+ base = pdf_load_colorspace(xref, baseobj);
+ /* "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */
+
+ idx = fz_malloc_struct(ctx, struct indexed);
+ idx->lookup = NULL;
+ idx->base = base;
+ idx->high = fz_to_int(highobj);
+ idx->high = CLAMP(idx->high, 0, 255);
+ n = base->n * (idx->high + 1);
+ idx->lookup = fz_malloc_array(ctx, 1, n);
+
+ cs = fz_new_colorspace(ctx, "Indexed", 1);
+ cs->to_rgb = indexed_to_rgb;
+ cs->free_data = free_indexed;
+ cs->data = idx;
+ cs->size += sizeof(*idx) + n + (base ? base->size : 0);
+
+ if (fz_is_string(lookup) && fz_to_str_len(lookup) == n)
{
- file = pdf_open_stream(xref, fz_to_num(lookup), fz_to_gen(lookup));
+ unsigned char *buf = (unsigned char *) fz_to_str_buf(lookup);
+ for (i = 0; i < n; i++)
+ idx->lookup[i] = buf[i];
}
- fz_catch(ctx)
+ else if (fz_is_indirect(lookup))
{
- fz_drop_colorspace(ctx, cs);
- fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup));
- }
+ fz_stream *file = NULL;
+
+ fz_try(ctx)
+ {
+ file = pdf_open_stream(xref, fz_to_num(lookup), fz_to_gen(lookup));
+ }
+ fz_catch(ctx)
+ {
+ fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup));
+ }
+
+ i = fz_read(file, idx->lookup, n);
+ if (i < 0)
+ {
+ fz_close(file);
+ fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup));
+ }
- i = fz_read(file, idx->lookup, n);
- if (i < 0)
+ fz_close(file);
+ }
+ else
{
- fz_drop_colorspace(ctx, cs);
- fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup));
+ fz_throw(ctx, "cannot parse colorspace lookup table");
}
-
- fz_close(file);
}
- else
+ fz_catch(ctx)
{
+ if (cs == NULL || cs->data != idx)
+ {
+ fz_drop_colorspace(ctx, base);
+ if (idx)
+ fz_free(ctx, idx->lookup);
+ fz_free(ctx, idx);
+ }
fz_drop_colorspace(ctx, cs);
- fz_throw(ctx, "cannot parse colorspace lookup table");
+ fz_rethrow(ctx);
}
return cs;
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index ead5c365..db2c6cc4 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -166,7 +166,8 @@ pdf_load_image_imp(pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm, i
}
fz_catch(ctx)
{
- fz_throw(ctx, "out of memory");
+ fz_drop_colorspace(ctx, colorspace);
+ fz_rethrow(ctx);
}
if (colorspace)
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index 0d5e2aa2..7fce1d52 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -1266,6 +1266,7 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
fz_matrix oldtopctm;
int oldtop;
int popmask;
+ int caught = 0;
pdf_gsave(csi);
@@ -1277,55 +1278,62 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
transform = fz_concat(xobj->matrix, transform);
gstate->ctm = fz_concat(transform, gstate->ctm);
- /* apply soft mask, create transparency group and reset state */
- if (xobj->transparency)
+ fz_try(ctx)
{
- if (gstate->softmask)
+ /* apply soft mask, create transparency group and reset state */
+ if (xobj->transparency)
{
- pdf_xobject *softmask = gstate->softmask;
- fz_rect bbox = fz_transform_rect(gstate->ctm, xobj->bbox);
+ if (gstate->softmask)
+ {
+ pdf_xobject *softmask = gstate->softmask;
+ fz_rect bbox = fz_transform_rect(gstate->ctm, xobj->bbox);
- gstate->softmask = NULL;
- popmask = 1;
+ gstate->softmask = NULL;
+ popmask = 1;
- fz_begin_mask(csi->dev, bbox, gstate->luminosity,
- softmask->colorspace, gstate->softmask_bc);
- pdf_run_xobject(csi, resources, softmask, fz_identity);
- /* RJW: "cannot run softmask" */
- fz_end_mask(csi->dev);
+ fz_begin_mask(csi->dev, bbox, gstate->luminosity,
+ softmask->colorspace, gstate->softmask_bc);
+ pdf_run_xobject(csi, resources, softmask, fz_identity);
+ /* RJW: "cannot run softmask" */
+ fz_end_mask(csi->dev);
- pdf_drop_xobject(ctx, softmask);
- }
+ pdf_drop_xobject(ctx, softmask);
+ }
- fz_begin_group(csi->dev,
- fz_transform_rect(gstate->ctm, xobj->bbox),
- xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
+ fz_begin_group(csi->dev,
+ fz_transform_rect(gstate->ctm, xobj->bbox),
+ xobj->isolated, xobj->knockout, gstate->blendmode, gstate->fill.alpha);
- gstate->blendmode = 0;
- gstate->stroke.alpha = 1;
- gstate->fill.alpha = 1;
- }
+ gstate->blendmode = 0;
+ gstate->stroke.alpha = 1;
+ gstate->fill.alpha = 1;
+ }
- /* clip to the bounds */
+ /* clip to the bounds */
- fz_moveto(ctx, csi->path, xobj->bbox.x0, xobj->bbox.y0);
- fz_lineto(ctx, csi->path, xobj->bbox.x1, xobj->bbox.y0);
- fz_lineto(ctx, csi->path, xobj->bbox.x1, xobj->bbox.y1);
- fz_lineto(ctx, csi->path, xobj->bbox.x0, xobj->bbox.y1);
- fz_closepath(ctx, csi->path);
- csi->clip = 1;
- pdf_show_path(csi, 0, 0, 0, 0);
+ fz_moveto(ctx, csi->path, xobj->bbox.x0, xobj->bbox.y0);
+ fz_lineto(ctx, csi->path, xobj->bbox.x1, xobj->bbox.y0);
+ fz_lineto(ctx, csi->path, xobj->bbox.x1, xobj->bbox.y1);
+ fz_lineto(ctx, csi->path, xobj->bbox.x0, xobj->bbox.y1);
+ fz_closepath(ctx, csi->path);
+ csi->clip = 1;
+ pdf_show_path(csi, 0, 0, 0, 0);
- /* run contents */
+ /* run contents */
- oldtopctm = csi->top_ctm;
- csi->top_ctm = gstate->ctm;
+ oldtopctm = csi->top_ctm;
+ csi->top_ctm = gstate->ctm;
- if (xobj->resources)
- resources = xobj->resources;
+ if (xobj->resources)
+ resources = xobj->resources;
- pdf_run_buffer(csi, resources, xobj->contents);
- /* RJW: "cannot interpret XObject stream" */
+ pdf_run_buffer(csi, resources, xobj->contents);
+ /* RJW: "cannot interpret XObject stream" */
+ }
+ fz_catch(ctx)
+ {
+ caught = 1;
+ }
csi->top_ctm = oldtopctm;
@@ -1334,8 +1342,10 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
pdf_grestore(csi);
- /* wrap up transparency stacks */
+ if (caught)
+ fz_rethrow(ctx);
+ /* wrap up transparency stacks */
if (xobj->transparency)
{
fz_end_group(csi->dev);
@@ -1671,8 +1681,15 @@ static void pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
if (!xobj->resources)
xobj->resources = fz_keep_obj(rdb);
- pdf_run_xobject(csi, xobj->resources, xobj, fz_identity);
- /* RJW: "cannot draw xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ fz_try(ctx)
+ {
+ pdf_run_xobject(csi, xobj->resources, xobj, fz_identity);
+ }
+ fz_catch(ctx)
+ {
+ pdf_drop_xobject(ctx, xobj);
+ fz_throw(ctx, "cannot draw xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ }
pdf_drop_xobject(ctx, xobj);
}
@@ -1684,7 +1701,15 @@ static void pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
fz_pixmap *img;
img = pdf_load_image(csi->xref, obj);
/* RJW: "cannot load image (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
- pdf_show_image(csi, img);
+ fz_try(ctx)
+ {
+ pdf_show_image(csi, img);
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, img);
+ fz_rethrow(ctx);
+ }
fz_drop_pixmap(ctx, img);
}
}