core/vidl/vidl_image_list_istream.cxx
Go to the documentation of this file.
00001 // This is core/vidl/vidl_image_list_istream.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author Matt Leotta
00008 // \date   19 Dec 2005
00009 //
00010 //-----------------------------------------------------------------------------
00011 
00012 #include "vidl_image_list_istream.h"
00013 #include "vidl_frame.h"
00014 #include "vidl_convert.h"
00015 #include <vcl_algorithm.h>
00016 #include <vul/vul_file_iterator.h>
00017 #include <vul/vul_file.h>
00018 #include <vil/vil_image_resource_sptr.h>
00019 #include <vil/vil_load.h>
00020 
00021 //--------------------------------------------------------------------------------
00022 
00023 
00024 //: The initial frame index
00025 // \note the initial frame index is invalid until advance() is called
00026 static const unsigned int INIT_INDEX = unsigned(-1);
00027 
00028 
00029 //: Constructor
00030 vidl_image_list_istream::
00031 vidl_image_list_istream()
00032   : index_(INIT_INDEX),
00033     ni_(0), nj_(0),
00034     format_(VIDL_PIXEL_FORMAT_UNKNOWN),
00035     current_frame_(NULL) {}
00036 
00037 
00038 //: Constructor
00039 vidl_image_list_istream::
00040 vidl_image_list_istream(const vcl_string& glob)
00041   : index_(INIT_INDEX),
00042     ni_(0), nj_(0),
00043     format_(VIDL_PIXEL_FORMAT_UNKNOWN),
00044     current_frame_(NULL)
00045 {
00046   open(glob);
00047 }
00048 
00049 //: Constructor
00050 vidl_image_list_istream::
00051 vidl_image_list_istream(const vcl_vector<vcl_string>& paths)
00052   : index_(INIT_INDEX),
00053     ni_(0), nj_(0),
00054     format_(VIDL_PIXEL_FORMAT_UNKNOWN),
00055     current_frame_(NULL)
00056 {
00057   open(paths);
00058 }
00059 
00060 //: Open a new stream using a file glob (see vul_file_iterator)
00061 // \note files are loaded in alphanumeric order by path name
00062 bool
00063 vidl_image_list_istream::
00064 open(const vcl_string& glob)
00065 {
00066   vcl_vector<vcl_string> filenames;
00067 
00068   for (vul_file_iterator fit=glob; fit; ++fit) {
00069     // check to see if file is a directory.
00070     if (vul_file::is_directory(fit()))
00071       continue;
00072     filenames.push_back(fit());
00073   }
00074 
00075   // no matching filenames
00076   if (filenames.empty()) {
00077     vcl_cerr << "In vidl_image_list_istream(.) - no files to open\n";
00078     return false;
00079   }
00080   // Sort - because the file iterator uses readdir() it does not
00081   //        iterate over files in alphanumeric order
00082   vcl_sort(filenames.begin(),filenames.end());
00083 
00084   bool can_open = open(filenames);
00085 
00086   if (!can_open) {
00087     vcl_cerr << "In vidl_image_list_istream(.) -can't open files as images\n";
00088     for (vcl_vector<vcl_string>::iterator fit = filenames.begin();
00089          fit != filenames.end(); ++fit)
00090       vcl_cerr << *fit << '\n';
00091     return false;
00092   }
00093   this->image_paths_ = filenames;
00094   return true;
00095 }
00096 
00097 
00098 //: Open a new stream using a vector of file paths
00099 bool
00100 vidl_image_list_istream::
00101 open(const vcl_vector<vcl_string>& paths)
00102 {
00103   image_paths_.clear();
00104   // test each file to ensure it exists and is a supported image format
00105   for (vcl_vector<vcl_string>::const_iterator i = paths.begin(); i!=paths.end(); ++i)
00106   {
00107     vil_image_resource_sptr img = vil_load_image_resource(i->c_str());
00108     if (img)
00109     {
00110       if (ni_ == 0 || nj_ == 0)
00111       {
00112         ni_ = img->ni();
00113         nj_ = img->nj();
00114         // convert the first frame to get the pixel format
00115         format_ = vidl_convert_to_frame(img->get_view())->pixel_format();
00116       }
00117       else if (ni_ != img->ni() || nj_ != img->nj())
00118         continue;
00119       image_paths_.push_back(*i);
00120     }
00121   }
00122   index_ = INIT_INDEX;
00123   current_frame_ = NULL;
00124   return !image_paths_.empty();
00125 }
00126 
00127 
00128 //: Close the stream
00129 void
00130 vidl_image_list_istream::
00131 close()
00132 {
00133   image_paths_.clear();
00134   index_ = INIT_INDEX;
00135   current_frame_ = NULL;
00136   ni_ = 0;
00137   nj_ = 0;
00138   format_ = VIDL_PIXEL_FORMAT_UNKNOWN;
00139 }
00140 
00141 
00142 //: Advance to the next frame (but do not load the next image)
00143 bool
00144 vidl_image_list_istream::
00145 advance()
00146 {
00147   current_frame_ = NULL;
00148   if (index_ < image_paths_.size() || index_ == INIT_INDEX )
00149     return ++index_ < image_paths_.size();
00150 
00151   return false;
00152 }
00153 
00154 
00155 //: Read the next frame from the stream
00156 vidl_frame_sptr
00157 vidl_image_list_istream::read_frame()
00158 {
00159   advance();
00160   return current_frame();
00161 }
00162 
00163 
00164 //: Return the current frame in the stream
00165 vidl_frame_sptr
00166 vidl_image_list_istream::current_frame()
00167 {
00168   if (is_valid()) {
00169     if (!current_frame_) {
00170       vil_image_resource_sptr img = vil_load_image_resource(image_paths_[index_].c_str());
00171       current_frame_ = vidl_convert_to_frame(img->get_view());
00172     }
00173     return current_frame_;
00174   }
00175   return NULL;
00176 }
00177 
00178 
00179 //: Return the path to the current image in the stream
00180 vcl_string
00181 vidl_image_list_istream::current_path() const
00182 {
00183   if (is_valid()) {
00184     return image_paths_[index_];
00185   }
00186   return "";
00187 }
00188 
00189 
00190 //: Seek to the given frame number (but do not load the image)
00191 // \returns true if successful
00192 bool
00193 vidl_image_list_istream::
00194 seek_frame(unsigned int frame_nr)
00195 {
00196   if (is_open() && frame_nr < image_paths_.size()) {
00197     if (index_ != frame_nr)
00198       current_frame_ = NULL;
00199     index_ = frame_nr;
00200     return true;
00201   }
00202   return false;
00203 }
00204