1f2ca8ec
David Mayerich
added files for b...
|
1
2
|
//make sure that this header file is only loaded once
|
180d7f3a
David Mayerich
added binary file...
|
3
4
5
|
#ifndef RTS_BINARY_H
#define RTS_BINARY_H
|
e8eb202f
David Mayerich
added a new ENVI ...
|
6
|
#include "../envi/envi_header.h"
|
4dcc9392
heziqi
Ziqi's first chan...
|
7
|
#include "../math/vector.h"
|
180d7f3a
David Mayerich
added binary file...
|
8
9
10
|
#include <fstream>
#include <sys/stat.h>
|
8a86bd56
David Mayerich
changed rts names...
|
11
|
namespace stim{
|
180d7f3a
David Mayerich
added binary file...
|
12
|
|
33d7d3cf
David Mayerich
documentation for...
|
13
14
15
16
17
18
19
|
/** This class manages the streaming of large multidimensional binary files.
* Generally these are hyperspectral files with 2 spatial and 1 spectral dimension. However, this class supports
* other dimensions via the template parameter D.
*
* @param T is the data type used to store data to disk (generally float or double)
* @param D is the dimension of the data (default 3)
*/
|
180d7f3a
David Mayerich
added binary file...
|
20
21
22
23
|
template< typename T, unsigned int D = 3 >
class binary{
protected:
|
180d7f3a
David Mayerich
added binary file...
|
24
25
26
|
std::fstream file; //file stream used for reading and writing
std::string name; //file name
|
193ff00e
David Mayerich
dealth with preci...
|
27
|
unsigned long long int R[D]; //resolution
|
180d7f3a
David Mayerich
added binary file...
|
28
|
unsigned int header; //header size (in bytes)
|
f4c5d71b
David Mayerich
started working w...
|
29
|
unsigned char* mask; //pointer to a character array: 0 = background, 1 = foreground (or valid data)
|
180d7f3a
David Mayerich
added binary file...
|
30
31
|
|
ee4dea28
David Mayerich
fixed errors in c...
|
32
33
|
|
33d7d3cf
David Mayerich
documentation for...
|
34
|
/// Private initialization function used to set default parameters in the data structure.
|
180d7f3a
David Mayerich
added binary file...
|
35
36
37
|
void init(){
memset(R, 0, sizeof(unsigned int) * D); //initialize the resolution to zero
header = 0; //initialize the header size to zero
|
f4c5d71b
David Mayerich
started working w...
|
38
|
mask = NULL;
|
180d7f3a
David Mayerich
added binary file...
|
39
40
|
}
|
33d7d3cf
David Mayerich
documentation for...
|
41
|
/// Private helper function that returns the size of the file on disk using system functions.
|
b0fee590
heziqi
convert long int ...
|
42
|
long long int get_file_size(){
|
193ff00e
David Mayerich
dealth with preci...
|
43
|
#ifdef _WIN32
|
b0fee590
heziqi
convert long int ...
|
44
45
|
struct _stat64 results;
if(_stat64(name.c_str(), &results) == 0)
|
180d7f3a
David Mayerich
added binary file...
|
46
|
return results.st_size;
|
193ff00e
David Mayerich
dealth with preci...
|
47
48
49
50
51
|
#else
struct stat results;
if(stat(name.c_str(), &results) == 0)
return results.st_size;
#endif
|
180d7f3a
David Mayerich
added binary file...
|
52
53
54
|
else return 0;
}
|
33d7d3cf
David Mayerich
documentation for...
|
55
|
/// Private helper function that tests to make sure that the calculated data size specified by the structure is the same as the data size on disk.
|
180d7f3a
David Mayerich
added binary file...
|
56
|
bool test_file_size(){
|
b0fee590
heziqi
convert long int ...
|
57
|
long long int npts = 1; //initialize the number of data points to 1
|
87da9adc
David Mayerich
fixed issues with...
|
58
59
|
for(unsigned int i = 0; i<D; i++) //iterate over each dimension
npts *= R[i]; //compute the total number of data points in the file
|
b0fee590
heziqi
convert long int ...
|
60
|
long long int datasize = npts * sizeof(T);//multiply the sum by the size of the template parameter
|
87da9adc
David Mayerich
fixed issues with...
|
61
62
|
if(datasize + header == get_file_size()) return true; //if the byte size matches the file size, we're golden
|
180d7f3a
David Mayerich
added binary file...
|
63
64
65
66
|
else return false; //otherwise return an error
}
|
33d7d3cf
David Mayerich
documentation for...
|
67
68
69
|
/// Private helper file that opens a specified binary file.
/// @param filename is the name of the binary file to stream
|
180d7f3a
David Mayerich
added binary file...
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
bool open_file(std::string filename){
//open the file as binary for reading and writing
file.open(filename.c_str(), std::ios::in | std::ios::out | std::ios::binary);
//if the file is successful
if(file){
name = filename; //set the name
if(test_file_size()) //test the file size
return true;
}
return false;
}
public:
|
33d7d3cf
David Mayerich
documentation for...
|
86
87
88
89
90
|
/// Open a binary file for streaming.
/// @param filename is the name of the binary file
/// @param r is a STIM vector specifying the size of the binary file along each dimension
/// @param h is the length (in bytes) of any header file (default zero)
|
180d7f3a
David Mayerich
added binary file...
|
91
|
bool open(std::string filename, vec<unsigned int, D> r, unsigned int h = 0){
|
180d7f3a
David Mayerich
added binary file...
|
92
|
|
87da9adc
David Mayerich
fixed issues with...
|
93
|
for(unsigned int i = 0; i < D; i++) //set the dimensions of the binary file object
|
180d7f3a
David Mayerich
added binary file...
|
94
95
|
R[i] = r[i];
|
87da9adc
David Mayerich
fixed issues with...
|
96
97
98
|
header = h; //save the header size
if(!open_file(filename)) return false; //open the binary file
|
180d7f3a
David Mayerich
added binary file...
|
99
100
101
102
|
return test_file_size();
}
|
33d7d3cf
David Mayerich
documentation for...
|
103
104
105
106
107
|
/// Creates a new binary file for streaming
/// @param filename is the name of the binary file to be created
/// @param r is a STIM vector specifying the size of the file along each dimension
/// @offset specifies how many bytes to offset the file (used to leave room for a header)
|
f47168a2
heziqi
Ziqi added create...
|
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
bool create(std::string filename, vec<unsigned int, D> r, unsigned int offset = 0){
std::ofstream target(filename.c_str(), std::ios::binary);
//initialize binary file
T p = 0;
for(unsigned int i =0; i < r[0] * r[1] * r[2]; i++){
target.write((char*)(&p), sizeof(T));
}
for(unsigned int i = 0; i < D; i++) //set the dimensions of the binary file object
R[i] = r[i];
header = offset; //save the header size
if(!open_file(filename)) return false; //open the binary file
return test_file_size();
}
|
33d7d3cf
David Mayerich
documentation for...
|
128
129
130
131
|
/// Writes a single page of data to disk. A page consists of a sequence of data of size R[0] * R[1] * ... * R[D-1].
/// @param p is a pointer to the data to be written
/// @param page is the page number (index of the highest-numbered dimension)
|
8157c392
David Mayerich
added parser and ...
|
132
|
bool write_page( T * p, unsigned int page){
|
f47168a2
heziqi
Ziqi added create...
|
133
134
135
136
137
138
|
if(p == NULL){
std::cout<<"ERROR: unable to write into file, empty pointer"<<std::endl;
exit(1);
}
|
8157c392
David Mayerich
added parser and ...
|
139
140
|
file.seekg(R[1] * R[0] * page * sizeof(T), std::ios::beg); //seek to the desired location on disk
file.write((char *)p, R[0] * R[1] * sizeof(T)); //write binary data
|
f47168a2
heziqi
Ziqi added create...
|
141
142
143
144
|
return true;
}
|
33d7d3cf
David Mayerich
documentation for...
|
145
146
147
148
|
/// Reads a page from disk. A page consists of a sequence of data of size R[0] * R[1] * ... * R[D-1].
/// @param p is a pointer to pre-allocated memory equal to the page size
/// @param page is the index of the page
|
8157c392
David Mayerich
added parser and ...
|
149
|
bool read_page( T * p, unsigned int page){
|
c7da85e3
heziqi
he,ziqi add metho...
|
150
|
|
5d5ce39a
heziqi
Ziqi convert the ...
|
151
|
if (page >= R[2]){ //make sure the bank number is right
|
2ad0ce4f
David Mayerich
syntactic edits b...
|
152
|
std::cout<<"ERROR: page out of range"<<std::endl;
|
5d5ce39a
heziqi
Ziqi convert the ...
|
153
|
return false;
|
c7da85e3
heziqi
he,ziqi add metho...
|
154
155
|
}
|
3b972fb3
David Mayerich
wrote a general f...
|
156
|
file.seekg(R[1] * R[0] * page * sizeof(T), std::ios::beg); //write into memory from the binary file
|
2ad0ce4f
David Mayerich
syntactic edits b...
|
157
|
file.read((char *)p, R[0] * R[1] * sizeof(T));
|
c7da85e3
heziqi
he,ziqi add metho...
|
158
|
|
5d5ce39a
heziqi
Ziqi convert the ...
|
159
|
return true;
|
c7da85e3
heziqi
he,ziqi add metho...
|
160
161
|
}
|
3b972fb3
David Mayerich
wrote a general f...
|
162
|
//saves a hyperplane orthogonal to dimension d at intersection n
|
8157c392
David Mayerich
added parser and ...
|
163
|
bool read_plane(T * dest, unsigned int d, unsigned int n){
|
3b972fb3
David Mayerich
wrote a general f...
|
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
//reset the file pointer back to the beginning of the file
file.seekg(0, std::ios::beg);
//compute the contiguous size C for each readable block
unsigned int C = 1;
for(unsigned int i = 0; i < d; i++) //for each dimension less than d
C *= R[i]; //compute the product
//compute the non-contiguous size NC for each readable block
unsigned int NC = 1;
for(unsigned int i = d + 1; i < D; i++)
NC *= R[i];
//for all noncontiguous blocks, read each contiguous block that makes up the hyper-plane
for(unsigned int nc = 0; nc < NC; nc++){
file.seekg(n * C * sizeof(T), std::ios::cur); //skip n contiguous blocks
file.read( (char*)&dest[nc * C], C * sizeof(T)); //read one contiguous block
file.seekg( (R[d] - n - 1) * C * sizeof(T), std::ios::cur); //skip R[d] - n contiguous blocks
}
return true;
}
|
5d5ce39a
heziqi
Ziqi convert the ...
|
189
|
//save one pixel of the file into the memory, and return the pointer
|
8157c392
David Mayerich
added parser and ...
|
190
|
bool read_spectrum(T * p, unsigned x, unsigned y){
|
c7da85e3
heziqi
he,ziqi add metho...
|
191
|
|
c7da85e3
heziqi
he,ziqi add metho...
|
192
193
|
unsigned int i;
|
5d5ce39a
heziqi
Ziqi convert the ...
|
194
195
196
|
if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right
std::cout<<"ERROR: sample or line out of range"<<std::endl;
return false;
|
51f94485
heziqi
Ziqi added saveZ,...
|
197
198
|
}
|
3b972fb3
David Mayerich
wrote a general f...
|
199
|
file.seekg((x + y * R[0]) * sizeof(T), std::ios::beg); //point to the certain sample and line
|
5d5ce39a
heziqi
Ziqi convert the ...
|
200
|
for (i = 0; i < R[2]; i++)
|
c7da85e3
heziqi
he,ziqi add metho...
|
201
|
{
|
5d5ce39a
heziqi
Ziqi convert the ...
|
202
|
file.read((char *)(p + i), sizeof(T));
|
3b972fb3
David Mayerich
wrote a general f...
|
203
|
file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band
|
c7da85e3
heziqi
he,ziqi add metho...
|
204
205
|
}
|
5d5ce39a
heziqi
Ziqi convert the ...
|
206
|
return true;
|
c7da85e3
heziqi
he,ziqi add metho...
|
207
208
|
}
|
180d7f3a
David Mayerich
added binary file...
|
209
210
211
212
213
214
|
};
}
#endif
|