Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

vul_sequence_filename_map.cxx

Go to the documentation of this file.
00001 // This is core/vul/vul_sequence_filename_map.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 
00006 // Author: David Capel, Oxford RRG
00007 // Created: 15 April 2000
00008 //
00009 //-----------------------------------------------------------------------------
00010 
00011 #include "vul_sequence_filename_map.h"
00012 #include <vcl_cstddef.h> // for vcl_size_t
00013 #include <vcl_cstdlib.h>
00014 #include <vcl_iostream.h>
00015 #include <vcl_string.h>
00016 
00017 #include <vul/vul_sprintf.h>
00018 #include <vul/vul_reg_exp.h>
00019 #include <vul/vul_file_iterator.h>
00020 
00021 const bool debug = 0;
00022 
00023 static struct
00024 {
00025   char const * image_dir;
00026   char const * extension;
00027 } dir_ext_pairs[] = { {"pgm/",".pgm"},
00028                       {"ppm/",".ppm"},
00029                       {"jpg/",".jpg"},
00030                       {"jpg/",".jpeg"},
00031                       {"jpeg/",".jpg"},
00032                       {"jpeg/",".jpeg"},
00033                       {"tiff/",".tiff"},
00034                       {"mit/",".mit"},
00035                       {"viff/",".viff"},
00036                       {"rgb/",".rgb"} };
00037 
00038 const int num_dir_ext_pairs = sizeof(dir_ext_pairs) / sizeof(dir_ext_pairs[0]);
00039 
00040 // Empty constructor to allow the operator= to be used later.
00041 vul_sequence_filename_map::vul_sequence_filename_map ()
00042   : start_(-1), step_(-1), end_(-1)
00043 {
00044 }
00045 
00046 vul_sequence_filename_map::vul_sequence_filename_map (vcl_string const & seq_template, vcl_vector<int> const & indices)
00047   : seq_template_(seq_template), indices_(indices), start_(-1), step_(-1), end_(-1)
00048 {
00049   parse();
00050 }
00051 
00052 vul_sequence_filename_map::vul_sequence_filename_map (vcl_string const & seq_template, int start, int end, int step)
00053   : seq_template_(seq_template), start_(start), step_(step), end_(end)
00054 {
00055   for (int i=start; i <= end; i+=step)
00056     indices_.push_back(i);
00057   parse();
00058 }
00059 
00060 vul_sequence_filename_map::vul_sequence_filename_map (vcl_string const & seq_template, int step)
00061   : seq_template_(seq_template), start_(-1), step_(step), end_(-1)
00062 {
00063   parse();
00064 }
00065 
00066 vul_sequence_filename_map::~vul_sequence_filename_map()
00067 {
00068 }
00069 
00070 vcl_string vul_sequence_filename_map::name(int frame)
00071 {
00072   vcl_string index_str = vul_sprintf(index_format_.c_str(), indices_[frame]);
00073   return basename_ + index_str;
00074 }
00075 
00076 vcl_string vul_sequence_filename_map::pair_name (int i, int j)
00077 {
00078   vcl_string index_str = vul_sprintf((index_format_ + "." + index_format_).c_str(), indices_[i], indices_[j]);
00079   return basename_ + index_str;
00080 }
00081 
00082 vcl_string vul_sequence_filename_map::triplet_name (int i, int j, int k)
00083 {
00084   vcl_string index_str = vul_sprintf((index_format_ + "." +
00085     index_format_ + "." + index_format_).c_str(), indices_[i],
00086     indices_[j], indices_[k]);
00087   return basename_ + index_str;
00088 }
00089 
00090 void vul_sequence_filename_map::parse()
00091 {
00092   vcl_string temp = seq_template_;
00093 
00094   // Search for trailing index spec -   "img.%03d.pgm,0:1:10" , "ppm/img*;:5:"
00095   {
00096     vul_reg_exp re("[,;]([0-9]+)?(:[0-9]+)?:([0-9]+)?$");
00097     if (re.find(temp.c_str()))
00098     {
00099       vcl_string match_start = re.match(1);
00100       vcl_string match_step = re.match(2);
00101       vcl_string match_end = re.match(3);
00102 
00103       temp.erase(re.start(0));
00104 
00105       if (match_start.length() > 0)
00106         start_ = vcl_atoi(match_start.c_str());
00107 
00108       if (match_step.length() > 0)
00109         step_ = vcl_atoi(match_step.c_str()+1);
00110 
00111       if (match_end.length() > 0)
00112         end_ = vcl_atoi(match_end.c_str());
00113     }
00114   }
00115   // Search for image extension
00116   {
00117     vul_reg_exp re("\\.([a-zA-Z_0-9]+)$");
00118     if (re.find(temp.c_str())) {
00119       image_extension_ = re.match(0);
00120       temp.erase(re.start(0));
00121     }
00122   }
00123   // Search for basename template
00124   {
00125     vul_reg_exp re("([a-zA-Z0-9_%#\\.]+)$");
00126     vcl_string bt;
00127     if (re.find(temp.c_str())) {
00128       bt = re.match(0);
00129       temp.erase(re.start(0));
00130     }
00131     // This should have the form "img.%03d" or "img.###". Split it into basename and index format
00132     vcl_size_t pos;
00133     if ( (pos = bt.find('%')) != vcl_string::npos)
00134       index_format_ = bt.substr(pos);
00135     else if ( (pos = bt.find('#')) != vcl_string::npos) {
00136       vcl_size_t last_pos = bt.rfind('#');
00137       index_format_ = vul_sprintf("0%id",last_pos - pos + 1);
00138       index_format_ = "%" + index_format_;
00139     } else
00140       index_format_ = "%03d";
00141     basename_ = bt.substr(0,pos);
00142   }
00143   // What remains must be the directory
00144   image_dir_ = temp;
00145 
00146   // Now to fill in any blanks
00147   //
00148   // Image dir and extension both blank :
00149   //  1 - Look in cwd for basename-compatible files with common image extensions
00150   //  2 - Look for basename-compatible files in common image dirs with corresponding image extensions
00151   if (image_dir_ == "" && image_extension_ == "")
00152   {
00153     bool found_match = false;
00154     {
00155       vul_file_iterator fn("./*");
00156       for (;!found_match && bool(fn); ++fn)
00157         for (int i=0; i < num_dir_ext_pairs && !found_match; ++i)
00158           if (filter_dirent(fn(), dir_ext_pairs[i].extension)) {
00159             image_dir_ = "./";
00160             image_extension_ = dir_ext_pairs[i].extension;
00161             found_match = true;
00162           }
00163     }
00164     if (!found_match)
00165       for (int i=0; i < num_dir_ext_pairs && !found_match; ++i) {
00166         vcl_string glob(dir_ext_pairs[i].image_dir);
00167         glob += "/*";
00168         vul_file_iterator fn(glob);
00169         for (;!found_match && bool(fn);++fn)
00170           if (filter_dirent(fn(), dir_ext_pairs[i].extension)) {
00171             image_dir_ = dir_ext_pairs[i].image_dir;
00172             image_extension_ = dir_ext_pairs[i].extension;
00173             found_match = true;
00174           }
00175       }
00176     if (!found_match) {
00177       vcl_cerr << __FILE__ << " : Can't find files matching " << basename_
00178                << index_format_ << " in common locations with common format!\n";
00179       vcl_abort();
00180     }
00181   }
00182 
00183   // Only image dir is blank :
00184   //  1 - Look for basename-compatible files in cwd
00185   //  2 - Look for basename-compatible files in dir corresponding to given image extension
00186   //  3 - Look for basename-compatible files in common image dirs
00187   else if (image_dir_ == "")
00188   {
00189     bool found_match = false;
00190     {
00191       for (vul_file_iterator fn("./*"); !found_match && bool(fn); ++fn)
00192         if (filter_dirent(fn.filename(), image_extension_)) {
00193           image_dir_ = "./";
00194           found_match = true;
00195         }
00196     }
00197 
00198     if (!found_match) {
00199       for (int i=0; i < num_dir_ext_pairs && !found_match; ++i)
00200         if (vcl_string(dir_ext_pairs[i].extension) == image_extension_) {
00201           vcl_string glob(dir_ext_pairs[i].image_dir); glob += "*";
00202           for (vul_file_iterator fn(glob); !found_match && bool(fn); ++fn)
00203             if (filter_dirent(fn.filename(), image_extension_)) {
00204               image_dir_ = dir_ext_pairs[i].image_dir;
00205               found_match = true;
00206             }
00207         }
00208     }
00209 
00210     if (!found_match) {
00211       for (int i=0; i < num_dir_ext_pairs && !found_match; ++i) {
00212         vcl_string glob(dir_ext_pairs[i].image_dir); glob += "*";
00213         for (vul_file_iterator fn(glob); !found_match && bool(fn); ++fn)
00214           if (filter_dirent(fn.filename(), image_extension_)) {
00215             image_dir_ = dir_ext_pairs[i].image_dir;
00216             found_match = true;
00217           }
00218       }
00219     }
00220 
00221     if (!found_match) {
00222       vcl_cerr << __FILE__ << " : Can't find files matching " << basename_
00223                << index_format_<<image_extension_ << " in common locations!\n";
00224       vcl_abort();
00225     }
00226   }
00227 
00228   // Only extension is blank :
00229   //  1 - Look in image dir for basename-compatible files with extension corresponding to the image dir
00230   //  2 - Look in image dir for basename-compatible files with common image extensions
00231   else if (image_extension_ == "")
00232   {
00233     bool found_match = false;
00234     {
00235       vcl_string glob(image_dir_ + "*");
00236       vul_file_iterator fn(glob);
00237       if (fn) {
00238         for (int i=0; i < num_dir_ext_pairs && !found_match; ++i)
00239           if (vcl_string(dir_ext_pairs[i].image_dir) == image_dir_) {
00240             for (;!found_match && bool(fn);++fn)
00241               if (filter_dirent(fn.filename(), dir_ext_pairs[i].extension)) {
00242                 image_extension_ = dir_ext_pairs[i].extension;
00243                 found_match = true;
00244               }
00245           }
00246       }
00247     }
00248 
00249     if (!found_match) {
00250       vul_file_iterator fn(image_dir_);
00251       if (fn) {
00252         for (int i=0; i < num_dir_ext_pairs && !found_match; ++i) {
00253           for (;!found_match && bool(fn); ++fn)
00254             if (filter_dirent(fn.filename(), dir_ext_pairs[i].extension)) {
00255               image_extension_ = dir_ext_pairs[i].extension;
00256               found_match = true;
00257             }
00258         }
00259       }
00260     }
00261 
00262     if (!found_match) {
00263       vcl_cerr << __FILE__ << " : Can't find files matching " << image_dir_
00264                << basename_ << index_format_ << " with common extension!\n";
00265       vcl_abort();
00266     }
00267   }
00268 
00269   // Start and/or end is not specified :
00270   //   Find all basename-compatible files and set sequence indices accordingly
00271   if (indices_.size() == 0)
00272   {
00273     // See if we need to scan the image directory to get the sequence start/end
00274     if (start_ == -1 || end_ == -1) {
00275       int max = -1000000;
00276       int min = 1000000;
00277       for (vul_file_iterator fn(image_dir_ + "*");fn;++fn)
00278         if (filter_dirent(fn.filename(), image_extension_)) {
00279           int index = extract_index(fn.filename());
00280           max = (index > max) ? index : max;
00281           min = (index < min) ? index : min;
00282         }
00283       if (max < min) {
00284         vcl_cerr << "vul_sequence_filename_map: WARNING: no files in " << image_dir_ << vcl_endl;
00285       }
00286 
00287       if (start_ == -1) start_ = min;
00288       if (end_ == -1) end_ = max;
00289     }
00290     for (int i=start_; i <=  end_; i = i+step_)
00291       indices_.push_back(i);
00292   }
00293 
00294   if (debug)
00295     vcl_cerr << seq_template_ << vcl_endl
00296              << "    image dir : " << image_dir_ << vcl_endl
00297              << "    basename  : " << basename_ << vcl_endl
00298              << " index format : " << index_format_ << vcl_endl
00299              << "    extension : " << image_extension_ << vcl_endl
00300              << "    indices   : " << start_ << ':' << step_ << ':' << end_
00301              << vcl_endl << vcl_endl;
00302 }
00303 
00304 int vul_sequence_filename_map::get_mapped_index(int real) const
00305 {
00306   int idx = -1;
00307   for (int i=0; i < int(indices_.size()); ++i)
00308     if (indices_[i] == real) {
00309       idx = i;
00310       break;
00311     }
00312   return idx;
00313 }
00314 
00315 
00316 vcl_ostream& vul_sequence_filename_map::print (vcl_ostream& s) const
00317 {
00318   s << "vul_sequence_filename_map : " << image_dir_ << basename_
00319     << index_format_ << image_extension_ << " [" << indices_[0] << ':'
00320     << indices_[1] - indices_[0] << ':' << indices_.back() << "]\n";
00321 
00322 #if 0
00323   s << vul_sprintf("vul_sequence_filename_map : %s%s%s [%i:%i:%i]",
00324                    image_dir_.c_str(), basename_.c_str(), index_format_.c_str(), image_extension_.c_str(),
00325                    indices_[0], indices_[1] - indices_[0], indices_.back());
00326 #endif
00327   return s;
00328 }
00329 
00330 bool vul_sequence_filename_map::filter_dirent(char const* name_string, vcl_string const& extension)
00331 {
00332   static unsigned int expected_length = 0;
00333   if (expected_length == 0)
00334     expected_length = basename_.size() +
00335     (vcl_string(vul_sprintf(index_format_.c_str(),0)) + extension).size();
00336 
00337   vcl_string name_str(name_string);
00338 
00339   if (name_str.size() != expected_length) return false;
00340 
00341   if (name_str.substr(0,basename_.size()) == basename_ &&
00342       name_str.substr(expected_length-extension.size(), vcl_string::npos) == extension) return true;
00343 
00344   return false;
00345 }
00346 
00347 int vul_sequence_filename_map::extract_index(char const* name_string)
00348 {
00349   vcl_string name_str(name_string);
00350   vcl_string index_str = name_str.substr(basename_.size(), name_str.size() - image_extension_.size());
00351   return vcl_atoi(index_str.c_str());
00352 }
00353 
00354 vcl_ostream& operator<<(vcl_ostream &os, const vul_sequence_filename_map& s)
00355 {
00356   return s.print(os);
00357 }

Generated on Thu Jan 10 14:41:00 2008 for core/vul by  doxygen 1.4.4