diff options
| author | Steven Fuller <relnev@icculus.org> | 2001-07-01 00:55:22 +0000 |
|---|---|---|
| committer | Patryk Obara <dreamer.tan@gmail.com> | 2019-08-20 02:09:04 +0200 |
| commit | 2186d5f3f95cd74a070a490d899291648d58667a (patch) | |
| tree | 55241a1afa3e1a22e0b6593a8dead0b703800f44 /src/win95/awbmpld.cpp | |
| parent | 218ca90543758a20ac326e444ca0643174ca7384 (diff) | |
Initial revision
Diffstat (limited to 'src/win95/awbmpld.cpp')
| -rw-r--r-- | src/win95/awbmpld.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/src/win95/awbmpld.cpp b/src/win95/awbmpld.cpp new file mode 100644 index 0000000..375e1d7 --- /dev/null +++ b/src/win95/awbmpld.cpp @@ -0,0 +1,192 @@ +#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) |
