193 lines
4.6 KiB
C++
193 lines
4.6 KiB
C++
![]() |
#include "advwin32.h"
|
||
|
#ifndef DB_LEVEL
|
||
|
#define DB_LEVEL 4
|
||
|
#endif
|
||
|
#include "db.h"
|
||
|
|
||
|
#include "awTexLd.hpp"
|
||
|
|
||
|
// BMP Loader
|
||
|
|
||
|
class AwBmpLoader : public AwTl::TypicalTexFileLoader
|
||
|
{
|
||
|
protected:
|
||
|
virtual void LoadHeaderInfo(MediaMedium * pMedium);
|
||
|
virtual AwTl::Colour * GetPalette();
|
||
|
virtual bool AreRowsReversed();
|
||
|
virtual void LoadNextRow(AwTl::PtrUnion pRow);
|
||
|
|
||
|
WORD bmp_bitdepth;
|
||
|
DWORD bmp_offset;
|
||
|
DWORD bmp_headsize;
|
||
|
|
||
|
unsigned bmp_filepitchpad;
|
||
|
unsigned bmp_bitmask;
|
||
|
|
||
|
MediaMedium * m_pMedium;
|
||
|
};
|
||
|
|
||
|
void AwBmpLoader::LoadHeaderInfo(MediaMedium * pMedium)
|
||
|
{
|
||
|
m_pMedium = pMedium; // store for later
|
||
|
|
||
|
db_log4("\tLoading a BMP file");
|
||
|
|
||
|
pMedium->MovePos(+10); // 2 bytes BM (magic) and 4 bytes bmp_filesize and 4 bytes reserved
|
||
|
|
||
|
MediaRead(pMedium,&bmp_offset);
|
||
|
MediaRead(pMedium,&bmp_headsize);
|
||
|
// 12 for OS/2 1.x 40 for Windows, 64 for OS/2 2.x
|
||
|
if (12 != bmp_headsize && 40 != bmp_headsize && 64 != bmp_headsize)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADFILEFORMAT;
|
||
|
db_logf3(("AwCreateTexture(): ERROR: BMP_headersize (%u) is not a recognized BMP format",bmp_headsize));
|
||
|
}
|
||
|
#if DB_LEVEL >= 4
|
||
|
switch (bmp_headsize)
|
||
|
{
|
||
|
case 12:
|
||
|
db_log4("\tBMP format is OS/2 1.x");
|
||
|
break;
|
||
|
case 40:
|
||
|
db_log4("\tBMP format is Windows 3.x");
|
||
|
break;
|
||
|
case 64:
|
||
|
db_log4("\tBMP format is OS/2 2.x");
|
||
|
}
|
||
|
#endif
|
||
|
if (bmp_headsize >= 40)
|
||
|
{
|
||
|
DWORD width, height;
|
||
|
MediaRead(pMedium,&width);
|
||
|
MediaRead(pMedium,&height);
|
||
|
m_nWidth = width;
|
||
|
m_nHeight = height;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WORD width, height;
|
||
|
MediaRead(pMedium,&width);
|
||
|
MediaRead(pMedium,&height);
|
||
|
m_nWidth = width;
|
||
|
m_nHeight = height;
|
||
|
}
|
||
|
// next WORD is planes and should == 1
|
||
|
WORD bmp_planes = 0; // ALEX: added in initialization to prevent compiler warnings
|
||
|
MediaRead(pMedium,&bmp_planes);
|
||
|
if (1!=bmp_planes)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADFILEDATA;
|
||
|
db_log3("AwCreateTexture(): ERROR: BMP_planes should be 1");
|
||
|
}
|
||
|
MediaRead(pMedium,&bmp_bitdepth);
|
||
|
db_logf4(("\tBMP_bitdepth is %hd",bmp_bitdepth));
|
||
|
if (1!=bmp_bitdepth && 2!=bmp_bitdepth && 4!=bmp_bitdepth && 8!=bmp_bitdepth && 24!=bmp_bitdepth)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADFILEDATA;
|
||
|
db_logf3(("AwCreateTexture(): ERROR: BMP_bitdepth (%u) should be 1,2,4,8 or 24",bmp_bitdepth));
|
||
|
}
|
||
|
if (bmp_headsize >= 40)
|
||
|
{
|
||
|
// next DWORD is compression, not supported so only accept 0
|
||
|
DWORD compression = 0;
|
||
|
MediaRead(pMedium,&compression);
|
||
|
if (compression)
|
||
|
{
|
||
|
db_log3("AwCreateTexture(): ERROR: Cannont read compressed BMP files");
|
||
|
awTlLastErr = AW_TLE_BADFILEFORMAT;
|
||
|
}
|
||
|
// DWORD bmp_size - ignored, 2xDWORDS ignored
|
||
|
pMedium->MovePos(+12);
|
||
|
DWORD palette_size = 0; // ALEX: added in initialization to prevent compiler warnings
|
||
|
MediaRead(pMedium,&palette_size);
|
||
|
m_nPaletteSize = palette_size;
|
||
|
// skip to the start of the palette if there would be one
|
||
|
pMedium->MovePos(bmp_headsize-36);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_nPaletteSize = 0;
|
||
|
}
|
||
|
bmp_offset -= (bmp_headsize+14);
|
||
|
if (!m_nPaletteSize && bmp_bitdepth<=8)
|
||
|
m_nPaletteSize = 1<<bmp_bitdepth;
|
||
|
if (m_nPaletteSize)
|
||
|
bmp_offset -= bmp_headsize >= 40 ? m_nPaletteSize*4 : m_nPaletteSize*3;
|
||
|
|
||
|
db_logf4(("\tBMP_palettesize is %u",m_nPaletteSize));
|
||
|
bmp_filepitchpad = (~(m_nWidth*bmp_bitdepth-1))/8 & 3;
|
||
|
db_logf4(("\tBMP has %u bytes padding per row",bmp_filepitchpad));
|
||
|
|
||
|
bmp_bitmask = (1<<bmp_bitdepth)-1;
|
||
|
}
|
||
|
|
||
|
AwTl::Colour * AwBmpLoader::GetPalette()
|
||
|
{
|
||
|
db_assert1(m_nPaletteSize);
|
||
|
db_assert1(m_pPalette);
|
||
|
|
||
|
if (m_nPaletteSize > 256)
|
||
|
{
|
||
|
awTlLastErr = AW_TLE_BADFILEDATA;
|
||
|
db_log3("AwCreateTexture(): ERROR: BMP_palettesize is too large");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
AwTl::Colour * pmP = m_pPalette;
|
||
|
for (unsigned pc = m_nPaletteSize; pc; --pc,++pmP)
|
||
|
{
|
||
|
MediaRead(m_pMedium,&pmP->b);
|
||
|
MediaRead(m_pMedium,&pmP->g);
|
||
|
MediaRead(m_pMedium,&pmP->r);
|
||
|
if (bmp_headsize >= 40) m_pMedium->MovePos(+1);
|
||
|
}
|
||
|
}
|
||
|
// skip to the start of the pixel data
|
||
|
m_pMedium->MovePos(bmp_offset);
|
||
|
|
||
|
return m_pPalette;
|
||
|
}
|
||
|
|
||
|
bool AwBmpLoader::AreRowsReversed()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void AwBmpLoader::LoadNextRow(AwTl::PtrUnion pRow)
|
||
|
{
|
||
|
if (m_nPaletteSize)
|
||
|
{
|
||
|
unsigned shift = 0;
|
||
|
BYTE byte = 0; // Not needed.
|
||
|
|
||
|
for (unsigned colcount = m_nWidth; colcount; --colcount)
|
||
|
{
|
||
|
if (!shift)
|
||
|
{
|
||
|
shift = 8;
|
||
|
MediaRead(m_pMedium, &byte);
|
||
|
}
|
||
|
shift -= bmp_bitdepth;
|
||
|
*pRow.byteP++ = static_cast<BYTE>(byte>>shift & bmp_bitmask);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (unsigned colcount = m_nWidth; colcount; --colcount)
|
||
|
{
|
||
|
MediaRead(m_pMedium,&pRow.colourP->b);
|
||
|
MediaRead(m_pMedium,&pRow.colourP->g);
|
||
|
MediaRead(m_pMedium,&pRow.colourP->r);
|
||
|
++pRow.colourP;
|
||
|
}
|
||
|
}
|
||
|
m_pMedium->MovePos(bmp_filepitchpad);
|
||
|
}
|
||
|
|
||
|
#ifdef _MSC_VER
|
||
|
// VC5.0 tries to compile out code that is in a library
|
||
|
// and it thinks isn't being used
|
||
|
#line 186
|
||
|
#endif
|
||
|
AWTEXLD_IMPLEMENT_DYNCREATE("BM",AwBmpLoader)
|