tga writing function

Hi!

Can you help me? I need in good tga file writing function. Where can i found it ?

Thanks for help!

Bye!

http://openil.sourceforge.net/

Don’t know about good but…

typedef struct TGA_HEADER_TAG
{
BYTE bIDLen;
BYTE bCMAPType;
BYTE bIMGType; // TGA_RLE, TGA_A, TGA_RGB

WORD wCMAPFirstEntry;
WORD wCMAPLength;
BYTE bCMAPEntrySize;

WORD wIMGXOrigin;
WORD wIMGYOrigin;
WORD wIMGWidth;
WORD wIMGHeight;
BYTE bIMGBits;
BYTE bIMGDescBits;
} TGA_HEADER;

#define TGA_RGB 2 // This tells us it’s a normal RGB (really BGR) file
#define TGA_A 3 // This tells us it’s a ALPHA file
#define TGA_RLE 10 // This tells us that the targa is Run-Length Encoded (RLE)

void UTILITIES::SaveTGA(char *szFile, BYTE *pData, WORD wWidth, WORD wHeight, BYTE wBits)
{
TGA_HEADER tgaOutput;
FILE *fOutput;
BYTE bTemp;
BYTE bOut;
int nPos;
int nBase;
BYTE bCount = 0;

memset(&tgaOutput, 0, sizeof(TGA_HEADER));

tgaOutput.wIMGWidth = wWidth;
tgaOutput.wIMGHeight = wHeight;
tgaOutput.bIMGBits = wBits;

// Set the Image type.
switch (wBits)
{
case 8:
tgaOutput.bIMGType = TGA_A;
break;
case 16:
case 24:
case 32:
tgaOutput.bIMGType = TGA_RGB;
break;
}

if (utilConsole.variables[GUI_SAVERLE].bValue)
tgaOutput.bIMGType += 8;

fOutput = fopen(szFile, “wb”);
if (!fOutput)
return;

// We do this because of some stupid packing problem is mucking up the header.
fwrite(&tgaOutput.bIDLen, sizeof(BYTE), 1, fOutput);
fwrite(&tgaOutput.bCMAPType, sizeof(BYTE), 1, fOutput);
fwrite(&tgaOutput.bIMGType, sizeof(BYTE), 1, fOutput);
fwrite(&tgaOutput.wCMAPFirstEntry, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.wCMAPLength, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.bCMAPEntrySize, sizeof(BYTE), 1, fOutput);
fwrite(&tgaOutput.wIMGXOrigin, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.wIMGYOrigin, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.wIMGWidth, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.wIMGHeight, sizeof(WORD), 1, fOutput);
fwrite(&tgaOutput.bIMGBits, sizeof(BYTE), 1, fOutput);
fwrite(&tgaOutput.bIMGDescBits, sizeof(BYTE), 1, fOutput);

if (!utilConsole.variables[GUI_SAVERLE].bValue)
{
for (nPos = 0; nPos < wHeight * wWidth; nPos++)
{
switch (wBits)
{
case 8:
bTemp = (BYTE)(0xFF & ((int)pData[(4 * nPos) + 0] + (int)pData[(4 * nPos) + 1] +
(int)pData[(4 * nPos) + 1] + (int)pData[(4 * nPos) + 2]) / 4);
fwrite(&bTemp, 1, 1, fOutput);
break;
case 16:
bOut = (0x1F & pData[(4 * nPos) + 0]);
bTemp = (0xE0 & (pData[(4 * nPos) + 1] << 5));
bOut |= bTemp;
fwrite(&bOut, 1, 1, fOutput);
bOut = (0x03 & (pData[(4 * nPos) + 1] >> 3));
bTemp = (0x7C & (pData[(4 * nPos) + 2] << 2));
bOut |= bTemp;
fwrite(&bOut, 1, 1, fOutput);
break;
case 24:
bOut = pData[(4 * nPos) + 0];
fwrite(&bOut, 1, 1, fOutput);
bOut = pData[(4 * nPos) + 1];
fwrite(&bOut, 1, 1, fOutput);
bOut = pData[(4 * nPos) + 2];
fwrite(&bOut, 1, 1, fOutput);
break;
case 32:
bOut = pData[(4 * nPos) + 0];
fwrite(&bOut, 1, 1, fOutput);
bOut = pData[(4 * nPos) + 1];
fwrite(&bOut, 1, 1, fOutput);
bOut = pData[(4 * nPos) + 2];
fwrite(&bOut, 1, 1, fOutput);
bOut = pData[(4 * nPos) + 3];
fwrite(&bOut, 1, 1, fOutput);
break;
}
}
}
else
{
for (int nY = 0; nY < (int)wHeight; nY++)
{
nBase = (int)wWidth * nY;
for (nPos = 0; nPos < (int)wWidth; nPos += (0x7F & bCount) + 1)
{
bCount = 0;
if (pData[(4 * (nBase + nPos)) + 0] != pData[(4 * (nBase + nPos + 1)) + 0] | |
pData[(4 * (nBase + nPos)) + 1] != pData[(4 * (nBase + nPos + 1)) + 1] | |
pData[(4 * (nBase + nPos)) + 2] != pData[(4 * (nBase + nPos + 1)) + 2] | |
pData[(4 * (nBase + nPos)) + 3] != pData[(4 * (nBase + nPos + 1)) + 3])
{
while (nPos + (int)bCount < (int)wWidth && bCount < 128 &&
(pData[(4 * (nBase + nPos + (int)bCount)) + 0] != pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 0] | |
pData[(4 * (nBase + nPos + (int)bCount)) + 1] != pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 1] | |
pData[(4 * (nBase + nPos + (int)bCount)) + 2] != pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 2] | |
pData[(4 * (nBase + nPos + (int)bCount)) + 3] != pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 3]))
{
bCount++;
}
bCount–;
if (nPos + (int)bCount + 1 < (int)wWidth && bCount > 0)
bCount–;
fwrite(&bCount, sizeof(BYTE), 1, fOutput);
fwrite(&pData[4 * (nBase + nPos)], sizeof(BYTE) * (int)(bCount + 1) * 4, 1, fOutput);
}
else
{
while (nPos + (int)bCount < (int)wWidth && bCount < 128 &&
(pData[(4 * (nBase + nPos + (int)bCount)) + 0] == pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 0] &&
pData[(4 * (nBase + nPos + (int)bCount)) + 1] == pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 1] &&
pData[(4 * (nBase + nPos + (int)bCount)) + 2] == pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 2] &&
pData[(4 * (nBase + nPos + (int)bCount)) + 3] == pData[(4 * (nBase + nPos + 1 + (int)bCount)) + 3]))
{
bCount++;
}
bCount–;
if (nPos + (int)bCount + 1 < (int)wWidth && bCount > 0)
bCount–;
bCount |= 0x80;
fwrite(&bCount, sizeof(BYTE), 1, fOutput);
fwrite(&pData[4 * (nBase + nPos)], sizeof(BYTE) * 4, 1, fOutput);
}
}
}

  }

