Hi Anton!

Looks good, however instead of (a * w + b * (1 - w)),
you can use (b + (a - b) * w), that should improve the
performance a little bit. There are also some unnecessary
brackets at the assignment of if x_scale and y_scale.



On Tue, 5 Sep 2017 11:31:07 +0200
<[email protected]> wrote:

> commit 4570f19440d0f99e3b301ebf1c51ed19a3d0ba6b
> Author: Anton Kindestam <[email protected]>
> Date:   Tue Sep 5 11:27:14 2017 +0200
> 
>     [sent] Add bilinear scaling patch
> 
> diff --git a/tools.suckless.org/sent/patches/bilinear_scaling.md 
> b/tools.suckless.org/sent/patches/bilinear_scaling.md
> new file mode 100644
> index 00000000..3eb45118
> --- /dev/null
> +++ b/tools.suckless.org/sent/patches/bilinear_scaling.md
> @@ -0,0 +1,33 @@
> +Use Bilinear Scaling for Image Slides
> +=====================================
> +
> +Description
> +-----------
> +
> +The patch replaces the Nearest Neighbor Scaling algorithm used for
> +images with Bilinear Scaling.
> +
> +This should give somewhat more pleasing results when using image
> +slides for graphs, or other material which suffers badly under
> +aliasing.
> +
> +Notes
> +-----
> +
> +Due to the nature of Bilinear Scaling, scaling down more than 50% will
> +have somewhat less pleasing results. Scaling up will generally be
> +quite blurry.
> +
> +There is room for further improvement of image scaling, e.g:
> +Implementing a better scaling algorithm such as bicubic, or lancszos;
> +and/or using separate algorithms for scaling up or down.
> +
> +Download
> +--------
> +
> +* [sent-bilinearscaling-1.0.diff](sent-bilinearscaling-1.0.diff)
> +
> +Author
> +------
> +
> +* Anton Kindestam (xantoz) <[email protected]>
> diff --git a/tools.suckless.org/sent/patches/sent-bilinearscaling-1.0.diff 
> b/tools.suckless.org/sent/patches/sent-bilinearscaling-1.0.diff
> new file mode 100644
> index 00000000..c943e846
> --- /dev/null
> +++ b/tools.suckless.org/sent/patches/sent-bilinearscaling-1.0.diff
> @@ -0,0 +1,88 @@
> +diff --git a/sent.c b/sent.c
> +index 0da2bff..d92cf3b 100644
> +--- a/sent.c
> ++++ b/sent.c
> +@@ -282,27 +282,66 @@ ffprepare(Image *img)
> +     img->state |= SCALED;
> + }
> + 
> ++static unsigned char double_to_uchar_clamp255(double dbl)
> ++{
> ++    dbl = round(dbl);
> ++
> ++    return
> ++            (dbl < 0.0)   ? 0 :
> ++            (dbl > 255.0) ? 255 : (unsigned char)dbl;
> ++}
> ++
> ++static int int_clamp(int integer, int lower, int upper)
> ++{
> ++    if (integer < lower)
> ++            return lower;
> ++    else if (integer >= upper)
> ++            return upper - 1;
> ++    else
> ++            return integer;
> ++}
> ++
> + void
> + ffscale(Image *img)
> + {
> +-    unsigned int x, y;
> +-    unsigned int width = img->ximg->width;
> +-    unsigned int height = img->ximg->height;
> +-    char* newBuf = img->ximg->data;
> +-    unsigned char* ibuf;
> +-    unsigned int jdy = img->ximg->bytes_per_line / 4 - width;
> +-    unsigned int dx = (img->bufwidth << 10) / width;
> +-
> +-    for (y = 0; y < height; y++) {
> +-            unsigned int bufx = img->bufwidth / width;
> +-            ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 
> 3];
> +-
> +-            for (x = 0; x < width; x++) {
> +-                    *newBuf++ = (ibuf[(bufx >> 10)*3+2]);
> +-                    *newBuf++ = (ibuf[(bufx >> 10)*3+1]);
> +-                    *newBuf++ = (ibuf[(bufx >> 10)*3+0]);
> ++    const unsigned width = img->ximg->width;
> ++    const unsigned height = img->ximg->height;
> ++    unsigned char* newBuf = (unsigned char*)img->ximg->data;
> ++    const unsigned jdy = img->ximg->bytes_per_line / 4 - width;
> ++
> ++    const double x_scale = ((double)img->bufwidth/(double)width);
> ++    const double y_scale = ((double)img->bufheight/(double)height);
> ++
> ++    for (unsigned y = 0; y < height; ++y) {
> ++            const double old_y = (double)y * y_scale;
> ++            const double y_factor = ceil(old_y) - old_y;
> ++            const int old_y_int_0 = int_clamp((int)floor(old_y), 0, 
> img->bufheight);
> ++            const int old_y_int_1 = int_clamp((int)ceil(old_y), 0, 
> img->bufheight);
> ++
> ++            for (unsigned x = 0; x < width; ++x) {
> ++                    const double old_x = (double)x * x_scale;
> ++                    const double x_factor = ceil(old_x) - old_x;
> ++                    const int old_x_int_0 = int_clamp((int)floor(old_x), 0, 
> img->bufwidth);
> ++                    const int old_x_int_1 = int_clamp((int)ceil(old_x), 0, 
> img->bufwidth);
> ++
> ++                    const unsigned c00_pos = 3*((old_x_int_0) + 
> ((old_y_int_0)*img->bufwidth));
> ++                    const unsigned c01_pos = 3*((old_x_int_0) + 
> ((old_y_int_1)*img->bufwidth));
> ++                    const unsigned c10_pos = 3*((old_x_int_1) + 
> ((old_y_int_0)*img->bufwidth));
> ++                    const unsigned c11_pos = 3*((old_x_int_1) + 
> ((old_y_int_1)*img->bufwidth));
> ++
> ++                    for (int i = 2; i >= 0 ; --i) {
> ++                            const unsigned char c00 = img->buf[c00_pos + i];
> ++                            const unsigned char c01 = img->buf[c01_pos + i];
> ++                            const unsigned char c10 = img->buf[c10_pos + i];
> ++                            const unsigned char c11 = img->buf[c11_pos + i];
> ++
> ++                            const double x_result_0 = (double)c00*x_factor 
> + (double)c10*(1.0 - x_factor);
> ++                            const double x_result_1 = (double)c01*x_factor 
> + (double)c11*(1.0 - x_factor);
> ++                            const double result = x_result_0*y_factor + 
> x_result_1*(1.0 - y_factor);
> ++
> ++                            *newBuf++ = double_to_uchar_clamp255(result);
> ++                    }
> +                     newBuf++;
> +-                    bufx += dx;
> +             }
> +             newBuf += jdy;
> +     }
> 
> 

Attachment: pgpVL_u6sgkHx.pgp
Description: OpenPGP digital signature

Reply via email to