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;
+       }


Reply via email to