summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile1
-rw-r--r--include/fitz/image.h2
-rw-r--r--include/fitz/object.h1
-rw-r--r--include/mupdf/rsrc.h3
-rw-r--r--include/mupdf/xref.h1
-rw-r--r--mupdf/build.c26
-rw-r--r--mupdf/colorspace.c21
-rw-r--r--mupdf/image.c157
-rw-r--r--mupdf/interpret.c143
-rw-r--r--mupdf/parse.c4
-rw-r--r--mupdf/resources.c113
-rw-r--r--mupdf/stream.c31
-rw-r--r--mupdf/xobject.c65
-rw-r--r--object/dict.c10
-rw-r--r--render/render.c4
15 files changed, 440 insertions, 142 deletions
diff --git a/Jamfile b/Jamfile
index 6e2f2c2a..2576ed77 100644
--- a/Jamfile
+++ b/Jamfile
@@ -111,6 +111,7 @@ Library libmupdf :
mupdf/fontfile.c
mupdf/colorspace.c
mupdf/image.c
+ mupdf/xobject.c
mupdf/resources.c
mupdf/page.c
mupdf/build.c
diff --git a/include/fitz/image.h b/include/fitz/image.h
index 13d4d096..cfbba169 100644
--- a/include/fitz/image.h
+++ b/include/fitz/image.h
@@ -10,3 +10,5 @@ struct fz_image_s
int w, h, n, a;
};
+void fz_dropimage(fz_image *img);
+
diff --git a/include/fitz/object.h b/include/fitz/object.h
index 520fa27f..e275074b 100644
--- a/include/fitz/object.h
+++ b/include/fitz/object.h
@@ -106,6 +106,7 @@ fz_obj *fz_dictgetkey(fz_obj *dict, int idx);
fz_obj *fz_dictgetval(fz_obj *dict, int idx);
fz_obj *fz_dictget(fz_obj *dict, fz_obj *key);
fz_obj *fz_dictgets(fz_obj *dict, char *key);
+fz_obj *fz_dictgetsa(fz_obj *dict, char *key, char *abbrev);
fz_error *fz_dictput(fz_obj *dict, fz_obj *key, fz_obj *val);
fz_error *fz_dictputs(fz_obj *dict, char *key, fz_obj *val);
fz_error *fz_dictdel(fz_obj *dict, fz_obj *key);
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 8277c5cc..9dc12acd 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -58,7 +58,7 @@ struct pdf_xobject_s
fz_buffer *contents;
};
-fz_error *pdf_loadxobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj);
+fz_error *pdf_loadxobject(pdf_xobject **xobjp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
void pdf_dropxobject(pdf_xobject *xobj);
/*
@@ -78,6 +78,7 @@ struct pdf_image_s
fz_buffer *samples;
};
+fz_error *pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_file *file);
fz_error *pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *obj, fz_obj *stm);
/*
diff --git a/include/mupdf/xref.h b/include/mupdf/xref.h
index d7d2e156..ac01ca9d 100644
--- a/include/mupdf/xref.h
+++ b/include/mupdf/xref.h
@@ -57,6 +57,7 @@ fz_error *pdf_loadobject(fz_obj **objp, pdf_xref *, int oid, int gen);
fz_error *pdf_loadindirect(fz_obj **objp, pdf_xref *, fz_obj *ref);
fz_error *pdf_resolve(fz_obj **reforobj, pdf_xref *);
+fz_error *pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj);
int pdf_isstream(pdf_xref *xref, int oid, int gen);
fz_error *pdf_loadrawstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen);
fz_error *pdf_loadstream(fz_buffer **bufp, pdf_xref *xref, int oid, int gen);
diff --git a/mupdf/build.c b/mupdf/build.c
index 448d2db4..7c52ccab 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -236,24 +236,38 @@ fz_error *
pdf_showimage(pdf_csi *csi, pdf_image *img)
{
fz_error *error;
- fz_node *node;
+ fz_node *mask;
+ fz_node *color;
+ fz_node *shape;
- error = fz_newimagenode(&node, (fz_image*)img);
+ error = fz_newimagenode(&color, (fz_image*)img);
if (error)
return error;
if (img->super.n == 0 && img->super.a == 1)
{
- error = pdf_addfillshape(csi->gstate + csi->gtop, node);
+ error = pdf_addfillshape(csi->gstate + csi->gtop, color);
if (error) {
- fz_dropnode(node);
+ fz_dropnode(color);
return error;
}
}
else
{
- /* TODO image mask sub-image */
- fz_insertnode(csi->gstate[csi->gtop].head, node);
+ if (img->mask)
+ {
+ error = fz_newimagenode(&shape, (fz_image*)img->mask);
+ if (error) return error;
+ error = fz_newmasknode(&mask);
+ if (error) return error;
+ fz_insertnode(mask, shape);
+ fz_insertnode(mask, color);
+ fz_insertnode(csi->gstate[csi->gtop].head, mask);
+ }
+ else
+ {
+ fz_insertnode(csi->gstate[csi->gtop].head, color);
+ }
}
return nil;
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index 5c2ae10f..28c34692 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -707,6 +707,24 @@ printf("\n");
*csp = pdf_devicecmyk;
return nil;
}
+
+ if (!strcmp(fz_toname(obj), "G"))
+ {
+ *csp = pdf_devicegray;
+ return nil;
+ }
+
+ if (!strcmp(fz_toname(obj), "RGB"))
+ {
+ *csp = pdf_devicergb;
+ return nil;
+ }
+
+ if (!strcmp(fz_toname(obj), "CMYK"))
+ {
+ *csp = pdf_devicecmyk;
+ return nil;
+ }
}
else if (fz_isarray(obj))
@@ -736,6 +754,9 @@ printf("\n");
if (!strcmp(fz_toname(name), "Indexed"))
return loadindexed(csp, xref, obj);
+ if (!strcmp(fz_toname(name), "I"))
+ return loadindexed(csp, xref, obj);
+
if (!strcmp(fz_toname(name), "Separation"))
return loadseparation(csp, xref, obj);
diff --git a/mupdf/image.c b/mupdf/image.c
index c30fb780..044307eb 100644
--- a/mupdf/image.c
+++ b/mupdf/image.c
@@ -1,6 +1,14 @@
#include <fitz.h>
#include <mupdf.h>
+void pdf_dropimage(fz_image *fzimg)
+{
+ pdf_image *img = (pdf_image*)fzimg;
+ fz_dropbuffer(img->samples);
+ if (img->mask)
+ fz_dropimage(img->mask);
+}
+
static inline int getbit(const unsigned char *buf, int x)
{
return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
@@ -95,10 +103,6 @@ printf(" decode bpc=%d skip=%d n=%d twon=%g\n", bpc, skip, pix->n, twon);
}
}
-// for (i = 0; i < 256; i++)
-// for (k = 0; k < 32; k++)
-// table[k][i] = i;
-
for (y = 0; y < pix->h; y++)
{
for (x = 0; x < pix->w; x++)
@@ -143,6 +147,7 @@ loadtile(fz_image *img, fz_pixmap *tile)
return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
}
+printf(" unpack n=%d\n", tile->n);
for (y = 0; y < tile->h; y++)
{
for (x = 0; x < tile->w; x++)
@@ -194,12 +199,116 @@ loadtile(fz_image *img, fz_pixmap *tile)
return nil;
}
+fz_error *
+pdf_loadinlineimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_file *file)
+{
+ fz_error *error;
+ pdf_image *img;
+ fz_filter *filter;
+ fz_obj *cs;
+ fz_obj *d;
+ int ismask;
+ int i;
+
+ img = *imgp = fz_malloc(sizeof(pdf_image));
+ if (!img)
+ return fz_outofmem;
+
+printf("inline image ");fz_debugobj(dict);printf("\n");
+
+ img->super.loadtile = loadtile;
+ img->super.drop = pdf_dropimage;
+ img->super.n = 0;
+ img->super.a = 0;
+ img->indexed = nil;
+
+ img->super.w = fz_toint(fz_dictgetsa(dict, "Width", "W"));
+ img->super.h = fz_toint(fz_dictgetsa(dict, "Height", "H"));
+ img->bpc = fz_toint(fz_dictgetsa(dict, "BitsPerComponent", "BPC"));
+ ismask = fz_tobool(fz_dictgetsa(dict, "ImageMask", "IM"));
+ d = fz_dictgetsa(dict, "Decode", "D");
+ cs = fz_dictgetsa(dict, "ColorSpace", "CS");
+
+ if (ismask)
+ {
+ img->super.n = 0;
+ img->super.a = 1;
+ img->bpc = 1;
+ }
+
+ if (cs)
+ {
+ error = pdf_loadcolorspace(&img->super.cs, xref, cs);
+ if (error)
+ return error;
+ img->super.n = img->super.cs->n;
+ img->super.a = 0;
+ if (!strcmp(img->super.cs->name, "Indexed"))
+ {
+printf(" indexed!\n");
+ img->indexed = (pdf_indexed*)img->super.cs;
+ img->super.cs = img->indexed->base;
+ }
+ }
+
+ if (fz_isarray(d))
+ {
+printf(" decode array!\n");
+ if (img->indexed)
+ for (i = 0; i < 2; i++)
+ img->decode[i] = fz_toreal(fz_arrayget(d, i));
+ else
+ for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
+ img->decode[i] = fz_toreal(fz_arrayget(d, i));
+ }
+ else
+ {
+ if (img->indexed)
+ for (i = 0; i < 2; i++)
+ img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0;
+ else
+ for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
+ img->decode[i] = i & 1;
+ }
+
+ if (img->indexed)
+ img->stride = (img->super.w * img->bpc + 7) / 8;
+ else
+ img->stride = (img->super.w * (img->super.n + img->super.a) * img->bpc + 7) / 8;
+
+ /* load image data */
+ error = pdf_decodefilter(&filter, dict);
+ if (error)
+ return error;
+
+ error = fz_pushfilter(file, filter);
+ if (error)
+ return error;
+
+ error = fz_readfile(&img->samples, file);
+ if (error)
+ return error;
+
+ fz_popfilter(file);
+
+ /* 0 means opaque and 1 means transparent, so we invert to get alpha */
+ if (ismask)
+ {
+ unsigned char *p;
+ for (p = img->samples->bp; p < img->samples->ep; p++)
+ *p = ~*p;
+ }
+
+ return nil;
+}
+
/* TODO error cleanup */
fz_error *
pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
pdf_image *img;
+ pdf_image *mask;
int ismask;
fz_obj *obj;
fz_obj *sub;
@@ -246,7 +355,6 @@ printf(" indexed!\n");
indexed = (pdf_indexed*)cs;
cs = indexed->base;
}
-
n = cs->n;
a = 0;
@@ -257,6 +365,8 @@ printf(" indexed!\n");
* ImageMask, Mask and SoftMask
*/
+ mask = nil;
+
ismask = fz_tobool(fz_dictgets(dict, "ImageMask"));
if (ismask)
{
@@ -269,7 +379,23 @@ printf(" image mask!\n");
obj = fz_dictgets(dict, "SMask");
if (fz_isindirect(obj))
{
- // sub-image mask
+ puts(" smask");
+ error = pdf_loadindirect(&sub, xref, obj);
+ if (error)
+ return error;
+
+ error = pdf_loadimage(&mask, xref, sub, obj);
+ if (error)
+ return error;
+
+ if (mask->super.cs != pdf_devicegray)
+ return fz_throw("syntaxerror: SMask must be DeviceGray");
+
+ mask->super.cs = 0;
+ mask->super.n = 0;
+ mask->super.a = 1;
+
+ fz_dropobj(sub);
}
obj = fz_dictgets(dict, "Mask");
@@ -280,17 +406,20 @@ printf(" image mask!\n");
return error;
if (fz_isarray(sub))
{
- // color key masking
+ puts(" mask / color key");
}
else
{
- // sub-image mask
+ puts(" mask");
+ error = pdf_loadimage(&mask, xref, sub, obj);
+ if (error)
+ return error;
}
fz_dropobj(sub);
}
else if (fz_isarray(obj))
{
- // color key masking
+ puts(" mask / color key");
}
/*
@@ -312,7 +441,7 @@ printf(" decode array!\n");
{
if (indexed)
for (i = 0; i < 2; i++)
- img->decode[i] = i & 1 ? (1 << img->bpc) - 1 : 0;
+ img->decode[i] = i & 1 ? (1 << bpc) - 1 : 0;
else
for (i = 0; i < (n + a) * 2; i++)
img->decode[i] = i & 1;
@@ -351,18 +480,23 @@ printf(" decode array!\n");
*p = ~*p;
}
+if (indexed)
+printf(" decode [ %g %g ]\n", img->decode[0], img->decode[1]);
+else
+{
printf(" decode [ ");
for (i = 0; i < (n + a) * 2; i++)
printf("%g ", img->decode[i]);
printf("]\n");
printf("\n");
+}
/*
* Create image object
*/
img->super.loadtile = loadtile;
- img->super.drop = nil;
+ img->super.drop = pdf_dropimage;
img->super.cs = cs;
img->super.w = w;
img->super.h = h;
@@ -371,6 +505,7 @@ printf("\n");
img->indexed = indexed;
img->stride = stride;
img->bpc = bpc;
+ img->mask = (fz_image*)mask;
*imgp = img;
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 374f23bc..dfe7d36d 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -68,6 +68,99 @@ pdf_dropcsi(pdf_csi *csi)
fz_free(csi);
}
+/*
+ * Do some magic to call the xobject subroutine.
+ * Push gstate, set transform, clip, run, pop gstate.
+ */
+
+static fz_error *
+runxobject(pdf_csi *csi, pdf_xref *xref, pdf_xobject *xobj)
+{
+ fz_error *error;
+ fz_node *transform;
+ fz_file *file;
+
+puts("run xobject");
+
+ /* gsave */
+ if (csi->gtop == 31)
+ return fz_throw("gstate overflow in content stream");
+ memcpy(&csi->gstate[csi->gtop + 1],
+ &csi->gstate[csi->gtop],
+ sizeof (pdf_gstate));
+ csi->gtop ++;
+
+ /* push transform */
+
+ error = fz_newtransformnode(&transform, xobj->matrix);
+ if (error)
+ return error;
+
+ error = pdf_addtransform(csi->gstate + csi->gtop, transform);
+ if (error)
+ {
+ fz_dropnode(transform);
+ return error;
+ }
+
+ /* run contents */
+
+ xobj->contents->rp = xobj->contents->bp;
+
+ error = fz_openbuffer(&file, xobj->contents, FZ_READ);
+ if (error)
+ return error;
+
+ error = pdf_runcsi(csi, xref, xobj->resources, file);
+
+ fz_closefile(file);
+
+ if (error)
+ return error;
+
+ /* grestore */
+ if (csi->gtop == 0)
+ return fz_throw("gstate underflow in content stream");
+ csi->gtop --;
+
+ return nil;
+}
+
+/*
+ * Decode inline image and insert into page.
+ */
+
+static fz_error *
+runinlineimage(pdf_csi *csi, pdf_xref *xref, fz_file *file, fz_obj *dict)
+{
+ fz_error *error;
+ pdf_image *img;
+ char buf[256];
+ int token;
+ int len;
+
+ error = pdf_loadinlineimage(&img, xref, dict, file);
+ if (error)
+ return error;
+
+ token = pdf_lex(file, buf, sizeof buf, &len);
+ if (token != PDF_TKEYWORD || strcmp("EI", buf))
+ return fz_throw("syntaxerror: corrupt inline image");
+
+ error = pdf_showimage(csi, img);
+ if (error)
+ {
+ fz_dropimage((fz_image*)img);
+ return error;
+ }
+
+ return nil;
+}
+
+/*
+ * Set gstate params from an ExtGState dictionary.
+ */
+
static fz_error *
runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
{
@@ -119,6 +212,10 @@ runextgstate(pdf_gstate *gstate, pdf_xref *xref, fz_obj *extgstate)
return nil;
}
+/*
+ * The meat of the interpreter...
+ */
+
static fz_error *
runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
{
@@ -552,28 +649,42 @@ Lsetcolorspace:
fz_obj *dict;
fz_obj *obj;
pdf_image *img;
+ pdf_xobject *xobj;
if (csi->top != 1)
goto syntaxerror;
dict = fz_dictgets(rdb, "XObject");
if (!dict)
+{
+fz_debugobj(rdb);
return fz_throw("syntaxerror: missing xobject resource");
+}
obj = fz_dictget(dict, csi->stack[0]);
if (!obj)
return fz_throw("syntaxerror: missing xobject resource");
img = pdf_findresource(xref->rimage, obj);
- if (!img)
+ xobj = pdf_findresource(xref->rxobject, obj);
+
+ if (!img && !xobj)
+ return fz_throw("syntaxerror: missing xobject resource");
+
+ if (img)
{
-fprintf(stderr, "syntaxerror: missing image resource");
-return nil;
+ error = pdf_showimage(csi, img);
+ if (error)
+ return error;
}
- error = pdf_showimage(csi, img);
- if (error)
- return error;
+ if (xobj)
+ {
+ clearstack(csi);
+ error = runxobject(csi, xref, xobj);
+ if (error)
+ return error;
+ }
}
else
@@ -922,9 +1033,23 @@ pdf_runcsi(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, fz_file *file)
break;
case PDF_TKEYWORD:
- error = runkeyword(csi, xref, rdb, buf);
- if (error) return error;
- clearstack(csi);
+ if (!strcmp(buf, "BI"))
+ {
+ fz_obj *obj;
+ error = pdf_parsedict(&obj, file, buf, sizeof buf);
+ if (error)
+ return error;
+ error = runinlineimage(csi, xref, file, obj);
+ fz_dropobj(obj);
+ if (error)
+ return error;
+ }
+ else
+ {
+ error = runkeyword(csi, xref, rdb, buf);
+ if (error) return error;
+ clearstack(csi);
+ }
break;
default:
diff --git a/mupdf/parse.c b/mupdf/parse.c
index ef6e93a3..3bf1e00f 100644
--- a/mupdf/parse.c
+++ b/mupdf/parse.c
@@ -122,6 +122,10 @@ skip:
if (tok == PDF_TCDICT)
return nil;
+ /* for BI .. ID .. EI in content streams */
+ if (tok == PDF_TKEYWORD && !strcmp(buf, "ID"))
+ return nil;
+
if (tok != PDF_TNAME)
goto cleanup;
diff --git a/mupdf/resources.c b/mupdf/resources.c
index 068de99b..7051c04d 100644
--- a/mupdf/resources.c
+++ b/mupdf/resources.c
@@ -109,7 +109,7 @@ preloadxobject(pdf_xref *xref, fz_obj *ref)
if (!strcmp(fz_toname(subtype), "Form"))
{
-// error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj);
+ error = pdf_loadxobject((pdf_xobject**)&rsrc->val, xref, obj, ref);
fz_dropobj(obj);
if (error) {
fz_free(rsrc);
@@ -341,114 +341,3 @@ cleanup:
return error;
}
-#if 0
-
-static fz_error *
-loadcolorspaces(pdf_resources *rdb, pdf_xref *xref, fz_obj *dict)
-{
- fz_error *err;
- fz_colorspace *colorspace;
- fz_obj *key, *val;
- fz_obj *ptr;
- int i;
-
- for (i = 0; i < fz_dictlen(dict); i++)
- {
- colorspace = nil;
- ptr = nil;
-
- key = fz_dictgetkey(dict, i);
- val = fz_dictgetval(dict, i);
-
- err = pdf_resolve(&val, xref);
- if (err) return err;
-
- err = pdf_loadcolorspace(&colorspace, xref, val);
- if (err) goto cleanup;
-
-printf(" -> %s\n", colorspace->name);
-
- err = fz_newpointer(&ptr, colorspace);
- if (err) goto cleanup;
-
- err = fz_dictput(rdb->colorspace, key, ptr);
- if (err) goto cleanup;
-
- fz_dropobj(ptr);
- fz_dropobj(val);
- colorspace = nil;
- }
-
- return nil;
-
-cleanup:
- if (colorspace) fz_dropcolorspace(colorspace);
- if (ptr) fz_dropobj(ptr);
- fz_dropobj(val);
- return err;
-}
-
-fz_error *
-pdf_loadresources(pdf_resources **rdbp, pdf_xref *xref, fz_obj *topdict)
-{
- fz_error *err;
- pdf_resources *rdb;
- fz_obj *subdict;
-
- rdb = *rdbp = fz_malloc(sizeof (pdf_resources));
- if (!rdb)
- return fz_outofmem;
-
- rdb->extgstate = nil;
- rdb->font = nil;
- rdb->colorspace = nil;
- rdb->ximage = nil;
- rdb->xform = nil;
-
- err = fz_newdict(&rdb->extgstate, 5);
- if (err) { pdf_dropresources(rdb); return err; }
-
- subdict = fz_dictgets(topdict, "ExtGState");
- if (subdict)
- {
- err = pdf_resolve(&subdict, xref);
- if (err) { pdf_dropresources(rdb); return err; }
- err = loadextgstates(rdb, xref, subdict);
- fz_dropobj(subdict);
- if (err) { pdf_dropresources(rdb); return err; }
- }
-
- err = fz_newdict(&rdb->font, 15);
- if (err) { pdf_dropresources(rdb); return err; }
-
- err = loadextgstatefonts(rdb, xref);
- if (err) { pdf_dropresources(rdb); return err; }
-
- subdict = fz_dictgets(topdict, "Font");
- if (subdict)
- {
- err = pdf_resolve(&subdict, xref);
- if (err) { pdf_dropresources(rdb); return err; }
- err = loadfonts(rdb, xref, subdict);
- fz_dropobj(subdict);
- if (err) { pdf_dropresources(rdb); return err; }
- }
-
- err = fz_newdict(&rdb->colorspace, 5);
- if (err) { pdf_dropresources(rdb); return err; }
-
- subdict = fz_dictgets(topdict, "ColorSpace");
- if (subdict)
- {
- err = pdf_resolve(&subdict, xref);
- if (err) { pdf_dropresources(rdb); return err; }
- err = loadcolorspaces(rdb, xref, subdict);
- fz_dropobj(subdict);
- if (err) { pdf_dropresources(rdb); return err; }
- }
-
- return nil;
-}
-
-#endif
-
diff --git a/mupdf/stream.c b/mupdf/stream.c
index 5d39436f..9b108a2b 100644
--- a/mupdf/stream.c
+++ b/mupdf/stream.c
@@ -87,7 +87,10 @@ buildfilters(fz_filter **filterp, fz_filter *head, fz_obj *fs, fz_obj *ps)
p = nil;
error = buildonefilter(&tail, f, p);
- error = fz_newpipeline(&head, head, tail);
+ if (head)
+ error = fz_newpipeline(&head, head, tail);
+ else
+ head = tail;
}
*filterp = head;
@@ -118,6 +121,28 @@ makerawfilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int
return nil;
}
+fz_error *
+pdf_decodefilter(fz_filter **filterp, fz_obj *stmobj)
+{
+ fz_obj *filters;
+ fz_obj *params;
+
+ filters = fz_dictgetsa(stmobj, "Filter", "F");
+ params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
+
+ if (filters)
+ {
+ if (fz_isname(filters))
+ return buildonefilter(filterp, filters, params);
+ else
+ return buildfilters(filterp, nil, filters, params);
+ }
+ else
+ return fz_newnullfilter(filterp, -1);
+
+ return nil;
+}
+
static fz_error *
makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, int gen)
{
@@ -128,8 +153,8 @@ makedecodefilter(fz_filter **filterp, pdf_xref *xref, fz_obj *stmobj, int oid, i
error = makerawfilter(&pipe, xref, stmobj, oid, gen);
- filters = fz_dictgets(stmobj, "Filter");
- params = fz_dictgets(stmobj, "DecodeParms");
+ filters = fz_dictgetsa(stmobj, "Filter", "F");
+ params = fz_dictgetsa(stmobj, "DecodeParms", "DP");
if (filters)
{
diff --git a/mupdf/xobject.c b/mupdf/xobject.c
new file mode 100644
index 00000000..1340bc5c
--- /dev/null
+++ b/mupdf/xobject.c
@@ -0,0 +1,65 @@
+#include <fitz.h>
+#include <mupdf.h>
+
+fz_error *
+pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
+{
+ fz_error *error;
+ pdf_xobject *form;
+ fz_obj *obj;
+
+ form = fz_malloc(sizeof(pdf_xobject));
+ if (!form)
+ return fz_outofmem;
+
+printf("loading xobject ");fz_debugobj(dict);printf("\n");
+
+ obj = fz_dictgets(dict, "BBox");
+ form->bbox.min.x = fz_toreal(fz_arrayget(obj, 0));
+ form->bbox.min.y = fz_toreal(fz_arrayget(obj, 1));
+ form->bbox.max.x = fz_toreal(fz_arrayget(obj, 2));
+ form->bbox.max.y = fz_toreal(fz_arrayget(obj, 3));
+
+ obj = fz_dictgets(dict, "Matrix");
+ form->matrix.a = fz_toreal(fz_arrayget(obj, 0));
+ form->matrix.b = fz_toreal(fz_arrayget(obj, 1));
+ form->matrix.c = fz_toreal(fz_arrayget(obj, 2));
+ form->matrix.d = fz_toreal(fz_arrayget(obj, 3));
+ form->matrix.e = fz_toreal(fz_arrayget(obj, 4));
+ form->matrix.f = fz_toreal(fz_arrayget(obj, 5));
+
+ form->resources = nil;
+ obj = fz_dictgets(dict, "Resources");
+ if (obj)
+ {
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ {
+ fz_free(form);
+ return error;
+ }
+
+ error = pdf_loadresources(&form->resources, xref, obj);
+ if (error)
+ {
+ fz_dropobj(obj);
+ fz_free(form);
+ return error;
+ }
+
+ fz_dropobj(obj);
+ }
+
+ error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref));
+ if (error)
+ {
+ fz_dropobj(form->resources);
+ fz_free(form);
+ return error;
+ }
+
+ *formp = form;
+ return nil;
+}
+
+
diff --git a/object/dict.c b/object/dict.c
index 61e55bc4..fda48dc3 100644
--- a/object/dict.c
+++ b/object/dict.c
@@ -169,6 +169,16 @@ fz_dictget(fz_obj *obj, fz_obj *key)
return fz_dictgets(obj, fz_toname(key));
}
+fz_obj *
+fz_dictgetsa(fz_obj *obj, char *key, char *abbrev)
+{
+ fz_obj *v;
+ v = fz_dictgets(obj, key);
+ if (v)
+ return v;
+ return fz_dictgets(obj, abbrev);
+}
+
fz_error *
fz_dictput(fz_obj *obj, fz_obj *key, fz_obj *val)
{
diff --git a/render/render.c b/render/render.c
index 6b2d5e29..fd3e0620 100644
--- a/render/render.c
+++ b/render/render.c
@@ -183,6 +183,7 @@ fz_error *
fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
{
fz_error *error;
+ fz_pixmap *oldacc;
fz_pixmap *colorpix;
fz_pixmap *shapepix;
fz_node *color;
@@ -202,7 +203,9 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
printf("begin mask\n");
+ oldacc = gc->acc;
oldmode = gc->mode;
+ gc->acc = nil;
gc->mode = FZ_RMASK;
gc->tmp = nil;
@@ -232,6 +235,7 @@ if (!shapepix) return nil;
fz_droppixmap(shapepix);
fz_droppixmap(colorpix);
+ gc->acc = oldacc;
gc->mode = oldmode;
printf("end mask\n");