From 531f7ea84daa607e370757d82d8bf7e300fc76b5 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 24 Oct 2017 16:00:54 +0200 Subject: Fix colorspace reference counting in fz_load_*_info. These are called from fz_new_image_from_buffer. --- source/fitz/image.c | 2 -- source/fitz/load-bmp.c | 2 +- source/fitz/load-gif.c | 3 +-- source/fitz/load-jpeg.c | 43 +++++++++++++++++++++---------------------- source/fitz/load-jpx.c | 2 +- source/fitz/load-jxr.c | 7 +++---- source/fitz/load-png.c | 6 ++---- source/fitz/load-pnm.c | 31 +++++++------------------------ source/fitz/load-tiff.c | 26 ++++++++++++++------------ 9 files changed, 50 insertions(+), 72 deletions(-) diff --git a/source/fitz/image.c b/source/fitz/image.c index b4fd2112..03038b2c 100644 --- a/source/fitz/image.c +++ b/source/fitz/image.c @@ -948,8 +948,6 @@ fz_new_image_from_buffer(fz_context *ctx, fz_buffer *buffer) if (len < 8) fz_throw(ctx, FZ_ERROR_GENERIC, "unknown image file format"); - /* Note: cspace is only ever a borrowed reference here */ - type = fz_recognize_image_format(ctx, buf); switch (type) { diff --git a/source/fitz/load-bmp.c b/source/fitz/load-bmp.c index 16953338..f41516d3 100644 --- a/source/fitz/load-bmp.c +++ b/source/fitz/load-bmp.c @@ -961,7 +961,7 @@ fz_load_bmp_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, bmp_read_image(ctx, &bmp, p, total, 1); - *cspacep = fz_device_rgb(ctx); + *cspacep = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); *wp = bmp.width; *hp = bmp.height; *xresp = bmp.xres / (1000.0f / 25.4f); diff --git a/source/fitz/load-gif.c b/source/fitz/load-gif.c index cc87ff84..25a37e3f 100644 --- a/source/fitz/load-gif.c +++ b/source/fitz/load-gif.c @@ -564,8 +564,7 @@ fz_load_gif_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, struct info gif; gif_read_image(ctx, &gif, p, total, 1); - - *cspacep = fz_device_rgb(ctx); + *cspacep = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); *wp = gif.width; *hp = gif.height; *xresp = gif.xres; diff --git a/source/fitz/load-jpeg.c b/source/fitz/load-jpeg.c index 266cfc80..810d49e0 100644 --- a/source/fitz/load-jpeg.c +++ b/source/fitz/load-jpeg.c @@ -145,7 +145,7 @@ static fz_colorspace *extract_icc_profile(fz_context *ctx, jpeg_saved_marker_ptr fz_always(ctx) fz_drop_buffer(ctx, buff); fz_catch(ctx) - fz_warn(ctx, "Failed to ICC Profile from JPEG"); + fz_warn(ctx, "could not load ICC profile in JPEG image"); return cs; } @@ -259,11 +259,12 @@ fz_load_jpeg(fz_context *ctx, const unsigned char *rbuf, size_t rlen) struct jpeg_error_mgr err; struct jpeg_source_mgr src; unsigned char *row[1], *sp, *dp; - fz_colorspace *colorspace, *cs = NULL; + fz_colorspace *colorspace, *icc; unsigned int x; int k, stride; fz_pixmap *image = NULL; + fz_var(colorspace); fz_var(image); fz_var(row); @@ -297,19 +298,18 @@ fz_load_jpeg(fz_context *ctx, const unsigned char *rbuf, size_t rlen) jpeg_start_decompress(&cinfo); - if (cinfo.output_components == 1) - colorspace = fz_device_gray(ctx); + icc = extract_icc_profile(ctx, cinfo.marker_list); + if (icc != NULL) + colorspace = icc; + else if (cinfo.output_components == 1) + colorspace = fz_keep_colorspace(ctx, fz_device_gray(ctx)); else if (cinfo.output_components == 3) - colorspace = fz_device_rgb(ctx); + colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); else if (cinfo.output_components == 4) - colorspace = fz_device_cmyk(ctx); + colorspace = fz_keep_colorspace(ctx, fz_device_cmyk(ctx)); else fz_throw(ctx, FZ_ERROR_GENERIC, "bad number of components in jpeg: %d", cinfo.num_components); - cs = extract_icc_profile(ctx, cinfo.marker_list); - if (cs != NULL) - colorspace = cs; - image = fz_new_pixmap(ctx, colorspace, cinfo.output_width, cinfo.output_height, NULL, 0); if (extract_exif_resolution(cinfo.marker_list, &image->xres, &image->yres)) @@ -378,7 +378,7 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr err; struct jpeg_source_mgr src; - fz_colorspace *cs = NULL; + fz_colorspace *icc; fz_try(ctx) { @@ -407,18 +407,21 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * jpeg_read_header(&cinfo, 1); - if (cinfo.num_components == 1) - *cspacep = fz_device_gray(ctx); + *xp = cinfo.image_width; + *yp = cinfo.image_height; + + icc = extract_icc_profile(ctx, cinfo.marker_list); + if (icc != NULL) + *cspacep = icc; + else if (cinfo.num_components == 1) + *cspacep = fz_keep_colorspace(ctx, fz_device_gray(ctx)); else if (cinfo.num_components == 3) - *cspacep = fz_device_rgb(ctx); + *cspacep = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); else if (cinfo.num_components == 4) - *cspacep = fz_device_cmyk(ctx); + *cspacep = fz_keep_colorspace(ctx, fz_device_cmyk(ctx)); else fz_throw(ctx, FZ_ERROR_GENERIC, "bad number of components in jpeg: %d", cinfo.num_components); - *xp = cinfo.image_width; - *yp = cinfo.image_height; - if (extract_exif_resolution(cinfo.marker_list, xresp, yresp)) /* XPS prefers EXIF resolution to JFIF density */; else if (extract_app13_resolution(cinfo.marker_list, xresp, yresp)) @@ -439,10 +442,6 @@ fz_load_jpeg_info(fz_context *ctx, const unsigned char *rbuf, size_t rlen, int * *yresp = 0; } - cs = extract_icc_profile(ctx, cinfo.marker_list); - if (cs != NULL) - *cspacep = cs; - if (*xresp <= 0) *xresp = 96; if (*yresp <= 0) *yresp = 96; } diff --git a/source/fitz/load-jpx.c b/source/fitz/load-jpx.c index b7ddd505..f2751a58 100644 --- a/source/fitz/load-jpx.c +++ b/source/fitz/load-jpx.c @@ -435,7 +435,7 @@ fz_load_jpx_info(fz_context *ctx, const unsigned char *data, size_t size, int *w jpx_read_image(ctx, &state, data, size, NULL, 1); - *cspacep = state.cs; + *cspacep = fz_keep_colorspace(ctx, state.cs); /* state.cs is a borrowed device colorspace */ *wp = state.width; *hp = state.height; *xresp = state.xres; diff --git a/source/fitz/load-jxr.c b/source/fitz/load-jxr.c index a83d7f6a..29877575 100644 --- a/source/fitz/load-jxr.c +++ b/source/fitz/load-jxr.c @@ -431,12 +431,11 @@ fz_load_jxr_info(fz_context *ctx, const unsigned char *data, size_t size, int *w struct info info = { 0 }; jxr_read_image(ctx, data, size, &info, 1); - - *xresp = info.xres; - *yresp = info.yres; + *cspacep = fz_keep_colorspace(ctx, info.cspace); /* info.cspace is a borrowed device colorspace */ *wp = info.width; *hp = info.height; - *cspacep = info.cspace; + *xresp = info.xres; + *yresp = info.yres; } #else /* HAVE_JPEGXR */ diff --git a/source/fitz/load-png.c b/source/fitz/load-png.c index 8015af6d..1df6559e 100644 --- a/source/fitz/load-png.c +++ b/source/fitz/load-png.c @@ -648,12 +648,10 @@ fz_load_png_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, struct info png; png_read_image(ctx, &png, p, total, 1); - *cspacep = fz_keep_colorspace(ctx, png.cs); + + *cspacep = png.cs; *wp = png.width; *hp = png.height; *xresp = png.xres; *yresp = png.xres; - - fz_drop_colorspace(ctx, png.cs); - fz_free(ctx, png.samples); } diff --git a/source/fitz/load-pnm.c b/source/fitz/load-pnm.c index 0a1fa3f4..95c613c0 100644 --- a/source/fitz/load-pnm.c +++ b/source/fitz/load-pnm.c @@ -623,35 +623,18 @@ pnm_read_image(fz_context *ctx, struct info *pnm, const unsigned char *p, size_t fz_pixmap * fz_load_pnm(fz_context *ctx, const unsigned char *p, size_t total) { - fz_pixmap *img = NULL; struct info pnm = { 0 }; - - fz_try(ctx) - img = pnm_read_image(ctx, &pnm, p, total, 0); - fz_always(ctx) - fz_drop_colorspace(ctx, pnm.cs); - fz_catch(ctx) - fz_rethrow(ctx); - - return img; + return pnm_read_image(ctx, &pnm, p, total, 0); } void fz_load_pnm_info(fz_context *ctx, const unsigned char *p, size_t total, int *wp, int *hp, int *xresp, int *yresp, fz_colorspace **cspacep) { struct info pnm = { 0 }; - - fz_try(ctx) - { - pnm_read_image(ctx, &pnm, p, total, 1); - *cspacep = pnm.cs; - *wp = pnm.width; - *hp = pnm.height; - *xresp = 72; - *yresp = 72; - } - fz_always(ctx) - fz_drop_colorspace(ctx, pnm.cs); - fz_catch(ctx) - fz_rethrow(ctx); + (void) pnm_read_image(ctx, &pnm, p, total, 1); + *cspacep = fz_keep_colorspace(ctx, pnm.cs); /* pnm.cs is a borrowed device colorspace */ + *wp = pnm.width; + *hp = pnm.height; + *xresp = 72; + *yresp = 72; } diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c index 6a8dd40e..80abd6f1 100644 --- a/source/fitz/load-tiff.c +++ b/source/fitz/load-tiff.c @@ -1157,36 +1157,36 @@ tiff_decode_ifd(fz_context *ctx, struct tiff *tiff) switch (tiff->photometric) { case 0: /* WhiteIsZero -- inverted */ - tiff->colorspace = fz_device_gray(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_gray(ctx)); break; case 1: /* BlackIsZero */ - tiff->colorspace = fz_device_gray(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_gray(ctx)); break; case 2: /* RGB */ - tiff->colorspace = fz_device_rgb(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); break; case 3: /* RGBPal */ - tiff->colorspace = fz_device_rgb(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); break; case 5: /* CMYK */ - tiff->colorspace = fz_device_cmyk(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_cmyk(ctx)); break; case 6: /* YCbCr */ /* it's probably a jpeg ... we let jpeg convert to rgb */ - tiff->colorspace = fz_device_rgb(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); break; case 8: /* Direct L*a*b* encoding. a*, b* signed values */ case 9: /* ICC Style L*a*b* encoding */ - tiff->colorspace = fz_device_lab(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_lab(ctx)); break; case 32844: /* SGI CIE Log 2 L (16bpp Greyscale) */ - tiff->colorspace = fz_device_gray(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_gray(ctx)); if (tiff->bitspersample != 8) tiff->bitspersample = 8; tiff->stride >>= 1; break; case 32845: /* SGI CIE Log 2 L, u, v (24bpp or 32bpp) */ - tiff->colorspace = fz_device_rgb(ctx); + tiff->colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); if (tiff->bitspersample != 8) tiff->bitspersample = 8; tiff->stride >>= 1; @@ -1416,9 +1416,11 @@ fz_load_tiff_info_subimage(fz_context *ctx, const unsigned char *buf, size_t len *xresp = (tiff.xresolution ? tiff.xresolution : 96); *yresp = (tiff.yresolution ? tiff.yresolution : 96); if (tiff.extrasamples /* == 2 */) - *cspacep = fz_device_rgb(ctx); - else - *cspacep = tiff.colorspace; + { + fz_drop_colorspace(ctx, tiff.colorspace); + tiff.colorspace = fz_keep_colorspace(ctx, fz_device_rgb(ctx)); + } + *cspacep = tiff.colorspace; } fz_always(ctx) { -- cgit v1.2.3