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 check_read_access(image_index);
00209 int ref_image_index = calc_ref_image_index(image_index);
00210 int err = imageio->read_header(dict, ref_image_index, area, is_3d);
00211 EXITFUNC;
00212 return err;
00213 }
00214
00215 int LstIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00216 {
00217 ENTERFUNC;
00218 fprintf(lst_file, "%s\n", MAGIC);
00219 EXITFUNC;
00220 return 0;
00221 }
00222
00223 int LstIO::read_data(float *data, int image_index, const Region * area, bool is_3d)
00224 {
00225 ENTERFUNC;
00226 check_read_access(image_index, data);
00227 int ref_image_index = calc_ref_image_index(image_index);
00228 int err = imageio->read_data(data, ref_image_index, area, is_3d);
00229 EXITFUNC;
00230 return err;
00231 }
00232
00233 int LstIO::write_data(float *data, int, const Region* , EMUtil::EMDataType, bool)
00234 {
00235 ENTERFUNC;
00236 fprintf(lst_file, "%s\n", (char*)data);
00237 EXITFUNC;
00238 return 0;
00239 }
00240
00241 void LstIO::flush()
00242 {
00243 fflush(lst_file);
00244 }
00245
00246 bool LstIO::is_complex_mode()
00247 {
00248 return false;
00249 }
00250
00251 bool LstIO::is_image_big_endian()
00252 {
00253 init();
00254 return is_big_endian;
00255 }
00256
00257 int LstIO::get_nimg()
00258 {
00259 init();
00260 return nimg;
00261 }