#include "Raw_Processor_implC.h"

#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))
#define SQR(x) ((x)*(x))
#define SQRI(x) (((int)x)*((int)x))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/*
void mul_matrix_01(const mul_matrix_function_variable *variable){
	int pos_row, comp_pointer, end_pointer;
	float fcomp0, fcomp1, fcomp2;
	const float *matrix = variable->matrix;
	int icomp0, icomp1, icomp2;
	unsigned short *scomp0 = variable->comp0;
	unsigned short *scomp1 = variable->comp1;
	unsigned short *scomp2 = variable->comp2;


	for(pos_row = variable->start_row; pos_row < variable->number_row; pos_row++){
		comp_pointer 	= pos_row * variable->linestride + variable->start_col;
		end_pointer		=  comp_pointer + variable->linestride;
		for(;comp_pointer < end_pointer; comp_pointer ++){
			fcomp0 = scomp0[comp_pointer];
			fcomp1 = scomp1[comp_pointer];
			fcomp2 = scomp2[comp_pointer];

			icomp0 = (int)(fcomp0 * matrix[0] + fcomp1 * matrix[1] + fcomp2 * matrix[2]);
			icomp1 = (int)(fcomp0 * matrix[3] + fcomp1 * matrix[4] + fcomp2 * matrix[5]);
			icomp2 = (int)(fcomp0 * matrix[6] + fcomp1 * matrix[7] + fcomp2 * matrix[8]);

			scomp0[comp_pointer] = (unsigned short) CROP(icomp0);
			scomp1[comp_pointer] = (unsigned short) CROP(icomp1);
			scomp2[comp_pointer] = (unsigned short) CROP(icomp2);
		}
	}
}
*/

inline unsigned short crop(float in){
	if(in <= 0xFFFF){
		if(in < 0){
			return 0;
		}else{
			return (unsigned short) in;
		}
	}else{
		return 0xFFFF;
	}
	return 0;
}

inline unsigned short crop_i(int in)
{
	unsigned short back = 0;
	if(in & 0xFFFF0000){
		if(!(in & 0x8000)){
			back = 0xFFFF;
		}
	}else{
		back = (unsigned short) in;
	}

	return back;
}

void mul_matrix_01(const mul_matrix_function_variable *variable){
	int pos_row;
	float fcomp0, fcomp1, fcomp2;
	const float *matrix = variable->matrix;
	//unsigned int icomp0, icomp1, icomp2;
	unsigned short *scomp0, *scomp0_end;
	unsigned short *scomp1;
	unsigned short *scomp2;


	for(pos_row = variable->start_row; pos_row < variable->number_row; pos_row++){
		scomp0 = &(variable->comp0[pos_row * variable->linestride + variable->start_col]);
		scomp1 = &(variable->comp1[pos_row * variable->linestride + variable->start_col]);
		scomp2 = &(variable->comp2[pos_row * variable->linestride + variable->start_col]);

		scomp0_end = scomp0 + variable->number_col;
		for(;scomp0 < scomp0_end; scomp0 += 1, scomp1 += 1, scomp2 += 1){
			fcomp0 = *scomp0;
			fcomp1 = *scomp1;
			fcomp2 = *scomp2;

			*scomp0 = crop(fcomp0 * matrix[0] + fcomp1 * matrix[1] + fcomp2 * matrix[2]);
			*scomp1	= crop(fcomp0 * matrix[3] + fcomp1 * matrix[4] + fcomp2 * matrix[5]);
			*scomp2 = crop(fcomp0 * matrix[6] + fcomp1 * matrix[7] + fcomp2 * matrix[8]);

			/*
			icomp0 = (unsigned int)(fcomp0 * matrix[0] + fcomp1 * matrix[1] + fcomp2 * matrix[2]);
			icomp1 = (unsigned int)(fcomp0 * matrix[3] + fcomp1 * matrix[4] + fcomp2 * matrix[5]);
			icomp2 = (unsigned int)(fcomp0 * matrix[6] + fcomp1 * matrix[7] + fcomp2 * matrix[8]);


			*scomp0 = (unsigned short) CROP(icomp0);
			*scomp1 = (unsigned short) CROP(icomp1);
			*scomp2 = (unsigned short) CROP(icomp2);
*/

		}
	}
}

