summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-04-07 11:08:42 +0100
committerRobin Watts <robin.watts@artifex.com>2016-04-28 12:30:40 +0100
commitb944f16a564f8a31d9a064980318ad690be31f8e (patch)
tree6fb5a572487943e7cdccee2b201ae526c23bd595 /source
parent6ab232064f3fc9037e97157dd9a77f286ad85e23 (diff)
downloadmupdf-b944f16a564f8a31d9a064980318ad690be31f8e.tar.xz
Partial image decode.
Update the core fz_get_pixmap_from_image code to allow fetching a subarea of a pixmap. We pass in the required subarea, together with the transformation matrix for the whole image. On return, we have a pixmap at least as big as was requested, and the transformation matrix is updated to map the supplied area to the correct place on the screen. The draw device is updated to use this as required. Everywhere else passes NULLs in, and so gets unchanged behaviour. The standard 'get_pixmap' function has been updated to decode just the required areas of the bitmaps. This means that banded rendering of pages will decode just the image subareas that are required for each band, limiting the memory use. The downside to this is that each band will redecode the image again to extract just the section we want. The image subareas are put into the fz_store in the same way as full images. Currently image areas in the store are only matched when they match exactly; subareas are not identified as being able to use existing images.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/draw-device.c88
-rw-r--r--source/fitz/geometry.c12
-rw-r--r--source/fitz/image.c209
-rw-r--r--source/fitz/pixmap.c4
-rw-r--r--source/fitz/stext-output.c2
-rw-r--r--source/fitz/stream-read.c20
-rw-r--r--source/fitz/svg-device.c6
-rw-r--r--source/fitz/test-device.c2
-rw-r--r--source/gprf/gprf-doc.c10
-rw-r--r--source/pdf/pdf-image.c2
-rw-r--r--source/pdf/pdf-resources.c2
-rw-r--r--source/pdf/pdf-stream.c2
-rw-r--r--source/tools/murun.c4
-rw-r--r--source/tools/pdfextract.c2
14 files changed, 321 insertions, 44 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index b9db1558..4108cf09 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -1106,6 +1106,8 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m
fz_colorspace *model = state->dest->colorspace;
fz_irect clip;
fz_matrix local_ctm = *ctm;
+ fz_matrix inverse;
+ fz_irect src_area;
fz_intersect_irect(fz_pixmap_bbox(ctx, state->dest, &clip), &state->scissor);
@@ -1120,10 +1122,42 @@ fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_m
if (image->w == 0 || image->h == 0)
return;
- dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b);
- dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d);
-
- pixmap = fz_get_pixmap_from_image(ctx, image, dx, dy);
+ /* ctm maps the image (expressed as the unit square) onto the
+ * destination device. Reverse that to get a mapping from
+ * the destination device to the source pixels. */
+ if (fz_try_invert_matrix(&inverse, &local_ctm))
+ {
+ /* Not invertible. Could just bale? Use the whole image
+ * for now. */
+ src_area.x0 = 0;
+ src_area.x1 = image->w;
+ src_area.y0 = 0;
+ src_area.y1 = image->h;
+ }
+ else
+ {
+ float exp;
+ fz_rect rect;
+ fz_irect sane;
+ /* We want to scale from image coords, not from unit square */
+ fz_post_scale(&inverse, image->w, image->h);
+ /* Are we scaling up or down? exp < 1 means scaling down. */
+ exp = fz_matrix_max_expansion(&inverse);
+ fz_rect_from_irect(&rect, &clip);
+ fz_transform_rect(&rect, &inverse);
+ /* Allow for support requirements for scalers. */
+ fz_expand_rect(&rect, fz_max(exp, 1) * 4);
+ fz_irect_from_rect(&src_area, &rect);
+ sane.x0 = 0;
+ sane.y0 = 0;
+ sane.x1 = image->w;
+ sane.y1 = image->h;
+ fz_intersect_irect(&src_area, &sane);
+ if (fz_is_empty_irect(&src_area))
+ return;
+ }
+
+ pixmap = fz_get_pixmap_from_image(ctx, image, &src_area, &local_ctm, &dx, &dy);
orig_pixmap = pixmap;
/* convert images with more components (cmyk->rgb) before scaling */
@@ -1214,6 +1248,8 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const
fz_colorspace *model = state->dest->colorspace;
fz_irect clip;
fz_matrix local_ctm = *ctm;
+ fz_matrix inverse;
+ fz_irect src_area;
fz_pixmap_bbox(ctx, state->dest, &clip);
fz_intersect_irect(&clip, &state->scissor);
@@ -1221,9 +1257,42 @@ fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const
if (image->w == 0 || image->h == 0)
return;
- dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b);
- dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d);
- pixmap = fz_get_pixmap_from_image(ctx, image, dx, dy);
+ /* ctm maps the image (expressed as the unit square) onto the
+ * destination device. Reverse that to get a mapping from
+ * the destination device to the source pixels. */
+ if (fz_try_invert_matrix(&inverse, &local_ctm))
+ {
+ /* Not invertible. Could just bale? Use the whole image
+ * for now. */
+ src_area.x0 = 0;
+ src_area.x1 = image->w;
+ src_area.y0 = 0;
+ src_area.y1 = image->h;
+ }
+ else
+ {
+ float exp;
+ fz_rect rect;
+ fz_irect sane;
+ /* We want to scale from image coords, not from unit square */
+ fz_post_scale(&inverse, image->w, image->h);
+ /* Are we scaling up or down? exp < 1 means scaling down. */
+ exp = fz_matrix_max_expansion(&inverse);
+ fz_rect_from_irect(&rect, &clip);
+ fz_transform_rect(&rect, &inverse);
+ /* Allow for support requirements for scalers. */
+ fz_expand_rect(&rect, fz_max(exp, 1) * 4);
+ fz_irect_from_rect(&src_area, &rect);
+ sane.x0 = 0;
+ sane.y0 = 0;
+ sane.x1 = image->w;
+ sane.y1 = image->h;
+ fz_intersect_irect(&src_area, &sane);
+ if (fz_is_empty_irect(&src_area))
+ return;
+ }
+
+ pixmap = fz_get_pixmap_from_image(ctx, image, &src_area, &local_ctm, &dx, &dy);
orig_pixmap = pixmap;
fz_try(ctx)
@@ -1321,12 +1390,9 @@ fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const
fz_intersect_irect(&bbox, fz_irect_from_rect(&bbox2, scissor));
}
- dx = sqrtf(local_ctm.a * local_ctm.a + local_ctm.b * local_ctm.b);
- dy = sqrtf(local_ctm.c * local_ctm.c + local_ctm.d * local_ctm.d);
-
fz_try(ctx)
{
- pixmap = fz_get_pixmap_from_image(ctx, image, dx, dy);
+ pixmap = fz_get_pixmap_from_image(ctx, image, NULL, &local_ctm, &dx, &dy);
orig_pixmap = pixmap;
state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox);
diff --git a/source/fitz/geometry.c b/source/fitz/geometry.c
index 073536ff..f7a92816 100644
--- a/source/fitz/geometry.c
+++ b/source/fitz/geometry.c
@@ -59,6 +59,18 @@ fz_pre_scale(fz_matrix *mat, float sx, float sy)
}
fz_matrix *
+fz_post_scale(fz_matrix *mat, float sx, float sy)
+{
+ mat->a *= sx;
+ mat->b *= sy;
+ mat->c *= sx;
+ mat->d *= sy;
+ mat->e *= sx;
+ mat->f *= sy;
+ return mat;
+}
+
+fz_matrix *
fz_shear(fz_matrix *mat, float h, float v)
{
mat->a = 1; mat->b = v;
diff --git a/source/fitz/image.c b/source/fitz/image.c
index 9c66176f..36026a19 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -21,14 +21,16 @@ struct fz_image_key_s {
int refs;
fz_image *image;
int l2factor;
+ fz_irect rect;
};
static int
fz_make_hash_image_key(fz_context *ctx, fz_store_hash *hash, void *key_)
{
fz_image_key *key = (fz_image_key *)key_;
- hash->u.pi.ptr = key->image;
- hash->u.pi.i = key->l2factor;
+ hash->u.pir.ptr = key->image;
+ hash->u.pir.i = key->l2factor;
+ hash->u.pir.r = key->rect;
return 1;
}
@@ -55,7 +57,7 @@ fz_cmp_image_key(fz_context *ctx, void *k0_, void *k1_)
{
fz_image_key *k0 = (fz_image_key *)k0_;
fz_image_key *k1 = (fz_image_key *)k1_;
- return k0->image == k1->image && k0->l2factor == k1->l2factor;
+ return k0->image == k1->image && k0->l2factor == k1->l2factor && k0->rect.x0 == k1->rect.x0 && k0->rect.y0 == k1->rect.y0 && k0->rect.x1 == k1->rect.x1 && k0->rect.y1 == k1->rect.y1;
}
static void
@@ -96,7 +98,7 @@ fz_mask_color_key(fz_pixmap *pix, int n, const int *colorkey)
static void
fz_unblend_masked_tile(fz_context *ctx, fz_pixmap *tile, fz_image *image)
{
- fz_pixmap *mask = fz_get_pixmap_from_image(ctx, image->mask, tile->w, tile->h);
+ fz_pixmap *mask = fz_get_pixmap_from_image(ctx, image->mask, NULL, NULL, NULL, NULL);
unsigned char *s = mask->samples, *end = s + mask->w * mask->h;
unsigned char *d = tile->samples;
int k;
@@ -122,14 +124,39 @@ fz_unblend_masked_tile(fz_context *ctx, fz_pixmap *tile, fz_image *image)
}
fz_pixmap *
-fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor)
+fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, fz_irect *subarea, int indexed, int l2factor)
{
fz_pixmap *tile = NULL;
int stride, len, i;
unsigned char *samples = NULL;
int f = 1<<l2factor;
- int w = (image->w + f-1) >> l2factor;
- int h = (image->h + f-1) >> l2factor;
+ int w = image->w;
+ int h = image->h;
+
+ if (subarea)
+ {
+ int bpp = image->bpc * image->n;
+ int mask;
+ switch (bpp)
+ {
+ case 1: mask = 8*f; break;
+ case 2: mask = 4*f; break;
+ case 4: mask = 2*f; break;
+ default: mask = f; break;
+ }
+ subarea->x0 &= ~(mask - 1);
+ subarea->y0 &= ~(f - 1);
+ subarea->x1 = (subarea->x1 + mask - 1) & ~(mask - 1);
+ if (subarea->x1 > image->w)
+ subarea->x1 = image->w;
+ subarea->y1 = (subarea->y1 + f - 1) & ~(f - 1);
+ if (subarea->y1 > image->h)
+ subarea->y1 = image->h;
+ w = (subarea->x1 - subarea->x0);
+ h = (subarea->y1 - subarea->y0);
+ }
+ w = (w + f - 1) >> l2factor;
+ h = (h + f - 1) >> l2factor;
fz_var(tile);
fz_var(samples);
@@ -143,7 +170,46 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in
samples = fz_malloc_array(ctx, h, stride);
- len = fz_read(ctx, stm, samples, h * stride);
+ if (subarea)
+ {
+ int hh;
+ unsigned char *s = samples;
+ int stream_w = (image->w + f - 1)>>l2factor;
+ int stream_stride = (stream_w * image->n * image->bpc + 7) / 8;
+ int l_margin = subarea->x0 >> l2factor;
+ int t_margin = subarea->y0 >> l2factor;
+ int r_margin = (image->w + f - 1 - subarea->x1) >> l2factor;
+ int b_margin = (image->h + f - 1 - subarea->y1) >> l2factor;
+ int l_skip = (l_margin * image->n * image->bpc)/8;
+ int r_skip = (r_margin * image->n * image->bpc)/8;
+ int t_skip = t_margin * stream_stride + l_skip;
+ int b_skip = b_margin * stream_stride + r_skip;
+ int l = fz_skip(ctx, stm, t_skip);
+ len = 0;
+ if (l == t_skip)
+ {
+ hh = h;
+ do
+ {
+ l = fz_read(ctx, stm, s, stride);
+ s += l;
+ len += l;
+ if (l < stride)
+ break;
+ if (--hh == 0)
+ break;
+ l = fz_skip(ctx, stm, r_skip + l_skip);
+ if (l < r_skip + l_skip)
+ break;
+ }
+ while (1);
+ (void)fz_skip(ctx, stm, r_skip + b_skip);
+ }
+ }
+ else
+ {
+ len = fz_read(ctx, stm, samples, h * stride);
+ }
/* Pad truncated images */
if (len < stride * h)
@@ -219,12 +285,13 @@ fz_drop_image_imp(fz_context *ctx, fz_storable *image_)
}
static fz_pixmap *
-standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int *l2factor)
+standard_image_get_pixmap(fz_context *ctx, fz_image *image, fz_irect *subarea, int w, int h, int *l2factor)
{
int native_l2factor;
fz_stream *stm;
int indexed;
fz_pixmap *tile;
+ int can_sub = 0;
/* We need to make a new one. */
/* First check for ones that we can't decode using streams */
@@ -271,7 +338,8 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int *l
native_l2factor -= *l2factor;
indexed = fz_colorspace_is_indexed(ctx, image->colorspace);
- tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, native_l2factor);
+ can_sub = 1;
+ tile = fz_decomp_image_from_stream(ctx, stm, image, subarea, indexed, native_l2factor);
/* CMYK JPEGs in XPS documents have to be inverted */
if (image->invert_cmyk_jpeg &&
@@ -285,20 +353,63 @@ standard_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h, int *l
break;
}
+ if (can_sub == 0 && subarea != NULL)
+ {
+ subarea->x0 = 0;
+ subarea->y0 = 0;
+ subarea->x1 = image->w;
+ subarea->y1 = image->h;
+ }
+
return tile;
}
+static void
+update_ctm_for_subarea(fz_matrix *ctm, const fz_irect *subarea, int w, int h)
+{
+ fz_matrix m;
+
+ if (subarea->x0 == 0 && subarea->y0 == 0 && subarea->x1 == w && subarea->y1 == h)
+ return;
+
+ m.a = (subarea->x1 - subarea->x0) / (float)w;
+ m.b = 0;
+ m.c = 0;
+ m.d = (subarea->y1 - subarea->y0) / (float)h;
+ m.e = subarea->x0 / (float)w;
+ m.f = subarea->y0 / (float)h;
+ fz_concat(ctm, &m, ctm);
+}
+
fz_pixmap *
-fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
+fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *ctm, int *dw, int *dh)
{
fz_pixmap *tile;
int l2factor, l2factor_remaining;
fz_image_key key;
fz_image_key *keyp;
+ int w;
+ int h;
if (!image)
return NULL;
+ /* Figure out the extent. */
+ if (ctm)
+ {
+ w = sqrtf(ctm->a * ctm->a + ctm->b * ctm->b);
+ if (w > image->w)
+ w = image->w;
+ h = sqrtf(ctm->c * ctm->c + ctm->d * ctm->d);
+ if (h > image->h)
+ w = image->h;
+ }
+ else
+ {
+ w = image->w;
+ h = image->h;
+ }
+
/* 'Simple' images created direct from pixmaps will have no buffer
* of compressed data. We cannot do any better than just returning
* a pointer to the original 'tile'.
@@ -307,13 +418,13 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
* with masks applied, so we need both parts of the following test.
*/
if (image->buffer == NULL && image->tile != NULL)
+ {
+ if (dw)
+ *dw = w;
+ if (dh)
+ *dh = h;
return fz_keep_pixmap(ctx, image->tile); /* That's all we can give you! */
-
- /* Ensure our expectations for tile size are reasonable */
- if (w < 0 || w > image->w)
- w = image->w;
- if (h < 0 || h > image->h)
- h = image->h;
+ }
/* What is our ideal factor? We search for the largest factor where
* we can subdivide and stay larger than the required size. We add
@@ -324,6 +435,61 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
else
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)
+ {
+ /* 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;
+ key.rect.y1 = image->h;
+ }
+ 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;
+ }
+
+ if (ctm)
+ {
+ float frac_w = (key.rect.x1 - key.rect.x0) / (float)image->w;
+ float frac_h = (key.rect.y1 - key.rect.y0) / (float)image->h;
+ float a = ctm->a * frac_w;
+ float b = ctm->b * frac_h;
+ float c = ctm->c * frac_w;
+ float d = ctm->d * frac_h;
+
+ w = sqrtf(a * a + b * b);
+ h = sqrtf(c * c + d * d);
+ }
+ else
+ {
+ w = image->w;
+ h = image->h;
+ }
+
+ /* Return the true sizes to the caller */
+ if (dw)
+ *dw = w;
+ if (dh)
+ *dh = h;
+ if (w > image->w)
+ w = image->w;
+ if (h > image->h)
+ h = image->h;
+
+ if (w == 0 || h == 0)
+ l2factor = 0;
+
/* Can we find any suitable tiles in the cache? */
key.refs = 1;
key.image = image;
@@ -332,7 +498,10 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
{
tile = fz_find_item(ctx, fz_drop_pixmap_imp, &key, &fz_image_store_type);
if (tile)
+ {
+ update_ctm_for_subarea(ctm, &key.rect, image->w, image->h);
return tile;
+ }
key.l2factor--;
}
while (key.l2factor >= 0);
@@ -340,7 +509,10 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
/* We'll have to decode the image; request the correct amount of
* downscaling. */
l2factor_remaining = l2factor;
- tile = image->get_pixmap(ctx, image, w, h, &l2factor_remaining);
+ tile = image->get_pixmap(ctx, image, &key.rect, w, h, &l2factor_remaining);
+
+ /* Update the ctm to allow for subareas. */
+ update_ctm_for_subarea(ctm, &key.rect, image->w, image->h);
/* l2factor_remaining is updated to the amount of subscaling left to do */
assert(l2factor_remaining >= 0 && l2factor_remaining <= 6);
@@ -360,6 +532,7 @@ fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
keyp->refs = 1;
keyp->image = fz_keep_image(ctx, image);
keyp->l2factor = l2factor;
+ keyp->rect = key.rect;
existing_tile = fz_store_item(ctx, keyp, tile, fz_pixmap_size(ctx, tile), &fz_image_store_type);
if (existing_tile)
{
diff --git a/source/fitz/pixmap.c b/source/fitz/pixmap.c
index 88e16d9d..fca6f733 100644
--- a/source/fitz/pixmap.c
+++ b/source/fitz/pixmap.c
@@ -1123,9 +1123,9 @@ png_from_pixmap(fz_context *ctx, fz_pixmap *pix, int drop)
}
fz_buffer *
-fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image, int w, int h)
+fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image)
{
- return png_from_pixmap(ctx, fz_get_pixmap_from_image(ctx, image, image->w, image->h), 1);
+ return png_from_pixmap(ctx, fz_get_pixmap_from_image(ctx, image, NULL, NULL, NULL, NULL), 1);
}
fz_buffer *
diff --git a/source/fitz/stext-output.c b/source/fitz/stext-output.c
index 1ba9fe51..70b0bf7e 100644
--- a/source/fitz/stext-output.c
+++ b/source/fitz/stext-output.c
@@ -258,7 +258,7 @@ fz_print_stext_page_html(fz_context *ctx, fz_output *out, fz_stext_page *page)
break;
default:
{
- fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image->image, image->image->w, image->image->h);
+ fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image->image);
fz_printf(ctx, out, "image/png;base64,");
send_data_base64(ctx, out, buf);
fz_drop_buffer(ctx, buf);
diff --git a/source/fitz/stream-read.c b/source/fitz/stream-read.c
index 2ebd5ad6..2ace7b1f 100644
--- a/source/fitz/stream-read.c
+++ b/source/fitz/stream-read.c
@@ -27,6 +27,26 @@ fz_read(fz_context *ctx, fz_stream *stm, unsigned char *buf, int len)
return count;
}
+static unsigned char skip_buf[4096];
+
+int fz_skip(fz_context *ctx, fz_stream *stm, int len)
+{
+ int count, l, total = 0;
+
+ while (len)
+ {
+ l = len;
+ if (l > sizeof(skip_buf))
+ l = sizeof(skip_buf);
+ count = fz_read(ctx, stm, skip_buf, l);
+ total += count;
+ if (count < l)
+ break;
+ len -= count;
+ }
+ return total;
+}
+
fz_buffer *
fz_read_all(fz_context *ctx, fz_stream *stm, int initial)
{
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index d36a5872..5f60cf75 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -743,7 +743,7 @@ svg_dev_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma
break;
default:
{
- fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image, image->w, image->h);
+ fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image);
fz_printf(ctx, out, "image/png;base64,");
send_data_base64(ctx, out, buf);
fz_drop_buffer(ctx, buf);
@@ -830,7 +830,7 @@ svg_dev_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
break;
default:
{
- fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image, image->w, image->h);
+ fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image);
fz_printf(ctx, out, "image/png;base64,");
send_data_base64(ctx, out, buf);
fz_drop_buffer(ctx, buf);
@@ -874,7 +874,7 @@ svg_dev_clip_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const
break;
default:
{
- fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image, image->w, image->h);
+ fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image);
fz_printf(ctx, out, "image/png;base64,");
send_data_base64(ctx, out, buf);
fz_drop_buffer(ctx, buf);
diff --git a/source/fitz/test-device.c b/source/fitz/test-device.c
index 64c7804f..6a4e0127 100644
--- a/source/fitz/test-device.c
+++ b/source/fitz/test-device.c
@@ -184,7 +184,7 @@ fz_test_fill_image(fz_context *ctx, fz_device *dev, fz_image *image, const fz_ma
return;
}
- pix = fz_get_pixmap_from_image(ctx, image, 0, 0);
+ pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0);
if (pix == NULL) /* Should never happen really, but... */
return;
diff --git a/source/gprf/gprf-doc.c b/source/gprf/gprf-doc.c
index d56501ba..d1dc4aa3 100644
--- a/source/gprf/gprf-doc.c
+++ b/source/gprf/gprf-doc.c
@@ -314,7 +314,7 @@ unsigned char undelta(unsigned char delta, unsigned char *ptr, int len)
}
static fz_pixmap *
-gprf_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h, int *l2factor)
+gprf_get_pixmap(fz_context *ctx, fz_image *image_, fz_irect *area, int w, int h, int *l2factor)
{
/* The file contains RGB + up to FZ_MAX_SEPARATIONS. Hence the
* "3 + FZ_MAX_SEPARATIONS" usage in all the arrays below. */
@@ -332,6 +332,14 @@ gprf_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h, int *l2factor)
fz_var(file);
+ if (area)
+ {
+ area->x0 = 0;
+ area->y0 = 0;
+ area->x1 = image->base.w;
+ area->y1 = image->base.h;
+ }
+
fz_try(ctx)
{
/* First off, figure out if we are doing RGB or separations
diff --git a/source/pdf/pdf-image.c b/source/pdf/pdf-image.c
index 04e1c1f0..e0da7ad9 100644
--- a/source/pdf/pdf-image.c
+++ b/source/pdf/pdf-image.c
@@ -330,7 +330,7 @@ pdf_add_image(fz_context *ctx, pdf_document *doc, fz_image *image, int mask)
/* Currently, set to maintain resolution; should we consider
* subsampling here according to desired output res? */
- pixmap = fz_get_pixmap_from_image(ctx, image, image->w, image->h);
+ pixmap = fz_get_pixmap_from_image(ctx, image, NULL, NULL, NULL, NULL);
colorspace = pixmap->colorspace; /* May be different to image->colorspace! */
n = (pixmap->n == 1 ? 1 : pixmap->n - 1);
size = image->w * image->h * n;
diff --git a/source/pdf/pdf-resources.c b/source/pdf/pdf-resources.c
index 4fae6c87..212c57df 100644
--- a/source/pdf/pdf-resources.c
+++ b/source/pdf/pdf-resources.c
@@ -28,7 +28,7 @@ res_image_get_md5(fz_context *ctx, fz_image *image, unsigned char *digest)
fz_pixmap *pixmap;
fz_md5 state;
- pixmap = fz_get_pixmap_from_image(ctx, image, 0, 0);
+ pixmap = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0);
fz_md5_init(&state);
fz_md5_update(&state, pixmap->samples, pixmap->w * pixmap->h * pixmap->n);
fz_md5_final(&state, digest);
diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index 1743a22c..3c275d2d 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -357,7 +357,7 @@ pdf_load_compressed_inline_image(fz_context *ctx, pdf_document *doc, pdf_obj *di
stm = fz_open_leecher(ctx, stm, bc->buffer);
stm = fz_open_image_decomp_stream(ctx, stm, &bc->params, &dummy_l2factor);
- image->tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, 0);
+ image->tile = fz_decomp_image_from_stream(ctx, stm, image, NULL, indexed, 0);
}
fz_catch(ctx)
{
diff --git a/source/tools/murun.c b/source/tools/murun.c
index c2a9f0bc..6e6e2719 100644
--- a/source/tools/murun.c
+++ b/source/tools/murun.c
@@ -1881,12 +1881,10 @@ static void ffi_Image_toPixmap(js_State *J)
{
fz_context *ctx = js_getcontext(J);
fz_image *image = js_touserdata(J, 0, "fz_image");
- int w = js_isnumber(J, 1) ? js_tonumber(J, 1) : image->w;
- int h = js_isnumber(J, 2) ? js_tonumber(J, 2) : image->h;
fz_pixmap *pixmap = NULL;
fz_try(ctx)
- pixmap = fz_get_pixmap_from_image(ctx, image, w, h);
+ pixmap = fz_get_pixmap_from_image(ctx, image, NULL, NULL, NULL, NULL);
fz_catch(ctx)
rethrow(J);
diff --git a/source/tools/pdfextract.c b/source/tools/pdfextract.c
index 74b3654e..3f79137a 100644
--- a/source/tools/pdfextract.c
+++ b/source/tools/pdfextract.c
@@ -72,7 +72,7 @@ static void saveimage(int num)
/* TODO: detect DCTD and save as jpeg */
image = pdf_load_image(ctx, doc, ref);
- pix = fz_get_pixmap_from_image(ctx, image, 0, 0);
+ pix = fz_get_pixmap_from_image(ctx, image, NULL, NULL, 0, 0);
fz_drop_image(ctx, image);
snprintf(buf, sizeof(buf), "img-%04d", num);