diff options
-rw-r--r-- | apps/pdfextract.c | 23 | ||||
-rw-r--r-- | fitz/filt_faxd.c | 4 | ||||
-rw-r--r-- | fitz/filt_jpxd.c | 51 | ||||
-rw-r--r-- | fitz/fitz.h | 3 | ||||
-rw-r--r-- | fitz/res_pixmap.c | 3 | ||||
-rw-r--r-- | mupdf/mupdf.h | 31 | ||||
-rw-r--r-- | mupdf/pdf_build.c | 23 | ||||
-rw-r--r-- | mupdf/pdf_image.c | 362 | ||||
-rw-r--r-- | mupdf/pdf_interpret.c | 12 | ||||
-rw-r--r-- | mupdf/pdf_store.c | 3 |
10 files changed, 245 insertions, 270 deletions
diff --git a/apps/pdfextract.c b/apps/pdfextract.c index cb10e117..ef7d94b2 100644 --- a/apps/pdfextract.c +++ b/apps/pdfextract.c @@ -39,8 +39,7 @@ static int isfontdesc(fz_obj *obj) static void saveimage(int num) { fz_error error; - pdf_image *img; - fz_pixmap *pix; + fz_pixmap *img; fz_obj *ref; char name[1024]; @@ -52,33 +51,29 @@ static void saveimage(int num) if (error) die(error); - pix = pdf_loadtile(img); - if (dorgb && img->colorspace && img->colorspace != fz_devicergb) { fz_pixmap *temp; - temp = fz_newpixmap(fz_devicergb, pix->x, pix->y, pix->w, pix->h); - fz_convertpixmap(pix, temp); - fz_droppixmap(pix); - pix = temp; + temp = fz_newpixmap(fz_devicergb, img->x, img->y, img->w, img->h); + fz_convertpixmap(img, temp); + fz_droppixmap(img); + img = temp; } - if (pix->n <= 4) + if (img->n <= 4) { sprintf(name, "img-%04d.png", num); printf("extracting image %s\n", name); - fz_writepng(pix, name, 0); + fz_writepng(img, name, 0); } else { sprintf(name, "img-%04d.pam", num); printf("extracting image %s\n", name); - fz_writepam(pix, name, 0); + fz_writepam(img, name, 0); } - fz_droppixmap(pix); - pdf_dropimage(img); - + fz_droppixmap(img); fz_dropobj(ref); } diff --git a/fitz/filt_faxd.c b/fitz/filt_faxd.c index 4a732091..fb9b4c52 100644 --- a/fitz/filt_faxd.c +++ b/fitz/filt_faxd.c @@ -683,6 +683,10 @@ eol: eatbits(fax, (8 - fax->bidx) & 7); } + /* no more space in output, don't decode the next row yet */ + if (p == buf + len) + return p - buf; + goto loop; rtc: diff --git a/fitz/filt_jpxd.c b/fitz/filt_jpxd.c index 34f68444..3ec06ab3 100644 --- a/fitz/filt_jpxd.c +++ b/fitz/filt_jpxd.c @@ -1,5 +1,4 @@ #include "fitz.h" -#include "mupdf.h" #define OPJ_STATIC #include <openjpeg.h> @@ -16,40 +15,29 @@ static void fz_opj_warning_callback(const char *msg, void *client_data) static void fz_opj_info_callback(const char *msg, void *client_data) { - char buf[80]; - int len = fz_strlcpy(buf, msg, sizeof buf); - if (len > 0) buf[len-1] = 0; - pdf_logimage("%s\n", buf); + /* fprintf(stderr, "openjpeg info: %s", msg); */ } fz_error -pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) +fz_loadjpximage(fz_pixmap **imgp, unsigned char *data, int size) { - pdf_image *img; + fz_pixmap *img; opj_event_mgr_t evtmgr; opj_dparameters_t params; opj_dinfo_t *info; opj_cio_t *cio; opj_image_t *jpx; - fz_error error; - fz_buffer *buf; + fz_colorspace *colorspace; unsigned char *p; int format; int n, w, h, depth, sgnd; int x, y, k, v; - error = pdf_loadstream(&buf, xref, fz_tonum(dict), fz_togen(dict)); - if (error) - return fz_throw("read error in jpx image"); - - if (buf->len < 2) - { - fz_dropbuffer(buf); + if (size < 2) return fz_throw("not enough data to determine image format"); - } /* Check for SOC marker -- if found we have a bare J2K stream */ - if (buf->data[0] == 0xFF && buf->data[1] == 0x4F) + if (data[0] == 0xFF && data[1] == 0x4F) format = CODEC_J2K; else format = CODEC_JP2; @@ -65,13 +53,12 @@ pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) opj_set_event_mgr((opj_common_ptr)info, &evtmgr, stderr); opj_setup_decoder(info, ¶ms); - cio = opj_cio_open((opj_common_ptr)info, buf->data, buf->len); + cio = opj_cio_open((opj_common_ptr)info, data, size); jpx = opj_decode(info, cio); opj_cio_close(cio); opj_destroy_decompress(info); - fz_dropbuffer(buf); if (!jpx) return fz_throw("opj_decode failed"); @@ -92,33 +79,18 @@ pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) depth = jpx->comps[0].prec; sgnd = jpx->comps[0].sgnd; - img = fz_malloc(sizeof(pdf_image)); - memset(img, 0, sizeof(pdf_image)); - img->refs = 1; - img->w = w; - img->h = h; - img->bpc = 8; - img->n = n; - img->stride = w * n; - img->samples = fz_malloc(w * n * h); - switch (n) { - case 1: img->colorspace = fz_devicegray; break; - case 3: img->colorspace = fz_devicergb; break; - case 4: img->colorspace = fz_devicecmyk; break; + case 1: colorspace = fz_devicegray; break; + case 3: colorspace = fz_devicergb; break; + case 4: colorspace = fz_devicecmyk; break; default: /* TODO: SMaskInData */ opj_image_destroy(jpx); - fz_free(img); return fz_throw("unknown jpx colorspace (%d components)", n); } - for (k = 0; k < n; k++) - { - img->decode[k * 2] = 0; - img->decode[k * 2 + 1] = 1; - } + img = fz_newpixmap(colorspace, 0, 0, w, h); p = img->samples; for (y = 0; y < h; y++) @@ -134,6 +106,7 @@ pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) v = v >> (depth - 8); *p++ = v; } + *p++ = 255; /* TODO: SMaskInData */ } } diff --git a/fitz/fitz.h b/fitz/fitz.h index 8cd351ae..9671c46d 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -591,6 +591,7 @@ struct fz_pixmap_s { int refs; int x, y, w, h, n; + fz_pixmap *mask; /* explicit soft/image mask */ fz_colorspace *colorspace; unsigned char *samples; }; @@ -611,6 +612,8 @@ fz_error fz_writepnm(fz_pixmap *pixmap, char *filename); fz_error fz_writepam(fz_pixmap *pixmap, char *filename, int savealpha); fz_error fz_writepng(fz_pixmap *pixmap, char *filename, int savealpha); +fz_error fz_loadjpximage(fz_pixmap **imgp, unsigned char *data, int size); + /* * Colorspace resources. */ diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c index 4599fb0c..652d0426 100644 --- a/fitz/res_pixmap.c +++ b/fitz/res_pixmap.c @@ -11,6 +11,7 @@ fz_newpixmap(fz_colorspace *colorspace, int x, int y, int w, int h) pix->y = y; pix->w = w; pix->h = h; + pix->mask = nil; pix->colorspace = nil; pix->n = 1; @@ -43,6 +44,8 @@ fz_droppixmap(fz_pixmap *pix) { if (pix && --pix->refs == 0) { + if (pix->mask) + fz_droppixmap(pix->mask); if (pix->colorspace) fz_dropcolorspace(pix->colorspace); fz_free(pix->samples); diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index 0963a2fd..a62ccc6c 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -255,31 +255,8 @@ void pdf_dropxobject(pdf_xobject *xobj); * Image */ -typedef struct pdf_image_s pdf_image; - -struct pdf_image_s -{ - int refs; - int w, h, bpc, n; - int imagemask; - int interpolate; - fz_colorspace *colorspace; - int indexed; - pdf_image *mask; /* explicit mask/softmask image */ - int usecolorkey; /* color-keyed masking */ - int colorkey[FZ_MAXCOLORS * 2]; - float decode[FZ_MAXCOLORS * 2]; - int stride; - unsigned char *samples; -}; - -fz_error pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); -fz_error pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *obj); -fz_pixmap *pdf_loadtile(pdf_image *image); -pdf_image *pdf_keepimage(pdf_image *img); -void pdf_dropimage(pdf_image *img); - -fz_error pdf_loadjpximage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict); +fz_error pdf_loadinlineimage(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file); +fz_error pdf_loadimage(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *obj); /* * CMap @@ -628,8 +605,8 @@ void pdf_setshade(pdf_csi *csi, int what, fz_shade *shade); void pdf_showpath(pdf_csi*, int close, int fill, int stroke, int evenodd); void pdf_showtext(pdf_csi*, fz_obj *text); void pdf_flushtext(pdf_csi*); -void pdf_showimage(pdf_csi*, pdf_image *img); -void pdf_showshade(pdf_csi*, fz_shade *shd); +void pdf_showimage(pdf_csi*, fz_pixmap *image); +void pdf_showshade(pdf_csi*, fz_shade *shade); /* interpret.c */ void pdf_gsave(pdf_csi *csi); diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c index 9c2bd2c7..589f638b 100644 --- a/mupdf/pdf_build.c +++ b/mupdf/pdf_build.c @@ -240,10 +240,9 @@ pdf_showshade(pdf_csi *csi, fz_shade *shd) } void -pdf_showimage(pdf_csi *csi, pdf_image *image) +pdf_showimage(pdf_csi *csi, fz_pixmap *image) { pdf_gstate *gstate = csi->gstate + csi->gtop; - fz_pixmap *tile, *mask; fz_rect bbox; bbox = fz_transformrect(gstate->ctm, fz_unitrect); @@ -252,15 +251,9 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1); if (image->mask) - { - mask = pdf_loadtile(image->mask); - csi->dev->clipimagemask(csi->dev->user, mask, gstate->ctm); - fz_droppixmap(mask); - } + csi->dev->clipimagemask(csi->dev->user, image->mask, gstate->ctm); - tile = pdf_loadtile(image); - - if (image->imagemask) + if (!image->colorspace) { switch (gstate->fill.kind) @@ -268,13 +261,13 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) case PDF_MNONE: break; case PDF_MCOLOR: - csi->dev->fillimagemask(csi->dev->user, tile, gstate->ctm, + csi->dev->fillimagemask(csi->dev->user, image, gstate->ctm, gstate->fill.cs, gstate->fill.v, gstate->fill.alpha); break; case PDF_MPATTERN: if (gstate->fill.pattern) { - csi->dev->clipimagemask(csi->dev->user, tile, gstate->ctm); + csi->dev->clipimagemask(csi->dev->user, image, gstate->ctm); pdf_showpattern(csi, gstate->fill.pattern, bbox, PDF_MFILL); csi->dev->popclip(csi->dev->user); } @@ -282,7 +275,7 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) case PDF_MSHADE: if (gstate->fill.shade) { - csi->dev->clipimagemask(csi->dev->user, tile, gstate->ctm); + csi->dev->clipimagemask(csi->dev->user, image, gstate->ctm); csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm, gstate->fill.alpha); csi->dev->popclip(csi->dev->user); } @@ -291,7 +284,7 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) } else { - csi->dev->fillimage(csi->dev->user, tile, gstate->ctm, gstate->fill.alpha); + csi->dev->fillimage(csi->dev->user, image, gstate->ctm, gstate->fill.alpha); } if (image->mask) @@ -299,8 +292,6 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) if (gstate->blendmode != FZ_BNORMAL) csi->dev->endgroup(csi->dev->user); - - fz_droppixmap(tile); } void diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c index 5ae6508f..946590d0 100644 --- a/mupdf/pdf_image.c +++ b/mupdf/pdf_image.c @@ -1,63 +1,74 @@ #include "fitz.h" #include "mupdf.h" -/* TODO: special case JPXDecode image loading */ /* TODO: store JPEG compressed samples */ /* TODO: store flate compressed samples */ -pdf_image * -pdf_keepimage(pdf_image *image) -{ - image->refs ++; - return image; -} - -void -pdf_dropimage(pdf_image *img) +static void +pdf_maskcolorkey(fz_pixmap *pix, int n, int *colorkey) { - if (img && --img->refs == 0) + unsigned char *p = pix->samples; + int len = pix->w * pix->h; + int k, t; + while (len--) { - if (img->colorspace) - fz_dropcolorspace(img->colorspace); - if (img->mask) - pdf_dropimage(img->mask); - if (img->samples) - fz_free(img->samples); - fz_free(img); + t = 1; + for (k = 0; k < n; k++) + if (p[k] < colorkey[k * 2] || p[k] > colorkey[k * 2 + 1]) + t = 0; + if (t) + for (k = 0; k < pix->n; k++) + p[k] = 0; + p += pix->n; } } static fz_error -pdf_loadimageimp(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm) +pdf_loadimageimp(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm) { - pdf_image *img; fz_stream *stm; - fz_error error; + fz_pixmap *tile; fz_obj *obj, *res; - int i, n; - - img = fz_malloc(sizeof(pdf_image)); - memset(img, 0, sizeof(pdf_image)); - - img->refs = 1; - img->w = fz_toint(fz_dictgetsa(dict, "Width", "W")); - img->h = fz_toint(fz_dictgetsa(dict, "Height", "H")); - img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); - img->imagemask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); - img->interpolate = fz_tobool(fz_dictgetsa(dict, "Interpolate", "I")); + fz_error error; - if (img->imagemask) - img->bpc = 1; + int w, h, bpc, n; + int imagemask; + int interpolate; + int indexed; + fz_colorspace *colorspace; + fz_pixmap *mask; /* explicit mask/softmask image */ + int usecolorkey; + int colorkey[FZ_MAXCOLORS * 2]; + float decode[FZ_MAXCOLORS * 2]; - if (img->w == 0) - fz_warn("image width is zero"); - if (img->h == 0) - fz_warn("image height is zero"); - if (img->bpc == 0) - img->bpc = 8; /* for JPX */ + int scale; + int stride; + unsigned char *samples; + int i, len; + + w = fz_toint(fz_dictgetsa(dict, "Width", "W")); + h = fz_toint(fz_dictgetsa(dict, "Height", "H")); + bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC")); + imagemask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM")); + interpolate = fz_tobool(fz_dictgetsa(dict, "Interpolate", "I")); + + indexed = 0; + usecolorkey = 0; + colorspace = nil; + mask = nil; + + if (imagemask) + bpc = 1; + + if (w == 0) + return fz_throw("image width is zero"); + if (h == 0) + return fz_throw("image height is zero"); + if (bpc == 0) + return fz_throw("image depth is zero"); obj = fz_dictgetsa(dict, "ColorSpace", "CS"); - if (obj) + if (obj && !imagemask) { if (fz_isname(obj)) { @@ -66,133 +77,177 @@ pdf_loadimageimp(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz obj = res; } - error = pdf_loadcolorspace(&img->colorspace, xref, obj); + error = pdf_loadcolorspace(&colorspace, xref, obj); if (error) - { - pdf_dropimage(img); return fz_rethrow(error, "cannot load image colorspace"); - } - if (!strcmp(img->colorspace->name, "Indexed")) - img->indexed = 1; + if (!strcmp(colorspace->name, "Indexed")) + indexed = 1; - img->n = img->colorspace->n; + n = colorspace->n; } else { - img->n = 1; + n = 1; } obj = fz_dictgetsa(dict, "Decode", "D"); if (obj) { - for (i = 0; i < img->n * 2; i++) - img->decode[i] = fz_toreal(fz_arrayget(obj, i)); + for (i = 0; i < n * 2; i++) + decode[i] = fz_toreal(fz_arrayget(obj, i)); } else { - float maxval = img->indexed ? (1 << img->bpc) - 1 : 1; - for (i = 0; i < img->n * 2; i++) - img->decode[i] = i & 1 ? maxval : 0; + float maxval = indexed ? (1 << bpc) - 1 : 1; + for (i = 0; i < n * 2; i++) + decode[i] = i & 1 ? maxval : 0; } - /* Not allowed for inline images */ obj = fz_dictgetsa(dict, "SMask", "Mask"); if (fz_isdict(obj)) { - error = pdf_loadimage(&img->mask, xref, rdb, obj); - if (error) + /* Not allowed for inline images */ + if (!cstm) { - pdf_dropimage(img); - return fz_rethrow(error, "cannot load image mask/softmask"); - } - img->mask->imagemask = 1; - if (img->mask->colorspace) - { - fz_dropcolorspace(img->mask->colorspace); - img->mask->colorspace = nil; + error = pdf_loadimage(&mask, xref, rdb, obj); + if (error) + { + if (colorspace) + fz_dropcolorspace(colorspace); + return fz_rethrow(error, "cannot load image mask/softmask"); + } } } else if (fz_isarray(obj)) { - img->usecolorkey = 1; - for (i = 0; i < img->n * 2; i++) - img->colorkey[i] = fz_toint(fz_arrayget(obj, i)); - } - - if (img->imagemask) - { - if (img->colorspace) - { - fz_dropcolorspace(img->colorspace); - img->colorspace = nil; - } + usecolorkey = 1; + for (i = 0; i < n * 2; i++) + colorkey[i] = fz_toint(fz_arrayget(obj, i)); } - img->stride = (img->w * img->n * img->bpc + 7) / 8; - img->samples = fz_malloc(img->h * img->stride); + stride = (w * n * bpc + 7) / 8; + samples = fz_malloc(h * stride); if (cstm) { - stm = pdf_openinlinestream(cstm, xref, dict, img->stride * img->h); + stm = pdf_openinlinestream(cstm, xref, dict, stride * h); } else { error = pdf_openstream(&stm, xref, fz_tonum(dict), fz_togen(dict)); if (error) { - pdf_dropimage(img); + if (colorspace) + fz_dropcolorspace(colorspace); + if (mask) + fz_droppixmap(mask); return fz_rethrow(error, "cannot open image data stream (%d 0 R)", fz_tonum(dict)); } } - n = fz_read(stm, img->samples, img->h * img->stride); - if (n < 0) + len = fz_read(stm, samples, h * stride); + if (len < 0) { fz_close(stm); - pdf_dropimage(img); + if (colorspace) + fz_dropcolorspace(colorspace); + if (mask) + fz_droppixmap(mask); return fz_rethrow(n, "cannot read image data"); } + /* Make sure we read the EOF marker (for inline images only) */ + if (cstm) + { + unsigned char tbuf[512]; + int tlen = fz_read(stm, tbuf, sizeof tbuf); + if (tlen < 0) + fz_catch(tlen, "ignoring error at end of image"); + if (tlen > 0) + fz_warn("ignoring garbage at end of image"); + } + fz_close(stm); /* Pad truncated images */ - if (n < img->stride * img->h) + if (len < stride * h) { fz_warn("padding truncated image (%d 0 R)", fz_tonum(dict)); - memset(img->samples + n, 0, img->stride * img->h - n); + memset(samples + len, 0, stride * h - len); } - if (img->imagemask) + /* Invert 1-bit image masks */ + if (imagemask) { /* 0=opaque and 1=transparent so we need to invert */ - unsigned char *p = img->samples; - n = img->h * img->stride; - for (i = 0; i < n; i++) + unsigned char *p = samples; + len = h * stride; + for (i = 0; i < len; i++) p[i] = ~p[i]; } - pdf_logimage("size %dx%d n=%d bpc=%d (imagemask=%d)\n", img->w, img->h, img->n, img->bpc, img->imagemask); + pdf_logimage("size %dx%d n=%d bpc=%d imagemask=%d indexed=%d\n", w, h, n, bpc, imagemask, indexed); - *imgp = img; + /* Unpack samples into pixmap */ + + tile = fz_newpixmap(colorspace, 0, 0, w, h); + + tile->mask = mask; + + scale = 1; + if (!indexed) + { + switch (bpc) + { + case 1: scale = 255; break; + case 2: scale = 85; break; + case 4: scale = 17; break; + } + } + + fz_unpacktile(tile, samples, n, bpc, stride, scale); + + if (usecolorkey) + pdf_maskcolorkey(tile, n, colorkey); + + if (indexed) + { + fz_pixmap *conv; + + fz_decodeindexedtile(tile, decode, (1 << bpc) - 1); + + conv = pdf_expandindexedpixmap(tile); + fz_droppixmap(tile); + tile = conv; + } + else + { + fz_decodetile(tile, decode); + } + + if (colorspace) + fz_dropcolorspace(colorspace); + + fz_free(samples); + + *imgp = tile; return fz_okay; } fz_error -pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file) +pdf_loadinlineimage(fz_pixmap **pixp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file) { fz_error error; - pdf_image *img; pdf_logimage("load inline image {\n"); - error = pdf_loadimageimp(&img, xref, rdb, dict, file); + error = pdf_loadimageimp(pixp, xref, rdb, dict, file); if (error) return fz_rethrow(error, "cannot load inline image"); pdf_logimage("}\n"); - - *imgp = img; + return fz_okay; } @@ -208,101 +263,76 @@ pdf_isjpximage(fz_obj *filter) return 0; } -fz_error -pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) +static fz_error +pdf_loadjpximage(fz_pixmap **imgp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { fz_error error; - pdf_image *img; + fz_buffer *buf; + fz_pixmap *img; fz_obj *obj; - if ((*imgp = pdf_finditem(xref->store, pdf_dropimage, dict))) - { - pdf_keepimage(*imgp); - return fz_okay; - } + pdf_logimage("jpeg2000\n"); - pdf_logimage("load image (%d %d R) {\n", fz_tonum(dict), fz_togen(dict)); + error = pdf_loadstream(&buf, xref, fz_tonum(dict), fz_togen(dict)); + if (error) + return fz_rethrow(error, "cannot load jpx image data"); - /* special case for JPEG2000 images */ - obj = fz_dictgets(dict, "Filter"); - if (pdf_isjpximage(obj)) + error = fz_loadjpximage(&img, buf->data, buf->len); + if (error) { - error = pdf_loadjpximage(&img, xref, rdb, dict); - if (error) - return fz_rethrow(error, "cannot load jpx image"); + fz_dropbuffer(buf); + return fz_rethrow(error, "cannot load jpx image"); } - else + + fz_dropbuffer(buf); + + obj = fz_dictgetsa(dict, "SMask", "Mask"); + if (fz_isdict(obj)) { - error = pdf_loadimageimp(&img, xref, rdb, dict, nil); + error = pdf_loadimage(&img->mask, xref, rdb, obj); if (error) - return fz_rethrow(error, "cannot load image (%d %d R)", fz_tonum(dict), fz_togen(dict)); + { + fz_droppixmap(img); + return fz_rethrow(error, "cannot load image mask/softmask"); + } } - pdf_storeitem(xref->store, pdf_keepimage, pdf_dropimage, dict, img); - - pdf_logimage("}\n"); - *imgp = img; return fz_okay; } -static void -pdf_maskcolorkey(fz_pixmap *pix, int n, int *colorkey) -{ - unsigned char *p = pix->samples; - int len = pix->w * pix->h; - int k, t; - while (len--) - { - t = 1; - for (k = 0; k < n; k++) - if (p[k] < colorkey[k * 2] || p[k] > colorkey[k * 2 + 1]) - t = 0; - if (t) - for (k = 0; k < pix->n; k++) - p[k] = 0; - p += pix->n; - } -} - -fz_pixmap * -pdf_loadtile(pdf_image *img /* ...bbox/y+h should go here... */) +fz_error +pdf_loadimage(fz_pixmap **pixp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict) { - fz_pixmap *tile; - int scale; - - tile = fz_newpixmap(img->colorspace, 0, 0, img->w, img->h); + fz_error error; + fz_obj *obj; - scale = 1; - if (!img->indexed) + if ((*pixp = pdf_finditem(xref->store, fz_droppixmap, dict))) { - switch (img->bpc) - { - case 1: scale = 255; break; - case 2: scale = 85; break; - case 4: scale = 17; break; - } + fz_keeppixmap(*pixp); + return fz_okay; } - fz_unpacktile(tile, img->samples, img->n, img->bpc, img->stride, scale); - - if (img->usecolorkey) - pdf_maskcolorkey(tile, img->n, img->colorkey); + pdf_logimage("load image (%d 0 R) {\n", fz_tonum(dict)); - if (img->indexed) + /* special case for JPEG2000 images */ + obj = fz_dictgets(dict, "Filter"); + if (pdf_isjpximage(obj)) { - fz_pixmap *conv; - - fz_decodeindexedtile(tile, img->decode, (1 << img->bpc) - 1); - - conv = pdf_expandindexedpixmap(tile); - fz_droppixmap(tile); - tile = conv; + error = pdf_loadjpximage(pixp, xref, rdb, dict); + if (error) + return fz_rethrow(error, "cannot load jpx image (%d 0 R)", fz_tonum(dict)); } else { - fz_decodetile(tile, img->decode); + error = pdf_loadimageimp(pixp, xref, rdb, dict, nil); + if (error) + return fz_rethrow(error, "cannot load image (%d 0 R)", fz_tonum(dict)); } - return tile; + pdf_storeitem(xref->store, fz_keeppixmap, fz_droppixmap, dict, *pixp); + + pdf_logimage("}\n"); + + return fz_okay; } diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index 0bb15669..f33a7ef4 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -231,7 +231,7 @@ static fz_error pdf_runinlineimage(pdf_csi *csi, fz_obj *rdb, fz_stream *file, fz_obj *dict) { fz_error error; - pdf_image *img; + fz_pixmap *img; char buf[256]; pdf_token_e tok; int len; @@ -243,19 +243,19 @@ pdf_runinlineimage(pdf_csi *csi, fz_obj *rdb, fz_stream *file, fz_obj *dict) error = pdf_lex(&tok, file, buf, sizeof buf, &len); if (error) { - pdf_dropimage(img); + fz_droppixmap(img); return fz_rethrow(error, "syntax error after inline image"); } if (tok != PDF_TKEYWORD || strcmp("EI", buf)) { - pdf_dropimage(img); + fz_droppixmap(img); return fz_throw("syntax error after inline image"); } pdf_showimage(csi, img); - pdf_dropimage(img); + fz_droppixmap(img); return fz_okay; } @@ -548,12 +548,12 @@ Lsetcolorspace: { if ((csi->dev->hints & FZ_IGNOREIMAGE) == 0) { - pdf_image *img; + fz_pixmap *img; error = pdf_loadimage(&img, csi->xref, rdb, obj); if (error) return fz_rethrow(error, "cannot load image (%d %d R)", fz_tonum(obj), fz_togen(obj)); pdf_showimage(csi, img); - pdf_dropimage(img); + fz_droppixmap(img); } } diff --git a/mupdf/pdf_store.c b/mupdf/pdf_store.c index 481c3d22..1364bb86 100644 --- a/mupdf/pdf_store.c +++ b/mupdf/pdf_store.c @@ -157,7 +157,6 @@ pdf_agestore(pdf_store *store, int maxage) for (i = 0; i < fz_hashlen(store->hash); i++) { -again: refkey = fz_hashgetkey(store->hash, i); item = fz_hashgetval(store->hash, i); if (item && ++item->age > maxage) @@ -166,7 +165,7 @@ again: ((void(*)(void*))item->dropfunc)(item->val); fz_dropobj(item->key); fz_free(item); - goto again; /* items with same hash may move into place */ + i--; /* items with same hash may move into place */ } } |