00001
00006 #include "TGALoader.h"
00007
00008
00009
00010
00011
00012 using namespace ParticleSystems;
00013
00014 TGALoader::TGALoader() {
00015 for(int i = 0; i < 12; i++) {
00016 if(i == 2) {
00017 uTGAcompare[i] = 2;
00018 cTGAcompare[i] = 10;
00019 } else {
00020 uTGAcompare[i] = 0;
00021 cTGAcompare[i] = 0;
00022 }
00023 }
00024 }
00025
00026 TGALoader::~TGALoader() {
00027 }
00028
00029 bool TGALoader::LoadTGA(Texture * texture, char * filename)
00030 {
00031 FILE * fTGA;
00032 fTGA = fopen(filename, "rb");
00033
00034 if(fTGA == NULL)
00035 {
00036
00037 return false;
00038 }
00039
00040 if(fread(&tgaheader, sizeof(TGAHeader), 1, fTGA) == 0)
00041 {
00042
00043 if(fTGA != NULL)
00044 {
00045 fclose(fTGA);
00046 }
00047 return false;
00048 }
00049
00050 if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
00051 {
00052 LoadUncompressedTGA(texture, filename, fTGA);
00053 }
00054 else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
00055 {
00056 LoadCompressedTGA(texture, filename, fTGA);
00057 }
00058 else
00059 {
00060
00061 fclose(fTGA);
00062 return false;
00063 }
00064 return true;
00065 }
00066
00067 bool TGALoader::LoadUncompressedTGA(Texture * texture, char * filename, FILE * fTGA)
00068 {
00069 if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)
00070 {
00071
00072 if(fTGA != NULL)
00073 {
00074 fclose(fTGA);
00075 }
00076 return false;
00077 }
00078
00079 texture->width = tga.header[1] * 256 + tga.header[0];
00080 texture->height = tga.header[3] * 256 + tga.header[2];
00081 texture->bpp = tga.header[4];
00082 tga.Width = texture->width;
00083 tga.Height = texture->height;
00084 tga.Bpp = texture->bpp;
00085
00086 if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
00087 {
00088
00089 if(fTGA != NULL)
00090 {
00091 fclose(fTGA);
00092 }
00093 return false;
00094 }
00095
00096 if(texture->bpp == 24)
00097 {
00098 texture->type = GL_RGB;
00099 }
00100 else
00101 {
00102 texture->type = GL_RGBA;
00103 }
00104
00105 tga.bytesPerPixel = (tga.Bpp / 8);
00106 tga.imageSize = (tga.bytesPerPixel * tga.Width * tga.Height);
00107 texture->imageData = (GLubyte *)malloc(tga.imageSize);
00108
00109 if(texture->imageData == NULL)
00110 {
00111
00112 fclose(fTGA);
00113 return false;
00114 }
00115
00116 if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize)
00117 {
00118
00119 if(texture->imageData != NULL)
00120 {
00121 free(texture->imageData);
00122 }
00123 fclose(fTGA);
00124 return false;
00125 }
00126
00127
00128 for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)
00129 {
00130 texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
00131 texture->imageData[cswap] ^= texture->imageData[cswap+2];
00132 }
00133
00134 fclose(fTGA);
00135 return true;
00136 }
00137
00138 bool TGALoader::LoadCompressedTGA(Texture * texture, char * filename, FILE * fTGA)
00139 {
00140 if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)
00141 {
00142
00143 if(fTGA != NULL)
00144 {
00145 fclose(fTGA);
00146 }
00147 return false;
00148 }
00149
00150 texture->width = tga.header[1] * 256 + tga.header[0];
00151 texture->height = tga.header[3] * 256 + tga.header[2];
00152 texture->bpp = tga.header[4];
00153 tga.Width = texture->width;
00154 tga.Height = texture->height;
00155 tga.Bpp = texture->bpp;
00156
00157 if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
00158 {
00159
00160 if(fTGA != NULL)
00161 {
00162 fclose(fTGA);
00163 }
00164 return false;
00165 }
00166
00167 tga.bytesPerPixel = (tga.Bpp / 8);
00168 tga.imageSize = (tga.bytesPerPixel * tga.Width * tga.Height);
00169 texture->imageData = (GLubyte *)malloc(tga.imageSize);
00170
00171 if(texture->imageData == NULL)
00172 {
00173
00174 fclose(fTGA);
00175 return false;
00176 }
00177
00178 GLuint pixelcount = tga.Height * tga.Width;
00179 GLuint currentpixel = 0;
00180 GLuint currentbyte = 0;
00181 GLubyte * colorbuffer = (GLubyte *)malloc(tga.bytesPerPixel);
00182
00183 do
00184 {
00185 GLubyte chunkheader = 0;
00186
00187 if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
00188 {
00189
00190 if(fTGA != NULL)
00191 {
00192 fclose(fTGA);
00193 }
00194 if(texture->imageData != NULL)
00195 {
00196 free(texture->imageData);
00197 }
00198 return false;
00199 }
00200
00201 if(chunkheader < 128)
00202 {
00203 chunkheader++;
00204 for(short counter = 0; counter < chunkheader; counter++)
00205 {
00206 if(fread(colorbuffer, 1, tga.bytesPerPixel, fTGA) != tga.bytesPerPixel)
00207 {
00208
00209
00210 if(fTGA != NULL)
00211 {
00212 fclose(fTGA);
00213 }
00214
00215 if(colorbuffer != NULL)
00216 {
00217 free(colorbuffer);
00218 }
00219
00220 if(texture->imageData != NULL)
00221 {
00222 free(texture->imageData);
00223 }
00224
00225 return false;
00226 }
00227
00228 texture->imageData[currentbyte ] = colorbuffer[2];
00229 texture->imageData[currentbyte + 1 ] = colorbuffer[1];
00230 texture->imageData[currentbyte + 2 ] = colorbuffer[0];
00231
00232 if(tga.bytesPerPixel == 4)
00233 {
00234 texture->imageData[currentbyte + 3] = colorbuffer[3];
00235 }
00236
00237 currentbyte += tga.bytesPerPixel;
00238 currentpixel++;
00239
00240 if(currentpixel > pixelcount)
00241 {
00242
00243
00244 if(fTGA != NULL)
00245 {
00246 fclose(fTGA);
00247 }
00248
00249 if(colorbuffer != NULL)
00250 {
00251 free(colorbuffer);
00252 }
00253
00254 if(texture->imageData != NULL)
00255 {
00256 free(texture->imageData);
00257 }
00258
00259 return false;
00260 }
00261 }
00262 }
00263 else
00264 {
00265 chunkheader -= 127;
00266 if(fread(colorbuffer, 1, tga.bytesPerPixel, fTGA) != tga.bytesPerPixel)
00267 {
00268
00269
00270 if(fTGA != NULL)
00271 {
00272 fclose(fTGA);
00273 }
00274
00275 if(colorbuffer != NULL)
00276 {
00277 free(colorbuffer);
00278 }
00279
00280 if(texture->imageData != NULL)
00281 {
00282 free(texture->imageData);
00283 }
00284
00285 return false;
00286 }
00287
00288 for(short counter = 0; counter < chunkheader; counter++)
00289 {
00290 texture->imageData[currentbyte ] = colorbuffer[2];
00291 texture->imageData[currentbyte + 1 ] = colorbuffer[1];
00292 texture->imageData[currentbyte + 2 ] = colorbuffer[0];
00293
00294 if(tga.bytesPerPixel == 4)
00295 {
00296 texture->imageData[currentbyte + 3] = colorbuffer[3];
00297 }
00298
00299 currentbyte += tga.bytesPerPixel;
00300 currentpixel++;
00301
00302 if(currentpixel > pixelcount)
00303 {
00304
00305
00306 if(fTGA != NULL)
00307 {
00308 fclose(fTGA);
00309 }
00310
00311 if(colorbuffer != NULL)
00312 {
00313 free(colorbuffer);
00314 }
00315
00316 if(texture->imageData != NULL)
00317 {
00318 free(texture->imageData);
00319 }
00320
00321 return false;
00322 }
00323 }
00324 }
00325 }
00326
00327 while(currentpixel < pixelcount);
00328 fclose(fTGA);
00329 return true;
00330 }