EMAN2
spiderio.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 "spiderio.h"
00037 #include "geometry.h"
00038 #include "portable_fileio.h"
00039 #include "emassert.h"
00040 #include "util.h"
00041 #include "transform.h"
00042 #include <iostream>
00043 #include <ctime>
00044 #include <algorithm>
00045 
00046 using namespace EMAN;
00047 
00048 SpiderIO::SpiderIO(const string & spider_filename, IOMode rw)
00049 :       filename(spider_filename), rw_mode(rw),
00050         spider_file(0), first_h(0), cur_h(0),
00051         is_big_endian(ByteOrder::is_host_big_endian()),
00052         initialized(false)
00053 {
00054         is_new_file = !Util::is_file_exist(filename);
00055 }
00056 
00057 SpiderIO::~SpiderIO()
00058 {
00059         if (spider_file) {
00060                 fclose(spider_file);
00061                 spider_file = 0;
00062         }
00063 
00064         if (first_h) {
00065                 free(first_h);
00066                 first_h = 0;
00067         }
00068 
00069         if (cur_h) {
00070                 free(cur_h);
00071                 cur_h = 0;
00072         }
00073 }
00074 
00075 void SpiderIO::init()
00076 {
00077         if (initialized) {
00078                 return;
00079         }
00080         ENTERFUNC;
00081         spider_file = sfopen(filename, rw_mode, &is_new_file);
00082         initialized = true;
00083 
00084         if (!is_new_file) {
00085                 first_h = static_cast < SpiderHeader * >(calloc(1, sizeof(SpiderHeader)));
00086 
00087                 if (fread(first_h, sizeof(SpiderHeader), 1, spider_file) != 1) {
00088                         throw ImageReadException(filename, "SPIDER header");
00089                 }
00090 
00091                 if (!is_valid_spider(first_h)) {
00092                         throw ImageReadException(filename, "invalid SPIDER");
00093                 }
00094 
00095                 float nslice = first_h->nslice;
00096 
00097                 is_big_endian = ByteOrder::is_float_big_endian(nslice);
00098                 become_host_endian((float *) first_h, NUM_FLOATS_IN_HEADER);
00099 
00100                 if (first_h->istack == SINGLE_IMAGE_HEADER && rw_mode == WRITE_ONLY) {
00101                         fclose(spider_file);
00102                         spider_file = 0;
00103 
00104                         spider_file = fopen(filename.c_str(), "wb");
00105                 }
00106         }
00107 
00108         EXITFUNC;
00109 }
00110 
00111 bool SpiderIO::is_valid_spider(const void *first_block)
00112 {
00113         return SpiderIO::is_valid(first_block);
00114 }
00115 
00116 bool SpiderIO::is_valid(const void *first_block)
00117 {
00118         ENTERFUNC;
00119         bool result = false;
00120 
00121         if (first_block) {
00122                 const float *data = static_cast < const float *>(first_block);
00123                 float nslice = data[0];
00124                 float nrow = data[1];
00125                 float iform = data[4];
00126                 float nsam = data[11];
00127                 float labrec = data[12];        //NO. of records in file header
00128                 float labbyt = data[21];        //total NO. of bytes in header
00129                 float lenbyt = data[22];        //record length in bytes
00130                 float istack = data[23];
00131 
00132                 bool big_endian = ByteOrder::is_float_big_endian(nslice);
00133                 if (big_endian != ByteOrder::is_host_big_endian()) {
00134                         ByteOrder::swap_bytes(&nslice);
00135                         ByteOrder::swap_bytes(&nrow);
00136                         ByteOrder::swap_bytes(&iform);
00137                         ByteOrder::swap_bytes(&nsam);
00138                         ByteOrder::swap_bytes(&labrec);
00139                         ByteOrder::swap_bytes(&labbyt);
00140                         ByteOrder::swap_bytes(&lenbyt);
00141                         ByteOrder::swap_bytes(&istack);
00142                 }
00143 
00144                 if( int(nslice) != nslice || int(nrow) != nrow
00145                                 || int(iform) != iform || int(nsam) != nsam
00146                                 || int(labrec) != labrec || int(labbyt) != labbyt
00147                                 || int(lenbyt) != lenbyt ) {
00148                         result =  false;
00149                 }
00150                 else {
00151                         //now we expect this header to be an overall header for SPIDER
00152                         if( int(istack) > 0 ) {
00153                                 result = true; //istack>0 for overall header, istack<0 for indexed stack of image
00154                         }
00155                 }
00156 
00157                 int ilabrec = static_cast<int>(labrec);
00158                 int ilabbyt = static_cast<int>(labbyt);
00159                 int ilenbyt = static_cast<int>(lenbyt);
00160                 if( ilabbyt != ilabrec * ilenbyt ) {
00161                         result = false;
00162                 }
00163         }
00164 
00165         EXITFUNC;
00166         return result;
00167 }
00168 
00171 int SpiderIO::read_header(Dict & dict, int image_index, const Region * area, bool)
00172 {
00173         ENTERFUNC;
00174 
00175     bool is_read_overall_header = false;
00176     if (image_index == -1) {
00177         is_read_overall_header = true;
00178         image_index = 0;
00179     }
00180 
00181         check_read_access(image_index);
00182 
00183         if (!first_h) {
00184                 throw ImageReadException(filename, "empty spider header");
00185         }
00186 
00187         check_region(area, FloatSize(first_h->nsam, first_h->nrow,first_h->nslice), is_new_file,false);
00188 
00189         float size = first_h->nsam * first_h->nrow * first_h->nslice;
00190         int overall_headlen = 0;
00191 
00192     if (!is_read_overall_header) {
00193         if (first_h->istack > 0) {      //stack image
00194             overall_headlen = (int) first_h->headlen;
00195         }
00196         else if(first_h->istack == SINGLE_IMAGE_HEADER) {       //single 2D/3D image
00197             if(image_index != 0) {
00198                 char desc[1024];
00199                 sprintf(desc, "For a single image, index must be 0. Your image index = %d.", image_index);
00200                 throw ImageReadException(filename, desc);
00201             }
00202         }
00203         else {  //complex spider image not supported
00204                 throw ImageFormatException("complex spider image not supported.");
00205         }
00206     }
00207 
00208         size_t single_image_size = (size_t) (first_h->headlen + size * sizeof(float));
00209         size_t offset = overall_headlen + single_image_size * image_index;
00210 
00211         SpiderHeader *cur_image_hed;
00212         if (offset == 0) {
00213                 cur_image_hed = first_h;
00214         }
00215         else {
00216                 cur_image_hed = static_cast < SpiderHeader * >(calloc(1, sizeof(SpiderHeader)));
00217                 portable_fseek(spider_file, offset, SEEK_SET);
00218 
00219                 if (fread(cur_image_hed, sizeof(SpiderHeader), 1, spider_file) != 1) {
00220                         char desc[1024];
00221                         sprintf(desc, "read spider header with image_index = %d failed", image_index);
00222                         throw ImageReadException(filename, desc);
00223                 }
00224 
00225                 become_host_endian((float *) cur_image_hed, NUM_FLOATS_IN_HEADER);
00226 
00227                 if (cur_image_hed->nsam != first_h->nsam || cur_image_hed->nrow != first_h->nrow
00228                         || cur_image_hed->nslice != first_h->nslice) {
00229                         char desc[1024];
00230                         sprintf(desc, "%dth image size %dx%dx%d != overall size %dx%dx%d",
00231                                         image_index, (int)cur_image_hed->nsam, (int)cur_image_hed->nrow,
00232                                         (int)cur_image_hed->nslice,
00233                                         (int)first_h->nsam, (int)first_h->nrow, (int)first_h->nslice);
00234                         throw ImageReadException(filename, desc);
00235                 }
00236         }
00237 
00238 
00239         int xlen = 0, ylen = 0, zlen = 0;
00240         EMUtil::get_region_dims(area, (int) cur_image_hed->nsam, &xlen, (int) cur_image_hed->nrow,
00241                                                         &ylen, (int) cur_image_hed->nslice, &zlen);
00242 
00243         dict["nx"] = xlen;
00244         dict["ny"] = ylen;
00245         dict["nz"] = zlen;
00246 
00247         dict["datatype"] = EMUtil::EM_FLOAT;
00248 
00249         if(cur_image_hed->mmvalid == 1) {
00250                 dict["minimum"] = cur_image_hed->min;
00251                 dict["maximum"] = cur_image_hed->max;
00252                 dict["mean"] = cur_image_hed->mean;
00253                 dict["sigma"] = cur_image_hed->sigma;
00254         }
00255 
00256         dict["SPIDER.nslice"] = (int) cur_image_hed->nslice;
00257         dict["SPIDER.type"] = (int) cur_image_hed->type;
00258 
00259         dict["SPIDER.irec"] = cur_image_hed->irec;
00260 
00261         dict["SPIDER.angvalid"] = (int)cur_image_hed->angvalid;
00262         if((int)dict["SPIDER.angvalid"] != 0) {
00263                 dict["SPIDER.phi"] = cur_image_hed->phi;
00264                 dict["SPIDER.theta"] = cur_image_hed->theta;
00265                 dict["SPIDER.gamma"] = cur_image_hed->gamma;
00266         }
00267 
00268         dict["SPIDER.headrec"] = (int) cur_image_hed->headrec;
00269         dict["SPIDER.headlen"] = (int) cur_image_hed->headlen;
00270         dict["SPIDER.reclen"] = (int) cur_image_hed->reclen;
00271 
00272         dict["SPIDER.dx"] = cur_image_hed->dx;
00273         dict["SPIDER.dy"] = cur_image_hed->dy;
00274         dict["SPIDER.dz"] = cur_image_hed->dz;
00275 
00276         dict["SPIDER.istack"] = (int) cur_image_hed->istack;
00277         if((int)dict["SPIDER.istack"] > 0) {    //maxim only for overall header
00278                 dict["SPIDER.maxim"] = (int)cur_image_hed->maxim;
00279         }
00280         dict["SPIDER.imgnum"] = (int)cur_image_hed->imgnum;
00281 
00282         dict["SPIDER.Kangle"] = (int)cur_image_hed->Kangle;
00283         if((int)dict["SPIDER.Kangle"] == 1) {
00284                 dict["SPIDER.phi1"] = cur_image_hed->phi1;
00285                 dict["SPIDER.theta1"] = cur_image_hed->theta1;
00286                 dict["SPIDER.psi1"] = cur_image_hed->psi1;
00287         }
00288         else if((int)dict["SPIDER.Kangle"] == 2) {
00289                 dict["SPIDER.phi1"] = cur_image_hed->phi1;
00290                 dict["SPIDER.theta1"] = cur_image_hed->theta1;
00291                 dict["SPIDER.psi1"] = cur_image_hed->psi1;
00292                 dict["SPIDER.phi2"] = cur_image_hed->phi2;
00293                 dict["SPIDER.theta2"] = cur_image_hed->theta2;
00294                 dict["SPIDER.psi2"] = cur_image_hed->psi2;
00295         }
00296 
00297         dict["SPIDER.date"] = string(cur_image_hed->date).substr(0, 11);
00298         dict["SPIDER.time"] = string(cur_image_hed->time).substr(0, 8);
00299 
00300         dict["SPIDER.title"] = string(cur_image_hed->title);
00301 
00302         if(cur_image_hed->scale>0) {
00303                 dict["SPIDER.scale"] = cur_image_hed->scale;
00304                 Dict dic;
00305                 dic.put("type", "spider");
00306                 dic.put("phi", cur_image_hed->phi);
00307                 dic.put("theta", cur_image_hed->theta);
00308                 dic.put("psi", cur_image_hed->gamma);
00309                 dic.put("tx", cur_image_hed->dx);
00310                 dic.put("ty", cur_image_hed->dy);
00311                 dic.put("tz", cur_image_hed->dz);
00312                 dic.put("scale", cur_image_hed->scale);
00313                 Transform * trans = new Transform(dic);
00314                 if(zlen<=1) {
00315                         dict["xform.projection"] = trans;
00316                 }
00317                 else {
00318                         dict["xform.align3d"] = trans;
00319                 }
00320                 if(trans) {delete trans; trans=0;}
00321         }
00322 
00323 
00334         if (offset != 0) {
00335                 if( cur_image_hed )
00336                 {
00337                         free(cur_image_hed);
00338                         cur_image_hed = 0;
00339                 }
00340         }
00341         EXITFUNC;
00342         return 0;
00343 }
00344 
00345 
00346 int SpiderIO::write_header(const Dict & dict, int image_index, const Region* area,
00347                                                    EMUtil::EMDataType, bool use_host_endian)
00348 {
00349         ENTERFUNC;
00350 
00351         if (image_index<0) {
00352                 image_index = get_nimg();
00353         }
00354 
00355         if(is_new_file) {       //for a new file write overall header first
00356                 write_single_header(dict, area, image_index, 0, first_h, OVERALL_STACK_HEADER, 1, 0, use_host_endian);
00357         }
00358         else {
00359                 swap_header(first_h);
00360         }
00361 
00362         if(!initialized) {
00363                 init();
00364         }
00365 
00366         if(!((int)dict["nx"]==first_h->nsam && (int)dict["ny"]==first_h->nrow &&
00367                         (int)dict["nz"]==first_h->nslice)) {
00368                 char desc[1024];
00369                 sprintf(desc, "%dth image size %dx%dx%d != overall size %dx%dx%d",
00370                                 image_index, (int)dict["nx"], (int)dict["ny"], (int)dict["nz"],
00371                                 (int)first_h->nsam, (int)first_h->nrow, (int)first_h->nslice);
00372                 throw ImageReadException(filename, desc);
00373         }
00374 
00375         if (!cur_h) {
00376                 cur_h = (SpiderHeader *) calloc(1, static_cast<size_t>(first_h->headlen));
00377         }
00378 
00379         int MAXIM;
00380         float size = first_h->nsam * first_h->nrow * first_h->nslice;
00381         size_t single_image_size = (int) (first_h->headlen + size * sizeof(float));
00382         size_t offset;
00383         if(image_index == -1) { //append image
00384                 offset = (int) first_h->headlen + single_image_size * (int)first_h->maxim;
00385                 MAXIM = (int)first_h->maxim + 1;
00386         }
00387         else {
00388                 offset = (int) first_h->headlen + single_image_size * image_index;
00389                 MAXIM = image_index>=(int)first_h->maxim ? image_index+1 : (int)first_h->maxim;
00390         }
00391 
00392         //update overall header
00393         if(MAXIM > (int)first_h->maxim) {
00394                 portable_fseek(spider_file, 0, SEEK_SET);
00395                 write_single_header(dict, area, image_index, 0, first_h, OVERALL_STACK_HEADER, MAXIM, 0, use_host_endian);
00396         }
00397 
00398         portable_fseek(spider_file, offset, SEEK_SET);
00399         write_single_header(dict, area, image_index, offset, cur_h, SINGLE_IMAGE_HEADER, 0, image_index+1, use_host_endian);
00400 
00401         EXITFUNC;
00402         return 0;
00403 }
00404 
00405 int SpiderIO::write_single_header(const Dict & dict, const Region *area, int image_index, size_t offset,
00406                                         SpiderHeader *& hp, int ISTACK, int MAXIM, int IMGNUM, bool use_host_endian)
00407 {
00408         ENTERFUNC;
00409 
00410         check_write_access(rw_mode, image_index);
00411 
00412         if (area) {
00413                 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
00414                 EXITFUNC;
00415                 return 0;
00416         }
00417 
00418         int nx = dict["nx"];
00419         int ny = dict["ny"];
00420         int nz = dict["nz"];
00421 
00422         size_t header_size = sizeof(SpiderHeader);
00423         size_t record_size = nx * sizeof(float);
00424     size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1;
00425         size_t header_length = num_records * record_size;
00426 
00427         if (!hp) {
00428                 hp = static_cast < SpiderHeader * >(calloc(1, header_size));
00429         }
00430 
00431         hp->angvalid = 0;
00432         hp->scale = 1.0;
00433         hp->istack = (float)ISTACK;
00434         hp->nslice = (float)nz;
00435         hp->nsam = (float)nx;
00436         hp->nrow = (float)ny;
00437 
00438         hp->max = dict["maximum"];
00439         hp->min = dict["minimum"];
00440         hp->mean = dict["mean"];
00441         hp->sigma = dict["sigma"];
00442         hp->mmvalid = 1;
00443 
00444         if(nz<=1 && dict.has_key("xform.projection")) {
00445                 hp->angvalid = 1;
00446                 Transform * t = dict["xform.projection"];
00447                 Dict d = t->get_params("spider");
00448                 hp->phi = d["phi"];
00449                 hp->theta = d["theta"];
00450                 hp->gamma = d["psi"];
00451                 hp->dx = d["tx"];
00452                 hp->dy = d["ty"];
00453                 hp->dz = d["tz"];
00454                 hp->scale = d["scale"];
00455                 if(t) {delete t; t=0;}
00456         }
00457         else if(nz>1 && dict.has_key("xform.align3d")) {
00458                 hp->angvalid = 1;
00459                 Transform * t = dict["xform.align3d"];
00460                 Dict d = t->get_params("spider");
00461                 hp->phi = d["phi"];
00462                 hp->theta = d["theta"];
00463                 hp->gamma = d["psi"];
00464                 hp->dx = d["tx"];
00465                 hp->dy = d["ty"];
00466                 hp->dz = d["tz"];
00467                 hp->scale = d["scale"];
00468                 if(t) {delete t; t=0;}
00469         }
00470 
00471         if(nz == 1) {
00472                 hp->type = IMAGE_2D;
00473         }
00474         else {
00475                 hp->type = IMAGE_3D;
00476         }
00477 
00478 // complex image file not supported in EMAN2
00479 
00480         hp->reclen = (float)record_size;
00481         hp->headrec = (float)num_records;
00482         hp->headlen = (float)header_length;
00483 
00484         if(ISTACK == OVERALL_STACK_HEADER) {
00485                 hp->maxim = (float)MAXIM;
00486         }
00487         hp->irec = (float)(num_records + ny*nz);
00488 
00489         hp->imgnum = (float)IMGNUM;
00490 
00491         time_t tod;
00492         time(&tod);
00493         struct tm * ttt = localtime(&tod);
00494         char ctime[9];
00495         char cdate[12];
00496         strftime(ctime, 9, "%H:%M:%S", ttt);
00497         std::copy(&ctime[0], &ctime[8], hp->time);
00498         strftime(cdate, 12, "%d-%b-%Y", ttt);
00499         std::copy(&cdate[0], &cdate[11], hp->date);
00500 
00501         if(dict.has_key("SPIDER.title")) {
00502                 string title = static_cast<string>(dict["SPIDER.title"]);
00503                 std::copy(&(title[0]), &(title[title.length()]), hp->title);
00504         }
00505 
00506         portable_fseek(spider_file, offset, SEEK_SET);
00507 
00508         if(use_host_endian) {
00509                 if (fwrite(hp, header_size, 1, spider_file) != 1) {
00510                         throw ImageWriteException(filename, "write spider header failed");
00511                 }
00512         }
00513         else {  //swap byte order
00514                 SpiderHeader * hp2 = new SpiderHeader(*hp);
00515                 ByteOrder::swap_bytes((float *) hp2, NUM_FLOATS_IN_HEADER);
00516                 if (fwrite(hp2, header_size, 1, spider_file) != 1) {
00517                         throw ImageWriteException(filename, "write spider header failed");
00518                 }
00519                 if(hp2) {delete hp2; hp2=0;}
00520         }
00521 
00522         size_t pad_size = header_length - header_size;
00523         char *pad = static_cast < char *>(calloc(pad_size, 1));
00524         fwrite(pad, pad_size, 1, spider_file);
00525         if( pad )
00526         {
00527                 free(pad);
00528                 pad = 0;
00529         }
00530 
00531         EXITFUNC;
00532         return 0;
00533 }
00534 
00535 
00536 int SpiderIO::read_data(float *data, int image_index, const Region * area, bool)
00537 {
00538         ENTERFUNC;
00539 
00540         check_read_access(image_index, data);
00541 
00542         check_region(area, FloatSize((int) first_h->nsam, (int) first_h->nrow,
00543                                                                  (int) first_h->nslice), is_new_file,false);
00544 
00545         int overall_headlen = 0;
00546         if (first_h->istack >0) {       //for over all header length
00547                 overall_headlen = (int) first_h->headlen;
00548         }
00549         else {
00550                 if(image_index != 0) {
00551                         char desc[256];
00552                         sprintf(desc, "For single image, index must be 0. Your image index = %d.", image_index);
00553                         throw ImageReadException(filename, desc);
00554                 }
00555         }
00556 
00557         size_t size = static_cast < size_t > (first_h->nsam * first_h->nrow * first_h->nslice);
00558         size_t single_image_size = static_cast < size_t > (first_h->headlen + size * sizeof(float));
00559         off_t offset = overall_headlen + single_image_size * image_index;
00560         portable_fseek(spider_file, offset, SEEK_SET);
00561 
00562         portable_fseek(spider_file, (int) first_h->headlen, SEEK_CUR);
00563 
00564 #if 1
00565         EMUtil::process_region_io(data, spider_file, READ_ONLY, 0, sizeof(float),
00566                                                           (int) first_h->nsam, (int) first_h->nrow,
00567                                                           (int) first_h->nslice, area);
00568 #endif
00569 #if 0
00570         unsigned int nz = static_cast < unsigned int >(first_h->nslice);
00571         int sec_size = static_cast < int >(first_h->nsam * first_h->nrow * sizeof(float));
00572 
00573         if (fread(data, sec_size, nz, spider_file) != nz) {
00574                 LOGERR("Incomplete SPIDER data read");
00575                 return 1;
00576         }
00577 #endif
00578 
00579         int xlen = 0, ylen = 0, zlen = 0;
00580         EMUtil::get_region_dims(area, (int) first_h->nsam, &xlen, (int) first_h->nrow, &ylen,
00581                                                         (int) first_h->nslice, &zlen);
00582 
00583         int data_size = xlen * ylen * zlen;
00584         become_host_endian(data, data_size);
00585         EXITFUNC;
00586         return 0;
00587 }
00588 
00589 int SpiderIO::write_data(float *data, int image_index, const Region* area,
00590                                                  EMUtil::EMDataType, bool use_host_endian)
00591 {
00592         ENTERFUNC;
00593 
00594         if(!cur_h) {
00595                 throw ImageWriteException(filename, "Please write header before write data");
00596         }
00597 
00598         if(first_h->istack == SINGLE_IMAGE_HEADER) {
00599                 throw ImageWriteException(filename, "Cannot mix single spider and stack spider");
00600         }
00601 
00602         size_t offset;
00603         float size = first_h->nsam * first_h->nrow * first_h->nslice;
00604         size_t single_image_size = (int) (first_h->headlen + size * sizeof(float));
00605         offset = (int) first_h->headlen + single_image_size * image_index + (int) first_h->headlen;
00606 
00607         swap_data(data, (size_t)size);
00608 
00609         write_single_data(data, area, cur_h, offset, image_index, (int)first_h->maxim+1, use_host_endian);
00610 
00611         EXITFUNC;
00612         return 0;
00613 }
00614 
00615 
00616 void SpiderIO::flush()
00617 {
00618         fflush(spider_file);
00619 }
00620 
00621 int SpiderIO::write_single_data(float *data, const Region * area, SpiderHeader *& hp,
00622                                                                 size_t offset, int img_index, int max_nimg, bool use_host_endian)
00623 {
00624         ENTERFUNC;
00625 
00626         check_write_access(rw_mode, img_index, max_nimg, data);
00627 
00628         if (area) {
00629                 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
00630         }
00631 
00632         if (!hp) {
00633                 throw ImageWriteException(filename, "NULL image header");
00634         }
00635 
00636         portable_fseek(spider_file, offset, SEEK_SET);
00637 
00638         int size = (int)(hp->nsam * hp->nrow * hp->nslice);
00639         if(!use_host_endian) {
00640                 ByteOrder::swap_bytes(data, size);
00641         }
00642 
00643         // remove the stuff in #if 0 ... #endif if the following works.
00644         EMUtil::process_region_io(data, spider_file, WRITE_ONLY,0, sizeof(float),
00645                                                           (int) hp->nsam, (int) hp->nrow,
00646                                                           (int) hp->nslice, area);
00647 
00648         EXITFUNC;
00649         return 0;
00650 }
00651 
00652 void SpiderIO::swap_data(float *data, size_t size)
00653 {
00654         if (data && need_swap()) {
00655                 ByteOrder::swap_bytes(data, size);
00656         }
00657 }
00658 
00659 void SpiderIO::swap_header(SpiderHeader * header)
00660 {
00661         if (header && need_swap()) {
00662                 ByteOrder::swap_bytes((float *) header, NUM_FLOATS_IN_HEADER);
00663         }
00664 }
00665 
00666 bool SpiderIO::is_complex_mode()
00667 {
00668         int type = static_cast<int>(first_h->type);
00669         if (type == IMAGE_2D_FFT_ODD
00670                 || type == IMAGE_2D_FFT_EVEN
00671                 || type == IMAGE_3D_FFT_ODD
00672                 || type == IMAGE_3D_FFT_EVEN
00673            ) return true;
00674         return false;
00675 }
00676 
00677 bool SpiderIO::is_image_big_endian()
00678 {
00679         init();
00680         return is_big_endian;
00681 }
00682 
00683 int SpiderIO::get_nimg()
00684 {
00685         init();
00686         if (!first_h) {
00687                 Assert(is_new_file);
00688                 return 0;
00689         }
00690         else if (first_h->istack > 0) {                                         //image stack
00691                 return static_cast < int >(first_h->maxim);
00692         }
00693         else if (first_h->istack == SINGLE_IMAGE_HEADER) {      //single 2D/3D image
00694                 return 1;
00695         }
00696         else {                                                                                          //complex image
00697                 throw ImageFormatException("complex spider image not supported.");
00698         }
00699 }
00700 
00701 bool SpiderIO::need_swap() const
00702 {
00703         if (!is_new_file && (is_big_endian != ByteOrder::is_host_big_endian())) {
00704                 return true;
00705         }
00706         return false;
00707 }
00708 /* vim: set ts=4 noet: */