summaryrefslogtreecommitdiff
path: root/3dc/win95/awIffLd.cpp
diff options
context:
space:
mode:
authorSteven Fuller <relnev@icculus.org>2001-07-01 00:55:22 +0000
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-20 02:09:04 +0200
commit2186d5f3f95cd74a070a490d899291648d58667a (patch)
tree55241a1afa3e1a22e0b6593a8dead0b703800f44 /3dc/win95/awIffLd.cpp
parent218ca90543758a20ac326e444ca0643174ca7384 (diff)
Initial revision
Diffstat (limited to '3dc/win95/awIffLd.cpp')
-rw-r--r--3dc/win95/awIffLd.cpp507
1 files changed, 0 insertions, 507 deletions
diff --git a/3dc/win95/awIffLd.cpp b/3dc/win95/awIffLd.cpp
deleted file mode 100644
index de3be19..0000000
--- a/3dc/win95/awIffLd.cpp
+++ /dev/null
@@ -1,507 +0,0 @@
-#include "advwin32.h"
-#ifndef DB_LEVEL
-#define DB_LEVEL 4
-#endif
-#include "db.h"
-#ifndef DB_COMMA
- #define DB_COMMA ,
-#endif
-
-#pragma warning(disable: 4701)
-#include "awTexLd.hpp"
-#pragma warning(default: 4701)
-
-#include "iff.hpp"
-#include "iff_ILBM.hpp"
-
-#include "list_tem.hpp"
-
-#include <limits.h>
-
-// conversion functors for IFF loader
-class AwIffConvNull
-{
- public:
- static inline unsigned DoConv (unsigned const * _colP, AwTl::Colour const * db_code1(DB_COMMA unsigned))
- {
- db_assert1(AwTl::pixelFormat.palettizedB);
- return *_colP;
- }
-};
-
-class AwIffConvNonTransp : public AwTl::Colour::ConvNonTransp
-{
- public:
- static inline unsigned DoConv(unsigned const * pCol, AwTl::Colour const * pPalette db_code1(DB_COMMA unsigned nPaletteSize))
- {
- db_assert1(pPalette);
- db_onlyassert1(*pCol < nPaletteSize);
- return AwTl::Colour::ConvNonTransp::DoConv(&pPalette[*pCol]);
- }
-};
-
-class AwIffConvTransp
-{
- public:
- static unsigned iTranspCol; // the index of the transparent colour
- static unsigned rawTranspCol; // the value of a transparent pixel on the surface
-
- static inline unsigned DoConv(unsigned const * pCol, AwTl::Colour const * pPalette db_code1(DB_COMMA unsigned nPaletteSize))
- {
- using namespace AwTl;
-
- if (*pCol == iTranspCol) return rawTranspCol;
- unsigned rv = AwIffConvNonTransp::DoConv(pCol,pPalette db_code1(DB_COMMA nPaletteSize));
- if (rv != rawTranspCol) return rv;
-
- // make the colour non-transparent (nb: only an occasional case)
-
- // OK, Here's the plan:
-
- // First, suppose that I were to decrease either the Red, Green or Blue
- // component in order to make the colour non-transparent.
- // Taking Red as an example, I'll work out what the resultant red value
- // will be if I decrease red to achieve a non-transparent colour
- // I'll compare this to the actual red value of the colour in question
- // The lower the difference, the better it'll be (ie. closer to the
- // original colour).
- // Obviously, I'll do the same for Green and Blue
- // Then I'll repeat the process but this time considering increasing
- // the components.
- // I'll then have six values which are scores (the lower the better)
- // for what colour component to change and how to change it.
- // If any of the components cannot be decreased (ie. their resulting
- // value is already zero) or increased (ie. their resulting value
- // is at maximum), then I'll set the corresponding score to
- // UINT_MAX so that that colour-changing operation won't be selected
- // (because that'll be the one that buggers everything up).
-
- unsigned nRedDiffDown =
- (pPalette[*pCol].r < 1<<pixelFormat.redRightShift ) ? UINT_MAX
- : (pPalette[*pCol].r & (1<<pixelFormat.redRightShift )-1) + ((1<<pixelFormat.redRightShift )+1)/2;
-
- unsigned nGreenDiffDown =
- (pPalette[*pCol].g < 1<<pixelFormat.greenRightShift) ? UINT_MAX
- : (pPalette[*pCol].g & (1<<pixelFormat.greenRightShift)-1) + ((1<<pixelFormat.greenRightShift)+1)/2;
-
- unsigned nBlueDiffDown =
- (pPalette[*pCol].b < 1<<pixelFormat.blueRightShift ) ? UINT_MAX
- : (pPalette[*pCol].b & (1<<pixelFormat.blueRightShift )-1) + ((1<<pixelFormat.blueRightShift )+1)/2;
-
- unsigned nRedDiffUp =
- (pPalette[*pCol].r >= (255 & ~((1<<pixelFormat.redRightShift )-1) ) ? UINT_MAX
- : (1<<pixelFormat.redRightShift )*3/2 - (pPalette[*pCol].r & (1<<pixelFormat.redRightShift )-1));
-
- unsigned nGreenDiffUp =
- (pPalette[*pCol].g >= (255 & ~((1<<pixelFormat.greenRightShift)-1) ) ? UINT_MAX
- : (1<<pixelFormat.greenRightShift)*3/2 - (pPalette[*pCol].g & (1<<pixelFormat.greenRightShift)-1));
-
- unsigned nBlueDiffUp =
- (pPalette[*pCol].b >= (255 & ~((1<<pixelFormat.blueRightShift )-1) ) ? UINT_MAX
- : (1<<pixelFormat.blueRightShift )*3/2 - (pPalette[*pCol].b & (1<<pixelFormat.blueRightShift )-1));
-
- // Pick lowest value and do the business
-
- Colour colAdj = pPalette[*pCol];
-
- #if defined(_MSC_VER) && _MSC_VER >= 1100
- // VC5.0 gives inane warnings when += type operators
- // are used on types smaller than int (even with
- // explicit casting!)
- #pragma warning(disable:4244)
- #endif
- if
- (
- nBlueDiffUp <= nBlueDiffDown
- && nBlueDiffUp <= nRedDiffUp
- && nBlueDiffUp <= nRedDiffDown
- && nBlueDiffUp <= nGreenDiffUp
- && nBlueDiffUp <= nGreenDiffDown
- )
- {
- colAdj.b += static_cast<unsigned char>(1<<pixelFormat.blueRightShift);
- }
- else if
- (
- nBlueDiffDown <= nRedDiffUp
- && nBlueDiffDown <= nRedDiffDown
- && nBlueDiffDown <= nGreenDiffUp
- && nBlueDiffDown <= nGreenDiffDown
- )
- {
- colAdj.b -= static_cast<unsigned char>(1<<pixelFormat.blueRightShift);
- }
- else if
- (
- nRedDiffUp <= nRedDiffDown
- && nRedDiffUp <= nGreenDiffUp
- && nRedDiffUp <= nGreenDiffDown
- )
- {
- colAdj.r += static_cast<unsigned char>(1<<pixelFormat.redRightShift);
- }
- else if
- (
- nRedDiffDown <= nGreenDiffUp
- && nRedDiffDown <= nGreenDiffDown
- )
- {
- colAdj.r -= static_cast<unsigned char>(1<<pixelFormat.redRightShift);
- }
- else if (nGreenDiffUp <= nGreenDiffDown)
- {
- colAdj.g += static_cast<unsigned char>(1<<pixelFormat.greenRightShift);
- }
- else
- {
- colAdj.g -= static_cast<unsigned char>(1<<pixelFormat.greenRightShift);
- }
- #if defined(_MSC_VER) && _MSC_VER == 1100
- // VC5.0 gives inane warnings when += type operators
- // are used on types smaller than int (even with
- // explicit casting!)
- #pragma warning(default:4244)
- #endif
-
- return Colour::ConvNonTransp::DoConv(&colAdj);
- }
-};
-
-unsigned AwIffConvTransp::iTranspCol;
-unsigned AwIffConvTransp::rawTranspCol;
-
-// IFF Loader
-
-class AwIffLoader : public AwTl::TexFileLoader
-{
- public:
- AwIffLoader() : m_pPalette(NULL), m_bDecoding(false) {}
- protected:
- virtual ~AwIffLoader();
-
- virtual void LoadHeaderInfo(MediaMedium * pMedium);
-
- virtual unsigned GetNumColours();
-
- virtual unsigned GetMinPaletteSize();
-
- virtual bool HasTransparentMask(bool bDefault);
-
- virtual void AllocateBuffers(bool bWantBackup, unsigned nMaxPaletteSize);
-
- virtual void OnBeginRestoring(unsigned nMaxPaletteSize);
-
- virtual AwTl::Colour * GetPalette();
-
-
- virtual AwTl::PtrUnion GetRowPtr(unsigned nRow);
-
- virtual void LoadNextRow(AwTl::PtrUnion pRow);
-
- virtual void ConvertRow(AwTl::PtrUnion pDest, unsigned nDestWidth, AwTl::PtrUnionConst pSrc, unsigned nSrcOffset, unsigned nSrcWidth, AwTl::Colour * pPalette db_code1(DB_COMMA unsigned nPaletteSize));
-
- virtual DWORD GetTransparentColour();
-
- virtual void OnFinishLoading(bool bSuccess);
-
- virtual void OnFinishRestoring(bool bSuccess);
-
- virtual AwBackupTexture * CreateBackupTexture();
-
- private:
- static bool Enumerator(IFF::Chunk * pChunk, void * pData);
- // list of chunks found by enumerator
- List<IFF::IlbmBodyChunk *> m_listBodyChunks;
-
- // smallest and largest palette sizes of versions of this image
- unsigned m_nMaxPaletteSize;
- unsigned m_nMinPaletteSize;
-
- // buffer for palette -
- // since the IFF cmap table is in a different format to what the Aw loaders require
- // (maybe should think about standardizing the data types?)
- AwTl::Colour * m_pPalette;
-
- // iff data
- IFF::File m_ifData;
- IFF::IlbmBmhdChunk * m_pHdr;
- IFF::IlbmCmapChunk * m_pCmap;
- IFF::IlbmBodyChunk * m_pBody;
-
- bool m_bDecoding;
-};
-
-AwIffLoader::~AwIffLoader()
-{
- if (m_pPalette) delete[] m_pPalette;
-}
-
-void AwIffLoader::LoadHeaderInfo(MediaMedium * pMedium)
-{
- db_log4("\tLoading an IFF file");
-
- while (m_listBodyChunks.size())
- m_listBodyChunks.delete_first_entry();
-
- if (!m_ifData.Load(pMedium) || !m_ifData.GetContents())
- {
- if (NO_ERROR == (awTlLastWinErr = GetLastError()))
- awTlLastErr = AW_TLE_BADFILEDATA;
- else
- awTlLastErr = AW_TLE_CANTREADFILE;
-
- db_log3("AwCreateTexture(): ERROR: IFF file load failed");
- }
- else
- {
- m_nMinPaletteSize = UINT_MAX;
- m_nMaxPaletteSize = 0;
- m_ifData.GetContents()->EnumChildren("ILBM","BODY",Enumerator,this);
- }
-}
-
-unsigned AwIffLoader::GetNumColours()
-{
- return m_nMaxPaletteSize;
-}
-
-unsigned AwIffLoader::GetMinPaletteSize()
-{
- return m_nMinPaletteSize;
-}
-
-void AwIffLoader::AllocateBuffers(bool /*bWantBackup*/, unsigned nMaxPaletteSize)
-{
- // we will need to allocate buffers when restoring as well as first-time loading
- // so allocate buffers in OnBeginRestoring() which we'll call here
-
- OnBeginRestoring(nMaxPaletteSize);
-}
-
-bool AwIffLoader::Enumerator(IFF::Chunk * pChunk, void * pData)
-{
- db_assert1(pChunk);
- db_assert1(pData);
- AwIffLoader * pThis = static_cast<AwIffLoader *>(pData);
-
- IFF::Chunk * pCmap = pChunk->GetProperty("CMAP");
- IFF::Chunk * pHdr = pChunk->GetProperty("BMHD");
- if (pCmap && pHdr) // must have these two properties
- {
- unsigned nThisPaletteSize = static_cast<IFF::IlbmCmapChunk *>(pCmap)->nEntries;
- db_logf4(("\tfound a %u colour %scompressed IFF body chunk",nThisPaletteSize,static_cast<IFF::IlbmBmhdChunk *>(pHdr)->eCompression ? "" : "un"));
-
- pThis->m_listBodyChunks.add_entry(static_cast<IFF::IlbmBodyChunk *>(pChunk));
-
- if (nThisPaletteSize < pThis->m_nMinPaletteSize)
- pThis->m_nMinPaletteSize = nThisPaletteSize;
-
- if (nThisPaletteSize > pThis->m_nMaxPaletteSize)
- pThis->m_nMaxPaletteSize = nThisPaletteSize;
- }
- else db_log3("AwCreateTexture(): WARNING: IFF body chunk found with insufficient associated property chunks");
-
- return true; // continue enumeration
-}
-
-void AwIffLoader::OnBeginRestoring(unsigned nMaxPaletteSize)
-{
- using namespace AwTl;
-
- if (m_listBodyChunks.size())
- {
- // if decodeing, m_pBody will be valid
- if (m_bDecoding)
- {
- m_pBody->EndDecode();
- m_bDecoding = false;
- }
-
- m_pBody = NULL;
- unsigned nBestPaletteSize = 0;
-
- for (LIF<IFF::IlbmBodyChunk *> itChunks(&m_listBodyChunks); !itChunks.done(); itChunks.next())
- {
- IFF::IlbmCmapChunk * pCmap = static_cast<IFF::IlbmCmapChunk *>(itChunks()->GetProperty("CMAP"));
- db_assert1(pCmap);
-
- if ((!nMaxPaletteSize || pCmap->nEntries <= nMaxPaletteSize) && pCmap->nEntries > nBestPaletteSize)
- {
- m_pBody = itChunks();
- m_pCmap = pCmap;
- nBestPaletteSize = pCmap->nEntries;
- }
- }
-
- if (m_pBody)
- {
- m_pHdr = static_cast<IFF::IlbmBmhdChunk *>(m_pBody->GetProperty("BMHD"));
- // delete old buffers
- if (m_pPalette) delete[] m_pPalette;
- // allocate buffer for palette, make it extra big to cope with corrupt files
- unsigned nAllocPaletteSize = m_pCmap->nEntries;
- unsigned nAllocPaletteSizeShift = 0;
- while (0!=(nAllocPaletteSize >>= 1))
- {
- ++nAllocPaletteSizeShift;
- }
- m_pPalette = new Colour [2<<nAllocPaletteSizeShift]; // prevent corrupt data causing a crash
- //m_pPalette = new Colour [m_pCmap->nEntries];
- // copy the palette
- for (unsigned i=0; i<m_pCmap->nEntries; ++i)
- {
- // hacked testa
- m_pPalette[i].r = m_pCmap->pTable[i].r;
- m_pPalette[i].g = m_pCmap->pTable[i].g;
- m_pPalette[i].b = m_pCmap->pTable[i].b;
- }
- // set the width height and palette size in the base class
- m_nPaletteSize = m_pCmap->nEntries;
- m_nWidth = m_pHdr->width;
- m_nHeight = m_pHdr->height;
- // prepare to decode the data
- m_pBody->BeginDecode();
- m_bDecoding = true;
- // set the transparent mask colours
- switch (m_pHdr->eMasking)
- {
- case IFF::IlbmBmhdChunk::MASK_NONE:
- break;
- case IFF::IlbmBmhdChunk::MASK_TRANSPARENTCOL:
- AwIffConvTransp::iTranspCol = m_pHdr->iTranspCol;
- if (pixelFormat.palettizedB)
- AwIffConvTransp::rawTranspCol = AwIffConvTransp::iTranspCol;
- else
- AwIffConvTransp::rawTranspCol =
- static_cast<unsigned>(m_pPalette[AwIffConvTransp::iTranspCol].r)>>pixelFormat.redRightShift<<pixelFormat.redLeftShift
- |static_cast<unsigned>(m_pPalette[AwIffConvTransp::iTranspCol].g)>>pixelFormat.greenRightShift<<pixelFormat.greenLeftShift
- |static_cast<unsigned>(m_pPalette[AwIffConvTransp::iTranspCol].b)>>pixelFormat.blueRightShift<<pixelFormat.blueLeftShift;
- break;
- default:
- db_log3("AwCreateTexture(): ERROR: IFF mask field wrong");
- awTlLastErr = AW_TLE_BADFILEDATA;
- }
- }
- else
- {
- awTlLastErr = AW_TLE_CANTPALETTIZE; // no suitable chunk found
- db_log3("AwCreateTexture(): ERROR: No suitable IFF body chunk found");
- }
- }
- else
- {
- awTlLastErr = AW_TLE_BADFILEDATA;
- db_log3("AwCreateTexture(): ERROR: IFF file not loaded or contains no image data");
- }
-}
-
-AwTl::Colour * AwIffLoader::GetPalette()
-{
- return m_pPalette;
-}
-
-bool AwIffLoader::HasTransparentMask(bool bDefault)
-{
- if (m_listBodyChunks.size())
- {
- IFF::IlbmBmhdChunk * pHdr = static_cast<IFF::IlbmBmhdChunk *>(m_listBodyChunks.first_entry()->GetProperty("BMHD"));
- db_assert1(pHdr);
- return (IFF::IlbmBmhdChunk::MASK_TRANSPARENTCOL == pHdr->eMasking);
- }
- else
- return bDefault;
-}
-
-DWORD AwIffLoader::GetTransparentColour()
-{
- return AwIffConvTransp::rawTranspCol;
-}
-
-AwTl::PtrUnion AwIffLoader::GetRowPtr(unsigned /*nRow*/)
-{
- // the iff object has an internal buffer to which a pointer
- // is returned when we decode each row
- // unfortunately we have to cast constness away, but never mind
- return const_cast<unsigned *>(m_pBody->DecodeNextRow());
-}
-
-void AwIffLoader::LoadNextRow(AwTl::PtrUnion /*pRow*/)
-{
- // GetRowPtr() has called DecodeNextRow()
- // which has filled in the data already
- // so do nothing here
-}
-
-void AwIffLoader::ConvertRow(AwTl::PtrUnion pDest, unsigned nDestWidth, AwTl::PtrUnionConst pSrc, unsigned nSrcOffset, unsigned nSrcWidth, AwTl::Colour * pPalette db_code1(DB_COMMA unsigned nPaletteSize))
-{
- using namespace AwTl;
-
- // we have overridden this function for two reasons:
- // 1. The data type for each texel in the row is unsigned int
- // to allow for the fact that all images are palettized
- // with no limit on the palette size. The default
- // implementation would assume BYTE (unsigned char)
- // 2. The transparency flag and colour is stored in the
- // file and the transparency flag passed to AwCreateTexture()
- // is ignored. The transparent colour does not have to be 0,0,0
- // either
-
- db_assert1(pPalette);
- db_assert1(pPalette == m_pPalette);
- // we can still use GenericConvertRow though, using the conversion functors above
-
- if (pixelFormat.palettizedB)
- {
- GenericConvertRow<AwIffConvNull,unsigned>::Do(pDest, nDestWidth, pSrc.uintP+nSrcOffset, nSrcWidth);
- }
- else
- {
- switch (m_pHdr->eMasking)
- {
- case IFF::IlbmBmhdChunk::MASK_NONE:
- GenericConvertRow<AwIffConvNonTransp,unsigned>::Do(pDest, nDestWidth, pSrc.uintP+nSrcOffset, nSrcWidth, pPalette db_code1(DB_COMMA nPaletteSize));
- break;
- case IFF::IlbmBmhdChunk::MASK_TRANSPARENTCOL:
- GenericConvertRow<AwIffConvTransp,unsigned>::Do(pDest, nDestWidth, pSrc.uintP+nSrcOffset, nSrcWidth, pPalette db_code1(DB_COMMA nPaletteSize));
- break;
- default:
- db_log3("AwCreateTexture(): ERROR: IFF mask field wrong");
- awTlLastErr = AW_TLE_BADFILEDATA;
- }
- }
-}
-
-void AwIffLoader::OnFinishLoading(bool /*bSuccess*/)
-{
- if (m_bDecoding)
- {
- m_pBody->EndDecode();
- m_bDecoding = false;
- }
-}
-
-void AwIffLoader::OnFinishRestoring(bool /*bSuccess*/)
-{
- if (m_bDecoding)
- {
- m_pBody->EndDecode();
- m_bDecoding = false;
- }
-}
-
-AwBackupTexture * AwIffLoader::CreateBackupTexture()
-{
- // use the same object for restoring
- AddRef();
- return this;
-}
-
-// Valid file ID fields: 'FORM' 'LIST' 'CAT ' - we can load them all
-#ifdef _MSC_VER
- // VC5.0 tries to compile out code that is in a library
- // and it thinks isn't being used
- #line 427
-#endif
-AWTEXLD_IMPLEMENT_DYNCREATE("FORM",AwIffLoader)
-AWTEXLD_IMPLEMENT_DYNCREATE("LIST",AwIffLoader)
-AWTEXLD_IMPLEMENT_DYNCREATE("CAT ",AwIffLoader)