📄 tga.cpp
字号:
// ==========================================================================================================
//
// BREW v2.0+ OPENGLES MICROENGINE
//
// ----------------------------------------
//
// Written by Vander Nunes
//
// ==========================================================================================================
#include "tga.h"
//
CTGA::CTGA()
{
ClearHeader();
m_pData = NULL;
m_pPalette = NULL;
}
//
CTGA::~CTGA()
{
Reset();
}
//
void CTGA::Reset()
{
if (m_pData != NULL)
delete [] m_pData;
if (m_pPalette != NULL)
delete [] m_pPalette;
m_pData = NULL;
m_pPalette = NULL;
ClearHeader();
}
//
void CTGA::ClearHeader()
{
m_Header.jIIFSize = 0;
m_Header.jMapType = 0;
m_Header.jImgType = 2;
for (int i=0; i<5; i++)
m_Header.jPad[i] = 0;
m_Header.wXOrigin = 0;
m_Header.wYOrigin = 0;
m_Header.wWidth = 0;
m_Header.wHeight = 0;
m_Header.jDepth = 0;
m_Header.jDescriptor = 0;
}
// load from a pack
int CTGA::Load(AEEApplet* pApplet, char* szPack, char* szFile)
{
CVfs Vfs;
if (!Vfs.Unpack(szPack, szFile, pApplet)) return 0;
LoadFromVfs(&Vfs);
Vfs.Finish();
return 1;
}
// load from virtual file system
int CTGA::LoadFromVfs(CVfs* pVfs)
{
// clear image if there is one already loaded
Reset();
// read the header
pVfs->Read(&m_Header,sizeof(tTGAHeader));
// only uncompressed palettized (1) and RGB (2) formats are supported
if (m_Header.jImgType != 1 && m_Header.jImgType != 2)
{
ClearHeader();
return 0;
}
// supports 8/24/32 color depths only
if (m_Header.jDepth != 8 && m_Header.jDepth != 24 && m_Header.jDepth != 32)
{
ClearHeader();
return 0;
}
// image size in bytes, not including palette
DWORD dwSize = m_Header.wWidth*m_Header.wHeight*(m_Header.jDepth/8);
// allocate space for pixels
m_pData = new BYTE[dwSize];
if (!m_pData)
{
ClearHeader();
return 0;
}
// allocate space for palette
if (m_Header.jDepth == 8)
{
// requires a 256 colors palette preceding the pixel data
m_pPalette = new BYTE[768];
if (!m_pPalette)
{
delete [] m_pData;
m_pData = NULL;
ClearHeader();
return 0;
}
}
int t=0, p=0;
WORD wPixelSize = m_Header.jDepth/8;
// read palette
if (m_Header.jDepth == 8)
{
// this is 0 to 255 mapped colors, in BGR format.
for (p=0; p<768; p+=3)
{
// read BGR
byte rgb[3];
pVfs->Read(rgb,3);
// invert to RGB
m_pPalette[p+0] = rgb[2];
m_pPalette[p+1] = rgb[1];
m_pPalette[p+2] = rgb[0];
}
// read pixels (indexes)
for (p=m_Header.wHeight-1; p>=0; p--)
{
// left to right
t = p * (m_Header.wWidth*wPixelSize);
pVfs->Read(&m_pData[t],m_Header.wWidth*wPixelSize);
}
}
else
{
// read ABGR
for (p=m_Header.wHeight-1; p>=0; p--)
{
// left to right ABGR
t = p * (m_Header.wWidth*wPixelSize);
for (WORD x=0; x<m_Header.wWidth; x++)
{
for (BYTE c=1; c<=wPixelSize; c++)
{
pVfs->Read(&m_pData[t + (wPixelSize - c)],1);
}
t += wPixelSize;
}
}
}
return 1;
}
// initialize from an existing memory pixel array
int CTGA::Set(WORD wWidth, WORD wHeight, BYTE jDepth, BYTE *pData)
{
// supports only 8/16/24/32 color depths
if (jDepth != 8 && jDepth != 16 && jDepth != 24 && jDepth != 32)
return 0;
Reset();
// image size in bytes, not including palette
DWORD dwSize = wWidth*wHeight*(jDepth>>3);
m_pData = new BYTE[dwSize];
if (!m_pData) return 0;
if (jDepth == 8)
{
// requires a 256 colors palette following the pixel data
m_pPalette = new BYTE[768];
if (!m_pPalette)
{
delete [] m_pData;
m_pData = NULL;
return 0;
}
m_Header.jImgType = 1;
}
else
m_Header.jImgType = 2;
// space is allocated, copy the passed pixel array to it's own buffers
API_MEMCPY(m_pData,pData,dwSize);
if (m_pPalette)
API_MEMCPY(m_pPalette,&pData[dwSize],768);
// update it's internal members
m_Header.wWidth = wWidth;
m_Header.wHeight = wHeight;
m_Header.jDepth = jDepth;
// bit mapped descriptor
// 0-3: alpha channel size
// 4: reserved (0)
// 5: origin (0)
// 6-7: interleaving (0)
if (m_Header.jDepth != 32)
// assume image doesn't have an alpha channel
m_Header.jDescriptor = 0;
else
// image has an alpha channel of 8 bits
m_Header.jDescriptor = 8;
return 1;
}
// -------------------------------------------------------------------
// Converts from 8bit palettized to 24bit true-color format
// -------------------------------------------------------------------
int CTGA::Unpalettize()
{
if (m_Header.jDepth != 8) return 0;
BYTE* m_pNewData = m_pData;
DWORD dwSize = Width() * Height();
m_pData = new BYTE[dwSize*3];
DWORD p = 0;
for (DWORD x=0; x<dwSize; x++)
{
WORD wIdx = m_pNewData[x] * 3;
BYTE r = m_pPalette[wIdx+0];
BYTE g = m_pPalette[wIdx+1];
BYTE b = m_pPalette[wIdx+2];
m_pData[p++] = r;
m_pData[p++] = g;
m_pData[p++] = b;
}
// change image format
m_Header.jDepth = 24;
m_Header.jImgType = 2;
// release old memory
delete [] m_pPalette; m_pPalette = NULL;
delete [] m_pNewData; m_pNewData = NULL;
return 1;
}
// Resize to half-size
void CTGA::HalfSize()
{
DWORD dwSize = Width() * Height();
DWORD p = 0;
switch (m_Header.jDepth)
{
case 8:
{
for (DWORD x=0; x<dwSize; x+=2)
m_pData[p++] = m_pData[x];
break;
}
case 24:
{
for (DWORD x=0; x<dwSize; x+=6)
{
m_pData[p++] = m_pData[x];
m_pData[p++] = m_pData[x+1];
m_pData[p++] = m_pData[x+2];
}
break;
}
case 32:
{
for (DWORD x=0; x<dwSize; x+=8)
{
m_pData[p++] = m_pData[x];
m_pData[p++] = m_pData[x+1];
m_pData[p++] = m_pData[x+2];
m_pData[p++] = m_pData[x+3];
}
break;
}
}
m_Header.wWidth >>= 1;
m_Header.wHeight >>= 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -