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 <cstring>
00037 #include "icosio.h"
00038 #include "portable_fileio.h"
00039 #include "geometry.h"
00040
00041 using namespace EMAN;
00042
00043
00044 IcosIO::IcosIO(const string & file, IOMode rw)
00045 : filename(file), rw_mode(rw), icos_file(0), initialized(false)
00046 {
00047 is_big_endian = ByteOrder::is_host_big_endian();
00048 is_new_file = false;
00049 memset(&icosh, 0, sizeof(IcosHeader));
00050 }
00051
00052 IcosIO::~IcosIO()
00053 {
00054 if (icos_file) {
00055 fclose(icos_file);
00056 icos_file = 0;
00057 }
00058 }
00059
00060 void IcosIO::init()
00061 {
00062 ENTERFUNC;
00063 if (initialized) {
00064 return ;
00065 }
00066
00067 initialized = true;
00068 icos_file = sfopen(filename, rw_mode, &is_new_file);
00069
00070 if (!is_new_file) {
00071 if (fread(&icosh, sizeof(IcosHeader), 1, icos_file) != 1) {
00072 throw ImageReadException(filename, "ICOS header");
00073 }
00074
00075 if (!is_valid(&icosh)) {
00076 throw ImageReadException(filename, "invalid ICOS file");
00077 }
00078 is_big_endian = ByteOrder::is_data_big_endian(&icosh.stamp);
00079 become_host_endian((int *) &icosh, sizeof(IcosHeader) / sizeof(int));
00080 }
00081 EXITFUNC;
00082 }
00083
00084 bool IcosIO::is_valid(const void *first_block)
00085 {
00086 ENTERFUNC;
00087 bool result = false;
00088 if (!first_block) {
00089 result = false;
00090 }
00091 else {
00092 const int *data = static_cast < const int *>(first_block);
00093 int stamp = data[0];
00094 int stamp1 = data[19];
00095 int stamp2 = data[20];
00096 int stamp3 = data[26];
00097
00098 bool data_big_endian = ByteOrder::is_data_big_endian(&stamp);
00099
00100 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00101 ByteOrder::swap_bytes(&stamp);
00102 ByteOrder::swap_bytes(&stamp1);
00103 ByteOrder::swap_bytes(&stamp2);
00104 ByteOrder::swap_bytes(&stamp3);
00105 }
00106
00107 if (stamp == STAMP && stamp1 == STAMP1 && stamp2 == STAMP2 && stamp3 == STAMP3) {
00108 result = true;
00109 }
00110 }
00111 EXITFUNC;
00112 return result;
00113 }
00114
00115 int IcosIO::read_header(Dict & dict, int image_index, const Region * area, bool)
00116 {
00117 ENTERFUNC;
00118
00119
00120 image_index = 0;
00121 check_read_access(image_index);
00122 check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
00123
00124 int xlen = 0, ylen = 0, zlen = 0;
00125 EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
00126
00127 dict["nx"] = xlen;
00128 dict["ny"] = ylen;
00129 dict["nz"] = zlen;
00130 dict["datatype"] = EMUtil::EM_FLOAT;
00131 dict["minimum"] = icosh.min;
00132 dict["maximum"] = icosh.max;
00133
00134 EXITFUNC;
00135 return 0;
00136 }
00137
00138 int IcosIO::write_header(const Dict & dict, int image_index, const Region* ,
00139 EMUtil::EMDataType, bool)
00140 {
00141 ENTERFUNC;
00142 int err = 0;
00143
00144 image_index = 0;
00145 check_write_access(rw_mode, image_index, 1);
00146
00147 icosh.stamp = STAMP;
00148 icosh.stamp1 = STAMP1;
00149 icosh.stamp2 = STAMP2;
00150 icosh.stamp3 = STAMP3;
00151
00152 icosh.nx = dict["nx"];
00153 icosh.ny = dict["ny"];
00154 icosh.nz = dict["nz"];
00155
00156 icosh.min = dict["minimum"];
00157 icosh.max = dict["maximum"];
00158
00159 rewind(icos_file);
00160
00161 if (fwrite(&icosh, sizeof(IcosHeader), 1, icos_file) != 1) {
00162 throw ImageWriteException(filename, "ICOS header write");
00163 }
00164
00165 EXITFUNC;
00166 return err;
00167 }
00168
00169 int IcosIO::read_data(float *data, int image_index, const Region * area, bool)
00170 {
00171 ENTERFUNC;
00172
00173
00174 image_index = 0;
00175 check_read_access(image_index, data);
00176 check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
00177
00178 portable_fseek(icos_file, sizeof(IcosHeader), SEEK_SET);
00179
00180 EMUtil::process_region_io((unsigned char *) data, icos_file,
00181 READ_ONLY, image_index,
00182 sizeof(float), icosh.nx, icosh.ny, icosh.nz,
00183 area, false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
00184
00185 int xlen = 0, ylen = 0, zlen = 0;
00186 EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
00187 become_host_endian(data, xlen * ylen * zlen);
00188
00189
00190 EXITFUNC;
00191 return 0;
00192 }
00193
00194 int IcosIO::write_data(float *data, int image_index, const Region* area,
00195 EMUtil::EMDataType, bool)
00196 {
00197 ENTERFUNC;
00198
00199 image_index = 0;
00200 check_write_access(rw_mode, image_index, 1, data);
00201 portable_fseek(icos_file, sizeof(IcosHeader), SEEK_SET);
00202
00203 EMUtil::process_region_io(data, icos_file, rw_mode, image_index,
00204 sizeof(float), icosh.nx, icosh.ny, icosh.nz, area,
00205 false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
00206
00207 #if 0
00208 int float_size = sizeof(float);
00209 int nx = icosh.nx;
00210 float *buf = new float[nx + 2];
00211 buf[0] = (float)float_size * nx;
00212 buf[nx + 1] = buf[0];
00213 int nrows = icosh.ny * icosh.nz;
00214
00215 int row_size = (nx + 2) * float_size;
00216
00217
00218 for (int j = 0; j < nrows; j++) {
00219 memcpy(&buf[1], &data[nx * j], nx * float_size);
00220 if (fwrite(buf, row_size, 1, icos_file) != 1) {
00221 throw ImageWriteException(filename, "ICOS data");
00222 }
00223 }
00224
00225 if( buf )
00226 {
00227 delete[]buf;
00228 buf = 0;
00229 }
00230 #endif
00231 EXITFUNC;
00232 return 0;
00233 }
00234
00235 void IcosIO::flush()
00236 {
00237 fflush(icos_file);
00238 }
00239
00240 bool IcosIO::is_complex_mode()
00241 {
00242 return false;
00243 }
00244
00245 bool IcosIO::is_image_big_endian()
00246 {
00247 init();
00248 return is_big_endian;
00249 }
00250