/*************************************************************************************************/
/*!
   	@file		pp_cpp_gradation_radial.h
	@author 	Fanzo
 	@date 		2008/4/20
*/
/*************************************************************************************************/
#pragma		once

///////////////////////////////////////////////////////////////////////////////////////////////////
//include files
#include	"pp_cpp_gradation_radial.h"

#pragma pack( push , 8 )		//set align

namespace icubic
{
using namespace icubic;

//=================================================================================================
// gradation radial
//=================================================================================================

//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_int16_rgb
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const int16*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_wrgba( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_wrgba( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wrgba( &c , sc , tc , d );

			wrgba_to_rgb( &c , c );
			StoreAddr_rgb( dest , c );
			dest	= AddPixelSize_rgb( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_rgb();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wrgba( &c , sc , tc , d );

			wrgba_to_rgb( &c , c );
			StoreAddr_rgb( dest , c );
			dest	= SubPixelSize_rgb( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}
//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_int16_rgba
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const int16*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_wrgba( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_wrgba( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wrgba( &c , sc , tc , d );

			wrgba_to_rgba( &c , c );
			StoreAddr_rgba( dest , c );
			dest	= AddPixelSize_rgba( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_rgba();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wrgba( &c , sc , tc , d );

			wrgba_to_rgba( &c , c );
			StoreAddr_rgba( dest , c );
			dest	= SubPixelSize_rgba( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}
//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_int16_a
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const int16*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_wa( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_wa( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wa( &c , sc , tc , d );

			wa_to_a( &c , c );
			StoreAddr_a( dest , c );
			dest	= AddPixelSize_a( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_a();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			int16	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_wa( &c , sc , tc , d );

			wa_to_a( &c , c );
			StoreAddr_a( dest , c );
			dest	= SubPixelSize_a( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}

//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_float_rgb
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const float*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_frgba( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_frgba( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_frgba( &c , sc , tc , d );

			frgba_to_rgb( &c , c );
			StoreAddr_rgb( dest , c );
			dest	= AddPixelSize_rgb( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_rgb();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_frgba( &c , sc , tc , d );

			frgba_to_rgb( &c , c );
			StoreAddr_rgb( dest , c );
			dest	= SubPixelSize_rgb( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}
//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_float_rgba
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const float*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_frgba( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_frgba( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_frgba( &c , sc , tc , d );

			frgba_to_rgba( &c , c );
			StoreAddr_rgba( dest , c );
			dest	= AddPixelSize_rgba( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_rgba();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_frgba( &c , sc , tc , d );

			frgba_to_rgba( &c , c );
			StoreAddr_rgba( dest , c );
			dest	= SubPixelSize_rgba( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}
//=================================================================================================
cb_inline
void pp_cpp_gradation_radial_float_a
		(
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const float*	blendtbl , 
		bool			inverse
		)
{
	if( lt == ls )
		return;

	// def_xy
	float	def_x	= ( dtx - dsx ) / len;
	float	def_y	= ( dty - dsy ) / len;

	// ss_color , st_color
	pp_pixel_calc	sc;
	color_to_fa( &sc , ss_color );
	pp_pixel_calc	tc;
	color_to_fa( &tc , st_color );

	// render
	int		off;
	
	if( inverse == false )
	{
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_fa( &c , sc , tc , d );

			fa_to_a( &c , c );
			StoreAddr_a( dest , c );
			dest	= AddPixelSize_a( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
	else
	{
		dest	= ( uint8* )dest + ( len - 1 ) * PixelSize_a();
		
		for( off = 0 ; off < len ; off++ )
		{
			// t = ( sqrt( dx^2+dy^2 ) - ls ) / ( lt - ls )
			float	t	= ( sqrtf( dsx * dsx + dsy * dsy ) - ls ) / (lt-ls);

			// t->0-256
			int		tbloff	= ( int )( t * 256 );
			tbloff	= tbloff < 0 ? 0 : tbloff > 256 ? 256 : tbloff;
			float	d = blendtbl[ tbloff ];
				
			// color
			pp_pixel_calc	c;
			pp_gradation_linear_fa( &c , sc , tc , d );

			fa_to_a( &c , c );
			StoreAddr_a( dest , c );
			dest	= SubPixelSize_a( dest );
			dsx += def_x;
			dsy += def_y;
		}
	}
}

//=================================================================================================
//!	gradation radial
//!	@retval			---
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_gradation_radial_i16
		(
		pp_format		destformat , 
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const int16*	blendtbl , 
		bool			inverse
		)
{
	typedef void (*func)( void* , int32 , float , float , float , float , const pp_color& , const pp_color& , float , float , const int16* , bool );

	static
	func	funclist[4] = 
	{	
	pp_cpp_gradation_radial_int16_rgb , 
	pp_cpp_gradation_radial_int16_rgba , 
	pp_cpp_gradation_radial_int16_a , 
	};
	( funclist[ destformat ] )( dest , len , dsx , dsy , dtx , dty , ss_color , st_color , ls , lt , blendtbl , inverse );
}

//=================================================================================================
//!	gradation radial
//!	@retval			---
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_gradation_radial_f
		(
		pp_format		destformat , 
		void			*dest , 
		int32			len , 
		float			dsx , 
		float			dsy , 
		float			dtx , 
		float			dty , 
		const pp_color&	ss_color , 
		const pp_color&	st_color , 
		float			ls , 
		float			lt , 
		const float*	blendtbl , 
		bool			inverse
		)
{
	typedef void (*func)( void* , int32 , float , float , float , float , const pp_color& , const pp_color& , float , float , const float* , bool );

	static
	func	funclist[4] = 
	{	
	pp_cpp_gradation_radial_float_rgb , 
	pp_cpp_gradation_radial_float_rgba , 
	pp_cpp_gradation_radial_float_a , 
	};
	( funclist[ destformat ] )( dest , len , dsx , dsy , dtx , dty , ss_color , st_color , ls , lt , blendtbl , inverse );
}

};	//namespace

//using namespace icubic;		

#pragma pack( pop )			//release align

