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

emimio.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 "emimio.h"
00038 #include "portable_fileio.h"
00039 
00040 using namespace EMAN;
00041 
00042 const char *EmimIO::MAGIC = "EMIM";
00043 
00044 EmimIO::EmimIO(const string & file, IOMode rw)
00045 :       filename(file), rw_mode(rw), emim_file(0), initialized(false)
00046 {
00047         is_big_endian = ByteOrder::is_host_big_endian();
00048         memset(&efh, 0, sizeof(EmimFileHeader));
00049 }
00050 
00051 EmimIO::~EmimIO()
00052 {
00053         if (emim_file) {
00054                 fclose(emim_file);
00055                 emim_file = 0;
00056         }
00057 }
00058 
00059 void EmimIO::init()
00060 {
00061         ENTERFUNC;
00062         if (initialized) {
00063                 return;
00064         }
00065 
00066         initialized = true;
00067         bool is_new_file = false;
00068         emim_file = sfopen(filename, rw_mode, &is_new_file);
00069 
00070         if (!is_new_file) {
00071                 if (fread(&efh, sizeof(EmimFileHeader), 1, emim_file) != 1) {
00072                         throw ImageReadException(filename, "EMIM header");
00073                 }
00074 
00075                 if (!is_valid(&efh)) {
00076                         throw ImageReadException(filename, "invalid EMIM file");
00077                 }
00078 
00079                 become_host_endian((int *) &efh, NUM_INT_IN_FILE_HEADER);
00080                 is_big_endian = ByteOrder::is_data_big_endian(&efh.count);
00081         }
00082 
00083         EXITFUNC;
00084 }
00085 
00086 bool EmimIO::is_valid(const void *first_block)
00087 {
00088         ENTERFUNC;
00089 
00090         if (!first_block) {
00091                 return false;
00092         }
00093 
00094         const char *data = static_cast < const char *>(first_block);
00095         const int *idata = static_cast < const int *>(first_block);
00096         int count = idata[2];
00097 
00098         if (strncmp(data, MAGIC, sizeof(MAGIC)) == 0) {
00099                 bool data_big_endian = ByteOrder::is_data_big_endian(&count);
00100 
00101                 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00102                         ByteOrder::swap_bytes(&count);
00103                 }
00104 
00105                 if (count >= 0 && count <= 1 << 20) {
00106                         return true;
00107                 }
00108         }
00109         EXITFUNC;
00110         return false;
00111 }
00112 
00113 int EmimIO::read_header(Dict & dict, int image_index, const Region * area, bool)
00114 {
00115         ENTERFUNC;
00116 
00117         //single image format, index can only be zero
00118         if(image_index == -1) {
00119                 image_index = 0;
00120         }
00121         image_index = 0;
00122         check_read_access(image_index);
00123 
00124         int xlen = 0, ylen = 0, zlen = 0;
00125         EMUtil::get_region_dims(area, efh.nx, &xlen, efh.ny, &ylen, efh.nz, &zlen);
00126 
00127         dict["nx"] = xlen;
00128         dict["ny"] = ylen;
00129         dict["nz"] = zlen;
00130 
00131         dict["datatype"] = EMUtil::EM_FLOAT;
00132         dict["pixel"] = efh.pixel;
00133 
00134         off_t imgsize = (off_t)efh.nx * (off_t)efh.ny * (off_t)efh.nz * (off_t)sizeof(float) + (off_t)sizeof(EmimImageHeader);
00135         off_t offset = (off_t)sizeof(EmimFileHeader) + imgsize * (off_t)image_index;
00136 
00137         portable_fseek(emim_file, offset, SEEK_SET);
00138 
00139         EmimImageHeader eih;
00140         fread(&eih, sizeof(EmimImageHeader), 1, emim_file);
00141 
00142         int n = eih.mgnum;
00143         become_host_endian(&n);
00144 
00145         char mgnum[32];
00146         sprintf(mgnum, "%d", n);
00147 
00148         dict["micrograph_id"] = mgnum;
00149         EXITFUNC;
00150         return 0;
00151 
00152 }
00153 
00154 int EmimIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00155 {
00156         ENTERFUNC;
00157         LOGWARN("EMIM write header is not supported.");
00158         EXITFUNC;
00159         return 1;
00160 }
00161 
00162 int EmimIO::read_data(float *data, int image_index, const Region * area, bool)
00163 {
00164         ENTERFUNC;
00165         int err = 0;
00166         //single image format, index can only be zero
00167         image_index = 0;
00168         check_read_access(image_index, data);
00169 
00170         off_t imgsize = (off_t)efh.nx * (off_t)efh.ny * (off_t)efh.nz * (off_t)sizeof(float) + (off_t)sizeof(EmimImageHeader);
00171         off_t offset = (off_t)sizeof(EmimFileHeader) + imgsize * (off_t)(image_index+1);
00172         portable_fseek(emim_file, offset, SEEK_SET);
00173 
00174         unsigned char *cdata = (unsigned char *) data;
00175         EMUtil::process_region_io(cdata, emim_file, READ_ONLY, 0, sizeof(float),
00176                                                           efh.nx, efh.ny, efh.nz, area);
00177 
00178         become_host_endian(data, efh.nx * efh.ny * efh.nz);
00179 
00180 
00181         EXITFUNC;
00182         return err;
00183 }
00184 
00185 int EmimIO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00186 {
00187         ENTERFUNC;
00188         LOGWARN("EMIM write data is not supported.");
00189         EXITFUNC;
00190         return 1;
00191 }
00192 
00193 void EmimIO::flush()
00194 {
00195 }
00196 
00197 bool EmimIO::is_complex_mode()
00198 {
00199         init();
00200         if (efh.flag & EMIM_COMPLEX) {
00201                 return true;
00202         }
00203         return false;
00204 }
00205 
00206 bool EmimIO::is_image_big_endian()
00207 {
00208         init();
00209         return is_big_endian;
00210 }
00211 
00212 int EmimIO::get_nimg()
00213 {
00214         init();
00215         return efh.count;
00216 }

Generated on Tue Jun 11 13:46:14 2013 for EMAN2 by  doxygen 1.3.9.1