unsigned short limit(int i, unsigned short maxmin1, unsigned short maxmin2)
{
	if(maxmin1 < maxmin2){
		if(i >= maxmin1 && i <= maxmin2){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}else{
		if(i >= maxmin2 && i <= maxmin1){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}
}

unsigned short limit_f(float f, unsigned short maxmin1, unsigned short maxmin2)
{
	int i = (int)f;
	if(maxmin1 < maxmin2){
		if(i >= maxmin1 && i <= maxmin2){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}else{
		if(i >= maxmin2 && i <= maxmin1){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}
}

unsigned short limit_f2(float f, unsigned short maxmin1, unsigned short maxmin2)
{
	int i = (int)f;
	unsigned short temp;
	if(maxmin1 < maxmin2){
		temp = maxmin1 - 0xFF;
		if(temp < maxmin1){
			maxmin1 = temp;
		}else{
			maxmin1 = 0;
		}
		temp = maxmin2 + 0xFF ;
		if(temp > maxmin2){
			maxmin2 = temp;
		}else{
			maxmin2 = 0xFFFF;
		}

		if(i >= maxmin1 && i <= maxmin2){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}else{
		temp = maxmin2 - 0xFF;
		if(temp < maxmin2){
			maxmin2 = temp;
		}else{
			maxmin2 = 0;
		}
		temp = maxmin1 + 0xFF;
		if(temp > maxmin1){
			maxmin1 = temp;
		}else{
			maxmin1 = 0xFFFF;
		}

		if(i >= maxmin2 && i <= maxmin1){
			return (unsigned short) i;
		}else{
			return (maxmin1 + maxmin2) >> 1;
		}
	}
}


int demosaic_AHD_default_green(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short	 *input1, *input2, *input3, *input0, *input_end;
	unsigned short *h_buffer_green0, *v_buffer_green0, *h_buffer_green3, *v_buffer_green3;
	int	h_buffer_green0_linestride, v_buffer_green0_linestride, h_buffer_green3_linestride, v_buffer_green3_linestride;;
	int linestride1, linestride2, linestride3, linestride0;
	int col_pos;
	int temp;

	/*
	int red0_01, green1_01, green2_01, blue3_01;
	int red0_11, green1_11, green2_11, blue3_11;
	int red0_21, green1_21, green2_21, blue3_21;
	int red0_10, green1_10, green2_10, blue3_10;
	int red0_12, green1_12, green2_12, blue3_12;


	h_buffer_green0_linestride = variable->temp_buffer_linestride[0];
	v_buffer_green0_linestride = variable->temp_buffer_linestride[1];
	h_buffer_green3_linestride = variable->temp_buffer_linestride[2];
	v_buffer_green3_linestride = variable->temp_buffer_linestride[3];
*/

	v_buffer_green0_linestride = variable->linestride[0];
	h_buffer_green0_linestride = variable->linestride[1];
	v_buffer_green3_linestride = variable->linestride[2];
	h_buffer_green3_linestride = variable->linestride[3];

	linestride0	= variable->linestride[16];
	linestride1	= variable->linestride[17];
	linestride2	= variable->linestride[18];
	linestride3 = variable->linestride[19];

//	const int homo_green = 200;

//	float dif1, dif2, sum;
//	float factor1, factor2, factor3, factor4, factor5;
//	const float filter1	= -0.2569;
//	const float filter2	= 0.4339;
//	const float filter3	= 0.5138;

	// Green interpolation
	for(col_pos = 0; col_pos < half_block_size; col_pos += 1){
		input0 = variable->buffer[16] + (linestride0 * col_pos);
		input1 = variable->buffer[17] + (linestride1 * col_pos);
		input2 = variable->buffer[18] + (linestride2 * col_pos);
		input3 = variable->buffer[19] + (linestride3 * col_pos);
		input_end = input0 + half_width;

		v_buffer_green0 = variable->buffer[0] + (v_buffer_green0_linestride * col_pos);
		h_buffer_green0 = variable->buffer[1] + (h_buffer_green0_linestride * col_pos);
		v_buffer_green3 = variable->buffer[2] + (v_buffer_green3_linestride * col_pos);
		h_buffer_green3 = variable->buffer[3] + (h_buffer_green3_linestride * col_pos);

		for(;input0 < input_end;){

			temp = (*(input1 - 1) + *input1 + *input0) >> 1;
			temp -= ((*(input0 - 1) +  *(input0 + 1)) >> 2);
			*h_buffer_green0 = limit(temp, *(input1 - 1), *input1);

			temp = ( *(input2 - linestride2) + *input2 + *input0) >> 1;
			temp -= ( *(input0 - linestride0) + *(input0 + linestride0)) >> 2;
			*v_buffer_green0 = limit(temp, *(input2 - linestride2), *(input2));

			temp = (*input2 + *(input2 + 1) + *input3 ) >> 1;
			temp -= (*(input3 - 1) + *(input3 + 1)) >> 2;
			*h_buffer_green3 = limit(temp, *input2, *(input2 + 1));

			temp = (*input1 + *(input1 + linestride1) + *input3) >> 1;
			temp -= (*(input3 + linestride3) + *(input3 - linestride3)) >> 2;
			*v_buffer_green3 =  limit(temp, *input1, *(input1 + linestride1));


			input0 += 1;
			input1 += 1;
			input2 += 1;
			input3 += 1;
			h_buffer_green0 += 1;
			v_buffer_green0 += 1;
			h_buffer_green3 += 1;
			v_buffer_green3 += 1;
		}
	}
	return status;
}

int demosaic_AHD_extended_1_green(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short	 *input1, *input2, *input3, *input0, *input_end;
	unsigned short *h_buffer_green0, *v_buffer_green0, *h_buffer_green3, *v_buffer_green3;
	int	h_buffer_green0_linestride, v_buffer_green0_linestride, h_buffer_green3_linestride, v_buffer_green3_linestride;;
	int linestride1, linestride2, linestride3, linestride0;
	int col_pos;
//	int temp;

	/*
	int red0_01, green1_01, green2_01, blue3_01;
	int red0_11, green1_11, green2_11, blue3_11;
	int red0_21, green1_21, green2_21, blue3_21;
	int red0_10, green1_10, green2_10, blue3_10;
	int red0_12, green1_12, green2_12, blue3_12;


	h_buffer_green0_linestride = variable->temp_buffer_linestride[0];
	v_buffer_green0_linestride = variable->temp_buffer_linestride[1];
	h_buffer_green3_linestride = variable->temp_buffer_linestride[2];
	v_buffer_green3_linestride = variable->temp_buffer_linestride[3];
*/

	v_buffer_green0_linestride = variable->linestride[0];
	h_buffer_green0_linestride = variable->linestride[1];
	v_buffer_green3_linestride = variable->linestride[2];
	h_buffer_green3_linestride = variable->linestride[3];

	linestride0	= variable->linestride[16];
	linestride1	= variable->linestride[17];
	linestride2	= variable->linestride[18];
	linestride3 = variable->linestride[19];

//	const int homo_green = 200;

	float dif1, dif2, sum;
	float factor1, factor2, factor3, factor4, factor5;
	const float filter1	= -0.2569;
	const float filter2	= 0.4339;
	const float filter3	= 0.5138;

	// Green interpolation
	for(col_pos = 0; col_pos < half_block_size; col_pos += 1){
		input0 = variable->buffer[16] + (linestride0 * col_pos);
		input1 = variable->buffer[17] + (linestride1 * col_pos);
		input2 = variable->buffer[18] + (linestride2 * col_pos);
		input3 = variable->buffer[19] + (linestride3 * col_pos);
		input_end = input0 + half_width;

		v_buffer_green0 = variable->buffer[0] + (v_buffer_green0_linestride * col_pos);
		h_buffer_green0 = variable->buffer[1] + (h_buffer_green0_linestride * col_pos);
		v_buffer_green3 = variable->buffer[2] + (v_buffer_green3_linestride * col_pos);
		h_buffer_green3 = variable->buffer[3] + (h_buffer_green3_linestride * col_pos);

		for(;input0 < input_end;){

			dif1	= ABS(*input0 - *(input0 - 1));
			dif2	= ABS(*input0 - *(input0 + 1));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 * 2 + dif2 * 2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;

			factor1	= filter1 * dif1;
			factor2	= filter2 * dif1;
			factor3	= filter3;
			factor4	= filter2 * dif2;
			factor5 = filter1 * dif2;
			//sum 	= factor1 + factor2 + factor3 + factor4 + factor5;
			//factor1	/= sum;
			//factor2	/= sum;
			//factor3	/= sum;
			//factor4	/= sum;
			//factor5	/= sum;
			sum = 	*(input0 - 1) 	* factor1 +
					*(input1 - 1) 	* factor2 +
					*input0 		* factor3 +
					*input1 		* factor4 +
					*(input0 + 1)	* factor5;
			*h_buffer_green0 = limit_f(sum, *(input1 - 1), *input1);

			dif1	= ABS(*input0 - *(input0 - linestride0));
			dif2	= ABS(*input0 - *(input0 + linestride0));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 * 2 + dif2 * 2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;

			factor1	= filter1 * dif1;
			factor2	= filter2 * dif1;
			factor3	= filter3;
			factor4	= filter2 * dif2;
			factor5 = filter1 * dif2;
			//sum 	= factor1 + factor2 + factor3 + factor4 + factor5;
			//factor1	/= sum;
			//factor2	/= sum;
			//factor3	/= sum;
			//factor4	/= sum;
			//factor5	/= sum;
			sum = 	*(input0 - linestride0)	* factor1 +
					*(input2 - linestride2)	* factor2 +
					*input0					* factor3 +
					*input2					* factor4 +
					*(input0 - linestride0)	* factor5;
			*v_buffer_green0 = limit_f(sum, *(input2 - linestride2), *(input2));

			dif1	= ABS(*input3 - *(input3 - 1));
			dif2	= ABS(*input3 - *(input3 + 1));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 * 2 + dif2 * 2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;

			factor1	= filter1 * dif1;
			factor2	= filter2 * dif1;
			factor3	= filter3;
			factor4	= filter2 * dif2;
			factor5 = filter1 * dif2;
			//sum 	= factor1 + factor2 + factor3 + factor4 + factor5;
			//factor1	/= sum;
			//factor2	/= sum;
			//factor3	/= sum;
			//factor4	/= sum;
			//factor5	/= sum;
			sum	=	*(input3 - 1)	* factor1	+
					*input2			* factor2	+
					*input3			* factor3	+
					*(input2 + 1)	* factor4	+
					*(input3 + 1)	* factor5;
			*h_buffer_green3 = limit_f(sum, *input2, *(input2 + 1));

			dif1	= ABS(*input3 - *(input3 - linestride3));
			dif2	= ABS(*input3 - *(input3 + linestride3));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 * 2 + dif2 * 2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;

			factor1	= filter1 * dif1;
			factor2	= filter2 * dif1;
			factor3	= filter3;
			factor4	= filter2 * dif2;
			factor5 = filter1 * dif2;
			//sum 	= factor1 + factor2 + factor3 + factor4 + factor5;
			//factor1	/= sum;
			//factor2	/= sum;
			//factor3	/= sum;
			//factor4	/= sum;
			//factor5	/= sum;
			sum = 	*(input3 - linestride3)	* factor1	+
					*input1					* factor2	+
					*input3					* factor3	+
					*(input1 + linestride1)	* factor4	+
					*(input3 + linestride3)	* factor5;
			*v_buffer_green3 =  limit_f(sum, *input1, *(input1 + linestride1));
			/*
			temp = (*(input1 - 1) + *input1 + *input0) >> 1;
			temp -= ((*(input0 - 1) +  *(input0 + 1)) >> 2);
			*h_buffer_green0 = limit(temp, *(input1 - 1), *input1);

			temp = ( *(input2 - linestride2) + *input2 + *input0) >> 1;
			temp -= ( *(input0 - linestride0) + *(input0 + linestride0)) >> 2;
			*v_buffer_green0 = limit(temp, *(input2 - linestride2), *(input2));

			temp = (*input2 + *(input2 + 1) + *input3 ) >> 1;
			temp -= (*(input3 - 1) + *(input3 + 1)) >> 2;
			*h_buffer_green3 = limit(temp, *input2, *(input2 + 1));

			temp = (*input1 + *(input1 + linestride1) + *input3) >> 1;
			temp -= (*(input3 + linestride3) + *(input3 - linestride3)) >> 2;
			*v_buffer_green3 =  limit(temp, *input1, *(input1 + linestride1));
			*/

			input0 += 1;
			input1 += 1;
			input2 += 1;
			input3 += 1;
			h_buffer_green0 += 1;
			v_buffer_green0 += 1;
			h_buffer_green3 += 1;
			v_buffer_green3 += 1;
		}
	}
	return status;
}

int demosaic_AHD_extended_2_green(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short	 *input1, *input2, *input3, *input0, *input_end;
	unsigned short *h_buffer_green0, *v_buffer_green0, *h_buffer_green3, *v_buffer_green3;
	int	h_buffer_green0_linestride, v_buffer_green0_linestride, h_buffer_green3_linestride, v_buffer_green3_linestride;;
	int linestride1, linestride2, linestride3, linestride0;
	int col_pos;
//	int temp;

	/*
	int red0_01, green1_01, green2_01, blue3_01;
	int red0_11, green1_11, green2_11, blue3_11;
	int red0_21, green1_21, green2_21, blue3_21;
	int red0_10, green1_10, green2_10, blue3_10;
	int red0_12, green1_12, green2_12, blue3_12;


	h_buffer_green0_linestride = variable->temp_buffer_linestride[0];
	v_buffer_green0_linestride = variable->temp_buffer_linestride[1];
	h_buffer_green3_linestride = variable->temp_buffer_linestride[2];
	v_buffer_green3_linestride = variable->temp_buffer_linestride[3];
*/

	v_buffer_green0_linestride = variable->linestride[0];
	h_buffer_green0_linestride = variable->linestride[1];
	v_buffer_green3_linestride = variable->linestride[2];
	h_buffer_green3_linestride = variable->linestride[3];

	linestride0	= variable->linestride[16];
	linestride1	= variable->linestride[17];
	linestride2	= variable->linestride[18];
	linestride3 = variable->linestride[19];

//	const int homo_green = 200;

	float dif1, dif2, sum;
	int left, right;
	//float factor1, factor2, factor3, factor4, factor5;
	//const float filter1	= -0.2569;
	//const float filter2	= 0.4339;
	//const float filter3	= 0.5138;

	// Green interpolation
	for(col_pos = 0; col_pos < half_block_size; col_pos += 1){
		input0 = variable->buffer[16] + (linestride0 * col_pos);
		input1 = variable->buffer[17] + (linestride1 * col_pos);
		input2 = variable->buffer[18] + (linestride2 * col_pos);
		input3 = variable->buffer[19] + (linestride3 * col_pos);
		input_end = input0 + half_width;

		v_buffer_green0 = variable->buffer[0] + (v_buffer_green0_linestride * col_pos);
		h_buffer_green0 = variable->buffer[1] + (h_buffer_green0_linestride * col_pos);
		v_buffer_green3 = variable->buffer[2] + (v_buffer_green3_linestride * col_pos);
		h_buffer_green3 = variable->buffer[3] + (h_buffer_green3_linestride * col_pos);

		for(;input0 < input_end;){

			dif1	= ABS(*input0 - *(input0 - 1));
			dif2	= ABS(*input0 - *(input0 + 1));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1  + dif2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;
			left 	= 	*(input1 - 1) + (( *(input1 - 1) - *(input1 - 2)) >> 1);
			right	= 	*(input1) + ((*(input1) - *(input1 + 1)) >> 1);
			sum 	= 	left * dif1 + right * dif2;
			*h_buffer_green0 = limit_f2(sum, *(input1 - 1), *input1);

			dif1	= ABS(*input0 - *(input0 - linestride0));
			dif2	= ABS(*input0 - *(input0 + linestride0));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1  + dif2 ;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;
			left	= *(input2 - linestride2) + ((*(input2 - linestride2) - *(input2 - 2 * linestride2)) >> 1);
			right	= *(input2) + ((*input2 - *(input2 + linestride2))>> 1);
			sum 	= left * dif1 + right * dif2;
			*v_buffer_green0 = limit_f2(sum, *(input2), *(input2 - linestride2));

			dif1	= ABS(*input3 - *(input3 - 1));
			dif2	= ABS(*input3 - *(input3 + 1));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 + dif2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;
			left	= *input2 + ((*input2 - *(input2 - 1))>>1);
			right	= *(input2 + 1) + (( *(input2 + 1) - *(input2 + 2)) >> 1);
			sum		= left * dif1 + right * dif2;
			*h_buffer_green3 = limit_f2(sum, *input2, *(input2 + 1));

			dif1	= ABS(*input3 - *(input3 - linestride3));
			dif2	= ABS(*input3 - *(input3 + linestride3));
			dif2	= dif1 / dif2;
			dif1	= 1.0f;
			sum		= dif1 + dif2;
			dif1	= dif1 / sum;
			dif2	= dif2 / sum;
			left	= *input1 + ( (*input1 - *(input1 - linestride1)) >> 1);
			right	= *(input1 + linestride1) + ( (*(input1 + linestride1) + *(input1 - 2*linestride1)) >> 1);
			sum		= left * dif1 + right * dif2;
			*v_buffer_green3 =  limit_f2(sum, *input1, *(input1 + linestride1));

			input0 += 1;
			input1 += 1;
			input2 += 1;
			input3 += 1;
			h_buffer_green0 += 1;
			v_buffer_green0 += 1;
			h_buffer_green3 += 1;
			v_buffer_green3 += 1;
		}
	}
	return status;
}

void cam_to_Lab(	int *L,
					int *a,
					int *b,
					unsigned short *cam_R,
					unsigned short *cam_G,
					unsigned short *cam_B,
					float cam_to_XYZ[9],
					float lut[0x10000])
{

	unsigned short x, y, z;
	float fx, fy, fz;

	x = crop(cam_to_XYZ[0] * *cam_R + cam_to_XYZ[1] * *cam_G + cam_to_XYZ[2] *  *cam_B + 0.5F);
	y = crop(cam_to_XYZ[3] * *cam_R + cam_to_XYZ[4] * *cam_G + cam_to_XYZ[5] *  *cam_B + 0.5F);
	z = crop(cam_to_XYZ[6] * *cam_R + cam_to_XYZ[7] * *cam_G + cam_to_XYZ[8] *  *cam_B + 0.5F);

	fx = lut[x];
	fy = lut[y];
	fz = lut[z];

	*L = 64 * (116 * fy - 16);
	*a = 64 * 500 * (fx - fy);
	*b = 64 * 200 * (fy - fz);

}


int demosaic_AHD_default_red_blue(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short *red_0, *green_1, *green_2, *blue_3, *red_end;
	unsigned short *v_green_0, *h_green_0, *v_green_3, *h_green_3;

	unsigned short *v_red_1, *v_red_2, *v_red_3;
	unsigned short *h_red_1, *h_red_2, *h_red_3;

	unsigned short	 *v_blue_0, *v_blue_1, *v_blue_2;
	unsigned short *h_blue_0, *h_blue_1, *h_blue_2;

	int *v_l, *v_a, *v_b, *h_l, *h_a, *h_b;

	const int li_v_l			= variable->lab_linestride[0];
	const int li_v_a			= variable->lab_linestride[1];
	const int li_v_b			= variable->lab_linestride[2];

	const int li_h_l			= variable->lab_linestride[3];
	const int li_h_a			= variable->lab_linestride[4];
	const int li_h_b			= variable->lab_linestride[5];

	const int li_red_0			= variable->linestride[16];
	const int li_red_0_p		= li_red_0 + 1;
	const int li_green_1		= variable->linestride[17];
	const int li_green_2		= variable->linestride[18];
	const int li_blue_3		= variable->linestride[19];
	const int li_blue_3_p		= li_blue_3 + 1;
	//const int li_blue_3_m		= li_blue_3 - 1;
	const int li_v_green_0		= variable->linestride[0];
	const int li_v_green_0_p	= li_v_green_0 + 1;
	//const int li_v_green_0_m	= li_v_green_0 - 1;
	const int li_h_green_0		= variable->linestride[1];
	const int li_h_green_0_p	= li_h_green_0 + 1;
	//const int li_h_green_0_m	= li_h_green_0 - 1;
	const int li_v_green_3		= variable->linestride[2];
	const int li_v_green_3_p	= li_v_green_3 + 1;
	//const int li_v_green_3_m	= li_v_green_3 - 1;
	const int li_h_green_3		= variable->linestride[3];
	const int li_h_green_3_p	= li_h_green_3 + 1;
	//const int li_h_green_3_m	= li_h_green_3 - 1;

	const int li_v_red_1		= variable->linestride[10];
	const int li_v_red_2		= variable->linestride[12];
	const int li_v_red_3		= variable->linestride[14];
	const int li_h_red_1		= variable->linestride[11];
	const int li_h_red_2		= variable->linestride[13];
	const int li_h_red_3		= variable->linestride[15];

	const int li_v_blue_0		= variable->linestride[4];
	const int li_v_blue_1		= variable->linestride[6];
	const int li_v_blue_2		= variable->linestride[8];
	const int li_h_blue_0		= variable->linestride[5];
	const int li_h_blue_1		= variable->linestride[7];
	const int li_h_blue_2		= variable->linestride[9];

	int col_pos;

	for(col_pos = 0; col_pos < half_block_size; col_pos++){
		red_0		= variable->buffer[16] + (li_red_0 * col_pos);
		green_1		= variable->buffer[17] + (li_green_1* col_pos);
		green_2		= variable->buffer[18] + (li_green_2* col_pos);
		blue_3		= variable->buffer[19] + (li_blue_3* col_pos);
		red_end		= red_0 + half_width;

		v_green_0	= variable->buffer[0] + (li_v_green_0 * col_pos);
		h_green_0	= variable->buffer[1] + (li_h_green_0 * col_pos);
		v_green_3	= variable->buffer[2] + (li_v_green_3 * col_pos);
		h_green_3	= variable->buffer[3] + (li_h_green_3 * col_pos);

		v_blue_0	= variable->buffer[4] + (li_v_blue_0 * col_pos);
		h_blue_0	= variable->buffer[5] + (li_h_blue_0 * col_pos);
		v_blue_1	= variable->buffer[6] + (li_v_blue_1 * col_pos);
		h_blue_1	= variable->buffer[7] + (li_h_blue_1 * col_pos);
		v_blue_2	= variable->buffer[8] + (li_v_blue_2 * col_pos);
		h_blue_2	= variable->buffer[9] + (li_h_blue_2 * col_pos);

		v_red_1		= variable->buffer[10] + (li_v_red_1 * col_pos);
		h_red_1		= variable->buffer[11] + (li_h_red_1 * col_pos);
		v_red_2		= variable->buffer[12] + (li_v_red_2 * col_pos);
		h_red_2		= variable->buffer[13] + (li_h_red_2 * col_pos);
		v_red_3		= variable->buffer[14] + (li_v_red_3 * col_pos);
		h_red_3		= variable->buffer[15] + (li_h_red_3 * col_pos);

		v_l		= variable->lab_buffer[0] + (li_v_l * 2 * col_pos);
		v_a		= variable->lab_buffer[1] + (li_v_a * 2 * col_pos);
		v_b		= variable->lab_buffer[2] + (li_v_b * 2 * col_pos);

		h_l		= variable->lab_buffer[3] + (li_h_l * 2 * col_pos);
		h_a		= variable->lab_buffer[4] + (li_h_a * 2 * col_pos);
		h_b		= variable->lab_buffer[5] + (li_h_b * 2 * col_pos);


		while(red_0 < red_end){

			*v_blue_0 = crop_i(*v_green_0 + ((	*(blue_3) +
												*(blue_3 - 1) +
												*(blue_3 - li_blue_3) +
												*(blue_3 - li_blue_3_p) -
												*(v_green_3 ) -
												*(v_green_3 - 1) -
												*(v_green_3 - li_v_green_3) -
												*(v_green_3 - li_v_green_3_p)) >> 2));

			*h_blue_0 = crop_i(*h_green_0 + ((	*(blue_3 ) +
												*(blue_3 - 1) +
												*(blue_3 - li_blue_3) +
												*(blue_3 - li_blue_3_p) -
												*(h_green_3) -
												*(h_green_3 - 1) -
												*(h_green_3 - li_h_green_3) -
												*(h_green_3 - li_h_green_3_p)) >> 2));



			*v_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(v_green_3) -
												*(v_green_3 - li_v_green_3)) >> 1));

			*h_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(h_green_3) -
												*(h_green_3 - li_h_green_3)) >> 1));


			*v_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(v_green_3) -
												*(v_green_3 - 1)) >> 1));

			*h_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(h_green_3) -
												*(h_green_3 - 1)) >> 1));


			*v_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(v_green_0) -
												*(v_green_0 + 1)) >> 1));

			*h_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(h_green_0) -
												*(h_green_0 + 1)) >> 1));

			*v_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(v_green_0) -
												*(v_green_0 + li_v_green_0)) >> 1));

			*h_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(h_green_0) -
												*(h_green_0 + li_h_green_0)) >> 1));

			*v_red_3	= crop_i(*v_green_3 +((	*(red_0)+
												*(red_0 + 1)+
												*(red_0 + li_red_0)+
												*(red_0 + li_red_0_p) -
												*(v_green_0)-
												*(v_green_0 + 1)-
												*(v_green_0 + li_v_green_0)-
												*(v_green_0 + li_v_green_0_p)) >> 2));



			*h_red_3	= crop_i(*h_green_3 +((	*(red_0)+
												*(red_0 + 1)+
												*(red_0 + li_red_0)+
												*(red_0 + li_red_0_p) -
												*(h_green_0)-
												*(h_green_0 + 1)-
												*(h_green_0 + li_h_green_0)-
												*(h_green_0 + li_h_green_0_p)) >> 2));


			cam_to_Lab(v_l, v_a, v_b, red_0, v_green_0, v_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + 1, v_a + 1, v_b + 1,v_red_1 , green_1, v_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + li_v_l, v_a + li_v_a, v_b + li_v_b, v_red_2, green_2, v_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + (li_v_l + 1), v_a + (li_v_a + 1), v_b + (li_v_b + 1), v_red_3, v_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);

			cam_to_Lab(h_l, h_a, h_b, red_0, h_green_0, h_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + 1, h_a + 1, h_b + 1,h_red_1 , green_1, h_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + li_h_l, h_a + li_h_a, h_b + li_h_b, h_red_2, green_2, h_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + (li_h_l + 1), h_a + (li_h_a + 1), h_b + (li_h_b + 1), h_red_3, h_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);

			v_l			+= 2;
			v_a			+= 2;
			v_b			+= 2;

			h_l			+= 2;
			h_a			+= 2;
			h_b			+= 2;

			red_0		+= 1;
			green_1		+= 1;
			green_2		+= 1;
			blue_3		+= 1;

			v_green_0	+= 1;
			h_green_0	+= 1;
			v_green_3	+= 1;
			h_green_3	+= 1;

			v_blue_0	+= 1;
			h_blue_0	+= 1;
			v_blue_1	+= 1;
			h_blue_1	+= 1;
			v_blue_2	+= 1;
			h_blue_2	+= 1;

			v_red_1		+= 1;
			h_red_1		+= 1;
			v_red_2		+= 1;
			h_red_2		+= 1;
			v_red_3		+= 1;
			h_red_3		+= 1;
		}


	}

	return status;
}

