1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
| // Purpose: loads a tga file into the passed texture object txTexture.
// In: ppdPixelData : CPixelData pointer, which will point to the created CPixelData object with the bitdata.
// pszFilename : tga file to load
// piWidth : pointer to int wherein the width of the picture loaded should be stored
// piHeight : pointer to int wherein the height of the picture loaded should be stored
// i3DDepth : 3D depth of texture. For 3D texture support.
// bCreateAlphaFromColor: if true, the greyvalue of RGB is used to create the A(lpha) value
// Out: SYS_OK : ppdPixelData is filled.
// Errorcode: if something went wrong.
// ppdPixelData will point to the CPixelData object with the bitdata loaded.
// Additional Info: - Converts all bitmap data to 24bit RGB triplets (because OpenGL wants that)
// - Only true color (24 bit/32 bit) are supported. (type 2) TGA is added for alphareading purposes.
// - When bCreateAlphaFromColor is true, the eventually available alphabyte is ignored.
// - XYorigin is ignored. (0,0) is left lower corner)
//
// Uses ConvertTGAtoRGBA() for dataconversion.
int
DoImportTGA(CPixelData **ppdPixelData, const char *pszFilename, int *piWidth, int *piHeight, int i3DDepth, bool bCreateAlphaFromColor)
{
int iHeight, iWidth, iResult;
byte *pTextureBuffer, *pTGAFile;
bool bHasAlpha;
CPixelData *pPD;
// load file.
pTGAFile = DEMOGL_FileLoad(pszFilename);
if(!pTGAFile)
{
// open didn't succeed
return SYS_TGA_LOAD_FAILED;
}
// Check if we have the right type of file.
if(pTGAFile[2] !=2)
{
// invalid format
DEMOGL_FileFree(pTGAFile);
return SYS_TGA_INVALID_FORMAT;
}
// SHITMACINTELCRAP. An integer is 4 bytes. lo-hi shit is reversed due to intel weirdness.
iWidth = int(pTGAFile[12] | ((int)pTGAFile[13] << 8));
iHeight = int(pTGAFile[14] | ((int)pTGAFile[15] << 8));
bHasAlpha=false;
// Create pixeldata object for the bitdata
pPD = new CPixelData(iWidth * iHeight * 4);
// check if creation did go well...
if(!pPD)
{
DEMOGL_FileFree(pTGAFile);
return SYS_MEM_ALLOC_FAIL;
}
pTextureBuffer = pPD->GetBitData();
// Convert. Retrieve if the texturedata contains an alphachannel
iResult=ConvertTGAtoRGBA(pTGAFile, pTextureBuffer,iWidth, iHeight, bCreateAlphaFromColor, &bHasAlpha);
// clean up
DEMOGL_FileFree(pTGAFile);
// Set HasAlpha bit.
pPD->SetbHasAlpha(bHasAlpha);
*ppdPixelData=pPD;
// report back the width and height of the bitmap loaded
*piWidth=iWidth;
*piHeight=iHeight;
return iResult;
}
// Purpose: converts a buffer that contains a TGA file to RGBA data.
// Gets: pTGAFile, bytepointer, pointer to the TGAfile in memory
// Gets: pRGBABuffer, bytepointer, pointer to pre-allocated RGBAbuffer. Should be of the size iWidth*iHeight*4
// No boundary checks are made!
// Gets: iWidth, iHeight, ints, with and height of picture
// Gets: bCreateAlphaFromColor, bool, if true the color of the pixel will be used to create the alphabyte, otherwise
// the alphabyte in the pixelitself is used, if present, otherwise 0xFF is used.
// Returns: SYS_OK if all went well, SYS_NOK otherwise.
// Returns in bHasAlpha true if the texturedata contains one or more pixels with an alphachannel or false if not.
int
ConvertTGAtoRGBA(byte *pTGAFile, byte *pRGBABuffer, int iWidth, int iHeight, bool bCreateAlphaFromColor, bool *bHasAlpha)
{
int i,j,iBytesPerPixel;
bool bAlphaBytesInFile;
byte *pPixelData;
byte byR, byG, byB, byAlpha;
if(!pRGBABuffer)
{
return SYS_NOK;
}
if(!pTGAFile)
{
return SYS_NOK;
}
iBytesPerPixel = pTGAFile[16] / 8;
bAlphaBytesInFile = ((pTGAFile[17] & 0x0F) == 8);
// now we have to skip the colormap and identification IF present.
pPixelData = pTGAFile;
if(pTGAFile[1]!=0)
{
// there is a colormap. Ignore it. Get the length and add this to pPixelData
pPixelData += (int)(pTGAFile[3] | ((int)pTGAFile[4] << 8)) + ((int)(pTGAFile[5] | ((int)pTGAFile[6] << 8)) * pTGAFile[7]);
}
else
{
// there is no colormap. perhaps an identification. skip it.
pPixelData = pTGAFile + pTGAFile[0] + 18;
}
// reverse the order of the data by copying the data reverse to the texturememory reserved in the
// texture object. Copy pixel for pixel the data towards the texture space in the texture object
// because we don't support 1 and 4 color tga files, we don't have to worry about alignbits.
for(i=0, *bHasAlpha=bCreateAlphaFromColor; i<iHeight;i++)
{
for(j=0;j<iWidth;j++)
{
// is stored as BGRA
byR = pPixelData[(i * iWidth*iBytesPerPixel) + (j * iBytesPerPixel)+2]; // R
byG = pPixelData[(i * iWidth*iBytesPerPixel) + (j * iBytesPerPixel)+1]; // G
byB = pPixelData[(i * iWidth*iBytesPerPixel) + (j * iBytesPerPixel)]; // B
pRGBABuffer[(i * iWidth * 4) + (j * 4)] = byR; // R
pRGBABuffer[(i * iWidth * 4) + (j * 4)+1] = byG; // G
pRGBABuffer[(i * iWidth * 4) + (j * 4)+2] = byB; // B
if(bCreateAlphaFromColor)
{
byAlpha = (byte)((0.35f * byR) + (0.45f * byG) + (0.20f * byB));
}
else
{
if(bAlphaBytesInFile)
{
byAlpha = pPixelData[(i * iWidth * iBytesPerPixel) + (j * iBytesPerPixel)+3];
*bHasAlpha|=(byAlpha<0xFF);
}
else
{
byAlpha = 0xFF;
}
}
pRGBABuffer[(i * iWidth * 4) + (j * 4)+3] = byAlpha;
}
}
return SYS_OK;
} |