summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/rsrc.h2
-rw-r--r--mupdf/colorspace.c381
-rw-r--r--mupdf/function.c6
-rw-r--r--mupdf/interpret.c4
-rw-r--r--render/renderimage.c36
-rw-r--r--test/pdffunction.c2
6 files changed, 259 insertions, 172 deletions
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 20df27e7..4b656910 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -22,7 +22,7 @@ typedef struct pdf_function_s pdf_function;
fz_error *pdf_loadfunction(pdf_function **func, pdf_xref *xref, fz_obj *obj);
fz_error *pdf_evalfunction(pdf_function *func, float *in, int inlen, float *out, int outlen);
-void pdf_freefunc(pdf_function *func);
+void pdf_freefunction(pdf_function *func);
/*
* ColorSpace
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index 3511dc91..85fdc283 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -112,6 +112,45 @@ newcalgray(fz_colorspace **csp, float *white, float *black, float gamma)
return nil;
}
+static fz_error *
+loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
+{
+ fz_obj *tmp;
+
+ float white[3];
+ float black[3];
+ float gamma;
+
+ tmp = fz_dictgets(dict, "WhitePoint");
+ if (!fz_isarray(tmp))
+ return fz_throw("syntaxerror: CalGray missing WhitePoint");
+ white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ white[2] = fz_toreal(fz_arrayget(tmp, 2));
+
+ tmp = fz_dictgets(dict, "BlackPoint");
+ if (fz_isarray(tmp))
+ {
+ black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ black[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+ else
+ {
+ black[0] = 0.0;
+ black[1] = 0.0;
+ black[2] = 0.0;
+ }
+
+ tmp = fz_dictgets(dict, "Gamma");
+ if (fz_isreal(tmp))
+ gamma = fz_toreal(tmp);
+ else
+ gamma = 1.0;
+
+ return newcalgray(csp, white, black, gamma);
+}
+
/*
* DeviceRGB
*/
@@ -192,6 +231,68 @@ newcalrgb(fz_colorspace **csp, float *white, float *black, float *gamma, float *
return nil;
}
+static fz_error *
+loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
+{
+ fz_obj *tmp;
+
+ float white[3];
+ float black[3];
+ float gamma[3];
+ float matrix[9];
+
+ tmp = fz_dictgets(dict, "WhitePoint");
+ if (!fz_isarray(tmp))
+ return fz_throw("syntaxerror: CalRGB missing White");
+ white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ white[2] = fz_toreal(fz_arrayget(tmp, 2));
+
+ tmp = fz_dictgets(dict, "BlackPoint");
+ if (fz_isarray(tmp))
+ {
+ black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ black[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+ else
+ {
+ black[0] = 0.0;
+ black[1] = 0.0;
+ black[2] = 0.0;
+ }
+
+ tmp = fz_dictgets(dict, "Gamma");
+ if (fz_isarray(tmp))
+ {
+ gamma[0] = fz_toreal(fz_arrayget(tmp, 0));
+ gamma[1] = fz_toreal(fz_arrayget(tmp, 1));
+ gamma[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+ else
+ {
+ gamma[0] = 1.0;
+ gamma[1] = 1.0;
+ gamma[2] = 1.0;
+ }
+
+ tmp = fz_dictgets(dict, "Matrix");
+ if (fz_isarray(tmp))
+ {
+ int i;
+ for (i = 0; i < 9; i++)
+ matrix[i] = fz_toreal(fz_arrayget(tmp, i));
+ }
+ else
+ {
+ matrix[0] = 1.0; matrix[1] = 0.0; matrix[2] = 0.0;
+ matrix[3] = 0.0; matrix[4] = 1.0; matrix[5] = 0.0;
+ matrix[6] = 0.0; matrix[7] = 0.0; matrix[8] = 1.0;
+ }
+
+ return newcalrgb(csp, white, black, gamma, matrix);
+}
+
/*
* DeviceCMYK
*/
@@ -252,7 +353,7 @@ static inline float cielabinvg(float x)
return (7.787 * x) + (16.0 / 116.0);
}
-static void labtoxyz(fz_colorspace *fzcs, float *xyz, float *lab)
+static void labtoxyz(fz_colorspace *fzcs, float *lab, float *xyz)
{
struct cielab *cs = (struct cielab *) fzcs;
float lstar = lab[0];
@@ -303,8 +404,57 @@ newlab(fz_colorspace **csp, float *white, float *black, float *range)
return nil;
}
+static fz_error *
+loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
+{
+ fz_obj *tmp;
+
+ float white[3];
+ float black[3];
+ float range[4];
+
+ tmp = fz_dictgets(dict, "WhitePoint");
+ if (!fz_isarray(tmp))
+ return fz_throw("syntaxerror: Lab missing WhitePoint");
+ white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ white[2] = fz_toreal(fz_arrayget(tmp, 2));
+
+ tmp = fz_dictgets(dict, "BlackPoint");
+ if (fz_isarray(tmp))
+ {
+ black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ black[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+ else
+ {
+ black[0] = 0.0;
+ black[1] = 0.0;
+ black[2] = 0.0;
+ }
+
+ tmp = fz_dictgets(dict, "Range");
+ if (fz_isarray(tmp))
+ {
+ range[0] = fz_toreal(fz_arrayget(tmp, 0));
+ range[1] = fz_toreal(fz_arrayget(tmp, 1));
+ range[2] = fz_toreal(fz_arrayget(tmp, 2));
+ range[3] = fz_toreal(fz_arrayget(tmp, 3));
+ }
+ else
+ {
+ range[0] = -100;
+ range[1] = 100;
+ range[2] = -100;
+ range[3] = 100;
+ }
+
+ return newlab(csp, white, black, range);
+}
+
/*
- * Load from PDF
+ * ICCBased
*/
static fz_error *
@@ -333,6 +483,79 @@ loadiccbased(fz_colorspace **csp, pdf_xref *xref, fz_obj *ref)
}
/*
+ * Separation
+ */
+
+struct separation
+{
+ fz_colorspace super;
+ fz_colorspace *base;
+ pdf_function *tint;
+};
+
+static void separationtoxyz(fz_colorspace *fzcs, float *sep, float *xyz)
+{
+ struct separation *cs = (struct separation *)fzcs;
+ fz_error *error;
+ float alt[32];
+
+ error = pdf_evalfunction(cs->tint, sep, 1, alt, cs->base->n);
+ if (error)
+ {
+ fz_warn("separation: %s", error->msg);
+ fz_freeerror(error);
+ xyz[0] = 0;
+ xyz[1] = 0;
+ xyz[2] = 0;
+ return;
+ }
+
+ cs->base->toxyz(cs->base, alt, xyz);
+}
+
+fz_error *
+loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
+{
+ fz_error *error;
+ struct separation *sep;
+ fz_obj *baseobj = fz_arrayget(array, 2);
+ fz_obj *tintobj = fz_arrayget(array, 3);
+ fz_colorspace *base;
+ pdf_function *tint;
+
+ error = pdf_resolve(&baseobj, xref);
+ if (error)
+ return error;
+ error = pdf_loadcolorspace(&base, xref, baseobj);
+ fz_dropobj(baseobj);
+ if (error)
+ return error;
+
+ error = pdf_loadfunction(&tint, xref, tintobj);
+ if (error)
+ {
+ fz_freecolorspace(base);
+ return error;
+ }
+
+ sep = fz_malloc(sizeof(struct separation));
+ if (!sep)
+ {
+ pdf_freefunction(tint);
+ fz_freecolorspace(base);
+ return fz_outofmem;
+ }
+
+ initcs((fz_colorspace*)sep, "Separation", 1, separationtoxyz, nil, nil);
+
+ sep->base = base;
+ sep->tint = tint;
+
+ *csp = (fz_colorspace*)sep;
+ return nil;
+}
+
+/*
* Parse and create colorspace from PDF object.
*/
@@ -371,105 +594,10 @@ printf("\n");
if (fz_isname(name))
{
if (!strcmp(fz_toname(name), "CalGray"))
- {
- fz_obj *dict = fz_arrayget(obj, 1);
- fz_obj *tmp;
-
- float white[3];
- float black[3];
- float gamma;
-
- tmp = fz_dictgets(dict, "WhitePoint");
- if (!fz_isarray(tmp))
- return fz_throw("syntaxerror: CalGray missing WhitePoint");
- white[0] = fz_toreal(fz_arrayget(tmp, 0));
- white[1] = fz_toreal(fz_arrayget(tmp, 1));
- white[2] = fz_toreal(fz_arrayget(tmp, 2));
-
- tmp = fz_dictgets(dict, "BlackPoint");
- if (fz_isarray(tmp))
- {
- black[0] = fz_toreal(fz_arrayget(tmp, 0));
- black[1] = fz_toreal(fz_arrayget(tmp, 1));
- black[2] = fz_toreal(fz_arrayget(tmp, 2));
- }
- else
- {
- black[0] = 0.0;
- black[1] = 0.0;
- black[2] = 0.0;
- }
-
- tmp = fz_dictgets(dict, "Gamma");
- if (fz_isreal(tmp))
- gamma = fz_toreal(tmp);
- else
- gamma = 1.0;
-
- return newcalgray(csp, white, black, gamma);
- }
+ return loadcalgray(csp, xref, fz_arrayget(obj, 1));
if (!strcmp(fz_toname(name), "CalRGB"))
- {
- fz_obj *dict = fz_arrayget(obj, 1);
- fz_obj *tmp;
-
- float white[3];
- float black[3];
- float gamma[3];
- float matrix[9];
-
- tmp = fz_dictgets(dict, "WhitePoint");
- if (!fz_isarray(tmp))
- return fz_throw("syntaxerror: CalRGB missing White");
- white[0] = fz_toreal(fz_arrayget(tmp, 0));
- white[1] = fz_toreal(fz_arrayget(tmp, 1));
- white[2] = fz_toreal(fz_arrayget(tmp, 2));
-
- tmp = fz_dictgets(dict, "BlackPoint");
- if (fz_isarray(tmp))
- {
- black[0] = fz_toreal(fz_arrayget(tmp, 0));
- black[1] = fz_toreal(fz_arrayget(tmp, 1));
- black[2] = fz_toreal(fz_arrayget(tmp, 2));
- }
- else
- {
- black[0] = 0.0;
- black[1] = 0.0;
- black[2] = 0.0;
- }
-
- tmp = fz_dictgets(dict, "Gamma");
- if (fz_isarray(tmp))
- {
- gamma[0] = fz_toreal(fz_arrayget(tmp, 0));
- gamma[1] = fz_toreal(fz_arrayget(tmp, 1));
- gamma[2] = fz_toreal(fz_arrayget(tmp, 2));
- }
- else
- {
- gamma[0] = 1.0;
- gamma[1] = 1.0;
- gamma[2] = 1.0;
- }
-
- tmp = fz_dictgets(dict, "Matrix");
- if (fz_isarray(tmp))
- {
- int i;
- for (i = 0; i < 9; i++)
- matrix[i] = fz_toreal(fz_arrayget(tmp, i));
- }
- else
- {
- matrix[0] = 1.0; matrix[1] = 0.0; matrix[2] = 0.0;
- matrix[3] = 0.0; matrix[4] = 1.0; matrix[5] = 0.0;
- matrix[6] = 0.0; matrix[7] = 0.0; matrix[8] = 1.0;
- }
-
- return newcalrgb(csp, white, black, gamma, matrix);
- }
+ return loadcalrgb(csp, xref, fz_arrayget(obj, 1));
if (!strcmp(fz_toname(name), "CalCMYK"))
{
@@ -478,64 +606,13 @@ printf("\n");
}
if (!strcmp(fz_toname(name), "Lab"))
- {
- fz_obj *dict = fz_arrayget(obj, 1);
- fz_obj *tmp;
-
- float white[3];
- float black[3];
- float range[4];
-
- tmp = fz_dictgets(dict, "WhitePoint");
- if (!fz_isarray(tmp))
- return fz_throw("syntaxerror: Lab missing WhitePoint");
- white[0] = fz_toreal(fz_arrayget(tmp, 0));
- white[1] = fz_toreal(fz_arrayget(tmp, 1));
- white[2] = fz_toreal(fz_arrayget(tmp, 2));
-
- tmp = fz_dictgets(dict, "BlackPoint");
- if (fz_isarray(tmp))
- {
- black[0] = fz_toreal(fz_arrayget(tmp, 0));
- black[1] = fz_toreal(fz_arrayget(tmp, 1));
- black[2] = fz_toreal(fz_arrayget(tmp, 2));
- }
- else
- {
- black[0] = 0.0;
- black[1] = 0.0;
- black[2] = 0.0;
- }
-
- tmp = fz_dictgets(dict, "Range");
- if (fz_isarray(tmp))
- {
- range[0] = fz_toreal(fz_arrayget(tmp, 0));
- range[1] = fz_toreal(fz_arrayget(tmp, 1));
- range[2] = fz_toreal(fz_arrayget(tmp, 2));
- range[3] = fz_toreal(fz_arrayget(tmp, 3));
- }
- else
- {
- range[0] = -100;
- range[1] = 100;
- range[2] = -100;
- range[3] = 100;
- }
-
- return newlab(csp, white, black, range);
- }
+ return loadlab(csp, xref, fz_arrayget(obj, 1));
if (!strcmp(fz_toname(name), "ICCBased"))
- {
return loadiccbased(csp, xref, fz_arrayget(obj, 1));
- }
if (!strcmp(fz_toname(name), "Separation"))
- {
- *csp = pdf_devicegray;
- return nil;
- }
+ return loadseparation(csp, xref, obj);
}
}
diff --git a/mupdf/function.c b/mupdf/function.c
index 6ec76e66..fb71da89 100644
--- a/mupdf/function.c
+++ b/mupdf/function.c
@@ -1385,7 +1385,7 @@ cleanup:
}
void
-pdf_freefunc(pdf_function *func)
+pdf_freefunction(pdf_function *func)
{
int i;
@@ -1417,7 +1417,7 @@ pdf_freefunc(pdf_function *func)
fz_free(func->u.st.encode);
if(func->u.st.funcs) {
for(i = 0; i < func->u.st.k; ++i)
- pdf_freefunc(func->u.st.funcs[i]);
+ pdf_freefunction(func->u.st.funcs[i]);
fz_free(func->u.st.funcs);
}
@@ -1541,7 +1541,7 @@ cleanup:
if(objfunc)
fz_dropobj(objfunc);
- pdf_freefunc(newfunc);
+ pdf_freefunction(newfunc);
if(err) return err;
return fz_throw("syntaxerror : ");
diff --git a/mupdf/interpret.c b/mupdf/interpret.c
index 2d2b9a42..eb9f60e0 100644
--- a/mupdf/interpret.c
+++ b/mupdf/interpret.c
@@ -329,6 +329,8 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (!gstate->fillcs)
return fz_throw("syntaxerror: missing colorspace resource");
}
+
+ // FIXME set default color
}
else if (!strcmp(buf, "CS"))
@@ -365,6 +367,8 @@ runkeyword(pdf_csi *csi, pdf_xref *xref, fz_obj *rdb, char *buf)
if (!gstate->strokecs)
return fz_throw("syntaxerror: missing colorspace resource");
}
+
+ // FIXME set default color
}
else if (!strcmp(buf, "sc") || !strcmp(buf, "scn"))
diff --git a/render/renderimage.c b/render/renderimage.c
index 80b7b771..a89409c5 100644
--- a/render/renderimage.c
+++ b/render/renderimage.c
@@ -5,23 +5,28 @@
void fz_gammapixmap(fz_pixmap *pix, float gamma);
#define LERP(a,b,t) (a + (((b - a) * t) >> 16))
+#define OUTSIDE(x,a,b) (x < a || x >= b)
-static int getcomp(fz_pixmap *pix, int u, int v, int k)
+static inline int getcomp(fz_pixmap *pix, int u, int v, int k)
+{
+ if (u < 0 || u >= pix->w)
+ return 0;
+ if (v < 0 || v >= pix->h)
+ return 0;
+ return pix->samples[ (v * pix->w + u) * pix->n + k ];
+}
+
+static inline int sampleimage(fz_pixmap *pix, int u, int v, int k)
{
int ui = u >> 16;
int vi = v >> 16;
int ud = u & 0xFFFF;
int vd = v & 0xFFFF;
- int x0 = CLAMP(ui, 0, pix->w - 1);
- int x1 = CLAMP(ui + 1, 0, pix->w - 1);
- int y0 = CLAMP(vi, 0, pix->h - 1);
- int y1 = CLAMP(vi + 1, 0, pix->h - 1);
-
- int a = pix->samples[ (y0 * pix->w + x0) * pix->n + k ];
- int b = pix->samples[ (y0 * pix->w + x1) * pix->n + k ];
- int c = pix->samples[ (y1 * pix->w + x0) * pix->n + k ];
- int d = pix->samples[ (y1 * pix->w + x1) * pix->n + k ];
+ int a = getcomp(pix, ui, vi, k);
+ int b = getcomp(pix, ui + 1, vi, k);
+ int c = getcomp(pix, ui, vi + 1, k);
+ int d = getcomp(pix, ui + 1, vi + 1, k);
int ab = LERP(a, b, ud);
int cd = LERP(c, d, ud);
@@ -41,7 +46,8 @@ drawscan(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, int x
for (x = x0; x < x1; x++)
{
for (k = 0; k < src->n; k++)
- dst->samples[ (y * dst->w + x) * dst->n + k ] = getcomp(src, u, v, k);
+ dst->samples[ (y * dst->w + x) * dst->n + k ]
+ = sampleimage(src, u, v, k);
u += du;
v += dv;
}
@@ -59,10 +65,10 @@ overscanrgb(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, in
for (x = x0; x < x1; x++)
{
- int sa = getcomp(src, u, v, 0);
- int sr = getcomp(src, u, v, 1);
- int sg = getcomp(src, u, v, 2);
- int sb = getcomp(src, u, v, 3);
+ int sa = sampleimage(src, u, v, 0);
+ int sr = sampleimage(src, u, v, 1);
+ int sg = sampleimage(src, u, v, 2);
+ int sb = sampleimage(src, u, v, 3);
int da = dst->samples[ (y * dst->w + x) * dst->n + 0 ];
int dr = dst->samples[ (y * dst->w + x) * dst->n + 1 ];
diff --git a/test/pdffunction.c b/test/pdffunction.c
index d2acd691..c67e60d7 100644
--- a/test/pdffunction.c
+++ b/test/pdffunction.c
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
fprintf(stderr, "output[%d] : %f\n", i, out[i]);
fz_dropobj(funcobj);
- pdf_freefunc(func);
+ pdf_freefunction(func);
}
}