]> git.sesse.net Git - qscale/commitdiff
Invert horizontal and vertical order.
authorsgunderson@bigfoot.com <>
Sun, 3 Feb 2008 16:10:59 +0000 (17:10 +0100)
committersgunderson@bigfoot.com <>
Sun, 3 Feb 2008 16:10:59 +0000 (17:10 +0100)
qscale.c

index 61f49c42df3487ea893beea8a99238eab94d8fdf..042d3411a110f5464e218a3ef8c4b55f0af66ca8 100644 (file)
--- 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);
        {