int demosaic_AHD_extended_red_blue(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short *red_0, *green_1, *green_2, *blue_3, *red_end;
	unsigned short *v_green_0, *h_green_0, *v_green_3, *h_green_3;

	unsigned short *v_red_1, *v_red_2, *v_red_3;
	unsigned short *h_red_1, *h_red_2, *h_red_3;

	unsigned short	 *v_blue_0, *v_blue_1, *v_blue_2;
	unsigned short *h_blue_0, *h_blue_1, *h_blue_2;

	int *v_l, *v_a, *v_b, *h_l, *h_a, *h_b;

	const int li_v_l			= variable->lab_linestride[0];
	const int li_v_a			= variable->lab_linestride[1];
	const int li_v_b			= variable->lab_linestride[2];

	const int li_h_l			= variable->lab_linestride[3];
	const int li_h_a			= variable->lab_linestride[4];
	const int li_h_b			= variable->lab_linestride[5];

	const int li_red_0			= variable->linestride[16];
	const int li_red_0_p		= li_red_0 + 1;
	const int li_green_1		= variable->linestride[17];
	const int li_green_2		= variable->linestride[18];
	const int li_blue_3		= variable->linestride[19];
	const int li_blue_3_p		= li_blue_3 + 1;
	//const int li_blue_3_m		= li_blue_3 - 1;
	const int li_v_green_0		= variable->linestride[0];
	const int li_v_green_0_p	= li_v_green_0 + 1;
	//const int li_v_green_0_m	= li_v_green_0 - 1;
	const int li_h_green_0		= variable->linestride[1];
	const int li_h_green_0_p	= li_h_green_0 + 1;
	//const int li_h_green_0_m	= li_h_green_0 - 1;
	const int li_v_green_3		= variable->linestride[2];
	const int li_v_green_3_p	= li_v_green_3 + 1;
	//const int li_v_green_3_m	= li_v_green_3 - 1;
	const int li_h_green_3		= variable->linestride[3];
	const int li_h_green_3_p	= li_h_green_3 + 1;
	//const int li_h_green_3_m	= li_h_green_3 - 1;

	const int li_v_red_1		= variable->linestride[10];
	const int li_v_red_2		= variable->linestride[12];
	const int li_v_red_3		= variable->linestride[14];
	const int li_h_red_1		= variable->linestride[11];
	const int li_h_red_2		= variable->linestride[13];
	const int li_h_red_3		= variable->linestride[15];

	const int li_v_blue_0		= variable->linestride[4];
	const int li_v_blue_1		= variable->linestride[6];
	const int li_v_blue_2		= variable->linestride[8];
	const int li_h_blue_0		= variable->linestride[5];
	const int li_h_blue_1		= variable->linestride[7];
	const int li_h_blue_2		= variable->linestride[9];

	int col_pos;

	float factor1, factor2, factor3, factor0, sum;
	float factor_not_null = 0.1f;

	for(col_pos = 0; col_pos < half_block_size; col_pos++){
		red_0		= variable->buffer[16] + (li_red_0 * col_pos);
		green_1		= variable->buffer[17] + (li_green_1* col_pos);
		green_2		= variable->buffer[18] + (li_green_2* col_pos);
		blue_3		= variable->buffer[19] + (li_blue_3* col_pos);
		red_end		= red_0 + half_width;

		v_green_0	= variable->buffer[0] + (li_v_green_0 * col_pos);
		h_green_0	= variable->buffer[1] + (li_h_green_0 * col_pos);
		v_green_3	= variable->buffer[2] + (li_v_green_3 * col_pos);
		h_green_3	= variable->buffer[3] + (li_h_green_3 * col_pos);

		v_blue_0	= variable->buffer[4] + (li_v_blue_0 * col_pos);
		h_blue_0	= variable->buffer[5] + (li_h_blue_0 * col_pos);
		v_blue_1	= variable->buffer[6] + (li_v_blue_1 * col_pos);
		h_blue_1	= variable->buffer[7] + (li_h_blue_1 * col_pos);
		v_blue_2	= variable->buffer[8] + (li_v_blue_2 * col_pos);
		h_blue_2	= variable->buffer[9] + (li_h_blue_2 * col_pos);

		v_red_1		= variable->buffer[10] + (li_v_red_1 * col_pos);
		h_red_1		= variable->buffer[11] + (li_h_red_1 * col_pos);
		v_red_2		= variable->buffer[12] + (li_v_red_2 * col_pos);
		h_red_2		= variable->buffer[13] + (li_h_red_2 * col_pos);
		v_red_3		= variable->buffer[14] + (li_v_red_3 * col_pos);
		h_red_3		= variable->buffer[15] + (li_h_red_3 * col_pos);

		v_l		= variable->lab_buffer[0] + (li_v_l * 2 * col_pos);
		v_a		= variable->lab_buffer[1] + (li_v_a * 2 * col_pos);
		v_b		= variable->lab_buffer[2] + (li_v_b * 2 * col_pos);

		h_l		= variable->lab_buffer[3] + (li_h_l * 2 * col_pos);
		h_a		= variable->lab_buffer[4] + (li_h_a * 2 * col_pos);
		h_b		= variable->lab_buffer[5] + (li_h_b * 2 * col_pos);


		while(red_0 < red_end){

			factor0 = (float)SQRI(*v_green_0 - *(v_green_3));
			factor1 = (float)SQRI(*v_green_0 - *(v_green_3 - 1));
			factor2 = (float)SQRI(*v_green_0 - *(v_green_3 - li_v_green_3));
			factor3 = (float)SQRI(*v_green_0 - *(v_green_3 - li_v_green_3_p));

			factor0 = (factor0 == 0.0f) ? factor_not_null : factor0;
			factor1 = (factor1 == 0.0f) ? factor_not_null : factor1;
			factor2 = (factor2 == 0.0f) ? factor_not_null : factor2;
			factor3 = (factor3 == 0.0f) ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*v_blue_0 = crop_i(*v_green_0 + ((int)(	(*(blue_3)				- *(v_green_3 )) 				* factor0 +
													(*(blue_3 - 1)			- *(v_green_3 - 1)) 			* factor1 +
													(*(blue_3 - li_blue_3)	- *(v_green_3 - li_v_green_3)) 	* factor2 +
													(*(blue_3 - li_blue_3_p)- *(v_green_3 - li_v_green_3_p))* factor3)));

			factor0 = (float)SQRI(*h_green_0 - *(h_green_3));
			factor1 = (float)SQRI(*h_green_0 - *(h_green_3 - 1));
			factor2 = (float)SQRI(*h_green_0 - *(h_green_3 - li_h_green_3));
			factor3 = (float)SQRI(*h_green_0 - *(h_green_3 - li_h_green_3_p));

			factor0 = (factor0 == 0.0f) ? factor_not_null : factor0;
			factor1 = (factor1 == 0.0f) ? factor_not_null : factor1;
			factor2 = (factor2 == 0.0f) ? factor_not_null : factor2;
			factor3 = (factor3 == 0.0f) ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;
			*h_blue_0 = crop_i(*h_green_0 + ((int)(	(*(blue_3)				- *(h_green_3 )) 				* factor0 +
													(*(blue_3 - 1)			- *(h_green_3 - 1)) 			* factor1 +
													(*(blue_3 - li_blue_3)	- *(h_green_3 - li_h_green_3)) 	* factor2 +
													(*(blue_3 - li_blue_3_p)- *(h_green_3 - li_h_green_3_p))* factor3)));

			/**h_blue_0 = *(blue_3) 				* factor0 +
						*(blue_3 - 1)			* factor1 +
						*(blue_3 - li_blue_3)	* factor2 +
						*(blue_3 - li_blue_3_p)	* factor3; */
			//*h_blue_0 = (*(blue_3 - li_blue_3) + *(blue_3 - li_blue_3_p)) >> 1;



			*v_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(v_green_3) -
												*(v_green_3 - li_v_green_3)) >> 1));

			*h_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(h_green_3) -
												*(h_green_3 - li_h_green_3)) >> 1));


			*v_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(v_green_3) -
												*(v_green_3 - 1)) >> 1));

			*h_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(h_green_3) -
												*(h_green_3 - 1)) >> 1));


			*v_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(v_green_0) -
												*(v_green_0 + 1)) >> 1));

			*h_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(h_green_0) -
												*(h_green_0 + 1)) >> 1));

			*v_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(v_green_0) -
												*(v_green_0 + li_v_green_0)) >> 1));

			*h_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(h_green_0) -
												*(h_green_0 + li_h_green_0)) >> 1));

			factor0 = (float)SQRI(*v_green_3 - *(v_green_0));
			factor1 = (float)SQRI(*v_green_3 - *(v_green_0 + 1));
			factor2 = (float)SQRI(*v_green_3 - *(v_green_0 + li_v_green_0));
			factor3 = (float)SQRI(*v_green_3 - *(v_green_0 + li_v_green_0_p));

			factor0 = (factor0 == 0.0f) ? factor_not_null : factor0;
			factor1 = (factor1 == 0.0f) ? factor_not_null : factor1;
			factor2 = (factor2 == 0.0f) ? factor_not_null : factor2;
			factor3 = (factor3 == 0.0f) ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*v_red_3	= crop_i(*v_green_3 +((int)((*(red_0)				- *(v_green_0))					* factor0 +
													(*(red_0 + 1)			- *(v_green_0 + 1))				* factor1 +
													(*(red_0 + li_red_0)	- *(v_green_0 + li_v_green_0))	* factor2 +
													(*(red_0 + li_red_0_p)	- *(v_green_0 + li_v_green_0_p))* factor3  )));


			factor0 = SQRI(*h_green_3 - *(h_green_0));
			factor1 = SQRI(*h_green_3 - *(h_green_0 + 1));
			factor2 = SQRI(*h_green_3 - *(h_green_0 + li_h_green_0));
			factor3 = SQRI(*h_green_3 - *(h_green_0 + li_h_green_0_p));

			factor0 = factor0 == 0 ? factor_not_null : factor0;
			factor1 = factor1 == 0 ? factor_not_null : factor1;
			factor2 = factor2 == 0 ? factor_not_null : factor2;
			factor3 = factor3 == 0 ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*h_red_3	= crop_i(*h_green_3 +((int)((*(red_0)				- *(h_green_0))					* factor0 +
													(*(red_0 + 1)			- *(h_green_0 + 1))				* factor1 +
													(*(red_0 + li_red_0)	- *(h_green_0 + li_h_green_0))	* factor2 +
													(*(red_0 + li_red_0_p)	- *(h_green_0 + li_h_green_0_p))* factor3  )));


			cam_to_Lab(v_l, v_a, v_b, red_0, v_green_0, v_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + 1, v_a + 1, v_b + 1,v_red_1 , green_1, v_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + li_v_l, v_a + li_v_a, v_b + li_v_b, v_red_2, green_2, v_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + (li_v_l + 1), v_a + (li_v_a + 1), v_b + (li_v_b + 1), v_red_3, v_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);

			cam_to_Lab(h_l, h_a, h_b, red_0, h_green_0, h_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + 1, h_a + 1, h_b + 1,h_red_1 , green_1, h_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + li_h_l, h_a + li_h_a, h_b + li_h_b, h_red_2, green_2, h_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + (li_h_l + 1), h_a + (li_h_a + 1), h_b + (li_h_b + 1), h_red_3, h_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);


			v_l			+= 2;
			v_a			+= 2;
			v_b			+= 2;

			h_l			+= 2;
			h_a			+= 2;
			h_b			+= 2;

			red_0		+= 1;
			green_1		+= 1;
			green_2		+= 1;
			blue_3		+= 1;

			v_green_0	+= 1;
			h_green_0	+= 1;
			v_green_3	+= 1;
			h_green_3	+= 1;

			v_blue_0	+= 1;
			h_blue_0	+= 1;
			v_blue_1	+= 1;
			h_blue_1	+= 1;
			v_blue_2	+= 1;
			h_blue_2	+= 1;

			v_red_1		+= 1;
			h_red_1		+= 1;
			v_red_2		+= 1;
			h_red_2		+= 1;
			v_red_3		+= 1;
			h_red_3		+= 1;
		}


	}

	return status;
}


