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
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
00037 std::string ext = fileutils::getExtension(fileName);
00038
00039 if(ext == "not_found") {
00040
00041 printf("[%s]: Error: Can not load file without extension. What file type? <%s>\n", __FILE__, fileName.c_str());
00042 return;
00043 }
00044
00045
00046 m_fileName = fileName;
00047
00048
00049 if(ext == "tga" || ext == "TGA") {
00050 result = loadTargaFile(alpha, ar, ag, ab);
00051
00052 } else {
00053
00054 if(ext == "bmp" || ext == "BMP") {
00055 swapBGR = true;
00056
00057 } else if(ext == "jpg" || ext == "JPG" || ext == "jpeg" || ext == "JPEG") {
00058 swapBGR = false;
00059 } else {
00060
00061 return;
00062 }
00063
00064 result = loadFile(alpha, swapBGR, ar, ag, ab);
00065 }
00066
00067
00068 if(!result) {
00069
00070 printf("[%s]: Error: Could not load image <%s>.\n", __FILE__, fileName.c_str());
00071 m_loadOk = false;
00072 } else {
00073
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
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
00102 if(m_bitsPerPixel == 24) {
00103 m_type = RGB;
00104 } else if(m_bitsPerPixel == 32) {
00105 m_type = RGBA;
00106 } else {
00107
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
00141
00142 SDL_RWops *rwops;
00143 SDL_Surface *sur;
00144 SDL_PixelFormat *pix;
00145
00146
00147
00148 rwops = SDL_RWFromFile(m_fileName.c_str(), "rb");
00149 if(rwops == NULL) {
00150
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
00157 printf("[%s]: Error: Could not load image.\n", __FILE__);
00158 return false;
00159 }
00160
00161 pix = sur->format;
00162 if(pix == NULL) {
00163
00164 printf("[%s]: Error: Could not get pixel format.\n", __FILE__);
00165 return false;
00166 }
00167
00168
00169 if(pix->BitsPerPixel == 24) {
00170 m_type = RGB;
00171 } else if(pix->BitsPerPixel == 32) {
00172 m_type = RGBA;
00173 } else {
00174
00175 printf("[%s]: Warning: Unknown pixeltype!\n", __FILE__);
00176 m_type = Unknown;
00177 }
00178
00179
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
00188 if(swapBGR) {
00189 swapBGRToRGB();
00190 }
00191
00192 if(alpha) {
00193 addAlphaChannel(ar, ag, ab);
00194 }
00195
00196
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
00212
00213 SDL_RWops *rwops;
00214 SDL_Surface *sur;
00215 SDL_PixelFormat *pix;
00216
00217
00218
00219 rwops = SDL_RWFromFile(m_fileName.c_str(), "rb");
00220 if(rwops == NULL) {
00221
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
00228 printf("[%s]: Error: Could not load image.\n", __FILE__);
00229 return false;
00230 }
00231
00232 pix = sur->format;
00233 if(pix == NULL) {
00234
00235 printf("[%s]: Error: Could not get pixel format.\n", __FILE__);
00236 return false;
00237 }
00238
00239
00240 if(pix->BitsPerPixel == 24) {
00241 m_type = RGB;
00242 } else if(pix->BitsPerPixel == 32) {
00243 m_type = RGBA;
00244 } else {
00245
00246 printf("[%s]: Warning: Unknown pixeltype!\n", __FILE__);
00247 m_type = Unknown;
00248 }
00249
00250
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
00259 swapBGRToRGB();
00260
00261 if(alpha) {
00262 this->addAlphaChannel(ar, ag, ab);
00263 }
00264
00265
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
00281
00282 unsigned char swap;
00283 int i;
00284 int size;
00285
00286
00287 size = m_width * m_height * (m_bitsPerPixel / 8);
00288
00289
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
00314
00315 uint8 *alphaImage;
00316 int i;
00317 int j;
00318 int size;
00319
00320
00321
00322
00323 if(this->m_type == RGB) {
00324
00325
00326 size = this->m_width * this->m_height * (this->m_bitsPerPixel / 8);
00327
00328
00329 alphaImage = new uint8[this->m_width * this->m_height * 4];
00330 if(alphaImage == NULL) {
00331
00332 printf("[%s]: Error: Could not allocate space for image.\n", __FILE__);
00333 return;
00334 }
00335
00336
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
00348 delete [] this->m_image;
00349 this->m_image = NULL;
00350
00351 this->m_image = alphaImage;
00352 this->m_type = RGBA;
00353 this->m_bitsPerPixel = 32;
00354 }
00355 }
00356 };