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 <algorithm>
00037 #include <climits>
00038
00039 #include "df3io.h"
00040 #include "portable_fileio.h"
00041
00042 using namespace EMAN;
00043
00044 Df3IO::Df3IO(const string & df3_filename, IOMode rw)
00045 : filename(df3_filename), rw_mode(rw), df3file(0),
00046 initialized(false), is_new_file(false)
00047 {
00048 }
00049
00050 Df3IO::~Df3IO()
00051 {
00052 if (df3file) {
00053 fclose(df3file);
00054 df3file = 0;
00055 }
00056 }
00057
00058 void Df3IO::init()
00059 {
00060 ENTERFUNC;
00061 if (initialized) {
00062 return;
00063 }
00064
00065 initialized = true;
00066 df3file = sfopen(filename, rw_mode, &is_new_file);
00067
00068 EXITFUNC;
00069 }
00070
00071
00072 int Df3IO::read_header(Dict & dict, int, const Region *, bool )
00073 {
00074 ENTERFUNC;
00075 init();
00076
00077 if (!is_new_file) {
00078 if (fread(&nx, sizeof(unsigned short), 1, df3file) != 1) {
00079 throw ImageReadException(filename, "DF3 header");
00080 }
00081
00082 fread(&ny, sizeof(unsigned short), 1, df3file);
00083 fread(&nz, sizeof(unsigned short), 1, df3file);
00084
00085 if(!ByteOrder::is_host_big_endian()) {
00086 ByteOrder::swap_bytes(&nx);
00087 ByteOrder::swap_bytes(&ny);
00088 ByteOrder::swap_bytes(&nz);
00089 }
00090
00091 dict["nx"] = (int)nx;
00092 dict["ny"] = (int)ny;
00093 dict["nz"] = (int)nz;
00094 }
00095
00096 EXITFUNC;
00097 return 0;
00098 }
00099
00100 int Df3IO::write_header(const Dict & dict, int, const Region*, EMUtil::EMDataType, bool)
00101 {
00102 ENTERFUNC;
00103 init();
00104
00105 nx = (unsigned short)((int)dict["nx"]);
00106 ny = (unsigned short)((int)dict["ny"]);
00107 nz = (unsigned short)((int)dict["nz"]);
00108
00109 portable_fseek(df3file, 0, SEEK_SET);
00110
00111 unsigned short df3header[3];
00112 df3header[0] = nx;
00113 df3header[1] = ny;
00114 df3header[2] = nz;
00115 ByteOrder::become_big_endian(df3header, 3);
00116
00117 if(fwrite(df3header, sizeof(unsigned short), 3, df3file) != 3) {
00118 throw ImageWriteException(filename, "DF3 header");
00119 }
00120
00121 EXITFUNC;
00122 return 0;
00123 }
00124
00125 int Df3IO::read_data(float *rdata, int, const Region *, bool)
00126 {
00127 ENTERFUNC;
00128
00129 size_t image_size = (size_t)nx*ny*nz;
00130
00131
00132 portable_fseek (df3file , 0 , SEEK_END);
00133 size_t fsize = ftell (df3file);
00134 rewind (df3file);
00135
00136 unsigned int * uidata = 0;
00137 unsigned short * usdata = 0;
00138 unsigned char * ucdata = 0;
00139
00140 portable_fseek(df3file, sizeof(unsigned short)*3, SEEK_SET);
00141 switch(fsize/image_size) {
00142 case sizeof(unsigned int):
00143 uidata = new unsigned int[image_size];
00144 fread(uidata, sizeof(unsigned int), image_size, df3file);
00145 become_host_endian < unsigned int >(uidata, image_size);
00146 std::copy(uidata, uidata+image_size, rdata);
00147 if(uidata) {delete [] uidata; uidata=0;}
00148 break;
00149 case sizeof(unsigned short):
00150 usdata = new unsigned short[image_size];
00151 fread(usdata, sizeof(unsigned short), image_size, df3file);
00152 become_host_endian < unsigned short >(usdata, image_size);
00153 std::copy(usdata, usdata+image_size, rdata);
00154 if(usdata) {delete [] usdata; usdata=0;}
00155 break;
00156 case sizeof(unsigned char):
00157 ucdata = new unsigned char[image_size];
00158 fread(ucdata, sizeof(unsigned char), image_size, df3file);
00159 std::copy(ucdata, ucdata+image_size, rdata);
00160 if(ucdata) {delete [] ucdata; ucdata=0;}
00161 break;
00162 default:
00163 throw ImageReadException(filename, "DF3 does not support this kind of data type.");
00164 }
00165
00166 EXITFUNC;
00167 return 0;
00168 }
00169
00170 int Df3IO::write_data(float *data, int, const Region*,
00171 EMUtil::EMDataType dt, bool)
00172 {
00173 ENTERFUNC;
00174
00175 size_t img_size = (size_t)nx*ny*nz;
00176 unsigned int * uidata = 0;
00177 unsigned short * usdata = 0;
00178 unsigned char * ucdata = 0;
00179 float rendermin = 0.0f;
00180 float rendermax = 0.0f;
00181 EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax, nz);
00182
00183 switch(dt) {
00184 case EMUtil::EM_UINT:
00185 uidata = new unsigned int[img_size];
00186 for (size_t i = 0; i < img_size; ++i) {
00187 if(data[i] <= rendermin) {
00188 uidata[i] = 0;
00189 }
00190 else if(data[i] >= rendermax) {
00191 uidata[i] = UINT_MAX;
00192 }
00193 else {
00194 uidata[i]=(unsigned int)((data[i]-rendermin)/(rendermax-rendermin)*UINT_MAX);
00195 }
00196 }
00197 ByteOrder::become_big_endian(uidata, img_size);
00198 if(fwrite(uidata, sizeof(unsigned int), img_size, df3file) != img_size) {
00199 throw ImageWriteException(filename, "DF3 unsigned int data");
00200 }
00201 if(uidata) {delete [] uidata; uidata=0;}
00202 break;
00203 case EMUtil::EM_USHORT:
00204 usdata = new unsigned short[img_size];
00205 for (size_t i = 0; i < img_size; ++i) {
00206 if(data[i] <= rendermin) {
00207 usdata[i] = 0;
00208 }
00209 else if(data[i] >= rendermax) {
00210 usdata[i] = USHRT_MAX;
00211 }
00212 else {
00213 usdata[i]=(unsigned short)((data[i]-rendermin)/(rendermax-rendermin)*USHRT_MAX);
00214 }
00215 }
00216 ByteOrder::become_big_endian(usdata, img_size);
00217 if(fwrite(usdata, sizeof(unsigned short), img_size, df3file) != img_size) {
00218 throw ImageWriteException(filename, "DF3 unsigned short data");
00219 }
00220 if(usdata) {delete [] usdata; usdata=0;}
00221 break;
00222 case EMUtil::EM_UCHAR:
00223 ucdata = new unsigned char[img_size];
00224 for (size_t i = 0; i < img_size; ++i) {
00225 if(data[i] <= rendermin) {
00226 ucdata[i] = 0;
00227 }
00228 else if(data[i] >= rendermax){
00229 ucdata[i] = UCHAR_MAX;
00230 }
00231 else {
00232 ucdata[i]=(unsigned char)((data[i]-rendermin)/(rendermax-rendermin)*UCHAR_MAX);
00233 }
00234 }
00235 if(fwrite(ucdata, sizeof(unsigned char), img_size, df3file) != img_size) {
00236 throw ImageWriteException(filename, "DF3 unsigned char data");
00237 }
00238 if(ucdata) {delete [] ucdata; ucdata=0;}
00239 break;
00240 default:
00241 throw ImageWriteException(filename,"DF3 does not support this data format");
00242 }
00243
00244 EXITFUNC;
00245 return 0;
00246 }
00247
00248 void Df3IO::flush()
00249 {
00250 fflush(df3file);
00251 }
00252
00253 bool Df3IO::is_image_big_endian()
00254 {
00255 return true;
00256 }
00257
00258 bool Df3IO::is_complex_mode()
00259 {
00260 return false;
00261 }
00262
00263 bool Df3IO::is_valid(const void *first_block, off_t)
00264 {
00265 ENTERFUNC;
00266
00267 if (!first_block) {
00268 return false;
00269 }
00270
00271 const unsigned short *data = static_cast < const unsigned short *>(first_block);
00272 unsigned short nx = data[0];
00273 unsigned short ny = data[1];
00274 unsigned short nz = data[2];
00275
00276 if(ByteOrder::is_data_big_endian(&nx) && ByteOrder::is_data_big_endian(&ny) && ByteOrder::is_data_big_endian(&nz)) {
00277 return true;
00278 }
00279
00280 EXITFUNC;
00281 return false;
00282 }