00001 #include "ExCImageLoader.h"
00002
00003
00004 ExCImageLoader::ExCImageLoader(void)
00005 {
00006 }
00007
00008 ExCImageLoader::ExCImageLoader(std::string FileName)
00009 {
00010 LoadImage(FileName);
00011 }
00012
00013 ExCImageLoader::~ExCImageLoader(void)
00014 {
00015 delete m_data;
00016 delete m_palette;
00017 }
00018
00019 TextureType ExCImageLoader::FindTextureType(std::string FileName)
00020 {
00021 Guard(TextureType ExCImageLoader::FindTextureType(std::string FileName))
00022
00023
00024 if(FileName.find("."))
00025 {
00026 if(FileName.find(".bmp")==(FileName.length()-4))return BMP;
00027 if(FileName.find(".tga")==(FileName.length()-4))return TGA;
00028 if(FileName.find(".pcx")==(FileName.length()-4))return PCX;
00029
00030
00031
00032 if(FileName.find(".ppm")==(FileName.length()-4))return PPM;
00033 if(FileName.find(".")<FileName.length())return UNKNOWN;
00034 }
00035
00036
00037 FILE *file;
00038 std::ifstream filetest;
00039 std::string strFileName;
00040
00041
00042 strFileName=FileName+".bmp";
00043 if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return BMP;}
00044
00045 strFileName=FileName+".pcx";
00046 if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return PCX;}
00047
00048 strFileName=FileName+".tga";
00049 if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return TGA;}
00050
00051 strFileName=FileName+".ppm";
00052 if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return PPM;}
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 throw ExCExpFileNotFound();
00065 return UNKNOWN;
00066 UnGuard
00067 }
00068
00069 bool ExCImageLoader::LoadImage(std::string FileName)
00070 {
00071 Guard(bool ExCImageLoader::LoadImage(std::string FileName))
00072 m_TextureType=FindTextureType(FileName);
00073
00074 switch(m_TextureType)
00075 {
00076 case BMP:return LoadBMP(FileName);
00077 case TGA:return LoadTGA(FileName);
00078 case PCX:return LoadPCX(FileName);
00079 case JPG:return LoadJPG(FileName);
00080
00081
00082 case PPM:return LoadPPM(FileName);
00083 case UNKNOWN:return false;
00084 default:return false;
00085 }
00086 UnGuard
00087 }
00088
00089 bool ExCImageLoader::LoadRAW(std::string strFileName)
00090 {
00091 return false;
00092 }
00093
00094 bool ExCImageLoader::LoadRGB(std::string strFileName)
00095 {
00096 return false;
00097 }
00098
00099 bool ExCImageLoader::LoadJPG(std::string strFileName)
00100 {
00101 return false;
00102 }
00103
00104 bool ExCImageLoader::LoadPPM(std::string strFileName)
00105 {
00106 Guard(bool ExCImageLoader::LoadPPM(std::string strFileName))
00107 FILE* fp;
00108 int i, w, h, d;
00109 char head[70];
00110
00111 strFileName=strFileName+".ppm";
00112
00113 fp = fopen(strFileName.data(), "rb");
00114 if (!fp)
00115 {
00116 std::cout<<strFileName<<std::endl;
00117 throw ExCExpFileNotFound();
00118 return NULL;
00119 }
00120
00121
00122
00123 fgets(head, 70, fp);
00124 if (strncmp(head, "P6", 2))
00125 {
00126 printf("%s: Not a raw PPM file\n", strFileName.data());
00127 return NULL;
00128 }
00129
00130
00131 i = 0;
00132 while(i < 3) {
00133 fgets(head, 70, fp);
00134 if (head[0] == '#')
00135 continue;
00136 if (i == 0)
00137 i += sscanf(head, "%d %d %d", &w, &h, &d);
00138 else if (i == 1)
00139 i += sscanf(head, "%d %d", &h, &d);
00140 else if (i == 2)
00141 i += sscanf(head, "%d", &d);
00142 }
00143
00144
00145 m_data = (unsigned char*)malloc(sizeof(unsigned char)*w*h*3);
00146 fread(m_data, sizeof(unsigned char), w*h*3, fp);
00147 fclose(fp);
00148
00149 m_sizeX = w;
00150 m_sizeY = h;
00151
00152
00153 return true;
00154 UnGuard
00155 }
00156
00157 bool ExCImageLoader::LoadTGA(std::string strFileName)
00158 {
00159 Guard(bool ExCImageLoader::LoadTGA(std::string strFileName))
00160 WORD width = 0, height = 0;
00161 byte length = 0;
00162 byte imageType = 0;
00163 byte bits = 0;
00164 FILE *pFile = NULL;
00165 int channels = 0;
00166 int stride = 0;
00167 int i = 0;
00168
00169 strFileName=strFileName+".tga";
00170
00171 if((pFile = fopen(strFileName.data(), "rb")) == NULL)
00172 {
00173
00174 std::cout<<strFileName<<std::endl;
00175 throw ExCExpFileNotFound();
00176 return NULL;
00177 }
00178
00179
00180 fread(&length, sizeof(byte), 1, pFile);
00181
00182
00183 fseek(pFile,1,SEEK_CUR);
00184
00185
00186 fread(&imageType, sizeof(byte), 1, pFile);
00187
00188
00189 fseek(pFile, 9, SEEK_CUR);
00190
00191
00192 fread(&width, sizeof(WORD), 1, pFile);
00193 fread(&height, sizeof(WORD), 1, pFile);
00194 fread(&bits, sizeof(byte), 1, pFile);
00195
00196
00197 fseek(pFile, length + 1, SEEK_CUR);
00198
00199
00200 if(imageType != TGA_RLE)
00201 {
00202
00203 if(bits == 24 || bits == 32)
00204 {
00205
00206
00207 channels = bits / 8;
00208 stride = channels * width;
00209 m_data = new unsigned char[stride * height];
00210
00211
00212 for(int y = 0; y < height; y++)
00213 {
00214
00215 unsigned char *pLine = &(m_data[stride * y]);
00216
00217
00218 fread(pLine, stride, 1, pFile);
00219
00220
00221
00222 for(i = 0; i < stride; i += channels)
00223 {
00224 int temp = pLine[i];
00225 pLine[i] = pLine[i + 2];
00226 pLine[i + 2] = temp;
00227 }
00228 }
00229 }
00230
00231 else if(bits == 16)
00232 {
00233 unsigned short pixels = 0;
00234 int r=0, g=0, b=0;
00235
00236
00237
00238 channels = 3;
00239 stride = channels * width;
00240 m_data = new unsigned char[stride * height];
00241
00242
00243 for(int i = 0; i < width*height; i++)
00244 {
00245
00246 fread(&pixels, sizeof(unsigned short), 1, pFile);
00247
00248
00249
00250
00251
00252
00253 b = (pixels & 0x1f) << 3;
00254 g = ((pixels >> 5) & 0x1f) << 3;
00255 r = ((pixels >> 10) & 0x1f) << 3;
00256
00257
00258
00259 m_data[i * 3 + 0] = r;
00260 m_data[i * 3 + 1] = g;
00261 m_data[i * 3 + 2] = b;
00262 }
00263 }
00264
00265 else
00266 return NULL;
00267 }
00268
00269 else
00270 {
00271
00272 byte rleID = 0;
00273 int colorsRead = 0;
00274 channels = bits / 8;
00275 stride = channels * width;
00276
00277
00278
00279 m_data = new unsigned char[stride * height];
00280 byte *pColors = new byte [channels];
00281
00282
00283 while(i < width*height)
00284 {
00285
00286 fread(&rleID, sizeof(byte), 1, pFile);
00287
00288
00289 if(rleID < 128)
00290 {
00291
00292 rleID++;
00293
00294
00295 while(rleID)
00296 {
00297
00298 fread(pColors, sizeof(byte) * channels, 1, pFile);
00299
00300
00301 m_data[colorsRead + 0] = pColors[2];
00302 m_data[colorsRead + 1] = pColors[1];
00303 m_data[colorsRead + 2] = pColors[0];
00304
00305
00306 if(bits == 32)
00307 m_data[colorsRead + 3] = pColors[3];
00308
00309
00310
00311 i++;
00312 rleID--;
00313 colorsRead += channels;
00314 }
00315 }
00316
00317 else
00318 {
00319
00320 rleID -= 127;
00321
00322
00323 fread(pColors, sizeof(byte) * channels, 1, pFile);
00324
00325
00326 while(rleID)
00327 {
00328
00329 m_data[colorsRead + 0] = pColors[2];
00330 m_data[colorsRead + 1] = pColors[1];
00331 m_data[colorsRead + 2] = pColors[0];
00332
00333
00334 if(bits == 32)
00335 m_data[colorsRead + 3] = pColors[3];
00336
00337
00338
00339 i++;
00340 rleID--;
00341 colorsRead += channels;
00342 }
00343
00344 }
00345
00346 }
00347 }
00348
00349
00350 fclose(pFile);
00351
00352
00353 m_channels = channels;
00354 m_sizeX = width;
00355 m_sizeY = height;
00356 m_TextureType = TGA;
00357 return true;
00358 UnGuard
00359 }
00360
00361 bool ExCImageLoader::LoadBMP(std::string strFileName)
00362 {
00363 Guard(bool ExCImageLoader::LoadBMP(std::string strFileName))
00364 strFileName=strFileName+".bmp";
00365 return LoadBMP(strFileName.data());
00366 UnGuard
00367 }
00368
00369 bool ExCImageLoader::LoadPCX(std::string strFileName)
00370 {
00371 Guard(bool ExCImageLoader::LoadPCX(std::string strFileName))
00372 PCXHEADER texInfo;
00373
00374 unsigned char *unscaledData;
00375 int i;
00376 int j;
00377 int width;
00378 int height;
00379
00380
00381
00382 m_data=LoadPCXFile(strFileName, &texInfo);
00383 if (m_data == NULL)
00384 {
00385 free(m_data);
00386 throw ExCExpNullPointer();
00387 return false;
00388 }
00389
00390
00391 m_palette = texInfo.palette;
00392 m_sizeX = texInfo.xMax - texInfo.xMin + 1;
00393 m_sizeY = texInfo.yMax - texInfo.yMin + 1;
00394
00395
00396 unscaledData = (unsigned char*)malloc(m_sizeX*m_sizeY*4);
00397
00398
00399 for (j = 0; j < m_sizeY; j++)
00400 {
00401 for (i = 0; i < m_sizeX; i++)
00402 {
00403 unscaledData[4*(j*m_sizeX+i)+0] = (unsigned char)m_palette[3*m_data[j*m_sizeX+i]+0];
00404 unscaledData[4*(j*m_sizeX+i)+1] = (unsigned char)m_palette[3*m_data[j*m_sizeX+i]+1];
00405 unscaledData[4*(j*m_sizeX+i)+2] = (unsigned char)m_palette[3*m_data[j*m_sizeX+i]+2];
00406 unscaledData[4*(j*m_sizeX+i)+3] = (unsigned char)255;
00407 }
00408 }
00409
00410
00411 width = m_sizeX;
00412 height = m_sizeY;
00413
00414
00415 i = 0;
00416 while (width)
00417 {
00418 width /= 2;
00419 i++;
00420 }
00421 m_scaledHeight = (long)pow(2, i-1);
00422
00423
00424 i = 0;
00425 while (height)
00426 {
00427 height /= 2;
00428 i++;
00429 }
00430 m_scaledWidth = (long)pow(2, i-1);
00431
00432
00433 if (m_data != NULL)
00434 {
00435 free(m_data);
00436 m_data = NULL;
00437 }
00438
00439
00440 m_data = (unsigned char*)malloc(m_scaledWidth*m_scaledHeight*4);
00441
00442
00443 gluScaleImage (GL_RGBA, m_sizeX, m_sizeY, GL_UNSIGNED_BYTE, unscaledData, m_scaledWidth, m_scaledHeight, GL_UNSIGNED_BYTE, m_data);
00444
00445 return true;
00446 UnGuard
00447 }
00448
00449 bool ExCImageLoader::LoadBMP(const char *strFileName)
00450 {
00451 Guard(bool ExCImageLoader::LoadBMP(const char *strFileName))
00452
00453 FILE *file;
00454 unsigned long size;
00455 unsigned long i;
00456 unsigned short int planes;
00457 unsigned short int channels;
00458 char temp;
00459
00460
00461 if ((file = fopen(strFileName, "rb"))==NULL)
00462 {
00463 printf("ExCImageLoader::LoadBMP ==>File Not Found : %s\n",strFileName);
00464 throw ExCExpFileNotFound();
00465 return false;
00466 }
00467 #ifdef UNIX_SRC
00468 unsigned short int is_bmp;
00469 if (! fread (&is_bmp, sizeof (short int), 1, file))
00470 {
00471 printf("cannot read %s.\n", strFileName);
00472 return false;
00473 }
00474
00475
00476 if (is_bmp != 19778)
00477 {
00478 printf("%s is not a valid bmp file.\n", strFileName);
00479 return false;
00480 }
00481
00482 fseek (file, 8, SEEK_CUR);
00483
00484 long int bfOffBits;
00485 if (! fread (&bfOffBits, sizeof (long int), 1, file))
00486 {
00487 printf("Error reading %s.\n", strFileName);
00488 return false;
00489 }
00490
00491
00492
00493
00494 fseek(file, 4, SEEK_CUR);
00495 #else
00496 fseek(file, 18, SEEK_SET);
00497 #endif
00498
00499 if ((i = fread(&m_sizeX, 4, 1, file)) != 1)
00500 {
00501 printf("Error reading width from %s.\n", strFileName);
00502 return false;
00503 }
00504
00505
00506 if ((i = fread(&m_sizeY, 4, 1, file)) != 1)
00507 {
00508 printf("Error reading height from %s.\n", strFileName);
00509 return false;
00510 }
00511
00512
00513
00514 size = m_sizeX * m_sizeY * 3;
00515
00516
00517 if ((fread(&planes, 2, 1, file)) != 1)
00518 {
00519 printf("Error reading planes from %s.\n", strFileName);
00520 return false;
00521 }
00522
00523 if (planes != 1)
00524 {
00525 printf("Planes from %s is not 1: %u.\n", strFileName, planes);
00526 return false;
00527 }
00528
00529
00530 if ((i = fread(&channels, 2, 1, file)) != 1)
00531 {
00532 printf("Error reading channels from %s.\n", strFileName);
00533 return false;
00534 }
00535 if (channels != 24)
00536 {
00537 printf("channels from %s is not 24: %u\n", strFileName, channels);
00538 return false;
00539 }
00540
00541
00542 fseek(file, 24, SEEK_CUR);
00543
00544 m_data = new unsigned char[size];
00545
00546
00547
00548 if (m_data == NULL)
00549 {
00550 printf("Error allocating memory for color-corrected image data");
00551 return false;
00552 }
00553
00554 if ((i = fread(m_data, size, 1, file)) != 1)
00555 {
00556 printf("Error reading image data from %s.\n", strFileName);
00557 return false;
00558 }
00559
00560 for (i=0;i<size;i+=3)
00561 {
00562
00563 temp = m_data[i];
00564 m_data[i] = m_data[i+2];
00565 m_data[i+2] = temp;
00566 }
00567
00568 m_type=GL_RGB;
00569 m_channels=3;
00570 fclose(file);
00571 return true;
00572 UnGuard
00573 }
00574
00575 unsigned char * ExCImageLoader::LoadPCXFile(std::string filename, PCXHEADER *pcxHeader)
00576 {
00577 Guard(unsigned char * ExCImageLoader::LoadPCXFile(std::string filename, PCXHEADER *pcxHeader))
00578 int idx = 0;
00579 int c;
00580 int i;
00581 int numRepeat;
00582 FILE *filePtr;
00583 int width;
00584 int height;
00585 unsigned char *pixelData;
00586 unsigned char *paletteData;
00587
00588 filename=filename+".pcx";
00589
00590 filePtr = fopen(filename.data(), "rb");
00591 if (filePtr == NULL)
00592 {
00593 throw ExCExpFileNotFound();
00594 return NULL;
00595 }
00596
00597 c = getc(filePtr);
00598 if (c != 10)
00599 {
00600 fclose(filePtr);
00601 return NULL;
00602 }
00603
00604 c = getc(filePtr);
00605 if (c != 5)
00606 {
00607 fclose(filePtr);
00608 return NULL;
00609 }
00610
00611 rewind(filePtr);
00612
00613
00614 fgetc(filePtr);
00615 fgetc(filePtr);
00616 fgetc(filePtr);
00617 fgetc(filePtr);
00618
00619
00620 pcxHeader->xMin = fgetc(filePtr);
00621 pcxHeader->xMin |= fgetc(filePtr) << 8;
00622
00623
00624 pcxHeader->yMin = fgetc(filePtr);
00625 pcxHeader->yMin |= fgetc(filePtr) << 8;
00626
00627
00628 pcxHeader->xMax = fgetc(filePtr);
00629 pcxHeader->xMax |= fgetc(filePtr) << 8;
00630
00631
00632 pcxHeader->yMax = fgetc(filePtr);
00633 pcxHeader->yMax |= fgetc(filePtr) << 8;
00634
00635
00636 width = pcxHeader->xMax - pcxHeader->xMin + 1;
00637 height = pcxHeader->yMax - pcxHeader->yMin + 1;
00638
00639
00640 pixelData = (unsigned char*)malloc(width*height);
00641
00642
00643 fseek(filePtr, 128, SEEK_SET);
00644
00645
00646 while (idx < (width*height))
00647 {
00648 c = getc(filePtr);
00649 if (c > 0xbf)
00650 {
00651 numRepeat = 0x3f & c;
00652 c = getc(filePtr);
00653
00654 for (i = 0; i < numRepeat; i++)
00655 {
00656 pixelData[idx++] = c;
00657 }
00658 }
00659 else
00660 pixelData[idx++] = c;
00661
00662 fflush(stdout);
00663 }
00664
00665
00666 paletteData = (unsigned char*)malloc(768);
00667
00668
00669 fseek(filePtr, -769, SEEK_END);
00670
00671
00672 c = getc(filePtr);
00673 if (c != 12)
00674 {
00675 fclose(filePtr);
00676 return NULL;
00677 }
00678
00679 for (i = 0; i < 768; i++)
00680 {
00681 c = getc(filePtr);
00682 paletteData[i] = c;
00683 }
00684
00685
00686 fclose(filePtr);
00687 pcxHeader->palette = paletteData;
00688
00689
00690 return pixelData;
00691 UnGuard
00692 }