fclose(fOutput);

} // End of UTILITIES::SaveTGA()

Does anyone use the TGA extension / developer areas? I am writing it in my writer and I think it would be useful to take them in consideration.

There may be a way to store HILO textures in 16bit format on disk… something like openEXR for dummies. You know, the open source hdr file format…

Originally posted by Obli:
Does anyone use the TGA extension / developer areas? I am writing it in my writer and I think it would be useful to take them in consideration.

TGA is still a much used extension.
that’s because it’s easy to read and can store RGBA… and becasue all the graphics-designers are still using it.

Originally posted by AdrianD:
TGA is still a much used extension.
that’s because it’s easy to read and can store RGBA… and becasue all the graphics-designers are still using it.

TGA used as extension? What do you exactly mean? I wonder how a file format can be an “extension” sure it can be used in application “extending” the range of file formats allowed (probably the first format supported to load textures) but I am referring to the TGA extension area or the TGA developer area. I don’t have the spec here right now so I cannot tell exactly how the TGA spec calls / numbers those fields.
The come after the image data and before the footer. I am just wondering if anyone uses those two areas (or at least have support for them) - they would have some interesting functionalities.

Originally posted by Obli:
[b]Does anyone use the TGA extension / developer areas? I am writing it in my writer and I think it would be useful to take them in consideration.

There may be a way to store HILO textures in 16bit format on disk… something like openEXR for dummies. You know, the open source hdr file format…[/b]

Yeah, actually. I think this is one of the coolest features of the TGA format. You can have all kinds of custom data in the file in addition to the image. I actually use it to provide metrics for skin and/or font images; like x, y, width, height for elements of the font or skin. Rather than hard code info like this into the application, you can have the TGA file specify it’s own metrics and just parse them out.