
#include	"stdafx.h"
#include	"ExtractBase.h"
#include	"Image.h"

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

CImage::CImage()
{
	m_pbtBMP = NULL;
	m_pstBMPFileHeader = NULL;
	m_pstBMPInfoHeader = NULL;
	m_bBMPHeader = TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	マウント

BOOL	CImage::Mount(
	CArcFile*			pclArc							// アーカイブ
	)
{
	if( m_clBMP.Mount( pclArc) )
	{
		return	TRUE;
	}

	return	FALSE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	デコード

BOOL	CImage::Decode(
	CArcFile*			pclArc							// アーカイブ
	)
{
	SFileInfo*			pstFileInfo = pclArc->GetOpenFileInfo();

	if( pstFileInfo->format != _T("BMP") )
	{
		return	FALSE;
	}

	// BMP読み込み

	YCMemory<BYTE>		clmbtSrc( pstFileInfo->sizeOrg );

	pclArc->Read( &clmbtSrc[0], pstFileInfo->sizeOrg );

	// 出力

	Init( pclArc, &clmbtSrc[0] );
	Write( pstFileInfo->sizeOrg );

	return	TRUE;
}

////////////////////////////////////////////////////////////
//	初期化(BMPが渡されたとき)

BOOL	CImage::Init(
	CArcFile*			pclArc,							// アーカイブ
	void*				pvBMP,							// BMP
	const YCString&		rfclsFileName					// ファイル名
	)
{
	SFileInfo*			pstFileInfo = pclArc->GetOpenFileInfo();
	BYTE*				pbtSrc = (BYTE*) pvBMP;

	if( (pstFileInfo->format == _T("BMP")) && (pstFileInfo->title == _T("")) && (pstFileInfo->key == 0) )
	{
		// 簡易復号

		pclArc->InitDecrypt( pbtSrc );
		pclArc->Decrypt( pbtSrc, pstFileInfo->sizeOrg );
	}

	m_pclArc = pclArc;
	m_pbtBMP = pbtSrc;
	m_pstBMPFileHeader = (BITMAPFILEHEADER*) &pbtSrc[0];
	m_pstBMPInfoHeader = (BITMAPINFOHEADER*) &pbtSrc[14];

	if( m_pstBMPFileHeader->bfType != 0x4D42 )
	{
		// 暗号化等でBMヘッダになっていない

		pclArc->OpenFile();
		pclArc->WriteFile( pbtSrc, pstFileInfo->sizeOrg );

		m_bBMPHeader = FALSE;

		return	FALSE;
	}

	// 正常なBMP

	return	Init( pclArc, m_pstBMPInfoHeader->biWidth, m_pstBMPInfoHeader->biHeight, m_pstBMPInfoHeader->biBitCount, &pbtSrc[54], (m_pstBMPFileHeader->bfOffBits - 54), rfclsFileName );
}

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

BOOL	CImage::Init(
	CArcFile*			pclArc,							// アーカイブ
	long				lWidth,							// 横幅
	long				lHeight,						// 縦幅
	WORD				wBpp,							// ビット数
	const void*			pvPallet,						// パレット
	DWORD				dwPalletSize,					// パレットサイズ
	const YCString&		rfclsFileName					// ファイル名
	)
{
	BOOL				bReturn = TRUE;

	m_pclArc = pclArc;
	m_pstOption = pclArc->GetOpt();

	// ヘッダの出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		TCHAR				szFileName[MAX_PATH];

		lstrcpy( szFileName, rfclsFileName );
		PathRenameExtension( szFileName, _T(".bmp") );
//		sFileName.append(_T(".bmp"));

		bReturn = m_clBMP.Init( pclArc, lWidth, lHeight, wBpp, pvPallet, dwPalletSize, szFileName );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		TCHAR				szFileName[MAX_PATH];

		lstrcpy( szFileName, rfclsFileName );
		PathRenameExtension( szFileName, _T(".png") );
//		sFileName.append(_T(".png"));

		bReturn = m_clPNG.Init( pclArc, lWidth, lHeight, wBpp, pvPallet, dwPalletSize, szFileName );
	}

	return	bReturn;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	閉じる

void	CImage::Close()
{
	m_pclArc->CloseFile();
}

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

BOOL	CImage::Write(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	Write( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

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

BOOL	CImage::Write(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.Write( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.WriteReverse( pvBMPData, dwBMPDataSize, bProgress ); // BMPがトップダウン形式のためReverseする
	}

	return	TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	逆さにして出力

BOOL	CImage::WriteReverse(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	WriteReverse( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

//////////////////////////////////////////////////////////////////////////////////////////
//	逆さにして出力

BOOL	CImage::WriteReverse(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.WriteReverse( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.Write( pvBMPData, dwBMPDataSize, bProgress ); // BMPがトップダウン形式のためReverseしない
	}

	return	TRUE;
}

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

BOOL	CImage::WriteCompoBGRA(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	WriteCompoBGRA( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

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

BOOL	CImage::WriteCompoBGRA(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.WriteCompoBGRA( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.WriteCompoBGRAReverse( pvBMPData, dwBMPDataSize, bProgress ); // BMPがトップダウン形式のためReverseする
	}

	return	TRUE;
}

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

BOOL	CImage::WriteCompoBGRAReverse(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	WriteCompoBGRAReverse( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

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

BOOL	CImage::WriteCompoBGRAReverse(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.WriteCompoBGRAReverse( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.WriteCompoBGRA( pvBMPData, dwBMPDataSize, bProgress ); // BMPがトップダウン形式のためReverseしない
	}

	return	TRUE;
}

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

BOOL	CImage::WriteCompoRGBA(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	WriteCompoRGBA( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

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

BOOL	CImage::WriteCompoRGBA(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.WriteCompoRGBA( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.WriteCompoRGBAReverse( pvBMPData, dwBMPDataSize, bProgress );
	}

	return	TRUE;
}

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

BOOL	CImage::WriteCompoRGBAReverse(
	DWORD				dwBMPSize,						// BMPサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	return	WriteCompoRGBAReverse( &m_pbtBMP[m_pstBMPFileHeader->bfOffBits], (dwBMPSize - m_pstBMPFileHeader->bfOffBits), bProgress );
}

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

BOOL	CImage::WriteCompoRGBAReverse(
	const void*			pvBMPData,						// BMPデータ(ヘッダは含まない)
	DWORD				dwBMPDataSize,					// BMPデータサイズ
	BOOL				bProgress						// プログレスバー進捗要求
	)
{
	if( !m_bBMPHeader )
	{
		// 不正なBMP

		return	FALSE;
	}

	// 出力

	if( m_pstOption->bDstBMP )
	{
		// BMPで出力

		m_clBMP.WriteCompoRGBAReverse( pvBMPData, dwBMPDataSize, bProgress );
	}
	else if( m_pstOption->bDstPNG )
	{
		// PNGで出力

		m_clPNG.WriteCompoRGBA( pvBMPData, dwBMPDataSize, bProgress );
	}

	return	TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	ビットマップファイルヘッダの取得

BITMAPFILEHEADER*	CImage::GetBmpFileHeader()
{
	return	m_pstBMPFileHeader;
}

//////////////////////////////////////////////////////////////////////////////////////////
//	ビットマップインフォヘッダの取得

BITMAPINFOHEADER*	CImage::GetBmpInfoHeader()
{
	return	m_pstBMPInfoHeader;
}
