summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/content.h37
-rw-r--r--include/mupdf/rsrc.h11
-rw-r--r--mupdf/build.c109
-rw-r--r--mupdf/colorspace.c54
-rw-r--r--mupdf/image.c201
-rw-r--r--mupdf/interpret.c157
6 files changed, 381 insertions, 188 deletions
diff --git a/include/mupdf/content.h b/include/mupdf/content.h
index b57a4d96..a7bfac22 100644
--- a/include/mupdf/content.h
+++ b/include/mupdf/content.h
@@ -2,9 +2,37 @@
* content stream parsing
*/
+typedef struct pdf_material_s pdf_material;
typedef struct pdf_gstate_s pdf_gstate;
typedef struct pdf_csi_s pdf_csi;
+enum
+{
+ PDF_MFILL,
+ PDF_MSTROKE
+};
+
+enum
+{
+ PDF_MNONE,
+ PDF_MCOLOR,
+ PDF_MLAB,
+ PDF_MINDEXED,
+ PDF_MTILE,
+ PDF_MSHADE
+};
+
+struct pdf_material_s
+{
+ int kind;
+ fz_colorspace *cs;
+ float v[32];
+ pdf_indexed *indexed;
+ // lookup
+ // tile
+ // shade
+};
+
struct pdf_gstate_s
{
/* path stroking */
@@ -17,10 +45,8 @@ struct pdf_gstate_s
float dashlist[32];
/* materials */
- fz_colorspace *strokecs;
- float stroke[32];
- fz_colorspace *fillcs;
- float fill[32];
+ pdf_material stroke;
+ pdf_material fill;
/* text state */
float charspace;
@@ -58,6 +84,9 @@ struct pdf_csi_s
/* build.c */
void pdf_initgstate(pdf_gstate *gs);
+fz_error *pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs);
+fz_error *pdf_setcolor(pdf_csi *csi, int what, float *v);
+
fz_error *pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path);
fz_error *pdf_buildfillpath(pdf_gstate *gs, fz_pathnode *path, int evenodd);
fz_error *pdf_addfillshape(pdf_gstate *gs, fz_node *shape);
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 4b656910..0fb28cf0 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -28,6 +28,16 @@ void pdf_freefunction(pdf_function *func);
* ColorSpace
*/
+typedef struct pdf_indexed_s pdf_indexed;
+
+struct pdf_indexed_s
+{
+ fz_colorspace super; /* hmmm... */
+ fz_colorspace *base;
+ int high;
+ unsigned char *lookup;
+};
+
extern fz_colorspace *pdf_devicegray;
extern fz_colorspace *pdf_devicergb;
extern fz_colorspace *pdf_devicecmyk;
@@ -61,6 +71,7 @@ struct pdf_image_s
{
fz_image super;
fz_image *mask; /* explicit mask with subimage */
+ pdf_indexed *indexed;
float decode[32];
int bpc;
int stride;
diff --git a/mupdf/build.c b/mupdf/build.c
index 6d0129ea..c2acde08 100644
--- a/mupdf/build.c
+++ b/mupdf/build.c
@@ -12,11 +12,13 @@ pdf_initgstate(pdf_gstate *gs)
gs->dashlen = 0;
memset(gs->dashlist, 0, sizeof(gs->dashlist));
- gs->strokecs = pdf_devicegray;
- gs->stroke[0] = 0;
+ gs->stroke.kind = PDF_MCOLOR;
+ gs->stroke.cs = pdf_devicegray;
+ gs->stroke.v[0] = 0;
- gs->fillcs = pdf_devicegray;
- gs->fill[0] = 0;
+ gs->fill.kind = PDF_MCOLOR;
+ gs->fill.cs = pdf_devicegray;
+ gs->fill.v[0] = 0;
gs->charspace = 0;
gs->wordspace = 0;
@@ -31,6 +33,83 @@ pdf_initgstate(pdf_gstate *gs)
}
fz_error *
+pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs)
+{
+ pdf_gstate *gs = csi->gstate + csi->gtop;
+ fz_error *error;
+ pdf_material *mat;
+
+ error = pdf_flushtext(csi);
+ if (error)
+ return error;
+
+ mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
+
+ mat->kind = PDF_MCOLOR;
+ mat->cs = cs;
+
+ mat->v[0] = 0; // FIXME: default color
+ mat->v[1] = 0; // FIXME: default color
+ mat->v[2] = 0; // FIXME: default color
+ mat->v[3] = 1; // FIXME: default color
+
+ if (!strcmp(cs->name, "Indexed"))
+ {
+ mat->kind = PDF_MINDEXED;
+ mat->indexed = (pdf_indexed*)cs;
+ mat->cs = mat->indexed->base;
+ }
+
+ if (!strcmp(cs->name, "Lab"))
+ mat->kind = PDF_MLAB;
+
+ return nil;
+}
+
+fz_error *
+pdf_setcolor(pdf_csi *csi, int what, float *v)
+{
+ pdf_gstate *gs = csi->gstate + csi->gtop;
+ fz_error *error;
+ pdf_indexed *ind;
+ pdf_material *mat;
+ int i, k;
+
+ error = pdf_flushtext(csi);
+ if (error)
+ return error;
+
+ mat = what == PDF_MFILL ? &gs->fill : &gs->stroke;
+
+ switch (mat->kind)
+ {
+ case PDF_MCOLOR:
+ for (i = 0; i < mat->cs->n; i++)
+ mat->v[i] = v[i];
+ break;
+
+ case PDF_MLAB:
+ mat->v[0] = v[0] / 100.0;
+ mat->v[1] = (v[1] + 100) / 200.0;
+ mat->v[2] = (v[2] + 100) / 200.0;
+ break;
+
+ case PDF_MINDEXED:
+ ind = mat->indexed;
+ i = CLAMP(v[0], 0, ind->high);
+ for (k = 0; k < ind->base->n; k++)
+ mat->v[k] = ind->lookup[ind->base->n * i + k] / 255.0;
+ break;
+
+ default:
+ return fz_throw("syntaxerror: color not compatible with material");
+ }
+
+ return nil;
+}
+
+
+fz_error *
pdf_buildstrokepath(pdf_gstate *gs, fz_pathnode *path)
{
fz_error *error;
@@ -89,13 +168,31 @@ addcolorshape(pdf_gstate *gs, fz_node *shape, fz_colorspace *cs, float *v)
fz_error *
pdf_addfillshape(pdf_gstate *gs, fz_node *shape)
{
- return addcolorshape(gs, shape, gs->fillcs, gs->fill);
+ switch (gs->fill.kind)
+ {
+ case PDF_MNONE:
+ fz_insertnode(gs->head, shape);
+ return nil;
+ case PDF_MCOLOR:
+ return addcolorshape(gs, shape, gs->fill.cs, gs->fill.v);
+ default:
+ return fz_throw("unimplemented material");
+ }
}
fz_error *
pdf_addstrokeshape(pdf_gstate *gs, fz_node *shape)
{
- return addcolorshape(gs, shape, gs->strokecs, gs->stroke);
+ switch (gs->stroke.kind)
+ {
+ case PDF_MNONE:
+ fz_insertnode(gs->head, shape);
+ return nil;
+ case PDF_MCOLOR:
+ return addcolorshape(gs, shape, gs->stroke.cs, gs->stroke.v);
+ default:
+ return fz_throw("unimplemented material");
+ }
}
fz_error *
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index 1b2eff61..b4ba8aa8 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -356,9 +356,13 @@ static inline float cielabinvg(float x)
static void labtoxyz(fz_colorspace *fzcs, float *lab, float *xyz)
{
struct cielab *cs = (struct cielab *) fzcs;
- float lstar = lab[0];
- float astar = MAX(MIN(lab[1], cs->range[1]), cs->range[0]);
- float bstar = MAX(MIN(lab[2], cs->range[3]), cs->range[2]);
+ float tmp[3];
+ tmp[0] = lab[0] * 100;
+ tmp[1] = lab[1] * 200 - 100;
+ tmp[2] = lab[2] * 200 - 100;
+ float lstar = tmp[0];
+ float astar = MAX(MIN(tmp[1], cs->range[1]), cs->range[0]);
+ float bstar = MAX(MIN(tmp[2], cs->range[3]), cs->range[2]);
float l = ((lstar * 16.0) / 116.0) + (astar / 500.0);
float m = (lstar * 16.0) / 116.0;
float n = ((lstar * 16.0) / 116.0) - (bstar / 200.0);
@@ -370,13 +374,17 @@ static void labtoxyz(fz_colorspace *fzcs, float *lab, float *xyz)
static void xyztolab(fz_colorspace *fzcs, float *xyz, float *lab)
{
struct cielab *cs = (struct cielab *) fzcs;
+ float tmp[3];
float yyn = xyz[1] / cs->white[1];
if (yyn < 0.008856)
- lab[0] = 116.0 * yyn * (1.0 / 3.0) - 16.0;
+ tmp[0] = 116.0 * yyn * (1.0 / 3.0) - 16.0;
else
- lab[0] = 903.3 * yyn;
- lab[1] = 500 * (cielabinvg(xyz[0]/cs->white[0]) - cielabinvg(xyz[1]/cs->white[1]));
- lab[2] = 200 * (cielabinvg(xyz[1]/cs->white[1]) - cielabinvg(xyz[2]/cs->white[2]));
+ tmp[0] = 903.3 * yyn;
+ tmp[1] = 500 * (cielabinvg(xyz[0]/cs->white[0]) - cielabinvg(xyz[1]/cs->white[1]));
+ tmp[2] = 200 * (cielabinvg(xyz[1]/cs->white[1]) - cielabinvg(xyz[2]/cs->white[2]));
+ lab[0] = tmp[0] / 100.0;
+ lab[1] = (tmp[1] + 100) / 200.0;
+ lab[2] = (tmp[2] + 100) / 200.0;
}
static fz_error *
@@ -576,27 +584,25 @@ loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
* Indexed
*/
-struct indexed
-{
- fz_colorspace super;
- fz_colorspace *base;
- int high;
- float *lookup;
-};
-
+/* only called for images... */
static void
indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz)
{
- struct indexed *cs = (struct indexed *)fzcs;
- int i = ind[0] * 255; // FIXME
+ pdf_indexed *cs = (pdf_indexed *)fzcs;
+ float alt[32];
+ int i, k;
+ i = ind[0] * 255;
i = CLAMP(i, 0, cs->high);
- cs->base->toxyz(cs->base, cs->lookup + i * cs->base->n, xyz);
+printf("indexedtoxyz: %d\n", i);
+ for (k = 0; k < cs->base->n; k++)
+ alt[k] = cs->lookup[i * cs->base->n + k] / 255.0;
+ cs->base->toxyz(cs->base, alt, xyz);
}
static void
freeindexed(fz_colorspace *fzcs)
{
- struct indexed *cs = (struct indexed *)fzcs;
+ pdf_indexed *cs = (pdf_indexed *)fzcs;
fz_freecolorspace(cs->base);
fz_free(cs->lookup);
}
@@ -605,7 +611,7 @@ static fz_error *
loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
{
fz_error *error;
- struct indexed *cs;
+ pdf_indexed *cs;
fz_obj *baseobj = fz_arrayget(array, 1);
fz_obj *highobj = fz_arrayget(array, 2);
fz_obj *lookup = fz_arrayget(array, 3);
@@ -620,7 +626,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
if (error)
return error;
- cs = fz_malloc(sizeof(struct indexed));
+ cs = fz_malloc(sizeof(pdf_indexed));
if (!cs)
{
fz_freecolorspace(base);
@@ -634,7 +640,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
n = base->n * (cs->high + 1);
- cs->lookup = fz_malloc(n * sizeof(float));
+ cs->lookup = fz_malloc(n);
if (!cs->lookup)
{
freeindexed((fz_colorspace*)cs);
@@ -646,7 +652,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
unsigned char *buf = fz_tostringbuf(lookup);
int i;
for (i = 0; i < n; i++)
- cs->lookup[i] = buf[i] / 255.0; // FIXME base range
+ cs->lookup[i] = buf[i];
}
if (fz_isindirect(lookup))
@@ -662,7 +668,7 @@ loadindexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
}
for (i = 0; i < n && i < (buf->wp - buf->rp); i++)
- cs->lookup[i] = buf->rp[i] / 255.0; // FIXME base range
+ cs->lookup[i] = buf->rp[i];
fz_freebuffer(buf);
}
diff --git a/mupdf/image.c b/mupdf/image.c
index 019e6129..2e90d9cb 100644
--- a/mupdf/image.c
+++ b/mupdf/image.c
@@ -6,10 +6,9 @@ static inline int getbit(const unsigned char *buf, int x)
return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
}
-static void loadtile1(pdf_image *src, fz_pixmap *dst)
+static void loadtile1(pdf_image *src, fz_pixmap *dst, int n)
{
int x, y, k;
- int n = dst->n;
for (y = dst->y; y < dst->y + dst->h; y++)
{
unsigned char *s = src->samples->bp + y * src->stride;
@@ -22,28 +21,25 @@ static void loadtile1(pdf_image *src, fz_pixmap *dst)
}
}
-static void loadtile1a(pdf_image *src, fz_pixmap *dst)
+static void loadtile1a(pdf_image *src, fz_pixmap *dst, int n)
{
int x, y, k;
- int sn = src->super.n;
- int dn = dst->n;
for (y = dst->y; y < dst->y + dst->h; y++)
{
unsigned char *s = src->samples->bp + y * src->stride;
unsigned char *d = dst->samples + y * dst->w * dst->n;
for (x = dst->x; x < dst->x + dst->w; x++)
{
- d[x * dn + 0] = 255;
- for (k = 0; k < sn; k++)
- d[x * dn + k + 1] = getbit(s, x * sn + k);
+ d[x * (n+1) + 0] = 255;
+ for (k = 0; k < n; k++)
+ d[x * (n+1) + k + 1] = getbit(s, x * n + k);
}
}
}
-static void loadtile8(pdf_image *src, fz_pixmap *dst)
+static void loadtile8(pdf_image *src, fz_pixmap *dst, int n)
{
int x, y, k;
- int n = src->super.n;
for (y = dst->y; y < dst->y + dst->h; y++)
{
unsigned char *s = src->samples->bp + y * src->stride;
@@ -54,10 +50,9 @@ static void loadtile8(pdf_image *src, fz_pixmap *dst)
}
}
-static void loadtile8a(pdf_image *src, fz_pixmap *dst)
+static void loadtile8a(pdf_image *src, fz_pixmap *dst, int n)
{
int x, y, k;
- int n = dst->n;
for (y = dst->y; y < dst->y + dst->h; y++)
{
unsigned char *s = src->samples->bp + y * src->stride;
@@ -65,19 +60,30 @@ static void loadtile8a(pdf_image *src, fz_pixmap *dst)
for (x = dst->x; x < dst->x + dst->w; x++)
{
*d++ = 255;
- for (k = 1; k < n; k++)
+ for (k = 0; k < n; k++)
*d++ = *s++;
}
}
}
static void
-decodetile(fz_pixmap *pix, int bpc, int a, float *decode, int scale)
+decodetile(fz_pixmap *pix, int bpc, int a, float *decode)
{
unsigned char table[32][256];
float twon = (1 << bpc) - 1;
int x, y, k, i;
+ int isdefault = 1;
+ for (k = 0; k < pix->n - a; k++)
+ {
+ int min = decode[k * 2 + 0] * 255;
+ int max = decode[k * 2 + 1] * 255;
+ if (min != 0 || max != 255)
+ isdefault = 0;
+ }
+ if (isdefault)
+ return;
+
for (i = 0; i < (1 << bpc); i++)
{
for (k = 0; k < pix->n - a; k++)
@@ -85,7 +91,7 @@ decodetile(fz_pixmap *pix, int bpc, int a, float *decode, int scale)
float min = decode[k * 2 + 0];
float max = decode[k * 2 + 1];
float f = min + i * (max - min) / twon;
- table[k][i] = f * scale;
+ table[k][i] = f * 255;
}
}
@@ -106,6 +112,7 @@ static fz_error *
loadtile(fz_image *img, fz_pixmap *tile)
{
pdf_image *src = (pdf_image*)img;
+ fz_error *error;
assert(tile->n == img->n + 1);
assert(tile->x >= 0);
@@ -113,35 +120,72 @@ loadtile(fz_image *img, fz_pixmap *tile)
assert(tile->x + tile->w <= img->w);
assert(tile->y + tile->h <= img->h);
- if (img->a)
+ if (src->indexed)
{
+ fz_pixmap *tmp;
+ int x, y, k, i;
+
+ error = fz_newpixmap(&tmp, tile->x, tile->y, tile->w, tile->h, 1);
+ if (error)
+ return error;
+
switch (src->bpc)
{
- case 1: loadtile1(src, tile); break;
- // case 2: loadtile2(src, tile); break;
- // case 4: loadtile4(src, tile); break;
- case 8: loadtile8(src, tile); break;
+ case 1: loadtile1(src, tmp, 1); break;
+ // case 2: loadtile2(src, tmp, 1); break;
+ // case 4: loadtile4(src, tmp, 1); break;
+ case 8: loadtile8(src, tmp, 1); break;
default:
return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
}
+
+ for (y = 0; y < tile->h; y++)
+ {
+ for (x = 0; x < tile->w; x++)
+ {
+ tile->samples[(y * tile->w + x) * tile->n] = 255;
+ i = tmp->samples[y * tile->w + x];
+ i = CLAMP(i, 0, src->indexed->high);
+ for (k = 0; k < src->indexed->base->n; k++)
+ {
+ tile->samples[(y * tile->w + x) * tile->n + k + 1] =
+ src->indexed->lookup[i * src->indexed->base->n + k];
+ }
+ }
+ }
+
+ fz_freepixmap(tmp);
}
+
else
{
- switch (src->bpc)
+ if (img->a)
{
- case 1: loadtile1a(src, tile); break;
- // case 2: loadtile2a(src, tile); break;
- // case 4: loadtile4a(src, tile); break;
- case 8: loadtile8a(src, tile); break;
- default:
- return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
+ switch (src->bpc)
+ {
+ case 1: loadtile1(src, tile, img->n + img->a); break;
+ // case 2: loadtile2(src, tile, img->n + img->a); break;
+ // case 4: loadtile4(src, tile, img->n + img->a); break;
+ case 8: loadtile8(src, tile, img->n + img->a); break;
+ default:
+ return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
+ }
+ }
+ else
+ {
+ switch (src->bpc)
+ {
+ case 1: loadtile1a(src, tile, img->n); break;
+ // case 2: loadtile2a(src, tile, img->n); break;
+ // case 4: loadtile4a(src, tile, img->n); break;
+ case 8: loadtile8a(src, tile, img->n); break;
+ default:
+ return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
+ }
}
- }
- if (img->cs && !strcmp(img->cs->name, "Indexed"))
- decodetile(tile, src->bpc, !src->super.a, src->decode, 1);
- else
- decodetile(tile, src->bpc, !src->super.a, src->decode, 255);
+ decodetile(tile, src->bpc, !img->a, src->decode);
+ }
return nil;
}
@@ -151,24 +195,27 @@ pdf_loadimage(pdf_image **imgp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
pdf_image *img;
- fz_colorspace *cs;
int ismask;
fz_obj *obj;
int i;
+ int w, h, bpc;
+ int n = 0;
+ int a = 0;
+ fz_colorspace *cs = nil;
+ pdf_indexed *indexed = nil;
+ int stride;
+
img = fz_malloc(sizeof(pdf_image));
if (!img)
return fz_outofmem;
- img->super.loadtile = loadtile;
- img->super.free = nil;
- img->super.cs = nil;
+ w = fz_toint(fz_dictgets(dict, "Width"));
+ h = fz_toint(fz_dictgets(dict, "Height"));
+ bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent"));
- img->super.w = fz_toint(fz_dictgets(dict, "Width"));
- img->super.h = fz_toint(fz_dictgets(dict, "Height"));
- img->bpc = fz_toint(fz_dictgets(dict, "BitsPerComponent"));
-
-printf("load image %d x %d @ %d\n", img->super.w, img->super.h, img->bpc);
+printf("loading image "); fz_debugobj(dict); printf("\n");
+printf(" geometry %d x %d @ %d\n", w, h, bpc);
cs = nil;
obj = fz_dictgets(dict, "ColorSpace");
@@ -182,45 +229,52 @@ printf("load image %d x %d @ %d\n", img->super.w, img->super.h, img->bpc);
if (error)
return error;
+ if (!strcmp(cs->name, "Indexed"))
+ {
+printf(" indexed!\n");
+ indexed = (pdf_indexed*)cs;
+ cs = indexed->base;
+ }
+
+ n = cs->n;
+ a = 0;
+
fz_dropobj(obj);
}
ismask = fz_tobool(fz_dictgets(dict, "ImageMask"));
- if (!ismask)
- {
- img->super.cs = cs;
- img->super.n = cs->n;
- img->super.a = 0;
- }
- else
+ if (ismask)
{
- img->super.cs = nil;
- img->super.n = 0;
- img->super.a = 1;
+printf(" image mask!\n");
+ n = 0;
+ a = 1;
}
- img->stride = ((img->super.w * (img->super.n + img->super.a)) * img->bpc + 7) / 8;
-
obj = fz_dictgets(dict, "Decode");
if (fz_isarray(obj))
- for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
- img->decode[i] = fz_toreal(fz_arrayget(obj, i));
+ {
+printf(" decode array!\n");
+ if (img->indexed)
+ for (i = 0; i < 2; i++)
+ img->decode[i] = fz_toreal(fz_arrayget(obj, i));
+ else
+ for (i = 0; i < (n + a) * 2; i++)
+ img->decode[i] = fz_toreal(fz_arrayget(obj, i));
+ }
else
{
- if (cs && !strcmp(cs->name, "IndexedXXX"))
- for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
+ 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++)
+ for (i = 0; i < (n + a) * 2; i++)
img->decode[i] = i & 1;
}
-printf(" colorspace %s\n", cs ? cs->name : "(null)");
-printf(" mask %d\n", ismask);
-printf(" decode [ ");
-for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
-printf("%g ", img->decode[i]);
-printf("]\n");
+ if (indexed)
+ stride = (w * bpc + 7) / 8;
+ else
+ stride = (w * (n + a) * bpc + 7) / 8;
error = pdf_loadstream(&img->samples, xref, fz_tonum(ref), fz_togen(ref));
if (error)
@@ -230,7 +284,7 @@ printf("]\n");
return error;
}
- if (img->samples->wp - img->samples->bp != img->stride * img->super.h)
+ if (img->samples->wp - img->samples->bp < stride * h)
{
/* TODO: colorspace? */
fz_freebuffer(img->samples);
@@ -246,6 +300,23 @@ printf("]\n");
*p = ~*p;
}
+printf(" decode [ ");
+for (i = 0; i < (n + a) * 2; i++)
+printf("%g ", img->decode[i]);
+printf("]\n");
+printf("\n");
+
+ img->super.loadtile = loadtile;
+ img->super.free = nil;
+ img->super.cs = cs;
+ img->super.w = w;
+ img->super.h = h;
+ img->super.n = n;
+ img->super.a = a;
+ img->indexed = indexed;
+ img->stride = stride;
+ img->bpc = bpc;
+
*imgp = img;
return nil;
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index eb9f60e0..cdee9fea 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -127,6 +127,8 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
float a, b, c, d, e, f;
float x, y, w, h;
fz_matrix m;
+ float v[32];
+ int what;
int i;
if (strlen(buf) > 1)
@@ -297,102 +299,75 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
else if (!strcmp(buf, "cs"))
{
- fz_obj *dict;
- fz_obj *obj;
-
- if (csi->top != 1)
- goto syntaxerror;
-
- error = pdf_flushtext(csi);
- if (error) return error;
-
- obj = csi->stack[0];
-
- if (!strcmp(fz_toname(obj), "DeviceGray"))
- gstate->fillcs = pdf_devicegray;
- else if (!strcmp(fz_toname(obj), "DeviceRGB"))
- gstate->fillcs = pdf_devicergb;
- else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
- gstate->fillcs = pdf_devicecmyk;
- else
- {
- dict = fz_dictgets(rdb, "ColorSpace");
- if (!dict)
- return fz_throw("syntaxerror: missing colorspace resource");
- obj = fz_dictget(dict, obj);
- if (!obj)
- return fz_throw("syntaxerror: missing colorspace resource");
- if (fz_isindirect(obj))
- gstate->fillcs = pdf_findresource(xref->rcolorspace, obj);
- else
- return fz_throw("syntaxerror: inline colorspace in dict");
- if (!gstate->fillcs)
- return fz_throw("syntaxerror: missing colorspace resource");
- }
-
- // FIXME set default color
+ what = PDF_MFILL;
+ goto Lsetcolorspace;
}
else if (!strcmp(buf, "CS"))
{
- fz_obj *dict;
+ fz_colorspace *cs;
fz_obj *obj;
+ what = PDF_MSTROKE;
+
+Lsetcolorspace:
if (csi->top != 1)
goto syntaxerror;
- error = pdf_flushtext(csi);
- if (error) return error;
-
obj = csi->stack[0];
if (!strcmp(fz_toname(obj), "DeviceGray"))
- gstate->strokecs = pdf_devicegray;
+ cs = pdf_devicegray;
else if (!strcmp(fz_toname(obj), "DeviceRGB"))
- gstate->strokecs = pdf_devicergb;
+ cs = pdf_devicergb;
else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
- gstate->strokecs = pdf_devicecmyk;
+ cs = pdf_devicecmyk;
else
{
- dict = fz_dictgets(rdb, "ColorSpace");
+ fz_obj *dict = fz_dictgets(rdb, "ColorSpace");
if (!dict)
return fz_throw("syntaxerror: missing colorspace resource");
obj = fz_dictget(dict, obj);
if (!obj)
return fz_throw("syntaxerror: missing colorspace resource");
if (fz_isindirect(obj))
- gstate->strokecs = pdf_findresource(xref->rcolorspace, obj);
+ cs = pdf_findresource(xref->rcolorspace, obj);
else
return fz_throw("syntaxerror: inline colorspace in dict");
- if (!gstate->strokecs)
+ if (!cs)
return fz_throw("syntaxerror: missing colorspace resource");
}
- // FIXME set default color
+ error = pdf_setcolorspace(csi, what, cs);
+ if (error) return error;
}
else if (!strcmp(buf, "sc") || !strcmp(buf, "scn"))
{
- if (csi->top != gstate->fillcs->n)
+ if (gstate->fill.kind == PDF_MINDEXED && csi->top != 1)
+ goto syntaxerror;
+ else if (csi->top != gstate->fill.cs->n)
goto syntaxerror;
-
- error = pdf_flushtext(csi);
- if (error) return error;
for (i = 0; i < csi->top; i++)
- gstate->fill[i] = fz_toreal(csi->stack[i]);
+ v[i] = fz_toreal(csi->stack[i]);
+
+ error = pdf_setcolor(csi, PDF_MFILL, v);
+ if (error) return error;
}
else if (!strcmp(buf, "SC") || !strcmp(buf, "SCN"))
{
- if (csi->top != gstate->strokecs->n)
+ if (gstate->stroke.kind == PDF_MINDEXED && csi->top != 1)
+ goto syntaxerror;
+ else if (csi->top != gstate->stroke.cs->n)
goto syntaxerror;
-
- error = pdf_flushtext(csi);
- if (error) return error;
for (i = 0; i < csi->top; i++)
- gstate->stroke[i] = fz_toreal(csi->stack[i]);
+ v[i] = fz_toreal(csi->stack[i]);
+
+ error = pdf_setcolor(csi, PDF_MFILL, v);
+ if (error) return error;
}
else if (!strcmp(buf, "rg"))
@@ -400,13 +375,14 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (csi->top != 3)
goto syntaxerror;
- error = pdf_flushtext(csi);
- if (error) return error;
+ v[0] = fz_toreal(csi->stack[0]);
+ v[1] = fz_toreal(csi->stack[1]);
+ v[2] = fz_toreal(csi->stack[2]);
- gstate->fillcs = pdf_devicergb;
- gstate->fill[0] = fz_toreal(csi->stack[0]);
- gstate->fill[1] = fz_toreal(csi->stack[1]);
- gstate->fill[2] = fz_toreal(csi->stack[2]);
+ error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicergb);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MFILL, v);
+ if (error) return error;
}
else if (!strcmp(buf, "RG"))
@@ -414,13 +390,14 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (csi->top != 3)
goto syntaxerror;
- error = pdf_flushtext(csi);
- if (error) return error;
+ v[0] = fz_toreal(csi->stack[0]);
+ v[1] = fz_toreal(csi->stack[1]);
+ v[2] = fz_toreal(csi->stack[2]);
- gstate->strokecs = pdf_devicergb;
- gstate->stroke[0] = fz_toreal(csi->stack[0]);
- gstate->stroke[1] = fz_toreal(csi->stack[1]);
- gstate->stroke[2] = fz_toreal(csi->stack[2]);
+ error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicergb);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MSTROKE, v);
+ if (error) return error;
}
else if (!strcmp(buf, "BT"))
@@ -776,50 +753,52 @@ fprintf(stderr, "syntaxerror: unknown keyword '%s'\n", buf);
if (csi->top != 1)
goto syntaxerror;
- error = pdf_flushtext(csi);
+ v[0] = fz_toreal(csi->stack[0]);
+ error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicegray);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MFILL, v);
if (error) return error;
-
- gstate->fillcs = pdf_devicegray;
- gstate->fill[0] = fz_toreal(csi->stack[0]);
break;
case 'G':
if (csi->top != 1)
goto syntaxerror;
- error = pdf_flushtext(csi);
+ v[0] = fz_toreal(csi->stack[0]);
+ error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicegray);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MSTROKE, v);
if (error) return error;
-
- gstate->strokecs = pdf_devicegray;
- gstate->stroke[0] = fz_toreal(csi->stack[0]);
break;
case 'k':
if (csi->top != 4)
goto syntaxerror;
- error = pdf_flushtext(csi);
- if (error) return error;
+ v[0] = fz_toreal(csi->stack[0]);
+ v[1] = fz_toreal(csi->stack[1]);
+ v[2] = fz_toreal(csi->stack[2]);
+ v[3] = fz_toreal(csi->stack[3]);
- gstate->fillcs = pdf_devicecmyk;
- gstate->fill[0] = fz_toreal(csi->stack[0]);
- gstate->fill[1] = fz_toreal(csi->stack[1]);
- gstate->fill[2] = fz_toreal(csi->stack[2]);
- gstate->fill[3] = fz_toreal(csi->stack[3]);
+ error = pdf_setcolorspace(csi, PDF_MFILL, pdf_devicecmyk);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MFILL, v);
+ if (error) return error;
break;
case 'K':
if (csi->top != 4)
goto syntaxerror;
- error = pdf_flushtext(csi);
- if (error) return error;
+ v[0] = fz_toreal(csi->stack[0]);
+ v[1] = fz_toreal(csi->stack[1]);
+ v[2] = fz_toreal(csi->stack[2]);
+ v[3] = fz_toreal(csi->stack[3]);
- gstate->strokecs = pdf_devicecmyk;
- gstate->stroke[0] = fz_toreal(csi->stack[0]);
- gstate->stroke[1] = fz_toreal(csi->stack[1]);
- gstate->stroke[2] = fz_toreal(csi->stack[2]);
- gstate->stroke[3] = fz_toreal(csi->stack[3]);
+ error = pdf_setcolorspace(csi, PDF_MSTROKE, pdf_devicecmyk);
+ if (error) return error;
+ error = pdf_setcolor(csi, PDF_MSTROKE, v);
+ if (error) return error;
break;
case '\'':