00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <cstdio>
00037 #include <cstring>
00038 #include "lstio.h"
00039 #include "util.h"
00040
00041 #ifndef WIN32
00042 #include <sys/param.h>
00043 #include <unistd.h>
00044 #else
00045 #include <direct.h>
00046 #include <windows.h>
00047 #define M_PI 3.14159265358979323846f
00048 #define MAXPATHLEN (MAX_PATH*4)
00049 #endif
00050
00051
00052 using namespace EMAN;
00053
00054 const char *LstIO::MAGIC = "#LST";
00055
00056 LstIO::LstIO(const string & file, IOMode rw)
00057 : filename(file), rw_mode(rw), lst_file(0)
00058 {
00059 is_big_endian = ByteOrder::is_host_big_endian();
00060 initialized = false;
00061 nimg = 0;
00062 imageio = 0;
00063 ref_filename = "";
00064 last_lst_index = -1;
00065 last_ref_index = -1;
00066 }
00067
00068 LstIO::~LstIO()
00069 {
00070 if (lst_file) {
00071 fclose(lst_file);
00072 lst_file = 0;
00073 }
00074 ref_filename = "";
00075 if(imageio) {
00076 delete imageio;
00077 imageio = 0;
00078 }
00079 }
00080
00081 void LstIO::init()
00082 {
00083 ENTERFUNC;
00084 if (initialized) {
00085 return ;
00086 }
00087
00088 initialized = true;
00089
00090 bool is_new_file = false;
00091 lst_file = sfopen(filename, rw_mode, &is_new_file);
00092
00093 if (!is_new_file) {
00094
00095 char buf[MAXPATHLEN];
00096
00097 if (!fgets(buf, MAXPATHLEN, lst_file)) {
00098 throw ImageReadException(filename, "first block");
00099 }
00100
00101 if (!is_valid(&buf)) {
00102 throw ImageReadException(filename, "invalid LST file");
00103 }
00104
00105 for (nimg = 0; fgets(buf, MAXPATHLEN, lst_file) != 0; nimg++) {
00106 if (buf[0] == '#') {
00107 nimg--;
00108 }
00109 }
00110 rewind(lst_file);
00111 }
00112 EXITFUNC;
00113 }
00114
00115 bool LstIO::is_valid(const void *first_block)
00116 {
00117 ENTERFUNC;
00118 bool result = false;
00119
00120 if (!first_block) {
00121 result = false;
00122 }
00123 else {
00124 result = Util::check_file_by_magic(first_block, MAGIC);
00125 }
00126
00127 EXITFUNC;
00128 return result;
00129 }
00130
00131 int LstIO::calc_ref_image_index(int image_index)
00132 {
00133 if (image_index == last_lst_index) {
00134 return last_ref_index;
00135 }
00136 else {
00137 char buf[MAXPATHLEN];
00138 int step = image_index - last_lst_index;
00139
00140 if (step < 0) {
00141 rewind(lst_file);
00142 step = image_index + 1;
00143 }
00144
00145 for (int i = 0; i < step; i++) {
00146 if (!fgets(buf, MAXPATHLEN, lst_file)) {
00147 LOGERR("reach EOF in file '%s' before reading %dth image",
00148 filename.c_str(), image_index);
00149 return 1;
00150 }
00151 if (buf[0] == '#') {
00152 i--;
00153 }
00154 }
00155 int ref_image_index = 0;
00156 char ref_image_path[MAXPATHLEN];
00157 char unused[256];
00158 sscanf(buf, " %d %s %[ .,0-9-]", &ref_image_index, ref_image_path, unused);
00159
00160 char fullpath[MAXPATHLEN];
00161
00162 char sep = '/';
00163 #ifdef WIN32
00164 sep = '\\';
00165 #endif
00166 if (ref_image_path[0] == sep) {
00167 strcpy(fullpath, ref_image_path);
00168 }
00169 else {
00170 if (strrchr(filename.c_str(), sep)) {
00171 strcpy(fullpath, filename.c_str());
00172 }
00173 else {
00174 #ifndef WIN32
00175 getcwd(fullpath, MAXPATHLEN);
00176 #else
00177
00178 #endif
00179 }
00180
00181 char *p_basename = strrchr(fullpath, sep);
00182 if (p_basename) {
00183
00184
00185 char ssep[2];
00186 ssep[0] = sep;
00187 ssep[1] = '\0';
00188 strcat(fullpath, ssep);
00189 strcat(fullpath, ref_image_path);
00190 }
00191 }
00192
00193 ref_filename = string(fullpath);
00194 imageio = EMUtil::get_imageio(ref_filename, rw_mode);
00195
00196 last_ref_index = ref_image_index;
00197 }
00198
00199 last_lst_index = image_index;
00200
00201 return last_ref_index;
00202 }
00203
00204
00205 int LstIO::read_header(Dict & dict, int image_index, const Region * area, bool is_3d)
00206 {
00207 ENTERFUNC;
00208 init();
00209 check_read_access(image_index);
00210 int ref_image_index = calc_ref_image_index(image_index);
00211 int err = imageio->read_header(dict, ref_image_index, area, is_3d);
00212 dict["source_path"] = ref_filename;
00213 EXITFUNC;
00214 return err;
00215 }
00216
00217 int LstIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00218 {
00219 ENTERFUNC;
00220 init();
00221 fprintf(lst_file, "%s\n", MAGIC);
00222 EXITFUNC;
00223 return 0;
00224 }
00225
00226 int LstIO::read_data(float *data, int image_index, const Region * area, bool is_3d)
00227 {
00228 ENTERFUNC;
00229 check_read_access(image_index, data);
00230 int ref_image_index = calc_ref_image_index(image_index);
00231 int err = imageio->read_data(data, ref_image_index, area, is_3d);
00232 EXITFUNC;
00233 return err;
00234 }
00235
00236 int LstIO::write_data(float *data, int, const Region* , EMUtil::EMDataType, bool)
00237 {
00238 ENTERFUNC;
00239 fprintf(lst_file, "%s\n", (char*)data);
00240 EXITFUNC;
00241 return 0;
00242 }
00243
00244 void LstIO::flush()
00245 {
00246 fflush(lst_file);
00247 }
00248
00249 bool LstIO::is_complex_mode()
00250 {
00251 return false;
00252 }
00253
00254 bool LstIO::is_image_big_endian()
00255 {
00256 init();
00257 return is_big_endian;
00258 }
00259
00260 int LstIO::get_nimg()
00261 {
00262 init();
00263 return nimg;
00264 }