EMAN2
df3io.cpp
Go to the documentation of this file.
1/*
2 * Author: Grant Tang, 08/06/2010 (gtang@bcm.edu)
3 * Copyright (c) 2000-2010 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 <algorithm>
33#include <climits>
34
35#include "df3io.h"
36#include "portable_fileio.h"
37
38using namespace EMAN;
39
40Df3IO::Df3IO(const string & fname, IOMode rw)
41: ImageIO(fname, rw),
42 is_new_file(false), rendermin(0.0), rendermax(0.0), renderbits(16)
43{
44}
45
47{
48 if (file) {
49 fclose(file);
50 file = 0;
51 }
52}
53
54void Df3IO::init()
55{
57 if (initialized) {
58 return;
59 }
60
61 initialized = true;
63
65}
66
67// header is 3 MSB unsigned shorts (nx,ny,nz) in big-endian
68int Df3IO::read_header(Dict & dict, int, const Region *, bool )
69{
71 init();
72 size_t nr;
73
74 if (!is_new_file) {
75 if (fread(&nx, sizeof(unsigned short), 1, file) != 1) {
76 throw ImageReadException(filename, "DF3 header");
77 }
78
79 nr = fread(&ny, sizeof(unsigned short), 1, file); nr++;
80 nr = fread(&nz, sizeof(unsigned short), 1, file); nr++;
81
86 }
87
88 dict["nx"] = (int)nx;
89 dict["ny"] = (int)ny;
90 dict["nz"] = (int)nz;
91 }
92
94 return 0;
95}
96
97int Df3IO::write_header(const Dict & dict, int, const Region*, EMUtil::EMDataType, bool)
98{
100 init();
101
102 nx = (unsigned short)((int)dict["nx"]);
103 ny = (unsigned short)((int)dict["ny"]);
104 nz = (unsigned short)((int)dict["nz"]);
105
106 portable_fseek(file, 0, SEEK_SET);
107
108 unsigned short df3header[3];
109 df3header[0] = nx;
110 df3header[1] = ny;
111 df3header[2] = nz;
112 ByteOrder::become_big_endian(df3header, 3);
113
115
116 if(fwrite(df3header, sizeof(unsigned short), 3, file) != 3) {
117 throw ImageWriteException(filename, "DF3 header");
118 }
119
120 EXITFUNC;
121 return 0;
122}
123
124int Df3IO::read_data(float *rdata, int, const Region *, bool)
125{
126 ENTERFUNC;
127
128 size_t image_size = (size_t)nx*ny*nz;
129 size_t nr;
130
131 // obtain file size:
132 portable_fseek (file , 0 , SEEK_END);
133 size_t fsize = ftell (file);
134 rewind (file);
135
136 unsigned int * uidata = 0;
137 unsigned short * usdata = 0;
138 unsigned char * ucdata = 0;
139
140 portable_fseek(file, sizeof(unsigned short)*3, SEEK_SET); //skip header
141 switch(fsize/image_size) {
142 case sizeof(unsigned int):
143 uidata = new unsigned int[image_size];
144 nr = fread(uidata, sizeof(unsigned int), image_size, file); nr++;
145 become_host_endian < unsigned int >(uidata, image_size);
146 std::copy(uidata, uidata+image_size, rdata);
147 if(uidata) {delete [] uidata; uidata=0;}
148 break;
149 case sizeof(unsigned short):
150 usdata = new unsigned short[image_size];
151 nr = fread(usdata, sizeof(unsigned short), image_size, file); nr++;
152 become_host_endian < unsigned short >(usdata, image_size);
153 std::copy(usdata, usdata+image_size, rdata);
154 if(usdata) {delete [] usdata; usdata=0;}
155 break;
156 case sizeof(unsigned char):
157 ucdata = new unsigned char[image_size];
158 nr = fread(ucdata, sizeof(unsigned char), image_size, file); nr++;
159 std::copy(ucdata, ucdata+image_size, rdata);
160 if(ucdata) {delete [] ucdata; ucdata=0;}
161 break;
162 default:
163 throw ImageReadException(filename, "DF3 does not support this kind of data type.");
164 }
165
166 EXITFUNC;
167 return 0;
168}
169
170int Df3IO::write_data(float *data, int, const Region*,
171 EMUtil::EMDataType dt, bool)
172{
173 ENTERFUNC;
174
175 size_t img_size = (size_t)nx*ny*nz;
176 unsigned int * uidata = 0;
177 unsigned short * usdata = 0;
178 unsigned char * ucdata = 0;
179
180 int truebits=EMDataTypeBits[(int)dt];
181 if (renderbits==0 || renderbits>truebits) renderbits=truebits;
183
184 switch(dt) {
185 case EMUtil::EM_UINT:
186 uidata = new unsigned int[img_size];
187 for (size_t i = 0; i < img_size; ++i) {
188 if(data[i] <= rendermin) {
189 uidata[i] = 0;
190 }
191 else if(data[i] >= rendermax) {
192 uidata[i] = UINT_MAX;
193 }
194 else {
195 uidata[i]=(unsigned int)((data[i]-rendermin)/(rendermax-rendermin)*UINT_MAX);
196 }
197 }
198 ByteOrder::become_big_endian(uidata, img_size);
199 if(fwrite(uidata, sizeof(unsigned int), img_size, file) != img_size) {
200 throw ImageWriteException(filename, "DF3 unsigned int data");
201 }
202 if(uidata) {delete [] uidata; uidata=0;}
203 break;
205 usdata = new unsigned short[img_size];
206 for (size_t i = 0; i < img_size; ++i) {
207 if(data[i] <= rendermin) {
208 usdata[i] = 0;
209 }
210 else if(data[i] >= rendermax) {
211 usdata[i] = USHRT_MAX;
212 }
213 else {
214 usdata[i]=(unsigned short)((data[i]-rendermin)/(rendermax-rendermin)*USHRT_MAX);
215 }
216 }
217 ByteOrder::become_big_endian(usdata, img_size);
218 if(fwrite(usdata, sizeof(unsigned short), img_size, file) != img_size) {
219 throw ImageWriteException(filename, "DF3 unsigned short data");
220 }
221 if(usdata) {delete [] usdata; usdata=0;}
222 break;
223 case EMUtil::EM_UCHAR:
224 ucdata = new unsigned char[img_size];
225 for (size_t i = 0; i < img_size; ++i) {
226 if(data[i] <= rendermin) {
227 ucdata[i] = 0;
228 }
229 else if(data[i] >= rendermax){
230 ucdata[i] = UCHAR_MAX;
231 }
232 else {
233 ucdata[i]=(unsigned char)((data[i]-rendermin)/(rendermax-rendermin)*UCHAR_MAX);
234 }
235 }
236 if(fwrite(ucdata, sizeof(unsigned char), img_size, file) != img_size) {
237 throw ImageWriteException(filename, "DF3 unsigned char data");
238 }
239 if(ucdata) {delete [] ucdata; ucdata=0;}
240 break;
241 default:
242 throw ImageWriteException(filename,"DF3 does not support this data format");
243 }
244
245 EXITFUNC;
246 return 0;
247}
248
249void Df3IO::flush()
250{
251 fflush(file);
252}
253
255{
256 return true; //DF3 file is always big endian
257}
258
260{
261 return false; //DF3 only support real image
262}
263
264bool Df3IO::is_valid(const void *first_block, off_t)
265{
266 ENTERFUNC;
267
268 if (!first_block) {
269 return false;
270 }
271
272 const unsigned short *data = static_cast < const unsigned short *>(first_block);
273 unsigned short nx = data[0];
274 unsigned short ny = data[1];
275 unsigned short nz = data[2];
276
278 return true;
279 }
280
281 EXITFUNC;
282 return false;
283}
#define rdata(i)
Definition: analyzer.cpp:592
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
static void become_big_endian(T *data, size_t n=1)
convert data from host byte order to big endian order.
Definition: byteorder.h:112
float rendermin
Definition: df3io.h:65
unsigned short ny
Definition: df3io.h:63
bool is_new_file
Definition: df3io.h:64
float rendermax
Definition: df3io.h:66
unsigned short nx
Definition: df3io.h:63
static bool is_valid(const void *first_block, off_t file_size=0)
Definition: df3io.cpp:264
int renderbits
Definition: df3io.h:67
unsigned short nz
Definition: df3io.h:63
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
@ EM_UCHAR
Definition: emutil.h:95
@ EM_USHORT
Definition: emutil.h:97
static void getRenderMinMax(float *data, const int nx, const int ny, float &rendermin, float &rendermax, int &renderbits, const int nz=1)
Calculate the min and max pixel value accepted for image nomalization, if we did not get them from im...
Definition: emutil.cpp:1706
static void getRenderLimits(const Dict &dict, float &rendermin, float &rendermax, int &renderbits)
Get the min and max pixel value accepted for image nomalization from image attribute dictionary,...
Definition: emutil.cpp:1689
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
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
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.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
#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
const int EMDataTypeBits[]
Definition: emutil.h:82
int portable_fseek(FILE *fp, off_t offset, int whence)