runMACS
 All Data Structures Files Functions Variables Enumerations Enumerator Macros
Envi.cpp
Go to the documentation of this file.
1 #include "Envi.h"
2 
3 #include <fstream>
4 #include <iostream>
5 
6 #include <cstring>
7 #include <cstdlib>
8 #include <cstdint>
9 
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <sys/mman.h>
13 #include <unistd.h>
14 #include <fcntl.h>
15 
16 EnviFile::EnviFile(const std::string & _filename) :
17  filename(_filename), data(nullptr), fd(-1),
18  width(0), height(0), numFrames(0), bytesPerPixel(0) {
19  loadImage();
20 }
21 
23  EnviFile("") {
24 }
25 
27  closeFile();
28 }
29 
30 unsigned long long EnviFile::getWidth() const { return width; }
31 unsigned long long EnviFile::getHeight() const { return height; }
32 unsigned long long EnviFile::getNumFrames() const { return numFrames; }
33 unsigned int EnviFile::getBytesPerPixel() const { return bytesPerPixel; }
34 double EnviFile::getTint() const { return tint; }
35 double EnviFile::getFps() const { return fps; }
36 
37 void *EnviFile::getDataByFrame(unsigned int frame) const {
38  if(data == nullptr)
39  return NULL;
40  return ((char*)data)+(width*height*bytesPerPixel*frame);
41 }
42 
43 void EnviFile::openFile(const std::string & _filename) {
44  closeFile();
45  filename = _filename;
46  loadImage();
47 }
48 
50  if(fd != -1) {
51  close(fd);
52  fd = -1;
53  }
54  if(data != nullptr) {
55  munmap(data, width*height*numFrames*bytesPerPixel);
56  data = nullptr;
57  }
58 }
59 
60 uint16_t *EnviFile::getAvg() {
61  if(data == nullptr)
62  return NULL;
63  unsigned int i, j, avg;
64  unsigned int dim = width*height;
65  // uint16_t *ret = (uint16_t *)calloc(dim, sizeof(uint16_t));
66  uint16_t *ret = new uint16_t[dim]();
67  switch(interleave) {
68  case Interleave::BIL:
69  for(i=0; i<dim; i++) {
70  avg = 0;
71  for(j=0; j<numFrames; j++)
72  avg+=((uint16_t *)data)[j*dim+i];
73  ret[i] = avg/numFrames;
74  }
75  break;
76  default:
77  std::cerr << "Interleave type not supported!" << std::endl;
78  }
79  return ret;
80 }
81 
82 // PRIVATE
83 
84 void EnviFile::parseHeader() {
85  std::ifstream hdrStream;
86  hdrStream.exceptions(std::ifstream::failbit);
87  try {
88  std::string line;
89  hdrStream.open(filename);
90  // check for signature
91  std::getline(hdrStream, line);
92  if(line.compare(0, 4, "ENVI") !=0)
93  std::cerr << filename << " is not an ENVI header file!" << std::endl;
94 
95  // read width, height and number of frames
96  int ctr=0;
97  while(std::getline(hdrStream,line) && ctr < 5) {
98  if(line.compare(0, 7, "samples") == 0) {
99  auto pos = line.find_last_of(" ");
100  width = atoi(line.substr(pos+1).c_str());
101  ctr++;
102  } else if(line.compare(0, 5, "lines") == 0) {
103  auto pos = line.find_last_of(" ");
104  numFrames = atoi(line.substr(pos+1).c_str());
105  ctr++;
106  } else if(line.compare(0, 5, "bands") == 0) {
107  auto pos = line.find_last_of(" ");
108  height = atoi(line.substr(pos+1).c_str());
109  ctr++;
110  } else if(line.compare(0, 4, "tint") == 0) {
111  auto pos = line.find_last_of("=");
112  tint = strtod(line.substr(pos+1).c_str(), nullptr);
113  ctr++;
114  } else if(line.compare(0, 3, "fps") == 0) {
115  auto pos = line.find_last_of("=");
116  fps = strtod(line.substr(pos+1).c_str(), nullptr);
117  ctr++;
118  }
119  }
120  // interleave and bpp are equal for all cameras, so we hardcode it
121  interleave = Interleave::BIL;
122  bytesPerPixel = 2;
123  }
124  catch(std::ifstream::failure e) {
125  std::cerr << "File " << filename << " not found!" << std::endl;
126  std::cerr << "Error: " << e.what() << std::endl;
127  }
128 
129 #ifdef DEBUG
130  std::cout << "Width: " << width << std::endl;
131  std::cout << "Height: " << height << std::endl;
132  std::cout << "numFrames: " << numFrames << std::endl;
133 #endif // DEBUG
134 
135  hdrStream.close();
136 }
137 
138 void EnviFile::loadImage() {
139  if(filename == "")
140  return;
141 
142  parseHeader();
143 
144  auto dot = filename.find_last_of(".");
145  std::string imgFilename = filename.replace(dot+1, 3, "raw");
146 
147  // get file size
148  struct stat st;
149  fd = open(imgFilename.c_str(), O_RDONLY);
150  if(fd == -1) {
151  perror("open");
152  return;
153  }
154  if(fstat(fd, &st) == -1) {
155  perror("fstat");
156  return;
157  }
158  if((unsigned long long)(st.st_size) != (width*height*numFrames*bytesPerPixel)) {
159  std::cerr << "Expected filesize: " << width*height*numFrames*bytesPerPixel << "\nActual filesize: " << st.st_size << std::endl;
160  }
161  data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
162 }
163 
double getTint() const
Definition: Envi.cpp:34
unsigned long long getNumFrames() const
Definition: Envi.cpp:32
void * getDataByFrame(unsigned int frame) const
Definition: Envi.cpp:37
uint16_t * getAvg()
Definition: Envi.cpp:60
EnviFile()
Definition: Envi.cpp:22
void openFile(const std::string &_filename)
Definition: Envi.cpp:43
~EnviFile()
Definition: Envi.cpp:26
unsigned long long getHeight() const
Definition: Envi.cpp:31
unsigned long long getWidth() const
Definition: Envi.cpp:30
Definition: Envi.h:8
unsigned int getBytesPerPixel() const
Definition: Envi.cpp:33
double getFps() const
Definition: Envi.cpp:35
void closeFile()
Definition: Envi.cpp:49