diff options
-rw-r--r-- | include/mupdf/fitz/image.h | 24 | ||||
-rw-r--r-- | include/mupdf/fitz/math.h | 15 | ||||
-rw-r--r-- | include/mupdf/fitz/output-png.h | 2 | ||||
-rw-r--r-- | include/mupdf/fitz/store.h | 6 | ||||
-rw-r--r-- | include/mupdf/fitz/stream.h | 11 | ||||
-rw-r--r-- | source/fitz/draw-device.c | 88 | ||||
-rw-r--r-- | source/fitz/geometry.c | 12 | ||||
-rw-r--r-- | source/fitz/image.c | 209 | ||||
-rw-r--r-- | source/fitz/pixmap.c | 4 | ||||
-rw-r--r-- | source/fitz/stext-output.c | 2 | ||||
-rw-r--r-- | source/fitz/stream-read.c | 20 | ||||
-rw-r--r-- | source/fitz/svg-device.c | 6 | ||||
-rw-r--r-- | source/fitz/test-device.c | 2 | ||||
-rw-r--r-- | source/gprf/gprf-doc.c | 10 | ||||
-rw-r--r-- | source/pdf/pdf-image.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-resources.c | 2 | ||||
-rw-r--r-- | source/pdf/pdf-stream.c | 2 | ||||
-rw-r--r-- | source/tools/murun.c | 4 | ||||
-rw-r--r-- | source/tools/pdfextract.c | 2 |
19 files changed, 369 insertions, 54 deletions
diff --git a/include/mupdf/fitz/image.h b/include/mupdf/fitz/image.h index 3355748c..5b9db325 100644 --- a/include/mupdf/fitz/image.h +++ b/include/mupdf/fitz/image.h @@ -24,17 +24,23 @@ typedef struct fz_image_s fz_image; image: The image to retrieve a pixmap from. - w: The desired width (in pixels). This may be completely ignored, but - may serve as an indication of a suitable subsample factor to use for - image types that support this. + subarea: The subarea of the image that we actually care about (or NULL + to indicate the whole image). - h: The desired height (in pixels). This may be completely ignored, but - may serve as an indication of a suitable subsample factor to use for - image types that support this. + trans: Optional, unless subarea is given. If given, then on entry this is + the transform that will be applied to the complete image. It should be + updated on exit to the transform to apply to the given subarea of the + image. This is used to calculate the desired width/height for subsampling. + + w: If non-NULL, a pointer to an int to be updated on exit to the + width (in pixels) that the scaled output will cover. + + h: If non-NULL, a pointer to an int to be updated on exit to the + height (in pixels) that the scaled output will cover. Returns a non NULL pixmap pointer. May throw exceptions. */ -fz_pixmap *fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h); +fz_pixmap *fz_get_pixmap_from_image(fz_context *ctx, fz_image *image, const fz_irect *subarea, fz_matrix *trans, int *w, int *h); /* fz_drop_image: Drop a reference to an image. @@ -58,7 +64,7 @@ fz_image *fz_new_image_from_data(fz_context *ctx, unsigned char *data, int len); fz_image *fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer); fz_image *fz_new_image_from_file(fz_context *ctx, const char *path); void fz_drop_image_imp(fz_context *ctx, fz_storable *image); -fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, int indexed, int l2factor); +fz_pixmap *fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, fz_irect *subarea, int indexed, int l2factor); fz_pixmap *fz_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src); struct fz_image_s @@ -67,7 +73,7 @@ struct fz_image_s int w, h, n, bpc; fz_image *mask; fz_colorspace *colorspace; - fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h, int *l2factor); + fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, fz_irect *subarea, int w, int h, int *l2factor); int colorkey[FZ_MAX_COLORS * 2]; float decode[FZ_MAX_COLORS * 2]; int imagemask; diff --git a/include/mupdf/fitz/math.h b/include/mupdf/fitz/math.h index f16b3627..b7baede8 100644 --- a/include/mupdf/fitz/math.h +++ b/include/mupdf/fitz/math.h @@ -294,6 +294,21 @@ fz_matrix *fz_scale(fz_matrix *m, float sx, float sy); fz_matrix *fz_pre_scale(fz_matrix *m, float sx, float sy); /* + fz_post_scale: Scale a matrix by postmultiplication. + + m: Pointer to the matrix to scale + + sx, sy: Scaling factors along the X- and Y-axes. A scaling + factor of 1.0 will not cause any scaling along the relevant + axis. + + Returns m (updated). + + Does not throw exceptions. +*/ +fz_matrix *fz_post_scale(fz_matrix *m, float sx, float sy); + +/* fz_shear: Create a shearing matrix. The returned matrix is of the form [ 1 sy sx 1 0 0 ]. diff --git a/include/mupdf/fitz/output-png.h b/include/mupdf/fitz/output-png.h index 34af799a..c77f9e5f 100644 --- a/include/mupdf/fitz/output-png.h +++ b/include/mupdf/fitz/output-png.h @@ -29,7 +29,7 @@ void fz_write_png_trailer(fz_context *ctx, fz_output *out, fz_png_output_context /* Create a new buffer containing the image/pixmap in PNG format. */ -fz_buffer *fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image, int w, int h); +fz_buffer *fz_new_buffer_from_image_as_png(fz_context *ctx, fz_image *image); fz_buffer *fz_new_buffer_from_pixmap_as_png(fz_context *ctx, fz_pixmap *pixmap); #endif diff --git a/include/mupdf/fitz/store.h b/include/mupdf/fitz/store.h index e98e2394..5dbf5538 100644 --- a/include/mupdf/fitz/store.h +++ b/include/mupdf/fitz/store.h @@ -78,6 +78,12 @@ struct fz_store_hash_s } pi; struct { + const void *ptr; + int i; + fz_irect r; + } pir; + struct + { int id; float m[4]; } im; diff --git a/include/mupdf/fitz/stream.h b/include/mupdf/fitz/stream.h index 233e2b06..90b5ec22 100644 --- a/include/mupdf/fitz/stream.h +++ b/include/mupdf/fitz/stream.h @@ -136,6 +136,17 @@ void fz_seek(fz_context *ctx, fz_stream *stm, fz_off_t offset, int whence); int fz_read(fz_context *ctx, fz_stream *stm, unsigned char *data, int len); /* + fz_skip: Read from a stream discarding data. + + stm: The stream to read from. + + len: The number of bytes to read. + + Returns the number of bytes read. May throw exceptions. +*/ +int fz_skip(fz_context *ctx, fz_stream *stm, int len); + +/* fz_read_all: Read all of a stream into a buffer. stm: The stream to read from 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); |