core/vidl_vil1/vidl_vil1_file_sequence.cxx

Go to the documentation of this file.
00001 // This is core/vidl_vil1/vidl_vil1_file_sequence.cxx
00002 #include "vidl_vil1_file_sequence.h"
00003 
00004 #include <vcl_cassert.h>
00005 #include <vcl_fstream.h>
00006 
00007 #include <vul/vul_awk.h>
00008 #include <vul/vul_file.h>
00009 #include <vul/vul_sprintf.h>
00010 
00011 bool vidl_vil1_file_sequence::open(vcl_string const& fmt)
00012 {
00013   current_file_index = -1;
00014 
00015   // fmt could be a "lst" file, or a single vob or mpg or a %d list
00016   int l = fmt.size();
00017   if (l > 4 && fmt.substr(l-4) == ".lst") {
00018     vcl_ifstream f(fmt.c_str());
00019     assert(f.good());
00020     for (vul_awk awk(f); awk; ++awk) {
00021       if (awk.NF() > 0) {
00022         vcl_cerr << awk[0] << vcl_endl;
00023         filenames.push_back(awk[0]);
00024       }
00025     }
00026   }
00027   else if (fmt.find('%') != vcl_string::npos ) {
00028     // Assume a list.  Could start from some low number... Could glob.  hmmm.
00029     bool found_one = false;
00030     for (int i = 0; ; ++i) {
00031       vcl_string buf = vul_sprintf(fmt.c_str(), i);
00032       int s = vul_file::size(buf);
00033       if (s > 0) {
00034         found_one = true;
00035         filenames.push_back(buf);
00036         filesizes.push_back(s);
00037       }
00038       else {
00039         // If got at least one so far, then bail now
00040         if (found_one)
00041           break;
00042         else {
00043           // If not found one yet, and still only tried < 10, then
00044           // keep trying.
00045           if (i > 10)
00046             break;
00047         }
00048       }
00049     }
00050   }
00051   else {
00052     // No %, not .lst: assume it's an mpeg/vob
00053     filenames.push_back(fmt);
00054   }
00055 
00056   unsigned int n = filenames.size();
00057 
00058   if (n == 0) {
00059     vcl_cerr << "ERROR: Could not turn [" << fmt << "] into a list of files\n";
00060     return false;
00061   }
00062 
00063   // Fill in sizes if not done already
00064   if (filesizes.size() < n) {
00065     filesizes.resize(n);
00066     for (unsigned int i = 0; i < n; ++i) {
00067       int s = vul_file::size(filenames[i].c_str());
00068       if (s <= 0) {
00069         vcl_cerr << "WARNING: Zero size file [" << filenames[i].c_str() << "]\n";
00070       }
00071       filesizes[i] = s;
00072     }
00073   }
00074 
00075   // Set up file ptr etc.
00076   current_file_index = 0;
00077 
00078   // Fill start_bytes
00079   start_byte.resize(n);
00080   start_byte[0] = 0;
00081   for (unsigned int i = 1; i < filenames.size(); ++i)
00082     start_byte[i] = start_byte[i-1] + (offset_t)filesizes[i-1];
00083 
00084   // Open them all
00085   fps.resize(n);
00086   for (unsigned int i = 0; i < filenames.size(); ++i) {
00087     char const* fn = filenames[i].c_str();
00088     fps[i] = vcl_fopen(fn, "rb");
00089     if (!fps[i]) {
00090       vcl_cerr << "ERROR: Could not open [" << fn << "]\n";
00091       current_file_index = -1;
00092       return false;
00093     }
00094   }
00095 
00096   // Summarize:
00097   vcl_cerr << "files: sizeof offset_t = " << sizeof(offset_t) << '\n';
00098   for (unsigned int i = 0; i < n; ++i)
00099     vcl_cerr << "   " << filenames[i].c_str() << "  " << (int) start_byte[i] << '\n';
00100   vcl_cerr << '\n';
00101 
00102   return true;
00103 }
00104 
00105 void vidl_vil1_file_sequence::seek(offset_t to)
00106 {
00107   int newindex = -1;
00108   for (unsigned int i = 1; i < filesizes.size(); ++i)
00109     if (start_byte[i] > to) {
00110       newindex = i-1;
00111       break;
00112     }
00113 
00114   if (newindex == -1) {
00115     int i = filesizes.size() - 1;
00116     // Know start_byte[i] <= to
00117     if (to < start_byte[i] + (offset_t)filesizes[i])
00118       newindex = i;
00119   }
00120 
00121   if (newindex == -1) {
00122     vcl_cerr << "ERROR: Could not seek to [" << (int) to << "]\n";
00123     return;
00124   }
00125 
00126   current_file_index = newindex;
00127 
00128   offset_t file_ptr = to - start_byte[current_file_index];
00129   vcl_cerr << " si = " << (int) start_byte[current_file_index] << " to = " << (int) to << '\n';
00130   assert(file_ptr >= 0);
00131   assert(file_ptr < (offset_t)filesizes[current_file_index]);
00132 
00133   vcl_fseek(fps[current_file_index], (long)file_ptr, SEEK_SET);
00134 }
00135 
00136 vidl_vil1_file_sequence::offset_t vidl_vil1_file_sequence::tell() const
00137 {
00138   return start_byte[current_file_index] + ftell(fps[current_file_index]);
00139 }
00140 
00141 int vidl_vil1_file_sequence::read(void* buf, unsigned int len)
00142 {
00143   unsigned long space_left_in_this_file = filesizes[current_file_index] - ftell(fps[current_file_index]);
00144 
00145   int bytes_from_curr = len;
00146   int bytes_from_next = 0;
00147   if (space_left_in_this_file < len) {
00148     bytes_from_curr = space_left_in_this_file;
00149     bytes_from_next = len - space_left_in_this_file;
00150   }
00151 
00152   if (bytes_from_next == 0)
00153     return vcl_fread(buf, 1, len, fps[current_file_index]);
00154 
00155   int n1 = vcl_fread(buf, 1, bytes_from_curr, fps[current_file_index]);
00156   if (n1 < bytes_from_curr)
00157     // First read stopped short, don't even bother with next one
00158     return n1;
00159   if ((unsigned int)(current_file_index+1) == fps.size())
00160     // First was OK, and we've run out of files
00161     return n1;
00162 
00163   // First read was OK.  Advance to next file.
00164   ++current_file_index;
00165   vcl_fseek(fps[current_file_index], 0L, SEEK_SET); // need to seek(0) since we may have read from this file before.
00166   int n2 = vcl_fread((unsigned char*)buf + n1, 1, bytes_from_next, fps[current_file_index]);
00167   return n1 + n2;
00168 }
00169 
00170 void vidl_vil1_file_sequence::close()
00171 {
00172   for (unsigned int i = 0; i < fps.size(); ++i)
00173     vcl_fclose(fps[i]);
00174 }

Generated on Tue Dec 2 05:09:13 2008 for core/vidl_vil1 by  doxygen 1.5.1