EMAN2
icosio.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 "icosio.h"
00038 #include "portable_fileio.h"
00039 #include "geometry.h"
00040 
00041 using namespace EMAN;
00042 
00043 
00044 IcosIO::IcosIO(const string & file, IOMode rw)
00045 :       filename(file), rw_mode(rw), icos_file(0), initialized(false)
00046 {
00047         is_big_endian = ByteOrder::is_host_big_endian();
00048         is_new_file = false;
00049         memset(&icosh, 0, sizeof(IcosHeader));
00050 }
00051 
00052 IcosIO::~IcosIO()
00053 {
00054         if (icos_file) {
00055                 fclose(icos_file);
00056                 icos_file = 0;
00057         }
00058 }
00059 
00060 void IcosIO::init()
00061 {
00062         ENTERFUNC;
00063         if (initialized) {
00064                 return ;
00065         }
00066 
00067         initialized = true;
00068         icos_file = sfopen(filename, rw_mode, &is_new_file);
00069 
00070         if (!is_new_file) {
00071                 if (fread(&icosh, sizeof(IcosHeader), 1, icos_file) != 1) {
00072                         throw ImageReadException(filename, "ICOS header");
00073                 }
00074 
00075                 if (!is_valid(&icosh)) {
00076                         throw ImageReadException(filename, "invalid ICOS file");
00077                 }
00078                 is_big_endian = ByteOrder::is_data_big_endian(&icosh.stamp);
00079                 become_host_endian((int *) &icosh, sizeof(IcosHeader) / sizeof(int));
00080         }
00081         EXITFUNC;
00082 }
00083 
00084 bool IcosIO::is_valid(const void *first_block)
00085 {
00086         ENTERFUNC;
00087         bool result = false;
00088         if (!first_block) {
00089                 result = false;
00090         }
00091         else {
00092                 const int *data = static_cast < const int *>(first_block);
00093                 int stamp = data[0];
00094                 int stamp1 = data[19];
00095                 int stamp2 = data[20];
00096                 int stamp3 = data[26];
00097 
00098                 bool data_big_endian = ByteOrder::is_data_big_endian(&stamp);
00099 
00100                 if (data_big_endian != ByteOrder::is_host_big_endian()) {
00101                         ByteOrder::swap_bytes(&stamp);
00102                         ByteOrder::swap_bytes(&stamp1);
00103                         ByteOrder::swap_bytes(&stamp2);
00104                         ByteOrder::swap_bytes(&stamp3);
00105                 }
00106 
00107                 if (stamp == STAMP && stamp1 == STAMP1 && stamp2 == STAMP2 && stamp3 == STAMP3) {
00108                         result = true;
00109                 }
00110         }
00111         EXITFUNC;
00112         return result;
00113 }
00114 
00115 int IcosIO::read_header(Dict & dict, int image_index, const Region * area, bool)
00116 {
00117         ENTERFUNC;
00118 
00119         //single image format, index can only be zero
00120         if(image_index == -1) {
00121                 image_index = 0;
00122         }
00123 
00124         if(image_index != 0) {
00125                 throw ImageReadException(filename, "no stack allowed for MRC image. For take 2D slice out of 3D image, read the 3D image first, then use get_clip().");
00126         }
00127 
00128         init();
00129 
00130         check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
00131 
00132         int xlen = 0, ylen = 0, zlen = 0;
00133         EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
00134 
00135         dict["nx"] = xlen;
00136         dict["ny"] = ylen;
00137         dict["nz"] = zlen;
00138         dict["datatype"] = EMUtil::EM_FLOAT;
00139         dict["minimum"] = icosh.min;
00140         dict["maximum"] = icosh.max;
00141 
00142         EXITFUNC;
00143         return 0;
00144 }
00145 
00146 int IcosIO::write_header(const Dict & dict, int image_index, const Region* ,
00147                                                  EMUtil::EMDataType, bool)
00148 {
00149         ENTERFUNC;
00150         int err = 0;
00151         //single image format, index can only be zero
00152         if(image_index == -1) {
00153                 image_index = 0;
00154         }
00155         if(image_index != 0) {
00156                 throw ImageWriteException(filename, "ICOS file does not support stack.");
00157         }
00158         check_write_access(rw_mode, image_index, 1);
00159 
00160         icosh.stamp = STAMP;
00161         icosh.stamp1 = STAMP1;
00162         icosh.stamp2 = STAMP2;
00163         icosh.stamp3 = STAMP3;
00164 
00165         icosh.nx = dict["nx"];
00166         icosh.ny = dict["ny"];
00167         icosh.nz = dict["nz"];
00168 
00169         icosh.min = dict["minimum"];
00170         icosh.max = dict["maximum"];
00171 
00172         rewind(icos_file);
00173 
00174         if (fwrite(&icosh, sizeof(IcosHeader), 1, icos_file) != 1) {
00175                 throw ImageWriteException(filename, "ICOS header write");
00176         }
00177 
00178         EXITFUNC;
00179         return err;
00180 }
00181 
00182 int IcosIO::read_data(float *data, int image_index, const Region * area, bool)
00183 {
00184         ENTERFUNC;
00185 
00186         //single image format, index can only be zero
00187         image_index = 0;
00188         check_read_access(image_index, data);
00189         check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
00190 
00191         portable_fseek(icos_file, sizeof(IcosHeader), SEEK_SET);
00192 
00193         EMUtil::process_region_io((unsigned char *) data, icos_file,
00194                                                           READ_ONLY, image_index,
00195                                                           sizeof(float), icosh.nx, icosh.ny, icosh.nz,
00196                                                           area, false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
00197 
00198         int xlen = 0, ylen = 0, zlen = 0;
00199         EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
00200         become_host_endian(data, xlen * ylen * zlen);
00201 
00202 
00203         EXITFUNC;
00204         return 0;
00205 }
00206 
00207 int IcosIO::write_data(float *data, int image_index, const Region* area,
00208                                            EMUtil::EMDataType, bool)
00209 {
00210         ENTERFUNC;
00211         //single image format, index can only be zero
00212         image_index = 0;
00213         check_write_access(rw_mode, image_index, 1, data);
00214         portable_fseek(icos_file, sizeof(IcosHeader), SEEK_SET);
00215 
00216         EMUtil::process_region_io(data, icos_file, rw_mode, image_index,
00217                                                           sizeof(float), icosh.nx, icosh.ny, icosh.nz, area,
00218                                                           false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
00219 
00220 #if 0
00221         size_t float_size = sizeof(float);
00222         int nx = icosh.nx;
00223         float *buf = new float[nx + 2];
00224         buf[0] = (float)float_size * nx;
00225         buf[nx + 1] = buf[0];
00226         int nrows = icosh.ny * icosh.nz;
00227 
00228         int row_size = (nx + 2) * float_size;
00229 
00230 
00231         for (int j = 0; j < nrows; j++) {
00232                 memcpy(&buf[1], &data[nx * j], nx * float_size);
00233                 if (fwrite(buf, row_size, 1, icos_file) != 1) {
00234                         throw ImageWriteException(filename, "ICOS data");
00235                 }
00236         }
00237 
00238         if( buf )
00239         {
00240                 delete[]buf;
00241                 buf = 0;
00242         }
00243 #endif
00244         EXITFUNC;
00245         return 0;
00246 }
00247 
00248 void IcosIO::flush()
00249 {
00250         fflush(icos_file);
00251 }
00252 
00253 bool IcosIO::is_complex_mode()
00254 {
00255         return false;
00256 }
00257 
00258 bool IcosIO::is_image_big_endian()
00259 {
00260         init();
00261         return is_big_endian;
00262 }
00263