Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

image_file.h

Go to the documentation of this file.
00001 
00157 #ifndef __IMAGE_FILE__
00158 #define __IMAGE_FILE__
00159 
00160 #include <algorithm>
00161 #include <functional>
00162 #include <stdexcept>
00163 
00164 #include <qcolor.h> // Must be linked with QT with correct include paths.
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   ######   I M P L E M E N T A T I O N   ######
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     // A few typedefs to ease the following code.
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     // create a QImage
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     // Try to guess the file format.
00289     const std::string format = guess_format(file_name);
00290 
00291     if (format == std::string()) {
00292       // If format not found, use the default and save however.
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{ // If format is guessed.
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     // Conversion into a STL data stricture.
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     // Add some more if needed.
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     // Look for the extensions.
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   # image_container_traits #
00431   ##########################
00432 
00433  */
00434 
00436   //set_value() adapted to the used data structure. See the example on
00437   //the main page.
00438   namespace Image_container_traits{    
00439   } //END OF namespace Image_container_traits
00440  
00441 } //END OF namespace Image_file
00442 
00443 #endif
00444 
00445 
00446 

Generated on Fri Aug 20 15:03:52 2004 by doxygen1.2.18