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 "imagicio.h"
00038 #include "portable_fileio.h"
00039 #include "util.h"
00040 #include "geometry.h"
00041 #include "ctf.h"
00042 #include "emassert.h"
00043 #include "transform.h"
00044
00045 #ifdef _WIN32
00046 #include <ctime>
00047 #endif //_WIN32
00048
00049 using namespace EMAN;
00050
00051 const char *ImagicIO::HED_EXT = "hed";
00052 const char *ImagicIO::IMG_EXT = "img";
00053 const char *ImagicIO::REAL_TYPE_MAGIC = "REAL";
00054 const char *ImagicIO::CTF_MAGIC = "!-";
00055
00056 ImagicIO::ImagicIO(string file, IOMode rw)
00057 : filename(file), rw_mode(rw), hed_file(0), img_file(0), initialized(false)
00058 {
00059 hed_filename = Util::change_filename_ext(filename, HED_EXT);
00060 img_filename = Util::change_filename_ext(filename, IMG_EXT);
00061
00062 is_big_endian = ByteOrder::is_host_big_endian();
00063 is_new_hed = false;
00064 is_new_img = false;
00065 memset(&imagich, 0, sizeof(ImagicHeader));
00066 imagich.count = -1;
00067 datatype = IMAGIC_UNKNOWN_TYPE;
00068 nz = 0;
00069 }
00070
00071 ImagicIO::~ImagicIO()
00072 {
00073 if (hed_file) {
00074 fclose(hed_file);
00075 hed_file = 0;
00076 }
00077
00078 if (img_file) {
00079 fclose(img_file);
00080 img_file = 0;
00081 }
00082 }
00083
00084 void ImagicIO::init()
00085 {
00086 ENTERFUNC;
00087
00088 if (initialized) {
00089 return;
00090 }
00091
00092 initialized = true;
00093
00094 is_new_hed = false;
00095 is_new_img = false;
00096
00097 hed_file = sfopen(hed_filename, rw_mode, &is_new_hed);
00098 img_file = sfopen(img_filename, rw_mode, &is_new_img);
00099
00100 if (is_new_hed != is_new_img) {
00101 LOGWARN("IMAGIC header file and data file should both exist or both not exist");
00102 }
00103
00104 if (!is_new_hed) {
00105 if (fread(&imagich, sizeof(ImagicHeader), 1, hed_file) != 1) {
00106 throw ImageReadException(hed_filename, "IMAGIC header");
00107 }
00108
00109
00110
00111
00112
00113 datatype = get_datatype_from_name(imagich.type);
00114
00115 if (datatype != IMAGIC_USHORT && datatype != IMAGIC_FLOAT) {
00116 LOGERR("unsupported imagic data type: %s", imagich.type);
00117 throw ImageReadException(hed_filename, "unsupported imagic data type");
00118 }
00119
00120 is_big_endian = ByteOrder::is_data_big_endian(&imagich.ny);
00121 make_header_host_endian(imagich);
00122 rewind(hed_file);
00123 }
00124 EXITFUNC;
00125 }
00126
00127 bool ImagicIO::is_valid(const void *first_block)
00128 {
00129 ENTERFUNC;
00130
00131 if (!first_block) {
00132 return false;
00133 }
00134
00135 const int *data = static_cast < const int *>(first_block);
00136 int count = data[1];
00137 int headrec = data[3];
00138 int month = data[5];
00139 int hour = data[7];
00140 int nx = data[13];
00141 int ny = data[12];
00142
00143 bool data_big_endian = ByteOrder::is_data_big_endian(&headrec);
00144
00145 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00146 ByteOrder::swap_bytes(&count);
00147 ByteOrder::swap_bytes(&headrec);
00148 ByteOrder::swap_bytes(&month);
00149 ByteOrder::swap_bytes(&hour);
00150 ByteOrder::swap_bytes(&nx);
00151 ByteOrder::swap_bytes(&ny);
00152 }
00153
00154 const int max_dim = 1 << 20;
00155 bool result = false;
00156
00157 if (headrec == 1 &&
00158 count >= 0 && count < max_dim &&
00159 nx > 0 && nx < max_dim &&
00160 ny > 0 && ny < max_dim && month >= 0 && hour >= 0 && hour <= 24) {
00161 result = true;
00162 }
00163
00164 EXITFUNC;
00165 return result;
00166 }
00167
00168 int ImagicIO::read_header(Dict & dict, int image_index, const Region * area, bool is_3d)
00169 {
00170 ENTERFUNC;
00171
00172 check_read_access(image_index);
00173
00174 int nimg = 1;
00175
00176 if (is_3d) {
00177 nimg = imagich.count + 1;
00178
00179 if (nimg <= 1) {
00180 LOGWARN("this is not a 3D IMAGIC. Read as a 2D");
00181 }
00182 }
00183
00184 ImagicHeader hed;
00185 if (image_index == 0) {
00186 hed = imagich;
00187 }
00188 else {
00189 memset(&hed, 0, sizeof(ImagicHeader));
00190 portable_fseek(hed_file, sizeof(ImagicHeader) * image_index, SEEK_SET);
00191 fread(&hed, sizeof(ImagicHeader), 1, hed_file);
00192 make_header_host_endian(hed);
00193 }
00194 check_region(area, FloatSize(hed.nx, hed.ny, nimg), is_new_hed,false);
00195
00196 datatype = get_datatype_from_name(imagich.type);
00197
00198 int xlen = 0, ylen = 0, zlen = 0;
00199 EMUtil::get_region_dims(area, hed.nx, &xlen, hed.ny, &ylen, nimg, &zlen);
00200
00201 dict["nx"] = xlen;
00202 dict["ny"] = ylen;
00203 dict["nz"] = zlen;
00204
00205 dict["datatype"] = to_em_datatype(datatype);
00206
00207 dict["minimum"] = hed.min;
00208 dict["maximum"] = hed.max;
00209 dict["mean"] = hed.avdens;
00210 dict["sigma"] = hed.sigma;
00211
00212 dict["IMAGIC.imgnum"] = hed.imgnum;
00213 dict["IMAGIC.count"] = hed.count;
00214 dict["IMAGIC.error"] = hed.error;
00215
00216 dict["IMAGIC.headrec"] = hed.headrec;
00217 dict["IMAGIC.mday"] = hed.mday;
00218 dict["IMAGIC.month"] = hed.month;
00219
00220 dict["IMAGIC.year"] = hed.year;
00221 dict["IMAGIC.hour"] = hed.hour;
00222 dict["IMAGIC.minute"] = hed.minute;
00223
00224 dict["IMAGIC.sec"] = hed.sec;
00225 dict["IMAGIC.reals"] = hed.reals;
00226 dict["IMAGIC.pixels"] = hed.pixels;
00227
00228 char tmp[5] = { hed.type[0],hed.type[1],hed.type[2],hed.type[3],0 };
00229 dict["IMAGIC.type"] = tmp;
00230 dict["IMAGIC.ixold"] = hed.ixold;
00231 dict["IMAGIC.iyold"] = hed.iyold;
00232
00233 dict["IMAGIC.oldav"] = hed.oldav;
00234 dict["IMAGIC.label"] = hed.label;
00235 dict["ptcl_repr"] = hed.mrc2;
00236
00237 dict["orientation_convention"] = "EMAN";
00238 const float alt = hed.mrc1[1]*180.0f/M_PI;
00239 const float az = hed.mrc1[2]*180.0f/M_PI;
00240 const float phi = hed.mrc1[0]*180.0f/M_PI;
00241 dict["euler_alt"] = alt;
00242 dict["euler_az"] = az;
00243 dict["euler_phi"] = phi;
00244 Transform *trans = new Transform();
00245 trans->set_rotation(Dict("type", "eman", "alt", alt, "az", az, "phi", phi));
00246 if( hed.count==0 ) {
00247 dict["xform.projection"] = trans;
00248 }
00249 else {
00250 dict["xform.projection"] = trans;
00251 dict["xform.align3d"] = trans;
00252 }
00253 Ctf * ctf_ = read_ctf(hed);
00254 if( ctf_ != 0) {
00255 dict["ctf"] = ctf_;
00256 }
00257 if(trans) {delete trans; trans=0;}
00258 if(ctf_) {delete ctf_; ctf_=0;}
00259 EXITFUNC;
00260 return 0;
00261 }
00262
00263 int ImagicIO::write_header(const Dict & dict, int image_index,
00264 const Region * area, EMUtil::EMDataType, bool use_host_endian)
00265 {
00266 ENTERFUNC;
00267
00268 if(image_index<0) {
00269 image_index = get_nimg();
00270 }
00271
00272 check_write_access(rw_mode, image_index);
00273 nz = dict["nz"];
00274 if (nz > 1 && image_index != 0) {
00275 throw ImageWriteException(filename, "to write 3D IMAGIC image, image index must be 0");
00276 }
00277
00278 if (area) {
00279 check_region(area, FloatSize(imagich.nx, imagich.ny, imagich.count+1),
00280 is_new_hed);
00281 EXITFUNC;
00282 return 0;
00283 }
00284
00285 int nx = dict["nx"];
00286 int ny = dict["ny"];
00287 int nimg=0;
00288
00289
00290 if (!is_new_hed) {
00291 datatype = get_datatype_from_name(imagich.type);
00292
00293 if (imagich.nx != nx || imagich.ny != ny) {
00294 char desc[256];
00295 sprintf(desc, "new IMAGIC size %dx%d is not equal to existing size %dx%d",
00296 nx, ny, imagich.nx, imagich.ny);
00297 throw ImageWriteException(filename, desc);
00298 }
00299
00300 if (datatype!=IMAGIC_FLOAT) {
00301 throw ImageWriteException(filename, "Attempted write to non REAL Imagic file");
00302 }
00303
00304 rewind(hed_file);
00305 nimg=imagich.count+1;
00306 }
00307
00308 ImagicHeader new_hed;
00309 memset(&new_hed, 0, sizeof(ImagicHeader));
00310
00311 time_t cur_time = time(0);
00312 struct tm *tm = localtime(&cur_time);
00313
00314 new_hed.error = 0;
00315 new_hed.headrec = 1;
00316
00317 new_hed.mday = tm->tm_mday;
00318 new_hed.month = tm->tm_mon;
00319 new_hed.year = tm->tm_year + 1900;
00320 new_hed.hour = tm->tm_hour;
00321 new_hed.minute = tm->tm_min;
00322 new_hed.sec = tm->tm_sec;
00323
00324 new_hed.reals = nx * ny;
00325 new_hed.pixels = nx * ny;
00326 new_hed.ny = ny;
00327 new_hed.nx = nx;
00328
00329 new_hed.ixold = 0;
00330 new_hed.iyold = 0;
00331 new_hed.oldav = 0;
00332
00333 new_hed.min = (float)dict["minimum"];
00334 new_hed.max = (float)dict["maximum"];
00335 new_hed.avdens = (float)dict["mean"];
00336 new_hed.sigma = (float)dict["sigma"];
00337
00338 if(nz<=1 && dict.has_key("xform.projection")) {
00339 Transform * t = dict["xform.projection"];
00340 Dict d = t->get_rotation("eman");
00341 new_hed.mrc1[1] = (float)d["alt"]*M_PI/180.0f;
00342 new_hed.mrc1[2] = (float)d["az"]*M_PI/180.0f;
00343 new_hed.mrc1[0] = (float)d["phi"]*M_PI/180.0f;
00344 if(t) {delete t; t=0;}
00345 }
00346 else if(nz>1 && dict.has_key("xform.align3d")) {
00347 Transform * t = dict["xform.align3d"];
00348 Dict d = t->get_rotation("eman");
00349 new_hed.mrc1[1] = (float)d["alt"]*M_PI/180.0f;
00350 new_hed.mrc1[2] = (float)d["az"]*M_PI/180.0f;
00351 new_hed.mrc1[0] = (float)d["phi"]*M_PI/180.0f;
00352 if(t) {delete t; t=0;}
00353 }
00354 else {
00355 if(dict.has_key("euler_alt")) new_hed.mrc1[1] = (float)dict["euler_alt"]*M_PI/180.0f;
00356 if(dict.has_key("euler_az")) new_hed.mrc1[2] = (float)dict["euler_az"]*M_PI/180.0f;
00357 if(dict.has_key("euler_phi")) new_hed.mrc1[0] = (float)dict["euler_phi"]*M_PI/180.0f;
00358 }
00359
00360 if(dict.has_key("ptcl_repr")) new_hed.mrc2 = (int)dict["ptcl_repr"];
00361
00362 string new_label = dict.has_key("IMAGIC.label") ? (string) dict["IMAGIC.label"] : "";
00363 sprintf(new_hed.label, "%s", new_label.c_str() );
00364
00365 new_hed.lbuf = nx;
00366 new_hed.inn = 1;
00367 new_hed.iblp = ny;
00368 new_hed.ifb = 0;
00369 new_hed.lbw = 0;
00370 new_hed.lbr = -1;
00371 new_hed.lastlr = -1;
00372 new_hed.lastlw = 1;
00373 new_hed.num = 8;
00374 new_hed.nhalf = nx / 2;
00375 new_hed.ibsd = nx * 2;
00376 new_hed.ihfl = 7;
00377 new_hed.lcbr = -1;
00378 new_hed.lcbw = 1;
00379 new_hed.imstr = -1;
00380 new_hed.imstw = -1;
00381 new_hed.istart = 1;
00382 new_hed.iend = nx;
00383 new_hed.leff = nx;
00384 new_hed.linbuf = nx * 2;
00385 new_hed.ntotbuf = -1;
00386 new_hed.icstart = 1;
00387 new_hed.icend = nx / 2;
00388 strncpy(new_hed.type, REAL_TYPE_MAGIC,4);
00389
00390
00391
00392 if ( (is_big_endian != ByteOrder::is_host_big_endian()) || !use_host_endian) swap_header(new_hed);
00393
00394
00395 if (image_index>=0 && image_index<nimg) {
00396 portable_fseek(hed_file, sizeof(ImagicHeader)*image_index, SEEK_SET);
00397 new_hed.imgnum=image_index+1;
00398 if (is_big_endian != ByteOrder::is_host_big_endian())
00399 ByteOrder::swap_bytes((int *) &new_hed.imgnum,1);
00400 fwrite(&new_hed, sizeof(ImagicHeader),1,hed_file);
00401 }
00402
00403
00404 int required_len;
00405 if (nz>1) required_len=nz;
00406 else {
00407 if (image_index<0) required_len=nimg+1;
00408 else if (image_index+1>nimg) required_len=image_index+1;
00409 else required_len=nimg;
00410 }
00411
00412
00413 portable_fseek(hed_file, 0, SEEK_END);
00414 while (nimg<required_len) {
00415 nimg++;
00416 new_hed.imgnum=nimg;
00417 if (is_big_endian != ByteOrder::is_host_big_endian())
00418 ByteOrder::swap_bytes((int *) &new_hed.imgnum,1);
00419 fwrite(&new_hed, sizeof(ImagicHeader),1,hed_file);
00420 }
00421
00422
00423 portable_fseek(hed_file, sizeof(int), SEEK_SET);
00424 nimg--;
00425 if (is_big_endian != ByteOrder::is_host_big_endian())
00426 ByteOrder::swap_bytes((int *) &nimg,1);
00427 fwrite(&nimg, sizeof(int), 1, hed_file);
00428
00429
00430 if ( (is_big_endian != ByteOrder::is_host_big_endian()) || !use_host_endian) swap_header(new_hed);
00431 imagich=new_hed;
00432 imagich.count=nimg;
00433 is_new_hed = false;
00434
00435 if( dict.has_key("ctf") ) {
00436 Ctf * ctf_ = dict["ctf"];
00437 write_ctf(ctf_);
00438 if(ctf_) {delete ctf_; ctf_=0;}
00439 }
00440
00441 EXITFUNC;
00442 return 0;
00443 }
00444
00445 int ImagicIO::read_data(float *data, int image_index, const Region * area, bool is_3d)
00446 {
00447 ENTERFUNC;
00448
00449 check_read_access(image_index, data);
00450 Assert(datatype != IMAGIC_UNKNOWN_TYPE);
00451 int nimg = 1;
00452 if (is_3d) {
00453 nimg = imagich.count + 1;
00454 }
00455
00456 if (is_3d && imagich.count < 1) {
00457 LOGWARN("this is not a 3D IMAGIC. Read as a 2D");
00458 is_3d = false;
00459 }
00460
00461 check_region(area, FloatSize(imagich.nx, imagich.ny, nimg), is_new_hed,false);
00462
00463 rewind(img_file);
00464
00465 unsigned short *sdata = (unsigned short *) data;
00466 unsigned char *cdata = (unsigned char *) data;
00467 size_t mode_size = get_datatype_size(datatype);
00468 EMUtil::process_region_io(cdata, img_file, READ_ONLY, image_index, mode_size,
00469 imagich.nx, imagich.ny, nimg, area, true);
00470
00471 #if 0
00472 int row_size = imagich.nx * mode_size;
00473 int sec_size = imagich.nx * imagich.ny * mode_size;
00474
00475 for (int k = 0; k < nimg; k++) {
00476 for (int i = imagich.ny - 1; i >= 0; i--) {
00477 if (fread(&cdata[k * sec_size + i * row_size], row_size, 1, img_file) != 1) {
00478 LOGERR("incomplete data read: %d/%d blocks on file '%s'",
00479 i, imagich.ny, filename.c_str());
00480 return 1;
00481 }
00482 }
00483 }
00484 #endif
00485
00486 size_t img_size = imagich.nx * imagich.ny * nimg;
00487
00488 if (datatype == IMAGIC_FLOAT) {
00489 become_host_endian(data, img_size);
00490 }
00491 else if (datatype == IMAGIC_USHORT) {
00492 become_host_endian((unsigned short *) cdata, img_size);
00493
00494 for (int j = img_size - 1; j >= 0; j--) {
00495 data[j] = static_cast < float >(sdata[j]);
00496 }
00497 }
00498 else {
00499 throw ImageReadException(filename, "unknown imagic data type");
00500 }
00501
00502 EXITFUNC;
00503 return 0;
00504 }
00505
00506 int ImagicIO::write_data(float *data, int image_index, const Region* area,
00507 EMUtil::EMDataType, bool use_host_endian)
00508 {
00509 ENTERFUNC;
00510
00511 check_write_access(rw_mode, image_index, 0, data);
00512 check_region(area, FloatSize(imagich.nx, imagich.ny, imagich.count+1),
00513 is_new_hed);
00514
00515 if (nz == 1) {
00516 if (image_index == -1) {
00517 portable_fseek(img_file, 0, SEEK_END);
00518 }
00519 else {
00520 size_t sec_size = imagich.nx * imagich.ny * sizeof(float);
00521 portable_fseek(img_file, ((off_t) sec_size) * image_index, SEEK_SET);
00522 }
00523 }
00524
00525 if(is_new_img) {
00526 if(!use_host_endian) {
00527 ByteOrder::swap_bytes(data, imagich.nx * imagich.ny * nz);
00528 }
00529 }
00530 else if (is_big_endian != ByteOrder::is_host_big_endian()) {
00531 ByteOrder::swap_bytes(data, imagich.nx * imagich.ny * nz);
00532 }
00533 #if 0
00534 int n_pad_imgs = 0;
00535 int old_num_imgs = imagich.count + 1;
00536 if (image_index > old_num_imgs) {
00537 n_pad_imgs = image_index - old_num_imgs;
00538 }
00539 #endif
00540
00541
00542
00543
00544 EMUtil::process_region_io(data, img_file, WRITE_ONLY, 0,
00545 sizeof(float), imagich.nx, imagich.ny,
00546 nz, area, true);
00547
00548
00549 #if 0
00550 size_t row_size = imagich.nx * sizeof(float);
00551 int nxy = imagich.nx * imagich.ny;
00552
00553 for (int i = 0; i < nz; i++) {
00554 for (int j = imagich.ny - 1; j >= 0; j--) {
00555 fwrite(&data[i * nxy + j * imagich.nx], row_size, 1, img_file);
00556 }
00557
00558 if (!is_new_img && (is_big_endian != ByteOrder::is_host_big_endian())) {
00559 ByteOrder::swap_bytes(data, imagich.nx * imagich.ny);
00560 }
00561 }
00562 #endif
00563 EXITFUNC;
00564 return 0;
00565 }
00566
00567 void ImagicIO::flush()
00568 {
00569 fflush(img_file);
00570 fflush(hed_file);
00571 }
00572
00573 Ctf * ImagicIO::read_ctf(const ImagicHeader& hed) const
00574 {
00575 ENTERFUNC;
00576
00577 Ctf * ctf_ = 0;
00578 size_t n = strlen(CTF_MAGIC);
00579
00580 if (strncmp(imagich.label, CTF_MAGIC, n) == 0) {
00581 ctf_ = new EMAN1Ctf();
00582 string header_label(hed.label);
00583
00584
00585 if (header_label.size() > 2) {
00586 string sctf = "O" + header_label.substr(2);
00587 ctf_->from_string(sctf);
00588 }
00589 }
00590
00591 EXITFUNC;
00592 return ctf_;
00593 }
00594
00595 void ImagicIO::write_ctf(const Ctf * const ctf, int)
00596 {
00597 ENTERFUNC;
00598 init();
00599
00600 size_t n = strlen(CTF_MAGIC);
00601 strcpy(imagich.label, CTF_MAGIC);
00602 string ctf_ = ctf->to_string().substr(1);
00603 strncpy(&imagich.label[n], ctf_.c_str(), sizeof(imagich.label) - n);
00604
00605 rewind(hed_file);
00606 if (fwrite(&imagich, sizeof(ImagicHeader), 1, hed_file) != 1) {
00607 throw ImageWriteException(hed_filename, "Imagic Header");
00608 }
00609
00610 EXITFUNC;
00611 }
00612
00613 bool ImagicIO::is_complex_mode()
00614 {
00615 init();
00616 if (datatype == IMAGIC_FLOAT_COMPLEX || datatype == IMAGIC_FFT_FLOAT_COMPLEX) {
00617 return true;
00618 }
00619 return false;
00620 }
00621
00622 bool ImagicIO::is_image_big_endian()
00623 {
00624 init();
00625 return is_big_endian;
00626 }
00627
00628 int ImagicIO::get_nimg()
00629 {
00630 init();
00631 return (imagich.count + 1);
00632 }
00633
00634 ImagicIO::DataType ImagicIO::get_datatype_from_name(const char *name)
00635 {
00636 DataType t = IMAGIC_UNKNOWN_TYPE;
00637
00638 if (strncmp(name, "PACK",4) == 0) {
00639 t = IMAGIC_UCHAR;
00640 }
00641 else if (strncmp(name, "INTG",4) == 0) {
00642 t = IMAGIC_USHORT;
00643 }
00644 else if (strncmp(name, REAL_TYPE_MAGIC,4) == 0) {
00645 t = IMAGIC_FLOAT;
00646 }
00647 else if (strncmp(name, "COMP",4) == 0) {
00648 t = IMAGIC_FLOAT_COMPLEX;
00649 }
00650 else if (strncmp(name, "RECO",4) == 0) {
00651 t = IMAGIC_FFT_FLOAT_COMPLEX;
00652 }
00653 return t;
00654 }
00655
00656 size_t ImagicIO::get_datatype_size(DataType t)
00657 {
00658 size_t s = 0;
00659 switch (t) {
00660 case IMAGIC_UCHAR:
00661 s = sizeof(unsigned char);
00662 break;
00663 case IMAGIC_USHORT:
00664 s = sizeof(unsigned short);
00665 break;
00666 case IMAGIC_FLOAT:
00667 case IMAGIC_FLOAT_COMPLEX:
00668 case IMAGIC_FFT_FLOAT_COMPLEX:
00669 s = sizeof(float);
00670 break;
00671 default:
00672 s = 0;
00673 }
00674
00675 return s;
00676 }
00677
00678 int ImagicIO::to_em_datatype(DataType t)
00679 {
00680 switch (t) {
00681 case IMAGIC_UCHAR:
00682 return EMUtil::EM_UCHAR;
00683 case IMAGIC_USHORT:
00684 return EMUtil::EM_USHORT;
00685 case IMAGIC_FLOAT:
00686 return EMUtil::EM_FLOAT;
00687 case IMAGIC_FLOAT_COMPLEX:
00688 return EMUtil::EM_FLOAT_COMPLEX;
00689 default:
00690 break;
00691 }
00692
00693 return EMUtil::EM_UNKNOWN;
00694 }
00695
00696 void ImagicIO::make_header_host_endian(ImagicHeader & hed)
00697 {
00698 if (is_big_endian != ByteOrder::is_host_big_endian()) {
00699 swap_header(hed);
00700 }
00701 }
00702
00703
00704 void ImagicIO::swap_header(ImagicHeader & hed)
00705 {
00706 ByteOrder::swap_bytes((int *) &hed, NUM_4BYTES_PRE_IXOLD);
00707 ByteOrder::swap_bytes(&hed.ixold, NUM_4BYTES_AFTER_IXOLD);
00708 ByteOrder::swap_bytes((int *) &hed.space, NUM_4BYTES_AFTER_SPACE);
00709 }