diff options
-rw-r--r-- | include/fitz/image.h | 2 | ||||
-rw-r--r-- | include/fitz/pixmap.h | 22 | ||||
-rw-r--r-- | mupdf/image.c | 89 | ||||
-rw-r--r-- | render/pixmap.c | 157 | ||||
-rw-r--r-- | render/render.c | 31 | ||||
-rw-r--r-- | render/renderimage.c | 113 | ||||
-rw-r--r-- | render/renderpath.c | 16 | ||||
-rw-r--r-- | render/rendertext.c | 18 | ||||
-rw-r--r-- | render/scale.c | 85 |
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; } |