// BMPImage.cpp: implementation of the CBMPImage class.
//
//////////////////////////////////////////////////////////////////////

#include "BMPImage.h"

#include "FileStream.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBMPImage::CBMPImage()
{
	m_pszClassName = "CBMPImage";
}

CBMPImage::~CBMPImage()
{

}

bool CBMPImage::Load(LPSTR lpszFileName)
{
	CFileStream stream;
	if (!stream.Open(lpszFileName, CFileStream::READONLY))
		return false;

	// Read file header
	BITMAPFILEHEADER bmFileHeader;
	stream.Read(&bmFileHeader, sizeof(BITMAPINFOHEADER), 1);

	// File header check
	if (!(bmFileHeader.bfReserved1 == 0 && bmFileHeader.bfReserved2 == 0))
		return false;

	// Read info header
	BITMAPINFOHEADER bmInfoHeader;
	stream.Read(&bmInfoHeader, sizeof(BITMAPINFOHEADER), 1);

	// Info header check
	if (!(bmInfoHeader.biSize == sizeof(BITMAPINFOHEADER) && bmInfoHeader.biPlanes == 1))
		return false;

	// Bit depth?  Only 8-bit supported.
	if (bmInfoHeader.biBitCount != 8)
		return false;
	
	// Compression?  Only non-compressed supported.
	if (bmInfoHeader.biCompression != BI_RGB)
		return false;

	
	///////////////////////////////////////////////////////////////////////////
    m_dwWidth  = bmInfoHeader.biWidth;
    m_dwHeight = bmInfoHeader.biHeight;

	m_format = FMT_COLOR_INDEX;

	// Figure out how many entires are actually in the table
	DWORD dwPalBytes;
	if (bmInfoHeader.biClrUsed == 0)
		dwPalBytes = (1 << bmInfoHeader.biBitCount) * sizeof(RGBQUAD);
	else 
		dwPalBytes = bmInfoHeader.biClrUsed * sizeof(RGBQUAD);

	// Read palette (256 entries)
	///////////////////////////////////////////////////////////////////////////
	m_pPalBuffer = new BYTE [dwPalBytes];
	if (!m_pPalBuffer)
		return false;

	stream.Read(m_pPalBuffer, sizeof(BYTE), dwPalBytes);

	// Read bitmap bits (remainder of file)
	///////////////////////////////////////////////////////////////////////////
	m_dwBufferLength = bmFileHeader.bfSize - stream.Position();
	m_pBuffer = new BYTE [m_dwBufferLength];
	if (!m_pBuffer)
		return false;

	stream.Read(m_pBuffer, sizeof(BYTE), m_dwBufferLength);

	return true;
}