summaryrefslogtreecommitdiff
path: root/render/scale.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-11-26 03:20:37 +0100
committerTor Andersson <tor@ghostscript.com>2004-11-26 03:20:37 +0100
commit6c9bcc6f41bb738c216fc810246f60576d9ec6e4 (patch)
treea98834bbc2491c417743760d2869d1c066962b16 /render/scale.c
parente8696b4046767fcbfc05056c13f919fdeff65158 (diff)
downloadmupdf-6c9bcc6f41bb738c216fc810246f60576d9ec6e4.tar.xz
cpu dependent skeleton
Diffstat (limited to 'render/scale.c')
-rw-r--r--render/scale.c128
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);