PICCANTE  0.4
The hottest HDR imaging library!
pfm.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_IO_PFM_HPP
19 #define PIC_IO_PFM_HPP
20 
21 #include <stdio.h>
22 #include <string>
23 
24 #include "../base.hpp"
25 
26 namespace pic {
27 
36 {
37  float ret;
38 
39  unsigned char *c_v = (unsigned char*) &value;
40  unsigned char *c_r = (unsigned char*) &ret;
41 
42  c_r[0] = c_v[3];
43  c_r[1] = c_v[2];
44  c_r[2] = c_v[1];
45  c_r[3] = c_v[0];
46 
47  return ret;
48 }
49 
59 PIC_INLINE float *ReadPFM(std::string nameFile, float *data, int &width,
60  int &height, int &channel)
61 {
62  FILE *file = fopen(nameFile.c_str(), "rb");
63 
64  if(file == NULL) {
65  return NULL;
66  }
67 
68  char flagc;
69  float flag;
70  char P = fgetc(file);
71 
72  if(P != 'P') {
73  fclose(file);
74  return NULL;
75  }
76 
77  char F = fgetc(file);
78 
79  bool fCheck = false;
80 
81  if(F == 'f') {
82  fCheck = true;
83  channel = 1;
84  }
85 
86  if(F == 'F') {
87  fCheck = true;
88  channel = 3;
89  }
90 
91  if(!fCheck) {
92  fclose(file);
93  return NULL;
94  }
95 
96 
97  fgetc(file);
98  fscanf(file, "%d %d%c", &width, &height, &flagc);
99  fscanf(file, "%f%c", &flag, &flagc);
100 
101  if(data == NULL) {
102  data = new float[width * height * channel];
103  }
104 
105  if(flag < 0.0f) {
106  //little-endian encoding
107 
108  for(int i = height - 1; i > -1; i--) {
109  int ind = i * width;
110 
111  for(int j = 0; j < width; j++) {
112  int tmpInd = (ind + j) * channel;
113 
114  fread(&data[tmpInd], sizeof(float), channel, file);
115  }
116  }
117  } else {
118  //big-endian encoding
119 
120  for(int i = height - 1; i > -1; i--) {
121  int ind = i * width;
122 
123  for(int j = 0; j < width; j++) {
124  int tmpInd = (ind + j) * channel;
125 
126  fread(&data[tmpInd], sizeof(float), channel, file);
127 
128  for(int k = 0; k < channel; k++) {
129  data[tmpInd + k] = convertFloatEndianess(data[tmpInd + k]);
130  }
131  }
132  }
133  }
134 
135  fclose(file);
136  return data;
137 }
138 
148 PIC_INLINE bool WritePFM(std::string nameFile, float *data, int width,
149  int height, int channels = 3)
150 {
151  if((data == NULL) || (height < 1) || (width < 1) || (channels < 1)) {
152  return false;
153  }
154 
155  FILE *file = fopen(nameFile.c_str(), "wb");
156 
157  if(file == NULL) {
158  return false;
159  }
160 
161  //header
162  fputc('P', file);
163 
164  if(channels != 1) {
165  fputc('F', file);
166  } else {
167  fputc('f', file);
168  }
169 
170  fputc(0x0a, file);
171 
172  //width and height
173  fprintf(file, "%d %d", width, height);
174  fputc(0x0a, file);
175 
176  //flag: writing little-endian only
177  fprintf(file, "%f", -1.0f);
178  fputc(0x0a, file);
179 
180  //data
181  int ind1 = 1;
182  int ind2 = 2;
183 
184  if(channels == 2) {
185  ind1 = 1;
186  ind2 = 1;
187  }
188 
189  for(int i = height - 1; i > -1; i--) {
190  int ind = i * width;
191 
192  for(int j = 0; j < width; j++) {
193  int tmpInd = (ind + j) * channels;
194 
195  fwrite(&data[tmpInd], sizeof(float), 1, file);
196 
197  if(channels > 1) {
198  fwrite(&data[tmpInd + ind1], sizeof(float), 1, file);
199  fwrite(&data[tmpInd + ind2], sizeof(float), 1, file);
200  }
201  }
202  }
203 
204  fclose(file);
205  return true;
206 }
207 
208 } // end namespace pic
209 
210 #endif /* PIC_IO_PFM_HPP */
211 
PIC_INLINE float convertFloatEndianess(float value)
convertFloatEndianess converts a float from little-endian to big-endian or viceversa.
Definition: pfm.hpp:35
#define PIC_INLINE
Definition: base.hpp:33
PIC_INLINE bool WritePFM(std::string nameFile, float *data, int width, int height, int channels=3)
WritePFM writes an HDR image in the portable float map format into a file.
Definition: pfm.hpp:148
PIC_INLINE float * ReadPFM(std::string nameFile, float *data, int &width, int &height, int &channel)
ReadPFM loads a portable float map from a file.
Definition: pfm.hpp:59
Definition: bilateral_separation.hpp:25