psycho-math-op.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-math-op.C Psychophysics test to measure the influence of eyemovement on memory task performance */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-math-op.C $
00035 
00036 
00037 #include "Component/ModelManager.H"
00038 #include "Image/Image.H"
00039 #include "Psycho/PsychoDisplay.H"
00040 #include "Psycho/EyeTrackerConfigurator.H"
00041 #include "Psycho/EyeTracker.H"
00042 #include "Psycho/PsychoOpts.H"
00043 #include "Component/EventLog.H"
00044 #include "Component/ComponentOpts.H"
00045 #include "Raster/Raster.H"
00046 #include "Util/MathFunctions.H"
00047 #include "Util/Types.H"
00048 #include "GameBoard/basic-graphics.H"
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 #include <errno.h>
00052 #include <vector>
00053 #include <string>
00054 #include <iostream>
00055 #include <SDL/SDL.h>
00056 #include <SDL/SDL_image.h>
00057 #include <SDL/SDL_mixer.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 #include <sstream>
00061 #include <time.h>
00062 #include "Image/DrawOps.H"
00063 #include "GameBoard/resize.h"
00064 #include <iostream>
00065 #include <fstream>
00066 #include <set>
00067 #include <algorithm>
00068 #include <ctime>
00069 
00070 #ifndef INVT_HAVE_LIBSDL_IMAGE
00071 #include <cstdio>
00072 int main()
00073 {
00074         fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00075         return 1;
00076 }
00077 
00078 #else
00079 
00080 
00081 
00082 using namespace std;
00083 
00084 // ######################################################################
00085 
00086 ModelManager manager("Psycho-Math-Op");
00087 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00088 map<uint,uint> testMap ;
00089 map<string,string> argMap ;
00090 map<string,vector<SDL_Rect*>*> clipsmap;
00091 
00092 //////////////////////////////////////////////
00093 // a functionf for stringigying things
00094 //////////////////////////////////////////////
00095 template <class T> std::string stringify(T i)
00096 {
00097         ostringstream o ;
00098         o << i ;
00099         return o.str();
00100 }
00101 
00102 bool itIsInThere(int x , vector<int> bag){
00103         for( uint i=0 ; i < bag.size(); i++ ){
00104                 if(x == bag[i]) return true ;
00105         }
00106         return false ;
00107 }
00108 
00109 
00110 //pushes back the name of wav files in the directory into the given vector
00111 int getdir (string dir, vector<string> &files)
00112 {
00113         DIR *dp;
00114         struct dirent *dirp;
00115         if((dp  = opendir(dir.c_str())) == NULL) {
00116                 cout << "Error(" << errno << ") opening " << dir << endl;
00117                 return errno;
00118         }
00119         string fn = "" ;
00120         size_t found;
00121         string extension = "" ;
00122         while ((dirp = readdir(dp)) != NULL) {
00123                 fn = string(dirp->d_name) ;
00124                 found = fn.find_last_of(".");
00125                 if(found > 0 && found <1000){
00126                         extension = fn.substr(found) ;
00127                         if(extension.compare(".wav")== 0 )
00128                                 files.push_back(dir+"/"+fn);
00129                 }
00130         }
00131         closedir(dp);
00132         return 0;
00133 }
00134 
00135 
00136 ////////////////////////////////////////////////////////////////
00137 ////This is our button factory
00138 ////////////////////////////////////////////////////////////////
00139 SDL_Surface* getButtonImage(string label , PixRGB<byte> txtcolor=PixRGB<byte>(0,0,0) , PixRGB<byte> bgcolor=PixRGB<byte>(255,255,255) ,Point2D<int> size = Point2D<int>(100,100) ,PixRGB<byte> bordercolor=PixRGB<byte>(0,0,0) , int border=3){
00140         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00141         textIm.clear(bgcolor);
00142         writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00143         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00144         Uint32 bc = d->getUint32color(bordercolor);
00145         drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00146         SDL_Surface* blank =getABlankSurface(size.i , size.j);
00147         SDL_Rect clip;
00148         clip.x = 0 ;
00149         clip.y = 0 ;
00150         clip.w = size.i ;
00151         clip.h = size.j ;
00152         apply_surface(0,0,*surf,*blank,clip);
00153         dumpSurface(surf) ;
00154         return blank ;
00155 }
00156 
00157 ////////////////////////////////////////////////////////////////////////
00158 ////This is the function for creating the keypad, in fact it generates
00159 ////12 buttons and associates the actions to the region for each button
00160 ////////////////////////////////////////////////////////////////////////
00161 
00162 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00163         SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00164         SDL_Rect clip;
00165         clip.x=0;
00166         clip.y=0;
00167         int numofrows = alphabet.size()/3 +1;
00168         if(alphabet.size()%3 != 0 ) numofrows++ ;
00169         int numofcolumns = 3 ;
00170         clip.w= pad->w / numofcolumns ;
00171         clip.h = pad->h / numofrows ;
00172 
00173   //keys for 1 to 9
00174         for( int i = 0 ; i < numofrows*3 ; i++){
00175                 SDL_Surface* but ;
00176                 if((uint)i < alphabet.size()){
00177                         but = getButtonImage(alphabet.substr(i,1),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00178                 }else{
00179                         but = getButtonImage(" ",PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00180                 }
00181 
00182                 SDL_Rect cl ;
00183                 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00184                 cl.w = clip.w ;
00185                 cl.h = clip.h ;
00186                 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00187                 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00188                 dumpSurface(but);
00189         }
00190         SDL_Rect cl1 ;
00191         cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00192         cl1.w = clip.w ;
00193         cl1.h = clip.h ;
00194         buttmap["!"] = cl1 ;
00195         SDL_Surface* but = getButtonImage(string("<-"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00196         apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00197         dumpSurface(but);
00198         SDL_Rect cl2 ;
00199         cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00200         cl2.w = clip.w ;
00201         cl2.h = clip.h ;
00202         buttmap[" "] = cl2 ;
00203         but = getButtonImage(string("spc"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00204         apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00205         dumpSurface(but);
00206         SDL_Rect cl3 ;
00207         cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00208         cl3.w = clip.w ;
00209         cl3.h = clip.h ;
00210         buttmap["*"] = cl3 ;
00211         but = getButtonImage(string("Ok"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3);
00212         apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00213         dumpSurface(but);
00214         return pad ;
00215 }
00216 
00217 
00218 
00219 
00220 ///////////////////////////////////////////////////////////////////////////
00221 /////this function listens to mouse clicks and then finds the region of the screen
00222 /////associated with the action, buttmap is the map of the region, offset is the offset of
00223 /////buttons
00224 ///////////////////////////////////////////////////////////////////////////
00225 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00226         int quit = 0 ;
00227         string s ;
00228         SDL_Event event ;
00229         while( quit!=2 ){
00230                 while( SDL_PollEvent( &event ) ) {
00231                         if(event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT ){
00232                                 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00233                                         if(event.button.x >= (it->second).x + offset.i && event.button.x <= (it->second).x + (it->second).w + offset.i  && event.button.y >= (it->second).y+ offset.j && event.button.y <= (it->second).y + (it->second).h + offset.j) {
00234                                                 quit = 2 ;
00235                                                 s = it->first ;
00236                                                 break;
00237                                         }
00238 
00239                                 }
00240                         }
00241 
00242                 }
00243         }
00244         return s ;
00245 
00246 }
00247 
00248 
00249 ////////////////////////////////////////////////////
00250 ////This function creates a virtual keypad, creates a map of buttons
00251 ////and their representation area and listens to the button press and at
00252 ////the end returns the keyed digits
00253 ////////////////////////////////////////////////////
00254 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00255         d->showCursor(true) ;
00256         //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect
00257         map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00258         //now let's get the keypad surface while we get the actions map to regions
00259         SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00260         //this will be the offset of displaying the keypad on the screen
00261         SDL_Rect offset ;
00262         offset.x = (d->getWidth() - keypad->w) /2;
00263         offset.y = (d-> getHeight() - keypad->h) /2;
00264         //now let's display the keypad
00265         d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00266         //this will hold the final string keyed be the subject
00267         string p = string("") ;
00268         //this is a temporary string holding the last action related to the pressed key
00269         string tp = string("");
00270         //now let's record subject's key press
00271         while( tp.compare("*")!=0 ){
00272                 //this button is actually the display for the current string
00273                 SDL_Surface* dp = getButtonImage(p ,PixRGB<byte>(195,60,12) ,PixRGB<byte>(255,255,255) ,Point2D<int>(d->getWidth()/6,d->getHeight() /15) ,PixRGB<byte>(0,25,180) , 4) ;
00274                 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00275                 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00276                 //now let's listen to button events
00277                 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00278                 dumpSurface(dp) ;
00279                 if(tp.compare("!")==0 && p.size()>=0 ) {
00280                         if (p.size()>0) p = p.substr(0,p.size()-1) ;
00281                 }else{
00282                         if(p.size() < maxl && tp.compare("*")!=0) {
00283                                 p +=tp ;
00284                         }
00285 
00286                 }
00287 
00288         }
00289         buttmap = 0 ;
00290         dumpSurface(keypad) ;
00291         d->clearScreen() ;
00292         return p ;
00293 
00294 }
00295 
00296 
00297 
00298 int addArgument(const string st,const string delim="="){
00299         int i = st.find(delim) ;
00300         argMap[st.substr(0,i)] = st.substr(i+1);
00301 
00302         return 0 ;
00303 }
00304 
00305 std::string getArgumentValue(string arg){
00306         return argMap[arg] ;
00307 }
00308 
00309 std::vector<int> getDigits(int n , string zs="n" , string rs="n" ){
00310         if(rs.compare("n")==0){
00311                 if(zs.compare("n")==0 && n >9 ) {LINFO( "come on! what do you expect?!") ;  exit(-1) ;}
00312                 if(zs.compare("y")==0 && n >10 ) {LINFO( "come on! what do you expect?!") ; exit(-1) ;}
00313         }
00314         vector<int> digits ;
00315         int dig = 0 ;
00316         while( digits.size() < (uint)n ){
00317                 if(zs.compare("n")==0) {dig = 1+(random()%9);}else{dig = random()%10;}
00318                 if(rs.compare("y")==0){digits.push_back(dig);}else{if(!itIsInThere(dig,digits)) digits.push_back(dig);}
00319         }
00320         return digits ;
00321 }
00322 
00323 std::string getUsageComment(){
00324 
00325         string com = string("\nlist of arguments : \n");
00326 
00327         com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00328         com += "\nmemo=[a_string_without_white_space]\n";
00329         com += "\nnum-of-digits=[>0](the size of string){default=} \n";
00330         com += "\nsubject=[subject_name] \n" ;
00331         com += "\ntest-rounds=[>1] (number of tests ) {default=10}\n";
00332         com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00333         com += "\nrecall-prb=[a number between 0 to 1], probability of challenging the subject with a memorization task, default=0.4\n"  ;
00334         com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n";
00335         com += "\ncue-onset-frames=[<0](number of frames to show the cue onset){default=3}\n";
00336         com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00337         com += "\ndigit-repeat=[y/n](whether digits can repeat, y for yes , n for no){default=n}\n" ;
00338         com += "\ninclude-zero=[y/n](whether zero be included in the presented digits, y for yes , n for no){default=n}\n";
00339         return com ;
00340 }
00341 
00342 
00343 extern "C" int main(const int argc, char** argv)
00344 {
00345 
00346         MYLOGVERB = LOG_INFO;  // suppress debug messages
00347         //let's push the initial value for the parameters
00348         argMap["experiment"]="math-operation-with-played-numbers";
00349         argMap["logfile"]="psycho-math-op.psy" ;
00350         argMap["num-of-digits"]="3" ;
00351         argMap["test-rounds"]="10";
00352         argMap["subject"]="" ;
00353         argMap["memo"]="" ;
00354         argMap["alphabet"]="0123456789";
00355         argMap["recall-prb"]="0.4" ;
00356         argMap["cue-wait-frames"]="0" ;
00357         argMap["cue-onset-frames"] = "3" ;
00358         argMap["white-space"] = "20" ;
00359         argMap["sound-dir"]="..";
00360         argMap["include-zero"]="n";
00361         argMap["digit-repeat"]="n" ;
00362 
00363         manager.addSubComponent(d);
00364         nub::soft_ref<EventLog> el(new EventLog(manager));
00365         manager.addSubComponent(el);
00366         d->setEventLog(el);
00367         nub::soft_ref<EyeTrackerConfigurator>
00368                         etc(new EyeTrackerConfigurator(manager));
00369           manager.addSubComponent(etc);
00370 
00371         if (manager.parseCommandLine(argc, argv,
00372             "at least one argument needed", 1, -1)==false){
00373                     cout<<getUsageComment()<<endl;
00374                     return(1);
00375             }
00376 
00377         for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00378                     addArgument(manager.getExtraArg(i),std::string("=")) ;
00379         }
00380 
00381         manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00382         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00383         nub::soft_ref<EyeTracker> eyet = etc->getET();
00384         d->setEyeTracker(eyet);
00385         eyet->setEventLog(el);
00386 
00387         //now let's open the audio channel
00388          if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00389                     LINFO( "did not open the mix-audio") ;
00390                     return -1 ;
00391             }
00392         //let's load the 10 audio files off the director of audios and put them in a map
00393         map<int,Mix_Music*> audioMap ;
00394         for( int i = 0 ; i < 10 ; i++ ){
00395                 string str = argMap["sound-dir"]+"/"+stringify(i)+".wav" ;
00396                 audioMap[i] = Mix_LoadMUS(str.c_str());
00397         }
00398 
00399         int numOfDigits = atoi(argMap["num-of-digits"].c_str());
00400         int cue_onset_frames = atoi(argMap["cue-onset-frames"].c_str()) ;
00401         int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00402 
00403   // let's get all our ModelComponent instances started:
00404             manager.start();
00405             for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00406   // let's display an ISCAN calibration grid:
00407             d->clearScreen();
00408             d->displayISCANcalib();
00409             d->waitForMouseClick();
00410             d->displayText("Here the experiment starts! click to start!");
00411             d->waitForMouseClick();
00412             d->clearScreen();
00413         //let's see in what mode the user like to run the program
00414             int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00415 
00416             float memPrb = atof(argMap["recall-prb"].c_str()) ;
00417 
00418             //let's do calibration
00419             d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00420             int cl = d->waitForMouseClick();
00421             if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00422             d->clearScreen();
00423             //let's count the rounds
00424             int cr = 0 ;
00425             while( cr <numOfTests ){
00426                     d->showCursor(true);
00427                     d->displayText("click one of the  mouse buttons to start!");
00428                     d->waitForMouseClick() ;
00429                     d->showCursor(false) ;
00430                     d->clearScreen() ;
00431                     d->displayFixationBlink();
00432                     float mP = (float) rand()/RAND_MAX  ;
00433                     vector<int> digits = getDigits(numOfDigits,argMap["include-zero"],argMap["digit-repeat"]);
00434                     int counter = 0 ;
00435                     while( counter < numOfDigits ){
00436                         if(Mix_PlayingMusic() == 0 ){
00437                                 //Play the music
00438                                 if( Mix_PlayMusic( audioMap[digits[counter]], 0 ) == -1 ) { return 1; }
00439                                 d->pushEvent("the "+stringify(counter)+"th  : " +stringify(digits[counter]));
00440                                 counter++ ;
00441                         }
00442                     }
00443                 //just hold it there to the end of the audio playing
00444                 while( Mix_PlayingMusic() == 1 ){}
00445 
00446 
00447                     if(mP > memPrb){
00448                             cr++;
00449                             d->pushEvent("**************************************") ;
00450                             if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00451                             std::string imst = "===== Showing image: def"+ stringify(cr)+ ".png =====";
00452                             d->pushEvent(imst);
00453                             eyet->track(true);
00454                             d->displayRedDotFixation();
00455                             d->waitFrames(cue_onset_frames);
00456                             long st = d->getTimerValue() ;//we take this time as the start time of the operation, right after the signal for sorting
00457                             d->clearScreen() ;
00458                             d->pushEvent("manipulation starts");
00459                             d->waitForMouseClick() ;
00460                             long et = d->getTimerValue();//we take this time as the end time of the operation, right after recieving the mouse click
00461                             eyet->track(false);
00462                             d->pushEvent("manipulation ends") ;
00463                             d->pushEvent("manipulation time:"+stringify(et-st));
00464                             string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , numOfDigits);
00465                             d->pushEvent("subject keyed : "+answer);
00466 
00467                     }else{
00468                             d->pushEvent("+++++++++++++++++++++++++++++++++++++++") ;
00469                             if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00470                             d->displayFixationBlink(d->getWidth()/2,d->getHeight()/2,1,cue_onset_frames);
00471                             d->pushEvent("subject is being challenged for simple momorization");
00472                             string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , numOfDigits);
00473                             d->pushEvent("subject keyed : "+answer);
00474                     }
00475             }
00476 
00477             d->clearScreen();
00478             d->displayText("Experiment complete. Thank you!");
00479             d->waitForMouseClick();
00480 
00481 
00482           // stop all our ModelComponents
00483             manager.stop();
00484 
00485         //let's free up the audio files
00486         for( int i = 0 ; i < 10 ; i++ ){
00487                 Mix_FreeMusic(audioMap[i]);
00488         }
00489          //time to close the audio channel
00490         Mix_CloseAudio();
00491           // all done!
00492             return 0;
00493 }
00494 
00495 #endif // INVT_HAVE_LIBSDL_IMAGE
00496 
Generated on Sun May 8 08:04:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3