
#include	"stdafx.h"
#include	"ImageBase.h"

//////////////////////////////////////////////////////////////////////////////////////////
//	コンストラクタ

CImageBase::CImageBase()
{
	m_bAlphaBlendRequirement = FALSE;
	m_bOutputDummyFromBuffer = FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	デストラクタ

CImageBase::~CImageBase()
{
}

//////////////////////////////////////////////////////////////////////////////////////////
//	初期化
/*
BOOL	CImageBase::OnInit(
	long				lWidth,							// 横幅
	long				lHeight,						// 縦幅
	WORD				wBpp,							// ビット数
	const void*			pvPallet,						// パレット
	DWORD				dwPalletSize,					// パレットサイズ
	WORD				wPalletBpp						// パレットのビット数
	)
{
	// メンバ変数の初期化

	m_bAlphaBlendRequirement = FALSE;
	m_wBppWithAlpha = 0;
	m_lLineWithAlpha = 0;
	m_lPitchWithAlpha = 0;

	// トップダウンをボトムアップに修正

	if( lHeight < 0 )
	{
		lHeight = -lHeight;
	}

	// ビット数ごとの処理

	switch( wBpp )
	{
	case	8:
		// 8bit

		OnCreatePallet( pvPallet, dwPalletSize );
		break;

	case	32:
		// 32bit

		if( GetValidityOfAlphaBlend() )
		{
			// アルファブレンドが有効

			m_bAlphaBlendRequirement = TRUE;
			m_wBppWithAlpha = wBpp;
			m_lLineWithAlpha = (lWidth * (wBpp >> 3));
			m_lPitchWithAlpha = CalculatePitch( lWidth, wBpp );

			wBpp = 24;
		}

		break;
	}

	// パラメータの設定

	m_wBpp = wBpp;
	m_lWidth = lWidth;
	m_lHeight = lHeight;
	m_lLine = lWidth * (wBpp >> 3);
	m_lPitch = CalculatePitch( lWidth, wBpp );

	DWORD				dwOriginSize = pclArc->GetOpenFileInfo()->sizeOrg;

	m_dwRowSize = dwOriginSize / lHeight;
	m_dwRowSizeOfRemainder = dwOriginSize % lHeight;

	return	TRUE;
}
*/

//////////////////////////////////////////////////////////////////////////////////////////
//	初期化

BOOL	CImageBase::Init(
	CArcFile*			pclArc,							// アーカイブ
	long				lWidth,							// 横幅
	long				lHeight,						// 縦幅
	WORD				wBpp,							// ビット数
	const void*			pvPallet,						// パレット
	DWORD				dwPalletSize,					// パレットサイズ
	const YCString&		rfclsFileName					// ファイル名
	)
{
	// トップダウンをボトムアップに修正

	if( lHeight < 0 )
	{
		lHeight = -lHeight;
	}

	switch( wBpp )
	{
	case	8:
		// 8bit

		OnCreatePallet( pvPallet, dwPalletSize );
		break;

	case	32:
		// 32bit

		if( pclArc->GetOpt()->bAlphaBlend )
		{
			// アルファブレンド要求あり

			m_bAlphaBlendRequirement = TRUE;
			wBpp = 24;

			for (int i = 0; i < 3; i++)
			{
				m_abtBG[i] = BYTE((pclArc->GetOpt()->BgRGB >> (i << 3)) & 0xFF);
			}
		}
	}

	m_wBpp = wBpp;
	m_pclArc = pclArc;
	m_lWidth = lWidth;
	m_lHeight = lHeight;
	m_lLine = lWidth * (wBpp >> 3);
	m_lPitch = CalculatePitch( lWidth, wBpp );
	m_lPitchWithAlpha = lWidth * 4;

	DWORD				dwOriginSize = pclArc->GetOpenFileInfo()->sizeOrg;

	m_dwRowSize = dwOriginSize / lHeight;
	m_dwRowSizeOfRemainder = dwOriginSize % lHeight;

	return		OnInit( rfclsFileName );
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファブレンドの有効性の設定

void	CImageBase::SetValidityOfAlphaBlend(
	BOOL				bValidityOfAlphaBlend			// アルファブレンドの有効性
	)
{
	m_bValidityOfAlphaBlend = bValidityOfAlphaBlend;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファブレンドの有効性の取得
//
//	return	アルファブレンドの有効性

BOOL	CImageBase::GetValidityOfAlphaBlend()
{
	return	m_bValidityOfAlphaBlend;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファブレンド時の背景色の設定

void	CImageBase::SetBackColorWhenAlphaBlend(
	COLORREF			crBackColor						// 背景色
	)
{
	m_unpBackColorWhenAlphaBlend.crPixel = crBackColor;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	横幅の取得

long	CImageBase::GetWidth()
{
	return	m_lWidth;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	縦幅の取得

long	CImageBase::GetHeight()
{
	return	m_lHeight;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	ビット数の取得

WORD	CImageBase::GetBitCount()
{
	return	m_wBpp;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファ付きビット数の取得

WORD	CImageBase::GetBitCountWithAlpha()
{
	return	m_wBppWithAlpha;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	ピッチの取得

long	CImageBase::GetPitch()
{
	return	m_lPitch;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファ付きピッチの取得

long	CImageBase::GetPitchWithAlpha()
{
	return	m_lPitchWithAlpha;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	圧縮

BOOL	CImageBase::Compress(
	LPCTSTR				pszPathToDst,					// 出力先ファイルパス
	const void*			pvBMP,							// ビットマップデータ
	DWORD				dwBMPSize						// ビットマップデータサイズ
	)
{

	return	TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	圧縮

BOOL	CImageBase::Compress(
	LPCTSTR				pszPathToDst,					// 出力先ファイルパス
	const void*			pvDIB,							// DIBデータ
	DWORD				dwDIBSize,						// DIBデータサイズ
	const void*			pvPallet,						// パレット
	DWORD				dwPalletSize,					// パレットサイズ
	WORD				wPalletBpp,						// パレットのビット数
	long				lWidth,							// 横幅
	long				lHeight,						// 縦幅
	WORD				wBpp							// ビット数
	)
{
/*	const BYTE*			pbtDIB = (const BYTE*) pvDIB;
	const BYTE*			pbtPallet = (const BYTE*) pvPallet;

	// 初期化

	OnInit( lWidth, lHeight, wBpp, pvPallet, dwPalletSize, wPalletBpp );

	// ヘッダの出力

	OnWriteHeader();

	// データの出力

	if( IsRequireAlphaBlend() )
	{
		// アルファブレンド要求あり

		long				lDstSizeAfterAlphaBlend = (GetPitch() + 2);	// アルファブレンド高速処理用に余分に確保

		YCMemory<BYTE>		clmDstAfterAlphaBlend( lDstSizeAfterAlphaBlend );

		ZeroMemory( &clmDstOfAfterAlphaBlend[0], lDstSizeAfterAlphaBlend );

		for( long lY = 0 ; lY < GetHeight() ; lY++ )
		{
			AlphaBlend( &clmDstAfeterAlphaBlend[0], pbtDIB, m_unpBackColorWhenAlphaBlend, lWidth );

			OnWriteLine( &clmDstAfeterAlphaBlend[0], GetPitch() );

			pbtDIB += GetPitchWithAlpha();
		}
	}
	else
	{
		// アルファブレンド要求なし

		long				lLine = m_lLine;

		if( dwBufferSize >= m_lPitch * m_lHeight )
		{
			// ダミーデータをバッファから読み込む

			m_bOutputDummyFromBuffer = TRUE;
			lLine = m_lPitch;
		}

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			OnWriteLine( pbtBuffer );
			pbtBuffer += lLine;
		}
	}

	OnWriteFinish();
*/
	return	TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	圧縮

BOOL	CImageBase::Compress(
	void*				pvDst,							// 格納先
	DWORD				dwDstSize,						// 格納先サイズ
	const void*			pvBMP,							// ビットマップデータ
	DWORD				dwBMPSize						// ビットマップデータサイズ
	)
{


	return	TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	圧縮

BOOL	CImageBase::Compress(
	void*				pvDst,							// 格納先
	DWORD				dwDstSize,						// 格納先サイズ
	const void*			pvDIB,							// DIBデータ
	DWORD				dwDIBSize,						// DIBデータサイズ
	const void*			pvPallet,						// パレット
	DWORD				dwPalletSize,					// パレットサイズ
	WORD				wPalletBpp,						// パレットのビット数
	long				lWidth,							// 横幅
	long				lHeight,						// 縦幅
	WORD				wBpp							// ビット数
	)
{
/*	BYTE*				pbtDst = (BYTE*) pvDst;
	const BYTE*			pbtDIB = (const BYTE*) pvDIB;
	const BYTE*			pbtPallet = (const BYTE*) pvPallet;

	// 初期化

	OnInit( lWidth, lHeight, wBpp, pvPallet, dwPalletSize, wPalletBpp );

	// ヘッダの出力

	OnWriteHeader();

	// データの出力

	if( IsRequireAlphaBlend() )
	{
		// アルファブレンド要求あり

		long				lDstSizeAfterAlphaBlend = (GetPitch() + 2);	// アルファブレンド高速処理用に余分に確保

		YCMemory<BYTE>		clmDstAfterAlphaBlend( lDstSizeAfterAlphaBlend );

		ZeroMemory( &clmDstOfAfterAlphaBlend[0], lDstSizeAfterAlphaBlend );

		for( long lY = 0 ; lY < GetHeight() ; lY++ )
		{
			AlphaBlend( &clmDstAfeterAlphaBlend[0], pbtDIB );

			OnWriteLine( 

			OnWriteLineWithAlphaBlending( &clmbtBuffer24[0], pbtBuffer );
			pbtBuffer += m_lLine32;
		}
	}
	else
	{
		// アルファブレンド要求なし

		long				lLine = m_lLine;

		if( dwBufferSize >= m_lPitch * m_lHeight )
		{
			// ダミーデータをバッファから読み込む

			m_bOutputDummyFromBuffer = TRUE;
			lLine = m_lPitch;
		}

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			OnWriteLine( pbtBuffer );
			pbtBuffer += lLine;
		}
	}

	OnWriteFinish();*/

	return	TRUE;
}





//////////////////////////////////////////////////////////////////////////////////////////
//	アルファブレンド要求の取得
//
//	return	アルファブレンド要求
//
//	備考	戻り値がTRUEの場合、必ずアルファブレンドを行うこと

BOOL	CImageBase::IsRequireAlphaBlend()
{
	return	m_bAlphaBlendRequirement;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	アルファブレンド

void	CImageBase::AlphaBlend(
	void*				pvBuffer24,						// 格納先
	const void*			pvBuffer32						// 32bitデータ
	)
{
	BYTE*				pbtBuffer24 = (BYTE*) pvBuffer24;
	const BYTE*			pbtBuffer32 = (const BYTE*) pvBuffer32;
	const BYTE*			pbtBG = m_abtBG;
	long				lWidth = m_lWidth;

	if( m_pclArc->GetOpt()->bFastAlphaBlend )
	{
		// アルファブレンド高速処理要求あり

		// eax	カウンタ
		// edi	出力先
		// esi	入力元
		//
		// mm0	入力データ1
		// mm1	入力データ2
		// mm2	入力データ1のアルファ値
		// mm3	入力データ2のアルファ値
		// mm4	ワーク
		// mm5	00FF00FF 00FF00FF
		// mm6	背景色
		// mm7	アンパック用(00000000 00000000)

		_asm
		{
			mov			edi, pvBuffer24
			mov			esi, pvBuffer32

			// アンパック用に初期化

			pxor		mm7, mm7

			// 背景色の取得

			mov			eax, pbtBG
			movd		mm6, [eax]
			punpcklbw	mm6, mm7

			// 

			mov			eax, 0x01000100
			movd		mm5, eax
			punpckldq	mm5, mm5

			// メインループ

			mov			eax, lWidth
			shr			eax, 1								// 2ピクセルずつ処理する

		loop2000:

			// 8バイト(2ピクセル)取得

			movq		mm0, [esi]
			movq		mm1, mm0

			add			esi, 8

			// アルファ値の取得
/*
			movq		mm2, mm0
			psrld		mm2, 24

			movq		mm3, mm2

			punpcklwd	mm2, mm2
			punpckldq	mm2, mm2

			punpckhwd	mm3, mm3
			punpckldq	mm3, mm3
*/
//-- 入力データ1 -------------------------------------------------------------------------

			// アンパック

			punpcklbw	mm0, mm7

			// アルファ値の取得

			movq		mm2, mm0
			psrlq		mm2, 48

			movd		edx, mm2
			test		edx, edx
			jnz			pass3200							// アルファ値が0ではない

			// アルファ値が0

			movq		mm0, mm6
			jmp			pass3800

			// アルファ値が1〜255

		pass3200:

			cmp			edx, 0xFF
			jne			pass3400							// アルファ値が255ではない

			// アルファ値が255

			jmp			pass3800

			// アルファ値が1〜254

		pass3400:

			punpcklwd	mm2, mm2
			punpckldq	mm2, mm2

			// RGB×A

			pmullw		mm0, mm2

			// 背景×(0xFF - A)

			movq		mm4, mm5
			psubw		mm4, mm2
			pmullw		mm4, mm6

			// 加算して256で割る

			paddw		mm0, mm4
			psrlw		mm0, 8

		pass3800:

			// 下位32bitにまとめる

			packuswb	mm0, mm7

			// 格納

			movd		[edi], mm0

//-- 入力データ2 -------------------------------------------------------------------------

			// アンパック

			punpckhbw	mm1, mm7

			// アルファ値の取得

			movq		mm3, mm1
			psrlq		mm3, 48

			movd		edx, mm3
			test		edx, edx
			jnz			pass4200							// アルファ値が0ではない

			// アルファ値が0

			movq		mm1, mm6
			jmp			pass4800

			// アルファ値が1〜255

		pass4200:

			cmp			edx, 0xFF
			jne			pass4400							// アルファ値が255ではない

			// アルファ値が255

			jmp			pass4800

		pass4400:

			punpcklwd	mm3, mm3
			punpckldq	mm3, mm3

			// RGB×A

			pmullw		mm1, mm3

			// 背景×(0xFF - A)

			movq		mm4, mm5
			psubw		mm4, mm3
			pmullw		mm4, mm6

			// 加算して256で割る

			paddw		mm1, mm4
			psrlw		mm1, 8

		pass4800:

			// 下位32bitにまとめる

			packuswb	mm1, mm7

			// 格納

			movd		[edi + 3], mm1
//			movntq		[edi], mm1
			add			edi, 6

//----------------------------------------------------------------------------------------

			// 次のピクセルへ

			dec			eax
			jnz			loop2000							// 継続

			// 残りの1ピクセルを処理

			mov			eax, lWidth
			and			eax, 1
			jz			pass9900							// 未処理のピクセルなし

			// 4バイト(1ピクセル)取得

			movd		mm0, [esi]

			// アンパック

			punpcklbw	mm0, mm7

			// アルファ値の取得

			movq		mm2, mm0
			psrlq		mm2, 48
			punpcklwd	mm2, mm2
			punpckldq	mm2, mm2

			// RGB×A

			pmullw		mm0, mm2

			// 背景×(0xFF - A)

			movq		mm4, mm5
			psubw		mm4, mm2
			pmullw		mm4, mm6

			// 加算して256で割る

			paddw		mm0, mm4
			psrlw		mm0, 8

			// 下位32bitにまとめる

			packuswb	mm0, mm7

			// 格納

			movd		[edi], mm0

			// 終了

		pass9900:

			emms
		}
	}
	else
	{
		for( long lX = 0 ; lX < lWidth ; lX++ )
		{
			switch( pbtBuffer32[3] )
			{
			case	0x00:
				// アルファ値が0

				for( int i = 0 ; i < 3 ; i++ )
				{
					*pbtBuffer24++ = pbtBG[i];
				}

				break;

			case	0xFF:
				// アルファ値が255

				for( int i = 0 ; i < 3 ; i++ )
				{
					*pbtBuffer24++ = pbtBuffer32[i];
				}

				break;

			default:
				// その他

				for( int i = 0 ; i < 3 ; i++ )
				{
					*pbtBuffer24++ = (pbtBuffer32[i] * pbtBuffer32[3] + pbtBG[i] * (255 - pbtBuffer32[3])) / 255;
//					*pbtBuffer24++ = (pbtBuffer32[i] - pbtBG[i]) * pbtBuffer32[3] / 255 + pbtBG[i];
				}
			}

			pbtBuffer32 += 4;
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
//	出力

void	CImageBase::Write(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	const BYTE*			pbtBuffer = (const BYTE*) pvBuffer;

	if( !bProgress )
	{
		// プログレスバーを進めない(複数出力対策)

		m_dwRowSize = 0;
		m_dwRowSizeOfRemainder = 0;
	}

	// 出力

	if( IsRequireAlphaBlend() )
	{
		// アルファブレンディング要求あり

		YCMemory<BYTE>		clmbtBuffer24( m_lPitch + 2 );

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			WriteLineWithAlphaBlend( &clmbtBuffer24[0], pbtBuffer );
			pbtBuffer += GetPitchWithAlpha();
		}
	}
	else
	{
		long				lLine = m_lLine;

		if( dwBufferSize >= m_lPitch * m_lHeight )
		{
			// ダミーデータをバッファから読み込む

			m_bOutputDummyFromBuffer = TRUE;
			lLine = m_lPitch;
		}

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			WriteLine( pbtBuffer );
			pbtBuffer += lLine;
		}
	}

	WriteFinish();
}

//////////////////////////////////////////////////////////////////////////////////////////
//	上下反転して出力

void	CImageBase::WriteReverse(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	const BYTE*			pbtBuffer = (const BYTE*) pvBuffer;

	if( !bProgress )
	{
		// プログレスバーを進めない(複数出力対策)

		m_dwRowSize = 0;
		m_dwRowSizeOfRemainder = 0;
	}

	if( IsRequireAlphaBlend() )
	{
		// アルファブレンディング要求あり

		// 24bit用のバッファ確保

		YCMemory<BYTE>		clmbtBuffer24( m_lPitch + 2 );

		pbtBuffer += GetPitchWithAlpha() * m_lHeight;

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			pbtBuffer -= GetPitchWithAlpha();
			WriteLineWithAlphaBlend( &clmbtBuffer24[0], pbtBuffer );
		}
	}
	else
	{
		long				lLine = m_lLine;

		if( dwBufferSize >= m_lPitch * m_lHeight )
		{
			// ダミーデータをバッファから読み込む

			m_bOutputDummyFromBuffer = TRUE;
			lLine = m_lPitch;
		}

		pbtBuffer += lLine * m_lHeight;

		for( long lY = 0 ; lY < m_lHeight ; lY++ )
		{
			pbtBuffer -= lLine;
			WriteLine( pbtBuffer );
		}
	}

	WriteFinish();
}	

//////////////////////////////////////////////////////////////////////////////////////////
//	BGRAを合成

BOOL	CImageBase::ComposeBGRA(
	void*				pvDst,							// 格納先
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize					// データサイズ
	)
{
	BYTE*				pbtDst = (BYTE*) pvDst;
	const BYTE*			pbtBuffer = (const BYTE*) pvBuffer;
	WORD				wBpp = IsRequireAlphaBlend() ? 32 : m_wBpp;

	if( (wBpp == 24) || (wBpp == 32) )
	{
		// 24bitと32bitのみサポート

		WORD				wByteCount = (wBpp >> 3);
		DWORD				dwColorSize = dwBufferSize / wByteCount;

		// B,G,R,Aそれぞれへのポインタ取得

		const BYTE*			apbtBGRA[4];

		for( WORD i = 0 ; i < wByteCount ; i++ )
		{
			apbtBGRA[i] = &pbtBuffer[dwColorSize * i];
		}

		// BGRAを合成

		for( DWORD i = 0 ; i < dwColorSize ; i++ )
		{
			for( WORD j = 0 ; j < wByteCount ; j++ )
			{
				*pbtDst++ = *apbtBGRA[j]++;
			}
		}

		return	TRUE;
	}

	return	FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	BGRAを合成して出力

void	CImageBase::WriteCompoBGRA(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	// 合成データ格納用メモリの確保

	YCMemory<BYTE>		clmbtDst( dwBufferSize );

	// 合成

	if( ComposeBGRA( &clmbtDst[0], pvBuffer, dwBufferSize ) )
	{
		// 合成成功

		Write( &clmbtDst[0], dwBufferSize, bProgress );
	}
	else
	{
		// 合成失敗

		Write( pvBuffer, dwBufferSize, bProgress );
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
//	BGRAを合成して上下反転で出力

void	CImageBase::WriteCompoBGRAReverse(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	// 合成データ格納用メモリの確保

	YCMemory<BYTE>		clmbtDst( dwBufferSize );

	// 合成

	if( ComposeBGRA( &clmbtDst[0], pvBuffer, dwBufferSize ) )
	{
		// 合成成功

		WriteReverse( &clmbtDst[0], dwBufferSize, bProgress );
	}
	else
	{
		// 合成失敗

		WriteReverse( pvBuffer, dwBufferSize, bProgress );
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
//	RGBAを合成

BOOL	CImageBase::ComposeRGBA(
	void*				pvDst,							// 格納先
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize					// データサイズ
	)
{
	BYTE*				pbtDst = (BYTE*) pvDst;
	const BYTE*			pbtBuffer = (const BYTE*) pvBuffer;
	WORD				wBpp = IsRequireAlphaBlend() ? 32 : m_wBpp;

	if( (wBpp == 24) || (wBpp == 32) )
	{
		// 24bitと32bitのみサポート

		WORD				wByteCount = (wBpp >> 3);
		DWORD				dwColorSize = dwBufferSize / wByteCount;

		// B,G,R,Aそれぞれへのポインタ取得

		const BYTE*			apbtBGRA[4];

		for( int i = 0, j = 2 ; i < 3 ; i++, j-- )
		{
			apbtBGRA[i] = &pbtBuffer[dwColorSize * j];
		}
		if( wByteCount == 4 )
		{
			apbtBGRA[3] = &pbtBuffer[dwColorSize * 3];
		}

		// BGRAを合成

		for( DWORD i = 0 ; i < dwColorSize ; i++ )
		{
			for( WORD j = 0 ; j < wByteCount ; j++ )
			{
				*pbtDst++ = *apbtBGRA[j]++;
			}
		}

		return	TRUE;
	}

	return	FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	RGBAを合成して出力

void	CImageBase::WriteCompoRGBA(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	// RGBA合成データ格納用メモリの確保

	YCMemory<BYTE>		clmbtDst( dwBufferSize );

	// 合成

	if( ComposeRGBA( &clmbtDst[0], pvBuffer, dwBufferSize ) )
	{
		// 合成成功

		Write( &clmbtDst[0], dwBufferSize, bProgress );
	}
	else
	{
		// 合成失敗

		Write( pvBuffer, dwBufferSize, bProgress );
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
//	RGBAを合成して上下反転で出力

void	CImageBase::WriteCompoRGBAReverse(
	const void*			pvBuffer,						// データ
	DWORD				dwBufferSize,					// データサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	// RGBA合成データ格納用メモリの確保

	YCMemory<BYTE>		clmbtDst( dwBufferSize );

	// 合成

	if( ComposeRGBA( &clmbtDst[0], pvBuffer, dwBufferSize ) )
	{
		// 合成成功

		WriteReverse( &clmbtDst[0], dwBufferSize, bProgress );
	}
	else
	{
		// 合成失敗

		WriteReverse( pvBuffer, dwBufferSize, bProgress );
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
//	出力終了

void	CImageBase::WriteFinish()
{
	m_pclArc->GetProg()->UpdatePercent( m_dwRowSizeOfRemainder );
	OnWriteFinish();
}

//////////////////////////////////////////////////////////////////////////////////////////
//	ピッチの算出

long	CImageBase::CalculatePitch(
	long				lWidth,							// 横幅
	WORD				wBpp							// ビット数
	)
{
	return	((lWidth * (wBpp >> 3) + 3) & 0xFFFFFFFC);
}
