#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<= 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< 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>>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)