#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; iTransfer(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(pHdr)->width; eCompression = static_cast(pHdr)->eCompression; nBitPlanes = static_cast(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>b & 1; if (7==(x&7)) *pBuf++ = static_cast(byte); } if (nWidth & 7) { byte <<= 8-(nWidth & 7); *pBuf = static_cast(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 (jAppend(static_cast(0x101-j)); pEncodeDst->Append(*pBuf); pBuf += j; i -= j; nSizeCprss += 2; } else { unsigned j=2; while (jAppend(static_cast(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; x0x80) { repcnt = 0x100 - byte; byte = *pDecodeSrc; } else goto REPEAT_SKIP; } } pDecodeDst[x] |= (byte>>7 & 1)<>7 & 1)<Transfer(xHotSpot); pArchv->Transfer(yHotSpot); } }