source: pacpussensors/trunk/Vislab/20150310_lib3dv-1.2.0/src/pnm.h@ 149

Last change on this file since 149 was 136, checked in by ldecherf, 7 years ago

Doc

File size: 10.7 KB
Line 
1#ifndef PNM_H
2#define PNM_H
3
4/* 3dv-client/pnm.h
5 *
6 * Copyright (C) 2013 VisLab
7 *
8 * This file is part of 3dv-client; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22#ifdef _MSC_VER
23 #include <Winsock2.h>
24#else
25 #include <arpa/inet.h>
26#endif
27
28#include <fstream>
29#include <limits>
30#include <sstream>
31#include <string>
32
33#include <stdint.h>
34
35#ifdef ARCHIVE
36
37#include <archive.h>
38
39template<typename T>
40size_t ppm_file_size(unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
41{
42 size_t size = 3 + 1 + comment.size() + 1;
43
44 std::stringstream ss;
45 ss << width << ' ' << height << '\n' << static_cast<uint64_t>(max_value) << '\n';
46
47 size += ss.str().size(); // header
48 size += width * height * 3 * sizeof(T);
49
50 return size;
51}
52
53template<typename T>
54size_t pgm_file_size(unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
55{
56 size_t size = 3 + 1 + comment.size() + 1;
57
58 std::stringstream ss;
59 ss << width << ' ' << height << '\n' << static_cast<uint64_t>(max_value) << '\n';
60
61 size += ss.str().size(); // header
62 size += width * height * sizeof(T);
63
64 return size;
65}
66
67/**
68 * Writes a PPM file of up to 16 bits per pixel.
69 * @param archive the archive to write to
70 * @param buffer an RGB buffer (3 channels).
71 * @param width the number of image columns.
72 * @param height the number of image rows.
73 * @param comment a comment to embed into the file. Defaults to std::string().
74 * @param max_value the maximum pixel value contained within the image. Defaults to std::numeric_limits<T>::max().
75 * @return true if the file could be written successfully, false otherwise.
76 */
77template<typename T>
78bool write_ppm(archive* archive, const T* buffer, unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
79{
80 if(sizeof(T) > 2)
81 return false;
82
83 archive_write_data(archive, "P6\n", 3);
84
85 if(!comment.empty())
86 {
87 archive_write_data(archive, "#", 1);
88 archive_write_data(archive, comment.c_str(), comment.size());
89 archive_write_data(archive, "\n", 1);
90 }
91
92 std::stringstream ss;
93 ss << width << ' ' << height << '\n' << static_cast<uint64_t>(max_value) << '\n';
94
95 archive_write_data(archive, ss.str().c_str(), ss.str().size());
96
97 if(sizeof(T) == 2)
98 {
99 for(unsigned int p = 0; p < width * height * 3; ++p)
100 {
101 uint16_t pixel_big_endian = htons(buffer[p]);
102 archive_write_data(archive, reinterpret_cast<const char*>(&pixel_big_endian), sizeof(pixel_big_endian));
103 }
104 }
105 else
106 archive_write_data(archive, reinterpret_cast<const char*>(buffer), width * height * 3);
107
108 return true;
109}
110
111/**
112 * Writes a PGM file of up to 16 bits per pixel.
113 * @param archive the archive to write to
114 * @param buffer a grayscale buffer (1 channel).
115 * @param width the number of image columns.
116 * @param height the number of image rows.
117 * @param comment a comment to embed into the file. Defaults to std::string()
118 * @param max_value the maximum pixel value contained within the image. Defaults to std::numeric_limits<T>::max().
119 * @return true if the file could be written successfully, false otherwise.
120 */
121template<typename T>
122bool write_pgm(archive* archive, const T* buffer, unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
123{
124 if(sizeof(T) > 2)
125 return false;
126
127 archive_write_data(archive, "P5\n", 3);
128
129 if(!comment.empty())
130 {
131 archive_write_data(archive, "#", 1);
132 archive_write_data(archive, comment.c_str(), comment.size());
133 archive_write_data(archive, "\n", 1);
134 }
135
136 std::stringstream ss;
137 ss << width << ' ' << height << '\n' << static_cast<uint64_t>(max_value) << '\n';
138
139 archive_write_data(archive, ss.str().c_str(), ss.str().size());
140
141 if(sizeof(T) > 1)
142 {
143 for(unsigned int p = 0; p < width * height; ++p)
144 {
145 uint16_t pixel_big_endian = htons(buffer[p]);
146 archive_write_data(archive, reinterpret_cast<const char*>(&pixel_big_endian), sizeof(pixel_big_endian));
147 }
148 }
149 else
150 archive_write_data(archive, reinterpret_cast<const char*>(buffer), width * height);
151
152 return true;
153}
154
155
156#endif
157
158
159/**
160 * Writes a PPM file of up to 16 bits per pixel.
161 * @param filename the name of the file to write to
162 * @param buffer an RGB buffer (3 channels).
163 * @param width the number of image columns.
164 * @param height the number of image rows.
165 * @param comment a comment to embed into the file. Defaults to std::string().
166 * @param max_value the maximum pixel value contained within the image. Defaults to std::numeric_limits<T>::max().
167 * @return true if the file could be written successfully, false otherwise.
168 */
169template<typename T>
170bool write_ppm(const std::string& filename, const T* buffer, unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
171{
172 if(sizeof(T) > 2)
173 return false;
174
175 std::ofstream file(filename.c_str(), std::ios::out | std::ios::binary);
176
177 if(file)
178 {
179 std::stringstream ss;
180 ss << static_cast<uint64_t>(max_value);
181
182 file << "P6\n";
183
184 if(!comment.empty())
185 file << '#' << comment << '\n';
186
187 file << width << ' ' << height << '\n' << ss.str() << '\n';
188
189 if(sizeof(T) == 2)
190 {
191 for(unsigned int p = 0; p < width * height * 3; ++p)
192 {
193 uint16_t pixel_big_endian = htons(buffer[p]);
194 file.write(reinterpret_cast<const char*>(&pixel_big_endian), sizeof(pixel_big_endian));
195 }
196 }
197 else
198 file.write(reinterpret_cast<const char*>(buffer), width * height * 3);
199 return true;
200 }
201
202 return false;
203}
204
205/**
206 * Writes a PGM file of up to 16 bits per pixel.
207 * @param filename the name of the file to write to.
208 * @param buffer a grayscale buffer (1 channel).
209 * @param width the number of image columns.
210 * @param height the number of image rows.
211 * @param comment a comment to embed into the file. Defaults to std::string()
212 * @param max_value the maximum pixel value contained within the image. Defaults to std::numeric_limits<T>::max().
213 * @return true if the file could be written successfully, false otherwise.
214 */
215template<typename T>
216bool write_pgm(const std::string& filename, const T* buffer, unsigned int width, unsigned int height, const std::string& comment = std::string(), T max_value = std::numeric_limits<T>::max())
217{
218 if(sizeof(T) > 2)
219 return false;
220
221 std::ofstream file(filename.c_str(), std::ios::out | std::ios::binary);
222
223 if(file)
224 {
225 std::stringstream ss;
226 ss << static_cast<uint64_t>(max_value);
227
228 file << "P5\n";
229
230 if(!comment.empty())
231 file << '#' << comment << '\n';
232
233 file << width << ' ' << height << "\n" << ss.str() << "\n";
234
235 if(sizeof(T) > 1)
236 {
237 for(unsigned int p = 0; p < width * height; ++p)
238 {
239 uint16_t pixel_big_endian = htons(buffer[p]);
240 file.write(reinterpret_cast<const char*>(&pixel_big_endian), sizeof(pixel_big_endian));
241 }
242 }
243 else
244 file.write(reinterpret_cast<const char*>(buffer), width * height);
245 return true;
246 }
247
248 return false;
249}
250
251
252
253
254static void pnm_read_time(std::istream & i,boost::posix_time::ptime & timestamp)
255{
256 std::string date;
257 std::string time;
258 while (isspace(i.peek()))
259 {
260 while (isspace(i.peek()))
261 i.get();
262 if (i.peek() == '#')
263 {
264 i.get();
265 i>>date;
266 i>>time;
267 timestamp = boost::posix_time::time_from_string(date+" "+time);
268 }
269 }
270}
271
272static void pnm_read_comments(std::istream & i)
273{
274 std::string date;
275 std::string time;
276 while (isspace(i.peek()))
277 {
278 while (isspace(i.peek()))
279 i.get();
280 if (i.peek() == '#')
281 while (i.peek()!='\r' && i.peek()!='\n')
282 i.get();
283 }
284}
285
286static char pnm_read_header(uint16_t & width, uint16_t &height, std::istream &iss,boost::posix_time::ptime & timestamp)
287{
288 char h, t;
289 int max_val;
290
291 h = iss.get();
292 t = iss.get();
293 if(!((h=='P') && ((t=='5') || (t=='6'))))
294 {
295 return '\0';
296 }
297
298 pnm_read_time(iss,timestamp);
299 iss>>width;
300 pnm_read_comments(iss);
301 iss>>height;
302 pnm_read_comments(iss);
303 iss>>max_val;
304 iss.get();
305 return t;
306}
307
308
309template<typename T>
310bool pnm_load(boost::shared_ptr<lib3dv::image> & output_image, const char *file,lib3dv::image::type::types type)
311{
312 std::ifstream istr(file, std::ios::binary);
313 T *buffer = NULL;
314
315 uint16_t width;
316 uint16_t height;
317 char c = pnm_read_header(width,height,istr,output_image->m_timestamp);
318 if(c=='5')
319 {
320 output_image->m_channels=1;
321 buffer = new T [width * height];
322 istr.read(reinterpret_cast<char*>(buffer), width * height*sizeof(T));
323 }
324 else if(c=='6')
325 {
326 output_image->m_channels=3;
327 buffer = new T [width * height*3];
328 istr.read(reinterpret_cast<char*>(buffer), width * height*3);
329 }
330 else
331 return false;
332
333 output_image->m_height=height;
334 output_image->m_width=width;
335 output_image->m_bpp = 8*sizeof(T);
336 output_image->m_type = type;
337 output_image->m_format = (lib3dv::image::format::types)(output_image->m_channels*sizeof(T));
338 output_image->m_buffer.resize(width*height*output_image->m_channels*sizeof(T));
339 if(type==lib3dv::image::type::DSI)
340 {
341 int k=0;
342 for(int i=0;i<output_image->m_width*output_image->m_height;i++)
343 {
344 output_image->m_buffer[k++]=((uint8_t)((buffer[i] & 0xFF00) >> 8));
345 output_image->m_buffer[k++]=((uint8_t)(buffer[i] & 0x00FF));
346 }
347 }
348 else
349 memcpy(&(output_image->m_buffer[0]),buffer,output_image->m_width*output_image->m_height*output_image->m_channels);
350 free(buffer);
351
352 return true;
353}
354
355
356#endif
Note: See TracBrowser for help on using the repository browser.