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         image_index = 0;
00119         check_read_access(image_index);
00120 
00121         int xlen = 0, ylen = 0, zlen = 0;
00122         EMUtil::get_region_dims(area, efh.nx, &xlen, efh.ny, &ylen, efh.nz, &zlen);
00123 
00124         dict["nx"] = xlen;
00125         dict["ny"] = ylen;
00126         dict["nz"] = zlen;
00127 
00128         dict["datatype"] = EMUtil::EM_FLOAT;
00129         dict["pixel"] = efh.pixel;
00130 
00131         off_t imgsize = (off_t)efh.nx * (off_t)efh.ny * (off_t)efh.nz * (off_t)sizeof(float) + (off_t)sizeof(EmimImageHeader);
00132         off_t offset = (off_t)sizeof(EmimFileHeader) + imgsize * (off_t)image_index;
00133 
00134         portable_fseek(emim_file, offset, SEEK_SET);
00135 
00136         EmimImageHeader eih;
00137         fread(&eih, sizeof(EmimImageHeader), 1, emim_file);
00138 
00139         int n = eih.mgnum;
00140         become_host_endian(&n);
00141 
00142         char mgnum[32];
00143         sprintf(mgnum, "%d", n);
00144 
00145         dict["micrograph_id"] = mgnum;
00146         EXITFUNC;
00147         return 0;
00148 
00149 }
00150 
00151 int EmimIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00152 {
00153         ENTERFUNC;
00154         LOGWARN("EMIM write header is not supported.");
00155         EXITFUNC;
00156         return 1;
00157 }
00158 
00159 int EmimIO::read_data(float *data, int image_index, const Region * area, bool)
00160 {
00161         ENTERFUNC;
00162         int err = 0;
00163         //single image format, index can only be zero
00164         image_index = 0;
00165         check_read_access(image_index, data);
00166         
00167         off_t imgsize = (off_t)efh.nx * (off_t)efh.ny * (off_t)efh.nz * (off_t)sizeof(float) + (off_t)sizeof(EmimImageHeader);
00168         off_t offset = (off_t)sizeof(EmimFileHeader) + imgsize * (off_t)(image_index+1);
00169         portable_fseek(emim_file, offset, SEEK_SET);
00170                 
00171         unsigned char *cdata = (unsigned char *) data;
00172         EMUtil::process_region_io(cdata, emim_file, READ_ONLY, 0, sizeof(float),
00173                                                           efh.nx, efh.ny, efh.nz, area);
00174                 
00175         become_host_endian(data, efh.nx * efh.ny * efh.nz);
00176                 
00177         
00178         EXITFUNC;
00179         return err;
00180 }
00181 
00182 int EmimIO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00183 {
00184         ENTERFUNC;
00185         LOGWARN("EMIM write data is not supported.");
00186         EXITFUNC;
00187         return 1;
00188 }
00189 
00190 void EmimIO::flush()
00191 {
00192 }
00193 
00194 bool EmimIO::is_complex_mode()
00195 {
00196         init();
00197         if (efh.flag & EMIM_COMPLEX) {
00198                 return true;
00199         }
00200         return false;
00201 }
00202 
00203 bool EmimIO::is_image_big_endian()
00204 {
00205         init();
00206         return is_big_endian;
00207 }
00208 
00209 int EmimIO::get_nimg()
00210 {
00211         init();
00212         return efh.count;
00213 }

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