diff options
| author | John Hawthorn <john.hawthorn@gmail.com> | 2009-12-21 17:13:04 -0800 | 
|---|---|---|
| committer | John Hawthorn <john.hawthorn@gmail.com> | 2009-12-21 17:13:04 -0800 | 
| commit | a7fc167f214fd29eb62713c712e858031c31daf1 (patch) | |
| tree | 4b99615401c6b920869e565d7fb817367c1826f5 /src | |
| parent | 556d236a4f2bebbf17ac3f1bd11f0ceb7b7eab6e (diff) | |
| download | mirror-meh-a7fc167f214fd29eb62713c712e858031c31daf1.tar.gz mirror-meh-a7fc167f214fd29eb62713c712e858031c31daf1.tar.bz2 mirror-meh-a7fc167f214fd29eb62713c712e858031c31daf1.zip | |
added super sampling scale
Diffstat (limited to 'src')
| -rw-r--r-- | src/meh.h | 4 | ||||
| -rw-r--r-- | src/scale.c | 80 | 
2 files changed, 76 insertions, 8 deletions
| @@ -33,8 +33,8 @@ struct image{  /* scale */ -void scale(struct image *img, int width, int height, int bytesperline, char* __restrict__ newBuf); -void nearestscale(struct image *img, int width, int height, int bytesperline, char* __restrict__ newBuf); +void scale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf); +void nearestscale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf);  /* XLib */  void setaspect(unsigned int w, unsigned int h); diff --git a/src/scale.c b/src/scale.c index 21fa505..6555af3 100644 --- a/src/scale.c +++ b/src/scale.c @@ -1,4 +1,6 @@ +#include <assert.h> +#include <string.h>  #include <stdint.h>  #include <sys/time.h>  #include "meh.h" @@ -34,9 +36,64 @@  	ibuf = &img->buf[y * img->bufheight / height * img->bufwidth * 3];\  	ibufn = ibuf + dy; +/* + * Super sampling scale. Down only. + */ +static void superscale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf){ +	uint32_t x, y, i; +	unsigned char * __restrict__ ibuf; +	ibuf = &img->buf[0]; + +	TDEBUG_START + +	int divx[bytesperline]; +	int divy[bytesperline]; +	memset(divx, 0, sizeof divx); +	memset(divy, 0, sizeof divy); +	for(x = 0; x < img->bufwidth; x++){ +		 divx[x * width / img->bufwidth]++; +	} +	for(y = 0; y < img->bufheight; y++){ +		 divy[y * height / img->bufheight]++; +	} + +	int xoff[img->bufwidth]; +	for(x = 0; x < img->bufwidth; x++){ +		xoff[x] = (x * width / img->bufwidth) * 3; +	} -void scale(struct image *img, int width, int height, int bytesperline, char* __restrict__ newBuf){ -	int x, y; +	int tmp[width * 4]; +	unsigned int y0; +	for(y = 0; y < img->bufheight;){ +		int ydiv = divy[y * height / img->bufheight]; +		char * __restrict__ ydest = &newBuf[bytesperline * (y * height / img->bufheight)]; +		memset(tmp, 0, sizeof tmp); +		ibuf = &img->buf[y * img->bufwidth * 3]; +		for(y0 = y; y < y0 + ydiv; y++){ +			for(x = 0; x < img->bufwidth; x++){ +				int * __restrict__ dest = tmp + xoff[x]; +				for(i = 0; i < 3; i++){ +					*dest++ += *ibuf++; +				} +			} +		} +		int * __restrict__ src = tmp; +		for(x = 0; x < width; x++){ +			ydest[2] = *src++ / ydiv / divx[x]; +			ydest[1] = *src++ / ydiv / divx[x]; +			ydest[0] = *src++ / ydiv / divx[x]; +			ydest += 4; +		} +	} + +	TDEBUG_END("superscale") +} + +/* + * Bilinear scale. Used for up only. + */ +static void bilinearscale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf){ +	unsigned int x, y;  	const unsigned char * __restrict__ ibuf;  	const unsigned char * __restrict__ ibufn;  	const unsigned char * const bufend = &img->buf[img->bufwidth * img->bufheight * 3]; @@ -86,11 +143,22 @@ void scale(struct image *img, int width, int height, int bytesperline, char* __r  		y++;  	} -	TDEBUG_END("scale") +	TDEBUG_END("bilinearscale") +} + +void scale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf){ +	if(width < img->bufwidth){ +		superscale(img, width, height, bytesperline, newBuf); +	}else{ +		bilinearscale(img, width, height, bytesperline, newBuf); +	}  } -void nearestscale(struct image *img, int width, int height, int bytesperline, char* __restrict__ newBuf){ -	int x, y; +/* + * Nearest neighbour. Fast up and down. + */ +void nearestscale(struct image *img, unsigned int width, unsigned int height, unsigned int bytesperline, char* __restrict__ newBuf){ +	unsigned int x, y;  	unsigned char * __restrict__ ibuf;  	unsigned int jdy = bytesperline / 4 - width;  	unsigned int dx = (img->bufwidth << 10) / width; @@ -111,7 +179,7 @@ void nearestscale(struct image *img, int width, int height, int bytesperline, ch  		newBuf += jdy;  	} -	TDEBUG_END("linearscale") +	TDEBUG_END("nearestscale")  } | 
