summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fitz/image.h2
-rw-r--r--include/fitz/pixmap.h22
-rw-r--r--mupdf/image.c89
-rw-r--r--render/pixmap.c157
-rw-r--r--render/render.c31
-rw-r--r--render/renderimage.c113
-rw-r--r--render/renderpath.c16
-rw-r--r--render/rendertext.c18
-rw-r--r--render/scale.c85
9 files changed, 279 insertions, 254 deletions
diff --git a/include/fitz/image.h b/include/fitz/image.h
index 0ff954c5..ea3ebaa9 100644
--- a/include/fitz/image.h
+++ b/include/fitz/image.h
@@ -1,5 +1,7 @@
typedef struct fz_image_s fz_image;
+/* loadtile will fill a pixmap with the pixel samples. non-premultiplied alpha. */
+
struct fz_image_s
{
fz_error* (*loadtile)(fz_image*,fz_pixmap*);
diff --git a/include/fitz/pixmap.h b/include/fitz/pixmap.h
index 7b8bfb1e..508a304b 100644
--- a/include/fitz/pixmap.h
+++ b/include/fitz/pixmap.h
@@ -1,19 +1,25 @@
+/*
+pixmaps have n components per pixel. the first is always alpha.
+premultiplied alpha when rendering, but non-premultiplied for colorspace
+conversions and rescaling.
+*/
+
typedef struct fz_pixmap_s fz_pixmap;
+typedef unsigned char fz_sample;
struct fz_pixmap_s
{
- fz_colorspace *cs;
- int x, y, w, h;
- int n, a;
- int stride;
- unsigned char *samples;
+ int x, y, w, h, n;
+ fz_sample *samples;
};
-fz_error *fz_newpixmap(fz_pixmap **mapp, fz_colorspace *cs, int x, int y, int w, int h, int n, int a);
+fz_error *fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n);
void fz_debugpixmap(fz_pixmap *map);
-void fz_freepixmap(fz_pixmap *map);
void fz_clearpixmap(fz_pixmap *map);
-void fz_convertpixmap(fz_pixmap *src, fz_pixmap *dst);
+void fz_freepixmap(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);
void fz_blendmask(fz_pixmap *dst, fz_pixmap *color, fz_pixmap *shape);
diff --git a/mupdf/image.c b/mupdf/image.c
index f866264a..431645cc 100644
--- a/mupdf/image.c
+++ b/mupdf/image.c
@@ -9,31 +9,64 @@ static inline int getbit(const unsigned char *buf, int x)
static void loadtile1(pdf_image *src, fz_pixmap *dst)
{
int x, y, k;
- int n = dst->n + dst->a;
- for (y = 0; y < dst->h; y++)
+ int n = dst->n;
+ for (y = dst->y; y < dst->y + dst->h; y++)
{
- unsigned char *srcp = src->samples->bp + (dst->y + y) * src->stride;
- unsigned char *dstp = dst->samples + (dst->y + y) * dst->stride;
- for (x = 0; x < dst->w; x++)
+ unsigned char *s = src->samples->bp + y * src->stride;
+ unsigned char *d = dst->samples + y * dst->w * dst->n;
+ for (x = dst->x; x < dst->x + dst->w; x++)
{
for (k = 0; k < n; k++)
- dstp[(dst->x + x) * n + k] = getbit(srcp, (dst->x + x) * n + k) * 255;
+ d[x * n + k] = getbit(s, x * n + k) * 255;
}
}
}
-static void loadtile8(pdf_image *src, fz_pixmap *dst)
+static void loadtile1a(pdf_image *src, fz_pixmap *dst)
{
int x, y, k;
- int n = dst->n + dst->a;
- for (y = 0; y < dst->h; y++)
+ int sn = src->super.n;
+ int dn = dst->n;
+ for (y = dst->y; y < dst->y + dst->h; y++)
{
- unsigned char *srcp = src->samples->bp + (dst->y + y) * src->stride;
- unsigned char *dstp = dst->samples + (dst->y + y) * dst->stride;
- for (x = 0; x < dst->w; x++)
+ unsigned char *s = src->samples->bp + y * src->stride;
+ unsigned char *d = dst->samples + y * dst->w * dst->n;
+ for (x = dst->x; x < dst->x + dst->w; x++)
{
+ d[0] = 255;
+ for (k = 0; k < sn; k++)
+ d[x * dn + k + 1] = getbit(s, x * sn + k) * 255;
+ }
+ }
+}
+
+static void loadtile8(pdf_image *src, fz_pixmap *dst)
+{
+ int x, y, k;
+ int n = src->super.n;
+ for (y = dst->y; y < dst->y + dst->h; y++)
+ {
+ unsigned char *s = src->samples->bp + y * src->stride;
+ unsigned char *d = dst->samples + y * dst->w * dst->n;
+ for (x = dst->x; x < dst->x + dst->w; x++)
for (k = 0; k < n; k++)
- dstp[(dst->x + x) * n + k] = srcp[(dst->x + x) * n + k];
+ *d++ = *s++;
+ }
+}
+
+static void loadtile8a(pdf_image *src, fz_pixmap *dst)
+{
+ int x, y, k;
+ int n = dst->n;
+ for (y = dst->y; y < dst->y + dst->h; y++)
+ {
+ unsigned char *s = src->samples->bp + y * src->stride;
+ unsigned char *d = dst->samples + y * dst->w * dst->n;
+ for (x = dst->x; x < dst->x + dst->w; x++)
+ {
+ *d++ = 255;
+ for (k = 1; k < n; k++)
+ *d++ = *s++;
}
}
}
@@ -42,19 +75,31 @@ static fz_error *loadtile(fz_image *img, fz_pixmap *tile)
{
pdf_image *src = (pdf_image*)img;
- assert(tile->n == img->n);
- assert(tile->a == img->a);
+ assert(tile->n == img->n + 1);
assert(tile->x >= 0);
assert(tile->y >= 0);
assert(tile->x + tile->w <= img->w);
assert(tile->y + tile->h <= img->h);
- switch (src->bpc)
+ if (img->a)
{
- case 1: loadtile1(src, tile); return nil;
-// case 2: loadtile2(src, tile); return nil;
-// case 4: loadtile4(src, tile); return nil;
- case 8: loadtile8(src, tile); return nil;
+ switch (src->bpc)
+ {
+ case 1: loadtile1(src, tile); return nil;
+ // case 2: loadtile2(src, tile); return nil;
+ // case 4: loadtile4(src, tile); return nil;
+ case 8: loadtile8(src, tile); return nil;
+ }
+ }
+ else
+ {
+ switch (src->bpc)
+ {
+ case 1: loadtile1a(src, tile); return nil;
+ // case 2: loadtile2a(src, tile); return nil;
+ // case 4: loadtile4a(src, tile); return nil;
+ case 8: loadtile8a(src, tile); return nil;
+ }
}
return fz_throw("rangecheck: unsupported bit depth: %d", src->bpc);
@@ -123,7 +168,7 @@ printf("load image %d x %d @ %d\n", img->super.w, img->super.h, img->bpc);
for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
img->decode[i] = i & 1;
-printf(" cs %s\n", cs ? cs->name : "(null)");
+printf(" colorspace %s\n", cs ? cs->name : "(null)");
printf(" mask %d\n", ismask);
printf(" decode [ ");
for (i = 0; i < (img->super.n + img->super.a) * 2; i++)
@@ -138,8 +183,6 @@ printf("]\n");
return error;
}
-printf(" stride = %d -> %d bytes\n", img->stride, img->stride * img->super.h);
-printf(" samples = %d bytes\n", img->samples->wp - img->samples->bp);
if (img->samples->wp - img->samples->bp != img->stride * img->super.h)
{
/* TODO: colorspace? */
diff --git a/render/pixmap.c b/render/pixmap.c
index 6ef9d75c..07eea36e 100644
--- a/render/pixmap.c
+++ b/render/pixmap.c
@@ -1,7 +1,7 @@
#include <fitz.h>
fz_error *
-fz_newpixmap(fz_pixmap **pixp, fz_colorspace *cs, int x, int y, int w, int h, int n, int a)
+fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n)
{
fz_pixmap *pix;
@@ -9,22 +9,19 @@ fz_newpixmap(fz_pixmap **pixp, fz_colorspace *cs, int x, int y, int w, int h, in
if (!pix)
return fz_outofmem;
- pix->cs = cs;
pix->x = x;
pix->y = y;
pix->w = w;
pix->h = h;
pix->n = n;
- pix->a = a;
- pix->stride = (pix->n + pix->a) * pix->w;
- pix->samples = fz_malloc(sizeof(unsigned char) * pix->stride * pix->h);
+ pix->samples = fz_malloc(pix->w * pix->h * pix->n * sizeof(fz_sample));
if (!pix->samples) {
fz_free(pix);
return fz_outofmem;
}
- memset(pix->samples, 0, sizeof(unsigned char) * pix->stride * pix->h);
+ memset(pix->samples, 0, pix->w * pix->h * pix->n * sizeof(fz_sample));
return nil;
}
@@ -39,65 +36,71 @@ fz_freepixmap(fz_pixmap *pix)
void
fz_clearpixmap(fz_pixmap *pix)
{
- memset(pix->samples, 0, sizeof(unsigned char) * pix->stride * pix->h);
+ memset(pix->samples, 0, pix->w * pix->h * pix->n * sizeof(fz_sample));
}
-void
-fz_convertpixmap(fz_pixmap *src, fz_pixmap *dst)
+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;
- int sna = src->n + src->a;
- int dna = dst->n + dst->a;
-printf("convert pixmap from %s to %s\n", src->cs->name, dst->cs->name);
+ 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++)
{
- for (k = 0; k < src->n; k++)
- srcv[k] = src->samples[ y * src->stride + x * sna + k ] / 255.0;
- fz_convertcolor(src->cs, srcv, dst->cs, dstv);
- for (k = 0; k < dst->n; k++)
- dst->samples[ y * dst->stride + x * dna + k ] = dstv[k] * 255;
- if (src->a && dst->a)
- dst->samples[ y * dst->stride + x * dna + dst->n ] =
- src->samples[ y * src->stride + x * sna + src->n ];
- else if (dst->a)
- dst->samples[ y * dst->stride + x * dna + dst->n ] = 255;
+ *s++ = *d++;
+
+ 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 + 0.5;
}
}
+
+ *dstp = dst;
+ return nil;
}
void
fz_blendover(fz_pixmap *src, fz_pixmap *dst)
{
- int x, y;
+ int x, y, k;
assert(dst->n == src->n);
- assert(dst->a == 1);
- assert(src->n == 3);
- assert(src->a == 1);
+ assert(dst->w == src->w);
+ assert(dst->h == src->h);
+
+ unsigned char *s = src->samples;
+ unsigned char *d = dst->samples;
for (y = 0; y < dst->h; y++)
{
- unsigned char *s = &src->samples[y * src->stride];
- unsigned char *d = &dst->samples[y * dst->stride];
-
for (x = 0; x < dst->w; x++)
{
- int sa = s[3];
+ int sa = s[0];
int ssa = 255 - sa;
- d[0] = fz_mul255(s[0], sa) + fz_mul255(d[0], ssa);
- d[1] = fz_mul255(s[1], sa) + fz_mul255(d[1], ssa);
- d[2] = fz_mul255(s[2], sa) + fz_mul255(d[2], ssa);
- d[3] = sa + fz_mul255(d[3], ssa);
+ for (k = 0; k < dst->n; k++)
+ d[k] = s[k] + fz_mul255(d[k], ssa);
- s += 4;
- d += 4;
+ s += src->n;
+ d += dst->n;
}
}
}
@@ -108,22 +111,21 @@ fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
int x, y, k;
assert(src->n == dst->n);
- assert(src->a == 1);
- assert(msk->n == 0);
- assert(msk->a == 1);
- assert(dst->a == 1);
+ assert(msk->n == 1);
+
+ unsigned char *d = dst->samples;
+ unsigned char *s = src->samples;
+ unsigned char *m = msk->samples;
for (y = 0; y < dst->h; y++)
{
- unsigned char *d = &dst->samples[y * dst->stride];
- unsigned char *s = &src->samples[y * src->stride];
- unsigned char *m = &msk->samples[y * msk->stride];
-
for (x = 0; x < dst->w; x++)
{
for (k = 0; k < dst->n; k++)
- *d++ = *s++;
- *d++ = fz_mul255(*m++, *s++);
+ {
+ *d++ = fz_mul255(*s++, *m);
+ }
+ m++;
}
}
}
@@ -131,62 +133,39 @@ fz_blendmask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
void
fz_debugpixmap(fz_pixmap *pix)
{
- int x, y;
-
- FILE *ppm = fopen("out.ppm", "w");
- FILE *pgm = fopen("out.pgm", "w");
-
- fprintf(ppm, "P6\n%d %d\n255\n", pix->w, pix->h);
- fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h);
-
- if (pix->n == 3 && pix->a == 1)
+ if (pix->n == 4)
{
+ int x, y;
+ FILE *ppm = fopen("out.ppm", "w");
+ FILE *pgm = fopen("out.pgm", "w");
+ fprintf(ppm, "P6\n%d %d\n255\n", pix->w, pix->h);
+ fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h);
+
for (y = 0; y < pix->h; y++)
for (x = 0; x < pix->w; x++)
{
- int r = pix->samples[x * 4 + y * pix->stride + 0];
- int g = pix->samples[x * 4 + y * pix->stride + 1];
- int b = pix->samples[x * 4 + y * pix->stride + 2];
- int a = pix->samples[x * 4 + y * pix->stride + 3];
-
+ int a = pix->samples[x * pix->n + y * pix->w * pix->n + 0];
+ int r = pix->samples[x * pix->n + y * pix->w * pix->n + 1];
+ int g = pix->samples[x * pix->n + y * pix->w * pix->n + 2];
+ int b = pix->samples[x * pix->n + y * pix->w * pix->n + 3];
+ putc(a, pgm);
putc(r, ppm);
putc(g, ppm);
putc(b, ppm);
// putc(((r * a) / 255) + (255 - a), ppm);
// putc(((g * a) / 255) + (255 - a), ppm);
// putc(((b * a) / 255) + (255 - a), ppm);
-
- putc(a, pgm);
}
+ fclose(ppm);
+ fclose(pgm);
}
- if (pix->n == 3 && pix->a == 0)
- {
- for (y = 0; y < pix->h; y++)
- for (x = 0; x < pix->w; x++)
- {
- int r = pix->samples[x * 3 + y * pix->stride + 0];
- int g = pix->samples[x * 3 + y * pix->stride + 1];
- int b = pix->samples[x * 3 + y * pix->stride + 2];
- putc(r, ppm);
- putc(g, ppm);
- putc(b, ppm);
- putc(255, pgm);
- }
- }
- else if (pix->n == 0 && pix->a == 1)
+
+ else if (pix->n == 1)
{
- for (y = 0; y < pix->h; y++)
- for (x = 0; x < pix->w; x++)
- {
- int a = pix->samples[x + y * pix->stride];
- putc(0, ppm);
- putc(0, ppm);
- putc(0, ppm);
- putc(a, pgm);
- }
+ FILE *pgm = fopen("out.pgm", "w");
+ fprintf(pgm, "P5\n%d %d\n255\n", pix->w, pix->h);
+ fwrite(pix->samples, 1, pix->w * pix->h, pgm);
+ fclose(pgm);
}
-
- fclose(ppm);
- fclose(pgm);
}
diff --git a/render/render.c b/render/render.c
index 73408a8b..d1eb6136 100644
--- a/render/render.c
+++ b/render/render.c
@@ -82,19 +82,20 @@ printf("render color\n");
gc->g = rgb[1] * 255;
gc->b = rgb[2] * 255;
- error = fz_newpixmap(&gc->tmp, color->cs, gc->x, gc->y, gc->w, gc->h, 3, 1);
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 4);
if (error)
return error;
+ unsigned char *p = gc->tmp->samples;
+
for (y = 0; y < gc->tmp->h; y++)
{
- unsigned char *p = &gc->tmp->samples[y * gc->tmp->stride];
for (x = 0; x < gc->tmp->w; x++)
{
+ *p++ = 255;
*p++ = gc->r;
*p++ = gc->g;
*p++ = gc->b;
- *p++ = 255;
}
}
@@ -120,10 +121,10 @@ fz_renderoverchild(fz_renderer *gc, fz_node *node, fz_matrix ctm)
if (gc->tmp)
{
-printf("over src ");fz_debugpixmap(gc->tmp);getchar();
-printf("over dst ");fz_debugpixmap(gc->acc);getchar();
+//printf("over src ");fz_debugpixmap(gc->tmp);getchar();
+//printf("over dst ");fz_debugpixmap(gc->acc);getchar();
fz_blendover(gc->tmp, gc->acc);
-printf("over res ");fz_debugpixmap(gc->acc);getchar();
+//printf("over res ");fz_debugpixmap(gc->acc);getchar();
fz_freepixmap(gc->tmp);
gc->tmp = nil;
}
@@ -138,14 +139,14 @@ fz_renderover(fz_renderer *gc, fz_overnode *over, fz_matrix ctm)
fz_pixmap *oldacc = nil;
int oldmode;
-printf("begin over\n");
+//printf("begin over\n");
/* uh-oh! we have a new over cluster */
if (gc->mode != FZ_ROVER)
{
printf("begin over accumulator\n");
oldacc = gc->acc;
- error = fz_newpixmap(&gc->acc, gc->model, gc->x, gc->y, gc->w, gc->h, 3, 1);
+ error = fz_newpixmap(&gc->acc, gc->x, gc->y, gc->w, gc->h, 4);
if (error)
return error;
fz_clearpixmap(gc->acc);
@@ -173,7 +174,7 @@ printf("end over accumulator\n");
gc->acc = oldacc;
}
-printf("end over\n");
+//printf("end over\n");
return nil;
}
@@ -216,15 +217,17 @@ printf("begin mask\n");
return error;
shapepix = gc->tmp;
- error = fz_newpixmap(&gc->tmp, colorpix->cs, gc->x, gc->y, gc->w, gc->h, colorpix->n, 1);
+if (!shapepix) return nil;
+
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, colorpix->n);
if (error)
return error;
fz_blendmask(gc->tmp, colorpix, shapepix);
-printf("mask color");fz_debugpixmap(colorpix);getchar();
-printf("mask shape");fz_debugpixmap(shapepix);getchar();
-printf("mask blend");fz_debugpixmap(gc->tmp);getchar();
+//printf("mask color");fz_debugpixmap(colorpix);getchar();
+//printf("mask shape");fz_debugpixmap(shapepix);getchar();
+//printf("mask blend");fz_debugpixmap(gc->tmp);getchar();
fz_freepixmap(shapepix);
fz_freepixmap(colorpix);
@@ -239,7 +242,7 @@ printf("end mask\n");
fz_error *
fz_rendertransform(fz_renderer *gc, fz_transformnode *transform, fz_matrix ctm)
{
-printf("render transform\n");
+//printf("render transform\n");
ctm = fz_concat(transform->m, ctm);
return fz_rendernode(gc, transform->super.child, ctm);
}
diff --git a/render/renderimage.c b/render/renderimage.c
index 068c9ca4..9fdf47ba 100644
--- a/render/renderimage.c
+++ b/render/renderimage.c
@@ -1,8 +1,5 @@
#include <fitz.h>
-fz_error *
-fz_scalepixmap(fz_pixmap *src, fz_pixmap *dst, int xdenom, int ydenom);
-
static int getcomp(fz_pixmap *pix, float u, float v, int k)
{
float fu = floor(u);
@@ -20,10 +17,10 @@ static int getcomp(fz_pixmap *pix, float u, float v, int k)
y0 = CLAMP(y0, 0, pix->h - 1);
y1 = CLAMP(y1, 0, pix->h - 1);
- float a = pix->samples[ y0 * pix->stride + x0 * (pix->n + pix->a) + k ];
- float b = pix->samples[ y0 * pix->stride + x1 * (pix->n + pix->a) + k ];
- float c = pix->samples[ y1 * pix->stride + x0 * (pix->n + pix->a) + k ];
- float d = pix->samples[ y1 * pix->stride + x1 * (pix->n + pix->a) + k ];
+ float a = pix->samples[ (y0 * pix->w + x0) * pix->n + k ];
+ float b = pix->samples[ (y0 * pix->w + x1) * pix->n + k ];
+ float c = pix->samples[ (y1 * pix->w + x0) * pix->n + k ];
+ float d = pix->samples[ (y1 * pix->w + x1) * pix->n + k ];
float ab = a * (1.0 - su) + b * su;
float cd = c * (1.0 - su) + d * su;
@@ -42,11 +39,8 @@ drawscan(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, int x
for (x = x0; x < x1; x++)
{
- for (k = 0; k < src->n + src->a; k++)
- dst->samples[ y * dst->stride + x * (dst->n+dst->a) + k ] = getcomp(src, u, v, k);
- if (!src->a && dst->a)
- dst->samples[ y * dst->stride + x * (dst->n + dst->a) + dst->n ] = 0xFF;
-
+ for (k = 0; k < src->n; k++)
+ dst->samples[ (y * dst->w + x) * dst->n + k ] = getcomp(src, u, v, k);
u += invmat->a;
v += invmat->c;
}
@@ -62,35 +56,27 @@ overscanrgb(fz_matrix *invmat, fz_pixmap *dst, fz_pixmap *src, int y, int x0, in
for (x = x0; x < x1; x++)
{
- float a = 1.0;
- if (u < 0)
- a *= 1.0 - (u - floor(u));
- if (u > src->w - 1)
- a *= u - floor(u);
- if (v < 0)
- a *= 1.0 - (v - floor(v));
- if (v > src->h - 1)
- a *= v - floor(v);
-
- int sr = getcomp(src, u, v, 0);
- int sg = getcomp(src, u, v, 1);
- int sb = getcomp(src, u, v, 2);
-
- int dr = dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 0 ];
- int dg = dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 1 ];
- int db = dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 2 ];
-
- int sa = a * 255;
+ int sa = getcomp(src, u, v, 0);
+ int sr = getcomp(src, u, v, 1);
+ int sg = getcomp(src, u, v, 2);
+ int sb = getcomp(src, u, v, 3);
+
+ int da = dst->samples[ (y * dst->w + x) * dst->n + 0 ];
+ int dr = dst->samples[ (y * dst->w + x) * dst->n + 1 ];
+ int dg = dst->samples[ (y * dst->w + x) * dst->n + 2 ];
+ int db = dst->samples[ (y * dst->w + x) * dst->n + 3 ];
+
int ssa = 255 - sa;
- dr = fz_mul255(sr, sa) + fz_mul255(dr, ssa);
- dg = fz_mul255(sg, sa) + fz_mul255(dg, ssa);
- db = fz_mul255(sb, sa) + fz_mul255(db, ssa);
+ da = sa + fz_mul255(da, ssa);
+ dr = sr + fz_mul255(dr, ssa);
+ dg = sg + fz_mul255(dg, ssa);
+ db = sb + fz_mul255(db, ssa);
- dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 0 ] = dr;
- dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 1 ] = dg;
- dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 2 ] = db;
- dst->samples[ y * dst->stride + x * (dst->n+dst->a) + 3 ] = sa;
+ dst->samples[ (y * dst->w + x) * dst->n + 0 ] = sa;
+ dst->samples[ (y * dst->w + x) * dst->n + 1 ] = sr;
+ dst->samples[ (y * dst->w + x) * dst->n + 2 ] = sg;
+ dst->samples[ (y * dst->w + x) * dst->n + 3 ] = sb;
u += invmat->a;
v += invmat->c;
@@ -142,7 +128,7 @@ drawtile(fz_renderer *gc, fz_pixmap *out, fz_pixmap *tile, fz_matrix ctm, int ov
{
x0 = CLAMP(x0, out->x, out->x + out->w - 1);
x1 = CLAMP(x1, out->x, out->x + out->w - 1);
- if (over && tile->cs && tile->cs->n == 3)
+ if (over && tile->n == 4)
overscanrgb(&invmat, out, tile, y, x0, x1);
else
drawscan(&invmat, out, tile, y, x0, x1);
@@ -172,50 +158,46 @@ fz_renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
int h = image->h;
int n = image->n;
int a = image->a;
- int sw = w;
- int sh = h;
- float s = sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
+ float sx = sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
+ float sy = sqrt(ctm.c * ctm.c + ctm.d * ctm.d);
- int d = 1;
- while ((w + d - 1) / d > s)
- d++;
- if (d > 1)
- d --;
+ int dx = 1;
+ while ((w + dx - 1) / dx > sx) dx++;
+ if (dx > 1) dx --;
-printf("renderimage s=%g d=%d\n", s, d);
+ int dy = 1;
+ while ((h + dy - 1) / dy > sy) dy++;
+ if (dy > 1) dy --;
- error = fz_newpixmap(&tile1, cs, 0, 0, w, h, n, a);
+ if (dx > 1) dx --;
+ if (dy > 1) dy --;
+
+printf("renderimage s=%gx%g/%dx%d d=%d,%d\n", sx, sy, w, h, dx, dy);
+
+ error = fz_newpixmap(&tile1, 0, 0, w, h, n + 1);
printf(" load tile\n");
error = image->loadtile(image, tile1);
+//fz_debugpixmap(tile1);getchar();
- if (d != 1)
+ if (dx != 1 || dy != 1)
{
- sw = (w + d - 1) / d;
- sh = (h + d - 1) / d;
-
-printf(" new pixmap\n");
- error = fz_newpixmap(&tile2, cs, 0, 0, sw, sh, n, a);
-printf(" scale tile to %d %d\n", sw, sh);
- error = fz_scalepixmap(tile1, tile2, d, d);
-
-printf(" free loaded tile\n");
+printf(" scale tile 1/%d x 1/%d\n", dx, dy);
+ error = fz_scalepixmap(&tile2, tile1, dx, dy);
+//fz_debugpixmap(tile2);getchar();
fz_freepixmap(tile1);
}
else
tile2 = tile1;
-printf(" swtich render mode\n");
-
/* render image mask */
if (n == 0 && a == 1)
{
printf("draw image mask\n");
- error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 1);
fz_clearpixmap(gc->tmp);
error = drawtile(gc, gc->tmp, tile2, ctm, 0);
-fz_debugpixmap(gc->tmp);getchar();
}
/* render rgb over */
@@ -229,9 +211,8 @@ printf("draw image rgb over\n");
else
{
printf("draw generic image\n");
- error = fz_newpixmap(&tile3, gc->model, 0, 0, sw, sh, gc->model->n, a);
- fz_convertpixmap(tile2, tile3);
- error = fz_newpixmap(&gc->tmp, gc->model, gc->x, gc->y, gc->w, gc->h, gc->model->n, 1);
+ 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);
fz_clearpixmap(gc->tmp);
error = drawtile(gc, gc->tmp, tile3, ctm, 0);
fz_freepixmap(tile3);
diff --git a/render/renderpath.c b/render/renderpath.c
index 8d2f875b..a83505f9 100644
--- a/render/renderpath.c
+++ b/render/renderpath.c
@@ -1,7 +1,6 @@
#include <fitz.h>
// enum { HS = 1, VS = 1, SF = 255 };
-// enum { HS = 5, VS = 3, SF = 17 };
enum { HS = 17, VS = 15, SF = 1 };
static fz_error *pathtogel(fz_gel *gel, fz_pathnode *path, fz_matrix ctm)
@@ -9,7 +8,6 @@ static fz_error *pathtogel(fz_gel *gel, fz_pathnode *path, fz_matrix ctm)
float flatness = 0.3 / ctm.a;
if (flatness < 0.1)
flatness = 0.1;
-
if (path->paint == FZ_STROKE)
{
if (path->dash)
@@ -43,17 +41,17 @@ static void blitcolorspan(int y, int x, int n, unsigned char *alpha, void *userd
if (n < 0)
return;
- p = &pix->samples[(y - pix->y) * pix->stride + (x - pix->x) * 4];
+ p = pix->samples + ((y - pix->y) * pix->w + (x - pix->x)) * pix->n;
while (n--)
{
sa = *alpha++ * SF;
ssa = 255 - sa;
- p[0] = fz_mul255(r, sa) + fz_mul255(p[0], ssa);
- p[1] = fz_mul255(g, sa) + fz_mul255(p[1], ssa);
- p[2] = fz_mul255(b, sa) + fz_mul255(p[2], ssa);
- p[3] = sa + fz_mul255(p[3], ssa);
+ p[0] = sa + fz_mul255(p[0], ssa);
+ p[1] = fz_mul255(r, sa) + fz_mul255(p[1], ssa);
+ p[2] = fz_mul255(g, sa) + fz_mul255(p[2], ssa);
+ p[3] = fz_mul255(b, sa) + fz_mul255(p[3], ssa);
p += 4;
}
@@ -77,7 +75,7 @@ static void blitalphaspan(int y, int x, int n, unsigned char *alpha, void *userd
if (n < 0)
return;
- p = &pix->samples[(y - pix->y) * pix->stride + (x - pix->x)];
+ p = pix->samples + (y - pix->y) * pix->w + (x - pix->x);
while (n--)
*p++ = *alpha++ * SF;
}
@@ -122,7 +120,7 @@ fz_renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
fz_sortgel(gc->gel);
- error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 1);
if (error)
return error;
diff --git a/render/rendertext.c b/render/rendertext.c
index 81afeafa..1a3c49db 100644
--- a/render/rendertext.c
+++ b/render/rendertext.c
@@ -17,9 +17,9 @@ static void blitalphaglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo)
if (dy >= out->h) continue;
a = gl->bitmap[sx + sy * gl->w];
- b = out->samples[dx + dy * out->stride];
- c = MAX(a, b);
- out->samples[dx + dy * out->stride] = c;
+ b = out->samples[dx + dy * out->w];
+ c = a + fz_mul255(b, 255 - a);
+ out->samples[dx + dy * out->w] = c;
}
}
}
@@ -44,11 +44,11 @@ static void blitcolorglyph(fz_pixmap *out, fz_glyph *gl, int xo, int yo, fz_rend
sa = gl->bitmap[sx + sy * gl->w];
ssa = 255 - sa;
- p = out->samples + dx * 4 + dy * out->stride;
- p[0] = fz_mul255(gc->r, sa) + fz_mul255(p[0], ssa);
- p[1] = fz_mul255(gc->g, sa) + fz_mul255(p[1], ssa);
- p[2] = fz_mul255(gc->b, sa) + fz_mul255(p[2], ssa);
- p[3] = sa + fz_mul255(ssa, p[3]);
+ p = out->samples + dx * 4 + dy * out->w * out->n;
+ p[0] = sa + fz_mul255(ssa, p[0]);
+ p[1] = fz_mul255(gc->r, sa) + fz_mul255(p[1], ssa);
+ p[2] = fz_mul255(gc->g, sa) + fz_mul255(p[2], ssa);
+ p[3] = fz_mul255(gc->b, sa) + fz_mul255(p[3], ssa);
}
}
}
@@ -62,7 +62,7 @@ fz_rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
int g, i, ix, iy;
fz_matrix tm, trm;
- error = fz_newpixmap(&gc->tmp, nil, gc->x, gc->y, gc->w, gc->h, 0, 1);
+ error = fz_newpixmap(&gc->tmp, gc->x, gc->y, gc->w, gc->h, 1);
if (error)
return error;
diff --git a/render/scale.c b/render/scale.c
index 1fad5a0b..00203cfc 100644
--- a/render/scale.c
+++ b/render/scale.c
@@ -1,26 +1,26 @@
#include <fitz.h>
static void
-scalerow(unsigned char *src, int w, int denom, unsigned char *dst, int ncomp)
+scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
- int x, left, n;
+ int x, left, k;
int sum[32];
left = 0;
- for (n = 0; n < ncomp; n++)
- sum[n] = 0;
+ for (k = 0; k < ncomp; k++)
+ sum[k] = 0;
for (x = 0; x < w; x++)
{
- for (n = 0; n < ncomp; n++)
- sum[n] += src[x * ncomp + n];
+ for (k = 0; k < ncomp; k++)
+ sum[k] += src[x * ncomp + k];
if (++left == denom)
{
left = 0;
- for (n = 0; n < ncomp; n++)
+ for (k = 0; k < ncomp; k++)
{
- dst[n] = sum[n] / denom;
- sum[n] = 0;
+ dst[k] = sum[k] / denom;
+ sum[k] = 0;
}
dst += ncomp;
}
@@ -28,66 +28,79 @@ scalerow(unsigned char *src, int w, int denom, unsigned char *dst, int ncomp)
/* left overs */
if (left)
- for (n = 0; n < ncomp; n++)
- dst[n] = sum[n] / left;
+ for (k = 0; k < ncomp; k++)
+ dst[k] = sum[k] / left;
}
static void
-scalecols(unsigned char *src, int stride, int w, int denom, unsigned char *dst, int ncomp)
+scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom)
{
- int x, y, n;
+ int x, y, k;
unsigned char *s;
int sum[32];
for (x = 0; x < w; x++)
{
s = src + (x * ncomp);
- for (n = 0; n < ncomp; n++)
- sum[n] = 0;
+ for (k = 0; k < ncomp; k++)
+ sum[k] = 0;
for (y = 0; y < denom; y++)
- for (n = 0; n < ncomp; n++)
- sum[n] += s[y * stride + n];
- for (n = 0; n < ncomp; n++)
- dst[n] = sum[n] / denom;
+ for (k = 0; k < ncomp; k++)
+ sum[k] += s[y * w * ncomp + k];
+ for (k = 0; k < ncomp; k++)
+ dst[k] = sum[k] / denom;
dst += ncomp;
}
}
fz_error *
-fz_scalepixmap(fz_pixmap *src, fz_pixmap *dst, int xdenom, int ydenom)
+fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom)
{
- assert(src->n == dst->n);
- assert(src->a == dst->a);
- assert((src->w + xdenom - 1) / xdenom == dst->w);
- assert((src->h + ydenom - 1) / ydenom == dst->h);
+ fz_error *error;
+ fz_pixmap *dst;
+ unsigned char *buf;
+ int y, iy, oy;
+ int ow, oh, n;
- int ncomp = src->n + src->a;
- unsigned char scratch[dst->stride * ydenom];
+ ow = (src->w + xdenom - 1) / xdenom;
+ oh = (src->h + ydenom - 1) / ydenom;
+ n = src->n;
- int y, iy, oy;
+ buf = fz_malloc(ow * n * ydenom);
+ if (!buf)
+ return fz_outofmem;
+
+ error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n);
+ if (error)
+ {
+ fz_free(buf);
+ return error;
+ }
- for (y = 0, oy = 0; y < (dst->h - 1) * ydenom; y += ydenom, oy++)
+ for (y = 0, oy = 0; y < (src->h / ydenom) * ydenom; y += ydenom, oy++)
{
for (iy = 0; iy < ydenom; iy++)
- scalerow(src->samples + (y + iy) * src->stride, src->w, xdenom,
- scratch + iy * dst->stride, ncomp);
- scalecols(scratch, ncomp * dst->w, dst->w, ydenom,
- dst->samples + (oy * dst->stride), ncomp);
+ scalerow(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, n, xdenom);
+ scalecols(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
}
ydenom = src->h - y;
if (ydenom)
{
for (iy = 0; iy < ydenom; iy++)
- scalerow(src->samples + (y + iy) * src->stride, src->w, xdenom,
- scratch + iy * (ncomp * dst->w), ncomp);
- scalecols(scratch, ncomp * dst->w, dst->w, ydenom,
- dst->samples + (oy * dst->stride), ncomp);
+ scalerow(src->samples + (y + iy) * src->w * n,
+ buf + iy * ow * n,
+ src->w, n, xdenom);
+ scalecols(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom);
}
//printf("unscaled image ");fz_debugpixmap(src);getchar();
//printf("scaled image ");fz_debugpixmap(dst);getchar();
+ fz_free(buf);
+ *dstp = dst;
return nil;
}