00001
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
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
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
00040 if (found_one)
00041 break;
00042 else {
00043
00044
00045 if (i > 10)
00046 break;
00047 }
00048 }
00049 }
00050 }
00051 else {
00052
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
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
00076 current_file_index = 0;
00077
00078
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
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
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
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
00158 return n1;
00159 if ((unsigned int)(current_file_index+1) == fps.size())
00160
00161 return n1;
00162
00163
00164 ++current_file_index;
00165 vcl_fseek(fps[current_file_index], 0L, SEEK_SET);
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 }