int demosaic_AHD_extended_2_red_blue(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	const int half_width		= width / 2;
	unsigned short *red_0, *green_1, *green_2, *blue_3, *red_end;
	unsigned short *v_green_0, *h_green_0, *v_green_3, *h_green_3;

	unsigned short *v_red_1, *v_red_2, *v_red_3;
	unsigned short *h_red_1, *h_red_2, *h_red_3;

	unsigned short	 *v_blue_0, *v_blue_1, *v_blue_2;
	unsigned short *h_blue_0, *h_blue_1, *h_blue_2;

	int *v_l, *v_a, *v_b, *h_l, *h_a, *h_b;

	const int li_v_l			= variable->lab_linestride[0];
	const int li_v_a			= variable->lab_linestride[1];
	const int li_v_b			= variable->lab_linestride[2];

	const int li_h_l			= variable->lab_linestride[3];
	const int li_h_a			= variable->lab_linestride[4];
	const int li_h_b			= variable->lab_linestride[5];

	const int li_red_0			= variable->linestride[16];
	const int li_red_0_p		= li_red_0 + 1;
	const int li_green_1		= variable->linestride[17];
	const int li_green_2		= variable->linestride[18];
	const int li_blue_3		= variable->linestride[19];
	const int li_blue_3_p		= li_blue_3 + 1;
	//const int li_blue_3_m		= li_blue_3 - 1;
	const int li_v_green_0		= variable->linestride[0];
	const int li_v_green_0_p	= li_v_green_0 + 1;
	//const int li_v_green_0_m	= li_v_green_0 - 1;
	const int li_h_green_0		= variable->linestride[1];
	const int li_h_green_0_p	= li_h_green_0 + 1;
	//const int li_h_green_0_m	= li_h_green_0 - 1;
	const int li_v_green_3		= variable->linestride[2];
	const int li_v_green_3_p	= li_v_green_3 + 1;
	//const int li_v_green_3_m	= li_v_green_3 - 1;
	const int li_h_green_3		= variable->linestride[3];
	const int li_h_green_3_p	= li_h_green_3 + 1;
	//const int li_h_green_3_m	= li_h_green_3 - 1;

	const int li_v_red_1		= variable->linestride[10];
	const int li_v_red_2		= variable->linestride[12];
	const int li_v_red_3		= variable->linestride[14];
	const int li_h_red_1		= variable->linestride[11];
	const int li_h_red_2		= variable->linestride[13];
	const int li_h_red_3		= variable->linestride[15];

	const int li_v_blue_0		= variable->linestride[4];
	const int li_v_blue_1		= variable->linestride[6];
	const int li_v_blue_2		= variable->linestride[8];
	const int li_h_blue_0		= variable->linestride[5];
	const int li_h_blue_1		= variable->linestride[7];
	const int li_h_blue_2		= variable->linestride[9];

	int col_pos;

	float factor1, factor2, factor3, factor0, sum;
	float factor_not_null = 0.1f;

	for(col_pos = 0; col_pos < half_block_size; col_pos++){
		red_0		= variable->buffer[16] + (li_red_0 * col_pos);
		green_1		= variable->buffer[17] + (li_green_1* col_pos);
		green_2		= variable->buffer[18] + (li_green_2* col_pos);
		blue_3		= variable->buffer[19] + (li_blue_3* col_pos);
		red_end		= red_0 + half_width;

		v_green_0	= variable->buffer[0] + (li_v_green_0 * col_pos);
		h_green_0	= variable->buffer[1] + (li_h_green_0 * col_pos);
		v_green_3	= variable->buffer[2] + (li_v_green_3 * col_pos);
		h_green_3	= variable->buffer[3] + (li_h_green_3 * col_pos);

		v_blue_0	= variable->buffer[4] + (li_v_blue_0 * col_pos);
		h_blue_0	= variable->buffer[5] + (li_h_blue_0 * col_pos);
		v_blue_1	= variable->buffer[6] + (li_v_blue_1 * col_pos);
		h_blue_1	= variable->buffer[7] + (li_h_blue_1 * col_pos);
		v_blue_2	= variable->buffer[8] + (li_v_blue_2 * col_pos);
		h_blue_2	= variable->buffer[9] + (li_h_blue_2 * col_pos);

		v_red_1		= variable->buffer[10] + (li_v_red_1 * col_pos);
		h_red_1		= variable->buffer[11] + (li_h_red_1 * col_pos);
		v_red_2		= variable->buffer[12] + (li_v_red_2 * col_pos);
		h_red_2		= variable->buffer[13] + (li_h_red_2 * col_pos);
		v_red_3		= variable->buffer[14] + (li_v_red_3 * col_pos);
		h_red_3		= variable->buffer[15] + (li_h_red_3 * col_pos);

		v_l		= variable->lab_buffer[0] + (li_v_l * 2 * col_pos);
		v_a		= variable->lab_buffer[1] + (li_v_a * 2 * col_pos);
		v_b		= variable->lab_buffer[2] + (li_v_b * 2 * col_pos);

		h_l		= variable->lab_buffer[3] + (li_h_l * 2 * col_pos);
		h_a		= variable->lab_buffer[4] + (li_h_a * 2 * col_pos);
		h_b		= variable->lab_buffer[5] + (li_h_b * 2 * col_pos);


		while(red_0 < red_end){

			factor0 = SQRI(*v_green_0 - *(v_green_3));
			factor1 = SQRI(*v_green_0 - *(v_green_3 - 1));
			factor2 = SQRI(*v_green_0 - *(v_green_3 - li_v_green_3));
			factor3 = SQRI(*v_green_0 - *(v_green_3 - li_v_green_3_p));

			factor0 = factor0 == 0 ? factor_not_null : factor0;
			factor1 = factor1 == 0 ? factor_not_null : factor1;
			factor2 = factor2 == 0 ? factor_not_null : factor2;
			factor3 = factor3 == 0 ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*v_blue_0 = crop_i(*v_green_0 + ((int)(	(*(blue_3)				- *(v_green_3 )) 				* factor0 +
													(*(blue_3 - 1)			- *(v_green_3 - 1)) 			* factor1 +
													(*(blue_3 - li_blue_3)	- *(v_green_3 - li_v_green_3)) 	* factor2 +
													(*(blue_3 - li_blue_3_p)- *(v_green_3 - li_v_green_3_p))* factor3)));

			factor0 = SQRI(*h_green_0 - *(h_green_3));
			factor1 = SQRI(*h_green_0 - *(h_green_3 - 1));
			factor2 = SQRI(*h_green_0 - *(h_green_3 - li_h_green_3));
			factor3 = SQRI(*h_green_0 - *(h_green_3 - li_h_green_3_p));

			factor0 = factor0 == 0 ? factor_not_null : factor0;
			factor1 = factor1 == 0 ? factor_not_null : factor1;
			factor2 = factor2 == 0 ? factor_not_null : factor2;
			factor3 = factor3 == 0 ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;
			*h_blue_0 = crop_i(*h_green_0 + ((int)(	(*(blue_3)				- *(h_green_3 )) 				* factor0 +
													(*(blue_3 - 1)			- *(h_green_3 - 1)) 			* factor1 +
													(*(blue_3 - li_blue_3)	- *(h_green_3 - li_h_green_3)) 	* factor2 +
													(*(blue_3 - li_blue_3_p)- *(h_green_3 - li_h_green_3_p))* factor3)));

			/**h_blue_0 = *(blue_3) 				* factor0 +
						*(blue_3 - 1)			* factor1 +
						*(blue_3 - li_blue_3)	* factor2 +
						*(blue_3 - li_blue_3_p)	* factor3; */
			//*h_blue_0 = (*(blue_3 - li_blue_3) + *(blue_3 - li_blue_3_p)) >> 1;



			*v_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(v_green_3) -
												*(v_green_3 - li_v_green_3)) >> 1));

			*h_blue_1	= crop_i(*green_1 + ((	*(blue_3) +
												*(blue_3 - li_blue_3)-
												*(h_green_3) -
												*(h_green_3 - li_h_green_3)) >> 1));


			*v_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(v_green_3) -
												*(v_green_3 - 1)) >> 1));

			*h_blue_2	= crop_i(*green_2 + ((	*(blue_3) +
												*(blue_3 - 1) -
												*(h_green_3) -
												*(h_green_3 - 1)) >> 1));


			*v_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(v_green_0) -
												*(v_green_0 + 1)) >> 1));

			*h_red_1	= crop_i(*green_1 + ((	*(red_0) +
												*(red_0 + 1) -
												*(h_green_0) -
												*(h_green_0 + 1)) >> 1));

			*v_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(v_green_0) -
												*(v_green_0 + li_v_green_0)) >> 1));

			*h_red_2	= crop_i(*green_2 + ((	*(red_0)+
												*(red_0 + li_red_0) -
												*(h_green_0) -
												*(h_green_0 + li_h_green_0)) >> 1));

			factor0 = SQRI(*v_green_3 - *(v_green_0));
			factor1 = SQRI(*v_green_3 - *(v_green_0 + 1));
			factor2 = SQRI(*v_green_3 - *(v_green_0 + li_v_green_0));
			factor3 = SQRI(*v_green_3 - *(v_green_0 + li_v_green_0_p));

			factor0 = factor0 == 0 ? factor_not_null : factor0;
			factor1 = factor1 == 0 ? factor_not_null : factor1;
			factor2 = factor2 == 0 ? factor_not_null : factor2;
			factor3 = factor3 == 0 ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*v_red_3	= crop_i(*v_green_3 +((int)((*(red_0)				- *(v_green_0))					* factor0 +
													(*(red_0 + 1)			- *(v_green_0 + 1))				* factor1 +
													(*(red_0 + li_red_0)	- *(v_green_0 + li_v_green_0))	* factor2 +
													(*(red_0 + li_red_0_p)	- *(v_green_0 + li_v_green_0_p))* factor3  )));


			factor0 = SQRI(*h_green_3 - *(h_green_0));
			factor1 = SQRI(*h_green_3 - *(h_green_0 + 1));
			factor2 = SQRI(*h_green_3 - *(h_green_0 + li_h_green_0));
			factor3 = SQRI(*h_green_3 - *(h_green_0 + li_h_green_0_p));

			factor0 = factor0 == 0 ? factor_not_null : factor0;
			factor1 = factor1 == 0 ? factor_not_null : factor1;
			factor2 = factor2 == 0 ? factor_not_null : factor2;
			factor3 = factor3 == 0 ? factor_not_null : factor3;

			factor1	= factor0 / factor1;
			factor2	= factor0 / factor2;
			factor3	= factor0 / factor3;
			factor0	= 1;
			sum = factor0 + factor1 + factor2 + factor3;

			factor0	/= sum;
			factor1 /= sum;
			factor2 /= sum;
			factor3 /= sum;

			*h_red_3	= crop_i(*h_green_3 +((int)((*(red_0)				- *(h_green_0))					* factor0 +
													(*(red_0 + 1)			- *(h_green_0 + 1))				* factor1 +
													(*(red_0 + li_red_0)	- *(h_green_0 + li_h_green_0))	* factor2 +
													(*(red_0 + li_red_0_p)	- *(h_green_0 + li_h_green_0_p))* factor3  )));


			cam_to_Lab(v_l, v_a, v_b, red_0, v_green_0, v_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + 1, v_a + 1, v_b + 1,v_red_1 , green_1, v_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + li_v_l, v_a + li_v_a, v_b + li_v_b, v_red_2, green_2, v_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(v_l + (li_v_l + 1), v_a + (li_v_a + 1), v_b + (li_v_b + 1), v_red_3, v_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);

			cam_to_Lab(h_l, h_a, h_b, red_0, h_green_0, h_blue_0, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + 1, h_a + 1, h_b + 1,h_red_1 , green_1, h_blue_1,  variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + li_h_l, h_a + li_h_a, h_b + li_h_b, h_red_2, green_2, h_blue_2, variable->cam_to_XYZ, variable->lab_lut);
			cam_to_Lab(h_l + (li_h_l + 1), h_a + (li_h_a + 1), h_b + (li_h_b + 1), h_red_3, h_green_3, blue_3,variable->cam_to_XYZ, variable->lab_lut);


			v_l			+= 2;
			v_a			+= 2;
			v_b			+= 2;

			h_l			+= 2;
			h_a			+= 2;
			h_b			+= 2;

			red_0		+= 1;
			green_1		+= 1;
			green_2		+= 1;
			blue_3		+= 1;

			v_green_0	+= 1;
			h_green_0	+= 1;
			v_green_3	+= 1;
			h_green_3	+= 1;

			v_blue_0	+= 1;
			h_blue_0	+= 1;
			v_blue_1	+= 1;
			h_blue_1	+= 1;
			v_blue_2	+= 1;
			h_blue_2	+= 1;

			v_red_1		+= 1;
			h_red_1		+= 1;
			v_red_2		+= 1;
			h_red_2		+= 1;
			v_red_3		+= 1;
			h_red_3		+= 1;
		}


	}

	return status;
}



