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*,
00101 EMUtil::EMDataType filestoragetype, bool)
00102 {
00103 ENTERFUNC;
00104 init();
00105
00106 nx = (unsigned short)((int)dict["nx"]);
00107 ny = (unsigned short)((int)dict["ny"]);
00108 nz = (unsigned short)((int)dict["nz"]);
00109
00110 portable_fseek(df3file, 0, SEEK_SET);
00111
00112 unsigned short df3header[3];
00113 df3header[0] = nx;
00114 df3header[1] = ny;
00115 df3header[2] = nz;
00116 ByteOrder::become_big_endian(df3header, 3);
00117
00118 if(fwrite(df3header, sizeof(unsigned short), 3, df3file) != 3) {
00119 throw ImageWriteException(filename, "DF3 header");
00120 }
00121
00122 EXITFUNC;
00123 return 0;
00124 }
00125
00126 int Df3IO::read_data(float *rdata, int, const Region *, bool)
00127 {
00128 ENTERFUNC;
00129
00130 size_t image_size = nx*ny*nz;
00131
00132
00133 portable_fseek (df3file , 0 , SEEK_END);
00134 size_t fsize = ftell (df3file);
00135 rewind (df3file);
00136
00137 unsigned int * uidata = 0;
00138 unsigned short * usdata = 0;
00139 unsigned char * ucdata = 0;
00140
00141 portable_fseek(df3file, sizeof(unsigned short)*3, SEEK_SET);
00142 switch(fsize/image_size) {
00143 case sizeof(unsigned int):
00144 uidata = new unsigned int[image_size];
00145 fread(uidata, sizeof(unsigned int), image_size, df3file);
00146 become_host_endian < unsigned int >(uidata, image_size);
00147 std::copy(uidata, uidata+image_size, rdata);
00148 if(uidata) {delete [] uidata; uidata=0;}
00149 break;
00150 case sizeof(unsigned short):
00151 usdata = new unsigned short[image_size];
00152 fread(usdata, sizeof(unsigned short), image_size, df3file);
00153 become_host_endian < unsigned short >(usdata, image_size);
00154 std::copy(usdata, usdata+image_size, rdata);
00155 if(usdata) {delete [] usdata; usdata=0;}
00156 break;
00157 case sizeof(unsigned char):
00158 ucdata = new unsigned char[image_size];
00159 fread(ucdata, sizeof(unsigned char), image_size, df3file);
00160 std::copy(ucdata, ucdata+image_size, rdata);
00161 if(ucdata) {delete [] ucdata; ucdata=0;}
00162 break;
00163 default:
00164 throw ImageReadException(filename, "DF3 does not support this kind of data type.");
00165 }
00166
00167 EXITFUNC;
00168 return 0;
00169 }
00170
00171 int Df3IO::write_data(float *data, int, const Region*,
00172 EMUtil::EMDataType dt, bool)
00173 {
00174 ENTERFUNC;
00175
00176 size_t img_size = nx*ny*nz;
00177 unsigned int * uidata = 0;
00178 unsigned short * usdata = 0;
00179 unsigned char * ucdata = 0;
00180 float rendermin = 0.0f;
00181 float rendermax = 0.0f;
00182 EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax, nz);
00183
00184 switch(dt) {
00185 case EMUtil::EM_UINT:
00186 uidata = new unsigned int[img_size];
00187 for (size_t i = 0; i < img_size; ++i) {
00188 if(data[i] <= rendermin) {
00189 uidata[i] = 0;
00190 }
00191 else if(data[i] >= rendermax) {
00192 uidata[i] = UINT_MAX;
00193 }
00194 else {
00195 uidata[i]=(unsigned int)((data[i]-rendermin)/(rendermax-rendermin)*UINT_MAX);
00196 }
00197 }
00198 ByteOrder::become_big_endian(uidata, img_size);
00199 if(fwrite(uidata, sizeof(unsigned int), img_size, df3file) != img_size) {
00200 throw ImageWriteException(filename, "DF3 unsigned int data");
00201 }
00202 if(uidata) {delete [] uidata; uidata=0;}
00203 break;
00204 case EMUtil::EM_USHORT:
00205 usdata = new unsigned short[img_size];
00206 for (size_t i = 0; i < img_size; ++i) {
00207 if(data[i] <= rendermin) {
00208 usdata[i] = 0;
00209 }
00210 else if(data[i] >= rendermax) {
00211 usdata[i] = USHRT_MAX;
00212 }
00213 else {
00214 usdata[i]=(unsigned short)((data[i]-rendermin)/(rendermax-rendermin)*USHRT_MAX);
00215 }
00216 }
00217 ByteOrder::become_big_endian(usdata, img_size);
00218 if(fwrite(usdata, sizeof(unsigned short), img_size, df3file) != img_size) {
00219 throw ImageWriteException(filename, "DF3 unsigned short data");
00220 }
00221 if(usdata) {delete [] usdata; usdata=0;}
00222 break;
00223 case EMUtil::EM_UCHAR:
00224 ucdata = new unsigned char[img_size];
00225 for (size_t i = 0; i < img_size; ++i) {
00226 if(data[i] <= rendermin) {
00227 ucdata[i] = 0;
00228 }
00229 else if(data[i] >= rendermax){
00230 ucdata[i] = UCHAR_MAX;
00231 }
00232 else {
00233 ucdata[i]=(unsigned char)((data[i]-rendermin)/(rendermax-rendermin)*UCHAR_MAX);
00234 }
00235 }
00236 if(fwrite(ucdata, sizeof(unsigned char), img_size, df3file) != img_size) {
00237 throw ImageWriteException(filename, "DF3 unsigned char data");
00238 }
00239 if(ucdata) {delete [] ucdata; ucdata=0;}
00240 break;
00241 default:
00242 throw ImageWriteException(filename,"DF3 does not support this data format");
00243 }
00244
00245 EXITFUNC;
00246 return 0;
00247 }
00248
00249 void Df3IO::flush()
00250 {
00251 fflush(df3file);
00252 }
00253
00254 bool Df3IO::is_image_big_endian()
00255 {
00256 return true;
00257 }
00258
00259 bool Df3IO::is_complex_mode()
00260 {
00261 return false;
00262 }
00263
00264 bool Df3IO::is_valid(const void *first_block, off_t file_size)
00265 {
00266 ENTERFUNC;
00267
00268 if (!first_block) {
00269 return false;
00270 }
00271
00272 const unsigned short *data = static_cast < const unsigned short *>(first_block);
00273 unsigned short nx = data[0];
00274 unsigned short ny = data[1];
00275 unsigned short nz = data[2];
00276
00277 if(ByteOrder::is_data_big_endian(&nx) && ByteOrder::is_data_big_endian(&ny) && ByteOrder::is_data_big_endian(&nz)) {
00278 return true;
00279 }
00280
00281 EXITFUNC;
00282 return false;
00283 }