EMAN2
icosio.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#include <cstring>
33#include "icosio.h"
34#include "portable_fileio.h"
35#include "geometry.h"
36
37using namespace EMAN;
38
39
40IcosIO::IcosIO(const string & fname, IOMode rw)
41: ImageIO(fname, rw)
42{
44 is_new_file = false;
45 memset(&icosh, 0, sizeof(IcosHeader));
46}
47
49{
50 if (file) {
51 fclose(file);
52 file = 0;
53 }
54}
55
56void IcosIO::init()
57{
59 if (initialized) {
60 return ;
61 }
62
63 initialized = true;
65
66 if (!is_new_file) {
67 if (fread(&icosh, sizeof(IcosHeader), 1, file) != 1) {
68 throw ImageReadException(filename, "ICOS header");
69 }
70
71 if (!is_valid(&icosh)) {
72 throw ImageReadException(filename, "invalid ICOS file");
73 }
75 become_host_endian((int *) &icosh, sizeof(IcosHeader) / sizeof(int));
76 }
78}
79
80bool IcosIO::is_valid(const void *first_block)
81{
83 bool result = false;
84 if (!first_block) {
85 result = false;
86 }
87 else {
88 const int *data = static_cast < const int *>(first_block);
89 int stamp = data[0];
90 int stamp1 = data[19];
91 int stamp2 = data[20];
92 int stamp3 = data[26];
93
94 bool data_big_endian = ByteOrder::is_data_big_endian(&stamp);
95
96 if (data_big_endian != ByteOrder::is_host_big_endian()) {
98 ByteOrder::swap_bytes(&stamp1);
99 ByteOrder::swap_bytes(&stamp2);
100 ByteOrder::swap_bytes(&stamp3);
101 }
102
103 if (stamp == STAMP && stamp1 == STAMP1 && stamp2 == STAMP2 && stamp3 == STAMP3) {
104 result = true;
105 }
106 }
107 EXITFUNC;
108 return result;
109}
110
111int IcosIO::read_header(Dict & dict, int image_index, const Region * area, bool)
112{
113 ENTERFUNC;
114
115 //single image format, index can only be zero
116 if(image_index == -1) {
117 image_index = 0;
118 }
119
120 if(image_index != 0) {
121 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().");
122 }
123
124 init();
125
126 check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
127
128 int xlen = 0, ylen = 0, zlen = 0;
129 EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
130
131 dict["nx"] = xlen;
132 dict["ny"] = ylen;
133 dict["nz"] = zlen;
134 dict["datatype"] = EMUtil::EM_FLOAT;
135 dict["minimum"] = icosh.min;
136 dict["maximum"] = icosh.max;
137
138 EXITFUNC;
139 return 0;
140}
141
142int IcosIO::write_header(const Dict & dict, int image_index, const Region* ,
143 EMUtil::EMDataType, bool)
144{
145 ENTERFUNC;
146 int err = 0;
147 //single image format, index can only be zero
148 if(image_index == -1) {
149 image_index = 0;
150 }
151 if(image_index != 0) {
152 throw ImageWriteException(filename, "ICOS file does not support stack.");
153 }
154 check_write_access(rw_mode, image_index, 1);
155
156 icosh.stamp = STAMP;
160
161 icosh.nx = dict["nx"];
162 icosh.ny = dict["ny"];
163 icosh.nz = dict["nz"];
164
165 icosh.min = dict["minimum"];
166 icosh.max = dict["maximum"];
167
168 rewind(file);
169
170 if (fwrite(&icosh, sizeof(IcosHeader), 1, file) != 1) {
171 throw ImageWriteException(filename, "ICOS header write");
172 }
173
174 EXITFUNC;
175 return err;
176}
177
178int IcosIO::read_data(float *data, int image_index, const Region * area, bool)
179{
180 ENTERFUNC;
181
182 //single image format, index can only be zero
183 image_index = 0;
184 check_read_access(image_index, data);
185 check_region(area, IntSize(icosh.nx, icosh.ny, icosh.nz),false,false);
186
187 portable_fseek(file, sizeof(IcosHeader), SEEK_SET);
188
189 EMUtil::process_region_io((unsigned char *) data, file,
190 READ_ONLY, image_index,
191 sizeof(float), icosh.nx, icosh.ny, icosh.nz,
192 area, false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
193
194 int xlen = 0, ylen = 0, zlen = 0;
195 EMUtil::get_region_dims(area, icosh.nx, &xlen, icosh.ny, &ylen, icosh.nz, &zlen);
196 become_host_endian(data, xlen * ylen * zlen);
197
198
199 EXITFUNC;
200 return 0;
201}
202
203int IcosIO::write_data(float *data, int image_index, const Region* area,
204 EMUtil::EMDataType, bool)
205{
206 ENTERFUNC;
207 //single image format, index can only be zero
208 image_index = 0;
209 check_write_access(rw_mode, image_index, 1, data);
210 portable_fseek(file, sizeof(IcosHeader), SEEK_SET);
211
212 EMUtil::process_region_io(data, file, rw_mode, image_index,
213 sizeof(float), icosh.nx, icosh.ny, icosh.nz, area,
214 false, EMUtil::IMAGE_ICOS, sizeof(int), sizeof(int));
215
216#if 0
217 size_t float_size = sizeof(float);
218 int nx = icosh.nx;
219 float *buf = new float[nx + 2];
220 buf[0] = (float)float_size * nx;
221 buf[nx + 1] = buf[0];
222 int nrows = icosh.ny * icosh.nz;
223
224 int row_size = (nx + 2) * float_size;
225
226
227 for (int j = 0; j < nrows; j++) {
228 memcpy(&buf[1], &data[nx * j], nx * float_size);
229 if (fwrite(buf, row_size, 1, file) != 1) {
230 throw ImageWriteException(filename, "ICOS data");
231 }
232 }
233
234 if( buf )
235 {
236 delete[]buf;
237 buf = 0;
238 }
239#endif
240 EXITFUNC;
241 return 0;
242}
243
244void IcosIO::flush()
245{
246 fflush(file);
247}
248
250{
251 return false;
252}
253
255{
256 init();
257 return is_big_endian;
258}
259
static bool is_host_big_endian()
Definition: byteorder.cpp:40
static void swap_bytes(T *data, size_t n=1)
swap the byte order of data with 'n' T-type elements.
Definition: byteorder.h:131
static bool is_data_big_endian(const T *small_num_addr)
given a pointer to a reasonable small integer number, return whether the number is big endian or not.
Definition: byteorder.h:76
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
static void process_region_io(void *cdata, FILE *file, int rw_mode, int image_index, size_t mode_size, int nx, int ny, int nz=1, const Region *area=0, bool need_flip=false, ImageType imgtype=IMAGE_UNKNOWN, int pre_row=0, int post_row=0)
Process image region IO.
Definition: emutil.cpp:931
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
@ IMAGE_ICOS
Definition: emutil.h:131
static void get_region_dims(const Region *area, int nx, int *area_x, int ny, int *area_y, int nz=1, int *area_z=0)
Get a region's dimensions.
Definition: emutil.cpp:860
bool is_big_endian
Definition: icosio.h:79
static bool is_valid(const void *first_block)
Definition: icosio.cpp:80
IcosHeader icosh
Definition: icosio.h:78
bool is_new_file
Definition: icosio.h:80
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
IOMode rw_mode
Definition: imageio.h:353
string filename
Definition: imageio.h:352
void check_region(const Region *area, const FloatSize &max_size, bool is_new_file=false, bool inbounds_only=true)
Validate image I/O region.
Definition: imageio.cpp:58
virtual void flush()=0
Flush the IO buffer.
virtual int write_header(const Dict &dict, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write a header to an image.
bool initialized
Definition: imageio.h:355
virtual int write_data(float *data, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0
Write data to an image.
virtual bool is_complex_mode()=0
Is this an complex image or not.
virtual int read_header(Dict &dict, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the header from an image.
FILE * sfopen(const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false)
Run fopen safely.
Definition: imageio.cpp:135
void check_read_access(int image_index)
Validate 'image_index' in file reading.
Definition: imageio.cpp:95
virtual int read_data(float *data, int image_index=0, const Region *area=0, bool is_3d=false)=0
Read the data from an image.
FILE * file
Definition: imageio.h:354
virtual void init()=0
Do some initialization before doing the read/write.
void check_write_access(IOMode rw_mode, int image_index, int max_nimg=0)
Validate rw_mode and image_index in file writing.
Definition: imageio.cpp:113
void become_host_endian(T *data, size_t n=1)
Convert data of this image into host endian format.
Definition: imageio.h:261
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
IntSize is used to describe a 1D, 2D or 3D rectangular size in integers.
Definition: geometry.h:49
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define ImageWriteException(imagename, desc)
Definition: exception.h:223
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40
int portable_fseek(FILE *fp, off_t offset, int whence)