diff options
Diffstat (limited to 'render/scale.c')
-rw-r--r-- | render/scale.c | 128 |
1 files changed, 124 insertions, 4 deletions
diff --git a/render/scale.c b/render/scale.c index 6b06dcfa..461f5100 100644 --- a/render/scale.c +++ b/render/scale.c @@ -1,5 +1,8 @@ #include <fitz.h> +typedef void (*rowfunc)(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom); +typedef void (*colfunc)(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom); + static void scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) { @@ -33,6 +36,66 @@ scalerow(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) } static void +scalerow1(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) +{ + int x, left; + int sum; + + left = 0; + sum = 0; + + for (x = 0; x < w; x++) + { + sum += *src++; + if (++left == denom) + { + left = 0; + *dst++ = sum / denom; + sum = 0; + } + } + + /* left overs */ + if (left) + { + *dst++ = sum / left; + } +} + +static void +scalerow2(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) +{ + int x, left; + int sum0, sum1; + + left = 0; + sum0 = 0; + sum1 = 0; + + for (x = 0; x < w; x++) + { + sum0 += *src++; + sum1 += *src++; + if (++left == denom) + { + left = 0; + *dst++ = sum0 / denom; + *dst++ = sum1 / denom; + sum0 = 0; + sum1 = 0; + } + } + + /* left overs */ + if (left) + { + *dst++ = sum0 / left; + *dst++ = sum1 / left; + } +} + + +static void scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) { int x, y, k; @@ -53,6 +116,45 @@ scalecols(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) } } +static void +scalecols1(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) +{ + int x, y, k; + unsigned char *s; + int sum; + + for (x = 0; x < w; x++) + { + s = src + x; + sum = 0; + for (y = 0; y < denom; y++) + sum += s[y * w]; + *dst++ = sum / denom; + } +} + +static void +scalecols2(unsigned char *src, unsigned char *dst, int w, int ncomp, int denom) +{ + int x, y, k; + unsigned char *s; + int sum0, sum1; + + for (x = 0; x < w; x++) + { + s = src + (x * 2); + sum0 = 0; + sum1 = 0; + for (y = 0; y < denom; y++) + { + sum0 += s[y * w * 2 + 0]; + sum1 += s[y * w * 2 + 1]; + } + *dst++ = sum0 / denom; + *dst++ = sum1 / denom; + } +} + fz_error * fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) { @@ -61,6 +163,8 @@ fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) unsigned char *buf; int y, iy, oy; int ow, oh, n; + rowfunc rowfunc; + colfunc colfunc; ow = (src->w + xdenom - 1) / xdenom; oh = (src->h + ydenom - 1) / ydenom; @@ -77,23 +181,39 @@ fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) return error; } + switch (n) + { + case 1: + rowfunc = scalerow1; + colfunc = scalecols1; + break; + case 2: + rowfunc = scalerow2; + colfunc = scalecols2; + break; + default: + rowfunc = scalerow; + colfunc = scalecols; + break; + } + 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->w * n, + rowfunc(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); + colfunc(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->w * n, + rowfunc(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); + colfunc(buf, dst->samples + oy * dst->w * n, dst->w, n, ydenom); } fz_free(buf); |