00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00032 #ifndef _MILLIE_WITHOUT_SDL_
00033 #include <SDL/SDL.h>
00034 #endif
00035
00036 #ifdef _MILLIE_WITH_SDLIMAGE_
00037 #include <SDL/SDL_image.h>
00038 #endif
00039
00040 #include <iostream>
00041
00042 #include "ImageIO.hpp"
00043
00044
00045 #define IMAGEIO_BLUE_COLOR 0
00046 #define IMAGEIO_RED_COLOR 1
00047 #define IMAGEIO_GREEN_COLOR 2
00048
00049 using namespace Millie;
00050
00051 #ifndef _MILLIE_WITHOUT_SDL_
00052
00061 static Uint32 SDL_LireCouleurAux(const SDL_Surface* surface, int x, int y)
00062 {
00063 int bpp = surface->format->BytesPerPixel;
00064
00065 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00066
00067 switch(bpp)
00068 {
00069 case 1:
00070 return *p;
00071 case 2:
00072 return *(Uint16 *)p;
00073 case 3:
00074 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
00075 return p[0] << 16 | p[1] << 8 | p[2];
00076 else
00077 return p[0] | p[1] << 8 | p[2] << 16;
00078 case 4:
00079 return *(Uint32 *)p;
00080 default:
00081 return 0;
00082 }
00083 }
00084
00085
00096 static void SDL_LireCouleur(const SDL_Surface * surface, int x, int y, Uint8 * r, Uint8 * g, Uint8 * b)
00097 {
00098 if (x<0 | y<0 | x>=(surface->w) | y>=(surface->h))
00099 {
00100 *r = *g = *b = 0;
00101 }
00102
00103 SDL_GetRGB(SDL_LireCouleurAux(surface, x, y), surface->format,
00104 (Uint8*) r, (Uint8*) g, (Uint8*) b);
00105
00106 }
00107
00116 void SDL_EcrireCouleurAux(SDL_Surface* surface, int x, int y, Uint32 pixel)
00117 {
00118 int bpp = surface->format->BytesPerPixel;
00119 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
00120
00121
00122 switch(bpp)
00123 {
00124 case 1:
00125 *p = pixel;
00126 break;
00127
00128 case 2:
00129 *(Uint16 *)p = pixel;
00130 break;
00131
00132 case 3:
00133 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
00134 {
00135 p[0] = (pixel >> 16) & 0xff;
00136 p[1] = (pixel >> 8) & 0xff;
00137 p[2] = pixel & 0xff;
00138 }
00139 else
00140 {
00141 p[0] = pixel & 0xff;
00142 p[1] = (pixel >> 8) & 0xff;
00143 p[2] = (pixel >> 16) & 0xff;
00144 }
00145 break;
00146
00147 case 4:
00148 *(Uint32 *)p = pixel;
00149 break;
00150 }
00151 }
00152
00163 void SDL_EcrireCouleur(SDL_Surface* surface, int x, int y, int r, int g, int b)
00164 {
00165 SDL_EcrireCouleurAux(surface, x, y,
00166 SDL_MapRGB(surface->format, r, g, b));
00167 }
00168
00174 static inline int floatTo0_255(float f)
00175 {
00176 return (int) (std::max(0.0f, std::min(255.0f, f)));
00177 }
00178
00186 SDL_Surface* imageToSDL_Surface32(const ImageRGB & imRGB)
00187 {
00188
00189 int hauteur = imRGB.getHeight();
00190 int largeur = imRGB.getWidth();
00191
00192
00193 SDL_Surface* destination = SDL_CreateRGBSurface(SDL_HWSURFACE, largeur, hauteur,
00194 32,
00195 0xff0000,
00196 0x00ff00,
00197 0x0000ff,
00198 0x000000);
00199 if(destination==NULL)
00200 {
00201 std::cerr<<"ImageIO::saveBMP Erreur Memoire"<<std::endl;
00202 throw std::bad_alloc();
00203 }
00204
00205
00206
00207 for(int j = 0; j<hauteur;j++)
00208 {
00209
00210 for(int i = 0; i<largeur; i++)
00211 {
00212 SDL_EcrireCouleur(destination, i, j,
00213 floatTo0_255(imRGB.getRedPixel(i,j)),
00214 floatTo0_255(imRGB.getGreenPixel(i,j)),
00215 floatTo0_255(imRGB.getBluePixel(i,j)));
00216 }
00217 }
00218
00219 return destination;
00220 }
00221
00232 SDL_Surface* imagegrayToSDL_Surface32(const ImageGray & imGray, int color, bool all)
00233 {
00234
00235 int hauteur = imGray.getHeight();
00236 int largeur = imGray.getWidth();
00237
00238
00239 SDL_Surface* destination = SDL_CreateRGBSurface(SDL_HWSURFACE, largeur, hauteur,
00240 32,
00241 0xff0000,
00242 0x00ff00,
00243 0x0000ff,
00244 0x000000);
00245 if(destination==NULL)
00246 {
00247 std::cerr<<"ImageIO::saveBMP Erreur Memoire"<<std::endl;
00248 throw std::bad_alloc();
00249 }
00250
00251 for(int j = 0; j<hauteur;j++)
00252 {
00253
00254 for(int i = 0; i<largeur; i++)
00255 {
00256 if(all)
00257 {
00258 SDL_EcrireCouleur(destination, i, j,
00259 floatTo0_255(imGray.getPixel(i,j)),
00260 floatTo0_255(imGray.getPixel(i,j)),
00261 floatTo0_255(imGray.getPixel(i,j)));
00262 }
00263 else
00264 {
00265 if(color == IMAGEIO_BLUE_COLOR)
00266 SDL_EcrireCouleur(destination, i, j,
00267 0,
00268 0,
00269 floatTo0_255(imGray.getPixel(i,j)));
00270 if(color == IMAGEIO_RED_COLOR)
00271 SDL_EcrireCouleur(destination, i, j,
00272 floatTo0_255(imGray.getPixel(i,j)),
00273 0,
00274 0);
00275 if(color == IMAGEIO_BLUE_COLOR)
00276 SDL_EcrireCouleur(destination, i, j,
00277 floatTo0_255(imGray.getPixel(i,j)),
00278 0,
00279 0);
00280
00281 }
00282 }
00283 }
00284
00285 return destination;
00286 }
00287
00295 void sdl_SurfaceToImageRGB(ImageRGB & imRGB, const SDL_Surface* origine)
00296 {
00297 if(origine==NULL)
00298 throw NullPointer("sdl_SurfaceToImageRGB");
00299
00300 int hauteur = origine->h;
00301 int largeur = origine->w;
00302
00303 imRGB.resize(largeur, hauteur);
00304
00305
00306 Uint8 r;
00307 Uint8 g;
00308 Uint8 b;
00309
00310 for(int j = 0; j<hauteur;j++)
00311 {
00312 for(int i = 0; i<largeur; i++)
00313 {
00314 SDL_LireCouleur(origine, i, j, &r, &g, &b);
00315 imRGB.setRedPixel(i,j, (float) r);
00316 imRGB.setGreenPixel(i,j, (float) g);
00317 imRGB.setBluePixel(i,j, (float) b);
00318 }
00319 }
00320 }
00321
00333 void sdl_SurfaceToImageGray(ImageGray & imGray, const SDL_Surface* origine, int color)
00334 {
00335 if(origine==NULL)
00336 throw NullPointer("sdl_SurfaceToImageGray");
00337
00338 if(color<0 || color>2)
00339 throw OutOfRange("sdl_SurfaceToImageGray : color range");
00340
00341 int hauteur = origine->h;
00342 int largeur = origine->w;
00343
00344 imGray.resize(largeur, hauteur);
00345
00346 Uint8 r;
00347 Uint8 g;
00348 Uint8 b;
00349
00350 for(int j = 0; j<hauteur;j++)
00351 {
00352 for(int i = 0; i<largeur; i++)
00353 {
00354 SDL_LireCouleur(origine, i, j, &r, &g, &b);
00355
00356 if(color == IMAGEIO_RED_COLOR)
00357 imGray.setPixel(i,j, (float) r);
00358
00359 if(color == IMAGEIO_GREEN_COLOR)
00360 imGray.setPixel(i,j, (float) g);
00361
00362 if(color == IMAGEIO_BLUE_COLOR)
00363 imGray.setPixel(i,j, (float) b);
00364
00365 }
00366 }
00367
00368 }
00369
00370 #endif
00371
00372
00381 void ImageIO::loadJPGComponent(ImageGray & im, const char * chemin, int color)
00382 {
00383 #ifdef _MILLIE_WITH_SDLIMAGE_
00384 if(chemin ==NULL)
00385 throw NullPointer("ImageIO::saveBMP");
00386
00387 SDL_RWops *rwop = NULL;
00388 rwop=SDL_RWFromFile(chemin, "rb");
00389 if(rwop==NULL)
00390 throw IOException("LoadJPG");
00391
00392 SDL_Surface* imageSDL = IMG_LoadJPG_RW(rwop);
00393
00394 if(imageSDL==NULL)
00395 {
00396 std::cerr<<"Load JPG : Probleme de lecture fichier"<<std::endl;
00397 SDL_FreeRW(rwop);
00398 throw IOException("LoadJPG");
00399 }
00400
00401
00402 sdl_SurfaceToImageGray(im, imageSDL, color);
00403 SDL_FreeRW(rwop);
00404 SDL_FreeSurface(imageSDL);
00405 #else
00406 throw Exception("loadJPGComponent : Not yet implemented without SDL_Image");
00407 #endif
00408 }
00409
00410 void ImageIO::loadJPGRedComponent(ImageGray & im, const char* chemin)
00411 {
00412 return ImageIO::loadJPGComponent(im, chemin, IMAGEIO_RED_COLOR);
00413 }
00414
00415 void ImageIO::loadJPGGreenComponent(ImageGray & im, const char* chemin)
00416 {
00417 return ImageIO::loadJPGComponent(im, chemin, IMAGEIO_GREEN_COLOR);
00418 }
00419
00420 void ImageIO::loadJPGBlueComponent(ImageGray & im, const char* chemin)
00421 {
00422 return ImageIO::loadJPGComponent(im, chemin, IMAGEIO_BLUE_COLOR);
00423 }
00424
00425 void ImageIO::loadJPG(ImageRGB & imRGB, const char * chemin)
00426 {
00427 #ifdef _MILLIE_WITH_SDLIMAGE_
00428 if(chemin ==NULL)
00429 throw NullPointer("ImageIO::loadBMP");
00430
00431 SDL_RWops *rwop = NULL;
00432 rwop=SDL_RWFromFile(chemin, "rb");
00433 if(rwop==NULL)
00434 throw IOException("LoadJPG");
00435
00436 SDL_Surface* imageSDL = IMG_LoadJPG_RW(rwop);
00437
00438 if(imageSDL==NULL)
00439 {
00440 std::cerr<<"Load JPG : Probleme de lecture fichier"<<std::endl;
00441 throw IOException("LoadJPG");
00442 }
00443
00444 sdl_SurfaceToImageRGB(imRGB, imageSDL);
00445 SDL_FreeRW(rwop);
00446 SDL_FreeSurface(imageSDL);
00447 #else
00448 throw Exception("loadJPG : Not yet implemented without SDL_Image");
00449 #endif
00450 }
00451
00462 void ImageIO::loadBMPComponent(ImageGray & im, const char* chemin, int color)
00463 {
00464 #ifndef _MILLIE_WITHOUT_SDL_
00465 if(chemin ==NULL)
00466 throw NullPointer("ImageIO::saveBMP");
00467
00468 SDL_Surface* imageSDL =SDL_LoadBMP(chemin);
00469
00470 if(imageSDL==NULL)
00471 {
00472 std::cerr<<"Load BMP : Probleme de lecture fichier"<<std::endl;
00473 throw IOException("LoadBMP");
00474 }
00475
00476
00477 sdl_SurfaceToImageGray(im, imageSDL, color);
00478 SDL_FreeSurface(imageSDL);
00479 #else
00480 throw Exception("loadBMP: Not yet implemented without SDL");
00481 #endif
00482 }
00483
00484 void ImageIO::loadBMPGreenComponent(ImageGray & im, const char* chemin)
00485 {
00486 return ImageIO::loadBMPComponent(im, chemin, IMAGEIO_GREEN_COLOR);
00487 }
00488
00489 void ImageIO::loadBMPBlueComponent(ImageGray & im, const char* chemin)
00490 {
00491 return ImageIO::loadBMPComponent(im, chemin, IMAGEIO_BLUE_COLOR);
00492 }
00493
00494 void ImageIO::loadBMPRedComponent(ImageGray & im, const char* chemin)
00495 {
00496 return ImageIO::loadBMPComponent(im, chemin, IMAGEIO_RED_COLOR);
00497 }
00498
00499 void ImageIO::saveBMP(ImageGray & imGray, const char * chemin)
00500 {
00501 #ifndef _MILLIE_WITHOUT_SDL_
00502 if(chemin ==NULL)
00503 throw NullPointer("ImageIO::saveBMP");
00504
00505 SDL_Surface* destination = imagegrayToSDL_Surface32(imGray,0 , true);
00506
00507 if(SDL_SaveBMP(destination, chemin) == -1)
00508 {
00509 std::cerr<<"saveBMP : Erreur enregistrement"<<std::endl;
00510 throw IOException("saveBMP");
00511 }
00512
00513 SDL_FreeSurface(destination);
00514
00515 return;
00516 #else
00517 throw Exception("saveBMP : Not yet implemented without SDL");
00518 #endif
00519 }
00520
00521
00522
00523 void ImageIO::loadBMP(ImageRGB & imRGB, const char * chemin)
00524 {
00525 #ifndef _MILLIE_WITHOUT_SDL_
00526 if(chemin ==NULL)
00527 throw NullPointer("ImageIO::loadBMP");
00528
00529 SDL_Surface* imageSDL =SDL_LoadBMP(chemin);
00530
00531 if(imageSDL==NULL)
00532 {
00533 std::cerr<<"Load BMP : Probleme de lecture fichier"<<std::endl;
00534 throw IOException("LoadBMP");
00535 }
00536
00537 sdl_SurfaceToImageRGB(imRGB, imageSDL);
00538 SDL_FreeSurface(imageSDL);
00539 return;
00540 #else
00541 throw Exception("loadBMP : Not yet implemented without SDL");
00542 #endif
00543 }
00544
00545
00546
00547 void ImageIO::saveBMP(ImageRGB & imRGB, const char * chemin)
00548 {
00549 #ifndef _MILLIE_WITHOUT_SDL_
00550 if(chemin ==NULL)
00551 throw NullPointer("ImageIO::saveBMP");
00552
00553 SDL_Surface* destination = imageToSDL_Surface32(imRGB);
00554
00555 if(SDL_SaveBMP(destination, chemin) == -1)
00556 {
00557 std::cerr<<"saveBMP : Erreur enregistrement"<<std::endl;
00558 throw IOException("saveBMP");
00559 }
00560
00561 SDL_FreeSurface(destination);
00562
00563 return;
00564 #else
00565 throw Exception("loadBMP : Not yet implemented without SDL");
00566 #endif
00567 }
00568