00001
00157 #ifndef __IMAGE_FILE__
00158 #define __IMAGE_FILE__
00159
00160 #include <algorithm>
00161 #include <functional>
00162 #include <stdexcept>
00163
00164 #include <qcolor.h>
00165 #include <qimage.h>
00166 #include <qstring.h>
00167
00168 #include "msg_stream.h"
00169 #include "tools.h"
00170
00171
00172 namespace Image_file{
00173
00175 template<typename Image_container>
00176 void load(const char* file_name,
00177 Image_container* const target);
00178
00180 template<typename Image_container>
00181 void save(const char* file_name,
00182 const Image_container& source);
00183
00184
00186 template<typename Source_container,typename Target_container>
00187 inline void convert(const Source_container& source,
00188 Target_container* const target);
00189
00191 inline std::string guess_format(const std::string filename);
00192
00193
00195 template<typename Image_container>
00196 inline void reverse_x(Image_container* target);
00197
00198
00200 template<typename Image_container>
00201 inline void reverse_y(Image_container* target);
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 namespace Image_container_traits{}
00221
00222
00223
00224 template<typename Image_container>
00225 void load(const char* file_name,
00226 Image_container* const target){
00227
00228 QImage qt_image = QImage(QString(file_name));
00229
00230 if (qt_image.isNull()){
00231
00232 Message::warning<<"failure while loading \""<<file_name<<"\""
00233 <<Message::done;
00234
00235 throw std::invalid_argument("error during image loading");
00236 }
00237
00238
00239 typedef unsigned int size_type;
00240
00241 const size_type width = qt_image.width();
00242 const size_type height = qt_image.height();
00243
00244 Image_container_traits::set_size(target,width,height);
00245
00246 for(size_type x=0;x<width;x++){
00247 for(size_type y=0;y<height;y++){
00248
00249 QRgb rgb = qt_image.pixel(x,height-1-y);
00250
00251 Image_container_traits::
00252 set_value(target,x,y,
00253 static_cast<double>(qRed(rgb)) / 255.0,
00254 static_cast<double>(qGreen(rgb)) / 255.0,
00255 static_cast<double>(qBlue(rgb)) / 255.0);
00256 }
00257 }
00258 }
00259
00260
00264 template<typename Image_container>
00265 void save(const char* file_name,
00266 const Image_container& source){
00267
00268 typedef unsigned int size_type;
00269
00270 const size_type width = Image_container_traits::get_width(source);
00271 const size_type height = Image_container_traits::get_height(source);
00272
00273
00274 QImage image(width,height,32);
00275
00276 for(size_type x=0;x<width;x++){
00277 for(size_type y=0;y<height;y++){
00278 double r,g,b;
00279
00280 Image_container_traits::get_value(source,x,height-1-y,&r,&g,&b);
00281
00282 image.setPixel(x,y,qRgb(static_cast<char>(r*255),
00283 static_cast<char>(g*255),
00284 static_cast<char>(b*255)));
00285 }
00286 }
00287
00288
00289 const std::string format = guess_format(file_name);
00290
00291 if (format == std::string()) {
00292
00293 char* escape_format = strdup(QImage::outputFormats().first());
00294
00295 Message::warning<<"output format not recognized. "
00296 <<"image written ("<<file_name<<") in format: "
00297 <<escape_format<<Message::done;
00298
00299 image.save(QString(file_name),escape_format);
00300
00301 free(escape_format);
00302
00303 }
00304 else{
00305 image.save(QString(file_name),format.c_str());
00306 }
00307 }
00308
00309
00310
00311
00312 template<typename Source_container,typename Target_container>
00313 void convert(const Source_container& source,
00314 Target_container* const target){
00315
00316 typedef unsigned int size_type;
00317
00318 const size_type width = Image_container_traits::get_width(source);
00319 const size_type height = Image_container_traits::get_height(source);
00320
00321 Image_container_traits::set_size(target,width,height);
00322
00323 for(size_type x=0;x<width;x++){
00324 for(size_type y=0;y<height;y++){
00325
00326 double r,g,b;
00327
00328 Image_container_traits::get_value(source,x,y,&r,&g,&b);
00329 Image_container_traits::set_value(target,x,y,r,g,b);
00330 }
00331 }
00332
00333 }
00334
00335
00336
00337 std::string guess_format(const std::string filename){
00338
00339 using namespace std;
00340
00341
00342 list<string> valid_answers;
00343 QStrList qlist = QImage::outputFormats();
00344 for(char* c=qlist.first();c!=NULL;c=qlist.next()){
00345 valid_answers.push_back(c);
00346 }
00347
00348
00349 const bool has_JPG =
00350 (find(valid_answers.begin(),valid_answers.end(),"JPG")
00351 !=valid_answers.end());
00352
00353 const bool has_JPEG =
00354 (find(valid_answers.begin(),valid_answers.end(),"JPEG")
00355 !=valid_answers.end());
00356
00357 if (has_JPG&&(!has_JPEG)){
00358 valid_answers.push_back("JPEG");
00359 }
00360
00361 if (has_JPEG&&(!has_JPG)){
00362 valid_answers.push_back("JPG");
00363 }
00364
00365
00366 const string query = Tools::to_upper_case(filename);
00367 const unsigned int query_length = query.length();
00368 for(list<string>::iterator f=valid_answers.begin();
00369 f!=valid_answers.end();f++){
00370
00371 if (query.find(*f)<query_length){
00372 if ((*f=="JPG")&&(!has_JPG)){
00373 return "JPEG";
00374 }
00375 if ((*f=="JPEG")&&(!has_JPEG)){
00376 return "JPG";
00377 }
00378 return *f;
00379 }
00380 }
00381
00382 return string();
00383
00384 }
00385
00386
00387 template<typename Image_container>
00388 void reverse_x(Image_container* target){
00389
00390 typedef unsigned int size_type;
00391
00392 const size_type width = Image_container_traits::get_width(*target);
00393 const size_type height = Image_container_traits::get_height(*target);
00394
00395 for(size_type x=0;x<(width+1)/2;x++){
00396 for(size_type y=0;y<height;y++){
00397 double r1,g1,b1,r2,g2,b2;
00398 Image_container_traits::get_value(*target,width-1-x,y,&r1,&g1,&b1);
00399 Image_container_traits::get_value(*target,x,y,&r2,&g2,&b2);
00400 Image_container_traits::set_value(target,x,y,r1,g1,b1);
00401 Image_container_traits::set_value(target,width-1-x,y,r2,g2,b2);
00402 }
00403 }
00404 }
00405
00406
00407 template<typename Image_container>
00408 void reverse_y(Image_container* target){
00409
00410 typedef unsigned int size_type;
00411
00412 const size_type width = Image_container_traits::get_width(*target);
00413 const size_type height = Image_container_traits::get_height(*target);
00414
00415 for(size_type x=0;x<width;x++){
00416 for(size_type y=0;y<(height+1)/2;y++){
00417 double r1,g1,b1,r2,g2,b2;
00418 Image_container_traits::get_value(*target,x,height-1-y,&r1,&g1,&b1);
00419 Image_container_traits::get_value(*target,x,y,&r2,&g2,&b2);
00420 Image_container_traits::set_value(target,x,y,r1,g1,b1);
00421 Image_container_traits::set_value(target,x,height-1-y,r2,g2,b2);
00422 }
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00436
00437
00438 namespace Image_container_traits{
00439 }
00440
00441 }
00442
00443 #endif
00444
00445
00446