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 <climits>
00038 #include "imagicio2.h"
00039 #include "portable_fileio.h"
00040 #include "util.h"
00041 #include "geometry.h"
00042 #include "ctf.h"
00043 #include "emassert.h"
00044 #include "transform.h"
00045
00046 #ifdef _WIN32
00047 #include <ctime>
00048 #endif //_WIN32
00049
00050 using namespace EMAN;
00051
00052 const char *ImagicIO2::HED_EXT = "hed";
00053 const char *ImagicIO2::IMG_EXT = "img";
00054 const char *ImagicIO2::REAL_TYPE_MAGIC = "REAL";
00055 const char *ImagicIO2::CTF_MAGIC = "!-";
00056
00057 ImagicIO2::ImagicIO2(string file, IOMode rw)
00058 : filename(file), rw_mode(rw), hed_file(0), img_file(0), initialized(false)
00059 {
00060 hed_filename = Util::change_filename_ext(filename, HED_EXT);
00061 img_filename = Util::change_filename_ext(filename, IMG_EXT);
00062
00063 is_big_endian = ByteOrder::is_host_big_endian();
00064 is_new_hed = false;
00065 is_new_img = false;
00066 memset(&imagich, 0, sizeof(Imagic4D));
00067 imagich.count = -1;
00068 datatype = IMAGIC_UNKNOWN_TYPE;
00069 nz = 0;
00070 }
00071
00072 ImagicIO2::~ImagicIO2()
00073 {
00074 if (hed_file) {
00075 fclose(hed_file);
00076 hed_file = 0;
00077 }
00078
00079 if (img_file) {
00080 fclose(img_file);
00081 img_file = 0;
00082 }
00083 }
00084
00085 void ImagicIO2::init()
00086 {
00087 ENTERFUNC;
00088
00089 if (initialized) {
00090 return;
00091 }
00092
00093 initialized = true;
00094
00095 is_new_hed = false;
00096 is_new_img = false;
00097
00098 hed_file = sfopen(hed_filename, rw_mode, &is_new_hed);
00099 img_file = sfopen(img_filename, rw_mode, &is_new_img);
00100
00101 if (is_new_hed != is_new_img) {
00102 LOGWARN("IMAGIC header file and data file should both exist or both not exist");
00103 }
00104
00105 if (!is_new_hed) {
00106 if (fread(&imagich, sizeof(Imagic4D), 1, hed_file) != 1) {
00107 throw ImageReadException(hed_filename, "IMAGIC4D header");
00108 }
00109
00110
00111
00112
00113
00114 datatype = get_datatype_from_name(imagich.type);
00115
00116 if (datatype != IMAGIC_SHORT && datatype != IMAGIC_FLOAT) {
00117 LOGERR("unsupported imagic data type: %s", imagich.type);
00118 throw ImageReadException(hed_filename, "unsupported imagic data type");
00119 }
00120
00121 is_big_endian = ByteOrder::is_data_big_endian(&imagich.ny);
00122 make_header_host_endian(imagich);
00123 rewind(hed_file);
00124 }
00125
00126 EXITFUNC;
00127 }
00128
00129 int ImagicIO2::init_test()
00130 {
00131 ENTERFUNC;
00132
00133 if (initialized) {
00134 return 1;
00135 }
00136
00137 FILE *in = fopen(hed_filename.c_str(), "rb");
00138 if (!in) {
00139 throw FileAccessException(filename);
00140 }
00141
00142 char first_block[1024];
00143 size_t n = fread(first_block, sizeof(char), sizeof(first_block), in);
00144
00145 if (n == 0) {
00146 LOGERR("file '%s' is an empty file", filename.c_str());
00147 fclose(in);
00148 return -1;
00149 }
00150 fclose(in);
00151
00152 const int *data = reinterpret_cast <const int *>(first_block);
00153 int nx = data[13];
00154 int ny = data[12];
00155 int izold = data[11];
00156
00157 if(izold==nx*ny) {
00158 EXITFUNC;
00159 return -1;
00160 }
00161 else {
00162 EXITFUNC;
00163 return 0;
00164 }
00165 }
00166
00167 bool ImagicIO2::is_valid(const void *first_block)
00168 {
00169 ENTERFUNC;
00170
00171 if (!first_block) {
00172 return false;
00173 }
00174
00175 const int *data = static_cast < const int *>(first_block);
00176 int count = data[1];
00177 int headrec = data[3];
00178 int hour = data[7];
00179 int minute = data[8];
00180 int second = data[9];
00181 int rsize = data[10];
00182 int nx = data[13];
00183 int ny = data[12];
00184 int nz = data[60];
00185 int realtype = data[68];
00186
00187 bool data_big_endian = ByteOrder::is_data_big_endian(&headrec);
00188
00189 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00190 ByteOrder::swap_bytes(&count);
00191 ByteOrder::swap_bytes(&headrec);
00192 ByteOrder::swap_bytes(&hour);
00193 ByteOrder::swap_bytes(&rsize);
00194 ByteOrder::swap_bytes(&nx);
00195 ByteOrder::swap_bytes(&ny);
00196 ByteOrder::swap_bytes(&nz);
00197 ByteOrder::swap_bytes(&realtype);
00198 }
00199
00200 const int max_dim = 1 << 20;
00201 bool result = false;
00202
00203
00204 if(realtype != VAX_VMS && realtype != LINUX_WINDOWS && realtype != SGI_IBM) {
00205 EXITFUNC;
00206 return result;
00207 }
00208
00209 if (headrec == 1 &&
00210 count >= 0 && count < max_dim &&
00211 nx > 0 && nx < max_dim &&
00212 ny > 0 && ny < max_dim &&
00213 nz > 0 && nz < max_dim &&
00214 hour >= 0 && hour < 24 &&
00215 minute >=0 && minute <60 &&
00216 second >=0 && second <60) {
00217 result = true;
00218 }
00219
00220 EXITFUNC;
00221 return result;
00222 }
00223
00224 int ImagicIO2::read_header(Dict & dict, int image_index, const Region * area, bool)
00225 {
00226 ENTERFUNC;
00227
00228 check_read_access(image_index);
00229
00230 Imagic4D hed;
00231 if (image_index == 0) {
00232 hed = imagich;
00233 }
00234 else {
00235 memset(&hed, 0, sizeof(Imagic4D));
00236 portable_fseek(hed_file, sizeof(Imagic4D) * image_index, SEEK_SET);
00237 fread(&hed, sizeof(Imagic4D), 1, hed_file);
00238 make_header_host_endian(hed);
00239 }
00240
00241 int nz = hed.izlp ? hed.izlp : 1;
00242 check_region(area, FloatSize(hed.nx, hed.ny, nz), is_new_hed, false);
00243
00244 datatype = get_datatype_from_name(imagich.type);
00245
00246 int xlen = 0, ylen = 0, zlen = 0;
00247 EMUtil::get_region_dims(area, hed.nx, &xlen, hed.ny, &ylen, nz, &zlen);
00248
00249 dict["nx"] = xlen;
00250 dict["ny"] = ylen;
00251 dict["nz"] = zlen;
00252
00253 dict["IMAGIC.imgnum"] = hed.imgnum;
00254 dict["IMAGIC.count"] = hed.count;
00255 dict["IMAGIC.error"] = hed.error;
00256
00257 dict["IMAGIC.month"] = hed.month;
00258 dict["IMAGIC.day"] = hed.mday;
00259 dict["IMAGIC.year"] = hed.year;
00260 dict["IMAGIC.hour"] = hed.hour;
00261 dict["IMAGIC.minute"] = hed.minute;
00262 dict["IMAGIC.sec"] = hed.sec;
00263
00264 dict["IMAGIC.rsize"] = hed.rsize;
00265 dict["IMAGIC.izold"] = hed.izold;
00266
00267 dict["datatype"] = to_em_datatype(datatype);
00268 dict["IMAGIC.type"] = hed.type+'\0';
00269
00270 dict["IMAGIC.ixold"] = hed.ixold;
00271 dict["IMAGIC.iyold"] = hed.iyold;
00272
00273 dict["mean"] = hed.avdens;
00274 dict["sigma"] = hed.sigma;
00275
00276 dict["maximum"] = hed.densmax;
00277 dict["minimum"] = hed.densmin;
00278
00279 dict["IMAGIC.complex"] = hed.complex;
00280 dict["IMAGIC.defocus1"] = hed.defocus1;
00281 dict["IMAGIC.defocus2"] = hed.defocus2;
00282 dict["IMAGIC.defangle"] = hed.defangle;
00283 dict["IMAGIC.sinostart"] = hed.sinostart;
00284 dict["IMAGIC.sinoend"] = hed.sinoend;
00285
00286 dict["IMAGIC.label"] = hed.label+'\0';
00287
00288 dict["IMAGIC.ccc3d"] = hed.ccc3d;
00289 dict["IMAGIC.ref3d"] = hed.ref3d;
00290 dict["IMAGIC.mident"] = hed.mident;
00291 dict["IMAGIC.ezshift"] = hed.ezshift;
00292
00293 dict["IMAGIC.ealpha"] = hed.ealpha;
00294 dict["IMAGIC.ebeta"] = hed.ebeta;
00295 dict["IMAGIC.egamma"] = hed.egamma;
00296
00297 dict["IMAGIC.nalisum"] = hed.nalisum;
00298 dict["IMAGIC.pgroup"] = hed.pgroup;
00299
00300 dict["IMAGIC.i4lp"] = hed.i4lp;
00301
00302 dict["IMAGIC.alpha"] = hed.alpha;
00303 dict["IMAGIC.beta"] = hed.beta;
00304 dict["IMAGIC.gamma"] = hed.gamma;
00305
00306 dict["IMAGIC.IMAVERS"] = hed.imavers;
00307 dict["IMAGIC.REALTYPE"] = hed.realtype;
00308
00309 dict["IMAGIC.ANGLE"] = hed.angle;
00310 dict["IMAGIC.VOLTAGE"] = hed.voltage;
00311 dict["IMAGIC.SPABERR"] = hed.spaberr;
00312 dict["IMAGIC.PCOHER"] = hed.pcoher;
00313 dict["IMAGIC.CCC"] = hed.ccc;
00314 dict["IMAGIC.ERRAR"] = hed.errar;
00315 dict["IMAGIC.ERR3D"] = hed.err3d;
00316 dict["IMAGIC.REF"] = hed.ref;
00317 dict["IMAGIC.CLASSNO"] = hed.ref;
00318 dict["IMAGIC.LOCOLD"] = hed.locold;
00319 dict["IMAGIC.REPQUAL"] = hed.repqual;
00320 dict["IMAGIC.ZSHIFT"] = hed.zshift;
00321 dict["IMAGIC.XSHIFT"] = hed.xshift;
00322 dict["IMAGIC.YSHIFT"] = hed.yshift;
00323 dict["IMAGIC.NUMCLS"] = hed.numcls;
00324 dict["IMAGIC.OVQUAL"] = hed.ovqual;
00325 dict["IMAGIC.EANGLE"] = hed.eangle;
00326 dict["IMAGIC.EXSHIFT"] = hed.exshift;
00327 dict["IMAGIC.EYSHIFT"] = hed.eyshift;
00328 dict["IMAGIC.CMTOTVAR"] = hed.cmtotvar;
00329 dict["IMAGIC.INFORMAT"] = hed.informat;
00330 dict["IMAGIC.NUMEIGEN"] = hed.numeigen;
00331 dict["IMAGIC.NIACTIVE"] = hed.niactive;
00332 dict["IMAGIC.RESOLX"] = hed.resolx;
00333 dict["IMAGIC.RESOLY"] = hed.resoly;
00334 dict["IMAGIC.RESOLZ"] = hed.resolz;
00335 if(hed.errar==-1.0) {
00336 dict["IMAGIC.FABOSA1"] = hed.alpha2;
00337 dict["IMAGIC.FABOSA2"] = hed.beta2;
00338 dict["IMAGIC.FABOSA3"] = hed.gamma2;
00339 }
00340 else {
00341 dict["IMAGIC.ALPHA2"] = hed.alpha2;
00342 dict["IMAGIC.BETA2"] = hed.beta2;
00343 dict["IMAGIC.GAMMA2"] = hed.gamma2;
00344 }
00345 dict["IMAGIC.NMETRIC"] = hed.nmetric;
00346 dict["IMAGIC.ACTMSA"] = hed.actmsa;
00347
00348 vector<float> v_coosmsa(hed.coosmsa, hed.coosmsa+69);
00349 dict["IMAGIC.COOSMSA"] = v_coosmsa;
00350
00351 dict["IMAGIC.EIGVAL"] = hed.coosmsa[19];
00352 dict["IMAGIC.HISTORY"] = hed.history+'\0';
00353
00354 dict["orientation_convention"] = "IMAGIC";
00355 const float alpha = hed.alpha;
00356 const float beta = hed.beta;
00357 const float gamma = hed.gamma;
00358 dict["euler_alpha"] = alpha;
00359 dict["euler_beta"] = beta;
00360 dict["euler_gamma"] = gamma;
00361 Transform *trans = new Transform();
00362 trans->set_rotation(Dict("type", "imagic", "alpha", alpha, "beta", beta, "gamma", gamma));
00363 if( nz<=1 ) {
00364 dict["xform.projection"] = trans;
00365 }
00366 else {
00367 dict["xform.projection"] = trans;
00368 dict["xform.align3d"] = trans;
00369 }
00370 Ctf * ctf_ = read_ctf(hed);
00371 if( ctf_ != 0) {
00372 dict["ctf"] = ctf_;
00373 }
00374 if(trans) {delete trans; trans=0;}
00375 if(ctf_) {delete ctf_; ctf_=0;}
00376
00377 EXITFUNC;
00378 return 0;
00379 }
00380
00381 ImagicIO2::DataType ImagicIO2::get_datatype_from_name(const char *name) const
00382 {
00383 DataType t = IMAGIC_UNKNOWN_TYPE;
00384
00385 if (strncmp(name, "PACK",4) == 0) {
00386 t = IMAGIC_CHAR;
00387 }
00388 else if (strncmp(name, "INTG",4) == 0) {
00389 t = IMAGIC_SHORT;
00390 }
00391 else if (strncmp(name, REAL_TYPE_MAGIC,4) == 0) {
00392 t = IMAGIC_FLOAT;
00393 }
00394 else if (strncmp(name, "COMP",4) == 0) {
00395 t = IMAGIC_FLOAT_COMPLEX;
00396 }
00397 else if (strncmp(name, "RECO",4) == 0) {
00398 t = IMAGIC_FFT_FLOAT_COMPLEX;
00399 }
00400 return t;
00401 }
00402
00403 int ImagicIO2::to_em_datatype(DataType t) const
00404 {
00405 switch (t) {
00406 case IMAGIC_CHAR:
00407 return EMUtil::EM_CHAR;
00408 case IMAGIC_SHORT:
00409 return EMUtil::EM_SHORT;
00410 case IMAGIC_FLOAT:
00411 return EMUtil::EM_FLOAT;
00412 case IMAGIC_FLOAT_COMPLEX:
00413 case IMAGIC_FFT_FLOAT_COMPLEX:
00414 return EMUtil::EM_FLOAT_COMPLEX;
00415 default:
00416 break;
00417 }
00418
00419 return EMUtil::EM_UNKNOWN;
00420 }
00421
00422 Ctf * ImagicIO2::read_ctf(const Imagic4D& hed) const
00423 {
00424 ENTERFUNC;
00425
00426 Ctf * ctf_ = 0;
00427 size_t n = strlen(CTF_MAGIC);
00428
00429 if (strncmp(imagich.label, CTF_MAGIC, n) == 0) {
00430 ctf_ = new EMAN1Ctf();
00431 string header_label(hed.label);
00432
00433
00434 if (header_label.size() > 2) {
00435 string sctf = "O" + header_label.substr(2);
00436 ctf_->from_string(sctf);
00437 }
00438 }
00439
00440 EXITFUNC;
00441 return ctf_;
00442 }
00443
00444 void ImagicIO2::write_ctf(const Ctf * const ctf, int image_index)
00445 {
00446 ENTERFUNC;
00447 init();
00448
00449 size_t n = strlen(CTF_MAGIC);
00450 strcpy(imagich.label, CTF_MAGIC);
00451 string ctf_ = ctf->to_string().substr(1);
00452 strncpy(&imagich.label[n], ctf_.c_str(), sizeof(imagich.label) - n);
00453
00454 rewind(hed_file);
00455 if (fwrite(&imagich, sizeof(Imagic4D), 1, hed_file) != 1) {
00456 throw ImageWriteException(hed_filename, "Imagic Header");
00457 }
00458
00459 EXITFUNC;
00460 }
00461
00462 bool ImagicIO2::is_complex_mode()
00463 {
00464 init();
00465 if (datatype == IMAGIC_FLOAT_COMPLEX || datatype == IMAGIC_FFT_FLOAT_COMPLEX) {
00466 return true;
00467 }
00468 return false;
00469 }
00470
00471 void ImagicIO2::flush()
00472 {
00473 fflush(img_file);
00474 fflush(hed_file);
00475 }
00476
00477 int ImagicIO2::write_header(EMAN::Dict const& dict, int image_index,
00478 EMAN::Region const* area, EMUtil::EMDataType, bool use_host_endian)
00479 {
00480 ENTERFUNC;
00481
00482 if(image_index<0) {
00483 image_index = get_nimg();
00484 }
00485 check_write_access(rw_mode, image_index);
00486
00487 if (area) {
00488 check_region(area, FloatSize(imagich.nx, imagich.ny, imagich.izlp),
00489 is_new_hed);
00490 EXITFUNC;
00491 return 0;
00492 }
00493
00494 int nx = dict["nx"];
00495 int ny = dict["ny"];
00496 int nz = dict["nz"];
00497 int nimg=0;
00498
00499 if (!is_new_hed) {
00500 datatype = get_datatype_from_name(imagich.type);
00501
00502 if (imagich.nx != nx || imagich.ny != ny || imagich.izlp != nz) {
00503 char desc[256];
00504 sprintf(desc, "new IMAGIC size %dx%dx%d is not equal to existing size %dx%dx%d",
00505 nx, ny, nz, imagich.nx, imagich.ny, imagich.izlp);
00506 throw ImageWriteException(filename, desc);
00507 }
00508
00509 if (datatype!=IMAGIC_FLOAT) {
00510 throw ImageWriteException(filename, "Attempted write to non REAL Imagic file");
00511 }
00512
00513 rewind(hed_file);
00514 nimg=image_index+1;
00515 }
00516 else {
00517 nimg = 1;
00518 }
00519
00520 Imagic4D new_hed;
00521 memset(&new_hed, 0, sizeof(Imagic4D));
00522
00523 time_t cur_time = time(0);
00524 struct tm *tm = localtime(&cur_time);
00525
00526 new_hed.error = 0;
00527 new_hed.headrec = 1;
00528
00529 new_hed.mday = tm->tm_mday;
00530 new_hed.month = tm->tm_mon;
00531 new_hed.year = tm->tm_year + 1900;
00532 new_hed.hour = tm->tm_hour;
00533 new_hed.minute = tm->tm_min;
00534 new_hed.sec = tm->tm_sec;
00535
00536 size_t img_size = nx*ny*nz*sizeof(float);
00537 if(img_size > (size_t)INT_MAX) {
00538 new_hed.rsize = -1;
00539 }
00540 else {
00541 new_hed.rsize = (int)img_size;
00542 }
00543
00544 new_hed.nx = nx;
00545 new_hed.ny = ny;
00546 new_hed.izlp = nz;
00547
00548 strncpy(new_hed.type, REAL_TYPE_MAGIC,4);
00549 new_hed.avdens = (float)dict["mean"];
00550 new_hed.sigma = (float)dict["sigma"];
00551 new_hed.densmax = (float)dict["maximum"];
00552 new_hed.densmin = (float)dict["minimum"];
00553
00554 new_hed.ixold = 0;
00555 new_hed.iyold = 0;
00556
00557 string new_label = dict.has_key("IMAGIC.label") ? (string) dict["IMAGIC.label"] : "";
00558 sprintf(new_hed.label, new_label.c_str() );
00559
00560 new_hed.i4lp = nimg;
00561
00562 Transform * t = 0;
00563 if(nz<=1 && dict.has_key("xform.projection")) {
00564 t = dict["xform.projection"];
00565 }
00566 else if(nz>1 && dict.has_key("xform.align3d")) {
00567 t = dict["xform.align3d"];
00568 }
00569
00570 if(t) {
00571 Dict d = t->get_rotation("imagic");
00572 new_hed.alpha = d["alpha"];
00573 new_hed.beta = d["beta"];
00574 new_hed.gamma = d["gamma"];
00575 delete t;
00576 t=0;
00577 }
00578 else {
00579 if(dict.has_key("euler_alpha")) new_hed.alpha = dict["euler_alpha"];
00580 if(dict.has_key("euler_beta")) new_hed.beta = dict["euler_beta"];
00581 if(dict.has_key("euler_gamma")) new_hed.gamma = dict["euler_gamma"];
00582 }
00583
00584 new_hed.realtype = generate_machine_stamp();
00585
00586 new_hed.resolx = dict["apix_x"];
00587 new_hed.resoly = dict["apix_y"];
00588 new_hed.resolz = dict["apix_z"];
00589
00590 if ( (is_big_endian != ByteOrder::is_host_big_endian()) || !use_host_endian) swap_header(new_hed);
00591
00592
00593 if (image_index>=0 && image_index<nimg) {
00594 portable_fseek(hed_file, sizeof(Imagic4D)*image_index, SEEK_SET);
00595 new_hed.imgnum=image_index+1;
00596 if (is_big_endian != ByteOrder::is_host_big_endian())
00597 ByteOrder::swap_bytes((int *) &new_hed.imgnum,1);
00598 fwrite(&new_hed, sizeof(Imagic4D),1,hed_file);
00599 }
00600
00601
00602 int ifol = nimg-1;
00603 if (is_big_endian != ByteOrder::is_host_big_endian()) {
00604 ByteOrder::swap_bytes((int *) &nimg,1);
00605 ByteOrder::swap_bytes((int *) &ifol,1);
00606 }
00607 portable_fseek(hed_file, sizeof(int), SEEK_SET);
00608 fwrite(&ifol, sizeof(int), 1, hed_file);
00609 portable_fseek(hed_file, 61*sizeof(int), SEEK_SET);
00610 fwrite(&nimg, sizeof(int), 1, hed_file);
00611
00612
00613 if ( (is_big_endian != ByteOrder::is_host_big_endian()) || !use_host_endian) swap_header(new_hed);
00614 imagich=new_hed;
00615 imagich.count=nimg;
00616 is_new_hed = false;
00617
00618 if( dict.has_key("ctf") ) {
00619 Ctf * ctf_ = dict["ctf"];
00620 write_ctf(ctf_);
00621 if(ctf_) {delete ctf_; ctf_=0;}
00622 }
00623
00624 EXITFUNC;
00625 return 0;
00626 }
00627
00628 int ImagicIO2::generate_machine_stamp() const
00629 {
00630 int machinestamp;
00631
00632 #ifdef __sgi
00633 machinestamp = SGI_IBM;
00634 #elif defined __OPENVMS__
00635 machinestamp = VAX_VMS;
00636 #else
00637 machinestamp = LINUX_WINDOWS;
00638 #endif
00639
00640 return machinestamp;
00641 }
00642
00643 void ImagicIO2::make_header_host_endian(Imagic4D& hed) const
00644 {
00645 if (is_big_endian != ByteOrder::is_host_big_endian()) {
00646 swap_header(hed);
00647 }
00648 }
00649
00650 void ImagicIO2::swap_header(Imagic4D & hed) const
00651 {
00652 ByteOrder::swap_bytes((int *) &hed, NUM_4BYTES_PRE_IYLP);
00653 ByteOrder::swap_bytes(&hed.ixold, NUM_4BYTES_AFTER_IXOLD);
00654 ByteOrder::swap_bytes((int *) &hed.ccc3d, NUM_4BYTES_AFTER_NAME);
00655 }
00656
00657 int ImagicIO2::write_data(float* data, int image_index, const Region * area, EMAN::EMUtil::EMDataType, bool use_host_endian)
00658 {
00659 ENTERFUNC;
00660
00661 check_write_access(rw_mode, image_index, 0, data);
00662 check_region(area, FloatSize(imagich.nx, imagich.ny, imagich.izlp), is_new_hed);
00663
00664 if (image_index == -1) {
00665 portable_fseek(img_file, 0, SEEK_END);
00666 }
00667 else {
00668 size_t img_size = imagich.nx * imagich.ny * imagich.izlp * sizeof(float);
00669 portable_fseek(img_file, img_size*image_index, SEEK_SET);
00670 }
00671
00672 if(is_new_img) {
00673 if(!use_host_endian) {
00674 ByteOrder::swap_bytes(data, imagich.nx * imagich.ny * imagich.izlp);
00675 }
00676 }
00677 else if (is_big_endian != ByteOrder::is_host_big_endian()) {
00678 ByteOrder::swap_bytes(data, imagich.nx * imagich.ny * imagich.izlp);
00679 }
00680
00681 EMUtil::process_region_io(data, img_file, WRITE_ONLY, 0,
00682 sizeof(float), imagich.nx, imagich.ny,
00683 imagich.izlp, area, true);
00684
00685 EXITFUNC;
00686 return 0;
00687 }
00688
00689 int ImagicIO2::read_data(float* data, int image_index, EMAN::Region const* area, bool)
00690 {
00691 ENTERFUNC;
00692
00693 check_read_access(image_index, data);
00694 Assert(datatype != IMAGIC_UNKNOWN_TYPE);
00695
00696 int nx = imagich.ny;
00697 int ny = imagich.nx;
00698 int nz = imagich.izlp ? imagich.izlp : 1;
00699 size_t img_size = (size_t)nx*ny*nz;
00700
00701 check_region(area, FloatSize(nx, ny, nz), is_new_hed, false);
00702
00703 portable_fseek(img_file, img_size*image_index*sizeof(float), SEEK_SET);
00704
00705 short *sdata = (short *) data;
00706 unsigned char *cdata = (unsigned char *) data;
00707 size_t mode_size = get_datatype_size(datatype);
00708
00711 EMUtil::process_region_io(cdata, img_file, READ_ONLY, 0, mode_size, nx, ny, nz, area, true);
00712
00713 if (datatype == IMAGIC_FLOAT) {
00714 become_host_endian(data, img_size);
00715 }
00716 else if (datatype == IMAGIC_SHORT) {
00717 become_host_endian(sdata, img_size);
00718
00719 for (ptrdiff_t j = img_size - 1; j >= 0; --j) {
00720 data[j] = static_cast < float >(sdata[j]);
00721 }
00722 }
00723 else {
00724 throw ImageReadException(filename, "unknown imagic data type");
00725 }
00726
00727 EXITFUNC;
00728 return 0;
00729 }
00730
00731 int ImagicIO2::get_nimg()
00732 {
00733 init();
00734 return imagich.count + 1;
00735 }
00736
00737 bool ImagicIO2::is_image_big_endian()
00738 {
00739 init();
00740 return is_big_endian;
00741 }
00742
00743 size_t ImagicIO2::get_datatype_size(DataType t) const
00744 {
00745 size_t s = 0;
00746 switch (t) {
00747 case IMAGIC_CHAR:
00748 s = sizeof(unsigned char);
00749 break;
00750 case IMAGIC_SHORT:
00751 s = sizeof(unsigned short);
00752 break;
00753 case IMAGIC_FLOAT:
00754 case IMAGIC_FLOAT_COMPLEX:
00755 case IMAGIC_FFT_FLOAT_COMPLEX:
00756 s = sizeof(float);
00757 break;
00758 default:
00759 s = 0;
00760 }
00761
00762 return s;
00763 }