#include"CPlaneTransiter.h"
#include"../../../Color.h"
#include"../../../../Auxiliary/Debug/CWarning.h"
#include"../../../../Auxiliary/Debug/CAssert.h"

#include"Transiteralgorithm.h"
#include"PixelEffect.h"

namespace Maid
{
namespace CPlaneTransiter
{
	void ClipRect( const RECT2DI& Dst, const RECT2DI& Src )
	{
		//	みじっそー
	}

	//	↓ DXT を普通のピクセルフォーマットに変換するルーチンなんですが
	//	特許に引っかかるような気がするのでコメントアウト
	//	DXlib の関数でも DXTは変換できるので、そっちをつかうのが安全

/*
	struct SURFACEBLOCK_COLOR
	{
		COLOR_RGB565	Color0;
		COLOR_RGB565	Color1;
		unt32	Pixel;

		unt32 GetPixel( unt32 pos ) const { return (Pixel>>(pos*2))&0x03; }
		unt32 GetPixel( unt32 x, unt32 y ) const { return GetPixel( y*4+x ); }

		void GetPalette( COLOR_ARGB8888* pal, bool IsDXT1 ) const 
		{
			if( (Color0 > Color1) || !IsDXT1 )
			{	//	alpha 無し
				pal[0] = Color0;
				pal[1] = Color1;
				pal[2] = COLOR_ARGB8888(0xFF,
											Color0.GetR()*2/3 + Color1.GetR()*1/3,
											Color0.GetG()*2/3 + Color1.GetG()*1/3,
											Color0.GetB()*2/3 + Color1.GetB()*1/3 );
				pal[3] = COLOR_ARGB8888(0xFF,
											Color0.GetR()*1/3 + Color1.GetR()*2/3,
											Color0.GetG()*1/3 + Color1.GetG()*2/3,
											Color0.GetB()*1/3 + Color1.GetB()*2/3 );
			}else
			{	//	1 bit alpha
				pal[0] = Color0;
				pal[1] = Color1;
				pal[2] = COLOR_ARGB8888(0xFF,
											(Color0.GetR() + Color1.GetR())/2,
											(Color0.GetG() + Color1.GetG())/2,
											(Color0.GetB() + Color1.GetB())/2 );
				pal[3] = pal[2];
				pal[3].SetA( 0x00 );	//	index3は透過色なので色は自由でいいが、一応近い色を入れておく

			}
		}
	};

	struct SURFACEBLOCK_ALPHA1	// DXT2, DXT3 用α
	{
		unt16	Alpha[4];

		unt08 GetAlpha( unt32 pos ) const
		{
			const unt08 a = (Alpha[pos/4]>>(pos%4*4))&0x0F; 
			return (a<<4) | a;
		}
		unt08 GetAlpha( unt32 x, unt32 y ) const { return GetAlpha( y*4+x ); }
	};

	struct SURFACEBLOCK_ALPHA2	// DXT4, DXT5 用α
	{
		unt08	Alpha0;
		unt08	Alpha1;
		unt08	Pixel[6];

		void GetPalette( unt08* pal ) const
		{
			pal[0] = Alpha0;
			pal[1] = Alpha1;
			if (Alpha0 > Alpha1) 
			{    
				pal[2] = (6 * Alpha0 + 1 * Alpha1 + 3) / 7;    // bit code 010
				pal[3] = (5 * Alpha0 + 2 * Alpha1 + 3) / 7;    // bit code 011
				pal[4] = (4 * Alpha0 + 3 * Alpha1 + 3) / 7;    // bit code 100
				pal[5] = (3 * Alpha0 + 4 * Alpha1 + 3) / 7;    // bit code 101
				pal[6] = (2 * Alpha0 + 5 * Alpha1 + 3) / 7;    // bit code 110
				pal[7] = (1 * Alpha0 + 6 * Alpha1 + 3) / 7;    // bit code 111  
			}    
			else
			{  
				pal[2] = (4 * Alpha0 + 1 * Alpha1 + 2) / 5;    // Bit code 010
				pal[3] = (3 * Alpha0 + 2 * Alpha1 + 2) / 5;    // Bit code 011
				pal[4] = (2 * Alpha0 + 3 * Alpha1 + 2) / 5;    // Bit code 100
				pal[5] = (1 * Alpha0 + 4 * Alpha1 + 2) / 5;    // Bit code 101
				pal[6] = 0;                                      // Bit code 110
				pal[7] = 255;                                    // Bit code 111
			}
		}

		unt32 GetIndex( unt32 pos ) const
		{
			__int64& r = *(__int64*)&Alpha0;
			return (r >> (pos*3+16)) & 0x07;

		}
		unt32 GetIndex( unt32 x, unt32 y ) const { return GetIndex( y*4+x ); }

	};



		template <class DSTFORMAT, class FUNCTOR>
		void DecodeTransitDXT1( DSTFORMAT DstFmt, SPSURFACEBUFFERINFO& pDstPlane, int32 DstX, int32 DstY, int32 DstW, int32 DstH,
								SPSURFACEBUFFERINFO& pSrcPlane, int32 SrcX, int32 SrcY,
								FUNCTOR	Fn )
		{
			const unt32 SrcSize   = pSrcPlane->GetWidth() * pSrcPlane->GetHeight() * GetPixelBPP(pSrcPlane->GetPixelFormat()) / 8;
			const unt32 BlockSize = SrcSize / (64/8);	// dxt1 は 64bit で 16pixel

			const unt32 DstBlockWidth = DstW / 4;

			//	各ブロックごとに展開していく
			for( unt32 NowBlock=0; NowBlock<BlockSize; ++NowBlock )
			{
				const SURFACEBLOCK_COLOR* Src= (SURFACEBLOCK_COLOR*)((unt08*)pSrcPlane->GetAddress()+NowBlock*(64/8));
				COLOR_ARGB8888	pal[4];
				
				pSrc->GetPalette( pal, true );

				const unt32 BaseX = DstX + (NowBlock%DstBlockWidth) * 4;
				const unt32 BaseY = DstY + (NowBlock/DstBlockWidth) * 4;
				for( unt32 i=0; i<4; ++i )
				{
					//	4pixel まとめてコピーしてしまう
					DSTFORMAT* pDst = (DSTFORMAT*)((unt08*)pDstPlane->GetLinePtr(BaseY+i) + sizeof(DSTFORMAT)*BaseX );

					Fn( pDst[0] , pal[pSrc->GetPixel(0,i)] );
					Fn( pDst[1] , pal[pSrc->GetPixel(1,i)] );
					Fn( pDst[2] , pal[pSrc->GetPixel(2,i)] );
					Fn( pDst[3] , pal[pSrc->GetPixel(3,i)] );
				}
			}
		}


		template <class DSTFORMAT, class FUNCTOR>
		void DecodeTransitDXT2( DSTFORMAT DstFmt, SPSURFACEBUFFERINFO& pDstPlane, int32 DstX, int32 DstY, int32 DstW, int32 DstH,
								SPSURFACEBUFFERINFO& pSrcPlane, int32 SrcX, int32 SrcY,
								FUNCTOR	Fn )
		{
			const unt32 SrcSize   = pSrcPlane->GetWidth() * pSrcPlane->GetHeight() * GetPixelBPP(pSrcPlane->GetPixelFormat()) / 8;
			const unt32 BlockSize = SrcSize / (128/8);	// dxt4 は 128bit で 16pixel

			//	各ブロックごとに展開していく
			for( unt32 NowBlock=0; NowBlock<BlockSize; ++NowBlock )
			{
				const SURFACEBLOCK_ALPHA1* pAlpha = (SURFACEBLOCK_ALPHA1*)((unt08*)pSrcPlane->GetAddress()+NowBlock*(128/8));
				const SURFACEBLOCK_COLOR* Src= (SURFACEBLOCK_COLOR*)((unt08*)pAlpha + sizeof(SURFACEBLOCK_ALPHA2));
				COLOR_ARGB8888	pal[4];
				
				pSrc->GetPalette( pal, false );

				const unt32 BaseX = DstX + (NowBlock*4) % pDstPlane->GetWidth();
				const unt32 BaseY = DstY + ((NowBlock*4) / pDstPlane->GetWidth()) * 4;
				for( unt32 i=0; i<4; ++i )
				{
					//	4pixel まとめてコピーしてしまう
					DSTFORMAT* pDst = (DSTFORMAT*)((unt08*)pDstPlane->GetLinePtr(BaseY+i) + sizeof(DSTFORMAT)*BaseX );

					Fn( pDst[0] , pal[pSrc->GetPixel(0,i)] );
					Fn( pDst[1] , pal[pSrc->GetPixel(1,i)] );
					Fn( pDst[2] , pal[pSrc->GetPixel(2,i)] );
					Fn( pDst[3] , pal[pSrc->GetPixel(3,i)] );
					pDst[0].SetA( pAlpha->GetAlpha(0,i) );
					pDst[1].SetA( pAlpha->GetAlpha(1,i) );
					pDst[2].SetA( pAlpha->GetAlpha(2,i) );
					pDst[3].SetA( pAlpha->GetAlpha(3,i) );
				}
			}
		}

		template <class DSTFORMAT, class FUNCTOR>
		void DecodeTransitDXT4( DSTFORMAT DstFmt, SPSURFACEBUFFERINFO& pDstPlane, int32 DstX, int32 DstY, int32 DstW, int32 DstH,
								SPSURFACEBUFFERINFO& pSrcPlane, int32 SrcX, int32 SrcY,
								FUNCTOR	Fn )
		{
			const unt32 SrcSize   = pSrcPlane->GetWidth() * pSrcPlane->GetHeight() * GetPixelBPP(pSrcPlane->GetPixelFormat()) / 8;
			const unt32 BlockSize = SrcSize / (128/8);	// dxt4 は 128bit で 16pixel

			//	各ブロックごとに展開していく
			for( unt32 NowBlock=0; NowBlock<BlockSize; ++NowBlock )
			{
				const SURFACEBLOCK_ALPHA2* pAlpha = (SURFACEBLOCK_ALPHA2*)((unt08*)pSrcPlane->GetAddress()+NowBlock*(128/8));
				const SURFACEBLOCK_COLOR* Src= (SURFACEBLOCK_COLOR*)((unt08*)pAlpha + sizeof(SURFACEBLOCK_ALPHA2));
				COLOR_ARGB8888	pal[4];
				unt08				alp[8];
				
				pSrc->GetPalette( pal, false );
				pAlpha->GetPalette( alp );

				const unt32 BaseX = DstX + (NowBlock*4) % pDstPlane->GetWidth();
				const unt32 BaseY = DstY + ((NowBlock*4) / pDstPlane->GetWidth()) * 4;
				for( unt32 i=0; i<4; ++i )
				{
					//	4pixel まとめてコピーしてしまう
					DSTFORMAT* pDst = (DSTFORMAT*)((unt08*)pDstPlane->GetLinePtr(BaseY+i) + sizeof(DSTFORMAT)*BaseX );

					Fn( pDst[0] , pal[pSrc->GetPixel(0,i)] );
					Fn( pDst[1] , pal[pSrc->GetPixel(1,i)] );
					Fn( pDst[2] , pal[pSrc->GetPixel(2,i)] );
					Fn( pDst[3] , pal[pSrc->GetPixel(3,i)] );
					pDst[0].SetA( alp[pAlpha->GetIndex(0,i)] );
					pDst[1].SetA( alp[pAlpha->GetIndex(1,i)] );
					pDst[2].SetA( alp[pAlpha->GetIndex(2,i)] );
					pDst[3].SetA( alp[pAlpha->GetIndex(3,i)] );
				}
			}
		}
*/

/*!
 	@class	CPlaneTransiter CPlaneTransiter.h
 	@brief	ピクセルフォーマット変換付転送クラス
\n			s3tc を 普通のピクセルに変換するルーチンは特許に引っ掛かるかもしれません
\n			http://appft1.uspto.gov/netacgi/nph-Parser?Sect1=PTO2&Sect2=HITOFF&p=1&u=%2Fnetahtml%2FPTO%2Fsearch-bool.html&r=4&f=G&l=50&co1=AND&d=PG01&s1=s3tc&OS=s3tc&RS=s3tc
\n			を参照しておきましょう。
 */


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 通常転送
/*!
 	拡縮もできます
 	転送元が圧縮サーフェイスの場合展開されます（圧縮サーフェイス->圧縮サーフェイスは対応していません)
 
 	@param	pDst		[ o]	転送先サーフェス
 	@param	pDstRC		[i ]	転送先範囲（ＮＵＬＬで全体）
 	@param	pSrc		[i ]	転送元サーフェス
 	@param	pSrcRC		[i ]	転送元範囲（ＮＵＬＬで全体）
 */
void Blt( ISurfaceBuffer& Dst, const RECT2DI* pDstRC, const ISurfaceBuffer& Src, const RECT2DI* pSrcRC )
{
	MAID_ASSERT( Dst.GetPixelFormat()==PIXELFORMAT_NONE, "転送先のピクセルフォーマットが不明" );
	MAID_ASSERT( Src.GetPixelFormat()==PIXELFORMAT_NONE, "転送元のピクセルフォーマットが不明" );

	SPSURFACEBUFFERINFO pSrcInfo;
	SPSURFACEBUFFERINFO pDstInfo;

	CSurfaceBufferLoacker SrcLock( const_cast<ISurfaceBuffer&>(Src), pSrcInfo );
	CSurfaceBufferLoacker DstLock( Dst, pDstInfo );

	RECT2DI DstRC = pDstRC==NULL? RECT2DI(0,0,pDstInfo->GetWidth(), pDstInfo->GetHeight()) : *pDstRC;
	RECT2DI SrcRC = pSrcRC==NULL? RECT2DI(0,0,pSrcInfo->GetWidth(), pSrcInfo->GetHeight()) : *pSrcRC;

	//	クリッピング処理・・・そのうちね(・ω・)

	ClipRect( DstRC, SrcRC );



	if( DstRC.GetSize()==SrcRC.GetSize() )
	{	//	等倍転送
		///////////////////////	手抜き用 define
		#define BLT_SRCFMT( SRC_COLOR )			\
			switch( Dst.GetPixelFormat() )	\
			{									\
			case PIXELFORMAT_A08R08G08B08I:	{ TransiterAlgorithm::NormalTransit(	COLOR_A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																				SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X08R08G08B08I:	{ TransiterAlgorithm::NormalTransit(	COLOR_X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																				SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R08G08B08I:	{ TransiterAlgorithm::NormalTransit(	COLOR_R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																				SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A04R04G04B04I:	{ TransiterAlgorithm::NormalTransit(	COLOR_A04R04G04B04I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																				SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R05G06B05I:	{ TransiterAlgorithm::NormalTransit(	COLOR_R05G06B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																				SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X01R05G05B05I:	{ TransiterAlgorithm::NormalTransit(	COLOR_X01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																				SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A01R05G05B05I:	{ TransiterAlgorithm::NormalTransit(	COLOR_A01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																				SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_P08X08R08G08B08I:																								\
				{																														\
					COLOR_P08X08R08G08B08I::SetCLUTDst( (COLOR_X08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::NormalTransit(	COLOR_P08X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() );		\
				}break;																													\
			case PIXELFORMAT_P08A08R08G08B08I:																								\
				{																														\
					COLOR_P08A08R08G08B08I::SetCLUTDst( (COLOR_A08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::NormalTransit(	COLOR_P08A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, COLOR_COPY_SRC() );		\
				}break;																													\
			}
		#define BLT_SRCFMT_DXT( SRC_COLOR, func, type )			\
			switch( Dst.GetPixelFormat() )	\
			{									\
			case PIXELFORMAT_A08R08G08B08I:	{ func(	COLOR_A08R08G08B08I(),*pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_X08R08G08B08I:	{ func(	COLOR_X08R08G08B08I(),*pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_R08G08B08I:	{ func(	COLOR_R08G08B08I(),  *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_A04R04G04B04I:	{ func(	COLOR_A04R04G04B04I(),*pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_R05G06B05I:	{ func(	COLOR_R05G06B05I(),  *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_X01R05G05B05I:	{ func(	COLOR_X01R05G05B05I(),*pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_A01R05G05B05I:	{ func(	COLOR_A01R05G05B05I(),*pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																	*pSrcInfo, SrcRC.x, SrcRC.y, type() ); }break;	\
			case PIXELFORMAT_P08X08R08G08B08I:																								\
				{																														\
					COLOR_P08X08R08G08B08I::SetCLUTDst( (COLOR_X08R08G08B08I*)pDstInfo->GetCLUT() );								\
					func(	COLOR_P08X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														*pSrcInfo, SrcRC.x, SrcRC.y, type() );		\
				}break;																													\
			case PIXELFORMAT_P08ARGB8888:																								\
				{																														\
					COLOR_P08A08R08G08B08I::SetCLUTDst( (COLOR_A08R08G08B08I*)pDstInfo->GetCLUT() );								\
					func(	COLOR_P08A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														*pSrcInfo, SrcRC.x, SrcRC.y, type() );		\
				}break;																													\
			}
		/////////////////////	手抜き用 define 終了

		switch( Src.GetPixelFormat() )
		{
		case PIXELFORMAT_A08R08G08B08I:		{ BLT_SRCFMT( COLOR_A08R08G08B08I ); }break;
		case PIXELFORMAT_X08R08G08B08I:		{ BLT_SRCFMT( COLOR_X08R08G08B08I ); }break;
		case PIXELFORMAT_R08G08B08I:		{ BLT_SRCFMT( COLOR_R08G08B08I   ); }break;
		case PIXELFORMAT_A04R04G04B04I:		{ BLT_SRCFMT( COLOR_A04R04G04B04I ); }break;
		case PIXELFORMAT_R05G06B05I:		{ BLT_SRCFMT( COLOR_R05G06B05I   ); }break;
		case PIXELFORMAT_X01R05G05B05I:		{ BLT_SRCFMT( COLOR_X01R05G05B05I ); }break;
		case PIXELFORMAT_A01R05G05B05I:		{ BLT_SRCFMT( COLOR_A01R05G05B05I ); }break;
		case PIXELFORMAT_P08X08R08G08B08I:	{ COLOR_P08X08R08G08B08I::SetCLUTSrc( (COLOR_X08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08X08R08G08B08I  ); }break;
		case PIXELFORMAT_P08A08R08G08B08I:	{ COLOR_P08A08R08G08B08I::SetCLUTSrc( (COLOR_A08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08A08R08G08B08I  ); }break;
//		case PIXELFORMAT_DXT1:			{ BLT_SRCFMT_DXT( PIXELFORMAT_DXT1, DecodeTransitDXT1, COLOR_COPY_SRC );	}break;
//		case PIXELFORMAT_DXT2:			{ BLT_SRCFMT_DXT( PIXELFORMAT_DXT2, DecodeTransitDXT2, COLOR_COPY_SRC );	}break;
//		case PIXELFORMAT_DXT3:			{ BLT_SRCFMT_DXT( PIXELFORMAT_DXT3, DecodeTransitDXT2, COLOR_COPY_SRC );	}break;
//		case PIXELFORMAT_DXT4:			{ BLT_SRCFMT_DXT( PIXELFORMAT_DXT4, DecodeTransitDXT4, COLOR_COPY_SRC );	}break;
//		case PIXELFORMAT_DXT5:			{ BLT_SRCFMT_DXT( PIXELFORMAT_DXT5, DecodeTransitDXT4, COLOR_COPY_SRC );	}break;
		}

		#undef BLT_SRCFMT		//	define は切っておく
		#undef BLT_SRCFMT_DXT	//	define は切っておく
	}else
	{	//	拡縮転送
		///////////////////////	手抜き用 define
		#define BLT_SRCFMT( SRC_COLOR )			\
			switch( Dst.GetPixelFormat() )	\
			{									\
			case PIXELFORMAT_A08R08G08B08I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X08R08G08B08I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R08G08B08I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A04R04G04B04I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_A04R04G04B04I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R05G06B05I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_R05G06B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X01R05G05B05I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_X01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A01R05G05B05I:	{ TransiterAlgorithm::ScaleTransit(	COLOR_A01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_P08X08R08G08B08I:																								\
				{																														\
					COLOR_P08X08R08G08B08I::SetCLUTDst( (COLOR_X08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::ScaleTransit(	COLOR_P08X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() );		\
				}break;																													\
			case PIXELFORMAT_P08A08R08G08B08I:																								\
				{																														\
					COLOR_P08A08R08G08B08I::SetCLUTDst( (COLOR_A08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::ScaleTransit(	COLOR_P08A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() );		\
				}break;																													\
			}
		/////////////////////	手抜き用 define 終了

		switch( Src.GetPixelFormat() )
		{
		case PIXELFORMAT_A08R08G08B08I:  { BLT_SRCFMT( COLOR_A08R08G08B08I ); }break;
		case PIXELFORMAT_X08R08G08B08I:	{ BLT_SRCFMT( COLOR_X08R08G08B08I ); }break;
		case PIXELFORMAT_R08G08B08I:	{ BLT_SRCFMT( COLOR_R08G08B08I   ); }break;
		case PIXELFORMAT_A04R04G04B04I:	{ BLT_SRCFMT( COLOR_A04R04G04B04I ); }break;
		case PIXELFORMAT_R05G06B05I:	{ BLT_SRCFMT( COLOR_R05G06B05I   ); }break;
		case PIXELFORMAT_X01R05G05B05I:  { BLT_SRCFMT( COLOR_X01R05G05B05I ); }break;
		case PIXELFORMAT_A01R05G05B05I:	{ BLT_SRCFMT( COLOR_A01R05G05B05I ); }break;
		case PIXELFORMAT_P08X08R08G08B08I:{ COLOR_P08X08R08G08B08I::SetCLUTSrc( (COLOR_X08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08X08R08G08B08I  ); }break;
		case PIXELFORMAT_P08A08R08G08B08I:{ COLOR_P08A08R08G08B08I::SetCLUTSrc( (COLOR_A08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08A08R08G08B08I  ); }break;
		}

		#undef BLT_SRCFMT		//	define は切っておく

	}
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! サーフェスを固定色で塗りつぶします
/*!
 	拡縮もできます
 
 	@param	Dst		[ o]	転送先サーフェス
 	@param	pDstRC	[i ]	転送先範囲（ＮＵＬＬで全体）
 	@param	Color	[i ]	塗りつぶす色
 */
void Clear( ISurfaceBuffer& Dst, const RECT2DI* pDstRC, const COLOR_A08R08G08B08I& Color )
{
	MAID_ASSERT( Dst.GetPixelFormat()==PIXELFORMAT_NONE, "ピクセルフォーマットが不明" );

	SPSURFACEBUFFERINFO   pDstInfo;
	CSurfaceBufferLoacker DstLock( Dst, pDstInfo );

	const RECT2DI DstRC = pDstRC==NULL? RECT2DI(0,0,pDstInfo->GetWidth(), pDstInfo->GetHeight()) : *pDstRC;

	#define BLT_DSTFMT( DST_COLOR ); TransiterAlgorithm::SingleEffect( DST_COLOR(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, COLOR_COPY_CONST<DST_COLOR>(Color) )

	switch( Dst.GetPixelFormat() )
	{
	case PIXELFORMAT_A08R08G08B08I:  { BLT_DSTFMT( COLOR_A08R08G08B08I ); }break;
	case PIXELFORMAT_X08R08G08B08I:	{ BLT_DSTFMT( COLOR_X08R08G08B08I ); }break;
	case PIXELFORMAT_R08G08B08I:	{ BLT_DSTFMT( COLOR_R08G08B08I ); }break;
	case PIXELFORMAT_A04R04G04B04I:	{ BLT_DSTFMT( COLOR_A04R04G04B04I ); }break;
	case PIXELFORMAT_R05G06B05I:	{ BLT_DSTFMT( COLOR_R05G06B05I   ); }break;
	case PIXELFORMAT_X01R05G05B05I:  { BLT_DSTFMT( COLOR_X01R05G05B05I ); }break;
	case PIXELFORMAT_A01R05G05B05I:	{ BLT_DSTFMT( COLOR_A01R05G05B05I ); }break;
	case PIXELFORMAT_P08X08R08G08B08I:{ COLOR_P08X08R08G08B08I::SetCLUTDst( (COLOR_X08R08G08B08I*)pDstInfo->GetCLUT() ); BLT_DSTFMT( COLOR_P08X08R08G08B08I  ); }break;
	case PIXELFORMAT_P08A08R08G08B08I:{ COLOR_P08A08R08G08B08I::SetCLUTDst( (COLOR_A08R08G08B08I*)pDstInfo->GetCLUT() ); BLT_DSTFMT( COLOR_P08A08R08G08B08I  ); }break;
	}
	#undef BLT_DSTFMT		//	define は切っておく
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! サーフェスをバイリニア法により拡縮させます
/*!
 	@param	Dst		[ o]	転送先サーフェス
 	@param	pDstRC		[i ]	転送先範囲（ＮＵＬＬで全体）
 	@param	Src		[i ]	転送元サーフェス
 	@param	pSrcRC		[i ]	転送元範囲（ＮＵＬＬで全体）
 */
void BltBiliner( ISurfaceBuffer& Dst, const RECT2DI* pDstRC, const ISurfaceBuffer& Src, const RECT2DI* pSrcRC )
{
	MAID_ASSERT( Dst.GetPixelFormat()==PIXELFORMAT_NONE, "転送先のピクセルフォーマットが不明" );
	MAID_ASSERT( Src.GetPixelFormat()==PIXELFORMAT_NONE, "転送元のピクセルフォーマットが不明" );

	SPSURFACEBUFFERINFO pSrcInfo;
	SPSURFACEBUFFERINFO pDstInfo;

	CSurfaceBufferLoacker SrcLock( const_cast<ISurfaceBuffer&>(Src), pSrcInfo );
	CSurfaceBufferLoacker DstLock( Dst, pDstInfo );


	RECT2DI DstRC = pDstRC==NULL? RECT2DI(0,0,pDstInfo->GetWidth(), pDstInfo->GetHeight()) : *pDstRC;
	RECT2DI SrcRC = pSrcRC==NULL? RECT2DI(0,0,pSrcInfo->GetWidth(), pSrcInfo->GetHeight()) : *pSrcRC;

	ClipRect( DstRC, SrcRC );


	if( (DstRC.w==SrcRC.w) && (DstRC.h==SrcRC.h) )
	{	//	等倍ならいつもの転送をします。
		return Blt( Dst, &DstRC, Src, &SrcRC );
	}else
	{
		///////////////////////	手抜き用 define
		#define BLT_SRCFMT( SRC_COLOR )			\
			switch( Dst.GetPixelFormat() )	\
			{									\
			case PIXELFORMAT_A08R08G08B08I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X08R08G08B08I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R08G08B08I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A04R04G04B04I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_A04R04G04B04I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_R05G06B05I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_R05G06B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h, 		\
																			SRC_COLOR(),   *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_X01R05G05B05I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_X01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_A01R05G05B05I:	{ TransiterAlgorithm::BilinerTransit(	COLOR_A01R05G05B05I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,		\
																			SRC_COLOR(), *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() ); }break;	\
			case PIXELFORMAT_P08X08R08G08B08I:																								\
				{																														\
					COLOR_P08X08R08G08B08I::SetCLUTDst( (COLOR_X08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::BilinerTransit(	COLOR_P08X08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() );		\
				}break;																													\
			case PIXELFORMAT_P08A08R08G08B08I:																								\
				{																														\
					COLOR_P08A08R08G08B08I::SetCLUTDst( (COLOR_A08R08G08B08I*)pDstInfo->GetCLUT() );								\
					TransiterAlgorithm::BilinerTransit(	COLOR_P08A08R08G08B08I(), *pDstInfo, DstRC.x, DstRC.y, DstRC.w, DstRC.h,	\
														SRC_COLOR(),  *pSrcInfo, SrcRC.x, SrcRC.y, SrcRC.w, SrcRC.h, COLOR_COPY_SRC() );		\
				}break;																													\
			}
		/////////////////////	手抜き用 define 終了

		switch( Src.GetPixelFormat() )
		{
		case PIXELFORMAT_A08R08G08B08I:	{ BLT_SRCFMT( COLOR_A08R08G08B08I ); }break;
		case PIXELFORMAT_X08R08G08B08I:	{ BLT_SRCFMT( COLOR_X08R08G08B08I ); }break;
		case PIXELFORMAT_R08G08B08I:	{ BLT_SRCFMT( COLOR_R08G08B08I   ); }break;
		case PIXELFORMAT_A04R04G04B04I:	{ BLT_SRCFMT( COLOR_A04R04G04B04I ); }break;
		case PIXELFORMAT_R05G06B05I:	{ BLT_SRCFMT( COLOR_R05G06B05I   ); }break;
		case PIXELFORMAT_X01R05G05B05I:	{ BLT_SRCFMT( COLOR_X01R05G05B05I ); }break;
		case PIXELFORMAT_A01R05G05B05I:	{ BLT_SRCFMT( COLOR_A01R05G05B05I ); }break;
		case PIXELFORMAT_P08X08R08G08B08I:{ COLOR_P08X08R08G08B08I::SetCLUTSrc( (COLOR_X08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08X08R08G08B08I  ); }break;
		case PIXELFORMAT_P08A08R08G08B08I:{ COLOR_P08A08R08G08B08I::SetCLUTSrc( (COLOR_A08R08G08B08I*)pSrcInfo->GetCLUT() ); BLT_SRCFMT( COLOR_P08A08R08G08B08I  ); }break;
		}

		#undef BLT_SRCFMT		//	define は切っておく

	}
}

}

}