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 "lstfastio.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 *LstFastIO::MAGIC = "#LSX";
00055
00056 LstFastIO::LstFastIO(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 LstFastIO::~LstFastIO()
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 LstFastIO::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 fgets(buf,MAXPATHLEN,lst_file);
00106 fgets(buf,MAXPATHLEN,lst_file);
00107 line_length=atoi(buf+1);
00108 head_length=ftell(lst_file);
00109 fseek(lst_file,0L,SEEK_END);
00110 nimg=(ftell(lst_file)-head_length)/line_length;
00111 rewind(lst_file);
00112 }
00113 EXITFUNC;
00114 }
00115
00116 bool LstFastIO::is_valid(const void *first_block)
00117 {
00118 ENTERFUNC;
00119 bool result = false;
00120
00121 if (!first_block) {
00122 result = false;
00123 }
00124 else {
00125 result = Util::check_file_by_magic(first_block, MAGIC);
00126 }
00127
00128 EXITFUNC;
00129 return result;
00130 }
00131
00132 int LstFastIO::calc_ref_image_index(int image_index)
00133 {
00134 if (image_index == last_lst_index) {
00135 return last_ref_index;
00136 }
00137 else {
00138 char buf[MAXPATHLEN];
00139
00140 fseek(lst_file,head_length+line_length*image_index,SEEK_SET);
00141 if (!fgets(buf, MAXPATHLEN, lst_file)) {
00142 LOGERR("reach EOF in file '%s' before reading %dth image",
00143 filename.c_str(), image_index);
00144 return 1;
00145 }
00146
00147 int ref_image_index = 0;
00148 char ref_image_path[MAXPATHLEN];
00149 char unused[256];
00150 sscanf(buf, " %d %s %[ .,0-9-]", &ref_image_index, ref_image_path, unused);
00151
00152 char fullpath[MAXPATHLEN];
00153
00154 char sep = '/';
00155 #ifdef WIN32
00156 sep = '\\';
00157 #endif
00158 if (ref_image_path[0] == sep) {
00159 strcpy(fullpath, ref_image_path);
00160 }
00161 else {
00162 if (strrchr(filename.c_str(), sep)) {
00163 strcpy(fullpath, filename.c_str());
00164 }
00165 else {
00166 #ifndef WIN32
00167 getcwd(fullpath, MAXPATHLEN);
00168 #else
00169
00170 #endif
00171 }
00172
00173 char *p_basename = strrchr(fullpath, sep);
00174 if (p_basename) {
00175
00176
00177 char ssep[2];
00178 ssep[0] = sep;
00179 ssep[1] = '\0';
00180 strcat(fullpath, ssep);
00181 strcat(fullpath, ref_image_path);
00182 }
00183 }
00184
00185 ref_filename = string(fullpath);
00186 imageio = EMUtil::get_imageio(ref_filename, rw_mode);
00187
00188 last_ref_index = ref_image_index;
00189 }
00190
00191
00192 last_lst_index = image_index;
00193
00194 return last_ref_index;
00195 }
00196
00197
00198 int LstFastIO::read_header(Dict & dict, int image_index, const Region * area, bool is_3d)
00199 {
00200 ENTERFUNC;
00201 check_read_access(image_index);
00202 int ref_image_index = calc_ref_image_index(image_index);
00203 int err = imageio->read_header(dict, ref_image_index, area, is_3d);
00204 EXITFUNC;
00205 return err;
00206 }
00207
00208 int LstFastIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00209 {
00210 ENTERFUNC;
00211 fprintf(lst_file, "%s\n# 80\n", MAGIC);
00212 EXITFUNC;
00213 return 0;
00214 }
00215
00216 int LstFastIO::read_data(float *data, int image_index, const Region * area, bool is_3d)
00217 {
00218 ENTERFUNC;
00219 check_read_access(image_index, data);
00220 int ref_image_index = calc_ref_image_index(image_index);
00221 int err = imageio->read_data(data, ref_image_index, area, is_3d);
00222 EXITFUNC;
00223 return err;
00224 }
00225
00226 int LstFastIO::write_data(float *data, int, const Region* , EMUtil::EMDataType, bool)
00227 {
00228 ENTERFUNC;
00229 char *data2=(char*)data;
00230 if (strlen(data2)>line_length-1) throw ImageWriteException("", "Comment too long for this LSX file");
00231 fprintf(lst_file, "%s", (char*)data);
00232 for (unsigned int i=strlen(data2); i<line_length-1; i++) putc(' ',lst_file);
00233 putc('\n',lst_file);
00234
00235 EXITFUNC;
00236 return 0;
00237 }
00238
00239 void LstFastIO::flush()
00240 {
00241 fflush(lst_file);
00242 }
00243
00244 bool LstFastIO::is_complex_mode()
00245 {
00246 return false;
00247 }
00248
00249 bool LstFastIO::is_image_big_endian()
00250 {
00251 init();
00252 return is_big_endian;
00253 }
00254
00255 int LstFastIO::get_nimg()
00256 {
00257 init();
00258 return nimg;
00259 }