sent-bilinearscaling-1.0.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
sent-bilinearscaling-1.0.diff (2979B)
---
1 diff --git a/sent.c b/sent.c
2 index 0da2bff..d92cf3b 100644
3 --- a/sent.c
4 +++ b/sent.c
5 @@ -282,27 +282,66 @@ ffprepare(Image *img)
6 img->state |= SCALED;
7 }
8
9 +static unsigned char double_to_uchar_clamp255(double dbl)
10 +{
11 + dbl = round(dbl);
12 +
13 + return
14 + (dbl < 0.0) ? 0 :
15 + (dbl > 255.0) ? 255 : (unsigned char)dbl;
16 +}
17 +
18 +static int int_clamp(int integer, int lower, int upper)
19 +{
20 + if (integer < lower)
21 + return lower;
22 + else if (integer >= upper)
23 + return upper - 1;
24 + else
25 + return integer;
26 +}
27 +
28 void
29 ffscale(Image *img)
30 {
31 - unsigned int x, y;
32 - unsigned int width = img->ximg->width;
33 - unsigned int height = img->ximg->height;
34 - char* newBuf = img->ximg->data;
35 - unsigned char* ibuf;
36 - unsigned int jdy = img->ximg->bytes_per_line / 4 - width;
37 - unsigned int dx = (img->bufwidth << 10) / width;
38 -
39 - for (y = 0; y < height; y++) {
40 - unsigned int bufx = img->bufwidth / width;
41 - ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3];
42 -
43 - for (x = 0; x < width; x++) {
44 - *newBuf++ = (ibuf[(bufx >> 10)*3+2]);
45 - *newBuf++ = (ibuf[(bufx >> 10)*3+1]);
46 - *newBuf++ = (ibuf[(bufx >> 10)*3+0]);
47 + const unsigned width = img->ximg->width;
48 + const unsigned height = img->ximg->height;
49 + unsigned char* newBuf = (unsigned char*)img->ximg->data;
50 + const unsigned jdy = img->ximg->bytes_per_line / 4 - width;
51 +
52 + const double x_scale = ((double)img->bufwidth/(double)width);
53 + const double y_scale = ((double)img->bufheight/(double)height);
54 +
55 + for (unsigned y = 0; y < height; ++y) {
56 + const double old_y = (double)y * y_scale;
57 + const double y_factor = ceil(old_y) - old_y;
58 + const int old_y_int_0 = int_clamp((int)floor(old_y), 0, img->bufheight);
59 + const int old_y_int_1 = int_clamp((int)ceil(old_y), 0, img->bufheight);
60 +
61 + for (unsigned x = 0; x < width; ++x) {
62 + const double old_x = (double)x * x_scale;
63 + const double x_factor = ceil(old_x) - old_x;
64 + const int old_x_int_0 = int_clamp((int)floor(old_x), 0, img->bufwidth);
65 + const int old_x_int_1 = int_clamp((int)ceil(old_x), 0, img->bufwidth);
66 +
67 + const unsigned c00_pos = 3*((old_x_int_0) + ((old_y_int_0)*img->bufwidth));
68 + const unsigned c01_pos = 3*((old_x_int_0) + ((old_y_int_1)*img->bufwidth));
69 + const unsigned c10_pos = 3*((old_x_int_1) + ((old_y_int_0)*img->bufwidth));
70 + const unsigned c11_pos = 3*((old_x_int_1) + ((old_y_int_1)*img->bufwidth));
71 +
72 + for (int i = 2; i >= 0 ; --i) {
73 + const unsigned char c00 = img->buf[c00_pos + i];
74 + const unsigned char c01 = img->buf[c01_pos + i];
75 + const unsigned char c10 = img->buf[c10_pos + i];
76 + const unsigned char c11 = img->buf[c11_pos + i];
77 +
78 + const double x_result_0 = (double)c00*x_factor + (double)c10*(1.0 - x_factor);
79 + const double x_result_1 = (double)c01*x_factor + (double)c11*(1.0 - x_factor);
80 + const double result = x_result_0*y_factor + x_result_1*(1.0 - y_factor);
81 +
82 + *newBuf++ = double_to_uchar_clamp255(result);
83 + }
84 newBuf++;
85 - bufx += dx;
86 }
87 newBuf += jdy;
88 }