diff options
| -rw-r--r-- | libglitter_redistribute_energy_double.c | 137 | 
1 files changed, 120 insertions, 17 deletions
| diff --git a/libglitter_redistribute_energy_double.c b/libglitter_redistribute_energy_double.c index cfeef89..ce889de 100644 --- a/libglitter_redistribute_energy_double.c +++ b/libglitter_redistribute_energy_double.c @@ -9,21 +9,20 @@ vconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height,  	size_t y, x, i;  	if (kernelsize == 3 && kernel[0] == kernel[1] && kernel[1] == kernel[2]) { -		raster = &raster[-2 * rowsize];  		for (y = 0; y < height; y++) {  			for (x = 0; x < width; x++) -				raster[x] += raster[1 * rowsize + x]; +				raster[x] += raster[x + 1 * rowsize];  			for (x = 0; x < width; x++) { -				raster[x] += raster[2 * rowsize + x]; +				raster[x] += raster[x + 2 * rowsize];  				raster[x] *= kernel[0];  			}  			raster = &raster[rowsize];  		} -		for (x = 0; x < width; x++) -			raster[x] *= kernel[0]; -		raster = &raster[rowsize]; -		for (x = 0; x < width; x++) +		for (x = 0; x < width; x++) { +			raster[x] += raster[x + rowsize];  			raster[x] *= kernel[0]; +			raster[x + rowsize] *= kernel[0]; +		}  	} else {  		for (y = 0; y < height; y++) { @@ -31,7 +30,15 @@ vconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height,  				raster[x] *= kernel[0];  			for (i = 1; i < kernelsize; i++)  				for (x = 0; x < width; x++) -					raster[x] = fma(raster[i * rowsize + x], kernel[i], raster[x]); +					raster[x] = fma(raster[x + i * rowsize], kernel[i], raster[x]); +			raster = &raster[rowsize]; +		} +		for (y = 0; y < kernelsize - 1; y++) { +			for (x = 0; x < width; x++) +				raster[x] *= kernel[0]; +			for (i = 1; i < kernelsize - i - y; i++) +				for (x = 0; x < width; x++) +					raster[x] = fma(raster[x + i * rowsize], kernel[i], raster[x]);  			raster = &raster[rowsize];  		}  	} @@ -46,12 +53,12 @@ hconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height,  	if (kernelsize == 3 && kernel[0] == kernel[1] && kernel[1] == kernel[2]) {  		for (y = 0; y < height; y++) {  			for (x = 0; x < width; x++) { -				raster[x - 1] += raster[x]; -				raster[x - 2] += raster[x]; -				raster[x - 2] *= kernel[0]; +				raster[x + 1] += raster[x + 2]; +				raster[x] += raster[x + 2]; +				raster[x] *= kernel[0];  			} -			raster[width - 2] *= kernel[0]; -			raster[width - 1] *= kernel[0]; +			raster[width] *= kernel[0]; +			raster[width + 1] *= kernel[0];  			raster = &raster[rowsize];  		} @@ -62,7 +69,13 @@ hconvolute(double *restrict raster, size_t rowsize, size_t width, size_t height,  				for (i = 1; i < kernelsize; i++)  					raster[x] = fma(raster[x + i], kernel[i], raster[x]);  			} -			raster = &raster[rowsize]; +			raster = &raster[width]; +			for (x = 0; x < kernelsize - 1; x++) { +				raster[x] *= kernel[0]; +				for (i = 1; i < kernelsize - 1 - x; i++) +					raster[x] = fma(raster[x + i], kernel[i], raster[x]); +			} +			raster = &raster[rowsize - width];  		}  	}  } @@ -73,9 +86,9 @@ libglitter_redistribute_energy_double(double *restrict raster, size_t rowsize, s                                        size_t hkernelsize, size_t vkernelsize, const double *hkernel, const double *vkernel)  {  	if (vkernelsize > 1) { -		raster -= (hkernelsize - 1) * rowsize; +		raster -= (vkernelsize - 1) * rowsize;  		vconvolute(raster, rowsize, width, height, vkernelsize, vkernel); -		height += hkernelsize - 1; +		height += vkernelsize - 1;  	}  	if (hkernelsize > 1) {  		raster -= hkernelsize - 1; @@ -100,7 +113,97 @@ eq(double a, double b)  int  main(void)  { -	return 0; /* TODO add test */ +	double raster[100], hkern[15], vkern[15]; +	size_t i; + +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		raster[i] = (double)i; +	hkern[0] = vkern[0] = 0; +	libglitter_redistribute_energy_double(&raster[11], 10, 7, 8, 1, 1, NULL, NULL); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		ASSERT(raster[i] == (double)i); +	libglitter_redistribute_energy_double(&raster[11], 10, 7, 8, 1, 1, hkern, NULL); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		ASSERT(raster[i] == (double)i); +	libglitter_redistribute_energy_double(&raster[11], 10, 7, 8, 1, 1, NULL, vkern); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		ASSERT(raster[i] == (double)i); +	libglitter_redistribute_energy_double(&raster[11], 10, 7, 8, 1, 1, hkern, vkern); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		ASSERT(raster[i] == (double)i); + +	memset(raster, 0, sizeof(raster)); +	raster[53] = 1; +	raster[57] = 2; +	hkern[0] = 1 / 3.; +	hkern[1] = 1 / 3.; +	hkern[2] = 1 / 3.; +	libglitter_redistribute_energy_double(&raster[12], 10, 7, 8, 3, 1, hkern, NULL); +	ASSERT(eq(raster[52 - 1], 1 / 3.)); +	ASSERT(eq(raster[53 - 1], 1 / 3.)); +	ASSERT(eq(raster[54 - 1], 1 / 3.)); +	ASSERT(eq(raster[56 - 1], 2 / 3.)); +	ASSERT(eq(raster[57 - 1], 2 / 3.)); +	ASSERT(eq(raster[58 - 1], 2 / 3.)); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		if (!(51 <= i && i <= 53) && !(55 <= i && i <= 57)) +			ASSERT(!raster[i]); + +	memset(raster, 0, sizeof(raster)); +	raster[53] = 1; +	raster[57] = 2; +	hkern[0] = 1 / 4.; +	hkern[1] = 1 / 2.; +	hkern[2] = 1 / 4.; +	libglitter_redistribute_energy_double(&raster[12], 10, 7, 8, 3, 1, hkern, NULL); +	ASSERT(eq(raster[52 - 1], 1 / 4.)); +	ASSERT(eq(raster[53 - 1], 1 / 2.)); +	ASSERT(eq(raster[54 - 1], 1 / 4.)); +	ASSERT(eq(raster[56 - 1], 2 / 4.)); +	ASSERT(eq(raster[57 - 1], 2 / 2.)); +	ASSERT(eq(raster[58 - 1], 2 / 4.)); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		if (!(51 <= i && i <= 53) && !(55 <= i && i <= 57)) +			ASSERT(!raster[i]); + +	memset(raster, 0, sizeof(raster)); +	raster[35] = 1; +	raster[75] = 2; +	vkern[0] = 1 / 3.; +	vkern[1] = 1 / 3.; +	vkern[2] = 1 / 3.; +	libglitter_redistribute_energy_double(&raster[21], 10, 8, 7, 1, 3, NULL, vkern); +	ASSERT(eq(raster[25 - 10], 1 / 3.)); +	ASSERT(eq(raster[35 - 10], 1 / 3.)); +	ASSERT(eq(raster[45 - 10], 1 / 3.)); +	ASSERT(eq(raster[65 - 10], 2 / 3.)); +	ASSERT(eq(raster[75 - 10], 2 / 3.)); +	ASSERT(eq(raster[85 - 10], 2 / 3.)); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		if (i != 15 && i != 25 && i != 35 && i != 55 && i != 65 && i != 75) +			ASSERT(!raster[i]); + +	memset(raster, 0, sizeof(raster)); +	raster[35] = 1; +	raster[75] = 2; +	vkern[0] = 1 / 4.; +	vkern[1] = 1 / 2.; +	vkern[2] = 1 / 4.; +	libglitter_redistribute_energy_double(&raster[21], 10, 8, 7, 1, 3, NULL, vkern); +	ASSERT(eq(raster[25 - 10], 1 / 4.)); +	ASSERT(eq(raster[35 - 10], 1 / 2.)); +	ASSERT(eq(raster[45 - 10], 1 / 4.)); +	ASSERT(eq(raster[65 - 10], 2 / 4.)); +	ASSERT(eq(raster[75 - 10], 2 / 2.)); +	ASSERT(eq(raster[85 - 10], 2 / 4.)); +	for (i = 0; i < sizeof(raster) / sizeof(*raster); i++) +		if (i != 15 && i != 25 && i != 35 && i != 55 && i != 65 && i != 75) +			ASSERT(!raster[i]); + +	/* TODO test edges */ +	/* TODO test hkern+vkern */ + +	return 0;  } | 
