bool CSurface8::Save(const char *szFilename, CStdPalette *bpPalette)
{
	C4BMP256Info BitmapInfo;
	BitmapInfo.Set(Wdt,Hgt, bpPalette ? bpPalette : pPal);

	// Create file & write info
	CStdFile hFile;

	if ( !hFile.Create(szFilename)
	     || !hFile.Write(&BitmapInfo,sizeof(BitmapInfo)) )
		{ return false; }

	// Write lines
	char bpEmpty[4]; ZeroMem(bpEmpty, 4);
	const int iEmpty = DWordAligned(Wdt)-Wdt;
	for (int cnt=Hgt-1; cnt>=0; cnt--)
	{
		if (!hFile.Write(Bits+(Pitch*cnt),Wdt))
			{ return false; }
		if (iEmpty)
			if (!hFile.Write(bpEmpty,iEmpty))
				{ return false; }
	}

	// Close file
	hFile.Close();

	// Success
	return true;
}
bool CSurface8::Read(CStdStream &hGroup)
{
	int cnt,lcnt;
	C4BMP256Info BitmapInfo;
	// read bmpinfo-header
	if (!hGroup.Read(&BitmapInfo,sizeof(C4BMPInfo))) return false;
	// is it 8bpp?
	if (BitmapInfo.Info.biBitCount == 8)
	{
		if (!hGroup.Read(((BYTE *) &BitmapInfo)+sizeof(C4BMPInfo),sizeof(BitmapInfo)-sizeof(C4BMPInfo))) return false;
		if (!hGroup.Advance(BitmapInfo.FileBitsOffset())) return false;
	}
	else
	{
		// read 24bpp
		if (BitmapInfo.Info.biBitCount != 24) return false;
		if (!hGroup.Advance(((C4BMPInfo) BitmapInfo).FileBitsOffset())) return false;
	}

	// Create and lock surface
	if (!Create(BitmapInfo.Info.biWidth,BitmapInfo.Info.biHeight)) return false;

	if (BitmapInfo.Info.biBitCount == 8)
	{
		// Copy palette
		for (cnt=0; cnt<256; cnt++)
		{
			pPal->Colors[cnt] = C4RGB(BitmapInfo.Colors[cnt].rgbRed,
			                          BitmapInfo.Colors[cnt].rgbGreen,
			                          BitmapInfo.Colors[cnt].rgbBlue);
		}
	}

	// create line buffer
	int iBufSize=DWordAligned(BitmapInfo.Info.biWidth*BitmapInfo.Info.biBitCount/8);
	BYTE *pBuf = new BYTE[iBufSize];
	// Read lines
	for (lcnt=Hgt-1; lcnt>=0; lcnt--)
	{
		if (!hGroup.Read(pBuf, iBufSize))
			{ Clear(); delete [] pBuf; return false; }
		BYTE *pPix=pBuf;
		for (int x=0; x<BitmapInfo.Info.biWidth; ++x)
			switch (BitmapInfo.Info.biBitCount)
			{
			case 8:
				SetPix(x, lcnt, *pPix++);
				break;
			case 24:
				return false;
				break;
			}
	}
	// free buffer again
	delete [] pBuf;

	return true;
}
Example #3
0
bool C4Surface::ReadBMP(CStdStream &hGroup, int iFlags)
{
	int lcnt;
	C4BMP256Info BitmapInfo;
	// read bmpinfo-header
	if (!hGroup.Read(&BitmapInfo,sizeof(C4BMPInfo))) return false;
	// is it 8bpp?
	if (BitmapInfo.Info.biBitCount == 8)
	{
		if (!hGroup.Read(((BYTE *) &BitmapInfo)+sizeof(C4BMPInfo),
		                 std::min(sizeof(BitmapInfo)-sizeof(C4BMPInfo),sizeof(BitmapInfo)-sizeof(C4BMPInfo)+BitmapInfo.FileBitsOffset())))
			return false;
		if (!hGroup.Advance(BitmapInfo.FileBitsOffset())) return false;
	}
	else
	{
		// read 24bpp
		if (BitmapInfo.Info.biBitCount != 24) return false;
		if (!hGroup.Advance(((C4BMPInfo) BitmapInfo).FileBitsOffset())) return false;
	}

	// Create and lock surface
	if (!Create(BitmapInfo.Info.biWidth,BitmapInfo.Info.biHeight, iFlags)) return false;
	if (!Lock()) { Clear(); return false; }

	// create line buffer
	int iBufSize=DWordAligned(BitmapInfo.Info.biWidth*BitmapInfo.Info.biBitCount/8);
	BYTE *pBuf = new BYTE[iBufSize];
	// Read lines
	for (lcnt=Hgt-1; lcnt>=0; lcnt--)
	{
		if (!hGroup.Read(pBuf, iBufSize))
			{ Clear(); delete [] pBuf; return false; }
		BYTE *pPix=pBuf;
		for (int x=0; x<BitmapInfo.Info.biWidth; ++x)
			switch (BitmapInfo.Info.biBitCount)
			{
			case 8:
				SetPixDw(x, lcnt, C4RGB(
				         BitmapInfo.Colors[*pPix].rgbRed,
				         BitmapInfo.Colors[*pPix].rgbGreen,
				         BitmapInfo.Colors[*pPix].rgbBlue));
				++pPix;
				break;
			case 24:
				SetPixDw(x, lcnt, C4RGB(pPix[0], pPix[1], pPix[2]));
				pPix+=3;
				break;
			}
	}
	// free buffer again
	delete [] pBuf;

	Unlock();

	return true;
}