summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jamfile3
-rw-r--r--base/matrix.c35
-rw-r--r--include/fitz/geometry.h2
-rw-r--r--include/mupdf/rsrc.h4
-rw-r--r--mupdf/colorspace1.c (renamed from mupdf/colorspace.c)715
-rw-r--r--mupdf/font.c6
-rw-r--r--test/x11pdf.c41
-rw-r--r--tree/colorspace.c1
-rw-r--r--tree/debug.c2
9 files changed, 311 insertions, 498 deletions
diff --git a/Jamfile b/Jamfile
index 328b62a1..a92637ac 100644
--- a/Jamfile
+++ b/Jamfile
@@ -117,7 +117,8 @@ Library libmupdf :
mupdf/unicode.c
mupdf/font.c
mupdf/type3.c
- mupdf/colorspace.c
+ mupdf/colorspace1.c
+ mupdf/colorspace2.c
mupdf/image1.c
mupdf/image2.c
mupdf/xobject.c
diff --git a/base/matrix.c b/base/matrix.c
index 09a2de0f..2b831bf4 100644
--- a/base/matrix.c
+++ b/base/matrix.c
@@ -1,5 +1,40 @@
#include <fitz.h>
+void fz_invert3x3(float *dst, float *m)
+{
+ float det;
+ int i;
+
+#define M3(m,i,j) (m)[3*i+j]
+#define D2(a,b,c,d) (a * d - b * c)
+#define D3(a1,a2,a3,b1,b2,b3,c1,c2,c3) \
+ (a1 * D2(b2,b3,c2,c3)) - \
+ (b1 * D2(a2,a3,c2,c3)) + \
+ (c1 * D2(a2,a3,b2,b3))
+
+ det = D3(M3(m,0,0), M3(m,1,0), M3(m,2,0),
+ M3(m,0,1), M3(m,1,1), M3(m,2,1),
+ M3(m,0,2), M3(m,1,2), M3(m,2,2));
+ if (det == 0)
+ det = 1.0;
+ det = 1.0 / det;
+
+ M3(dst,0,0) = M3(m,1,1) * M3(m,2,2) - M3(m,1,2) * M3(m,2,1);
+ M3(dst,0,1) = -M3(m,0,1) * M3(m,2,2) + M3(m,0,2) * M3(m,2,1);
+ M3(dst,0,2) = M3(m,0,1) * M3(m,1,2) - M3(m,0,2) * M3(m,1,1);
+
+ M3(dst,1,0) = -M3(m,1,0) * M3(m,2,2) + M3(m,1,2) * M3(m,2,0);
+ M3(dst,1,1) = M3(m,0,0) * M3(m,2,2) - M3(m,0,2) * M3(m,2,0);
+ M3(dst,1,2) = -M3(m,0,0) * M3(m,1,2) + M3(m,0,2) * M3(m,1,0);
+
+ M3(dst,2,0) = M3(m,1,0) * M3(m,2,1) - M3(m,1,1) * M3(m,2,0);
+ M3(dst,2,1) = -M3(m,0,0) * M3(m,2,1) + M3(m,0,1) * M3(m,2,0);
+ M3(dst,2,2) = M3(m,0,0) * M3(m,1,1) - M3(m,0,1) * M3(m,1,0);
+
+ for (i = 0; i < 9; i++)
+ dst[i] *= det;
+}
+
fz_matrix
fz_concat(fz_matrix one, fz_matrix two)
{
diff --git a/include/fitz/geometry.h b/include/fitz/geometry.h
index af734f72..96977cc6 100644
--- a/include/fitz/geometry.h
+++ b/include/fitz/geometry.h
@@ -36,6 +36,8 @@ struct fz_irect_s
fz_ipoint max;
};
+void fz_invert3x3(float *dst, float *m);
+
fz_rect fz_infiniterect(void);
fz_matrix fz_concat(fz_matrix one, fz_matrix two);
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index 898ff8c5..9139a8e5 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -40,6 +40,10 @@ struct pdf_indexed_s
extern fz_colorspace *pdf_devicegray;
extern fz_colorspace *pdf_devicergb;
extern fz_colorspace *pdf_devicecmyk;
+extern fz_colorspace *pdf_devicelab;
+
+void pdf_convcolor(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv);
+void pdf_convpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
fz_error *pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj);
diff --git a/mupdf/colorspace.c b/mupdf/colorspace1.c
index 6ae6c4a6..d666904d 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace1.c
@@ -1,7 +1,7 @@
#include <fitz.h>
#include <mupdf.h>
-static void fastpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
+#define noUSECAL
static void initcs(fz_colorspace *cs, char *name, int n,
void(*to)(fz_colorspace*,float*,float*),
@@ -10,51 +10,16 @@ static void initcs(fz_colorspace *cs, char *name, int n,
{
strlcpy(cs->name, name, sizeof cs->name);
cs->refs = 1;
- cs->convpixmap = fastpixmap;
- cs->convcolor = fz_stdconvcolor;
+ cs->convpixmap = pdf_convpixmap;
+ cs->convcolor = pdf_convcolor;
cs->toxyz = to;
cs->fromxyz = from;
cs->drop = drop;
cs->n = n;
}
-static void mat3x3inv(float *dst, float *m)
-{
- float det;
- int i;
-
-#define M3(m,i,j) (m)[3*i+j]
-#define D2(a,b,c,d) (a * d - b * c)
-#define D3(a1,a2,a3,b1,b2,b3,c1,c2,c3) \
- (a1 * D2(b2,b3,c2,c3)) - \
- (b1 * D2(a2,a3,c2,c3)) + \
- (c1 * D2(a2,a3,b2,b3))
-
- det = D3(M3(m,0,0), M3(m,1,0), M3(m,2,0),
- M3(m,0,1), M3(m,1,1), M3(m,2,1),
- M3(m,0,2), M3(m,1,2), M3(m,2,2));
- if (det == 0)
- det = 1.0;
- det = 1.0 / det;
-
- M3(dst,0,0) = M3(m,1,1) * M3(m,2,2) - M3(m,1,2) * M3(m,2,1);
- M3(dst,0,1) = -M3(m,0,1) * M3(m,2,2) + M3(m,0,2) * M3(m,2,1);
- M3(dst,0,2) = M3(m,0,1) * M3(m,1,2) - M3(m,0,2) * M3(m,1,1);
-
- M3(dst,1,0) = -M3(m,1,0) * M3(m,2,2) + M3(m,1,2) * M3(m,2,0);
- M3(dst,1,1) = M3(m,0,0) * M3(m,2,2) - M3(m,0,2) * M3(m,2,0);
- M3(dst,1,2) = -M3(m,0,0) * M3(m,1,2) + M3(m,0,2) * M3(m,1,0);
-
- M3(dst,2,0) = M3(m,1,0) * M3(m,2,1) - M3(m,1,1) * M3(m,2,0);
- M3(dst,2,1) = -M3(m,0,0) * M3(m,2,1) + M3(m,0,1) * M3(m,2,0);
- M3(dst,2,2) = M3(m,0,0) * M3(m,1,1) - M3(m,0,1) * M3(m,1,0);
-
- for (i = 0; i < 9; i++)
- dst[i] *= det;
-}
-
/*
- * DeviceGray
+ * CalGray
*/
struct calgray
@@ -68,95 +33,22 @@ struct calgray
static void graytoxyz(fz_colorspace *fzcs, float *gray, float *xyz)
{
struct calgray *cs = (struct calgray *) fzcs;
- xyz[0] = cs->white[0] * pow(gray[0], cs->gamma);
- xyz[1] = cs->white[1] * pow(gray[0], cs->gamma);
- xyz[2] = cs->white[2] * pow(gray[0], cs->gamma);
+ xyz[0] = pow(gray[0], cs->gamma) * cs->white[0];
+ xyz[1] = pow(gray[0], cs->gamma) * cs->white[1];
+ xyz[2] = pow(gray[0], cs->gamma) * cs->white[2];
}
static void xyztogray(fz_colorspace *fzcs, float *xyz, float *gray)
{
struct calgray *cs = (struct calgray *) fzcs;
- float r = pow(xyz[0], 1.0 / cs->gamma);
- float g = pow(xyz[1], 1.0 / cs->gamma);
- float b = pow(xyz[2], 1.0 / cs->gamma);
+ float r = pow(xyz[0], 1.0 / cs->gamma) / cs->white[0];
+ float g = pow(xyz[1], 1.0 / cs->gamma) / cs->white[1];
+ float b = pow(xyz[2], 1.0 / cs->gamma) / cs->white[2];
gray[0] = r * 0.3 + g * 0.59 + b * 0.11;
}
-static struct calgray kdevicegray =
-{
- { -1, "DeviceGray", 1, fastpixmap, fz_stdconvcolor, graytoxyz, xyztogray, nil },
- { 1.0000, 1.0000, 1.0000 },
- { 0.0000, 0.0000, 0.0000 },
- 2.2000
-};
-
-fz_colorspace *pdf_devicegray = &kdevicegray.super;
-
-static fz_error *
-newcalgray(fz_colorspace **csp, float *white, float *black, float gamma)
-{
- struct calgray *cs;
- int i;
-
- cs = fz_malloc(sizeof(struct calgray));
- if (!cs)
- return fz_outofmem;
-
- initcs((fz_colorspace*)cs, "CalGray", 1, graytoxyz, xyztogray, nil);
-
- for (i = 0; i < 3; i++)
- {
- cs->white[i] = white[i];
- cs->black[i] = black[i];
- }
-
- cs->gamma = gamma;
-
- *csp = (fz_colorspace*) cs;
- 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
+ * CalRGB
*/
struct calrgb
@@ -172,9 +64,9 @@ struct calrgb
static void rgbtoxyz(fz_colorspace *fzcs, float *rgb, float *xyz)
{
struct calrgb *cs = (struct calrgb *) fzcs;
- float a = pow(rgb[0], cs->gamma[0]);
- float b = pow(rgb[1], cs->gamma[1]);
- float c = pow(rgb[2], cs->gamma[2]);
+ float a = pow(rgb[0], cs->gamma[0]) * cs->white[0];
+ float b = pow(rgb[1], cs->gamma[1]) * cs->white[1];
+ float c = pow(rgb[2], cs->gamma[2]) * cs->white[2];
xyz[0] = a * cs->matrix[0] + b * cs->matrix[1] + c * cs->matrix[2];
xyz[1] = a * cs->matrix[3] + b * cs->matrix[4] + c * cs->matrix[5];
xyz[2] = a * cs->matrix[6] + b * cs->matrix[7] + c * cs->matrix[8];
@@ -186,119 +78,13 @@ static void xyztorgb(fz_colorspace *fzcs, float *xyz, float *rgb)
float a = xyz[0] * cs->invmat[0] + xyz[1] * cs->invmat[1] + xyz[2] * cs->invmat[2];
float b = xyz[0] * cs->invmat[3] + xyz[1] * cs->invmat[4] + xyz[2] * cs->invmat[5];
float c = xyz[0] * cs->invmat[6] + xyz[1] * cs->invmat[7] + xyz[2] * cs->invmat[8];
- rgb[0] = pow(a, 1.0 / cs->gamma[0]);
- rgb[1] = pow(b, 1.0 / cs->gamma[1]);
- rgb[2] = pow(c, 1.0 / cs->gamma[2]);
-}
-
-static struct calrgb kdevicergb =
-{
- { -1, "DeviceRGB", 3, fastpixmap, fz_stdconvcolor, rgbtoxyz, xyztorgb, nil },
- { 1.0000, 1.0000, 1.0000 },
- { 0.0000, 0.0000, 0.0000 },
- { 2.2000, 2.2000, 2.2000 },
- { 1.0000, 0.0000, 0.0000,
- 0.0000, 1.0000, 0.0000,
- 0.0000, 0.0000, 1.0000 },
- { 1.0000, 0.0000, 0.0000,
- 0.0000, 1.0000, 0.0000,
- 0.0000, 0.0000, 1.0000 }
-};
-
-fz_colorspace *pdf_devicergb = &kdevicergb.super;
-
-static fz_error *
-newcalrgb(fz_colorspace **csp, float *white, float *black, float *gamma, float *matrix)
-{
- struct calrgb *cs;
- int i;
-
- cs = fz_malloc(sizeof(struct calrgb));
- if (!cs)
- return fz_outofmem;
-
- initcs((fz_colorspace*)cs, "CalRGB", 3, rgbtoxyz, xyztorgb, nil);
-
- for (i = 0; i < 3; i++)
- {
- cs->white[i] = white[i];
- cs->black[i] = black[i];
- cs->gamma[i] = gamma[i];
- }
-
- for (i = 0; i < 9; i++)
- cs->matrix[i] = matrix[i];
-
- mat3x3inv(cs->invmat, cs->matrix);
-
- *csp = (fz_colorspace*) cs;
- 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);
+ rgb[0] = pow(a, 1.0 / cs->gamma[0]) / cs->white[0];
+ rgb[1] = pow(b, 1.0 / cs->gamma[1]) / cs->white[1];
+ rgb[2] = pow(c, 1.0 / cs->gamma[2]) / cs->white[2];
}
/*
- * DeviceCMYK
+ * DeviceCMYK piggybacks on DeviceRGB
*/
static void devicecmyktoxyz(fz_colorspace *cs, float *cmyk, float *xyz)
@@ -325,13 +111,6 @@ static void xyztodevicecmyk(fz_colorspace *cs, float *xyz, float *cmyk)
cmyk[3] = k;
}
-static fz_colorspace kdevicecmyk =
-{
- -1, "DeviceCMYK", 4, fastpixmap, fz_stdconvcolor, devicecmyktoxyz, xyztodevicecmyk, nil
-};
-
-fz_colorspace *pdf_devicecmyk = &kdevicecmyk;
-
/*
* CIE Lab
*/
@@ -344,14 +123,14 @@ struct cielab
float range[4];
};
-static inline float cielabg(float x)
+static inline float fung(float x)
{
if (x >= 6.0 / 29.0)
return x * x * x;
return (108.0 / 841.0) * (x - (4.0 / 29.0));
}
-static inline float cielabinvg(float x)
+static inline float invg(float x)
{
if (x > 0.008856)
return pow(x, 1.0 / 3.0);
@@ -369,12 +148,12 @@ static void labtoxyz(fz_colorspace *fzcs, float *lab, float *xyz)
lstar = tmp[0];
astar = MAX(MIN(tmp[1], cs->range[1]), cs->range[0]);
bstar = MAX(MIN(tmp[2], cs->range[3]), cs->range[2]);
- l = ((lstar * 16.0) / 116.0) + (astar / 500.0);
- m = (lstar * 16.0) / 116.0;
- n = ((lstar * 16.0) / 116.0) - (bstar / 200.0);
- xyz[0] = cs->white[0] * cielabg(l);
- xyz[1] = cs->white[1] * cielabg(m);
- xyz[2] = cs->white[2] * cielabg(n);
+ l = (lstar + 16.0) / 116.0 + astar / 500.0;
+ m = (lstar + 16.0) / 116.0;
+ n = (lstar + 16.0) / 116.0 - bstar / 200.0;
+ xyz[0] = fung(l) * cs->white[0];
+ xyz[1] = fung(m) * cs->white[1];
+ xyz[2] = fung(n) * cs->white[2];
}
static void xyztolab(fz_colorspace *fzcs, float *xyz, float *lab)
@@ -386,87 +165,227 @@ static void xyztolab(fz_colorspace *fzcs, float *xyz, float *lab)
tmp[0] = 116.0 * yyn * (1.0 / 3.0) - 16.0;
else
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]));
+ tmp[1] = 500 * (invg(xyz[0]/cs->white[0]) - invg(xyz[1]/cs->white[1]));
+ tmp[2] = 200 * (invg(xyz[1]/cs->white[1]) - invg(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;
}
+/*
+ * Define global Device* colorspaces as Cal*
+ */
+
+static struct calgray kdevicegray =
+{
+ { -1, "DeviceGray", 1, pdf_convpixmap, pdf_convcolor, graytoxyz, xyztogray, nil },
+ { 1.0000, 1.0000, 1.0000 },
+ { 0.0000, 0.0000, 0.0000 },
+ 1.0000
+};
+
+static struct calrgb kdevicergb =
+{
+ { -1, "DeviceRGB", 3, pdf_convpixmap, pdf_convcolor, rgbtoxyz, xyztorgb, nil },
+ { 1.0000, 1.0000, 1.0000 },
+ { 0.0000, 0.0000, 0.0000 },
+ { 1.0000, 1.0000, 1.0000 },
+ { 1,0,0, 0,1,0, 0,0,1 },
+ { 1,0,0, 0,1,0, 0,0,1 },
+};
+
+static fz_colorspace kdevicecmyk =
+{
+ -1, "DeviceCMYK", 4, pdf_convpixmap, pdf_convcolor, devicecmyktoxyz, xyztodevicecmyk, nil
+};
+
+static struct cielab kdevicelab =
+{
+ { -1, "Lab", 3, fz_stdconvpixmap, fz_stdconvcolor, labtoxyz, xyztolab, nil },
+ { 1.0000, 1.0000, 1.0000 },
+ { 0.0000, 0.0000, 0.0000 },
+ { -100, 100, -100, 100 },
+};
+
+fz_colorspace *pdf_devicegray = &kdevicegray.super;
+fz_colorspace *pdf_devicergb = &kdevicergb.super;
+fz_colorspace *pdf_devicecmyk = &kdevicecmyk;
+fz_colorspace *pdf_devicelab = &kdevicelab.super;
+
+/*
+ * Colorspace parsing
+ */
+
+#ifdef USECAL
+
static fz_error *
-newlab(fz_colorspace **csp, float *white, float *black, float *range)
+loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
- struct cielab *cs;
- int i;
+ struct calgray *cs;
+ fz_obj *tmp;
- cs = fz_malloc(sizeof(struct cielab));
+ cs = fz_malloc(sizeof(struct calgray));
if (!cs)
return fz_outofmem;
- initcs((fz_colorspace*)cs, "Lab", 3, labtoxyz, xyztolab, nil);
+ initcs((fz_colorspace*)cs, "CalGray", 1, graytoxyz, xyztogray, nil);
+
+ cs->white[0] = 1.0;
+ cs->white[1] = 1.0;
+ cs->white[2] = 1.0;
+
+ cs->black[0] = 0.0;
+ cs->black[1] = 0.0;
+ cs->black[2] = 0.0;
+
+ cs->gamma = 1.0;
- for (i = 0; i < 3; i++)
+ tmp = fz_dictgets(dict, "WhitePoint");
+ if (fz_isarray(tmp))
+ {
+ cs->white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->white[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+
+ tmp = fz_dictgets(dict, "BlackPoint");
+ if (fz_isarray(tmp))
{
- cs->white[i] = white[i];
- cs->black[i] = black[i];
+ cs->black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->black[2] = fz_toreal(fz_arrayget(tmp, 2));
}
- for (i = 0; i < 4; i++)
- cs->range[i] = range[i];
+ tmp = fz_dictgets(dict, "Gamma");
+ if (fz_isreal(tmp))
+ cs->gamma = fz_toreal(tmp);
*csp = (fz_colorspace*) cs;
return nil;
}
static fz_error *
-loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
+loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
+ struct calrgb *cs;
fz_obj *tmp;
+ int i;
- float white[3];
- float black[3];
- float range[4];
+ cs = fz_malloc(sizeof(struct calrgb));
+ if (!cs)
+ return fz_outofmem;
+
+ initcs((fz_colorspace*)cs, "CalRGB", 3, rgbtoxyz, xyztorgb, nil);
+
+ cs->white[0] = 1.0;
+ cs->white[1] = 1.0;
+ cs->white[2] = 1.0;
+
+ cs->black[0] = 0.0;
+ cs->black[1] = 0.0;
+ cs->black[2] = 0.0;
+
+ cs->gamma[0] = 1.0;
+ cs->gamma[1] = 1.0;
+ cs->gamma[2] = 1.0;
+
+ cs->matrix[0] = 1.0; cs->matrix[1] = 0.0; cs->matrix[2] = 0.0;
+ cs->matrix[3] = 0.0; cs->matrix[4] = 1.0; cs->matrix[5] = 0.0;
+ cs->matrix[6] = 0.0; cs->matrix[7] = 0.0; cs->matrix[8] = 1.0;
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));
+ if (fz_isarray(tmp))
+ {
+ cs->white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->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));
+ cs->black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->black[2] = fz_toreal(fz_arrayget(tmp, 2));
}
- else
+
+ tmp = fz_dictgets(dict, "Gamma");
+ if (fz_isarray(tmp))
{
- black[0] = 0.0;
- black[1] = 0.0;
- black[2] = 0.0;
+ cs->gamma[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->gamma[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->gamma[2] = fz_toreal(fz_arrayget(tmp, 2));
}
- tmp = fz_dictgets(dict, "Range");
+ tmp = fz_dictgets(dict, "Matrix");
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));
+ for (i = 0; i < 9; i++)
+ cs->matrix[i] = fz_toreal(fz_arrayget(tmp, i));
}
- else
+
+ fz_invert3x3(cs->invmat, cs->matrix);
+
+ *csp = (fz_colorspace*) cs;
+ return nil;
+}
+
+static fz_error *
+loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
+{
+ struct cielab *cs;
+ fz_obj *tmp;
+
+ cs = fz_malloc(sizeof(struct cielab));
+ if (!cs)
+ return fz_outofmem;
+
+ initcs((fz_colorspace*)cs, "Lab", 3, labtoxyz, xyztolab, nil);
+
+ cs->white[0] = 1.0;
+ cs->white[1] = 1.0;
+ cs->white[2] = 1.0;
+
+ cs->black[0] = 0.0;
+ cs->black[1] = 0.0;
+ cs->black[2] = 0.0;
+
+ cs->range[0] = -100;
+ cs->range[1] = 100;
+ cs->range[2] = -100;
+ cs->range[3] = 100;
+
+ tmp = fz_dictgets(dict, "WhitePoint");
+ if (fz_isarray(tmp))
+ {
+ cs->white[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->white[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->white[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+
+ tmp = fz_dictgets(dict, "BlackPoint");
+ if (fz_isarray(tmp))
+ {
+ cs->black[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->black[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->black[2] = fz_toreal(fz_arrayget(tmp, 2));
+ }
+
+ tmp = fz_dictgets(dict, "Range");
+ if (fz_isarray(tmp))
{
- range[0] = -100;
- range[1] = 100;
- range[2] = -100;
- range[3] = 100;
+ cs->range[0] = fz_toreal(fz_arrayget(tmp, 0));
+ cs->range[1] = fz_toreal(fz_arrayget(tmp, 1));
+ cs->range[2] = fz_toreal(fz_arrayget(tmp, 2));
+ cs->range[3] = fz_toreal(fz_arrayget(tmp, 3));
}
- return newlab(csp, white, black, range);
+ *csp = (fz_colorspace*) cs;
+ return nil;
}
+#endif
+
/*
* ICCBased
*/
@@ -497,7 +416,7 @@ loadiccbased(fz_colorspace **csp, pdf_xref *xref, fz_obj *ref)
}
/*
- * Separation
+ * Separation and DeviceN
*/
struct separation
@@ -590,7 +509,6 @@ loadseparation(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
* Indexed
*/
-/* only called for images... */
static void
indexedtoxyz(fz_colorspace *fzcs, float *ind, float *xyz)
{
@@ -693,40 +611,20 @@ pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj)
if (fz_isname(obj))
{
if (!strcmp(fz_toname(obj), "DeviceGray"))
- {
*csp = pdf_devicegray;
- return nil;
- }
-
- if (!strcmp(fz_toname(obj), "DeviceRGB"))
- {
+ else if (!strcmp(fz_toname(obj), "DeviceRGB"))
*csp = pdf_devicergb;
- return nil;
- }
-
- if (!strcmp(fz_toname(obj), "DeviceCMYK"))
- {
+ else if (!strcmp(fz_toname(obj), "DeviceCMYK"))
*csp = pdf_devicecmyk;
- return nil;
- }
-
- if (!strcmp(fz_toname(obj), "G"))
- {
+ else if (!strcmp(fz_toname(obj), "G"))
*csp = pdf_devicegray;
- return nil;
- }
-
- if (!strcmp(fz_toname(obj), "RGB"))
- {
+ else if (!strcmp(fz_toname(obj), "RGB"))
*csp = pdf_devicergb;
- return nil;
- }
-
- if (!strcmp(fz_toname(obj), "CMYK"))
- {
+ else if (!strcmp(fz_toname(obj), "CMYK"))
*csp = pdf_devicecmyk;
- return nil;
- }
+ else
+ return fz_throw("unknown colorspace: %s", fz_toname(obj));
+ return nil;
}
else if (fz_isarray(obj))
@@ -735,184 +633,51 @@ pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj)
if (fz_isname(name))
{
- if (!strcmp(fz_toname(name), "CalGray"))
- {
- *csp = pdf_devicegray;
- return nil;
- return loadcalgray(csp, xref, fz_arrayget(obj, 1));
- }
-
- if (!strcmp(fz_toname(name), "CalRGB"))
- {
- *csp = pdf_devicergb;
- return nil;
- return loadcalrgb(csp, xref, fz_arrayget(obj, 1));
- }
-
if (!strcmp(fz_toname(name), "CalCMYK"))
- {
*csp = pdf_devicecmyk;
- return nil;
- }
- if (!strcmp(fz_toname(name), "Lab"))
+#ifdef USECAL
+ else if (!strcmp(fz_toname(name), "CalGray"))
+ return loadcalgray(csp, xref, fz_arrayget(obj, 1));
+ else if (!strcmp(fz_toname(name), "CalRGB"))
+ return loadcalrgb(csp, xref, fz_arrayget(obj, 1));
+ else if (!strcmp(fz_toname(name), "Lab"))
return loadlab(csp, xref, fz_arrayget(obj, 1));
+#else
+ else if (!strcmp(fz_toname(name), "CalGray"))
+ *csp = pdf_devicegray;
+ else if (!strcmp(fz_toname(name), "CalRGB"))
+ *csp = pdf_devicergb;
+ else if (!strcmp(fz_toname(name), "Lab"))
+ *csp = pdf_devicelab;
+#endif
- if (!strcmp(fz_toname(name), "ICCBased"))
+ else if (!strcmp(fz_toname(name), "ICCBased"))
return loadiccbased(csp, xref, fz_arrayget(obj, 1));
- if (!strcmp(fz_toname(name), "Indexed"))
+ else if (!strcmp(fz_toname(name), "Indexed"))
return loadindexed(csp, xref, obj);
- if (!strcmp(fz_toname(name), "I"))
+ else if (!strcmp(fz_toname(name), "I"))
return loadindexed(csp, xref, obj);
- if (!strcmp(fz_toname(name), "Separation"))
+ else if (!strcmp(fz_toname(name), "Separation"))
return loadseparation(csp, xref, obj);
- if (!strcmp(fz_toname(name), "DeviceN"))
+ else if (!strcmp(fz_toname(name), "DeviceN"))
return loadseparation(csp, xref, obj);
- /* pretend this never happened... */
- if (!strcmp(fz_toname(name), "Pattern"))
- {
+ /* load base colorspace instead */
+ else if (!strcmp(fz_toname(name), "Pattern"))
return pdf_loadcolorspace(csp, xref, fz_arrayget(obj, 1));
- }
- }
- }
-
- return fz_throw("syntaxerror: could not parse color space");
-}
-
-/*
- * Optimized color conversions for device*
- */
-static void fastgraytorgb(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- d[0] = s[0];
- d[1] = s[1];
- d[2] = s[1];
- d[3] = s[1];
- s += 2;
- d += 4;
- }
-}
+ else
+ return fz_throw("syntaxerror: unknown colorspace %s", fz_toname(name));
-static void fastgraytocmyk(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- d[0] = s[0];
- d[1] = 0;
- d[2] = 0;
- d[3] = 0;
- d[4] = s[1];
- s += 2;
- d += 5;
- }
-}
-
-static void fastrgbtogray(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- d[0] = s[0];
- d[1] = ((s[1]+1) * 77 + (s[2]+1) * 150 + (s[3]+1) * 28) >> 8;
- s += 4;
- d += 2;
- }
-}
-
-static void fastrgbtocmyk(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- unsigned char c = 255 - s[1];
- unsigned char m = 255 - s[2];
- unsigned char y = 255 - s[3];
- unsigned char k = MIN(c, MIN(y, k));
- d[0] = s[0];
- d[1] = c - k;
- d[2] = m - k;
- d[3] = y - k;
- d[4] = k;
- s += 4;
- d += 5;
- }
-}
-
-static void fastcmyktogray(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- unsigned char c = fz_mul255(s[1], 66);
- unsigned char m = fz_mul255(s[2], 150);
- unsigned char y = fz_mul255(s[3], 28);
- d[0] = s[0];
- d[1] = 255 - MIN(c + m + y + s[4], 255);
- s += 5;
- d += 2;
- }
-}
-
-static void fastcmyktorgb(fz_pixmap *src, fz_pixmap *dst)
-{
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
- int n = src->w * src->h;
- while (n--)
- {
- d[0] = s[0];
- d[1] = 255 - MIN(s[1] + s[4], 255);
- d[2] = 255 - MIN(s[2] + s[4], 255);
- d[3] = 255 - MIN(s[3] + s[4], 255);
- s += 5;
- d += 4;
- }
-}
-
-static void fastpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp)
-{
- if (ss == pdf_devicegray)
- {
- if (ds == pdf_devicergb) fastgraytorgb(sp, dp);
- else if (ds == pdf_devicecmyk) fastgraytocmyk(sp, dp);
- else fz_stdconvpixmap(ss, sp, ds, dp);
- }
-
- else if (ss == pdf_devicergb)
- {
- if (ds == pdf_devicegray) fastrgbtogray(sp, dp);
- else if (ds == pdf_devicecmyk) fastrgbtocmyk(sp, dp);
- else fz_stdconvpixmap(ss, sp, ds, dp);
-
- }
-
- else if (ss == pdf_devicecmyk)
- {
- if (ds == pdf_devicegray) fastcmyktogray(sp, dp);
- else if (ds == pdf_devicergb) fastcmyktorgb(sp, dp);
- else fz_stdconvpixmap(ss, sp, ds, dp);
+ return nil;
+ }
}
- else fz_stdconvpixmap(ss, sp, ds, dp);
+ return fz_throw("syntaxerror: could not parse color space");
}
diff --git a/mupdf/font.c b/mupdf/font.c
index b3fb6fc7..229ef932 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -135,7 +135,7 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP);
if (fterr)
- return fz_throw("freetype failed to load glyph: 0x%x", fterr);
+ fz_warn("freetype load glyph: 0x%x", fterr);
#else
@@ -151,13 +151,13 @@ ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
if (fterr)
- return fz_throw("freetype failed to load glyph: 0x%x", fterr);
+ fz_warn("freetype load glyph: 0x%x", fterr);
#endif
fterr = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
if (fterr)
- return fz_throw("freetype failed to render glyph: 0x%x", fterr);
+ fz_warn("freetype render glyph: 0x%x", fterr);
glyph->w = face->glyph->bitmap.width;
glyph->h = face->glyph->bitmap.rows;
diff --git a/test/x11pdf.c b/test/x11pdf.c
index e0724076..9b1e94c7 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -24,6 +24,8 @@ static XEvent xevt;
static int mapped = 0;
static Cursor xcarrow, xchand, xcwait;
+static char doctitle[256];
+
static float zoom = 1.0;
static int rotate = 0;
static int pageno = 1;
@@ -181,6 +183,12 @@ Lskipload:
XDefineCursor(xdpy, xwin, xcarrow);
XFlush(xdpy);
+ {
+ char buf[512];
+ sprintf(buf, "%s - %d/%d", doctitle, pageno, count);
+ xtitle(buf);
+ }
+
xresize();
xblit();
}
@@ -188,6 +196,7 @@ Lskipload:
static void pdfopen(char *filename, char *password)
{
fz_error *error;
+ fz_obj *obj;
error = pdf_openpdf(&xref, filename);
if (error)
@@ -208,6 +217,20 @@ static void pdfopen(char *filename, char *password)
count = pdf_getpagecount(pages);
+ strlcpy(doctitle, filename, sizeof doctitle);
+ obj = fz_dictgets(xref->trailer, "Info");
+ if (fz_isindirect(obj))
+ {
+ pdf_resolve(&obj, xref);
+ obj = fz_dictgets(obj, "Title");
+ if (obj)
+ {
+ int n = MIN(fz_tostringlen(obj) + 1, sizeof doctitle);
+ if (obj)
+ strlcpy(doctitle, fz_tostringbuf(obj), n);
+ }
+ }
+
error = fz_newrenderer(&rast, pdf_devicergb, 1024 * 512);
if (error) fz_abort(error);
@@ -320,8 +343,6 @@ static void handlekey(int c)
int main(int argc, char **argv)
{
char *filename;
- fz_obj *obj;
- char buf[256];
int c;
char *password = "";
@@ -347,22 +368,6 @@ int main(int argc, char **argv)
pdfopen(filename, password);
showpage();
- strlcpy(buf, filename, sizeof buf);
- obj = fz_dictgets(xref->trailer, "Info");
- if (fz_isindirect(obj))
- {
- pdf_resolve(&obj, xref);
- obj = fz_dictgets(obj, "Title");
- if (obj)
- {
- int n = MIN(fz_tostringlen(obj) + 1, sizeof buf);
- if (obj)
- strlcpy(buf, fz_tostringbuf(obj), n);
- printf("Title: %s\n", buf);
- }
- }
- xtitle(buf);
-
while (1)
{
int len;
diff --git a/tree/colorspace.c b/tree/colorspace.c
index 799011f3..f5025468 100644
--- a/tree/colorspace.c
+++ b/tree/colorspace.c
@@ -37,6 +37,7 @@ fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *ds
{
float xyz[3];
int i;
+
if (srcs != dsts)
{
srcs->toxyz(srcs, srcv, xyz);
diff --git a/tree/debug.c b/tree/debug.c
index 2f112b9c..cbfffc20 100644
--- a/tree/debug.c
+++ b/tree/debug.c
@@ -71,7 +71,7 @@ static void lispcolor(fz_colornode *node, int level)
{
int i;
indent(level);
- printf("(color ");
+ printf("(color %s ", node->cs->name);
for (i = 0; i < node->n; i++)
printf("%g ", node->samples[i]);
printf(")\n");