Tucano  0.1
A library for rapid prototyping with modern OpenGL and GLSL
pamIO.hpp
Go to the documentation of this file.
1 
23 #ifndef __PAMIO__
24 #define __PAMIO__
25 
26 #include <tucano/framebuffer.hpp>
27 
28 namespace Tucano
29 {
30 
31 namespace ImageImporter
32 {
33 
34 static bool loadPAMImage (string filename, Tucano::Texture *tex) __attribute__ ((unused));
35 static bool writePAMImage (string filename, Tucano::Framebuffer* fbo, int attach = 0) __attribute__ ((unused));
36 
37 
38 /* @brief Loads a texture from a PAM file.
39  * The texture receives data in the range [0,1] to create a FLOAT texture
40  * To convert to PAM in Linux use for example:
41  * convert filename.png filename_out.pam
42  *
43  * @param filename Given filename of the PAM file.
44  * @param tex Pointer to the texture
45  * @return True if loaded successfully, false otherwise
46  */
47 static bool loadPAMImage (string filename, Tucano::Texture *tex)
48 {
49 
50  ifstream in(filename.c_str(), std::ios::in | std::ios::binary);
51  if (!in)
52  {
53  cerr << "Cannot open " << filename.c_str() << endl; exit(1);
54  }
55 
56  vector<float> data;
57  string header, tuple;
58  bool magic_number = false;
59  int w, h, d, max_value;;
60 
61  in >> header;
62  while (header.compare("ENDHDR") != 0)
63  {
64  if (header.compare("WIDTH") == 0)
65  in >> w;
66  else if (header.compare("HEIGHT") == 0)
67  in >> h;
68  else if (header.compare("DEPTH") == 0)
69  in >> d;
70  else if (header.compare("MAXVAL") == 0)
71  in >> max_value;
72  else if (header.compare("TUPLTYPE") == 0)
73  in >> tuple;
74  else if (header.compare("P7") == 0)
75  magic_number = true;
76  in >> header;
77  }
78  getline(in, header);
79 
80  if (!magic_number)
81  {
82  std::cerr << "Error opening : " << filename.c_str() << " : Invalid Magic Number, should be P7" << std::endl;
83  return false;
84  }
85  if (w < 1 || h < 1 || d < 1)
86  {
87  std::cerr << "Error opening : " << filename.c_str() << "Invalid dimension, WIDTH HEIGHT and DEPTH should be at least 1" << std::endl;
88  return false;
89  }
90 
92 
93  unsigned char byte_value = 0;
94  unsigned int value = 0;
95  while (in.read(reinterpret_cast< char* >(&byte_value), sizeof(byte_value)) )
96  {
97  value = byte_value;
98  data.push_back(value/(float)max_value);
99  }
100 
101  if (data.size() != (unsigned int)(w*h*d))
102  {
103  std::cerr << "possible error reading PAM file:\n read " << data.size()*sizeof(byte_value) << " bytes, should have read " << w*h*d*sizeof(byte_value) << std::endl;
104  }
105 
106  if(in.is_open())
107  {
108  in.close();
109  }
110 
111  // convert from grayscale_alpha to rgb_alpha
112  bool convertGAToRGBA = !tuple.compare("GRAYSCALE_ALPHA");
113 
114  // flip texture since it will be upside down (invertex y axis)
115  vector<float> flipped;
116  for (int j = h-1; j >= 0; j--)
117  {
118  for (int i = 0; i < w; i++)
119  {
120  for (int k = 0; k < d; ++k)
121  {
122  flipped.push_back( data[(j*w + i)*d + k]);
123  // if grayscale_alpha convert to rgba_alpha (repeat value for G and B channels)
124  if (convertGAToRGBA && k == 0)
125  {
126  flipped.push_back( data[(j*w + i)*d + k]);
127  flipped.push_back( data[(j*w + i)*d + k]);
128  }
129  }
130  }
131  }
132 
133  if (d == 3)
134  tex->create (GL_TEXTURE_2D, GL_RGBA32F, w, h, GL_RGB, GL_FLOAT, &flipped[0], 0);
135  else if (d == 4 || convertGAToRGBA)
136  tex->create (GL_TEXTURE_2D, GL_RGBA32F, w, h, GL_RGBA, GL_FLOAT, &flipped[0], 0);
137 
138  #ifdef TUCANODEBUG
139  Misc::errorCheckFunc(__FILE__, __LINE__);
140  #endif
141 
142  return true;
143 }
144 
145 
146 
157 static bool writePAMImage (string filename, Tucano::Framebuffer* fbo, int attach)
158 {
159  int max_value = 255;
160  Eigen::Vector2i size = fbo->getDimensions();
161  ofstream out_stream;
162  out_stream.open(filename.c_str(), ios::out);
163  out_stream << "P7\n";
164  out_stream << "WIDTH " << size[0] <<"\n " << "HEIGHT " << size[1] << "\n";
165  out_stream << "DEPTH 4\n";
166  out_stream << "MAXVAL " << max_value << "\n";
167  out_stream << "TUPLTYPE RGB_ALPHA\n";
168  out_stream << "ENDHDR\n";
169 
170  GLfloat * pixels = new GLfloat[(int)(size[0]*size[1]*4)];
171  fbo->bind();
172  glReadBuffer(GL_COLOR_ATTACHMENT0+attach);
173  glReadPixels(0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, pixels);
174 
175  out_stream.close();
176  out_stream.open(filename.c_str(), ios::out | ios::app | ios::binary);
177  int pos;
178  unsigned int value;
179  for (int j = size[1]-1; j >= 0; --j)
180  {
181  for (int i = 0 ; i < size[0]; ++i)
182  {
183  pos = (i + size[0]*j)*4;
184  for (int k = 0; k < 4; ++k)
185  {
186  value = (unsigned int) (max_value*pixels[pos+k]);
187  out_stream.write(reinterpret_cast< char* >(&value), sizeof(value)) ;
188  }
189  }
190  out_stream << "\n";
191  }
192  out_stream.close();
193 
194  fbo->unbind();
195  delete [] pixels;
196  return true;
197 }
198 
199 
200 }
201 }
202 #endif
Eigen::Vector2i getDimensions(void)
Returns the dimensions of the FBO.
Definition: framebuffer.hpp:875
Definition: bufferobject.hpp:34
void errorCheckFunc(std::string file, int line, std::string message="")
GL error check method.
Definition: misc.hpp:53
virtual void bind(void)
Binds framebuffer object.
Definition: framebuffer.hpp:245
void unbind(void)
Unbinds fbo and all texture units in use.
Definition: framebuffer.hpp:408
A wrapper class for creating and using FBOs.
Definition: framebuffer.hpp:44
static bool loadPAMImage(string filename, Tucano::Texture *tex) __attribute__((unused))
Definition: pamIO.hpp:47
static bool writePAMImage(string filename, Tucano::Framebuffer *fbo, int attach=0) __attribute__((unused))
Saves a framebuffer attachment to an image file Note that since the input is a float image...
Definition: pamIO.hpp:157
An OpenGL texture. It can be a simple texture or an FBO texture.
Definition: texture.hpp:41