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

///////////////////////////////////////////////////////////////////////////////////////////////////
//include files


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

namespace icubic
{

//=================================================================================================
// pp_cpp_oversample_m
//=================================================================================================
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgb_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_rgb( &pix , b_color , pix );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgb_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_rgb( &pix , b_color , pix );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgb_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_rgb( &pix , b_color , pix );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_a( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgba_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_rgba( &pix , b_color , pix );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgba_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_rgba( &pix , b_color , pix );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_rgba_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_rgba( &pix , b_color , pix );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_a( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_a_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_a( &pix , b_color , pix );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_a_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_a( &pix , b_color , pix );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_a_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_a( &pix , b_color , pix );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_a( src );
	}
}

//=================================================================================================
// pp_cpp_oversample_m_alpha
//=================================================================================================
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgb_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_rgb( &pix , b_color , pix );
		MulAlpha_rgb( &pix , alpha );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgb_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_rgb( &pix , b_color , pix );
		MulAlpha_rgb( &pix , alpha );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgb_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_rgb( &pix , b_color , pix );
		MulAlpha_rgb( &pix , alpha );
		rgb_to_rgb( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgb( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgb( dest );
		}
		src = AddPixelSize_a( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgba_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_rgba( &pix , b_color , pix );
		MulAlpha_rgba( &pix , alpha );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgba_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_rgba( &pix , b_color , pix );
		MulAlpha_rgba( &pix , alpha );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_rgba_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_rgba( &pix , b_color , pix );
		MulAlpha_rgba( &pix , alpha );
		rgba_to_rgba( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_rgba( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_rgba( dest );
		}
		src = AddPixelSize_a( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_a_rgb
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgb( &pix , src );
		rgb_to_a( &pix , b_color , pix );
		MulAlpha_a( &pix , alpha );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_rgb( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_a_rgba
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_rgba( &pix , src );
		rgba_to_a( &pix , b_color , pix );
		MulAlpha_a( &pix , alpha );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_rgba( src );
	}
}
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m_alpha_a_a
		(
		void*			dest , 
		int32			pitchbyte , 
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	int32		samplenum	= 1 << sft_samplenum;
	int		off;
	for( off = 0 ; off < len ; off++ )
	{
		pp_pixel_calc	pix;
		LoadAddr_a( &pix , src );
		a_to_a( &pix , b_color , pix );
		MulAlpha_a( &pix , alpha );
		a_to_a( &pix , pix );
		
		int		ddx;
		for( ddx = 0 ; ddx < samplenum ; ddx++ )
		{
			void	*pd	= dest;
			int		ddy;
			for( ddy = 0 ; ddy < samplenum ; ddy++ )
			{
				StoreAddr_a( pd , pix );
				pd	= ( uint8* )pd + pitchbyte;
			}
			dest	= AddPixelSize_a( dest );
		}
		src = AddPixelSize_a( src );
	}
}

//=================================================================================================
//!	oversample
//!	@retval			---
//-------------------------------------------------------------------------------------------------
cb_inline
void pp_cpp_oversample_m
		(
		pp_format		destformat , 
		void*			dest , 
		int32			pitchbyte , 
		pp_format		srcformat ,
		const void*		src , 
		int32			len , 
		int32			sft_samplenum , 
		const pp_color&	b_color , 
		const pp_alpha&	alpha
		)
{
	typedef void (*func_m)( void* , int32 , const void* , int32 , int32 , const pp_color& );
	typedef void (*func_m_a)( void* , int32 , const void* , int32 , int32 , const pp_color& , const pp_alpha& );

	static
	func_m	funclist_m[4][4] = 
	{	
		{
		pp_cpp_oversample_m_rgb_rgb , 
		pp_cpp_oversample_m_rgb_rgba , 
		pp_cpp_oversample_m_rgb_a , 
		} , 
		{
		pp_cpp_oversample_m_rgba_rgb , 
		pp_cpp_oversample_m_rgba_rgba , 
		pp_cpp_oversample_m_rgba_a , 
		} , 
		{
		pp_cpp_oversample_m_a_rgb , 
		pp_cpp_oversample_m_a_rgba , 
		pp_cpp_oversample_m_a_a , 
		} , 
	};
	static
	func_m_a	funclist_m_a[4][4] = 
	{	
		{
		pp_cpp_oversample_m_alpha_rgb_rgb , 
		pp_cpp_oversample_m_alpha_rgb_rgba , 
		pp_cpp_oversample_m_alpha_rgb_a , 
		} , 
		{
		pp_cpp_oversample_m_alpha_rgba_rgb , 
		pp_cpp_oversample_m_alpha_rgba_rgba , 
		pp_cpp_oversample_m_alpha_rgba_a , 
		} , 
		{
		pp_cpp_oversample_m_alpha_a_rgb , 
		pp_cpp_oversample_m_alpha_a_rgba , 
		pp_cpp_oversample_m_alpha_a_a , 
		} , 
	};
	if( alpha.a == 256 )
		( funclist_m[ destformat ][ srcformat ] )( dest , pitchbyte , src , len , sft_samplenum , b_color );
	else
		( funclist_m_a[ destformat ][ srcformat ] )( dest , pitchbyte , src , len , sft_samplenum , b_color , alpha );
}


};	//namespace

//using namespace icubic;		

#pragma pack( pop )			//release align