int demosaic_AHD_default_build_homogeneity_map(variable_demosaic_AHD *variable)
{
	int status = 0;
	const int block_size		= variable->block_size;
	//const int half_block_size	= block_size / 2;
	const int width			= variable->width;
	//const int half_width		= width / 2;
	int  ldiff[2][4] , abdiff[2][4];
	int *v_l, *v_a, *v_b, *h_l, *h_a, *h_b, *v_l_end;
	int i;
	int leps, abeps;
	unsigned char *v_homo_map, *h_homo_map;


	const int li_v_l			= variable->lab_linestride[0];
	const int li_v_a			= variable->lab_linestride[1];
	const int li_v_b			= variable->lab_linestride[2];
	const int dir_v_l[4] = { -1, 1, -li_v_l, li_v_l };
	const int dir_v_a[4] = { -1, 1, -li_v_a, li_v_a };
	const int dir_v_b[4] = { -1, 1, -li_v_b, li_v_b };


	const int li_h_l			= variable->lab_linestride[3];
	const int li_h_a			= variable->lab_linestride[4];
	const int li_h_b			= variable->lab_linestride[5];
	const int dir_h_l[4] = { -1, 1, -li_h_l, li_h_l };
	const int dir_h_a[4] = { -1, 1, -li_h_a, li_h_a };
	const int dir_h_b[4] = { -1, 1, -li_h_b, li_h_b };
	int col_pos;

	const int v_homo_map_linestride	= variable->homo_map_linestride[0];
	const int h_homo_map_linestride	= variable->homo_map_linestride[1];

	for(col_pos = 0; col_pos < block_size; col_pos++){

		v_l		= variable->lab_buffer[0] + (li_v_l  * col_pos);
		v_a		= variable->lab_buffer[1] + (li_v_a  * col_pos);
		v_b		= variable->lab_buffer[2] + (li_v_b  * col_pos);

		h_l		= variable->lab_buffer[3] + (li_h_l  * col_pos);
		h_a		= variable->lab_buffer[4] + (li_h_a  * col_pos);
		h_b		= variable->lab_buffer[5] + (li_h_b  * col_pos);
		v_l_end	= v_l + width;

		v_homo_map	= variable->homo_map[0] + col_pos * v_homo_map_linestride;
		h_homo_map	= variable->homo_map[1] + col_pos * h_homo_map_linestride;

		for(;v_l < v_l_end;){
			for(i = 0; i < 4; i += 1){
				ldiff[0][i] 	= ABS(	*v_l - *(v_l + dir_v_l[i]));
				abdiff[0][i]	= SQR(	*v_a - *(v_a + dir_v_a[i])) +
								  SQR(	*v_b - *(v_b + dir_v_b[i]));
			}

			for(i = 0; i < 4; i += 1){
				ldiff[1][i] 	= ABS(	*h_l - *(h_l + dir_h_l[i]));
				abdiff[1][i]	= SQR(	*h_a - *(h_a + dir_h_a[i])) +
								  SQR(	*h_b - *(h_b + dir_h_b[i]));
			}

			leps = 	MIN(MAX(ldiff[1][0],ldiff[1][1]),
					MAX(ldiff[0][2],ldiff[0][3]));
			abeps = MIN(MAX(abdiff[1][0],abdiff[1][1]),
				  MAX(abdiff[0][2],abdiff[0][3]));

			*v_homo_map = 0;
			*h_homo_map = 0;
			for(i = 0; i < 4; i += 1){
			  if (ldiff[0][i] <= leps && abdiff[0][i] <= abeps)
				  *v_homo_map += 1;
			  if (ldiff[1][i] <= leps && abdiff[1][i] <= abeps)
				  *h_homo_map += 1;
			}

			v_l		+= 1;
			v_a		+= 1;
			v_b		+= 1;
			h_l		+= 1;
			h_a		+= 1;
			h_b		+= 1;
			v_homo_map	+= 1;
			h_homo_map	+= 1;
		}
	}
	return status;
}

