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; > + } > >
pgpVL_u6sgkHx.pgp
Description: OpenPGP digital signature
