diff options
-rw-r--r-- | Jamfile | 3 | ||||
-rw-r--r-- | base/matrix.c | 35 | ||||
-rw-r--r-- | include/fitz/geometry.h | 2 | ||||
-rw-r--r-- | include/mupdf/rsrc.h | 4 | ||||
-rw-r--r-- | mupdf/colorspace1.c (renamed from mupdf/colorspace.c) | 715 | ||||
-rw-r--r-- | mupdf/font.c | 6 | ||||
-rw-r--r-- | test/x11pdf.c | 41 | ||||
-rw-r--r-- | tree/colorspace.c | 1 | ||||
-rw-r--r-- | tree/debug.c | 2 |
9 files changed, 311 insertions, 498 deletions
@@ -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"); |