diff options
author | Tor Andersson <tor@ghostscript.com> | 2005-05-18 09:39:48 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2005-05-18 09:39:48 +0200 |
commit | 667a353692f00dfc7f05126c9809de0b487260a0 (patch) | |
tree | 9e5d334e8672cf52596e530e429d1c66e989fe48 | |
parent | b217e8969bea48bb47a656ea82249766406280dd (diff) | |
download | mupdf-667a353692f00dfc7f05126c9809de0b487260a0.tar.xz |
clean up and isolate jeongs shading code
-rw-r--r-- | Jamfile | 5 | ||||
-rw-r--r-- | include/mupdf/content.h | 6 | ||||
-rw-r--r-- | mupdf/pdf_function.c | 2 | ||||
-rw-r--r-- | mupdf/pdf_shade.c | 24 | ||||
-rw-r--r-- | mupdf/pdf_shade1.c | 262 | ||||
-rw-r--r-- | mupdf/pdf_shade2.c | 118 | ||||
-rw-r--r-- | mupdf/pdf_shade3.c | 151 | ||||
-rw-r--r-- | mupdf/pdf_shade4.c | 641 | ||||
-rw-r--r-- | mupdf/pdf_shade5.c | 168 | ||||
-rw-r--r-- | mupdf/pdf_shade6.c | 360 | ||||
-rw-r--r-- | mupdf/pdf_shade7.c | 151 |
11 files changed, 916 insertions, 972 deletions
@@ -250,12 +250,7 @@ Library libmupdf : pdf_pattern.c pdf_shade.c pdf_shade1.c - pdf_shade2.c - pdf_shade3.c pdf_shade4.c - pdf_shade5.c - pdf_shade6.c - pdf_shade7.c pdf_xobject.c # pages, resource dictionaries, ... diff --git a/include/mupdf/content.h b/include/mupdf/content.h index b28193b6..adc5757a 100644 --- a/include/mupdf/content.h +++ b/include/mupdf/content.h @@ -5,7 +5,6 @@ typedef struct pdf_material_s pdf_material; typedef struct pdf_gstate_s pdf_gstate; typedef struct pdf_csi_s pdf_csi; -typedef struct pdf_tensorpatch_s pdf_tensorpatch; enum { @@ -85,11 +84,6 @@ struct pdf_csi_s fz_tree *tree; }; -struct pdf_tensorpatch_s { - fz_point pole[4][4]; - float color[4][FZ_MAXCOLORS]; -}; - /* build.c */ void pdf_initgstate(pdf_gstate *gs); fz_error *pdf_setcolorspace(pdf_csi *csi, int what, fz_colorspace *cs); diff --git a/mupdf/pdf_function.c b/mupdf/pdf_function.c index 2cedefba..d6279ef4 100644 --- a/mupdf/pdf_function.c +++ b/mupdf/pdf_function.c @@ -1,7 +1,7 @@ #include <fitz.h> #include <mupdf.h> -/* author: seokgyo@gmail.com */ +/* this mess is seokgyo's */ enum { diff --git a/mupdf/pdf_shade.c b/mupdf/pdf_shade.c index baab4e4b..7da1824a 100644 --- a/mupdf/pdf_shade.c +++ b/mupdf/pdf_shade.c @@ -129,18 +129,18 @@ loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_m error = pdf_loadtype4shade(shade, xref, dict, ref); if (error) goto cleanup; break; - case 5:
- error = pdf_loadtype5shade(shade, xref, dict, ref);
- if (error) goto cleanup;
- break;
- case 6:
- error = pdf_loadtype6shade(shade, xref, dict, ref);
- if (error) goto cleanup;
- break;
- case 7:
- error = pdf_loadtype7shade(shade, xref, dict, ref);
- if (error) goto cleanup;
- break;
+ case 5: + error = pdf_loadtype5shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 6: + error = pdf_loadtype6shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; + case 7: + error = pdf_loadtype7shade(shade, xref, dict, ref); + if (error) goto cleanup; + break; default: fz_warn("syntaxerror: unknown shading type: %d", type); break; diff --git a/mupdf/pdf_shade1.c b/mupdf/pdf_shade1.c index f25616bd..d6823075 100644 --- a/mupdf/pdf_shade1.c +++ b/mupdf/pdf_shade1.c @@ -1,7 +1,12 @@ #include <fitz.h> #include <mupdf.h> +/* this mess is jeong's */ + +#define BIGNUM 32000 + #define NSEGS 32 +#define MAX_RAD_SEGS 36 fz_error * pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) @@ -106,3 +111,260 @@ pdf_loadtype1shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) return nil; } +fz_error * +pdf_loadtype2shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) +{ + fz_point p1, p2, p3, p4; + fz_point ep1, ep2, ep3, ep4; + float x0, y0, x1, y1; + float t0, t1; + int e0, e1; + fz_obj *obj; + float theta; + float dist; + int n; + + pdf_logshade("load type2 shade {\n"); + + obj = fz_dictgets(dict, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + x1 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + + pdf_logshade("coords %g %g %g %g\n", x0, y0, x1, y1); + + obj = fz_dictgets(dict, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + obj = fz_dictgets(dict, "Extend"); + if (obj) { + e0 = fz_tobool(fz_arrayget(obj, 0)); + e1 = fz_tobool(fz_arrayget(obj, 1)); + } else { + e0 = 0; + e1 = 0; + } + + pdf_logshade("domain %g %g\n", t0, t1); + pdf_logshade("extend %d %d\n", e0, e1); + + pdf_loadshadefunction(shade, xref, dict, t0, t1); + + shade->meshlen = 2 + e0 * 2 + e1 * 2; + shade->mesh = fz_malloc(sizeof(float) * 3*3 * shade->meshlen); + if (!shade->mesh) + return fz_outofmem; + + theta = atan2(y1 - y0, x1 - x0); + theta += M_PI / 2.0; + + pdf_logshade("theta=%g\n", theta); + + dist = hypot(x1 - x0, y1 - y0); + + p1.x = x0 + BIGNUM * cos(theta); + p1.y = y0 + BIGNUM * sin(theta); + p2.x = x1 + BIGNUM * cos(theta); + p2.y = y1 + BIGNUM * sin(theta); + p3.x = x0 - BIGNUM * cos(theta); + p3.y = y0 - BIGNUM * sin(theta); + p4.x = x1 - BIGNUM * cos(theta); + p4.y = y1 - BIGNUM * sin(theta); + + ep1.x = p1.x - (x1 - x0) / dist * BIGNUM; + ep1.y = p1.y - (y1 - y0) / dist * BIGNUM; + ep2.x = p2.x + (x1 - x0) / dist * BIGNUM; + ep2.y = p2.y + (y1 - y0) / dist * BIGNUM; + ep3.x = p3.x - (x1 - x0) / dist * BIGNUM; + ep3.y = p3.y - (y1 - y0) / dist * BIGNUM; + ep4.x = p4.x + (x1 - x0) / dist * BIGNUM; + ep4.y = p4.y + (y1 - y0) / dist * BIGNUM; + + pdf_logshade("p1 %g %g\n", p1.x, p1.y); + pdf_logshade("p2 %g %g\n", p2.x, p2.y); + pdf_logshade("p3 %g %g\n", p3.x, p3.y); + pdf_logshade("p4 %g %g\n", p4.x, p4.y); + + n = 0; + + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + + if (e0) { + pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); + pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); + pdf_setmeshvalue(shade->mesh, n++, ep3.x, ep3.y, 0); + } + + if (e1) { + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep2.x, ep2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); + pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); + pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); + } + + pdf_logshade("}\n"); + + return nil; +} + +static int +buildannulusmesh(float* mesh, int pos, + float x0, float y0, float r0, float x1, float y1, float r1, + float c0, float c1, int nomesh) +{ + int n = pos * 3; + float dist = hypot(x1 - x0, y1 - y0); + float step; + float theta; + int i; + + if (dist != 0) + theta = asin((r1 - r0) / dist) + M_PI/2.0 + atan2(y1 - y0, x1 - x0); + else + theta = 0; + + if (!(theta >= 0 && theta <= M_PI)) + theta = 0; + + step = M_PI * 2. / (float)MAX_RAD_SEGS; + + for (i = 0; i < MAX_RAD_SEGS; theta -= step, ++i) + { + fz_point pt1, pt2, pt3, pt4; + + pt1.x = cos (theta) * r1 + x1; + pt1.y = sin (theta) * r1 + y1; + pt2.x = cos (theta) * r0 + x0; + pt2.y = sin (theta) * r0 + y0; + pt3.x = cos (theta+step) * r1 + x1; + pt3.y = sin (theta+step) * r1 + y1; + pt4.x = cos (theta+step) * r0 + x0; + pt4.y = sin (theta+step) * r0 + y0; + + if (r0 > 0) { + if (!nomesh) { + pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); + pdf_setmeshvalue(mesh, n++, pt2.x, pt2.y, c0); + pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); + } + pos++; + } + + if (r1 > 0) { + if (!nomesh) { + pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); + pdf_setmeshvalue(mesh, n++, pt3.x, pt3.y, c1); + pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); + } + pos++; + } + } + + return pos; +} + +fz_error * +pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_obj *obj; + float x0, y0, r0, x1, y1, r1; + float t0, t1; + int e0, e1; + float ex0, ey0, er0; + float ex1, ey1, er1; + float rs; + int i; + + pdf_logshade("load type3 shade {\n"); + + obj = fz_dictgets(shading, "Coords"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + y0 = fz_toreal(fz_arrayget(obj, 1)); + r0 = fz_toreal(fz_arrayget(obj, 2)); + x1 = fz_toreal(fz_arrayget(obj, 3)); + y1 = fz_toreal(fz_arrayget(obj, 4)); + r1 = fz_toreal(fz_arrayget(obj, 5)); + + pdf_logshade("coords %g %g %g %g %g %g\n", x0, y0, r0, x1, y1, r1); + + obj = fz_dictgets(shading, "Domain"); + if (obj) { + t0 = fz_toreal(fz_arrayget(obj, 0)); + t1 = fz_toreal(fz_arrayget(obj, 1)); + } else { + t0 = 0.; + t1 = 1.; + } + + obj = fz_dictgets(shading, "Extend"); + if (obj) { + e0 = fz_tobool(fz_arrayget(obj, 0)); + e1 = fz_tobool(fz_arrayget(obj, 1)); + } else { + e0 = 0; + e1 = 0; + } + + pdf_logshade("domain %g %g\n", t0, t1); + pdf_logshade("extend %d %d\n", e0, e1); + + pdf_loadshadefunction(shade, xref, shading, t0, t1); + + if (r0 < r1) + rs = r0 / (r0 - r1); + else + rs = -BIGNUM; + + ex0 = x0 + (x1 - x0) * rs; + ey0 = y0 + (y1 - y0) * rs; + er0 = r0 + (r1 - r0) * rs; + + if (r0 > r1) + rs = r1 / (r1 - r0); + else + rs = -BIGNUM; + + ex1 = x1 + (x0 - x1) * rs; + ey1 = y1 + (y0 - y1) * rs; + er1 = r1 + (r0 - r1) * rs; + + for (i=0; i<2; ++i) + { + int pos = 0; + if (e0) + pos = buildannulusmesh(shade->mesh, pos, ex0, ey0, er0, x0, y0, r0, 0, 0, 1-i); + pos = buildannulusmesh(shade->mesh, pos, x0, y0, r0, x1, y1, r1, 0, 1., 1-i); + if (e1) + pos = buildannulusmesh(shade->mesh, pos, x1, y1, r1, ex1, ey1, er1, 1., 1., 1-i); + + if (i == 0) + { + shade->meshlen = pos; + shade->mesh = fz_malloc(sizeof(float) * 9 * shade->meshlen); + if (!shade->mesh) + return fz_outofmem; + } + } + + pdf_logshade("}\n"); + + return nil; +} + diff --git a/mupdf/pdf_shade2.c b/mupdf/pdf_shade2.c deleted file mode 100644 index 4af9e056..00000000 --- a/mupdf/pdf_shade2.c +++ /dev/null @@ -1,118 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -#define BIGNUM 32000 - -fz_error * -pdf_loadtype2shade(fz_shade *shade, pdf_xref *xref, fz_obj *dict, fz_obj *ref) -{ - fz_point p1, p2, p3, p4; - fz_point ep1, ep2, ep3, ep4; - float x0, y0, x1, y1; - float t0, t1; - int e0, e1; - fz_obj *obj; - float theta; - float dist; - int n; - - pdf_logshade("load type2 shade {\n"); - - obj = fz_dictgets(dict, "Coords"); - x0 = fz_toreal(fz_arrayget(obj, 0)); - y0 = fz_toreal(fz_arrayget(obj, 1)); - x1 = fz_toreal(fz_arrayget(obj, 2)); - y1 = fz_toreal(fz_arrayget(obj, 3)); - - pdf_logshade("coords %g %g %g %g\n", x0, y0, x1, y1); - - obj = fz_dictgets(dict, "Domain"); - if (obj) { - t0 = fz_toreal(fz_arrayget(obj, 0)); - t1 = fz_toreal(fz_arrayget(obj, 1)); - } else { - t0 = 0.; - t1 = 1.; - } - - obj = fz_dictgets(dict, "Extend"); - if (obj) { - e0 = fz_tobool(fz_arrayget(obj, 0)); - e1 = fz_tobool(fz_arrayget(obj, 1)); - } else { - e0 = 0; - e1 = 0; - } - - pdf_logshade("domain %g %g\n", t0, t1); - pdf_logshade("extend %d %d\n", e0, e1); - - pdf_loadshadefunction(shade, xref, dict, t0, t1); - - shade->meshlen = 2 + e0 * 2 + e1 * 2; - shade->mesh = fz_malloc(sizeof(float) * 3*3 * shade->meshlen); - if (!shade->mesh) - return fz_outofmem; - - theta = atan2(y1 - y0, x1 - x0); - theta += M_PI / 2.0; - - pdf_logshade("theta=%g\n", theta); - - dist = hypot(x1 - x0, y1 - y0); - - p1.x = x0 + BIGNUM * cos(theta); - p1.y = y0 + BIGNUM * sin(theta); - p2.x = x1 + BIGNUM * cos(theta); - p2.y = y1 + BIGNUM * sin(theta); - p3.x = x0 - BIGNUM * cos(theta); - p3.y = y0 - BIGNUM * sin(theta); - p4.x = x1 - BIGNUM * cos(theta); - p4.y = y1 - BIGNUM * sin(theta); - - ep1.x = p1.x - (x1 - x0) / dist * BIGNUM; - ep1.y = p1.y - (y1 - y0) / dist * BIGNUM; - ep2.x = p2.x + (x1 - x0) / dist * BIGNUM; - ep2.y = p2.y + (y1 - y0) / dist * BIGNUM; - ep3.x = p3.x - (x1 - x0) / dist * BIGNUM; - ep3.y = p3.y - (y1 - y0) / dist * BIGNUM; - ep4.x = p4.x + (x1 - x0) / dist * BIGNUM; - ep4.y = p4.y + (y1 - y0) / dist * BIGNUM; - - pdf_logshade("p1 %g %g\n", p1.x, p1.y); - pdf_logshade("p2 %g %g\n", p2.x, p2.y); - pdf_logshade("p3 %g %g\n", p3.x, p3.y); - pdf_logshade("p4 %g %g\n", p4.x, p4.y); - - n = 0; - - pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); - pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); - pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); - pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); - pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); - pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); - - if (e0) { - pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); - pdf_setmeshvalue(shade->mesh, n++, p1.x, p1.y, 0); - pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); - pdf_setmeshvalue(shade->mesh, n++, ep1.x, ep1.y, 0); - pdf_setmeshvalue(shade->mesh, n++, p3.x, p3.y, 0); - pdf_setmeshvalue(shade->mesh, n++, ep3.x, ep3.y, 0); - } - - if (e1) { - pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); - pdf_setmeshvalue(shade->mesh, n++, ep2.x, ep2.y, 1); - pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); - pdf_setmeshvalue(shade->mesh, n++, p2.x, p2.y, 1); - pdf_setmeshvalue(shade->mesh, n++, ep4.x, ep4.y, 1); - pdf_setmeshvalue(shade->mesh, n++, p4.x, p4.y, 1); - } - - pdf_logshade("}\n"); - - return nil; -} - diff --git a/mupdf/pdf_shade3.c b/mupdf/pdf_shade3.c deleted file mode 100644 index 59cfaed2..00000000 --- a/mupdf/pdf_shade3.c +++ /dev/null @@ -1,151 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -#define BIGNUM 32000 - -#define MAX_RAD_SEGS 36 - -int -buildannulusmesh(float* mesh, int pos, - float x0, float y0, float r0, float x1, float y1, float r1, - float c0, float c1, int nomesh) -{ - int n = pos * 3; - float dist = hypot(x1 - x0, y1 - y0); - float step; - float theta; - int i; - - if (dist != 0) - theta = asin((r1 - r0) / dist) + M_PI/2.0 + atan2(y1 - y0, x1 - x0); - else - theta = 0; - - if (!(theta >= 0 && theta <= M_PI)) - theta = 0; - - step = M_PI * 2. / (float)MAX_RAD_SEGS; - - for (i = 0; i < MAX_RAD_SEGS; theta -= step, ++i) - { - fz_point pt1, pt2, pt3, pt4; - - pt1.x = cos (theta) * r1 + x1; - pt1.y = sin (theta) * r1 + y1; - pt2.x = cos (theta) * r0 + x0; - pt2.y = sin (theta) * r0 + y0; - pt3.x = cos (theta+step) * r1 + x1; - pt3.y = sin (theta+step) * r1 + y1; - pt4.x = cos (theta+step) * r0 + x0; - pt4.y = sin (theta+step) * r0 + y0; - - if (r0 > 0) { - if (!nomesh) { - pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); - pdf_setmeshvalue(mesh, n++, pt2.x, pt2.y, c0); - pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); - } - pos++; - } - - if (r1 > 0) { - if (!nomesh) { - pdf_setmeshvalue(mesh, n++, pt1.x, pt1.y, c1); - pdf_setmeshvalue(mesh, n++, pt3.x, pt3.y, c1); - pdf_setmeshvalue(mesh, n++, pt4.x, pt4.y, c0); - } - pos++; - } - } - - return pos; -} - -fz_error * -pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) -{ - fz_obj *obj; - float x0, y0, r0, x1, y1, r1; - float t0, t1; - int e0, e1; - float ex0, ey0, er0; - float ex1, ey1, er1; - float rs; - int i; - - pdf_logshade("load type3 shade {\n"); - - obj = fz_dictgets(shading, "Coords"); - x0 = fz_toreal(fz_arrayget(obj, 0)); - y0 = fz_toreal(fz_arrayget(obj, 1)); - r0 = fz_toreal(fz_arrayget(obj, 2)); - x1 = fz_toreal(fz_arrayget(obj, 3)); - y1 = fz_toreal(fz_arrayget(obj, 4)); - r1 = fz_toreal(fz_arrayget(obj, 5)); - - pdf_logshade("coords %g %g %g %g %g %g\n", x0, y0, r0, x1, y1, r1); - - obj = fz_dictgets(shading, "Domain"); - if (obj) { - t0 = fz_toreal(fz_arrayget(obj, 0)); - t1 = fz_toreal(fz_arrayget(obj, 1)); - } else { - t0 = 0.; - t1 = 1.; - } - - obj = fz_dictgets(shading, "Extend"); - if (obj) { - e0 = fz_tobool(fz_arrayget(obj, 0)); - e1 = fz_tobool(fz_arrayget(obj, 1)); - } else { - e0 = 0; - e1 = 0; - } - - pdf_logshade("domain %g %g\n", t0, t1); - pdf_logshade("extend %d %d\n", e0, e1); - - pdf_loadshadefunction(shade, xref, shading, t0, t1); - - if (r0 < r1) - rs = r0 / (r0 - r1); - else - rs = -BIGNUM; - - ex0 = x0 + (x1 - x0) * rs; - ey0 = y0 + (y1 - y0) * rs; - er0 = r0 + (r1 - r0) * rs; - - if (r0 > r1) - rs = r1 / (r1 - r0); - else - rs = -BIGNUM; - - ex1 = x1 + (x0 - x1) * rs; - ey1 = y1 + (y0 - y1) * rs; - er1 = r1 + (r0 - r1) * rs; - - for (i=0; i<2; ++i) - { - int pos = 0; - if (e0) - pos = buildannulusmesh(shade->mesh, pos, ex0, ey0, er0, x0, y0, r0, 0, 0, 1-i); - pos = buildannulusmesh(shade->mesh, pos, x0, y0, r0, x1, y1, r1, 0, 1., 1-i); - if (e1) - pos = buildannulusmesh(shade->mesh, pos, x1, y1, r1, ex1, ey1, er1, 1., 1., 1-i); - - if (i == 0) - { - shade->meshlen = pos; - shade->mesh = fz_malloc(sizeof(float) * 9 * shade->meshlen); - if (!shade->mesh) - return fz_outofmem; - } - } - - pdf_logshade("}\n"); - - return nil; -} - diff --git a/mupdf/pdf_shade4.c b/mupdf/pdf_shade4.c index dfc821a2..8454643f 100644 --- a/mupdf/pdf_shade4.c +++ b/mupdf/pdf_shade4.c @@ -1,6 +1,14 @@ #include <fitz.h> #include <mupdf.h> +/* this mess is jeong's */ + +typedef struct pdf_tensorpatch_s pdf_tensorpatch; +struct pdf_tensorpatch_s { + fz_point pole[4][4]; + float color[4][FZ_MAXCOLORS]; +}; + fz_error * pdf_loadtype4shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) { @@ -155,3 +163,636 @@ cleanup: return nil; } +static int +getdata(fz_file *stream, int bps) +{ + unsigned int bitmask = (1 << bps) - 1; + unsigned int buf = 0; + int bits = 0; + int s; + + while (bits < bps) + { + buf = (buf << 8) | (fz_readbyte(stream) & 0xff); + bits += 8; + } + s = buf >> (bits - bps); + if (bps < 32) + s = s & bitmask; + bits -= bps; + + return s; +} + +fz_error * +pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int vpr, vpc; + int ncomp; + + float x0, x1, y0, y1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + int p, q; + unsigned int t; + + float *x, *y, *c[FZ_MAXCOLORS]; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + vpr = fz_toint(fz_dictgets(shading, "VerticesPerRow")); + if (vpr < 2) { + error = fz_throw("VerticesPerRow must be greater than or equal to 2"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + n = 2 + shade->cs->n; + j = 0; + +#define BIGNUM 1024 + + x = fz_malloc(sizeof(float) * vpr * BIGNUM); + y = fz_malloc(sizeof(float) * vpr * BIGNUM); + for (i = 0; i < ncomp; ++i) { + c[i] = fz_malloc(sizeof(float) * vpr * BIGNUM); + } + q = 0; + + error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(xref->stream) != EOF) + { + for (p = 0; p < vpr; ++p) { + int idx; + idx = q * vpr + p; + + t = getdata(xref->stream, bpcoord); + x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); + t = getdata(xref->stream, bpcoord); + y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); + + for (i=0; i < ncomp; ++i) { + t = getdata(xref->stream, bpcomp); + c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); + } + } + q++; + } + if ((error = fz_ferror(xref->stream))) + goto cleanup; + + pdf_closestream(xref); + +#define ADD_VERTEX(idx) \ + {\ + int z;\ + shade->mesh[j++] = x[idx];\ + shade->mesh[j++] = y[idx];\ + for (z = 0; z < shade->cs->n; ++z) {\ + shade->mesh[j++] = c[z][idx];\ + }\ + }\ + + vpc = q; + + shade->meshcap = 0; + shade->mesh = fz_malloc(sizeof(float) * 1024); + if (!shade) { + error = fz_outofmem; + goto cleanup; + } + + j = 0; + for (p = 0; p < vpr-1; ++p) { + for (q = 0; q < vpc-1; ++q) { + ADD_VERTEX(q * vpr + p); + ADD_VERTEX(q * vpr + p + 1); + ADD_VERTEX((q + 1) * vpr + p + 1); + + ADD_VERTEX(q * vpr + p); + ADD_VERTEX((q + 1) * vpr + p + 1); + ADD_VERTEX((q + 1) * vpr + p); + } + } + + shade->meshlen = j / n / 3; + + fz_free(x); + fz_free(y); + for (i = 0; i < ncomp; ++i) { + fz_free(c[i]); + } + + +cleanup: + + return nil; +} + +#define SEGMENTATION_DEPTH 2 + +static inline void copyvert(float *dst, float *src, int n) +{ + while (n--) + *dst++ = *src++; +} + + +static inline void copycolor(float *c, const float *s) +{ + int i; + for (i = 0; i<FZ_MAXCOLORS; ++i) + c[i] = s[i]; +} + +static inline void midcolor(float *c, const float *c1, const float *c2) +{ + int i; + for (i = 0; i<FZ_MAXCOLORS; ++i) + c[i] = (float)((c1[i] + c2[i]) / 2.0); +} + + +static void +filltensorinterior(pdf_tensorpatch *p) +{ +#define lcp1(p0, p3)\ + ((p0 + p0 + p3) / 3.0f) + +#define lcp2(p0, p3)\ + ((p0 + p3 + p3) / 3.0f) + + p->pole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[1][0].x, p->pole[1][3].x) - + lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[1][0].x, p->pole[1][3].x) - + lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) + + lcp1(p->pole[2][0].x, p->pole[2][3].x) - + lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), + lcp1(p->pole[3][0].x, p->pole[3][3].x)); + p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) + + lcp2(p->pole[2][0].x, p->pole[2][3].x) - + lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), + lcp2(p->pole[3][0].x, p->pole[3][3].x)); + + p->pole[1][1].y = lcp1(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[1][0].y, p->pole[1][3].y) - + lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[1][2].y = lcp1(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[1][0].y, p->pole[1][3].y) - + lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[2][1].y = lcp2(p->pole[0][1].y, p->pole[3][1].y) + + lcp1(p->pole[2][0].y, p->pole[2][3].y) - + lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y), + lcp1(p->pole[3][0].y, p->pole[3][3].y)); + p->pole[2][2].y = lcp2(p->pole[0][2].y, p->pole[3][2].y) + + lcp2(p->pole[2][0].y, p->pole[2][3].y) - + lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y), + lcp2(p->pole[3][0].y, p->pole[3][3].y)); + +#undef lcp1 +#undef lcp2 +} + +static void +split_curve_s(const fz_point *pole, fz_point *q0, fz_point *q1, int pole_step) +{ +#define midpoint(a,b)\ + ((a)/2.0f + (b)/2.0f) // to avoid overflow + float x12 = midpoint(pole[1 * pole_step].x, pole[2 * pole_step].x); + float y12 = midpoint(pole[1 * pole_step].y, pole[2 * pole_step].y); + + q0[1 * pole_step].x = midpoint(pole[0 * pole_step].x, pole[1 * pole_step].x); + q0[1 * pole_step].y = midpoint(pole[0 * pole_step].y, pole[1 * pole_step].y); + q1[2 * pole_step].x = midpoint(pole[2 * pole_step].x, pole[3 * pole_step].x); + q1[2 * pole_step].y = midpoint(pole[2 * pole_step].y, pole[3 * pole_step].y); + q0[2 * pole_step].x = midpoint(q0[1 * pole_step].x, x12); + q0[2 * pole_step].y = midpoint(q0[1 * pole_step].y, y12); + q1[1 * pole_step].x = midpoint(x12, q1[2 * pole_step].x); + q1[1 * pole_step].y = midpoint(y12, q1[2 * pole_step].y); + q0[0 * pole_step].x = pole[0 * pole_step].x; + q0[0 * pole_step].y = pole[0 * pole_step].y; + q0[3 * pole_step].x = q1[0 * pole_step].x = midpoint(q0[2 * pole_step].x, q1[1 * pole_step].x); + q0[3 * pole_step].y = q1[0 * pole_step].y = midpoint(q0[2 * pole_step].y, q1[1 * pole_step].y); + q1[3 * pole_step].x = pole[3 * pole_step].x; + q1[3 * pole_step].y = pole[3 * pole_step].y; +#undef midpoint +} + +static inline void +split_patch(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) +{ + split_curve_s(&p->pole[0][0], &s0->pole[0][0], &s1->pole[0][0], 4); + split_curve_s(&p->pole[0][1], &s0->pole[0][1], &s1->pole[0][1], 4); + split_curve_s(&p->pole[0][2], &s0->pole[0][2], &s1->pole[0][2], 4); + split_curve_s(&p->pole[0][3], &s0->pole[0][3], &s1->pole[0][3], 4); + + copycolor(s0->color[0], p->color[0]); + midcolor(s0->color[1], p->color[0], p->color[1]); + midcolor(s0->color[2], p->color[2], p->color[3]); + copycolor(s0->color[3], p->color[3]); + + copycolor(s1->color[0], s0->color[1]); + copycolor(s1->color[1], p->color[1]); + copycolor(s1->color[2], p->color[2]); + copycolor(s1->color[3], s0->color[2]); +} + +static inline void +split_stripe(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) + +{ + split_curve_s(p->pole[0], s0->pole[0], s1->pole[0], 1); + split_curve_s(p->pole[1], s0->pole[1], s1->pole[1], 1); + split_curve_s(p->pole[2], s0->pole[2], s1->pole[2], 1); + split_curve_s(p->pole[3], s0->pole[3], s1->pole[3], 1); + + copycolor(s0->color[0], p->color[0]); + copycolor(s0->color[1], p->color[1]); + midcolor(s0->color[2], p->color[1], p->color[2]); + midcolor(s0->color[3], p->color[0], p->color[3]); + + copycolor(s1->color[0], s0->color[3]); + copycolor(s1->color[1], s0->color[2]); + copycolor(s1->color[2], p->color[2]); + copycolor(s1->color[3], p->color[3]); +} + +static fz_error * +growshademesh(fz_shade *shade, int amount) +{ + float *newmesh; + int newcap; + + newcap = shade->meshcap + amount; + newmesh = fz_realloc(shade->mesh, sizeof(float) * newcap); + if (!newmesh) + return fz_outofmem; + + shade->mesh = newmesh; + shade->meshcap = newcap; + + return nil; +} + +static inline int setvertex(float *mesh, fz_point pt, float *color, int ptr, int ncomp) +{ + int i; + + mesh[ptr++] = pt.x; + mesh[ptr++] = pt.y; + for (i=0; i < ncomp; ++i) { + mesh[ptr++] = color[i]; + } + + return ptr; +} + +static int +triangulatepatch(pdf_tensorpatch p, fz_shade *shade, int ptr, int ncomp) +{ + fz_error* error; + + ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][0], p.color[1], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); + ptr = setvertex(shade->mesh, p.pole[0][3], p.color[3], ptr, ncomp); + + if (shade->meshcap - 1024 < ptr) { + error = growshademesh(shade, 1024); + if (error) goto cleanup; + } + + return ptr; + +cleanup: + // error handling + return -1; +} + +static int +drawstripe(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) +{ + pdf_tensorpatch s0, s1; + + split_stripe(&s0, &s1, &patch); + + depth++; + + if (depth >= SEGMENTATION_DEPTH) + { + ptr = triangulatepatch(s0, shade, ptr, ncomp); + ptr = triangulatepatch(s1, shade, ptr, ncomp); + } + else { + ptr = drawstripe(s0, shade, ptr, ncomp, depth); + ptr = drawstripe(s1, shade, ptr, ncomp, depth); + } + + return ptr; +} + +static int +drawpatch(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) +{ + pdf_tensorpatch s0, s1; + + split_patch(&s0, &s1, &patch); + depth++; + + if (depth > SEGMENTATION_DEPTH) + { + ptr = drawstripe(s0, shade, ptr, ncomp, 0); + ptr = drawstripe(s1, shade, ptr, ncomp, 0); + } + else { + ptr = drawpatch(s0, shade, ptr, ncomp, depth); + ptr = drawpatch(s1, shade, ptr, ncomp, depth); + } + + return ptr; +} + +fz_error * +pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int bpflag; + int ncomp; + + fz_point p0, p1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + unsigned int t; + + int flag; + fz_point p[12]; + + pdf_tensorpatch patch; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + p0.x = fz_toreal(fz_arrayget(obj, 0)); + p1.x = fz_toreal(fz_arrayget(obj, 1)); + p0.y = fz_toreal(fz_arrayget(obj, 2)); + p1.y = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + shade->meshcap = 0; + shade->mesh = nil; + error = growshademesh(shade, 1024); + if (error) goto cleanup; + + n = 2 + shade->cs->n; + j = 0; + + error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(xref->stream) != EOF) + { + flag = getdata(xref->stream, bpflag); + + for (i = 0; i < 12; ++i) { + t = getdata(xref->stream, bpcoord); + p[i].x = (float)(p0.x + (t * (p1.x - p0.x) / (pow(2, bpcoord) - 1.))); + t = getdata(xref->stream, bpcoord); + p[i].y = (float)(p0.y + (t * (p1.y - p0.y) / (pow(2, bpcoord) - 1.))); + } + + for (i = 0; i < 4; ++i) { + int k; + for (k=0; k < ncomp; ++k) { + t = getdata(xref->stream, bpcomp); + patch.color[i][k] = + c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); + } + } + + patch.pole[0][0] = p[0]; + patch.pole[1][0] = p[1]; + patch.pole[2][0] = p[2]; + patch.pole[3][0] = p[3]; + patch.pole[3][1] = p[4]; + patch.pole[3][2] = p[5]; + patch.pole[3][3] = p[6]; + patch.pole[2][3] = p[7]; + patch.pole[1][3] = p[8]; + patch.pole[0][3] = p[9]; + patch.pole[0][2] = p[10]; + patch.pole[0][1] = p[11]; + filltensorinterior(&patch); + + j = drawpatch(patch, shade, j, ncomp, 0); + } + if ((error = fz_ferror(xref->stream)) ) + goto cleanup; + + pdf_closestream(xref); + + shade->meshlen = j / n / 3; + +cleanup: + + return nil; +} + +fz_error * +pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) +{ + fz_error *error; + fz_obj *obj; + + int bpcoord; + int bpcomp; + int bpflag; + int ncomp; + + float x0, x1, y0, y1; + + float c0[FZ_MAXCOLORS]; + float c1[FZ_MAXCOLORS]; + + int i, n, j; + unsigned int t; + + int flag; + fz_point p[16]; + pdf_tensorpatch patch; + + error = nil; + + ncomp = shade->cs->n; + bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); + bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); + bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); + + obj = fz_dictgets(shading, "Decode"); + if (fz_isarray(obj)) + { + pdf_logshade("decode array\n"); + x0 = fz_toreal(fz_arrayget(obj, 0)); + x1 = fz_toreal(fz_arrayget(obj, 1)); + y0 = fz_toreal(fz_arrayget(obj, 2)); + y1 = fz_toreal(fz_arrayget(obj, 3)); + for (i=0; i < fz_arraylen(obj) / 2; ++i) { + c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); + c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); + } + } + else { + error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); + goto cleanup; + } + + obj = fz_dictgets(shading, "Function"); + if (obj) { + ncomp = 1; + pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); + shade->usefunction = 1; + } + else + shade->usefunction = 0; + + shade->meshcap = 0; + shade->mesh = nil; + error = growshademesh(shade, 1024); + if (error) goto cleanup; + + n = 2 + shade->cs->n; + j = 0; + + error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); + if (error) goto cleanup; + + while (fz_peekbyte(xref->stream) != EOF) + { + flag = getdata(xref->stream, bpflag); + + for (i = 0; i < 16; ++i) { + t = getdata(xref->stream, bpcoord); + p[i].x = x0 + (t * (x1 - x0) / (pow(2, bpcoord) - 1.)); + t = getdata(xref->stream, bpcoord); + p[i].y = y0 + (t * (y1 - y0) / (pow(2, bpcoord) - 1.)); + } + + for (i = 0; i < 4; ++i) { + int k; + for (k=0; k < ncomp; ++k) { + t = getdata(xref->stream, bpcomp); + patch.color[i][k] = + c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); + } + } + + patch.pole[0][0] = p[0]; + patch.pole[0][1] = p[1]; + patch.pole[0][2] = p[2]; + patch.pole[0][3] = p[3]; + patch.pole[1][3] = p[4]; + patch.pole[2][3] = p[5]; + patch.pole[3][3] = p[6]; + patch.pole[3][2] = p[7]; + patch.pole[3][1] = p[8]; + patch.pole[3][0] = p[9]; + patch.pole[2][0] = p[10]; + patch.pole[1][0] = p[11]; + patch.pole[1][1] = p[12]; + patch.pole[1][2] = p[13]; + patch.pole[2][2] = p[14]; + patch.pole[2][1] = p[15]; + + j = drawpatch(patch, shade, j, ncomp, 0); + } + if ((error = fz_ferror(xref->stream)) ) + goto cleanup; + + pdf_closestream(xref); + + shade->meshlen = j / n / 3; + +cleanup: + + return nil; +} + diff --git a/mupdf/pdf_shade5.c b/mupdf/pdf_shade5.c deleted file mode 100644 index 628600d2..00000000 --- a/mupdf/pdf_shade5.c +++ /dev/null @@ -1,168 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -int -getdata(fz_file *stream, int bps) -{ - unsigned int bitmask = (1 << bps) - 1; - unsigned int buf = 0; - int bits = 0; - int s; - - while (bits < bps) - { - buf = (buf << 8) | (fz_readbyte(stream) & 0xff); - bits += 8; - } - s = buf >> (bits - bps); - if (bps < 32) - s = s & bitmask; - bits -= bps; - - return s; -} - -fz_error * -pdf_loadtype5shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) -{ - fz_error *error; - fz_obj *obj; - - int bpcoord; - int bpcomp; - int vpr, vpc; - int ncomp; - - float x0, x1, y0, y1; - - float c0[FZ_MAXCOLORS]; - float c1[FZ_MAXCOLORS]; - - int i, n, j; - int p, q; - unsigned int t; - - float *x, *y, *c[FZ_MAXCOLORS]; - - error = nil; - - ncomp = shade->cs->n; - bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); - bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); - vpr = fz_toint(fz_dictgets(shading, "VerticesPerRow")); - if (vpr < 2) { - error = fz_throw("VerticesPerRow must be greater than or equal to 2"); - goto cleanup; - } - - obj = fz_dictgets(shading, "Decode"); - if (fz_isarray(obj)) - { - pdf_logshade("decode array\n"); - x0 = fz_toreal(fz_arrayget(obj, 0)); - x1 = fz_toreal(fz_arrayget(obj, 1)); - y0 = fz_toreal(fz_arrayget(obj, 2)); - y1 = fz_toreal(fz_arrayget(obj, 3)); - for (i=0; i < fz_arraylen(obj) / 2; ++i) { - c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); - c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); - } - } - else { - error = fz_throw("syntaxerror: No Decode key in Type 4 Shade"); - goto cleanup; - } - - obj = fz_dictgets(shading, "Function"); - if (obj) { - ncomp = 1; - pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); - shade->usefunction; - } - else - shade->usefunction = 0; - - n = 2 + shade->cs->n; - j = 0; - -#define BIGNUM 1024 - - x = fz_malloc(sizeof(float) * vpr * BIGNUM); - y = fz_malloc(sizeof(float) * vpr * BIGNUM); - for (i = 0; i < ncomp; ++i) { - c[i] = fz_malloc(sizeof(float) * vpr * BIGNUM); - } - q = 0; - - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); - if (error) goto cleanup; - - while (fz_peekbyte(xref->stream) != EOF) - { - for (p = 0; p < vpr; ++p) { - int idx; - idx = q * vpr + p; - - t = getdata(xref->stream, bpcoord); - x[idx] = x0 + (t * (x1 - x0) / ((float)pow(2, bpcoord) - 1)); - t = getdata(xref->stream, bpcoord); - y[idx] = y0 + (t * (y1 - y0) / ((float)pow(2, bpcoord) - 1)); - - for (i=0; i < ncomp; ++i) { - t = getdata(xref->stream, bpcomp); - c[i][idx] = c0[i] + (t * (c1[i] - c0[i]) / (float)(pow(2, bpcomp) - 1)); - } - } - q++; - } - if (error = fz_ferror(xref->stream)) - goto cleanup; - - pdf_closestream(xref); - -#define ADD_VERTEX(idx) \ - {\ - int z;\ - shade->mesh[j++] = x[idx];\ - shade->mesh[j++] = y[idx];\ - for (z = 0; z < shade->cs->n; ++z) {\ - shade->mesh[j++] = c[z][idx];\ - }\ - }\ - - vpc = q; - - shade->meshcap = 0; - shade->mesh = fz_malloc(sizeof(float) * 1024); - if (!shade) { - error = fz_outofmem; - goto cleanup; - } - - j = 0; - for (p = 0; p < vpr-1; ++p) { - for (q = 0; q < vpc-1; ++q) { - ADD_VERTEX(q * vpr + p); - ADD_VERTEX(q * vpr + p + 1); - ADD_VERTEX((q + 1) * vpr + p + 1); - - ADD_VERTEX(q * vpr + p); - ADD_VERTEX((q + 1) * vpr + p + 1); - ADD_VERTEX((q + 1) * vpr + p); - } - } - - shade->meshlen = j / n / 3; - - fz_free(x); - fz_free(y); - for (i = 0; i < ncomp; ++i) { - fz_free(c[i]); - } - - -cleanup: - - return nil; -} - diff --git a/mupdf/pdf_shade6.c b/mupdf/pdf_shade6.c deleted file mode 100644 index 400c6e1e..00000000 --- a/mupdf/pdf_shade6.c +++ /dev/null @@ -1,360 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -#define SEGMENTATION_DEPTH 2 - -int -getdata(fz_file *stream, int bps); - -void -filltensorinterior(pdf_tensorpatch *p); - -inline void -split_patch(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p); -inline void -split_stripe(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p); - -inline void copycolor(float *c, const float *s) -{ - int i; - for (i = 0; i<FZ_MAXCOLORS; ++i) - c[i] = s[i]; -} - -inline void midcolor(float *c, const float *c1, const float *c2) -{ - int i; - for (i = 0; i<FZ_MAXCOLORS; ++i) - c[i] = (float)((c1[i] + c2[i]) / 2.0); -} - -static fz_error * -growshademesh(fz_shade *shade, int amount) -{ - float *newmesh; - int newcap; - - newcap = shade->meshcap + amount; - newmesh = fz_realloc(shade->mesh, sizeof(float) * newcap); - if (!newmesh) - return fz_outofmem; - - shade->mesh = newmesh; - shade->meshcap = newcap; - - return nil; -} - -static inline void copyvert(float *dst, float *src, int n) -{ - while (n--) - *dst++ = *src++; -} - -static inline int setvertex(float *mesh, fz_point pt, float *color, int ptr, int ncomp) -{ - int i; - - mesh[ptr++] = pt.x; - mesh[ptr++] = pt.y; - for (i=0; i < ncomp; ++i) { - mesh[ptr++] = color[i]; - } - - return ptr; -} - -int -triangulatepatch(pdf_tensorpatch p, fz_shade *shade, int ptr, int ncomp) -{ - fz_error* error; - - ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); - ptr = setvertex(shade->mesh, p.pole[3][0], p.color[1], ptr, ncomp); - ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); - ptr = setvertex(shade->mesh, p.pole[0][0], p.color[0], ptr, ncomp); - ptr = setvertex(shade->mesh, p.pole[3][3], p.color[2], ptr, ncomp); - ptr = setvertex(shade->mesh, p.pole[0][3], p.color[3], ptr, ncomp); - - if (shade->meshcap - 1024 < ptr) { - error = growshademesh(shade, 1024); - if (error) goto cleanup; - } - - return ptr; - -cleanup: - // error handling - return -1; -} - -int -drawstripe(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) -{ - pdf_tensorpatch s0, s1; - - split_stripe(&s0, &s1, &patch); - - depth++; - - if (depth >= SEGMENTATION_DEPTH) - { - ptr = triangulatepatch(s0, shade, ptr, ncomp); - ptr = triangulatepatch(s1, shade, ptr, ncomp); - } - else { - ptr = drawstripe(s0, shade, ptr, ncomp, depth); - ptr = drawstripe(s1, shade, ptr, ncomp, depth); - } - - return ptr; -} - -int -drawpatch(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth) -{ - pdf_tensorpatch s0, s1; - - split_patch(&s0, &s1, &patch); - depth++; - - if (depth > SEGMENTATION_DEPTH) - { - ptr = drawstripe(s0, shade, ptr, ncomp, 0); - ptr = drawstripe(s1, shade, ptr, ncomp, 0); - } - else { - ptr = drawpatch(s0, shade, ptr, ncomp, depth); - ptr = drawpatch(s1, shade, ptr, ncomp, depth); - } - - return ptr; -} - -fz_error * -pdf_loadtype6shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) -{ - fz_error *error; - fz_obj *obj; - - int bpcoord; - int bpcomp; - int bpflag; - int ncomp; - - fz_point p0, p1; - - float c0[FZ_MAXCOLORS]; - float c1[FZ_MAXCOLORS]; - - int i, n, j; - unsigned int t; - - int flag; - fz_point p[12]; - - pdf_tensorpatch patch; - - error = nil; - - ncomp = shade->cs->n; - bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); - bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); - bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); - - obj = fz_dictgets(shading, "Decode"); - if (fz_isarray(obj)) - { - pdf_logshade("decode array\n"); - p0.x = fz_toreal(fz_arrayget(obj, 0)); - p1.x = fz_toreal(fz_arrayget(obj, 1)); - p0.y = fz_toreal(fz_arrayget(obj, 2)); - p1.y = fz_toreal(fz_arrayget(obj, 3)); - for (i=0; i < fz_arraylen(obj) / 2; ++i) { - c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); - c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); - } - } - else { - error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); - goto cleanup; - } - - obj = fz_dictgets(shading, "Function"); - if (obj) { - ncomp = 1; - pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); - shade->usefunction; - } - else - shade->usefunction = 0; - - shade->meshcap = 0; - shade->mesh = nil; - error = growshademesh(shade, 1024); - if (error) goto cleanup; - - n = 2 + shade->cs->n; - j = 0; - - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); - if (error) goto cleanup; - - while (fz_peekbyte(xref->stream) != EOF) - { - flag = getdata(xref->stream, bpflag); - - for (i = 0; i < 12; ++i) { - t = getdata(xref->stream, bpcoord); - p[i].x = (float)(p0.x + (t * (p1.x - p0.x) / (pow(2, bpcoord) - 1.))); - t = getdata(xref->stream, bpcoord); - p[i].y = (float)(p0.y + (t * (p1.y - p0.y) / (pow(2, bpcoord) - 1.))); - } - - for (i = 0; i < 4; ++i) { - int k; - for (k=0; k < ncomp; ++k) { - t = getdata(xref->stream, bpcomp); - patch.color[i][k] = - c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); - } - } - - patch.pole[0][0] = p[0]; - patch.pole[1][0] = p[1]; - patch.pole[2][0] = p[2]; - patch.pole[3][0] = p[3]; - patch.pole[3][1] = p[4]; - patch.pole[3][2] = p[5]; - patch.pole[3][3] = p[6]; - patch.pole[2][3] = p[7]; - patch.pole[1][3] = p[8]; - patch.pole[0][3] = p[9]; - patch.pole[0][2] = p[10]; - patch.pole[0][1] = p[11]; - filltensorinterior(&patch); - - j = drawpatch(patch, shade, j, ncomp, 0); - } - if (error = fz_ferror(xref->stream)) - goto cleanup; - - pdf_closestream(xref); - - shade->meshlen = j / n / 3; - -cleanup: - - return nil; -} - -void -filltensorinterior(pdf_tensorpatch *p) -{ -#define lcp1(p0, p3)\ - ((p0 + p0 + p3) / 3.0f) - -#define lcp2(p0, p3)\ - ((p0 + p3 + p3) / 3.0f) - - p->pole[1][1].x = lcp1(p->pole[0][1].x, p->pole[3][1].x) + - lcp1(p->pole[1][0].x, p->pole[1][3].x) - - lcp1(lcp1(p->pole[0][0].x, p->pole[0][3].x), - lcp1(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[1][2].x = lcp1(p->pole[0][2].x, p->pole[3][2].x) + - lcp2(p->pole[1][0].x, p->pole[1][3].x) - - lcp1(lcp2(p->pole[0][0].x, p->pole[0][3].x), - lcp2(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[2][1].x = lcp2(p->pole[0][1].x, p->pole[3][1].x) + - lcp1(p->pole[2][0].x, p->pole[2][3].x) - - lcp2(lcp1(p->pole[0][0].x, p->pole[0][3].x), - lcp1(p->pole[3][0].x, p->pole[3][3].x)); - p->pole[2][2].x = lcp2(p->pole[0][2].x, p->pole[3][2].x) + - lcp2(p->pole[2][0].x, p->pole[2][3].x) - - lcp2(lcp2(p->pole[0][0].x, p->pole[0][3].x), - lcp2(p->pole[3][0].x, p->pole[3][3].x)); - - p->pole[1][1].y = lcp1(p->pole[0][1].y, p->pole[3][1].y) + - lcp1(p->pole[1][0].y, p->pole[1][3].y) - - lcp1(lcp1(p->pole[0][0].y, p->pole[0][3].y), - lcp1(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[1][2].y = lcp1(p->pole[0][2].y, p->pole[3][2].y) + - lcp2(p->pole[1][0].y, p->pole[1][3].y) - - lcp1(lcp2(p->pole[0][0].y, p->pole[0][3].y), - lcp2(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[2][1].y = lcp2(p->pole[0][1].y, p->pole[3][1].y) + - lcp1(p->pole[2][0].y, p->pole[2][3].y) - - lcp2(lcp1(p->pole[0][0].y, p->pole[0][3].y), - lcp1(p->pole[3][0].y, p->pole[3][3].y)); - p->pole[2][2].y = lcp2(p->pole[0][2].y, p->pole[3][2].y) + - lcp2(p->pole[2][0].y, p->pole[2][3].y) - - lcp2(lcp2(p->pole[0][0].y, p->pole[0][3].y), - lcp2(p->pole[3][0].y, p->pole[3][3].y)); - -#undef lcp1 -#undef lcp2 -} - -void -split_curve_s(const fz_point *pole, fz_point *q0, fz_point *q1, int pole_step) -{ -#define midpoint(a,b)\ - ((a)/2.0f + (b)/2.0f) // to avoid overflow - float x12 = midpoint(pole[1 * pole_step].x, pole[2 * pole_step].x); - float y12 = midpoint(pole[1 * pole_step].y, pole[2 * pole_step].y); - - q0[1 * pole_step].x = midpoint(pole[0 * pole_step].x, pole[1 * pole_step].x); - q0[1 * pole_step].y = midpoint(pole[0 * pole_step].y, pole[1 * pole_step].y); - q1[2 * pole_step].x = midpoint(pole[2 * pole_step].x, pole[3 * pole_step].x); - q1[2 * pole_step].y = midpoint(pole[2 * pole_step].y, pole[3 * pole_step].y); - q0[2 * pole_step].x = midpoint(q0[1 * pole_step].x, x12); - q0[2 * pole_step].y = midpoint(q0[1 * pole_step].y, y12); - q1[1 * pole_step].x = midpoint(x12, q1[2 * pole_step].x); - q1[1 * pole_step].y = midpoint(y12, q1[2 * pole_step].y); - q0[0 * pole_step].x = pole[0 * pole_step].x; - q0[0 * pole_step].y = pole[0 * pole_step].y; - q0[3 * pole_step].x = q1[0 * pole_step].x = midpoint(q0[2 * pole_step].x, q1[1 * pole_step].x); - q0[3 * pole_step].y = q1[0 * pole_step].y = midpoint(q0[2 * pole_step].y, q1[1 * pole_step].y); - q1[3 * pole_step].x = pole[3 * pole_step].x; - q1[3 * pole_step].y = pole[3 * pole_step].y; -#undef midpoint -} - -inline void -split_patch(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) -{ - split_curve_s(&p->pole[0][0], &s0->pole[0][0], &s1->pole[0][0], 4); - split_curve_s(&p->pole[0][1], &s0->pole[0][1], &s1->pole[0][1], 4); - split_curve_s(&p->pole[0][2], &s0->pole[0][2], &s1->pole[0][2], 4); - split_curve_s(&p->pole[0][3], &s0->pole[0][3], &s1->pole[0][3], 4); - - copycolor(s0->color[0], p->color[0]); - midcolor(s0->color[1], p->color[0], p->color[1]); - midcolor(s0->color[2], p->color[2], p->color[3]); - copycolor(s0->color[3], p->color[3]); - - copycolor(s1->color[0], s0->color[1]); - copycolor(s1->color[1], p->color[1]); - copycolor(s1->color[2], p->color[2]); - copycolor(s1->color[3], s0->color[2]); -} - -inline void -split_stripe(pdf_tensorpatch *s0, pdf_tensorpatch *s1, const pdf_tensorpatch *p) - -{ - split_curve_s(p->pole[0], s0->pole[0], s1->pole[0], 1); - split_curve_s(p->pole[1], s0->pole[1], s1->pole[1], 1); - split_curve_s(p->pole[2], s0->pole[2], s1->pole[2], 1); - split_curve_s(p->pole[3], s0->pole[3], s1->pole[3], 1); - - copycolor(s0->color[0], p->color[0]); - copycolor(s0->color[1], p->color[1]); - midcolor(s0->color[2], p->color[1], p->color[2]); - midcolor(s0->color[3], p->color[0], p->color[3]); - - copycolor(s1->color[0], s0->color[3]); - copycolor(s1->color[1], s0->color[2]); - copycolor(s1->color[2], p->color[2]); - copycolor(s1->color[3], p->color[3]); -} diff --git a/mupdf/pdf_shade7.c b/mupdf/pdf_shade7.c deleted file mode 100644 index 9f9da69e..00000000 --- a/mupdf/pdf_shade7.c +++ /dev/null @@ -1,151 +0,0 @@ -#include <fitz.h> -#include <mupdf.h> - -int -getdata(fz_file *stream, int bps); - -int -drawpatch(pdf_tensorpatch patch, fz_shade *shade, int ptr, int ncomp, int depth); - -static fz_error * -growshademesh(fz_shade *shade, int amount) -{ - float *newmesh; - int newcap; - - newcap = shade->meshcap + amount; - newmesh = fz_realloc(shade->mesh, sizeof(float) * newcap); - if (!newmesh) - return fz_outofmem; - - shade->mesh = newmesh; - shade->meshcap = newcap; - - return nil; -} - -static inline void copyvert(float *dst, float *src, int n) -{ - while (n--) - *dst++ = *src++; -} - -fz_error * -pdf_loadtype7shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading, fz_obj *ref) -{ - fz_error *error; - fz_obj *obj; - - int bpcoord; - int bpcomp; - int bpflag; - int ncomp; - - float x0, x1, y0, y1; - - float c0[FZ_MAXCOLORS]; - float c1[FZ_MAXCOLORS]; - - int i, n, j; - unsigned int t; - - int flag; - fz_point p[16]; - pdf_tensorpatch patch; - - error = nil; - - ncomp = shade->cs->n; - bpcoord = fz_toint(fz_dictgets(shading, "BitsPerCoordinate")); - bpcomp = fz_toint(fz_dictgets(shading, "BitsPerComponent")); - bpflag = fz_toint(fz_dictgets(shading, "BitsPerFlag")); - - obj = fz_dictgets(shading, "Decode"); - if (fz_isarray(obj)) - { - pdf_logshade("decode array\n"); - x0 = fz_toreal(fz_arrayget(obj, 0)); - x1 = fz_toreal(fz_arrayget(obj, 1)); - y0 = fz_toreal(fz_arrayget(obj, 2)); - y1 = fz_toreal(fz_arrayget(obj, 3)); - for (i=0; i < fz_arraylen(obj) / 2; ++i) { - c0[i] = fz_toreal(fz_arrayget(obj, i*2+4)); - c1[i] = fz_toreal(fz_arrayget(obj, i*2+5)); - } - } - else { - error = fz_throw("syntaxerror: No Decode key in Type 6 Shade"); - goto cleanup; - } - - obj = fz_dictgets(shading, "Function"); - if (obj) { - ncomp = 1; - pdf_loadshadefunction(shade, xref, shading, c0[0], c1[0]); - shade->usefunction; - } - else - shade->usefunction = 0; - - shade->meshcap = 0; - shade->mesh = nil; - error = growshademesh(shade, 1024); - if (error) goto cleanup; - - n = 2 + shade->cs->n; - j = 0; - - error = pdf_openstream(xref, fz_tonum(ref), fz_togen(ref)); - if (error) goto cleanup; - - while (fz_peekbyte(xref->stream) != EOF) - { - flag = getdata(xref->stream, bpflag); - - for (i = 0; i < 16; ++i) { - t = getdata(xref->stream, bpcoord); - p[i].x = x0 + (t * (x1 - x0) / (pow(2, bpcoord) - 1.)); - t = getdata(xref->stream, bpcoord); - p[i].y = y0 + (t * (y1 - y0) / (pow(2, bpcoord) - 1.)); - } - - for (i = 0; i < 4; ++i) { - int k; - for (k=0; k < ncomp; ++k) { - t = getdata(xref->stream, bpcomp); - patch.color[i][k] = - c0[k] + (t * (c1[k] - c0[k]) / (pow(2, bpcomp) - 1.0f)); - } - } - - patch.pole[0][0] = p[0]; - patch.pole[0][1] = p[1]; - patch.pole[0][2] = p[2]; - patch.pole[0][3] = p[3]; - patch.pole[1][3] = p[4]; - patch.pole[2][3] = p[5]; - patch.pole[3][3] = p[6]; - patch.pole[3][2] = p[7]; - patch.pole[3][1] = p[8]; - patch.pole[3][0] = p[9]; - patch.pole[2][0] = p[10]; - patch.pole[1][0] = p[11]; - patch.pole[1][1] = p[12]; - patch.pole[1][2] = p[13]; - patch.pole[2][2] = p[14]; - patch.pole[2][1] = p[15]; - - j = drawpatch(patch, shade, j, ncomp, 0); - } - if (error = fz_ferror(xref->stream)) - goto cleanup; - - pdf_closestream(xref); - - shade->meshlen = j / n / 3; - -cleanup: - - return nil; -} - |