From 9c2b4088f2f72806dfd05136845e8e11a2dfb7f8 Mon Sep 17 00:00:00 2001 From: "sgunderson@bigfoot.com" <> Date: Sun, 3 Feb 2008 17:10:59 +0100 Subject: [PATCH] Invert horizontal and vertical order. --- qscale.c | 65 +++++++++++++++++++++++++++----------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/qscale.c b/qscale.c index 61f49c4..042d341 100644 --- a/qscale.c +++ b/qscale.c @@ -52,7 +52,7 @@ struct pix_desc { unsigned startcoeff; }; -void hscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nw) +void hscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nw) { struct pix_desc *pd = (struct pix_desc *)malloc(nw * sizeof(struct pix_desc)); int size_coeffs = 8; @@ -60,7 +60,7 @@ void hscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nw int num_coeffs = 0; int x, y, sx; double sf = (double)w / (double)nw; - double support = 3.0 * sf; + double support = (w > nw) ? (3.0 * sf) : (3.0 / sf); /* calculate the filter */ for (x = 0; x < nw; ++x) { @@ -80,13 +80,13 @@ void hscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nw pd[x].startcoeff = num_coeffs; for (sx = start; sx <= end; ++sx) { - double nd = sx/sf - x; + double nd = (w > nw) ? (sx/sf - x) : (sx - x*sf); double f = lanczos_tap(nd); if (num_coeffs == size_coeffs) { size_coeffs <<= 1; coeffs = (float *)realloc(coeffs, size_coeffs * sizeof(float)); } - + coeffs[num_coeffs++] = f; sum += f; } @@ -97,22 +97,30 @@ void hscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nw } for (y = 0; y < h; ++y) { - unsigned char *sptr = pix + y*w; - float *dptr = npix + y*nw; + float *sptr = pix + y*w; + unsigned char *dptr = npix + y*nw; for (x = 0; x < nw; ++x) { float acc = 0.0; float *cf = &coeffs[pd[x].startcoeff]; unsigned sx; + unsigned char ch; for (sx = pd[x].start; sx <= pd[x].end; ++sx) { acc += sptr[sx] * *cf++; } - *dptr++ = acc; + + if (acc < 0.0) + ch = 0; + else if (acc > 255.0) + ch = 255; + else + ch = (unsigned char)acc; + *dptr++ = ch; } } } -void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh) +void vscale(unsigned char *pix, float *npix, unsigned w, unsigned h, unsigned nh) { struct pix_desc *pd = (struct pix_desc *)malloc(nh * sizeof(struct pix_desc)); int size_coeffs = 8; @@ -120,7 +128,7 @@ void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh int num_coeffs = 0; int x, y, sy; double sf = (double)h / (double)nh; - double support = 3.0 * sf; + double support = (h > nh) ? (3.0 * sf) : (3.0 / sf); /* calculate the filter */ for (y = 0; y < nh; ++y) { @@ -140,7 +148,7 @@ void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh pd[y].startcoeff = num_coeffs; for (sy = start; sy <= end; ++sy) { - double nd = sy/sf - y; + double nd = (h > nh) ? (sy/sf - y) : (sy - y*sf); double f = lanczos_tap(nd); if (num_coeffs == size_coeffs) { size_coeffs <<= 1; @@ -155,10 +163,11 @@ void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh coeffs[pd[y].startcoeff + sy - start] /= sum; } } + #if CACHE_LINE_FACTOR > 1 for (x = 0; x < w; x += CACHE_LINE_FACTOR) { - float *sptr = pix + x; - unsigned char *dptr = npix + x; + unsigned char *sptr = pix + x; + float *dptr = npix + x; for (y = 0; y < nh; ++y) { int i; float acc[CACHE_LINE_FACTOR]; @@ -166,7 +175,6 @@ void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh acc[i] = 0.0; float *cf = &coeffs[pd[y].startcoeff]; unsigned sy; - unsigned char ch; for (sy = pd[y].start; sy <= pd[y].end; ++sy) { for (i = 0; i < CACHE_LINE_FACTOR; ++i) { @@ -176,39 +184,27 @@ void vscale(float *pix, unsigned char *npix, unsigned w, unsigned h, unsigned nh } for (i = 0; i < CACHE_LINE_FACTOR; ++i) { - if (acc[i] < 0.0) - ch = 0; - else if (acc[i] > 255.0) - ch = 255; - else - ch = (unsigned char)acc[i]; - dptr[i] = ch; + dptr[i] = acc[i]; } dptr += w; } } -#endif for (x = (x/CACHE_LINE_FACTOR)*CACHE_LINE_FACTOR; x < w; ++x) { - float *sptr = pix + x; - unsigned char *dptr = npix + x; +#else + for (x = 0; x < w; ++x) { +#endif + unsigned char *sptr = pix + x; + float *dptr = npix + x; for (y = 0; y < nh; ++y) { float acc = 0.0; float *cf = &coeffs[pd[y].startcoeff]; unsigned sy; - unsigned char ch; for (sy = pd[y].start; sy <= pd[y].end; ++sy) { acc += sptr[sy * w] * *cf++; } - if (acc < 0.0) - ch = 0; - else if (acc > 255.0) - ch = 255; - else - ch = (unsigned char)acc; - - *dptr = ch; + *dptr = acc; dptr += w; } } @@ -218,6 +214,7 @@ int main(void) { unsigned w, h; unsigned nw = 600, nh = 400; + //unsigned nw = 3504, nh = 2336; char buf[256]; unsigned char *pix; float *npix; @@ -264,8 +261,8 @@ int main(void) exit(1); } - hscale(pix, npix, w, h, nw); - vscale(npix, npix2, nw, h, nh); + vscale(pix, npix, w, h, nh); + hscale(npix, npix2, w, nh, nw); printf("P5\n# COMMENT: Made by qscale\n%u %u\n255\n", nw, nh); { -- 2.39.2