00001 #pragma once
00002 #include "../pch.h"
00003
00004 TextureData::TextureData()
00005 {
00006 mipmapsColor = 0;
00007 mipmapsDetail = 0;
00008 color = 0;
00009 detail = 0;
00010 }
00011
00012 TextureData::~TextureData()
00013 {
00014 mipmapsColor = 0;
00015 mipmapsDetail = 0;
00016 SAVEFREE(color);
00017 detail = 0;
00018 }
00019
00020
00021 inline bool loadUnknown(const wchar* filename, int& width, int& height, Pixel** outData)
00022 {
00023 bool ok = true;
00024 size_t filenameLength = wcslen(filename);
00025
00026 if(wcscmp(&filename[filenameLength-4], TEXT(".bmp")) == 0)
00027 ok = loadBMP(filename, width, height, outData);
00028 else if(wcscmp(&filename[filenameLength-4], TEXT(".tga")) == 0)
00029 ok = loadTGA(filename, width, height, outData);
00030 else
00031 return false;
00032
00033 if(outData == 0 && width != height)
00034 return false;
00035
00036 return ok;
00037 }
00038
00039 bool loadTextureData(const wchar* colorFilename, const wchar* normalFilename, const wchar* heightFilename, TextureData& out)
00040 {
00041 Pixel* colorData = 0;
00042 Pixel* normalData = 0;
00043 Pixel* heightData = 0;
00044 int widthColor = 0, heightColor = 0;
00045 int widthDetail = 0, heightDetail = 0;
00046 bool ok = true;
00047
00048 ok = loadUnknown(colorFilename, widthColor, heightColor, 0);
00049 if(ok) ok = loadUnknown(colorFilename, widthColor, heightColor, &colorData);
00050 if(normalFilename){
00051 ok = loadUnknown(normalFilename, widthDetail, heightDetail, 0);
00052 if(ok) ok = loadUnknown(normalFilename, widthDetail, heightDetail, &normalData);
00053 if(ok) ok = loadUnknown(heightFilename, widthDetail, heightDetail, &heightData);
00054 }
00055
00056 if(ok == false)
00057 {
00058 SAVEFREE(colorData);
00059 SAVEFREE(normalData);
00060 SAVEFREE(heightData);
00061 return false;
00062 }
00063
00064 int mipmapsColor = 0;
00065 int mipmapsDetail = 0;
00066 int mipmapPixelsColor = 0;
00067 int mipmapPixelsDetail = 0;
00068 MipMap* colorMipmaps;
00069 MipMap* detailMipmaps;
00070
00071 for(int w=widthColor; w>0; mipmapPixelsColor+=w*w, w/=2, mipmapsColor++);
00072 if(normalFilename)
00073 for(int w=widthDetail; w>0; mipmapPixelsDetail+=w*w, w/=2, mipmapsDetail++);
00074
00075 void* mem = malloc(sizeof(MipMap)*(mipmapsColor+mipmapsDetail) + sizeof(Pixel)*(mipmapPixelsColor+mipmapPixelsDetail));
00076
00077 colorMipmaps = (MipMap*)mem;
00078 detailMipmaps = &colorMipmaps[mipmapsColor];
00079 Pixel* colorPixels = (Pixel*)&detailMipmaps[mipmapsDetail];
00080 Pixel* detailPixels = &colorPixels[mipmapPixelsColor];
00081
00082 for(int i=0, w=widthColor, curPixel=0; i<mipmapsColor; curPixel+=w*w, w/=2, i++)
00083 {
00084 colorMipmaps[i].width = w;
00085 colorMipmaps[i].height = w;
00086 colorMipmaps[i].data = &colorPixels[curPixel];
00087 }
00088
00089 if(normalFilename){
00090 for(int i=0, w=widthDetail, curPixel=0; i<mipmapsDetail; curPixel+=w*w, w/=2, i++)
00091 {
00092 detailMipmaps[i].width = w;
00093 detailMipmaps[i].height = w;
00094 detailMipmaps[i].data = &detailPixels[curPixel];
00095 }
00096 }
00097
00098
00099 for(int y=0; y<colorMipmaps[0].height; y++)
00100 {
00101 for(int x=0; x<colorMipmaps[0].width; x++)
00102 colorMipmaps[0].data[(heightColor-1-y)*widthColor+(widthColor-1-x)] = colorData[y*widthColor+x];
00103 }
00104
00105
00106 for(int i=0; i<mipmapsColor-1; i++)
00107 {
00108 for(int y=0; y<colorMipmaps[i+1].height; y++)
00109 {
00110 for(int x=0; x<colorMipmaps[i+1].width; x++)
00111 {
00112 int color[4];
00113 for(int c=0; c<4; color[c] = colorMipmaps[i].data[((y+0)* colorMipmaps[i].width + x + 0)*2].canal[c], c++);
00114 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+0)* colorMipmaps[i].width + x + 1)*2].canal[c], c++);
00115 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+1)* colorMipmaps[i].width + x + 0)*2].canal[c], c++);
00116 for(int c=0; c<4; color[c] += colorMipmaps[i].data[((y+1)* colorMipmaps[i].width + x + 1)*2].canal[c], c++);
00117 for(int c=0; c<4; colorMipmaps[i+1].data[y * colorMipmaps[i+1].width + x].canal[c] = uchar(color[c]/4), c++);
00118 }
00119 }
00120 }
00121
00122 if(normalFilename){
00123
00124 for(int y=0; y<detailMipmaps[0].height; y++)
00125 {
00126 for(int x=0; x<detailMipmaps[0].width; x++)
00127 {
00128 normalData[y*widthDetail+x].a = heightData[y*widthDetail+x].r;
00129 detailMipmaps[0].data[y*widthDetail+x] = normalData[y*widthDetail+x];
00130 }
00131 }
00132
00133
00134 for(int i=0; i<mipmapsDetail-1; i++)
00135 {
00136 for(int y=0; y<detailMipmaps[i].height/2; y++)
00137 {
00138 for(int x=0; x<detailMipmaps[i].width/2; x++)
00139 {
00140 int normal[4];
00141 for(int c=0; c<4; normal[c] = detailMipmaps[i].data[((y+0)* detailMipmaps[i].width + x + 0)*2].canal[c], c++);
00142 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+0)* detailMipmaps[i].width + x + 1)*2].canal[c], c++);
00143 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+1)* detailMipmaps[i].width + x + 0)*2].canal[c], c++);
00144 for(int c=0; c<4; normal[c] += detailMipmaps[i].data[((y+1)* detailMipmaps[i].width + x + 1)*2].canal[c], c++);
00145 for(int c=0; c<4; detailMipmaps[i+1].data[y * detailMipmaps[i+1].width + x].canal[c] = uchar(normal[c]/4), c++);
00146 }
00147 }
00148 }
00149 }
00150
00151
00152 SAVEFREE(colorData);
00153 SAVEFREE(normalData);
00154 SAVEFREE(heightData);
00155
00156
00157 out.mipmapsColor = mipmapsColor;
00158 out.mipmapsDetail = mipmapsDetail;
00159 out.color = colorMipmaps;
00160 out.detail = detailMipmaps;
00161 return true;
00162 }
00163
00164
00165 #pragma pack(1)
00166
00167 struct BMP_SIGNATURE {
00168 BMP_SIGNATURE() {
00169 this->c[0] = 'B';
00170 this->c[1] = 'M';
00171 }
00172 union {
00173 unsigned short int s;
00174 unsigned char c[2];
00175 };
00176 };
00177
00178 const BMP_SIGNATURE bmpSignature;
00179 const unsigned short int BITMAP_SIGNATURE = bmpSignature.s;
00180
00181 typedef struct {
00182 unsigned short int Signature;
00183 unsigned int Size;
00184 unsigned int Reserved;
00185 unsigned int BitsOffset;
00186 } BITMAP_FILEHEADER;
00187
00188 #define BITMAP_FILEHEADER_SIZE 14
00189
00190 typedef struct {
00191 unsigned int HeaderSize;
00192 int Width;
00193 int Height;
00194 unsigned short int Planes;
00195 unsigned short int BitCount;
00196 unsigned int Compression;
00197 unsigned int SizeImage;
00198 int PelsPerMeterX;
00199 int PelsPerMeterY;
00200 unsigned int ClrUsed;
00201 unsigned int ClrImportant;
00202 unsigned int RedMask;
00203 unsigned int GreenMask;
00204 unsigned int BlueMask;
00205 unsigned int AlphaMask;
00206 unsigned int CsType;
00207 unsigned int Endpoints[9];
00208 unsigned int GammaRed;
00209 unsigned int GammaGreen;
00210 unsigned int GammaBlue;
00211 } BITMAP_HEADER;
00212
00213 typedef struct {
00214 unsigned char Red;
00215 unsigned char Green;
00216 unsigned char Blue;
00217 unsigned char Alpha;
00218 } RGBA;
00219
00220 typedef struct {
00221 unsigned char Blue;
00222 unsigned char Green;
00223 unsigned char Red;
00224 unsigned char Alpha;
00225 } BGRA;
00226
00227 typedef struct {
00228 unsigned char Blue;
00229 unsigned char Green;
00230 unsigned char Red;
00231 } BGR;
00232
00233 typedef struct {
00234 unsigned short int Blue:5;
00235 unsigned short int Green:5;
00236 unsigned short int Red:5;
00237 unsigned short int Reserved:1;
00238 } BGR16;
00239
00240 uint myShiftRightByMask(uint Color, uint Mask, uint DistributeToBits) {
00241 if (Mask == 0) return 0;
00242
00243 uint ShiftCount = 0;
00244 uint Test = 0x00000001;
00245
00246 while((ShiftCount<32) && !(Mask & Test)){
00247 Test <<= 1;
00248 ShiftCount++;
00249 }
00250
00251 uint BitCount = 32;
00252 Test = 0x80000000;
00253
00254 while(BitCount && !((Mask >> ShiftCount) & Test)){
00255 Test >>= 1;
00256 BitCount--;
00257 }
00258
00259 uint BaseColor = (Color & Mask) >> ShiftCount;
00260
00261 if(DistributeToBits > BitCount){
00262
00263 uint BitsToFill = DistributeToBits - BitCount;
00264 while(BitsToFill--) {
00265 BaseColor <<= 1;
00266 if(BaseColor & 1)
00267 BaseColor |= 1;
00268 }
00269 }else if(DistributeToBits < BitCount){
00270 BaseColor >>= (BitCount - DistributeToBits);
00271 }
00272 return BaseColor;
00273 }
00274
00275 bool loadBMP(const wchar* filename, int& width, int& height, Pixel** outData){
00276 FILE* file = 0;
00277 BITMAP_FILEHEADER m_BitmapFileHeader;
00278 BITMAP_HEADER m_BitmapHeader;
00279 RGBA* m_BitmapData = 0;
00280 uchar *Line = 0;
00281 uint m_BitmapSize = 0;
00282 BGRA m_ColorTable[256];
00283 uint m_ColorTableSize = 0;
00284 int bmpWidth = 0, bmpHeight = 0;
00285
00286 #define SAVEEXIT(rs) {\
00287 if(file){fclose(file);file=0;}\
00288 SAVEFREE(m_BitmapData);\
00289 SAVEFREE(Line);\
00290 return rs;}
00291
00292 if(_wfopen_s(&file, filename, TEXT("rb")) != 0)
00293 return false;
00294
00295 fread(&m_BitmapFileHeader, BITMAP_FILEHEADER_SIZE, 1, file);
00296 if(m_BitmapFileHeader.Signature != BITMAP_SIGNATURE)
00297 return false;
00298
00299 fread(&m_BitmapHeader, sizeof(BITMAP_HEADER), 1, file);
00300
00301
00302 fseek(file, BITMAP_FILEHEADER_SIZE + m_BitmapHeader.HeaderSize, SEEK_SET);
00303
00304 switch(m_BitmapHeader.BitCount){
00305 case 1: m_ColorTableSize = 2; break;
00306 case 4: m_ColorTableSize = 16; break;
00307 case 8: m_ColorTableSize = 256; break;
00308 default: break;
00309 }
00310
00311 if(m_ColorTableSize>0)
00312 fread(m_ColorTable, sizeof(BGRA), m_ColorTableSize, file);
00313
00314
00315 bmpWidth = m_BitmapHeader.Width < 0 ? -m_BitmapHeader.Width : m_BitmapHeader.Width;
00316 bmpHeight = m_BitmapHeader.Height < 0 ? -m_BitmapHeader.Height : m_BitmapHeader.Height;
00317
00318 if(width > 0 && height > 0 && width != bmpWidth && height != bmpHeight){
00319 fclose(file);
00320 return false;
00321 }
00322
00323 width = bmpWidth;
00324 height = bmpHeight;
00325
00326 if(outData == 0){
00327 fclose(file);
00328 return true;
00329 }
00330
00331 m_BitmapSize = bmpWidth * bmpHeight;
00332 m_BitmapData = (RGBA*)malloc(sizeof(RGBA)*m_BitmapSize);
00333
00334 uint LineWidth = (bmpWidth * m_BitmapHeader.BitCount/8 + 3) & ~3;
00335 Line = (uchar*)malloc(sizeof(uchar)*LineWidth);
00336
00337 fseek(file, m_BitmapFileHeader.BitsOffset, SEEK_SET);
00338
00339 int Index = 0;
00340
00341 switch(m_BitmapHeader.Compression){
00342
00343 case 0:{
00344 for (int i = 0; i < bmpHeight; i++) {
00345 fread(Line, LineWidth, 1, file);
00346 uchar *LinePtr = Line;
00347
00348 switch(m_BitmapHeader.BitCount) {
00349 case 1:
00350 for(int j = 0; j < bmpWidth; j++){
00351 uint Color = *((uchar*) LinePtr);
00352 for (int k = 0; k < 8; k++) {
00353 m_BitmapData[Index].Red = m_ColorTable[Color & 0x80 ? 1 : 0].Red;
00354 m_BitmapData[Index].Green = m_ColorTable[Color & 0x80 ? 1 : 0].Green;
00355 m_BitmapData[Index].Blue = m_ColorTable[Color & 0x80 ? 1 : 0].Blue;
00356 m_BitmapData[Index].Alpha = m_ColorTable[Color & 0x80 ? 1 : 0].Alpha;
00357 Index++;
00358 Color <<= 1;
00359 }
00360 LinePtr++;
00361 j += 7;
00362 }
00363 break;
00364 case 4:
00365 for(int j = 0; j < bmpWidth; j++){
00366 uint Color = *((uchar*) LinePtr);
00367 m_BitmapData[Index].Red = m_ColorTable[(Color >> 4) & 0x0f].Red;
00368 m_BitmapData[Index].Green = m_ColorTable[(Color >> 4) & 0x0f].Green;
00369 m_BitmapData[Index].Blue = m_ColorTable[(Color >> 4) & 0x0f].Blue;
00370 m_BitmapData[Index].Alpha = m_ColorTable[(Color >> 4) & 0x0f].Alpha;
00371 Index++;
00372 m_BitmapData[Index].Red = m_ColorTable[Color & 0x0f].Red;
00373 m_BitmapData[Index].Green = m_ColorTable[Color & 0x0f].Green;
00374 m_BitmapData[Index].Blue = m_ColorTable[Color & 0x0f].Blue;
00375 m_BitmapData[Index].Alpha = m_ColorTable[Color & 0x0f].Alpha;
00376 Index++;
00377 LinePtr++;
00378 j++;
00379 }
00380 break;
00381 case 8:
00382 for(int j = 0; j < bmpWidth; j++){
00383 uint Color = *((uchar*) LinePtr);
00384 m_BitmapData[Index].Red = m_ColorTable[Color].Red;
00385 m_BitmapData[Index].Green = m_ColorTable[Color].Green;
00386 m_BitmapData[Index].Blue = m_ColorTable[Color].Blue;
00387 m_BitmapData[Index].Alpha = m_ColorTable[Color].Alpha;
00388 Index++;
00389 LinePtr++;
00390 }
00391 break;
00392 case 16:
00393 for(int j = 0; j < bmpWidth; j++){
00394 uint Color = *((unsigned short int*) LinePtr);
00395 m_BitmapData[Index].Red = ((Color >> 10) & 0x1f) << 3;
00396 m_BitmapData[Index].Green = ((Color >> 5) & 0x1f) << 3;
00397 m_BitmapData[Index].Blue = (Color & 0x1f) << 3;
00398 m_BitmapData[Index].Alpha = 255;
00399 Index++;
00400 LinePtr += 2;
00401 }
00402 break;
00403 case 24:
00404 for(int j = 0; j < bmpWidth; j++){
00405 uint Color = *((uint*) LinePtr);
00406 m_BitmapData[Index].Blue = Color & 0xff;
00407 m_BitmapData[Index].Green = (Color >> 8) & 0xff;
00408 m_BitmapData[Index].Red = (Color >> 16) & 0xff;
00409 m_BitmapData[Index].Alpha = 255;
00410 Index++;
00411 LinePtr += 3;
00412 }
00413 break;
00414 case 32:
00415 for(int j = 0; j < bmpWidth; j++){
00416 uint Color = *((uint*) LinePtr);
00417 m_BitmapData[Index].Blue = Color & 0xff;
00418 m_BitmapData[Index].Green = (Color >> 8) & 0xff;
00419 m_BitmapData[Index].Red = (Color >> 16) & 0xff;
00420 m_BitmapData[Index].Alpha = Color >> 24;
00421 Index++;
00422 LinePtr += 4;
00423 }
00424 break;
00425 default:
00426 SAVEEXIT(false);
00427 }
00428 }
00429 break;
00430 }
00431
00432 case 1:{
00433 uchar Count = 0;
00434 uchar ColorIndex = 0;
00435 int x = 0, y = 0;
00436
00437 for(bool run = true; !feof(file) && run; ){
00438 fread(&Count, 1, 1, file);
00439 fread(&ColorIndex, 1, 1, file);
00440
00441 if (Count > 0) {
00442 Index = x + y * bmpWidth;
00443 for (int k = 0; k < Count; k++) {
00444 m_BitmapData[Index + k].Red = m_ColorTable[ColorIndex].Red;
00445 m_BitmapData[Index + k].Green = m_ColorTable[ColorIndex].Green;
00446 m_BitmapData[Index + k].Blue = m_ColorTable[ColorIndex].Blue;
00447 m_BitmapData[Index + k].Alpha = m_ColorTable[ColorIndex].Alpha;
00448 }
00449 x += Count;
00450 } else if (Count == 0) {
00451 int Flag = ColorIndex;
00452 switch(Flag){
00453 case 0: x = 0; y++; break;
00454 case 1: run = false; break;
00455 case 2:{
00456 char rx = 0;
00457 char ry = 0;
00458 fread(&rx, 1, 1, file);
00459 fread(&ry, 1, 1, file);
00460 x += rx;
00461 y += ry;
00462 break;
00463 }
00464 default:{
00465 Count = Flag;
00466 Index = x + y * bmpWidth;
00467 for(int k = 0; k < Count; k++){
00468 fread(&ColorIndex, 1, 1, file);
00469 m_BitmapData[Index + k].Red = m_ColorTable[ColorIndex].Red;
00470 m_BitmapData[Index + k].Green = m_ColorTable[ColorIndex].Green;
00471 m_BitmapData[Index + k].Blue = m_ColorTable[ColorIndex].Blue;
00472 m_BitmapData[Index + k].Alpha = m_ColorTable[ColorIndex].Alpha;
00473 }
00474 x += Count;
00475 if (ftell(file) & 1) fseek(file, 1, SEEK_CUR);
00476 break;
00477 }
00478 }
00479 }
00480 }
00481 break;
00482 }
00483
00484
00485
00486 case 3:{
00487
00488 for(int i=0; i<bmpHeight; i++){
00489 fread(Line, LineWidth, 1, file);
00490 uchar *LinePtr = Line;
00491
00492 for(int j=0; j < bmpWidth; j++){
00493 uint Color = 0;
00494
00495 if (m_BitmapHeader.BitCount == 16) {
00496 Color = *((unsigned short int*) LinePtr);
00497 LinePtr += 2;
00498 } else if (m_BitmapHeader.BitCount == 32) {
00499 Color = *((uint*) LinePtr);
00500 LinePtr += 4;
00501 }
00502 m_BitmapData[Index].Red = myShiftRightByMask(Color, m_BitmapHeader.RedMask);
00503 m_BitmapData[Index].Green = myShiftRightByMask(Color, m_BitmapHeader.GreenMask);
00504 m_BitmapData[Index].Blue = myShiftRightByMask(Color, m_BitmapHeader.BlueMask);
00505 m_BitmapData[Index].Alpha = myShiftRightByMask(Color, m_BitmapHeader.AlphaMask);
00506
00507 Index++;
00508 }
00509 }
00510 break;
00511 }
00512 default:
00513 SAVEEXIT(false);
00514 }
00515
00516 SAVEFREE(Line);
00517 fclose(file);
00518
00519 *outData = (Pixel*)m_BitmapData;
00520 return true;
00521 #undef SAVEEXIT
00522 }
00523
00524 bool myLoadUncompressedTGA(int& width, int& height, Pixel** outData, FILE * datei){
00525 uchar header[6];
00526 uint bytesPerPixel;
00527 uint size;
00528 uchar* data;
00529
00530 if(fread(header, sizeof(header), 1, datei) == 0)
00531 return false;
00532
00533 width = header[1] * 256 + header[0];
00534 height = header[3] * 256 + header[2];
00535
00536 if((width <= 0) || (height <= 0))
00537 return false;
00538
00539 bytesPerPixel = header[4] / 8;
00540 size = bytesPerPixel * width * height;
00541 data = (uchar*)malloc(sizeof(Pixel) * width * height);
00542
00543 if(fread(data, 1, size, datei) != size){
00544 free(data);
00545 return false;
00546 }
00547
00548 for(uint cswap = 0; cswap < size; cswap += bytesPerPixel)
00549 data[cswap] ^= data[cswap+2] ^= data[cswap] ^= data[cswap+2];
00550
00551 *outData = (Pixel*)data;
00552
00553 if(bytesPerPixel == 3)
00554 {
00555 for(int i=width*height-1, j=3*width*height-3; i>=0; i--, j-=3)
00556 {
00557 (*outData)[i].canal[3] = 255;
00558 (*outData)[i].canal[2] = data[j+2];
00559 (*outData)[i].canal[1] = data[j+1];
00560 (*outData)[i].canal[0] = data[j+0];
00561 }
00562 }
00563
00564 return true;
00565 }
00566
00567 bool myLoadCompressedTGA(int& width, int& height, Pixel** outData, FILE * datei){
00568 uchar header[6];
00569 uint bytesPerPixel;
00570 uint size;
00571 uchar* data;
00572 uchar counter;
00573
00574 if(fread(header, sizeof(header), 1, datei) == 0)
00575 return false;
00576
00577 width = header[1] * 256 + header[0];
00578 height = header[3] * 256 + header[2];
00579
00580 if((width <= 0) || (height <= 0))
00581 return false;
00582
00583 bytesPerPixel = header[4] / 8;
00584 size = bytesPerPixel * width * height;
00585 data = (uchar*)malloc(sizeof(Pixel) * width * height);
00586
00587
00588 uint pixelcount = width * height;
00589
00590 uint currentpixel = 0;
00591
00592 uint currentbyte = 0;
00593
00594 uchar colorbuffer[4];
00595
00596 do{
00597
00598 uchar chunkheader = 0;
00599
00600
00601 if(fread(&chunkheader, sizeof(uchar), 1, datei) == 0){
00602 free(data);
00603 return false;
00604 }
00605
00606 if(chunkheader < 128){
00607 chunkheader++;
00608
00609
00610
00611 for(counter = 0; counter < chunkheader; counter++){
00612
00613 if(fread(colorbuffer, 1, bytesPerPixel, datei) != bytesPerPixel){
00614 free(data);
00615 return false;
00616 }
00617
00618
00619
00620 data[currentbyte ] = colorbuffer[2];
00621 data[currentbyte+1] = colorbuffer[1];
00622 data[currentbyte+2] = colorbuffer[0];
00623
00624
00625
00626 if(bytesPerPixel == 4)
00627 data[currentbyte+3] = colorbuffer[3];
00628
00629 currentbyte += bytesPerPixel;
00630 currentpixel++;
00631
00632
00633 if(currentpixel > pixelcount){
00634 free(data);
00635 return false;
00636 }
00637 }
00638 }
00639
00640 else{
00641
00642 chunkheader -= 127;
00643
00644
00645 if(fread(colorbuffer, 1, bytesPerPixel, datei) != bytesPerPixel){
00646 free(data);
00647 return false;
00648 }
00649
00650
00651
00652 for(counter = 0; counter < chunkheader; counter++){
00653
00654 data[currentbyte ] = colorbuffer[2];
00655 data[currentbyte+1] = colorbuffer[1];
00656 data[currentbyte+2] = colorbuffer[0];
00657
00658
00659 if(bytesPerPixel == 4)
00660
00661 data[currentbyte + 3] = colorbuffer[3];
00662
00663 currentbyte += bytesPerPixel;
00664 currentpixel++;
00665
00666
00667 if(currentpixel > pixelcount){
00668 free(data);
00669 return false;
00670 }
00671 }
00672 }
00673
00674 }while(currentpixel < pixelcount);
00675
00676 *outData = (Pixel*)data;
00677
00678 if(bytesPerPixel == 3)
00679 {
00680 for(int i=width*height-1, j=3*width*height-3; i>=0; i--, j-=3)
00681 {
00682 (*outData)[i].canal[3] = 255;
00683 (*outData)[i].canal[2] = data[j+2];
00684 (*outData)[i].canal[1] = data[j+1];
00685 (*outData)[i].canal[0] = data[j+0];
00686 }
00687 }
00688
00689 return true;
00690 }
00691
00692 bool loadTGA(const wchar* filename, int& width, int& height, Pixel** outData){
00693 bool ok;
00694 FILE* file;
00695 uchar tgaheader[12];
00696
00697 uchar uTGAcompare[12] = {0,0, 2,0,0,0,0,0,0,0,0,0};
00698
00699 uchar cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};
00700
00701 if(_wfopen_s(&file, filename, TEXT("rb")) != 0)
00702 return false;
00703
00704 #define CHECK(_b) if(_b){fclose(file);return false;}
00705
00706 CHECK(fread(&tgaheader, sizeof(tgaheader), 1, file) == 0);
00707
00708
00709
00710 if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
00711 ok = myLoadUncompressedTGA(width, height, outData, file);
00712
00713 else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
00714 ok = myLoadCompressedTGA(width, height, outData, file);
00715
00716 else
00717 ok = false;
00718
00719
00720 CHECK(ok == false);
00721
00722
00723 fclose(file);
00724
00725 #undef CHECK
00726 return true;
00727 }