summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-08-12 14:17:15 +0000
committerTor Andersson <tor@ghostscript.com>2010-08-12 14:17:15 +0000
commit89365154d5cf23ed7cce262dbf799993899321c2 (patch)
treea8cb2124089d7d6c5b9ca7ed952fb7f6d2b8b11b
parent178c9fab191dd9f8c682eb0e8e4f54d9ba2c9923 (diff)
downloadmupdf-89365154d5cf23ed7cce262dbf799993899321c2.tar.xz
Remove pdf_image struct -- load images directly into fz_pixmaps instead.
-rw-r--r--apps/pdfextract.c23
-rw-r--r--fitz/filt_faxd.c4
-rw-r--r--fitz/filt_jpxd.c51
-rw-r--r--fitz/fitz.h3
-rw-r--r--fitz/res_pixmap.c3
-rw-r--r--mupdf/mupdf.h31
-rw-r--r--mupdf/pdf_build.c23
-rw-r--r--mupdf/pdf_image.c362
-rw-r--r--mupdf/pdf_interpret.c12
-rw-r--r--mupdf/pdf_store.c3
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, &params);
- 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 */
}
}