Main Page   Namespace List   Class Hierarchy   Alphabetical List   Data Structures   File List   Namespace Members   Data Fields   Globals  

ExCImageLoader.cpp

Go to the documentation of this file.
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         //std::cout<<FileName<<std::endl;
00023         //Extension in string
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                 //if(FileName.find(".jpg")==(FileName.length()-4))return JPG;
00030                 //if(FileName.find(".rgb")==(FileName.length()-4))return RGB;
00031                 //if(FileName.find(".raw")==(FileName.length()-4))return RAW;
00032                 if(FileName.find(".ppm")==(FileName.length()-4))return PPM;
00033                 if(FileName.find(".")<FileName.length())return UNKNOWN;
00034         }
00035         //No extension in string
00036         //std::cout<<"File without extension"<<std::endl;
00037         FILE *file;
00038         std::ifstream filetest;
00039         std::string strFileName;
00040         
00041         //try with bmp
00042         strFileName=FileName+".bmp";
00043         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return BMP;}
00044     //try with pcx
00045         strFileName=FileName+".pcx";
00046         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return PCX;}
00047         //try with tga
00048         strFileName=FileName+".tga";
00049         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return TGA;}
00050         //try with ppm
00051         strFileName=FileName+".ppm";
00052         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return PPM;}
00053         /*
00054         //try with jpg
00055         strFileName=FileName+".jpg";
00056         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return JPG;}
00057         //try with rgb
00058         strFileName=FileName+".rgb";
00059         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return RGB;}
00060         //try with raw
00061         strFileName=FileName+".raw";
00062         if ((file = fopen(strFileName.data(), "r"))!=NULL){fclose(file);return RAW;}
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         //std::cout<<m_TextureType;
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         //case RGB:return LoadRGB(FileName);
00081         //case RAW:return LoadRAW(FileName);
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];          /* max line <= 70 in PPM (per spec). */
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     /* grab first two chars of the file and make sure that it has the
00122        correct magic cookie for a raw PPM file. */
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     /* grab the three elements in the header (width, height, maxval). */
00131     i = 0;
00132     while(i < 3) {
00133         fgets(head, 70, fp);
00134         if (head[0] == '#')     /* skip comments. */
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     /* grab all the image data in one fell swoop. */
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;                     // The dimensions of the image
00161         byte length = 0;                                        // The length in bytes to the pixels
00162         byte imageType = 0;                                     // The image type (RLE, RGB, Alpha...)
00163         byte bits = 0;                                          // The bits per pixel for the image (16, 24, 32)
00164         FILE *pFile = NULL;                                     // The file pointer
00165         int channels = 0;                                       // The channels of the image (3 = RGA : 4 = RGBA)
00166         int stride = 0;                                         // The stride (channels * width)
00167         int i = 0;                                                      // A counter
00168 
00169         strFileName=strFileName+".tga";
00170         // Open a file pointer to the targa file and check if it was found and opened 
00171         if((pFile = fopen(strFileName.data(), "rb")) == NULL) 
00172         {
00173                 // Display an error message saying the file was not found, then return NULL
00174                 std::cout<<strFileName<<std::endl;
00175                 throw ExCExpFileNotFound();
00176                 return NULL;
00177         }
00178                 
00179         // Read in the length in bytes from the header to the pixel data
00180         fread(&length, sizeof(byte), 1, pFile);
00181         
00182         // Jump over one byte
00183         fseek(pFile,1,SEEK_CUR); 
00184 
00185         // Read in the imageType (RLE, RGB, etc...)
00186         fread(&imageType, sizeof(byte), 1, pFile);
00187         
00188         // Skip past general information we don't care about
00189         fseek(pFile, 9, SEEK_CUR); 
00190 
00191         // Read the width, height and bits per pixel (16, 24 or 32)
00192         fread(&width,  sizeof(WORD), 1, pFile);
00193         fread(&height, sizeof(WORD), 1, pFile);
00194         fread(&bits,   sizeof(byte), 1, pFile);
00195         
00196         // Now we move the file pointer to the pixel data
00197         fseek(pFile, length + 1, SEEK_CUR); 
00198 
00199         // Check if the image is RLE compressed or not
00200         if(imageType != TGA_RLE)
00201         {
00202                 // Check if the image is a 24 or 32-bit image
00203                 if(bits == 24 || bits == 32)
00204                 {
00205                         // Calculate the channels (3 or 4) - (use bits >> 3 for more speed).
00206                         // Next, we calculate the stride and allocate enough memory for the pixels.
00207                         channels = bits / 8;
00208                         stride = channels * width;
00209                         m_data = new unsigned char[stride * height];
00210 
00211                         // Load in all the pixel data line by line
00212                         for(int y = 0; y < height; y++)
00213                         {
00214                                 // Store a pointer to the current line of pixels
00215                                 unsigned char *pLine = &(m_data[stride * y]);
00216 
00217                                 // Read in the current line of pixels
00218                                 fread(pLine, stride, 1, pFile);
00219                         
00220                                 // Go through all of the pixels and swap the B and R values since TGA
00221                                 // files are stored as BGR instead of RGB (or use GL_BGR_EXT verses GL_RGB)
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                 // Check if the image is a 16 bit image (RGB stored in 1 unsigned short)
00231                 else if(bits == 16)
00232                 {
00233                         unsigned short pixels = 0;
00234                         int r=0, g=0, b=0;
00235 
00236                         // Since we convert 16-bit images to 24 bit, we hardcode the channels to 3.
00237                         // We then calculate the stride and allocate memory for the pixels.
00238                         channels = 3;
00239                         stride = channels * width;
00240                         m_data = new unsigned char[stride * height];
00241 
00242                         // Load in all the pixel data pixel by pixel
00243                         for(int i = 0; i < width*height; i++)
00244                         {
00245                                 // Read in the current pixel
00246                                 fread(&pixels, sizeof(unsigned short), 1, pFile);
00247                                 
00248                                 // To convert a 16-bit pixel into an R, G, B, we need to
00249                                 // do some masking and such to isolate each color value.
00250                                 // 0x1f = 11111 in binary, so since 5 bits are reserved in
00251                                 // each unsigned short for the R, G and B, we bit shift and mask
00252                                 // to find each value.  We then bit shift up by 3 to get the full color.
00253                                 b = (pixels & 0x1f) << 3;
00254                                 g = ((pixels >> 5) & 0x1f) << 3;
00255                                 r = ((pixels >> 10) & 0x1f) << 3;
00256                                 
00257                                 // This essentially assigns the color to our array and swaps the
00258                                 // B and R values at the same time.
00259                                 m_data[i * 3 + 0] = r;
00260                                 m_data[i * 3 + 1] = g;
00261                                 m_data[i * 3 + 2] = b;
00262                         }
00263                 }       
00264                 // Else return a NULL for a bad or unsupported pixel format
00265                 else
00266                         return NULL;
00267         }
00268         // Else, it must be Run-Length Encoded (RLE)
00269         else
00270         {
00271                 // Create some variables to hold the rleID, current colors read, channels, & stride.
00272                 byte rleID = 0;
00273                 int colorsRead = 0;
00274                 channels = bits / 8;
00275                 stride = channels * width;
00276 
00277                 // Next we want to allocate the memory for the pixels and create an array,
00278                 // depending on the channel count, to read in for each pixel.
00279                 m_data = new unsigned char[stride * height];
00280                 byte *pColors = new byte [channels];
00281 
00282                 // Load in all the pixel data
00283                 while(i < width*height)
00284                 {
00285                         // Read in the current color count + 1
00286                         fread(&rleID, sizeof(byte), 1, pFile);
00287                         
00288                         // Check if we don't have an encoded string of colors
00289                         if(rleID < 128)
00290                         {
00291                                 // Increase the count by 1
00292                                 rleID++;
00293 
00294                                 // Go through and read all the unique colors found
00295                                 while(rleID)
00296                                 {
00297                                         // Read in the current color
00298                                         fread(pColors, sizeof(byte) * channels, 1, pFile);
00299 
00300                                         // Store the current pixel in our image array
00301                                         m_data[colorsRead + 0] = pColors[2];
00302                                         m_data[colorsRead + 1] = pColors[1];
00303                                         m_data[colorsRead + 2] = pColors[0];
00304 
00305                                         // If we have a 4 channel 32-bit image, assign one more for the alpha
00306                                         if(bits == 32)
00307                                                 m_data[colorsRead + 3] = pColors[3];
00308 
00309                                         // Increase the current pixels read, decrease the amount
00310                                         // of pixels left, and increase the starting index for the next pixel.
00311                                         i++;
00312                                         rleID--;
00313                                         colorsRead += channels;
00314                                 }
00315                         }
00316                         // Else, let's read in a string of the same character
00317                         else
00318                         {
00319                                 // Minus the 128 ID + 1 (127) to get the color count that needs to be read
00320                                 rleID -= 127;
00321 
00322                                 // Read in the current color, which is the same for a while
00323                                 fread(pColors, sizeof(byte) * channels, 1, pFile);
00324 
00325                                 // Go and read as many pixels as are the same
00326                                 while(rleID)
00327                                 {
00328                                         // Assign the current pixel to the current index in our pixel array
00329                                         m_data[colorsRead + 0] = pColors[2];
00330                                         m_data[colorsRead + 1] = pColors[1];
00331                                         m_data[colorsRead + 2] = pColors[0];
00332 
00333                                         // If we have a 4 channel 32-bit image, assign one more for the alpha
00334                                         if(bits == 32)
00335                                                 m_data[colorsRead + 3] = pColors[3];
00336 
00337                                         // Increase the current pixels read, decrease the amount
00338                                         // of pixels left, and increase the starting index for the next pixel.
00339                                         i++;
00340                                         rleID--;
00341                                         colorsRead += channels;
00342                                 }
00343                                 
00344                         }
00345                                 
00346                 }
00347         }
00348 
00349         // Close the file pointer that opened the file
00350         fclose(pFile);
00351 
00352         // Fill in our tImageTGA structure to pass back
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;            // header of texture
00373      //texture_t *thisTexture;       // the texture
00374      unsigned char *unscaledData;// used to calculate pcx
00375      int i;                             // index counter
00376      int j;                             // index counter
00377      int width;                         // width of texture
00378      int height;                        // height of texture
00379 
00380 
00381      // load the PCX file into the texture struct
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      // store the texture information
00391      m_palette = texInfo.palette;
00392      m_sizeX = texInfo.xMax - texInfo.xMin + 1;
00393      m_sizeY = texInfo.yMax - texInfo.yMin + 1;
00394      
00395      // allocate memory for the unscaled data
00396      unscaledData = (unsigned char*)malloc(m_sizeX*m_sizeY*4);
00397 
00398      // store the unscaled data via the palette
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      // find width and height's nearest greater power of 2
00411      width = m_sizeX;
00412      height = m_sizeY;
00413 
00414      // find width's
00415      i = 0;
00416      while (width)
00417      {
00418           width /= 2;
00419           i++;
00420      }
00421      m_scaledHeight = (long)pow(2, i-1);
00422 
00423      // find height's
00424      i = 0;
00425      while (height)
00426      {
00427           height /= 2;
00428           i++;
00429      }
00430          m_scaledWidth = (long)pow(2, i-1);
00431 
00432      // clear the texture data
00433      if (m_data != NULL)
00434      {
00435           free(m_data);
00436           m_data = NULL;
00437      }
00438 
00439      // reallocate memory for the texture data
00440      m_data = (unsigned char*)malloc(m_scaledWidth*m_scaledHeight*4);
00441      
00442      // use the GL utility library to scale the texture to the unscaled dimensions
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;                 // size of the image in uchars.
00455         unsigned long i;                    // standard counter.
00456         unsigned short int planes;          // number of planes in image (must be 1) 
00457         unsigned short int channels;        // number of bits per pixel (must be 24)
00458         char temp;                          // temporary color storage for bgr-rgb conversion.
00459 
00460         // make sure the file is there.
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         /* check if file is a bitmap */
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         /* get the position of the actual bitmap data */
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         /*sprintf(buffer,"Data at offset: %ld.", bfOffBits);
00491         WriteToConsol(buffer);*/
00492         
00493         // seek through the bmp header, up to the width/height:
00494         fseek(file, 4, SEEK_CUR);
00495 #else
00496         fseek(file, 18, SEEK_SET);
00497 #endif
00498         // read the width
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         // read the height 
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         // calculate the size (assuming 24 bits or 3 uchars per pixel).
00514         size = m_sizeX * m_sizeY * 3;
00515 
00516         // read the planes
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         // read the channels
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         // seek past the rest of the bitmap header.
00542         fseek(file, 24, SEEK_CUR);
00543         // read the data. 
00544         m_data = new unsigned char[size];
00545         //char *foo = new char[size];
00546         //m_data = foo;
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                 // reverse all of the colors. (bgr -> rgb)
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;                  // counter index
00579      int c;                             // used to retrieve a char from the file
00580      int i;                             // counter index
00581      int numRepeat;      
00582      FILE *filePtr;                // file handle
00583      int width;                         // pcx width
00584      int height;                        // pcx height
00585          unsigned char *pixelData;     // pcx image data
00586      unsigned char *paletteData;   // pcx palette data
00587 
00588      filename=filename+".pcx";
00589          // open PCX file
00590      filePtr = fopen(filename.data(), "rb");
00591          if (filePtr == NULL)
00592          {
00593                 throw ExCExpFileNotFound();
00594                 return NULL;
00595          }
00596      // retrieve first character; should be equal to 10
00597      c = getc(filePtr);
00598      if (c != 10)
00599      {
00600           fclose(filePtr);
00601           return NULL;
00602      }
00603      // retrieve next character; should be equal to 5
00604      c = getc(filePtr);
00605      if (c != 5)
00606      {
00607           fclose(filePtr);
00608           return NULL;
00609      }
00610      // reposition file pointer to beginning of file
00611      rewind(filePtr);
00612 
00613      // read 4 characters of data to skip
00614      fgetc(filePtr);
00615      fgetc(filePtr);
00616      fgetc(filePtr);
00617      fgetc(filePtr);
00618 
00619      // retrieve leftmost x value of PCX
00620      pcxHeader->xMin = fgetc(filePtr);       // loword
00621      pcxHeader->xMin |= fgetc(filePtr) << 8; // hiword
00622 
00623      // retrieve bottom-most y value of PCX
00624      pcxHeader->yMin = fgetc(filePtr);       // loword
00625      pcxHeader->yMin |= fgetc(filePtr) << 8; // hiword
00626 
00627      // retrieve rightmost x value of PCX
00628      pcxHeader->xMax = fgetc(filePtr);       // loword
00629      pcxHeader->xMax |= fgetc(filePtr) << 8; // hiword
00630 
00631      // retrieve topmost y value of PCX
00632      pcxHeader->yMax = fgetc(filePtr);       // loword
00633      pcxHeader->yMax |= fgetc(filePtr) << 8; // hiword
00634 
00635      // calculate the width and height of the PCX
00636      width = pcxHeader->xMax - pcxHeader->xMin + 1;
00637      height = pcxHeader->yMax - pcxHeader->yMin + 1;
00638 
00639      // allocate memory for PCX image data
00640      pixelData = (unsigned char*)malloc(width*height);
00641 
00642      // set file pointer to 128th byte of file, where the PCX image data starts
00643      fseek(filePtr, 128, SEEK_SET);
00644      
00645      // decode the pixel data and store
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      // allocate memory for the PCX image palette
00666      paletteData = (unsigned char*)malloc(768);
00667 
00668      // palette is the last 769 bytes of the PCX file
00669      fseek(filePtr, -769, SEEK_END);
00670 
00671      // verify palette; first character should be 12
00672      c = getc(filePtr);
00673      if (c != 12)
00674      {
00675           fclose(filePtr);
00676           return NULL;
00677      }
00678      // read and store all of palette
00679      for (i = 0; i < 768; i++)
00680      {
00681           c = getc(filePtr);
00682           paletteData[i] = c;
00683      }
00684 
00685      // close file and store palette in header
00686      fclose(filePtr);
00687      pcxHeader->palette = paletteData;
00688 
00689          // return the pixel image data
00690          return pixelData;
00691 UnGuard
00692 }

Generated on Tue Dec 10 18:20:03 2002 for ExNihilo by doxygen1.3-rc1