FrameRange.C

Go to the documentation of this file.
00001 /*!@file Media/FrameRange.C A range of frames at a given inter-frame delay */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the 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/Media/FrameRange.C $
00035 // $Id: FrameRange.C 14376 2011-01-11 02:44:34Z pez $
00036 //
00037 
00038 #include "Media/FrameRange.H"
00039 
00040 #include "Util/Assert.H"
00041 #include "Util/StringConversions.H"
00042 #include "Util/StringUtil.H"
00043 #include "Util/log.H"
00044 #include "Util/sformat.H"
00045 
00046 #include <iterator> // for back_inserter()
00047 #include <limits>
00048 #include <vector>
00049 #include <cstdio>  // for fopen() and friends
00050 
00051 // ######################################################################
00052 FrameRange::FrameRange() :
00053   itsFirst(0),
00054   itsStep(1),
00055   itsLast(0),
00056   itsDelayTimes(),
00057   itsEventTriggered(false)
00058 {
00059   // make sure there is always at least one element in the vector:
00060   itsDelayTimes.push_back(SimTime::ZERO());
00061 }
00062 
00063 FrameRange::FrameRange(int first, int step, int last, std::vector<SimTime> delays, bool eventTriggered) :
00064   itsFirst(first),
00065   itsStep(step),
00066   itsLast(last),
00067   itsDelayTimes(delays),
00068   itsEventTriggered(eventTriggered)
00069 {
00070   // make sure there is always at least one element in the vector:
00071   if(itsDelayTimes.size() == 0)
00072   {
00073     itsDelayTimes.push_back(SimTime::ZERO());
00074   }
00075 }
00076 
00077 // ######################################################################
00078 std::string FrameRange::toString() const
00079 {
00080   const std::string range =
00081     itsStep == 1
00082     ? sformat("%d-%d", itsFirst, itsLast)
00083     : sformat("%d-%d-%d", itsFirst, itsStep, itsLast);
00084 
00085   if (itsEventTriggered)
00086     {
00087       return sformat("%s@EVENT", range.c_str());
00088     }
00089   else
00090     {
00091       ASSERT(itsDelayTimes.size() > 0);
00092       if (itsDelayTimes.size() == 1)
00093         {
00094           return sformat("%s@%.2fms",
00095                          range.c_str(), itsDelayTimes[0].msecs());
00096         }
00097       else
00098         {
00099           SimTime totstime = itsDelayTimes[0];
00100 
00101           for (size_t i = 1; i < itsDelayTimes.size(); ++i)
00102             totstime += itsDelayTimes[i] - itsDelayTimes[i-1];
00103 
00104           // average inter-frame delay:
00105           const double aifd =
00106             totstime.msecs() / double(itsDelayTimes.size());
00107           return sformat("%s@variable delay "
00108                          "(average inter-frame delay %.2fms)",
00109                          range.c_str(), aifd);
00110         }
00111     }
00112 }
00113 
00114 // ######################################################################
00115 FrameRange FrameRange::fromString(const std::string& str)
00116 {
00117   const std::string::size_type at = str.find('@');
00118   if (at == str.npos)
00119     conversion_error::raise<FrameRange>
00120       (str, "missing '@'; expected [first-[last]]@delay");
00121 
00122   const std::string range = str.substr(0, at);
00123   const std::string sdelay = str.substr(at+1, str.npos);
00124 
00125   int xfirst = -2, xstep = -2, xlast = -2;
00126 
00127   if (range.length() == 0)
00128     {
00129       xfirst = 0;
00130       xstep = 1;
00131       xlast = std::numeric_limits<int>::max();
00132     }
00133   else
00134     {
00135 #define EXPECTED_FORMAT "expected [[first[-step]]-[last]]@delay"
00136 
00137       std::vector<std::string> tokens;
00138       split(range, "-", std::back_inserter(tokens));
00139 
00140       if (tokens.size() != 2 && tokens.size() != 3)
00141         conversion_error::raise<FrameRange>
00142           (str, "missing '-'; " EXPECTED_FORMAT);
00143 
00144       const std::string sfirst = tokens.front();
00145       const std::string slast = tokens.back();
00146 
00147       if (sfirst.length() == 0)
00148         xfirst = 0;
00149       else if (sscanf(sfirst.c_str(), "%d", &xfirst) != 1)
00150         conversion_error::raise<FrameRange>
00151           (str, "bogus 'first'; " EXPECTED_FORMAT);
00152 
00153       if (slast.length() == 0
00154           || slast.compare("MAX") == 0
00155           || slast.compare("max") == 0)
00156         {
00157           xlast = std::numeric_limits<int>::max();
00158         }
00159       else if (sscanf(slast.c_str(), "%d", &xlast) != 1)
00160         {
00161           conversion_error::raise<FrameRange>
00162             (str, "bogus 'last'; " EXPECTED_FORMAT);
00163         }
00164 
00165       if (tokens.size() == 3)
00166         {
00167           if (sscanf(tokens[1].c_str(), "%d", &xstep) != 1)
00168             conversion_error::raise<FrameRange>
00169               (str, "bogus 'step'; " EXPECTED_FORMAT);
00170 
00171           if (xstep <= 0)
00172             conversion_error::raise<FrameRange>
00173               (str, "bogus 'step'; must be strictly greater than zero");
00174         }
00175       else
00176         xstep = 1;
00177     }
00178 
00179   FrameRange result;
00180 
00181   result.itsFirst = xfirst;
00182   result.itsStep = xstep;
00183   result.itsLast = xlast;
00184   result.itsEventTriggered = false;
00185   result.itsDelayTimes.resize(0);
00186 
00187   LDEBUG("sdelay: %s", sdelay.c_str());
00188 
00189   // check for magic values of sdelay:
00190   if (sdelay.compare("EVENT") == 0) {
00191       result.itsEventTriggered = true;
00192       // make sure there is always at least one element in the vector:
00193       result.itsDelayTimes.push_back(SimTime::ZERO());
00194   } else {
00195           // ok, sdelay didn't have a magic value
00196           // check if it's a filename
00197       const std::string::size_type suffix_pos = sdelay.find(".fl");
00198       if (suffix_pos == str.npos) {
00199               // no suffix, so assume sdelay is a time string
00200               // pass "ms" to indicate that the default units are milliseconds
00201           LDEBUG("didn't find fl suffix");
00202           result.itsDelayTimes.push_back(SimTime::fromString(sdelay, "ms"));
00203       } else {
00204               // the delay should be a .fl filename (necessary to account for variable framerates)
00205               // the expected format of .fl files is defined in the help message of OPT_InputFrameRange (FrameSeries.C)
00206           LDEBUG("found fl suffix");
00207           std::string fl_filename=sdelay;
00208           FILE *fl = fopen(fl_filename.c_str(), "r");
00209           if (fl == NULL) LFATAL("Cannot open %s", fl_filename.c_str());
00210           // double prevstime; // previous simulation time
00211           double nextstime; // next simulation time
00212           int i=1; // index of lines in fl file
00213           if (fscanf(fl, "%*s %lf\n", &nextstime) != 1) // read first line
00214             {
00215               fclose(fl);
00216               LFATAL("Error reading from %s[%i]",
00217                      fl_filename.c_str(), i);
00218             }
00219           if (nextstime!=0)
00220             {
00221               fclose(fl);
00222               LFATAL("Simulation start time must be 0, "
00223                      "but is %.2f in file: %s[%d]",
00224                      nextstime, fl_filename.c_str(), i);
00225             }
00226           while (!feof(fl)) {
00227               i++;
00228               //prevstime=nextstime;
00229               if (fscanf(fl, "%*s %lf\n", &nextstime) != 1)
00230                 {
00231                   fclose(fl);
00232                   LFATAL("Error reading from %s[%d]",
00233                          fl_filename.c_str(), i);
00234                 }
00235               result.itsDelayTimes.push_back(SimTime::MSECS(nextstime));
00236           }
00237       }
00238       LDEBUG("added %"ZU" delays to itsDelayTimes", result.itsDelayTimes.size());
00239   }
00240 
00241   LDEBUG("parsed FrameRange string '%s' as '%s'",
00242          str.c_str(), result.toString().c_str());
00243 
00244   return result;
00245 }
00246 
00247 // ######################################################################
00248 bool FrameRange::operator==(const FrameRange& that) const
00249 {
00250   return (this->itsFirst == that.itsFirst
00251           && this->itsStep == that.itsStep
00252           && this->itsLast == that.itsLast
00253           && this->itsDelayTimes == that.itsDelayTimes
00254           && this->itsEventTriggered == that.itsEventTriggered);
00255 }
00256 
00257 
00258 // ######################################################################
00259 /* So things look consistent in everyone's emacs... */
00260 /* Local Variables: */
00261 /* indent-tabs-mode: nil */
00262 /* End: */
Generated on Sun May 8 08:41:00 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3