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(is_new_file) {       //for a new file write overall header first
00352                 write_single_header(dict, area, image_index, 0, first_h, OVERALL_STACK_HEADER, 1, 0, use_host_endian);
00353         }
00354         else {
00355                 swap_header(first_h);
00356         }
00357 
00358         if(!initialized) {
00359                 init();
00360         }
00361 
00362         if(!((int)dict["nx"]==first_h->nsam && (int)dict["ny"]==first_h->nrow &&
00363                         (int)dict["nz"]==first_h->nslice)) {
00364                 char desc[1024];
00365                 sprintf(desc, "%dth image size %dx%dx%d != overall size %dx%dx%d",
00366                                 image_index, (int)dict["nx"], (int)dict["ny"], (int)dict["nz"],
00367                                 (int)first_h->nsam, (int)first_h->nrow, (int)first_h->nslice);
00368                 throw ImageReadException(filename, desc);
00369         }
00370 
00371         if (!cur_h) {
00372                 cur_h = (SpiderHeader *) calloc(1, static_cast<size_t>(first_h->headlen));
00373         }
00374 
00375         int MAXIM;
00376         float size = first_h->nsam * first_h->nrow * first_h->nslice;
00377         size_t single_image_size = (int) (first_h->headlen + size * sizeof(float));
00378         size_t offset;
00379         if(image_index == -1) { //append image
00380                 offset = (int) first_h->headlen + single_image_size * (int)first_h->maxim;
00381                 MAXIM = (int)first_h->maxim + 1;
00382         }
00383         else {
00384                 offset = (int) first_h->headlen + single_image_size * image_index;
00385                 MAXIM = image_index>=(int)first_h->maxim ? image_index+1 : (int)first_h->maxim;
00386         }
00387 
00388         //update overall header
00389         if(MAXIM > (int)first_h->maxim) {
00390                 portable_fseek(spider_file, 0, SEEK_SET);
00391                 write_single_header(dict, area, image_index, 0, first_h, OVERALL_STACK_HEADER, MAXIM, 0, use_host_endian);
00392         }
00393 
00394         portable_fseek(spider_file, offset, SEEK_SET);
00395         write_single_header(dict, area, image_index, offset, cur_h, SINGLE_IMAGE_HEADER, 0, image_index+1, use_host_endian);
00396 
00397         EXITFUNC;
00398         return 0;
00399 }
00400 
00401 int SpiderIO::write_single_header(const Dict & dict, const Region *area, int image_index, size_t offset,
00402                                         SpiderHeader *& hp, int ISTACK, int MAXIM, int IMGNUM, bool use_host_endian)
00403 {
00404         ENTERFUNC;
00405 
00406         check_write_access(rw_mode, image_index);
00407 
00408         if (area) {
00409                 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
00410                 EXITFUNC;
00411                 return 0;
00412         }
00413 
00414         int nx = dict["nx"];
00415         int ny = dict["ny"];
00416         int nz = dict["nz"];
00417 
00418         size_t header_size = sizeof(SpiderHeader);
00419         size_t record_size = nx * sizeof(float);
00420     size_t num_records = (header_size % record_size) == 0 ? header_size / record_size : header_size / record_size + 1;
00421         size_t header_length = num_records * record_size;
00422 
00423         if (!hp) {
00424                 hp = static_cast < SpiderHeader * >(calloc(1, header_size));
00425         }
00426 
00427         hp->angvalid = 0;
00428         hp->scale = 1.0;
00429         hp->istack = (float)ISTACK;
00430         hp->nslice = (float)nz;
00431         hp->nsam = (float)nx;
00432         hp->nrow = (float)ny;
00433 
00434         hp->max = dict["maximum"];
00435         hp->min = dict["minimum"];
00436         hp->mean = dict["mean"];
00437         hp->sigma = dict["sigma"];
00438         hp->mmvalid = 1;
00439 
00440         if(nz<=1 && dict.has_key("xform.projection")) {
00441                 hp->angvalid = 1;
00442                 Transform * t = dict["xform.projection"];
00443                 Dict d = t->get_params("spider");
00444                 hp->phi = d["phi"];
00445                 hp->theta = d["theta"];
00446                 hp->gamma = d["psi"];
00447                 hp->dx = d["tx"];
00448                 hp->dy = d["ty"];
00449                 hp->dz = d["tz"];
00450                 hp->scale = d["scale"];
00451                 if(t) {delete t; t=0;}
00452         }
00453         else if(nz>1 && dict.has_key("xform.align3d")) {
00454                 hp->angvalid = 1;
00455                 Transform * t = dict["xform.align3d"];
00456                 Dict d = t->get_params("spider");
00457                 hp->phi = d["phi"];
00458                 hp->theta = d["theta"];
00459                 hp->gamma = d["psi"];
00460                 hp->dx = d["tx"];
00461                 hp->dy = d["ty"];
00462                 hp->dz = d["tz"];
00463                 hp->scale = d["scale"];
00464                 if(t) {delete t; t=0;}
00465         }
00466 
00467         if(nz == 1) {
00468                 hp->type = IMAGE_2D;
00469         }
00470         else {
00471                 hp->type = IMAGE_3D;
00472         }
00473 
00474 // complex image file not supported in EMAN2
00475 
00476         hp->reclen = (float)record_size;
00477         hp->headrec = (float)num_records;
00478         hp->headlen = (float)header_length;
00479 
00480         if(ISTACK == OVERALL_STACK_HEADER) {
00481                 hp->maxim = (float)MAXIM;
00482         }
00483         hp->irec = (float)(num_records + ny*nz);
00484 
00485         hp->imgnum = (float)IMGNUM;
00486 
00487         time_t tod;
00488         time(&tod);
00489         struct tm * ttt = localtime(&tod);
00490         char ctime[9];
00491         char cdate[12];
00492         strftime(ctime, 9, "%H:%M:%S", ttt);
00493         std::copy(&ctime[0], &ctime[8], hp->time);
00494         strftime(cdate, 12, "%d-%b-%Y", ttt);
00495         std::copy(&cdate[0], &cdate[11], hp->date);
00496 
00497         if(dict.has_key("SPIDER.title")) {
00498                 string title = static_cast<string>(dict["SPIDER.title"]);
00499                 std::copy(&(title[0]), &(title[title.length()]), hp->title);
00500         }
00501 
00502         portable_fseek(spider_file, offset, SEEK_SET);
00503 
00504         if(use_host_endian) {
00505                 if (fwrite(hp, header_size, 1, spider_file) != 1) {
00506                         throw ImageWriteException(filename, "write spider header failed");
00507                 }
00508         }
00509         else {  //swap byte order
00510                 SpiderHeader * hp2 = new SpiderHeader(*hp);
00511                 ByteOrder::swap_bytes((float *) hp2, NUM_FLOATS_IN_HEADER);
00512                 if (fwrite(hp2, header_size, 1, spider_file) != 1) {
00513                         throw ImageWriteException(filename, "write spider header failed");
00514                 }
00515                 if(hp2) {delete hp2; hp2=0;}
00516         }
00517 
00518         size_t pad_size = header_length - header_size;
00519         char *pad = static_cast < char *>(calloc(pad_size, 1));
00520         fwrite(pad, pad_size, 1, spider_file);
00521         if( pad )
00522         {
00523                 free(pad);
00524                 pad = 0;
00525         }
00526 
00527         EXITFUNC;
00528         return 0;
00529 }
00530 
00531 
00532 int SpiderIO::read_data(float *data, int image_index, const Region * area, bool)
00533 {
00534         ENTERFUNC;
00535 
00536         check_read_access(image_index, data);
00537 
00538         check_region(area, FloatSize((int) first_h->nsam, (int) first_h->nrow,
00539                                                                  (int) first_h->nslice), is_new_file,false);
00540 
00541         int overall_headlen = 0;
00542         if (first_h->istack >0) {       //for over all header length
00543                 overall_headlen = (int) first_h->headlen;
00544         }
00545         else {
00546                 if(image_index != 0) {
00547                         char desc[256];
00548                         sprintf(desc, "For single image, index must be 0. Your image index = %d.", image_index);
00549                         throw ImageReadException(filename, desc);
00550                 }
00551         }
00552 
00553         size_t size = static_cast < size_t > (first_h->nsam * first_h->nrow * first_h->nslice);
00554         size_t single_image_size = static_cast < size_t > (first_h->headlen + size * sizeof(float));
00555         off_t offset = overall_headlen + single_image_size * image_index;
00556         portable_fseek(spider_file, offset, SEEK_SET);
00557 
00558         portable_fseek(spider_file, (int) first_h->headlen, SEEK_CUR);
00559 
00560 #if 1
00561         EMUtil::process_region_io(data, spider_file, READ_ONLY, 0, sizeof(float),
00562                                                           (int) first_h->nsam, (int) first_h->nrow,
00563                                                           (int) first_h->nslice, area);
00564 #endif
00565 #if 0
00566         unsigned int nz = static_cast < unsigned int >(first_h->nslice);
00567         int sec_size = static_cast < int >(first_h->nsam * first_h->nrow * sizeof(float));
00568 
00569         if (fread(data, sec_size, nz, spider_file) != nz) {
00570                 LOGERR("Incomplete SPIDER data read");
00571                 return 1;
00572         }
00573 #endif
00574 
00575         int xlen = 0, ylen = 0, zlen = 0;
00576         EMUtil::get_region_dims(area, (int) first_h->nsam, &xlen, (int) first_h->nrow, &ylen,
00577                                                         (int) first_h->nslice, &zlen);
00578 
00579         int data_size = xlen * ylen * zlen;
00580         become_host_endian(data, data_size);
00581         EXITFUNC;
00582         return 0;
00583 }
00584 
00585 int SpiderIO::write_data(float *data, int image_index, const Region* area,
00586                                                  EMUtil::EMDataType, bool use_host_endian)
00587 {
00588         ENTERFUNC;
00589 
00590         if(!cur_h) {
00591                 throw ImageWriteException(filename, "Please write header before write data");
00592         }
00593 
00594         if(first_h->istack == SINGLE_IMAGE_HEADER) {
00595                 throw ImageWriteException(filename, "Cannot mix single spider and stack spider");
00596         }
00597 
00598         size_t offset;
00599         float size = first_h->nsam * first_h->nrow * first_h->nslice;
00600         size_t single_image_size = (int) (first_h->headlen + size * sizeof(float));
00601         offset = (int) first_h->headlen + single_image_size * image_index + (int) first_h->headlen;
00602 
00603         swap_data(data, (size_t)size);
00604 
00605         write_single_data(data, area, cur_h, offset, image_index, (int)first_h->maxim+1, use_host_endian);
00606 
00607         EXITFUNC;
00608         return 0;
00609 }
00610 
00611 
00612 void SpiderIO::flush()
00613 {
00614         fflush(spider_file);
00615 }
00616 
00617 int SpiderIO::write_single_data(float *data, const Region * area, SpiderHeader *& hp,
00618                                                                 size_t offset, int img_index, int max_nimg, bool use_host_endian)
00619 {
00620         ENTERFUNC;
00621 
00622         check_write_access(rw_mode, img_index, max_nimg, data);
00623 
00624         if (area) {
00625                 check_region(area, FloatSize(hp->nsam, hp->nrow, hp->nslice), is_new_file);
00626         }
00627 
00628         if (!hp) {
00629                 throw ImageWriteException(filename, "NULL image header");
00630         }
00631 
00632         portable_fseek(spider_file, offset, SEEK_SET);
00633 
00634         int size = (int)(hp->nsam * hp->nrow * hp->nslice);
00635         if(!use_host_endian) {
00636                 ByteOrder::swap_bytes(data, size);
00637         }
00638 
00639         // remove the stuff in #if 0 ... #endif if the following works.
00640         EMUtil::process_region_io(data, spider_file, WRITE_ONLY,0, sizeof(float),
00641                                                           (int) hp->nsam, (int) hp->nrow,
00642                                                           (int) hp->nslice, area);
00643 
00644         EXITFUNC;
00645         return 0;
00646 }
00647 
00648 void SpiderIO::swap_data(float *data, size_t size)
00649 {
00650         if (data && need_swap()) {
00651                 ByteOrder::swap_bytes(data, size);
00652         }
00653 }
00654 
00655 void SpiderIO::swap_header(SpiderHeader * header)
00656 {
00657         if (header && need_swap()) {
00658                 ByteOrder::swap_bytes((float *) header, NUM_FLOATS_IN_HEADER);
00659         }
00660 }
00661 
00662 bool SpiderIO::is_complex_mode()
00663 {
00664         int type = static_cast<int>(first_h->type);
00665         if (type == IMAGE_2D_FFT_ODD
00666                 || type == IMAGE_2D_FFT_EVEN
00667                 || type == IMAGE_3D_FFT_ODD
00668                 || type == IMAGE_3D_FFT_EVEN
00669            ) return true;
00670         return false;
00671 }
00672 
00673 bool SpiderIO::is_image_big_endian()
00674 {
00675         init();
00676         return is_big_endian;
00677 }
00678 
00679 int SpiderIO::get_nimg()
00680 {
00681         init();
00682         if (!first_h) {
00683                 Assert(is_new_file);
00684                 return 0;
00685         }
00686         else if (first_h->istack > 0) {                                         //image stack
00687                 return static_cast < int >(first_h->maxim);
00688         }
00689         else if (first_h->istack == SINGLE_IMAGE_HEADER) {      //single 2D/3D image
00690                 return 1;
00691         }
00692         else {                                                                                          //complex image
00693                 throw ImageFormatException("complex spider image not supported.");
00694         }
00695 }
00696 
00697 bool SpiderIO::need_swap() const
00698 {
00699         if (!is_new_file && (is_big_endian != ByteOrder::is_host_big_endian())) {
00700                 return true;
00701         }
00702         return false;
00703 }
00704 /* vim: set ts=4 noet: */

Generated on Sat Nov 21 02:19:16 2009 for EMAN2 by  doxygen 1.5.6