avp/3dc/win95/iff_ILBM.cpp
Rebellion Developments 218ca90543 Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from:
https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code

All text files were converted to Unix format.
2019-08-19 05:45:17 +02:00

327 lines
6.2 KiB
C++

#include "advwin32.h"
#include "iff_ILBM.hpp"
IFF_IMPLEMENT_DYNCREATE("ILBM","BMHD",IlbmBmhdChunk)
IFF_IMPLEMENT_DYNCREATE("ILBM","CMAP",IlbmCmapChunk)
IFF_IMPLEMENT_DYNCREATE("ILBM","BODY",IlbmBodyChunk)
IFF_IMPLEMENT_DYNCREATE("ILBM","GRAB",IlbmGrabChunk)
namespace IFF
{
void IlbmBmhdChunk::Serialize(Archive * pArchv)
{
pArchv->Transfer(width);
pArchv->Transfer(height);
pArchv->Transfer(xTopLeft);
pArchv->Transfer(yTopLeft);
pArchv->Transfer(nBitPlanes);
pArchv->Transfer(eMasking);
pArchv->Transfer(eCompression);
pArchv->Transfer(flags);
pArchv->Transfer(iTranspCol);
pArchv->Transfer(xAspectRatio);
pArchv->Transfer(yAspectRatio);
pArchv->Transfer(xMax);
pArchv->Transfer(yMax);
}
void IlbmCmapChunk::Serialize(Archive * pArchv)
{
if (pArchv->m_bIsLoading)
{
nEntries = pArchv->GetSize()/3;
if (pTable) delete[] pTable;
pTable = new RGBTriple [nEntries];
}
for (unsigned i=0; i<nEntries; ++i)
pArchv->Transfer(pTable[i]);
}
IlbmCmapChunk::~IlbmCmapChunk()
{
if (pTable) delete[] pTable;
}
void IlbmBodyChunk::Serialize(Archive * pArchv)
{
if (pArchv->m_bIsLoading)
{
nSize = pArchv->GetSize();
if (pData) delete[] pData;
pData = new UBYTE [nSize];
}
pArchv->TransferBlock(pData,nSize);
}
bool IlbmBodyChunk::GetHeaderInfo() const
{
Chunk * pHdr = GetProperty("BMHD");
if (!pHdr)
{
return false;
}
nWidth = static_cast<IlbmBmhdChunk *>(pHdr)->width;
eCompression = static_cast<IlbmBmhdChunk *>(pHdr)->eCompression;
nBitPlanes = static_cast<IlbmBmhdChunk *>(pHdr)->nBitPlanes;
return true;
}
#ifndef IFF_READ_ONLY
bool IlbmBodyChunk::BeginEncode()
{
if (!GetHeaderInfo())
{
return false;
}
pEncodeDst = new DataBlock;
pEncodeSrc = new UBYTE [(nWidth+7)/8];
nSizeNonCprss = 0;
nSizeCprss = 0;
return true;
}
// The uninitialised part of byte is shifted out.
#ifdef _MSC_VER
#pragma warning(disable: 4701)
#endif
bool IlbmBodyChunk::EncodeNextRow(unsigned const * pRow)
{
if (!pEncodeDst) return false;
for (unsigned b=0; b<nBitPlanes; ++b)
{
UBYTE * pBuf = pEncodeSrc;
unsigned byte;
for (unsigned x=0; x<nWidth; ++x)
{
byte <<= 1;
byte |= pRow[x]>>b & 1;
if (7==(x&7)) *pBuf++ = static_cast<UBYTE>(byte);
}
if (nWidth & 7)
{
byte <<= 8-(nWidth & 7);
*pBuf = static_cast<UBYTE>(byte);
}
if (eCompression)
{
nSizeNonCprss += (nWidth+7)/8;
UBYTE const * pBuf = pEncodeSrc;
unsigned i=(nWidth+7)/8;
while (i)
{
if (1==i)
{
pEncodeDst->Append(0);
pEncodeDst->Append(*pBuf);
nSizeCprss += 2;
i=0;
}
else if (i>1)
{
if (pBuf[0]==pBuf[1])
{
unsigned j=2;
while (j<i && j<0x80 && pBuf[j-1]==pBuf[j])
++j;
pEncodeDst->Append(static_cast<UBYTE>(0x101-j));
pEncodeDst->Append(*pBuf);
pBuf += j;
i -= j;
nSizeCprss += 2;
}
else
{
unsigned j=2;
while (j<i && j<0x80 && (pBuf[j]!=pBuf[j-1] || pBuf[j-1]!=pBuf[j-2]))
++j;
if (j<i && pBuf[j]==pBuf[j-1] && pBuf[j-1]==pBuf[j-2])
j-=2;
pEncodeDst->Append(static_cast<UBYTE>(j-1));
pEncodeDst->Append(pBuf,j);
pBuf += j;
i -= j;
nSizeCprss += j+1;
}
}
}
}
else
{
pEncodeDst->Append(pEncodeSrc,(nWidth+7)/8);
}
}
return true;
}
#ifdef _MSC_VER
#pragma warning(default: 4701)
#endif
bool IlbmBodyChunk::EndEncode()
{
if (!pEncodeDst) return false;
if (pData) delete[] pData;
nSize = pEncodeDst->GetDataSize();
pData = new UBYTE[nSize];
memcpy(pData,pEncodeDst->GetDataPtr(),nSize);
delete pEncodeDst;
delete[] pEncodeSrc;
pEncodeDst = NULL;
pEncodeSrc = NULL;
return true;
}
#endif
bool IlbmBodyChunk::BeginDecode() const
{
if (pDecodeDst) delete[] pDecodeDst;
if (!pData || !GetHeaderInfo())
{
pDecodeSrc = NULL;
pDecodeDst = NULL;
return false;
}
pDecodeSrc = pData;
nRemaining = nSize;
pDecodeDst = new unsigned [nWidth];
return pData != NULL;
}
// The uninitialised part of pDecodeDst is shifted out.
#ifdef _MSC_VER
#pragma warning(disable: 4701)
#endif
unsigned const * IlbmBodyChunk::DecodeNextRow() const
{
if (!pDecodeSrc || !pDecodeDst) return NULL;
for (unsigned x=0; x<nWidth; ++x)
pDecodeDst[x]=0;
if (eCompression)
{
unsigned repcnt = 0;
unsigned rawcnt = 0;
for (unsigned b=0; b<nBitPlanes; ++b)
{
unsigned byte;
for (unsigned x=0; x<nWidth; ++x)
{
if (!(x&7))
{
if (!nRemaining) return NULL;
REPEAT_SKIP:
byte = *pDecodeSrc;
if (rawcnt)
{
--rawcnt;
++pDecodeSrc;
--nRemaining;
}
else if (repcnt)
{
--repcnt;
if (!repcnt)
{
++pDecodeSrc;
--nRemaining;
}
}
else // byte is control byte
{
++pDecodeSrc;
--nRemaining;
if (!nRemaining) return NULL;
if (byte<0x80)
{
rawcnt = byte;
byte = *pDecodeSrc++;
--nRemaining;
}
else if (byte>0x80)
{
repcnt = 0x100 - byte;
byte = *pDecodeSrc;
}
else goto REPEAT_SKIP;
}
}
pDecodeDst[x] |= (byte>>7 & 1)<<b;
byte <<= 1;
}
}
}
else
{
for (unsigned b=0; b<nBitPlanes; ++b)
{
unsigned byte;
for (unsigned x=0; x<nWidth; ++x)
{
if (!(x&7))
{
if (!nRemaining) return NULL;
byte = *pDecodeSrc++;
--nRemaining;
}
pDecodeDst[x] |= (byte>>7 & 1)<<b;
byte <<= 1;
}
}
}
return pDecodeDst;
}
#ifdef _MSC_VER
#pragma warning(default: 4701)
#endif
IlbmBodyChunk::~IlbmBodyChunk()
{
if (pData) delete[] pData;
if (pDecodeDst) delete[] pDecodeDst;
#ifndef IFF_READ_ONLY
if (pEncodeDst) delete pEncodeDst;
if (pEncodeSrc) delete[] pEncodeSrc;
#endif
}
void IlbmGrabChunk::Serialize(Archive * pArchv)
{
pArchv->Transfer(xHotSpot);
pArchv->Transfer(yHotSpot);
}
}