📄 imagehandle_tga.inl
字号:
//-----------------------------------------------------------------------------
inline bool FCImageHandle_Tga::LoadImageMemory (const BYTE* pStart, int nFileSize)
{
const TGAHEAD * pTga = (TGAHEAD*)pStart ;
if (!pStart)
return false ;
if ((pTga->byPalBits == 15) || (pTga->byPalBits == 16))
return false ; // 不支持15, 16位色调色板
// create image
FCObjImage * pImg = new FCObjImage ;
if (!pImg->Create (pTga->wWidth, pTga->wHeight, (pTga->byColorBits == 15) ? 16 : pTga->byColorBits))
{
delete pImg; return false ;
}
// set palette
const BYTE * pCurr = pStart + sizeof(TGAHEAD) + pTga->byID_Length ;
if (pTga->byPalType == 1)
{
if (pTga->wPalFirstNdx + pTga->wPalLength > 256)
{
delete pImg; return false ;
}
RGBQUAD pPal[256] = {0} ;
for (int i=0 ; i < pTga->wPalLength ; i++)
{
PCL_B(&pPal[pTga->wPalFirstNdx + i]) = *pCurr++ ;
PCL_G(&pPal[pTga->wPalFirstNdx + i]) = *pCurr++ ;
PCL_R(&pPal[pTga->wPalFirstNdx + i]) = *pCurr++ ;
if (pTga->byPalBits == 32)
PCL_A(&pPal[pTga->wPalFirstNdx + i]) = *pCurr++ ;
}
pImg->SetColorTable (0, 256, pPal) ;
}
// start decode
for (int i=0 ; i < pImg->Height() ; i++)
{
BYTE * pDest ;
if (pStart[17] & 0x20)
pDest = pImg->GetBits(i) ; // top to bottom
else
pDest = pImg->GetBits(pImg->Height() - 1 - i) ; // bottom to top
if ((pTga->byImageType == TGA_RLEPAL) || (pTga->byImageType == TGA_RLERGB) || (pTga->byImageType == TGA_RLEMONO)) // 压缩
{
pCurr = ::RLE_TGA_DecodeLine (pCurr, pImg->ColorBits(), pImg->Width(), pDest) ;
}
else // not-compressed
{
int nPitch = pImg->Width() * pImg->ColorBits() / 8 ;
memcpy (pDest, pCurr, nPitch) ;
pCurr += nPitch ;
}
}
PCL_PushObject (pImg) ; // pImg's ownership
return true ;
}
//-----------------------------------------------------------------------------
inline bool FCImageHandle_Tga::SaveImage (const char* szFileName, int nFlag)
{
if (m_SaveImg.empty())
return false ;
const FCObjImage &img = *m_SaveImg[0] ;
// validate
if ((img.ColorBits() != 8) && (img.ColorBits() != 16) && (img.ColorBits() != 24) && (img.ColorBits() != 32))
return false ;
// create image file
std::ofstream outFile (szFileName, std::ios::out|std::ios::binary|std::ios::trunc) ;
if (!outFile.is_open())
return false ;
// Initialize TGA Header
const BYTE fTgaInfo[] = {"PhoXo -- TGA"} ;
TGAHEAD TgaHead ;
memset (&TgaHead, 0, sizeof(TgaHead)) ;
TgaHead.byID_Length = sizeof(fTgaInfo) - 1 ; // tga size
TgaHead.byPalType = ((img.ColorBits() == 8) ? 1 : 0) ;
if (nFlag == -1)
TgaHead.byImageType = ((img.ColorBits() == 8) ? TGA_UCPAL : TGA_UCRGB) ;
else if (nFlag == 1)
TgaHead.byImageType = ((img.ColorBits() == 8) ? TGA_RLEPAL : TGA_RLERGB) ;
TgaHead.wPalFirstNdx = 0 ;
TgaHead.wPalLength = 256 ;
TgaHead.byPalBits = 24 ; // 调色板中每一颜色所占位数
TgaHead.wWidth = img.Width() ;
TgaHead.wHeight = img.Height() ;
TgaHead.byColorBits = (BYTE)img.ColorBits() ;
((BYTE*)&TgaHead)[17] = 0x20 ; // top to bottom
outFile.write ((char*)&TgaHead, sizeof(TGAHEAD)) ;
outFile.write ((char*)fTgaInfo, TgaHead.byID_Length) ;
// write palette
if (img.ColorBits() == 8)
{
RGBQUAD pPal[256] ;
img.GetColorTable (0, 256, pPal) ;
for (int i=0 ; i < 256 ; i++)
outFile.write ((char*)&pPal[i], 3) ;
}
// write pixels
const int nLineByte = img.ColorBits() * img.Width() / 8 ;
if (nFlag == -1)
{
// not compress
for (int y=0 ; y < img.Height() ; y++)
outFile.write ((char*)img.GetBits(y), nLineByte) ;
}
else if (nFlag == 1)
{
// RLE compress
PCL_array<BYTE> pStart (new BYTE[nLineByte * 2 + 4096]) ;
for (int y=0 ; y < img.Height() ; y++)
{
BYTE * pEn = ::RLE_TGA_EncodeLine (img.GetBits(y), img.ColorBits(), img.Width(), pStart.get()) ;
outFile.write ((char*)pStart.get(), pEn - pStart.get()) ;
}
}
return true ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -