sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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  	}