// PCXImage.cpp: implementation of the CPCXImage class.
//
//////////////////////////////////////////////////////////////////////

#include "PCXImage.h"

#include "FileStream.h"

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

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

CPCXImage::~CPCXImage()
{

}

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

	// Read file header
	PCXFILEHEADER pcxFileHeader;
	stream.Read(&pcxFileHeader, sizeof(PCXFILEHEADER), 1);
	
	if (pcxFileHeader.manufacturer != 0x0a ||
		pcxFileHeader.version != 5 ||
		pcxFileHeader.encoding != 1 ||
		pcxFileHeader.bitsPerPixel != 8 ||
		pcxFileHeader.xmax >= 640 ||
		pcxFileHeader.ymax >= 480)
		return false;

	m_dwWidth  = pcxFileHeader.xmax + 1;
	m_dwHeight = pcxFileHeader.ymax + 1;

	m_format = FMT_COLOR_INDEX;

	m_dwBufferLength = m_dwWidth * m_dwHeight;
	m_pBuffer = new BYTE [m_dwBufferLength];
	if (!m_pBuffer)
		return false;

	// Read bitmap bits (remainder of file)
	///////////////////////////////////////////////////////////////////////////
	int nPixel, nLength;
	int nCount = m_dwWidth * m_dwHeight;
	
	LPBYTE pBuffer = m_pBuffer;
	for (nPixel = 0; nPixel < nCount; nPixel ++)
	{
		BYTE dataByte = (BYTE) stream.ReadChar();
		if ((dataByte & 0xC0) == 0xC0)
		{
			nLength = dataByte & 0x3F;
			dataByte = (BYTE) stream.ReadChar();
		}
		else
			nLength = 1;

		while (nLength -- > 0)
		{
			*pBuffer = dataByte;
			pBuffer ++;
		}
	}

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

	stream.Seek(-768, SEEK_END);
	stream.Read(m_pPalBuffer, sizeof(BYTE), 768);

	return true;
}