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; }
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; }