int demosaic_AHD_default_combine_homogenous_pixels(variable_demosaic_AHD *variable)
{
	int status = 0;

	const int block_size		= variable->block_size;
	int col_pos, half_col_pos;
	const int width			= variable->width;
	unsigned char *v_homo_map, *h_homo_map;
	unsigned short *componente_0, *componente_1, *componente_2, *componente_0_end;
	unsigned short *v_red_0, *v_green_0, *v_blue_0, *h_red_0, *h_green_0, *h_blue_0;
	unsigned short *v_red_1, *v_green_1, *v_blue_1, *h_red_1, *h_green_1, *h_blue_1;
	unsigned char v_hm, h_hm;

	const int v_homo_map_linestride	= variable->homo_map_linestride[0];
	const int v_homo_map_linestride_p	= v_homo_map_linestride + 1;
	const int v_homo_map_linestride_m	= v_homo_map_linestride - 1;
	const int h_homo_map_linestride	= variable->homo_map_linestride[1];
	const int h_homo_map_linestride_p	= h_homo_map_linestride + 1;
	const int h_homo_map_linestride_m	= h_homo_map_linestride - 1;

	const int componente_0_linestride 	= variable->componente_linestride[0];
	const int componente_1_linestride	= variable->componente_linestride[1];
	const int componente_2_linestride	= variable->componente_linestride[2];

	const int li_red_0			= variable->linestride[16];
	const int li_green_1		= variable->linestride[17];
	const int li_green_2		= variable->linestride[18];
	const int li_blue_3		= variable->linestride[19];
	const int li_v_green_0		= variable->linestride[0];
	const int li_h_green_0		= variable->linestride[1];
	const int li_v_green_3		= variable->linestride[2];
	const int li_h_green_3		= variable->linestride[3];
;

	const int li_v_red_1		= variable->linestride[10];
	const int li_v_red_2		= variable->linestride[12];
	const int li_v_red_3		= variable->linestride[14];
	const int li_h_red_1		= variable->linestride[11];
	const int li_h_red_2		= variable->linestride[13];
	const int li_h_red_3		= variable->linestride[15];

	const int li_v_blue_0		= variable->linestride[4];
	const int li_v_blue_1		= variable->linestride[6];
	const int li_v_blue_2		= variable->linestride[8];
	const int li_h_blue_0		= variable->linestride[5];
	const int li_h_blue_1		= variable->linestride[7];
	const int li_h_blue_2		= variable->linestride[9];

	for(col_pos = 0; col_pos < block_size; col_pos += 1){
		v_homo_map	= variable->homo_map[0] + col_pos * v_homo_map_linestride;
		h_homo_map	= variable->homo_map[1] + col_pos * h_homo_map_linestride;

		componente_0 = variable->componente[0] + col_pos * componente_0_linestride;
		componente_1 = variable->componente[1] + col_pos * componente_1_linestride;
		componente_2 = variable->componente[2] + col_pos * componente_2_linestride;
		componente_0_end = componente_0 + width;

		if(col_pos % 2 == 0){
			half_col_pos = col_pos / 2;

			v_red_0 	= variable->buffer[16] 	+ half_col_pos * li_red_0;
			v_green_0	= variable->buffer[0]	+ half_col_pos * li_v_green_0;
			v_blue_0	= variable->buffer[4]	+ half_col_pos * li_v_blue_0;

			v_red_1		= variable->buffer[10]	+ half_col_pos * li_v_red_1;
			v_green_1	= variable->buffer[17]	+ half_col_pos * li_green_1;
			v_blue_1	= variable->buffer[6]	+ half_col_pos * li_v_blue_1;

			h_red_0		= variable->buffer[16]	+ half_col_pos * li_red_0;
			h_green_0	= variable->buffer[1]	+ half_col_pos * li_h_green_0;
			h_blue_0	= variable->buffer[5]	+ half_col_pos * li_h_blue_0;

			h_red_1		= variable->buffer[11]	+ half_col_pos * li_h_red_1;
			h_green_1	= variable->buffer[17]	+ half_col_pos * li_green_1;
			h_blue_1	= variable->buffer[7]	+ half_col_pos * li_h_blue_1;

		}else{
			half_col_pos = (col_pos - 1) / 2;

			v_red_0		= variable->buffer[12]	+ half_col_pos * li_v_red_2;
			v_green_0	= variable->buffer[18]	+ half_col_pos * li_green_2;
			v_blue_0	= variable->buffer[8]	+ half_col_pos * li_v_blue_2;

			v_red_1		= variable->buffer[14]	+ half_col_pos * li_v_red_3;
			v_green_1	= variable->buffer[2]	+ half_col_pos * li_v_green_3;
			v_blue_1	= variable->buffer[19]	+ half_col_pos * li_blue_3;

			h_red_0		= variable->buffer[13]	+ half_col_pos * li_h_red_2;
			h_green_0	= variable->buffer[18]	+ half_col_pos * li_green_2;
			h_blue_0	= variable->buffer[9]	+ half_col_pos * li_h_blue_2;

			h_red_1		= variable->buffer[15]	+ half_col_pos * li_h_red_3;
			h_green_1	= variable->buffer[3]	+ half_col_pos * li_h_green_3;
			h_blue_1	= variable->buffer[19]	+ half_col_pos * li_blue_3;
		}


		for(;componente_0 < componente_0_end;){
			v_hm = 	*(v_homo_map - v_homo_map_linestride_p) + *(v_homo_map - v_homo_map_linestride) + *(v_homo_map - v_homo_map_linestride_m) +
					*(v_homo_map - 1) + *v_homo_map + *(v_homo_map + 1) +
					*(v_homo_map - v_homo_map_linestride_m) + *(v_homo_map + v_homo_map_linestride) + *(v_homo_map + v_homo_map_linestride_p);

			h_hm = 	*(h_homo_map - h_homo_map_linestride_p) + *(h_homo_map - h_homo_map_linestride) + *(h_homo_map - h_homo_map_linestride_m) +
					*(h_homo_map - 1) + *h_homo_map + *(h_homo_map + 1) +
					*(h_homo_map - h_homo_map_linestride_m) + *(h_homo_map + h_homo_map_linestride) + *(h_homo_map + h_homo_map_linestride_p);

			if(h_hm != v_hm){
				if(v_hm > h_hm){
					*componente_0	= *v_red_0;
					*componente_1	= *v_green_0;
					*componente_2	= *v_blue_0;
				}else{
					*componente_0	= *h_red_0;
					*componente_1	= *h_green_0;
					*componente_2	= *h_blue_0;
				}
			}else{
				*componente_0	= (*v_red_0 + *h_red_0) >> 1;
				*componente_1	= (*v_green_0 + *h_green_0) >> 1;
				*componente_2	= (*v_blue_0 + *h_blue_0) >> 1;
			}
			//*componente_0	= 0;//*h_red_0;
			//*componente_1	= *h_green_0;
			//*componente_2	= 0;//*h_blue_0;

			v_homo_map 		+= 1;
			h_homo_map		+= 1;
			componente_0	+= 1;
			componente_1	+= 1;
			componente_2	+= 1;

			v_hm = 	*(v_homo_map - v_homo_map_linestride_p) + *(v_homo_map - v_homo_map_linestride) + *(v_homo_map - v_homo_map_linestride_m) +
					*(v_homo_map - 1) + *v_homo_map + *(v_homo_map + 1) +
					*(v_homo_map - v_homo_map_linestride_m) + *(v_homo_map + v_homo_map_linestride) + *(v_homo_map + v_homo_map_linestride_p);

			h_hm = 	*(h_homo_map - h_homo_map_linestride_p) + *(h_homo_map - h_homo_map_linestride) + *(h_homo_map - h_homo_map_linestride_m) +
					*(h_homo_map - 1) + *h_homo_map + *(h_homo_map + 1) +
					*(h_homo_map - h_homo_map_linestride_m) + *(h_homo_map + h_homo_map_linestride) + *(h_homo_map + h_homo_map_linestride_p);


			if(h_hm != v_hm){
				if(v_hm > h_hm){
					*componente_0	= *v_red_1;
					*componente_1	= *v_green_1;
					*componente_2	= *v_blue_1;
				}else{
					*componente_0	= *h_red_1;
					*componente_1	= *h_green_1;
					*componente_2	= *h_blue_1;
				}
			}else{
				*componente_0	= (*v_red_1 + *h_red_1) >> 1;
				*componente_1	= (*v_green_1 + *h_green_1) >> 1;
				*componente_2	= (*v_blue_1 + *h_blue_1) >> 1;
			}
			//*componente_0	= 0;//*h_red_1;
			//*componente_1	= *h_green_1;
			//*componente_2	= 0;//*h_blue_1;

			v_homo_map 		+= 1;
			h_homo_map		+= 1;
			componente_0	+= 1;
			componente_1	+= 1;
			componente_2	+= 1;
			v_red_0			+= 1;
			v_green_0		+= 1;
			v_blue_0		+= 1;
			h_red_0			+= 1;
			h_green_0		+= 1;
			h_blue_0		+= 1;
			v_red_1			+= 1;
			v_green_1		+= 1;
			v_blue_1		+= 1;
			h_red_1			+= 1;
			h_green_1		+= 1;
			h_blue_1		+= 1;
		}
	}

	return status;
}
