2019-08-23 11:56:54 -07:00
|
|
|
#include "TGAData.h"
|
|
|
|
|
|
|
|
USING_NS_BF;
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
|
|
bool TGAData::ReadData()
|
|
|
|
{
|
|
|
|
size_t step = sizeof(unsigned char) * 2;
|
|
|
|
//CC_BREAK_IF((step + sizeof(unsigned char)) > bufSize);
|
|
|
|
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
struct Header
|
|
|
|
{
|
|
|
|
char mIdLength;
|
|
|
|
char mColourMapType;
|
|
|
|
char mDataTypeCode;
|
|
|
|
short int mColourMapOrigin;
|
|
|
|
short int mColourMapLength;
|
|
|
|
char mColourMapDepth;
|
|
|
|
short int mXOrigin;
|
|
|
|
short int mYOrigin;
|
|
|
|
short mWidth;
|
|
|
|
short mHeight;
|
|
|
|
char mBitsPerPixel;
|
|
|
|
char mImageDescriptor;
|
|
|
|
};
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
Header* hdr = (Header*)mSrcData;
|
|
|
|
|
|
|
|
/*memcpy(&aType, mSrcData, sizeof(unsigned char));
|
|
|
|
|
|
|
|
step += sizeof(unsigned char) * 2;
|
|
|
|
step += sizeof(signed short) * 4;
|
|
|
|
//CC_BREAK_IF((step + sizeof(signed short) * 2 + sizeof(unsigned char)) > bufSize);
|
|
|
|
memcpy(&width, mSrcData + step, sizeof(signed short));
|
|
|
|
memcpy(&height, mSrcData + step + sizeof(signed short), sizeof(signed short));
|
|
|
|
memcpy(&pixelDepth, mSrcData + step + sizeof(signed short) * 2, sizeof(unsigned char));
|
|
|
|
|
|
|
|
step += sizeof(unsigned char);
|
|
|
|
step += sizeof(signed short) * 2;
|
|
|
|
//CC_BREAK_IF((step + sizeof(unsigned char)) > bufSize);
|
|
|
|
unsigned char cGarbage;
|
|
|
|
memcpy(&cGarbage, mSrcData + step, sizeof(unsigned char));
|
|
|
|
|
|
|
|
bool flipped = (cGarbage & 0x20) != 0;*/
|
|
|
|
|
|
|
|
bool flipped = (hdr->mImageDescriptor & 0x20) != 0;
|
|
|
|
|
|
|
|
mWidth = hdr->mWidth;
|
2021-05-12 07:24:29 -04:00
|
|
|
mHeight = hdr->mHeight;
|
2019-08-23 11:56:54 -07:00
|
|
|
mBits = new uint32[mWidth * mHeight];
|
|
|
|
|
|
|
|
if (hdr->mDataTypeCode == 10) // RLE
|
|
|
|
{
|
|
|
|
int total;
|
|
|
|
size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
|
|
|
|
|
|
|
|
// mode equal the number of components for each pixel
|
|
|
|
int aMode = hdr->mBitsPerPixel / 8;
|
|
|
|
// total is the number of unsigned chars we'll have to read
|
|
|
|
total = mHeight * mWidth * aMode;
|
|
|
|
|
|
|
|
size_t dataSize = sizeof(unsigned char) * total;
|
|
|
|
//CC_BREAK_IF((step + dataSize) > bufSize);
|
|
|
|
|
|
|
|
uint8* srcPtr = mSrcData + step;
|
|
|
|
uint32* destPtr = mBits;
|
|
|
|
|
|
|
|
int destAdd = 0;
|
|
|
|
if (!flipped)
|
|
|
|
{
|
|
|
|
destPtr = mBits + mWidth*(mHeight - 1);
|
|
|
|
destAdd = -mWidth * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aMode == 4)
|
|
|
|
{
|
|
|
|
int y = 0;
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
readSpanHeader:
|
|
|
|
int spanLen = 0;
|
|
|
|
uint32 spanColor = 0;
|
|
|
|
|
|
|
|
uint8 spanHeader = *(srcPtr++);
|
|
|
|
spanLen = (spanHeader & 0x7F) + 1;
|
|
|
|
if ((spanHeader & 0x80) != 0)
|
|
|
|
{
|
|
|
|
// Repeat color
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = *(srcPtr++);
|
|
|
|
|
|
|
|
if (mWantsAlphaPremultiplied)
|
|
|
|
{
|
|
|
|
r = (r * a) / 255;
|
|
|
|
g = (g * a) / 255;
|
|
|
|
b = (b * a) / 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
spanColor = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
|
|
|
|
for (; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
if (spanLen == 0)
|
|
|
|
goto readSpanHeader;
|
|
|
|
*(destPtr++) = spanColor;
|
|
|
|
spanLen--;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
if (spanLen == 0)
|
|
|
|
goto readSpanHeader;
|
|
|
|
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = *(srcPtr++);
|
|
|
|
|
|
|
|
if (mWantsAlphaPremultiplied)
|
|
|
|
{
|
|
|
|
r = (r * a) / 255;
|
|
|
|
g = (g * a) / 255;
|
|
|
|
b = (b * a) / 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
|
|
|
|
spanLen--;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-12 07:24:29 -04:00
|
|
|
NOP;
|
|
|
|
}
|
|
|
|
else if (aMode == 3)
|
|
|
|
{
|
|
|
|
int y = 0;
|
|
|
|
int x = 0;
|
|
|
|
|
|
|
|
readSpanHeader3:
|
|
|
|
int spanLen = 0;
|
|
|
|
uint32 spanColor = 0;
|
|
|
|
|
|
|
|
uint8 spanHeader = *(srcPtr++);
|
|
|
|
spanLen = (spanHeader & 0x7F) + 1;
|
|
|
|
if ((spanHeader & 0x80) != 0)
|
|
|
|
{
|
|
|
|
// Repeat color
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = 255;
|
|
|
|
|
|
|
|
spanColor = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
|
|
|
|
for (; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
if (spanLen == 0)
|
|
|
|
goto readSpanHeader3;
|
|
|
|
*(destPtr++) = spanColor;
|
|
|
|
spanLen--;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
if (spanLen == 0)
|
|
|
|
goto readSpanHeader3;
|
|
|
|
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = 255;
|
|
|
|
|
|
|
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
|
|
|
|
spanLen--;
|
|
|
|
}
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
NOP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int total;
|
|
|
|
size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
|
|
|
|
|
|
|
|
// mode equal the number of components for each pixel
|
|
|
|
int aMode = hdr->mBitsPerPixel / 8;
|
|
|
|
// total is the number of unsigned chars we'll have to read
|
|
|
|
total = mHeight * mWidth * aMode;
|
|
|
|
|
|
|
|
size_t dataSize = sizeof(unsigned char) * total;
|
|
|
|
//CC_BREAK_IF((step + dataSize) > bufSize);
|
|
|
|
|
|
|
|
uint8* srcPtr = mSrcData + step;
|
|
|
|
uint32* destPtr = mBits;
|
|
|
|
|
|
|
|
int destAdd = 0;
|
|
|
|
if (!flipped)
|
|
|
|
{
|
|
|
|
destPtr = mBits + mWidth*(mHeight - 1);
|
|
|
|
destAdd = -mWidth*2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aMode == 4)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = *(srcPtr++);
|
|
|
|
|
|
|
|
if (mWantsAlphaPremultiplied)
|
|
|
|
{
|
|
|
|
r = (r * a) / 255;
|
|
|
|
g = (g * a) / 255;
|
|
|
|
b = (b * a) / 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
}
|
|
|
|
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aMode == 3)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
int b = *(srcPtr++);
|
|
|
|
int g = *(srcPtr++);
|
|
|
|
int r = *(srcPtr++);
|
|
|
|
int a = 255;
|
|
|
|
|
|
|
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
}
|
|
|
|
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (aMode == 1)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < mHeight; y++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < mWidth; x++)
|
|
|
|
{
|
|
|
|
int a = *(srcPtr++);
|
|
|
|
|
|
|
|
#ifdef BF_PLATFORM_WINDOWS
|
|
|
|
// Only windows has alpha correction for colored fonts (ATM)
|
|
|
|
//int r = (int) (pow(a / 255.0f, 0.7f) * 255.0f);
|
|
|
|
int r = (int)(pow(a / 255.0f, 1.2f) * 255.0f);
|
|
|
|
//int r = a;
|
|
|
|
int g = 255;
|
|
|
|
int b = 255;
|
|
|
|
#else
|
|
|
|
int r = a;
|
|
|
|
int g = a;
|
|
|
|
int b = a;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
|
|
|
|
}
|
|
|
|
|
|
|
|
destPtr += destAdd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//memcpy(psInfo->imageData, Buffer + step, dataSize);
|
|
|
|
|
|
|
|
// mode=3 or 4 implies that the image is RGB(A). However TGA
|
|
|
|
// stores it as BGR(A) so we'll have to swap R and B.
|
|
|
|
/*if (mode >= 3)
|
|
|
|
{
|
|
|
|
for (i=0; i < total; i+= mode)
|
|
|
|
{
|
|
|
|
aux = psInfo->imageData[i];
|
|
|
|
psInfo->imageData[i] = psInfo->imageData[i+2];
|
|
|
|
psInfo->imageData[i+2] = aux;
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
mAlphaPremultiplied = mWantsAlphaPremultiplied;
|
|
|
|
return true;
|
|
|
|
}
|