summaryrefslogtreecommitdiff
path: root/source/fitz/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/image.c')
-rw-r--r--source/fitz/image.c97
1 files changed, 62 insertions, 35 deletions
diff --git a/source/fitz/image.c b/source/fitz/image.c
index 556e841b..77999ff1 100644
--- a/source/fitz/image.c
+++ b/source/fitz/image.c
@@ -1,5 +1,7 @@
#include "mupdf/fitz.h"
+#define SANE_DPI 72.0f
+
fz_pixmap *
fz_new_pixmap_from_image(fz_context *ctx, fz_image *image, int w, int h)
{
@@ -29,10 +31,9 @@ struct fz_image_key_s {
};
static int
-fz_make_hash_image_key(fz_store_hash *hash, void *key_)
+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;
return 1;
@@ -42,26 +43,14 @@ static void *
fz_keep_image_key(fz_context *ctx, void *key_)
{
fz_image_key *key = (fz_image_key *)key_;
-
- fz_lock(ctx, FZ_LOCK_ALLOC);
- key->refs++;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
-
- return (void *)key;
+ return fz_keep_imp(ctx, key, &key->refs);
}
static void
fz_drop_image_key(fz_context *ctx, void *key_)
{
fz_image_key *key = (fz_image_key *)key_;
- int drop;
-
- if (key == NULL)
- return;
- fz_lock(ctx, FZ_LOCK_ALLOC);
- drop = --key->refs;
- fz_unlock(ctx, FZ_LOCK_ALLOC);
- if (drop == 0)
+ if (fz_drop_imp(ctx, key, &key->refs))
{
fz_drop_image(ctx, key->image);
fz_free(ctx, key);
@@ -69,17 +58,16 @@ fz_drop_image_key(fz_context *ctx, void *key_)
}
static int
-fz_cmp_image_key(void *k0_, void *k1_)
+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;
}
#ifndef NDEBUG
static void
-fz_debug_image(FILE *out, void *key_)
+fz_debug_image(fz_context *ctx, FILE *out, void *key_)
{
fz_image_key *key = (fz_image_key *)key_;
@@ -167,7 +155,7 @@ 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(stm, samples, h * stride);
+ len = fz_read(ctx, stm, samples, h * stride);
/* Pad truncated images */
if (len < stride * h)
@@ -186,7 +174,7 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in
p[i] = ~p[i];
}
- fz_unpack_tile(tile, samples, image->n, image->bpc, stride, indexed);
+ fz_unpack_tile(ctx, tile, samples, image->n, image->bpc, stride, indexed);
fz_free(ctx, samples);
samples = NULL;
@@ -198,14 +186,14 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in
if (indexed)
{
fz_pixmap *conv;
- fz_decode_indexed_tile(tile, image->decode, (1 << image->bpc) - 1);
+ fz_decode_indexed_tile(ctx, tile, image->decode, (1 << image->bpc) - 1);
conv = fz_expand_indexed_pixmap(ctx, tile);
fz_drop_pixmap(ctx, tile);
tile = conv;
}
else
{
- fz_decode_tile(tile, image->decode);
+ fz_decode_tile(ctx, tile, image->decode);
}
/* pre-blended matte color */
@@ -214,7 +202,7 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in
}
fz_always(ctx)
{
- fz_close(stm);
+ fz_drop_stream(ctx, stm);
}
fz_catch(ctx)
{
@@ -237,14 +225,14 @@ fz_decomp_image_from_stream(fz_context *ctx, fz_stream *stm, fz_image *image, in
}
void
-fz_free_image(fz_context *ctx, fz_storable *image_)
+fz_drop_image_imp(fz_context *ctx, fz_storable *image_)
{
fz_image *image = (fz_image *)image_;
if (image == NULL)
return;
fz_drop_pixmap(ctx, image->tile);
- fz_free_compressed_buffer(ctx, image->buffer);
+ fz_drop_compressed_buffer(ctx, image->buffer);
fz_drop_colorspace(ctx, image->colorspace);
fz_drop_image(ctx, image->mask);
fz_free(ctx, image);
@@ -291,7 +279,7 @@ fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h)
key.l2factor = l2factor;
do
{
- tile = fz_find_item(ctx, fz_free_pixmap_imp, &key, &fz_image_store_type);
+ tile = fz_find_item(ctx, fz_drop_pixmap_imp, &key, &fz_image_store_type);
if (tile)
return tile;
key.l2factor--;
@@ -334,7 +322,7 @@ fz_image_get_pixmap(fz_context *ctx, fz_image *image, int w, int h)
native_l2factor = l2factor;
stm = fz_open_image_decomp_stream_from_buffer(ctx, image->buffer, &native_l2factor);
- indexed = fz_colorspace_is_indexed(image->colorspace);
+ indexed = fz_colorspace_is_indexed(ctx, image->colorspace);
tile = fz_decomp_image_from_stream(ctx, stm, image, indexed, l2factor, native_l2factor);
/* CMYK JPEGs in XPS documents have to be inverted */
@@ -391,7 +379,7 @@ fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask)
fz_try(ctx)
{
image = fz_malloc_struct(ctx, fz_image);
- FZ_INIT_STORABLE(image, 1, fz_free_image);
+ FZ_INIT_STORABLE(image, 1, fz_drop_image_imp);
image->w = pixmap->w;
image->h = pixmap->h;
image->n = pixmap->n;
@@ -401,12 +389,11 @@ fz_new_image_from_pixmap(fz_context *ctx, fz_pixmap *pixmap, fz_image *mask)
image->get_pixmap = fz_image_get_pixmap;
image->xres = pixmap->xres;
image->yres = pixmap->yres;
- image->tile = pixmap;
+ image->tile = fz_keep_pixmap(ctx, pixmap);
image->mask = mask;
}
fz_catch(ctx)
{
- fz_drop_pixmap(ctx, pixmap);
fz_drop_image(ctx, mask);
fz_rethrow(ctx);
}
@@ -425,7 +412,7 @@ fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
fz_try(ctx)
{
image = fz_malloc_struct(ctx, fz_image);
- FZ_INIT_STORABLE(image, 1, fz_free_image);
+ FZ_INIT_STORABLE(image, 1, fz_drop_image_imp);
image->get_pixmap = fz_image_get_pixmap;
image->w = w;
image->h = h;
@@ -443,7 +430,7 @@ fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
memcpy(image->decode, decode, sizeof(float)*image->n*2);
else
{
- float maxval = fz_colorspace_is_indexed(colorspace) ? (1 << bpc) - 1 : 1;
+ float maxval = fz_colorspace_is_indexed(ctx, colorspace) ? (1 << bpc) - 1 : 1;
int i;
for (i = 0; i < image->n; i++)
{
@@ -456,7 +443,7 @@ fz_new_image(fz_context *ctx, int w, int h, int bpc, fz_colorspace *colorspace,
}
fz_catch(ctx)
{
- fz_free_compressed_buffer(ctx, buffer);
+ fz_drop_compressed_buffer(ctx, buffer);
fz_rethrow(ctx);
}
@@ -536,9 +523,49 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer)
}
fz_catch(ctx)
{
- fz_free_compressed_buffer(ctx, bc);
+ fz_drop_compressed_buffer(ctx, bc);
fz_rethrow(ctx);
}
return fz_new_image(ctx, w, h, 8, cspace, xres, yres, 0, 0, NULL, NULL, bc, NULL);
}
+
+void
+fz_image_get_sanitised_res(fz_image *image, int *xres, int *yres)
+{
+ *xres = image->xres;
+ *yres = image->yres;
+ if (*xres < 0 || *yres < 0 || (*xres == 0 && *yres == 0))
+ {
+ /* If neither xres or yres is sane, pick a sane value */
+ *xres = SANE_DPI; *yres = SANE_DPI;
+ }
+ else if (*xres == 0)
+ {
+ *xres = *yres;
+ }
+ else if (*yres == 0)
+ {
+ *yres = *xres;
+ }
+
+ /* Scale xres and yres up until we get beleivable values */
+ if (*xres < SANE_DPI || *yres < SANE_DPI)
+ {
+ if (*xres == *yres)
+ {
+ *xres = SANE_DPI;
+ *yres = SANE_DPI;
+ }
+ else if (*xres < *yres)
+ {
+ *yres = *yres * SANE_DPI / *xres;
+ *xres = SANE_DPI;
+ }
+ else
+ {
+ *xres = *xres * SANE_DPI / *yres;
+ *yres = SANE_DPI;
+ }
+ }
+}