EMAN2
imagicio.cpp
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 //              if (!is_valid(&imagich)) {
00110 //                      throw ImageReadException(hed_filename, "invalid IMAGIC file");
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;                   // raw images represented by this image
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;             //# images currently in file
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         // header in file order
00392         if ( (is_big_endian != ByteOrder::is_host_big_endian()) || !use_host_endian)  swap_header(new_hed);
00393 
00394         // overwrite existing header if necessary
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         // How many images does the file need when we're done ?
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         // Extend the file to the necessary length
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         // update the 1st header with total # images
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         // header in machine order
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         // New way to write data which includes region writing.
00542         // If it is tested to be OK, remove the old code in the
00543         // #if 0  ... #endif block.
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                 // Note: this block was making things crash because it assumed the following if statement
00584                 // was true - I added the if statement (d.woolford)
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 }