summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-15 07:50:43 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-15 07:50:43 +0100
commit01a774064e13cebc9a75e44432226d845fa46f9a (patch)
treee817e8ad3d4fa2d4bb52f1ac543c9b932b40d657
parent67781c58fef0f94ea234341cea8e7e13646bc4a2 (diff)
downloadmupdf-01a774064e13cebc9a75e44432226d845fa46f9a.tar.xz
render optimizations
-rw-r--r--include/fitz.h2
-rw-r--r--include/fitz/colorspace.h7
-rw-r--r--include/fitz/math.h8
-rw-r--r--include/fitz/pixmap.h1
-rw-r--r--include/fitz/render.h2
-rw-r--r--include/fitz/sysdep.h7
-rw-r--r--mupdf/colorspace.c144
-rw-r--r--mupdf/image.c8
-rw-r--r--mupdf/type3.c4
-rw-r--r--render/pixmap.c101
-rw-r--r--render/render.c30
-rw-r--r--render/renderimage.c20
-rw-r--r--test/pdfrip.c2
-rw-r--r--test/x11pdf.c2
-rw-r--r--tree/colorspace.c47
15 files changed, 303 insertions, 82 deletions
diff --git a/include/fitz.h b/include/fitz.h
index 48754391..2e2c69d1 100644
--- a/include/fitz.h
+++ b/include/fitz.h
@@ -19,8 +19,8 @@
#include "fitz/cmap.h"
#include "fitz/font.h"
-#include "fitz/colorspace.h"
#include "fitz/pixmap.h"
+#include "fitz/colorspace.h"
#include "fitz/image.h"
#include "fitz/tree.h"
diff --git a/include/fitz/colorspace.h b/include/fitz/colorspace.h
index 322b96c8..1d6c9a64 100644
--- a/include/fitz/colorspace.h
+++ b/include/fitz/colorspace.h
@@ -9,6 +9,8 @@ struct fz_colorspace_s
int refs;
char name[16];
int n;
+ void (*convpixmap)(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
+ void (*convcolor)(fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv);
void (*toxyz)(fz_colorspace *, float *src, float *xyz);
void (*fromxyz)(fz_colorspace *, float *xyz, float *dst);
void (*drop)(fz_colorspace *);
@@ -27,5 +29,10 @@ struct fz_colorcube_s
fz_colorspace *fz_keepcolorspace(fz_colorspace *cs);
void fz_dropcolorspace(fz_colorspace *cs);
+
void fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
+void fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);
+
+void fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
+void fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *srcv, fz_colorspace *dsts, fz_pixmap *dstv);
diff --git a/include/fitz/math.h b/include/fitz/math.h
index 30577691..b2f1bf24 100644
--- a/include/fitz/math.h
+++ b/include/fitz/math.h
@@ -1,24 +1,18 @@
/* multiply 8-bit fixpoint (0..1) so that 0*0==0 and 255*255==255 */
static inline unsigned char fz_mul255(unsigned char a, unsigned char b)
{
- return ((a + 1) * b) >> 8;
+ return (a * ((unsigned int)b + 1)) >> 8;
}
/* floor / ceil towards/from +/- inf */
static inline float fz_floor(float x)
{
return floor(x);
-// if (x > 0)
-// return floor(x);
-// return ceil(x);
}
static inline float fz_ceil(float x)
{
return ceil(x);
-// if (x > 0)
-// return ceil(x);
-// return floor(x);
}
/* divide and floor towards -inf */
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index ea112405..ecd45270 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -18,7 +18,6 @@ void fz_debugpixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
void fz_droppixmap(fz_pixmap *map);
-fz_error *fz_convertpixmap(fz_pixmap **dstp, fz_pixmap *src, fz_colorspace *srcs, fz_colorspace *dsts);
fz_error *fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom);
void fz_blendover(fz_pixmap *src, fz_pixmap *dst);
diff --git a/include/fitz/render.h b/include/fitz/render.h
index 9ff4b3f7..ac25a09d 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -15,7 +15,7 @@ struct fz_renderer_s
unsigned char r, g, b;
};
-fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm);
+fz_error *fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int gcmem);
void fz_droprenderer(fz_renderer *gc);
fz_error *fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm);
diff --git a/include/fitz/sysdep.h b/include/fitz/sysdep.h
index 7f7ddbca..3e0f3232 100644
--- a/include/fitz/sysdep.h
+++ b/include/fitz/sysdep.h
@@ -14,6 +14,13 @@
#include <errno.h>
#include <fcntl.h> /* O_RDONLY & co */
+#ifdef _ISOC99_SOURCE
+#elif __GNUC__
+#define restrict __restrict__
+#else
+#define restrict
+#endif
+
#ifdef WIN32
#define NEED_STRLCPY
diff --git a/mupdf/colorspace.c b/mupdf/colorspace.c
index f636a013..a52f3ed0 100644
--- a/mupdf/colorspace.c
+++ b/mupdf/colorspace.c
@@ -1,6 +1,8 @@
#include <fitz.h>
#include <mupdf.h>
+static void fastpixmap(fz_colorspace *ss, fz_pixmap *sp, fz_colorspace *ds, fz_pixmap *dp);
+
static void initcs(fz_colorspace *cs, char *name, int n,
void(*to)(fz_colorspace*,float*,float*),
void(*from)(fz_colorspace*,float*,float*),
@@ -8,10 +10,12 @@ static void initcs(fz_colorspace *cs, char *name, int n,
{
strlcpy(cs->name, name, sizeof cs->name);
cs->refs = 1;
- cs->n = n;
+ cs->convpixmap = fastpixmap;
+ cs->convcolor = fz_stdconvcolor;
cs->toxyz = to;
cs->fromxyz = from;
cs->drop = drop;
+ cs->n = n;
}
static void mat3x3inv(float *dst, float *m)
@@ -80,7 +84,7 @@ static void xyztogray(fz_colorspace *fzcs, float *xyz, float *gray)
static struct calgray kdevicegray =
{
- { -1, "DeviceGray", 1, graytoxyz, xyztogray, nil },
+ { -1, "DeviceGray", 1, fastpixmap, fz_stdconvcolor, graytoxyz, xyztogray, nil },
{ 1.0000, 1.0000, 1.0000 },
{ 0.0000, 0.0000, 0.0000 },
2.2000
@@ -189,7 +193,7 @@ static void xyztorgb(fz_colorspace *fzcs, float *xyz, float *rgb)
static struct calrgb kdevicergb =
{
- { -1, "DeviceRGB", 3, rgbtoxyz, xyztorgb, nil },
+ { -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 },
@@ -322,7 +326,7 @@ static void xyztodevicecmyk(fz_colorspace *cs, float *xyz, float *cmyk)
static fz_colorspace kdevicecmyk =
{
- -1, "DeviceCMYK", 4, devicecmyktoxyz, xyztodevicecmyk, nil
+ -1, "DeviceCMYK", 4, fastpixmap, fz_stdconvcolor, devicecmyktoxyz, xyztodevicecmyk, nil
};
fz_colorspace *pdf_devicecmyk = &kdevicecmyk;
@@ -783,3 +787,135 @@ printf("oopsie, got a pattern colorspace\n");
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;
+ }
+}
+
+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[3] = 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);
+ }
+
+ else fz_stdconvpixmap(ss, sp, ds, dp);
+}
+
diff --git a/mupdf/image.c b/mupdf/image.c
index f280be89..0c70a6df 100644
--- a/mupdf/image.c
+++ b/mupdf/image.c
@@ -78,10 +78,10 @@ static void
decodetile(fz_pixmap *pix, int bpc, int skip, float *decode)
{
unsigned char table[32][256];
- float twon = (1 << bpc) - 1;
+ float invtwon = 1.0 / ((1 << bpc) - 1);
int x, y, k, i;
-printf(" decode bpc=%d skip=%d n=%d twon=%g\n", bpc, skip, pix->n, twon);
+printf(" decode bpc=%d skip=%d n=%d invtwon=%g\n", bpc, skip, pix->n, invtwon);
for (k = skip; k < pix->n; k++)
{
@@ -93,12 +93,12 @@ printf(" decode bpc=%d skip=%d n=%d twon=%g\n", bpc, skip, pix->n, twon);
for (i = 0; i < (1 << bpc); i++)
{
if (skip)
- table[0][i] = (i * 255) / twon;
+ table[0][i] = (i * 255) * invtwon;
for (k = skip; k < pix->n; k++)
{
float min = decode[(k - skip) * 2 + 0];
float max = decode[(k - skip) * 2 + 1];
- float f = min + i * (max - min) / twon;
+ float f = min + i * (max - min) * invtwon;
table[k][i] = f * 255;
}
}
diff --git a/mupdf/type3.c b/mupdf/type3.c
index ec34d090..4e1a9287 100644
--- a/mupdf/type3.c
+++ b/mupdf/type3.c
@@ -1,6 +1,8 @@
#include <fitz.h>
#include <mupdf.h>
+#define GCMEM (4 * 1024)
+
extern pdf_font *pdf_newfont(char *name);
/* TODO: factor out loadencoding which is common with simple fonts */
@@ -67,7 +69,7 @@ t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
bbox.max.x = fz_ceil(bbox.max.x + 0.5);
bbox.max.y = fz_ceil(bbox.max.y + 0.5);
- error = fz_newrenderer(&gc, nil);
+ error = fz_newrenderer(&gc, nil, GCMEM);
if (error)
return error;
error = fz_rendertree(&pixmap, gc, tree, ctm, bbox);
diff --git a/render/pixmap.c b/render/pixmap.c
index a9287ea8..9bbe297b 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -37,61 +37,35 @@ fz_clearpixmap(fz_pixmap *pix)
memset(pix->samples, 0, pix->w * pix->h * pix->n * sizeof(fz_sample));
}
-fz_error *
-fz_convertpixmap(fz_pixmap **dstp, fz_pixmap *src, fz_colorspace *srcs, fz_colorspace *dsts)
-{
- fz_error *error;
- fz_pixmap *dst;
- float srcv[32];
- float dstv[32];
- int y, x, k;
-
- error = fz_newpixmap(&dst, src->x, src->y, src->w, src->h, dsts->n + 1);
- if (error)
- return error;
-
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
-
- printf("convert pixmap from %s to %s\n", srcs->name, dsts->name);
-
- for (y = 0; y < src->h; y++)
- {
- for (x = 0; x < src->w; x++)
- {
- *d++ = *s++;
-
- for (k = 0; k < src->n - 1; k++)
- srcv[k] = *s++ / 255.0;
-
- fz_convertcolor(srcs, srcv, dsts, dstv);
-
- for (k = 0; k < dst->n - 1; k++)
- *d++ = dstv[k] * 255;
- }
- }
-
- *dstp = dst;
- return nil;
-}
-
void
fz_blendover(fz_pixmap *src, fz_pixmap *dst)
{
int x, y, k;
+ fz_irect sr, dr, rect;
+ unsigned char *s;
+ unsigned char *d;
assert(dst->n == src->n || src->n == 1);
- assert(dst->w == src->w);
- assert(dst->h == src->h);
- unsigned char *s = src->samples;
- unsigned char *d = dst->samples;
+ sr.min.x = src->x;
+ sr.min.y = src->y;
+ sr.max.x = src->x + src->w;
+ sr.max.y = src->y + src->h;
+
+ dr.min.x = dst->x;
+ dr.min.y = dst->y;
+ dr.max.x = dst->x + dst->w;
+ dr.max.y = dst->y + dst->h;
+
+ rect = fz_intersectirects(sr, dr);
if (dst->n == src->n)
{
- for (y = 0; y < dst->h; y++)
+ for (y = rect.min.y; y < rect.max.y; y++)
{
- for (x = 0; x < dst->w; x++)
+ s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
+ d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
+ for (x = rect.min.x; x < rect.max.x; x++)
{
int sa = s[0];
int ssa = 255 - sa;
@@ -106,9 +80,11 @@ fz_blendover(fz_pixmap *src, fz_pixmap *dst)
}
else if (src->n == 1)
{
- for (y = 0; y < dst->h; y++)
+ for (y = rect.min.y; y < rect.max.y; y++)
{
- for (x = 0; x < dst->w; x++)
+ s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
+ d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
+ for (x = rect.min.x; x < rect.max.x; x++)
{
int sa = s[0];
int ssa = 255 - sa;
@@ -127,22 +103,41 @@ fz_blendover(fz_pixmap *src, fz_pixmap *dst)
void
fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
{
+ unsigned char *d;
+ unsigned char *s;
+ unsigned char *m;
+ fz_irect sr, dr, mr, rect;
int x, y, k;
assert(src->n == dst->n);
- unsigned char *d = dst->samples;
- unsigned char *s = src->samples;
- unsigned char *m = msk->samples;
+ sr.min.x = src->x;
+ sr.min.y = src->y;
+ sr.max.x = src->x + src->w;
+ sr.max.y = src->y + src->h;
+
+ dr.min.x = dst->x;
+ dr.min.y = dst->y;
+ dr.max.x = dst->x + dst->w;
+ dr.max.y = dst->y + dst->h;
+
+ mr.min.x = msk->x;
+ mr.min.y = msk->y;
+ mr.max.x = msk->x + msk->w;
+ mr.max.y = msk->y + msk->h;
- for (y = 0; y < dst->h; y++)
+ rect = fz_intersectirects(sr, dr);
+ rect = fz_intersectirects(rect, mr);
+
+ for (y = rect.min.y; y < rect.max.y; y++)
{
- for (x = 0; x < dst->w; x++)
+ s = src->samples + ((rect.min.x - src->x) + (y - src->y) * src->w) * src->n;
+ d = dst->samples + ((rect.min.x - dst->x) + (y - dst->y) * dst->w) * dst->n;
+ m = msk->samples + ((rect.min.x - msk->x) + (y - msk->y) * msk->w) * msk->n;
+ for (x = rect.min.x; x < rect.max.x; x++)
{
for (k = 0; k < dst->n; k++)
- {
*d++ = fz_mul255(*s++, *m);
- }
m += msk->n;
}
}
diff --git a/render/render.c b/render/render.c
index ad42bdbe..1798e011 100644
--- a/render/render.c
+++ b/render/render.c
@@ -9,7 +9,7 @@ fz_error *fz_renderimageover(fz_renderer*, fz_imagenode*, fz_matrix);
fz_error *fz_renderimage(fz_renderer*, fz_imagenode*, fz_matrix);
fz_error *
-fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel)
+fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel, int gcmem)
{
fz_error *error;
fz_renderer *gc;
@@ -26,7 +26,7 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *processcolormodel)
gc->tmp = nil;
gc->acc = nil;
- error = fz_newglyphcache(&gc->cache, 4096, 256 * 1024);
+ error = fz_newglyphcache(&gc->cache, gcmem / 32, gcmem);
if (error)
goto cleanup;
@@ -191,6 +191,8 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
fz_node *color;
fz_node *shape;
int oldmode;
+ fz_rect bbox;
+ int ox, oy, ow, oh;
color = mask->super.child;
shape = color->next;
@@ -201,6 +203,8 @@ fz_rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
return fz_rendercolorpath(gc, (fz_pathnode*)shape, (fz_colornode*)color, ctm);
if (fz_istextnode(shape) && fz_iscolornode(color))
return fz_rendercolortext(gc, (fz_textnode*)shape, (fz_colornode*)color, ctm);
+ if (fz_isimagenode(shape) && fz_iscolornode(color))
+ puts("could optimize image mask!");
}
printf("begin mask\n");
@@ -210,6 +214,23 @@ printf("begin mask\n");
gc->acc = nil;
gc->mode = FZ_RMASK;
+ // TODO: set clip bbox to that of shape
+
+ bbox = fz_boundnode(shape, ctm);
+ bbox = fz_intersectrects(bbox, (fz_rect){{gc->x,gc->y},{gc->x+gc->w,gc->y+gc->h}});
+ printf("mask bbox [%g %g %g %g]\n", bbox.min.x, bbox.min.y, bbox.max.x, bbox.max.y);
+ ox = gc->x;
+ oy = gc->y;
+ ow = gc->w;
+ oh = gc->h;
+
+ gc->x = fz_floor(bbox.min.x) - 1;
+ gc->y = fz_floor(bbox.min.y) - 1;
+ gc->w = fz_ceil(bbox.max.x) - fz_floor(bbox.min.x) + 1;
+ gc->h = fz_ceil(bbox.max.y) - fz_floor(bbox.min.y) + 1;
+ ctm.e -= bbox.min.x - fz_floor(bbox.min.x);
+ ctm.f -= bbox.min.y - fz_floor(bbox.min.y);
+
gc->tmp = nil;
error = fz_rendernode(gc, color, ctm);
if (error)
@@ -240,6 +261,11 @@ if (!shapepix) return nil;
gc->acc = oldacc;
gc->mode = oldmode;
+ gc->x = ox;
+ gc->y = oy;
+ gc->w = ow;
+ gc->h = oh;
+
printf("end mask\n");
return nil;
diff --git a/render/renderimage.c b/render/renderimage.c
index e4daae57..3741ab73 100644
--- a/render/renderimage.c
+++ b/render/renderimage.c
@@ -12,8 +12,6 @@ static inline int getcomp(fz_pixmap *pix, int u, int v, int k)
return 0;
if (v < 0 || v >= pix->h)
return 0;
-// u = CLAMP(u, 0, pix->w - 1);
-// v = CLAMP(v, 0, pix->h - 1);
return pix->samples[ (v * pix->w + u) * pix->n + k ];
}
@@ -204,7 +202,8 @@ printf(" draw image rgb over\n");
else
{
printf(" draw image rgb over after cs transform\n");
- error = fz_convertpixmap(&tile3, tile2, cs, gc->model);
+ error = fz_newpixmap(&tile3, tile2->x, tile2->y, tile2->w, tile2->h, gc->model->n + 1);
+ fz_convertpixmap(cs, tile2, gc->model, tile3);
error = drawtile(gc, gc->acc, tile3, ctm, 1);
fz_droppixmap(tile3);
}
@@ -214,8 +213,19 @@ printf(" draw image rgb over after cs transform\n");
else
{
printf(" draw image after cs transform\n");
- error = fz_convertpixmap(&tile3, tile2, cs, gc->model);
- error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, gc->model->n + 1);
+ error = fz_newpixmap(&tile3, tile2->x, tile2->y, tile2->w, tile2->h, gc->model->n + 1);
+ fz_convertpixmap(cs, tile2, gc->model, tile3);
+ fz_rect bbox = fz_boundnode((fz_node*)node, ctm);
+ fz_irect aabb;
+ aabb.min.x = fz_floor(bbox.min.x) - 1;
+ aabb.min.y = fz_floor(bbox.min.y) - 1;
+ aabb.max.x = fz_ceil(bbox.max.x) + 1;
+ aabb.max.y = fz_ceil(bbox.max.y) + 1;
+ aabb = fz_intersectirects(aabb, (fz_irect){{gc->x,gc->y},{gc->x+gc->w,gc->y+gc->h}});
+ error = fz_newpixmap(&gc->tmp,
+ aabb.min.x, aabb.min.y,
+ aabb.max.x - aabb.min.x, aabb.max.y - aabb.min.y,
+ gc->model->n + 1);
fz_clearpixmap(gc->tmp);
error = drawtile(gc, gc->tmp, tile3, ctm, 0);
fz_droppixmap(tile3);
diff --git a/test/pdfrip.c b/test/pdfrip.c
index 2f79f334..daca3ba9 100644
--- a/test/pdfrip.c
+++ b/test/pdfrip.c
@@ -49,7 +49,7 @@ void showpage(pdf_xref *xref, fz_obj *pageobj)
fz_matrix ctm;
fz_rect bbox;
- error = fz_newrenderer(&gc, pdf_devicergb);
+ error = fz_newrenderer(&gc, pdf_devicergb, 1024 * 512);
if (error) fz_abort(error);
ctm = fz_concat(fz_translate(0, -page->mediabox.max.y), fz_scale(zoom, -zoom));
diff --git a/test/x11pdf.c b/test/x11pdf.c
index 60f25d65..83b340b1 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -200,7 +200,7 @@ static void pdfopen(char *filename, char *password)
count = pdf_getpagecount(pages);
- error = fz_newrenderer(&rast, pdf_devicergb);
+ error = fz_newrenderer(&rast, pdf_devicergb, 1024 * 512);
if (error) fz_abort(error);
image = nil;
diff --git a/tree/colorspace.c b/tree/colorspace.c
index ae922bcd..af0239f5 100644
--- a/tree/colorspace.c
+++ b/tree/colorspace.c
@@ -1,5 +1,17 @@
#include <fitz.h>
+void
+fz_convertpixmap(fz_colorspace *srcs, fz_pixmap *src, fz_colorspace *dsts, fz_pixmap *dst)
+{
+ srcs->convpixmap(srcs, src, dsts, dst);
+}
+
+void
+fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
+{
+ srcs->convcolor(srcs, srcv, dsts, dstv);
+}
+
fz_colorspace *
fz_keepcolorspace(fz_colorspace *cs)
{
@@ -21,7 +33,7 @@ fz_dropcolorspace(fz_colorspace *cs)
}
void
-fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
+fz_stdconvcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv)
{
float xyz[3];
int i;
@@ -43,3 +55,36 @@ fz_convertcolor(fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *ds
}
}
+void
+fz_stdconvpixmap(fz_colorspace *srcs, fz_pixmap *src, fz_colorspace *dsts, fz_pixmap *dst)
+{
+ float srcv[32];
+ float dstv[32];
+ int y, x, k;
+
+ unsigned char *s = src->samples;
+ unsigned char *d = dst->samples;
+
+ assert(src->w == dst->w && src->h == dst->h);
+ assert(src->n == srcs->n + 1);
+ assert(dst->n == dsts->n + 1);
+
+ printf("convert pixmap from %s to %s\n", srcs->name, dsts->name);
+
+ for (y = 0; y < src->h; y++)
+ {
+ for (x = 0; x < src->w; x++)
+ {
+ *d++ = *s++;
+
+ for (k = 0; k < src->n - 1; k++)
+ srcv[k] = *s++ / 255.0;
+
+ fz_convertcolor(srcs, srcv, dsts, dstv);
+
+ for (k = 0; k < dst->n - 1; k++)
+ *d++ = dstv[k] * 255;
+ }
+ }
+}
+