summaryrefslogtreecommitdiff
path: root/src/win95/awbmpld.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/awbmpld.cpp')
-rw-r--r--src/win95/awbmpld.cpp192
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)