Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

df3io.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Grant Tang, 08/06/2010 (gtang@bcm.edu)
00007  * Copyright (c) 2000-2010 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 <algorithm>
00037 #include <climits>
00038 
00039 #include "df3io.h"
00040 #include "portable_fileio.h"
00041 
00042 using namespace EMAN;
00043 
00044 Df3IO::Df3IO(const string & df3_filename, IOMode rw)
00045 :       filename(df3_filename), rw_mode(rw), df3file(0),
00046         initialized(false), is_new_file(false)
00047 {
00048 }
00049 
00050 Df3IO::~Df3IO()
00051 {
00052         if (df3file) {
00053                 fclose(df3file);
00054                 df3file = 0;
00055         }
00056 }
00057 
00058 void Df3IO::init()
00059 {
00060         ENTERFUNC;
00061         if (initialized) {
00062                 return;
00063         }
00064 
00065         initialized = true;
00066         df3file = sfopen(filename, rw_mode, &is_new_file);
00067 
00068         EXITFUNC;
00069 }
00070 
00071 // header is 3 MSB unsigned shorts (nx,ny,nz) in big-endian
00072 int Df3IO::read_header(Dict & dict, int, const Region *, bool )
00073 {
00074         ENTERFUNC;
00075         init();
00076 
00077         if (!is_new_file) {
00078                 if (fread(&nx, sizeof(unsigned short), 1, df3file) != 1) {
00079                         throw ImageReadException(filename, "DF3 header");
00080                 }
00081 
00082                 fread(&ny, sizeof(unsigned short), 1, df3file);
00083                 fread(&nz, sizeof(unsigned short), 1, df3file);
00084 
00085                 if(!ByteOrder::is_host_big_endian()) {
00086                         ByteOrder::swap_bytes(&nx);
00087                         ByteOrder::swap_bytes(&ny);
00088                         ByteOrder::swap_bytes(&nz);
00089                 }
00090 
00091                 dict["nx"] = (int)nx;
00092                 dict["ny"] = (int)ny;
00093                 dict["nz"] = (int)nz;
00094         }
00095 
00096         EXITFUNC;
00097         return 0;
00098 }
00099 
00100 int Df3IO::write_header(const Dict & dict, int, const Region*,
00101                                                 EMUtil::EMDataType filestoragetype, bool)
00102 {
00103         ENTERFUNC;
00104         init();
00105 
00106         nx = (unsigned short)((int)dict["nx"]);
00107         ny = (unsigned short)((int)dict["ny"]);
00108         nz = (unsigned short)((int)dict["nz"]);
00109 
00110         portable_fseek(df3file, 0, SEEK_SET);
00111 
00112         unsigned short df3header[3];
00113         df3header[0] = nx;
00114         df3header[1] = ny;
00115         df3header[2] = nz;
00116         ByteOrder::become_big_endian(df3header, 3);
00117 
00118         if(fwrite(df3header, sizeof(unsigned short), 3, df3file) != 3) {
00119                 throw ImageWriteException(filename, "DF3 header");
00120         }
00121 
00122         EXITFUNC;
00123         return 0;
00124 }
00125 
00126 int Df3IO::read_data(float *rdata, int, const Region *, bool)
00127 {
00128         ENTERFUNC;
00129 
00130         size_t image_size = nx*ny*nz;
00131 
00132         // obtain file size:
00133         portable_fseek (df3file , 0 , SEEK_END);
00134         size_t fsize = ftell (df3file);
00135         rewind (df3file);
00136 
00137         unsigned int * uidata = 0;
00138         unsigned short * usdata = 0;
00139         unsigned char * ucdata = 0;
00140 
00141         portable_fseek(df3file, sizeof(unsigned short)*3, SEEK_SET);    //skip header
00142         switch(fsize/image_size) {
00143         case sizeof(unsigned int):
00144                 uidata = new unsigned int[image_size];
00145                 fread(uidata, sizeof(unsigned int), image_size, df3file);
00146                 become_host_endian < unsigned int >(uidata, image_size);
00147                 std::copy(uidata, uidata+image_size, rdata);
00148                 if(uidata) {delete [] uidata; uidata=0;}
00149                 break;
00150         case sizeof(unsigned short):
00151                 usdata = new unsigned short[image_size];
00152                 fread(usdata, sizeof(unsigned short), image_size, df3file);
00153                 become_host_endian < unsigned short >(usdata, image_size);
00154                 std::copy(usdata, usdata+image_size, rdata);
00155                 if(usdata) {delete [] usdata; usdata=0;}
00156                 break;
00157         case sizeof(unsigned char):
00158                 ucdata = new unsigned char[image_size];
00159                 fread(ucdata, sizeof(unsigned char), image_size, df3file);
00160                 std::copy(ucdata, ucdata+image_size, rdata);
00161                 if(ucdata) {delete [] ucdata; ucdata=0;}
00162                 break;
00163         default:
00164                 throw ImageReadException(filename, "DF3 does not support this kind of data type.");
00165         }
00166 
00167         EXITFUNC;
00168         return 0;
00169 }
00170 
00171 int Df3IO::write_data(float *data, int, const Region*,
00172                                           EMUtil::EMDataType dt, bool)
00173 {
00174         ENTERFUNC;
00175 
00176         size_t img_size = nx*ny*nz;
00177         unsigned int * uidata = 0;
00178         unsigned short * usdata = 0;
00179         unsigned char * ucdata = 0;
00180         float rendermin = 0.0f;
00181         float rendermax = 0.0f;
00182         EMUtil::getRenderMinMax(data, nx, ny, rendermin, rendermax, nz);
00183 
00184         switch(dt) {
00185         case EMUtil::EM_UINT:
00186                 uidata = new unsigned int[img_size];
00187                 for (size_t i = 0; i < img_size; ++i) {
00188                         if(data[i] <= rendermin) {
00189                                 uidata[i] = 0;
00190                         }
00191                         else if(data[i] >= rendermax) {
00192                                 uidata[i] = UINT_MAX;
00193                         }
00194                         else {
00195                                 uidata[i]=(unsigned int)((data[i]-rendermin)/(rendermax-rendermin)*UINT_MAX);
00196                         }
00197                 }
00198                 ByteOrder::become_big_endian(uidata, img_size);
00199                 if(fwrite(uidata, sizeof(unsigned int), img_size, df3file) != img_size) {
00200                         throw ImageWriteException(filename, "DF3 unsigned int data");
00201                 }
00202                 if(uidata) {delete [] uidata; uidata=0;}
00203                 break;
00204         case EMUtil::EM_USHORT:
00205                 usdata = new unsigned short[img_size];
00206                 for (size_t i = 0; i < img_size; ++i) {
00207                         if(data[i] <= rendermin) {
00208                                 usdata[i] = 0;
00209                         }
00210                         else if(data[i] >= rendermax) {
00211                                 usdata[i] = USHRT_MAX;
00212                         }
00213                         else {
00214                                 usdata[i]=(unsigned short)((data[i]-rendermin)/(rendermax-rendermin)*USHRT_MAX);
00215                         }
00216                 }
00217                 ByteOrder::become_big_endian(usdata, img_size);
00218                 if(fwrite(usdata, sizeof(unsigned short), img_size, df3file) != img_size) {
00219                         throw ImageWriteException(filename, "DF3 unsigned short data");
00220                 }
00221                 if(usdata) {delete [] usdata; usdata=0;}
00222                 break;
00223         case EMUtil::EM_UCHAR:
00224                 ucdata = new unsigned char[img_size];
00225                 for (size_t i = 0; i < img_size; ++i) {
00226                         if(data[i] <= rendermin) {
00227                                 ucdata[i] = 0;
00228                         }
00229                         else if(data[i] >= rendermax){
00230                                 ucdata[i] = UCHAR_MAX;
00231                         }
00232                         else {
00233                                 ucdata[i]=(unsigned char)((data[i]-rendermin)/(rendermax-rendermin)*UCHAR_MAX);
00234                         }
00235                 }
00236                 if(fwrite(ucdata, sizeof(unsigned char), img_size, df3file) != img_size) {
00237                         throw ImageWriteException(filename, "DF3 unsigned char data");
00238                 }
00239                 if(ucdata) {delete [] ucdata; ucdata=0;}
00240                 break;
00241         default:
00242                 throw ImageWriteException(filename,"DF3 does not support this data format");
00243         }
00244 
00245         EXITFUNC;
00246         return 0;
00247 }
00248 
00249 void Df3IO::flush()
00250 {
00251         fflush(df3file);
00252 }
00253 
00254 bool Df3IO::is_image_big_endian()
00255 {
00256         return true;    //DF3 file is always big endian
00257 }
00258 
00259 bool Df3IO::is_complex_mode()
00260 {
00261         return false;   //DF3 only support real image
00262 }
00263 
00264 bool Df3IO::is_valid(const void *first_block, off_t file_size)
00265 {
00266         ENTERFUNC;
00267 
00268         if (!first_block) {
00269                 return false;
00270         }
00271 
00272         const unsigned short *data = static_cast < const unsigned short *>(first_block);
00273         unsigned short nx = data[0];
00274         unsigned short ny = data[1];
00275         unsigned short nz = data[2];
00276 
00277         if(ByteOrder::is_data_big_endian(&nx) && ByteOrder::is_data_big_endian(&ny) && ByteOrder::is_data_big_endian(&nz)) {
00278                 return true;
00279         }
00280 
00281         EXITFUNC;
00282         return false;
00283 }

Generated on Thu Dec 9 13:45:44 2010 for EMAN2 by  doxygen 1.3.9.1