EMAN2
lstfastio.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#ifndef WIN32
33#include <sys/param.h>
34#include <unistd.h>
35#else
36#include <direct.h>
37#include <windows.h>
38#define M_PI 3.14159265358979323846f
39#define MAXPATHLEN (MAX_PATH*4)
40#endif
41
42#include <cstdio>
43#include <cstring>
44#include "lstfastio.h"
45#include "util.h"
46
47
48using namespace EMAN;
49
50const char *LstFastIO::MAGIC = "#LSX";
51
52LstFastIO::LstFastIO(const string & fname, IOMode rw)
53: ImageIO(fname, rw)
54{
56 nimg = 0;
57 imageio = 0;
58 ref_filename = "";
59 last_lst_index = -1;
60 last_ref_index = -1;
61}
62
64{
65 if (file) {
66 fclose(file);
67 file = 0;
68 }
69 ref_filename = "";
70 if(imageio) {
71 delete imageio;
72 imageio = 0;
73 }
74}
75
76void LstFastIO::init()
77{
79 if (initialized) {
80 return ;
81 }
82
83 initialized = true;
84
85 bool is_new_file = false;
86 file = sfopen(filename, rw_mode, &is_new_file);
87
88 if (!is_new_file) {
89
90 char buf[MAXPATHLEN];
91
92 if (!fgets(buf, MAXPATHLEN, file)) {
93 throw ImageReadException(filename, "first block");
94 }
95
96 if (!is_valid(&buf)) {
97 throw ImageReadException(filename, "invalid LST file");
98 }
99
100 fgets(buf,MAXPATHLEN,file);
101 fgets(buf,MAXPATHLEN,file);
102 line_length=atoi(buf+1);
103 head_length=ftell(file);
104 fseek(file,0L,SEEK_END);
106 rewind(file);
107 }
108 EXITFUNC;
109}
110
111bool LstFastIO::is_valid(const void *first_block)
112{
113 ENTERFUNC;
114 bool result = false;
115
116 if (!first_block) {
117 result = false;
118 }
119 else {
120 result = Util::check_file_by_magic(first_block, MAGIC);
121 }
122
123 if (result) {
124 for (int i=0; i<1024; i++) {
125 char c = ((const char *)first_block)[i];
126 if (c==0) break;
127 if (c==13) {
128// printf("%1024s\n",(const char *)first_block);
129 printf("ERROR: .lst file contains \\r at pos %d. This should never happen. (If you edit a .lst file with a text editor on Windows, it will corrupt the file). Aborting program.\n",i);
130 exit(1);
131 }
132 }
133 }
134 EXITFUNC;
135 return result;
136}
137
139{
140 if (image_index == last_lst_index) {
141 return last_ref_index;
142 }
143 else {
144 vector<char> buf(line_length+1);
145
146 fseek(file,head_length+line_length*image_index,SEEK_SET);
147 if (!fgets(buf.data(), line_length, file)) {
148 LOGERR("reach EOF in file '%s' before reading %dth image",
149 filename.c_str(), image_index);
150 return 1;
151 }
152
153 int ref_image_index = 0;
154 char ref_image_path[MAXPATHLEN];
155 vector<char> unused(line_length);
156 sscanf(buf.data(), " %d %s %[ .,0-9-]", &ref_image_index, ref_image_path, unused.data());
157 string newrefname = string(ref_image_path);
158 if (newrefname.compare(ref_filename)==0) { // use the existing imageio when possible, TODO: cache a few?
160 } else {
161 ref_filename = newrefname;
163 if (imageio!=0) delete imageio;
165 }
166 last_ref_index = ref_image_index;
167 }
168// printf("%d\t%d\t%s\n",image_index,last_ref_index,ref_filename.c_str());
169
170 last_lst_index = image_index;
171
172 return last_ref_index;
173}
174
175
176int LstFastIO::read_header(Dict & dict, int image_index, const Region * area, bool is_3d)
177{
178 ENTERFUNC;
179 check_read_access(image_index);
180 int ref_image_index = calc_ref_image_index(image_index);
181 int err = imageio->read_header(dict, ref_image_index, area, is_3d);
182 dict.put("data_source",ref_filename);
183 dict.put("data_n",ref_image_index);
184 EXITFUNC;
185 return err;
186}
187
188int LstFastIO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
189{
190 ENTERFUNC;
191 fprintf(file, "%s\n# 80\n", MAGIC);
192 EXITFUNC;
193 return 0;
194}
195
196int LstFastIO::read_data(float *data, int image_index, const Region * area, bool is_3d)
197{
198 ENTERFUNC;
199 check_read_access(image_index, data);
200 int ref_image_index = calc_ref_image_index(image_index);
201 int err = imageio->read_data(data, ref_image_index, area, is_3d);
202 EXITFUNC;
203 return err;
204}
205
206int LstFastIO::write_data(float *data, int, const Region* , EMUtil::EMDataType, bool)
207{
208 ENTERFUNC;
209 char *data2=(char*)data;
210 if (strlen(data2)>line_length-1) throw ImageWriteException("", "Comment too long for this LSX file");
211 fprintf(file, "%s", (char*)data);
212 for (unsigned int i=strlen(data2); i<line_length-1; i++) putc(' ',file);
213 putc('\n',file);
214
215 EXITFUNC;
216 return 0;
217}
218
219void LstFastIO::flush()
220{
221 fflush(file);
222}
223
225{
226 return false;
227}
228
230{
231 init();
232 return is_big_endian;
233}
234
236{
237 init();
238 return nimg;
239}
static bool is_host_big_endian()
Definition: byteorder.cpp:40
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
void put(const string &key, EMObject val)
Put the value/key pair into the dictionary probably better to just use operator[].
Definition: emobject.h:545
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
static ImageIO * get_imageio(const string &filename, int rw_mode, ImageType image_type=IMAGE_UNKNOWN)
Get an ImageIO object.
Definition: emutil.cpp:558
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
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.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
unsigned int line_length
Definition: lstfastio.h:71
unsigned int head_length
Definition: lstfastio.h:72
static bool is_valid(const void *first_block)
Definition: lstfastio.cpp:111
int get_nimg()
Return the number of images in this image file.
Definition: lstfastio.cpp:235
int calc_ref_image_index(int image_index)
Definition: lstfastio.cpp:138
bool is_big_endian
Definition: lstfastio.h:69
string ref_filename
Definition: lstfastio.h:75
static const char * MAGIC
Definition: lstfastio.h:81
int last_lst_index
Definition: lstfastio.h:77
ImageIO * imageio
Definition: lstfastio.h:74
int last_ref_index
Definition: lstfastio.h:78
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
static bool is_file_exist(const string &filename)
check whether a file exists or not
Definition: util.cpp:253
static bool check_file_by_magic(const void *first_block, const char *magic)
check whether a file starts with certain magic string.
Definition: util.cpp:239
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define FileAccessException(filename)
Definition: exception.h:187
#define ImageWriteException(imagename, desc)
Definition: exception.h:223
#define LOGERR
Definition: log.h:51
#define ENTERFUNC
Definition: log.h:48
#define EXITFUNC
Definition: log.h:49
E2Exception class.
Definition: aligner.h:40