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

/Users/blackie/Documents/myRepository/phobosengine-vc2005/phobosengine/phobosengine/Image.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include "Image.h"
00004 
00005 #include "FileUtils.h"
00006 
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <SDL_image.h>
00010 
00011 
00012 namespace pge {
00013 
00014 
00015         //****************************************************************************
00016         //
00017         //
00018         //
00019         //****************************************************************************
00020         Image::Image(const std::string &fileName, bool alpha, int ar, int ag, int ab) {
00021                 bool result;
00022                 bool swapBGR;
00023 
00024 
00025                 // Initialize class variables.
00026                 m_type = Unknown;
00027                 m_image = NULL;
00028                 m_width = 0;
00029                 m_height = 0;
00030                 m_bitsPerPixel = 0;
00031                 m_loadOk = false;
00032 
00033                 result = false;
00034                 swapBGR = false;
00035 
00036                 // Get the extension of the image filename
00037                 std::string ext = fileutils::getExtension(fileName);
00038 
00039                 if(ext == "not_found") {
00040                         // TODO: log
00041                         printf("[%s]: Error: Can not load file without extension. What file type? <%s>\n", __FILE__, fileName.c_str());
00042                         return;
00043                 }
00044 
00045                 // Copy filename
00046                 m_fileName = fileName;
00047 
00048                 // If extensions equals "tga" or "TGA", load tga files
00049                 if(ext == "tga" || ext == "TGA") {
00050                         result = loadTargaFile(alpha, ar, ag, ab);
00051 
00052                 } else {
00053                         // BMP
00054                         if(ext == "bmp" || ext == "BMP") {
00055                                 swapBGR = true;
00056                                 // JPEG
00057                         } else if(ext == "jpg" || ext == "JPG" || ext == "jpeg" || ext == "JPEG") {
00058                                 swapBGR = false;
00059                         } else {
00060                                 // TODO: log message and add new filetypes
00061                                 return;
00062                         }
00063                         // Load image
00064                         result = loadFile(alpha, swapBGR, ar, ag, ab);
00065                 }
00066 
00067                 // Check result
00068                 if(!result) {
00069                         // TODO: log
00070                         printf("[%s]: Error: Could not load image <%s>.\n", __FILE__, fileName.c_str());
00071                         m_loadOk = false;
00072                 } else {
00073                         // Loading was successfully done
00074                         m_loadOk = true;
00075                 }
00076         }
00077 
00078 
00079         //****************************************************************************
00080         //
00081         //
00082         //
00083         //****************************************************************************
00084         Image::Image(unsigned char *image, int width, int height, int bits, ImageType type,
00085                 bool alpha, int ar, int ag, int ab) {
00086 
00087                         if(image != NULL) {
00088                                 m_image = image;
00089                                 image = NULL;
00090                         } else {
00091                                 // TODO: log
00092                                 printf("[%s]: Error: You must give a valid image to the constructor!\n", __FILE__);
00093                                 m_loadOk = false;
00094                                 return;
00095                         }
00096 
00097                         m_width = width;
00098                         m_height = height;
00099                         m_bitsPerPixel = bits;
00100 
00101                         // set pixel type
00102                         if(m_bitsPerPixel == 24) {
00103                                 m_type = RGB;
00104                         } else if(m_bitsPerPixel == 32) {
00105                                 m_type = RGBA;
00106                         } else {
00107                                 // TODO: log
00108                                 printf("[%s]: Warning: Unknown pixeltype!\n", __FILE__);
00109                                 m_type = Unknown;
00110                         }
00111 
00112                         if(alpha) {
00113                                 addAlphaChannel(ar, ag, ab);
00114                         }
00115 
00116                         m_loadOk = true;
00117         }
00118 
00119 
00120         //****************************************************************************
00121         //
00122         //
00123         //
00124         //****************************************************************************
00125         Image::~Image() {
00126                 if(m_image != NULL) {
00127                         delete [] m_image;
00128                 }
00129                 m_image = NULL;
00130         }
00131 
00132 
00133         //****************************************************************************
00134         //
00135         //
00136         //
00137         //****************************************************************************
00138         bool Image::loadFile(int alpha, bool swapBGR, int ar, int ag, int ab) {
00139                 //
00140                 // Variables
00141                 //
00142                 SDL_RWops *rwops;
00143                 SDL_Surface *sur;
00144                 SDL_PixelFormat *pix;
00145 
00146 
00147                 // Load file
00148                 rwops = SDL_RWFromFile(m_fileName.c_str(), "rb");
00149                 if(rwops == NULL) {
00150                         // TODO: log
00151                         printf("[%s]: Error: Could not open file.\n", __FILE__);
00152                         return false;
00153                 }
00154                 sur = IMG_Load_RW(rwops, 0);
00155                 if(sur == NULL) {
00156                         // TODO: log
00157                         printf("[%s]: Error: Could not load image.\n", __FILE__);
00158                         return false;
00159                 }
00160 
00161                 pix = sur->format;
00162                 if(pix == NULL) {
00163                         // TODO: log
00164                         printf("[%s]: Error: Could not get pixel format.\n", __FILE__);
00165                         return false;
00166                 }
00167 
00168                 // Set pixel type
00169                 if(pix->BitsPerPixel == 24) {
00170                         m_type = RGB;
00171                 } else if(pix->BitsPerPixel == 32) {
00172                         m_type = RGBA;
00173                 } else {
00174                         // TODO: log
00175                         printf("[%s]: Warning: Unknown pixeltype!\n", __FILE__);
00176                         m_type = Unknown;
00177                 }
00178 
00179                 // Copy data over
00180                 m_width = sur->w;
00181                 m_height = sur->h;
00182                 m_bitsPerPixel = pix->BitsPerPixel;
00183 
00184                 m_image = new unsigned char[m_width * m_height * pix->BytesPerPixel];
00185                 memcpy(m_image, sur->pixels, m_width * m_height * pix->BytesPerPixel);
00186 
00187                 // Swap blue and red
00188                 if(swapBGR) {
00189                         swapBGRToRGB();
00190                 }
00191 
00192                 if(alpha) {
00193                         addAlphaChannel(ar, ag, ab);
00194                 }
00195 
00196                 // Clean up
00197                 SDL_FreeSurface(sur);
00198                 SDL_FreeRW(rwops);
00199 
00200                 return true;
00201         }
00202 
00203 
00204         //****************************************************************************
00205         //
00206         //
00207         //
00208         //****************************************************************************
00209         bool Image::loadTargaFile(int alpha, int ar, int ag, int ab) {
00210                 //
00211                 // Variables
00212                 //
00213                 SDL_RWops *rwops;
00214                 SDL_Surface *sur;
00215                 SDL_PixelFormat *pix;
00216 
00217 
00218                 // Load file
00219                 rwops = SDL_RWFromFile(m_fileName.c_str(), "rb");
00220                 if(rwops == NULL) {
00221                         // TODO: log
00222                         printf("[%s]: Error: Could not open file.\n", __FILE__);
00223                         return false;
00224                 }
00225                 sur = IMG_LoadTGA_RW(rwops);
00226                 if(sur == NULL) {
00227                         // TODO: log
00228                         printf("[%s]: Error: Could not load image.\n", __FILE__);
00229                         return false;
00230                 }
00231 
00232                 pix = sur->format;
00233                 if(pix == NULL) {
00234                         // TODO: log
00235                         printf("[%s]: Error: Could not get pixel format.\n", __FILE__);
00236                         return false;
00237                 }
00238 
00239                 // Set pixel type
00240                 if(pix->BitsPerPixel == 24) {
00241                         m_type = RGB;
00242                 } else if(pix->BitsPerPixel == 32) {
00243                         m_type = RGBA;
00244                 } else {
00245                         // TODO: log
00246                         printf("[%s]: Warning: Unknown pixeltype!\n", __FILE__);
00247                         m_type = Unknown;
00248                 }
00249 
00250                 // Copy data over
00251                 m_width = sur->w;
00252                 m_height = sur->h;
00253                 m_bitsPerPixel = pix->BitsPerPixel;
00254 
00255                 m_image = new unsigned char[m_width * m_height * pix->BytesPerPixel];
00256                 memcpy(m_image, sur->pixels, m_width * m_height * pix->BytesPerPixel);
00257 
00258                 // Swap blue and red
00259                 swapBGRToRGB();
00260 
00261                 if(alpha) {
00262                         this->addAlphaChannel(ar, ag, ab);
00263                 }
00264 
00265                 // Clean up
00266                 SDL_FreeSurface(sur);
00267                 SDL_FreeRW(rwops);
00268 
00269                 return true;
00270         }
00271 
00272 
00273         //****************************************************************************
00274         //
00275         //
00276         //
00277         //****************************************************************************
00278         void Image::swapBGRToRGB(void) {
00279                 //
00280                 // Variables
00281                 //
00282                 unsigned char swap;
00283                 int i;
00284                 int size;
00285 
00286 
00287                 size = m_width * m_height * (m_bitsPerPixel / 8);
00288 
00289                 // Swap BGR to RGB
00290                 if(m_bitsPerPixel == 24) {
00291                         for(i = 0; i < size; i += 3) {
00292                                 swap = m_image[i];
00293                                 m_image[i] = m_image[i + 2];
00294                                 m_image[i + 2] = swap;
00295                         }
00296                 } else if(m_bitsPerPixel == 32) {
00297                         for(i = 0; i < size; i += 4) {
00298                                 swap = m_image[i];
00299                                 m_image[i] = m_image[i + 2];
00300                                 m_image[i + 2] = swap;
00301                         }
00302                 }
00303         }
00304 
00305 
00306         //****************************************************************************
00307         //
00308         //
00309         //
00310         //****************************************************************************
00311         void Image::addAlphaChannel(int ar, int ag, int ab) {
00312                 //
00313                 // Variables
00314                 //
00315                 uint8 *alphaImage;
00316                 int i;
00317                 int j;
00318                 int size;
00319 
00320 
00321                 // If we already have alpha, then don't do anything
00322                 // but if the type is RGB, then add alpha
00323                 if(this->m_type == RGB) {
00324 
00325                         // The size of the original image
00326                         size = this->m_width * this->m_height * (this->m_bitsPerPixel / 8);
00327 
00328                         // The new image with alpha
00329                         alphaImage = new uint8[this->m_width * this->m_height * 4];
00330                         if(alphaImage == NULL) {
00331                                 // TODO: log
00332                                 printf("[%s]: Error: Could not allocate space for image.\n", __FILE__);
00333                                 return;
00334                         }
00335 
00336                         // Add alpha
00337                         for(i = 0, j = 0; i < size; i += 3, j += 4) {
00338                                 alphaImage[j] = this->m_image[i];
00339                                 alphaImage[j + 1] = this->m_image[i + 1];
00340                                 alphaImage[j + 2] = this->m_image[i + 2];
00341                                 if(this->m_image[i] == ar && this->m_image[i + 1] == ag && this->m_image[i + 2] == ab) {
00342                                         alphaImage[j + 3] = 0;
00343                                 } else {
00344                                         alphaImage[j + 3] = 255;
00345                                 }
00346                         }
00347                         // Delete old image
00348                         delete [] this->m_image;
00349                         this->m_image = NULL;
00350                         // Copy over and set new infos
00351                         this->m_image = alphaImage;
00352                         this->m_type = RGBA;
00353                         this->m_bitsPerPixel = 32;
00354                 }
00355         }
00356 };

Generated on Mon Oct 16 12:08:10 2006 for Phobosengine by doxygen 1.3.4