Re: [wiki] [sites] [sent] Add bilinear scaling patch || Anton Kindestam

From: Mattias Andrée <maandree_AT_kth.se>
Date: Tue, 5 Sep 2017 18:21:31 +0200

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
<git_AT_suckless.org> wrote:

> commit 4570f19440d0f99e3b301ebf1c51ed19a3d0ba6b
> Author: Anton Kindestam <antonki_AT_kth.se>
> 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
> _AT_@ -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) <antonki_AT_kth.se>
> 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
> _AT_@ -0,0 +1,88 @@
> +diff --git a/sent.c b/sent.c
> +index 0da2bff..d92cf3b 100644
> +--- a/sent.c
> ++++ b/sent.c
> +_AT_@ -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;
> + }
>
>


Received on Tue Sep 05 2017 - 18:21:31 CEST

This archive was generated by hypermail 2.3.0 : Tue Sep 05 2017 - 18:24:27 CEST