Visual Servoing Platform  version 3.6.1 under development (2024-05-18)
vpImageIoPortable.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Backend for portable image format I/O operations.
32  */
33 
39 #include "vpImageIoBackend.h"
40 #include <visp3/core/vpImageConvert.h>
41 #include <visp3/core/vpIoTools.h>
42 #include <visp3/core/vpEndian.h>
43 
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
54 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
55  unsigned int &h, unsigned int &maxval)
56 {
57  std::string line;
58  unsigned int nb_elt = 4, cpt_elt = 0;
59  while (cpt_elt != nb_elt) {
60  // Skip empty lines or lines starting with # (comment)
61  while (std::getline(fd, line) && (line.compare(0, 1, "#") == 0 || line.size() == 0)) {
62  }
63 
64  if (fd.eof()) {
65  fd.close();
66  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
67  }
68 
69  std::vector<std::string> header = vpIoTools::splitChain(line, std::string(" "));
70 
71  if (header.size() == 0) {
72  fd.close();
73  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
74  }
75 
76  if (cpt_elt == 0) { // decode magic
77  if (header[0].compare(0, magic.size(), magic) != 0) {
78  fd.close();
79  throw(vpImageException(vpImageException::ioError, "\"%s\" is not a PNM file with magic number %s",
80  filename.c_str(), magic.c_str()));
81  }
82  cpt_elt++;
83  header.erase(header.begin(),
84  header.begin() + 1); // erase first element that is processed
85  }
86  while (header.size()) {
87  if (cpt_elt == 1) { // decode width
88  std::istringstream ss(header[0]);
89  ss >> w;
90  cpt_elt++;
91  header.erase(header.begin(),
92  header.begin() + 1); // erase first element that is processed
93  }
94  else if (cpt_elt == 2) { // decode height
95  std::istringstream ss(header[0]);
96  ss >> h;
97  cpt_elt++;
98  header.erase(header.begin(),
99  header.begin() + 1); // erase first element that is processed
100  }
101  else if (cpt_elt == 3) { // decode maxval
102  std::istringstream ss(header[0]);
103  ss >> maxval;
104  cpt_elt++;
105  header.erase(header.begin(),
106  header.begin() + 1); // erase first element that is processed
107  }
108  }
109  }
110 }
111 
112 void vp_decodeHeaderPFM(const std::string &filename, std::ifstream &fd, std::string &magic, unsigned int &w,
113  unsigned int &h, double &scale, bool &littleEndian)
114 {
115  std::string line;
116  const unsigned int nb_elt = 4;
117  unsigned int cpt_elt = 0;
118  while (cpt_elt != nb_elt) {
119  // Skip empty lines or lines starting with # (comment)
120  while (std::getline(fd, line) && (line.compare(0, 1, "#") == 0 || line.size() == 0)) {
121  }
122 
123  if (fd.eof()) {
124  fd.close();
125  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
126  }
127 
128  std::vector<std::string> header = vpIoTools::splitChain(line, std::string(" "));
129 
130  if (header.empty()) {
131  fd.close();
132  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
133  }
134 
135  if (cpt_elt == 0) { // decode magic
136  magic = header[0];
137  if (magic != "PF" && magic != "Pf") {
138  fd.close();
140  "\"%s\" is not a PFM file with PF (RGB) or Pf (gray) magic number", filename.c_str()));
141  }
142  cpt_elt++;
143  header.erase(header.begin(),
144  header.begin() + 1); // erase first element that is processed
145  }
146  while (header.size()) {
147  if (cpt_elt == 1) { // decode width
148  std::istringstream ss(header[0]);
149  ss >> w;
150  cpt_elt++;
151  header.erase(header.begin(),
152  header.begin() + 1); // erase first element that is processed
153  }
154  else if (cpt_elt == 2) { // decode height
155  std::istringstream ss(header[0]);
156  ss >> h;
157  cpt_elt++;
158  header.erase(header.begin(),
159  header.begin() + 1); // erase first element that is processed
160  }
161  else if (cpt_elt == 3) { // decode byte order
162  std::istringstream ss(header[0]);
163  ss >> scale;
164  littleEndian = scale < 0;
165  cpt_elt++;
166  header.erase(header.begin(),
167  header.begin() + 1); // erase first element that is processed
168  }
169  }
170  }
171 }
172 #endif
173 
174 //--------------------------------------------------------------------------
175 // PFM
176 //--------------------------------------------------------------------------
177 
186 void vp_writePFM(const vpImage<float> &I, const std::string &filename)
187 {
188  FILE *fd;
189 
190  // Test the filename
191  if (filename.empty()) {
192  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
193  }
194 
195  fd = fopen(filename.c_str(), "wb");
196 
197  if (fd == nullptr) {
198  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
199  }
200 
201  // Write the head
202  fprintf(fd, "P8\n"); // Magic number
203  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
204  fprintf(fd, "255\n"); // Max level
205 
206  // Write the bitmap
207  size_t ierr;
208  size_t nbyte = I.getWidth() * I.getHeight();
209 
210  ierr = fwrite(I.bitmap, sizeof(float), nbyte, fd);
211  if (ierr != nbyte) {
212  fclose(fd);
213  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
214  filename.c_str(), ierr, nbyte));
215  }
216 
217  fflush(fd);
218  fclose(fd);
219 }
220 
221 void vp_writePFM_HDR(const vpImage<float> &I, const std::string &filename)
222 {
223  // Test the filename
224  if (filename.empty()) {
225  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
226  }
227 
228  FILE *fd = fopen(filename.c_str(), "wb");
229  if (fd == nullptr) {
230  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
231  }
232 
233  // Write the head
234  fprintf(fd, "Pf\n"); // Magic number
235  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
236 #ifdef VISP_LITTLE_ENDIAN
237  fprintf(fd, "%f\n", -1.0f); // Byte order
238 #else
239  fprintf(fd, "%f\n", 1.0f); // Byte order
240 #endif
241 
242  // Write the bitmap
243  size_t nbyte = I.getWidth();
244  for (int i = static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
245  size_t ierr = fwrite(I[i], sizeof(float), nbyte, fd);
246  if (ierr != nbyte) {
247  fclose(fd);
248  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
249  filename.c_str(), ierr, nbyte));
250  }
251  }
252 
253  fflush(fd);
254  fclose(fd);
255 }
256 
257 void vp_writePFM_HDR(const vpImage<vpRGBf> &I, const std::string &filename)
258 {
259  // Test the filename
260  if (filename.empty()) {
261  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
262  }
263 
264  FILE *fd = fopen(filename.c_str(), "wb");
265  if (fd == nullptr) {
266  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
267  }
268 
269  // Write the head
270  fprintf(fd, "PF\n"); // Magic number
271  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
272 #ifdef VISP_LITTLE_ENDIAN
273  fprintf(fd, "%f\n", -1.0f); // Byte order
274 #else
275  fprintf(fd, "%f\n", 1.0f); // Byte order
276 #endif
277 
278  // Write the bitmap
279  size_t nbyte = I.getWidth() * 3;
280  for (int i = static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
281  size_t ierr = fwrite(I[i], sizeof(float), nbyte, fd);
282  if (ierr != nbyte) {
283  fclose(fd);
284  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
285  filename.c_str(), ierr, nbyte));
286  }
287  }
288 
289  fflush(fd);
290  fclose(fd);
291 }
292 
293 //--------------------------------------------------------------------------
294 // PGM
295 //--------------------------------------------------------------------------
296 
304 void vp_writePGM(const vpImage<unsigned char> &I, const std::string &filename)
305 {
306  FILE *fd;
307 
308  // Test the filename
309  if (filename.empty()) {
310  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
311  }
312 
313  fd = fopen(filename.c_str(), "wb");
314 
315  if (fd == nullptr) {
316  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
317  }
318 
319  // Write the head
320  fprintf(fd, "P5\n"); // Magic number
321  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
322  fprintf(fd, "255\n"); // Max level
323 
324  // Write the bitmap
325  size_t ierr;
326  size_t nbyte = I.getWidth() * I.getHeight();
327 
328  ierr = fwrite(I.bitmap, sizeof(unsigned char), nbyte, fd);
329  if (ierr != nbyte) {
330  fclose(fd);
331  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
332  filename.c_str(), ierr, nbyte));
333  }
334 
335  fflush(fd);
336  fclose(fd);
337 }
338 
346 void vp_writePGM(const vpImage<short> &I, const std::string &filename)
347 {
349  unsigned int nrows = I.getHeight();
350  unsigned int ncols = I.getWidth();
351 
352  Iuc.resize(nrows, ncols);
353 
354  for (unsigned int i = 0; i < nrows * ncols; ++i)
355  Iuc.bitmap[i] = (unsigned char)I.bitmap[i];
356 
357  vp_writePGM(Iuc, filename);
358 }
359 
368 void vp_writePGM(const vpImage<vpRGBa> &I, const std::string &filename)
369 {
370 
371  FILE *fd;
372 
373  // Test the filename
374  if (filename.empty()) {
375  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
376  }
377 
378  fd = fopen(filename.c_str(), "wb");
379 
380  if (fd == nullptr) {
381  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
382  }
383 
384  // Write the head
385  fprintf(fd, "P5\n"); // Magic number
386  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
387  fprintf(fd, "255\n"); // Max level
388 
389  // Write the bitmap
390  size_t ierr;
391  size_t nbyte = I.getWidth() * I.getHeight();
392 
394  vpImageConvert::convert(I, Itmp);
395 
396  ierr = fwrite(Itmp.bitmap, sizeof(unsigned char), nbyte, fd);
397  if (ierr != nbyte) {
398  fclose(fd);
399  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
400  filename.c_str(), ierr, nbyte));
401  }
402 
403  fflush(fd);
404  fclose(fd);
405 }
406 
421 void vp_readPFM(vpImage<float> &I, const std::string &filename)
422 {
423  unsigned int w = 0, h = 0, maxval = 0;
424  const unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
425  const std::string magic("P8");
426 
427  std::ifstream fd(filename.c_str(), std::ios::binary);
428 
429  // Open the filename
430  if (!fd.is_open()) {
431  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
432  }
433 
434  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
435 
436  if (w > w_max || h > h_max) {
437  fd.close();
438  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
439  }
440  if (maxval > maxval_max) {
441  fd.close();
442  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
443  }
444 
445  if ((h != I.getHeight()) || (w != I.getWidth())) {
446  I.resize(h, w);
447  }
448 
449  unsigned int nbyte = I.getHeight() * I.getWidth();
450  fd.read((char *)I.bitmap, sizeof(float) * nbyte);
451  if (!fd) {
452  fd.close();
453  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
454  filename.c_str()));
455  }
456 
457  fd.close();
458 }
459 
475 void vp_readPFM_HDR(vpImage<float> &I, const std::string &filename)
476 {
477  std::ifstream fd(filename.c_str(), std::ios::binary);
478 
479  // Open the filename
480  if (!fd.is_open()) {
481  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
482  }
483 
484  const unsigned int w_max = 100000, h_max = 100000;
485  const std::string magicRGB("PF"), magicGray("Pf");
486  std::string magic;
487  unsigned int w = 0, h = 0;
488  double scale = 1;
489  bool littleEndian = true;
490  vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
491 
492  if (w > w_max || h > h_max) {
493  fd.close();
494  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
495  }
496 
497  unsigned int channels = (magic == magicRGB) ? 3 : 1;
498  if (h != I.getHeight() || channels * w != I.getWidth()) {
499  I.resize(h, channels * w);
500  }
501 
502 #ifdef VISP_LITTLE_ENDIAN
503  bool swapEndianness = !littleEndian;
504 #else
505  bool swapEndianness = littleEndian;
506 #endif
507  for (int i = I.getHeight() - 1; i >= 0; i--) {
508  fd.read((char *)I[i], sizeof(float) * w * channels);
509  if (swapEndianness) {
510  for (unsigned int j = 0; j < w * channels; ++j) {
511  I[i][j] = vpEndian::swapFloat(I[i][j]);
512  }
513  }
514  }
515 
516  if (!fd) {
517  fd.close();
518  throw(vpImageException(vpImageException::ioError, "Read only %d bytes in file \"%s\"", fd.gcount(),
519  filename.c_str()));
520  }
521  fd.close();
522 
523  if (std::fabs(scale) > 0.0f) {
524  for (unsigned int i = 0; i < I.getHeight(); ++i) {
525  for (unsigned int j = 0; j < I.getWidth(); ++j) {
526  I[i][j] *= 1.0f / static_cast<float>(std::fabs(scale));
527  }
528  }
529  }
530 }
531 
547 void vp_readPFM_HDR(vpImage<vpRGBf> &I, const std::string &filename)
548 {
549  std::ifstream fd(filename.c_str(), std::ios::binary);
550 
551  // Open the filename
552  if (!fd.is_open()) {
553  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
554  }
555 
556  const unsigned int w_max = 100000, h_max = 100000;
557  const std::string magicRGB("PF"), magicGray("Pf");
558  std::string magic;
559  unsigned int w = 0, h = 0;
560  double scale = 1;
561  bool littleEndian = true;
562  vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
563 
564  if (w > w_max || h > h_max) {
565  fd.close();
566  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
567  }
568 
569  unsigned int channels = (magic == magicRGB) ? 3 : 1;
570  if (magic != magicRGB) {
571  throw(vpImageException(vpImageException::ioError, "Image \"%s\" is not an RGB image!", filename.c_str()));
572  }
573  if (h != I.getHeight() || w != I.getWidth()) {
574  I.resize(h, w);
575  }
576 
577 #ifdef VISP_LITTLE_ENDIAN
578  bool swapEndianness = !littleEndian;
579 #else
580  bool swapEndianness = littleEndian;
581 #endif
582  for (int i = I.getHeight() - 1; i >= 0; i--) {
583  fd.read((char *)I[i], sizeof(float) * w * channels);
584  if (swapEndianness) {
585  for (unsigned int j = 0; j < w; ++j) {
586  I[i][j].R = vpEndian::swapFloat(I[i][j].R);
587  I[i][j].G = vpEndian::swapFloat(I[i][j].G);
588  I[i][j].B = vpEndian::swapFloat(I[i][j].B);
589  }
590  }
591  }
592 
593  if (!fd) {
594  fd.close();
595  throw(vpImageException(vpImageException::ioError, "Read only %d bytes in file \"%s\"", fd.gcount(),
596  filename.c_str()));
597  }
598  fd.close();
599 
600  if (std::fabs(scale) > 0.0f) {
601  for (unsigned int i = 0; i < I.getHeight(); ++i) {
602  for (unsigned int j = 0; j < I.getWidth(); ++j) {
603  I[i][j].R *= 1.0f / static_cast<float>(std::fabs(scale));
604  I[i][j].G *= 1.0f / static_cast<float>(std::fabs(scale));
605  I[i][j].B *= 1.0f / static_cast<float>(std::fabs(scale));
606  }
607  }
608  }
609 }
610 
625 void vp_readPGM(vpImage<unsigned char> &I, const std::string &filename)
626 {
627  unsigned int w = 0, h = 0, maxval = 0;
628  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
629  std::string magic("P5");
630 
631  std::ifstream fd(filename.c_str(), std::ios::binary);
632 
633  // Open the filename
634  if (!fd.is_open()) {
635  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
636  }
637 
638  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
639 
640  if (w > w_max || h > h_max) {
641  fd.close();
642  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
643  }
644  if (maxval > maxval_max) {
645  fd.close();
646  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
647  }
648 
649  if ((h != I.getHeight()) || (w != I.getWidth())) {
650  I.resize(h, w);
651  }
652 
653  unsigned int nbyte = I.getHeight() * I.getWidth();
654  fd.read((char *)I.bitmap, nbyte);
655  if (!fd) {
656  fd.close();
657  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
658  filename.c_str()));
659  }
660 
661  fd.close();
662 }
663 
681 void vp_readPGM(vpImage<vpRGBa> &I, const std::string &filename)
682 {
684 
685  vp_readPGM(Itmp, filename);
686 
687  vpImageConvert::convert(Itmp, I);
688 }
689 
690 //--------------------------------------------------------------------------
691 // PPM
692 //--------------------------------------------------------------------------
693 
709 void vp_readPPM(vpImage<unsigned char> &I, const std::string &filename)
710 {
711  vpImage<vpRGBa> Itmp;
712 
713  vp_readPPM(Itmp, filename);
714 
715  vpImageConvert::convert(Itmp, I);
716 }
717 
729 void vp_readPPM(vpImage<vpRGBa> &I, const std::string &filename)
730 {
731  unsigned int w = 0, h = 0, maxval = 0;
732  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
733  std::string magic("P6");
734 
735  std::ifstream fd(filename.c_str(), std::ios::binary);
736 
737  // Open the filename
738  if (!fd.is_open()) {
739  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
740  }
741 
742  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
743 
744  if (w > w_max || h > h_max) {
745  fd.close();
746  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
747  }
748  if (maxval > maxval_max) {
749  fd.close();
750  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
751  }
752 
753  if ((h != I.getHeight()) || (w != I.getWidth())) {
754  I.resize(h, w);
755  }
756 
757  for (unsigned int i = 0; i < I.getHeight(); ++i) {
758  for (unsigned int j = 0; j < I.getWidth(); ++j) {
759  unsigned char rgb[3];
760  fd.read((char *)&rgb, 3);
761 
762  if (!fd) {
763  fd.close();
764  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"",
765  (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
766  }
767 
768  I[i][j].R = rgb[0];
769  I[i][j].G = rgb[1];
770  I[i][j].B = rgb[2];
771  I[i][j].A = vpRGBa::alpha_default;
772  }
773  }
774 
775  fd.close();
776 }
777 
786 void vp_writePPM(const vpImage<unsigned char> &I, const std::string &filename)
787 {
788  vpImage<vpRGBa> Itmp;
789 
790  vpImageConvert::convert(I, Itmp);
791 
792  vp_writePPM(Itmp, filename);
793 }
794 
802 void vp_writePPM(const vpImage<vpRGBa> &I, const std::string &filename)
803 {
804  FILE *f;
805 
806  // Test the filename
807  if (filename.empty()) {
808  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file: filename empty"));
809  }
810 
811  f = fopen(filename.c_str(), "wb");
812 
813  if (f == nullptr) {
814  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file \"%s\"", filename.c_str()));
815  }
816 
817  fprintf(f, "P6\n"); // Magic number
818  fprintf(f, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
819  fprintf(f, "%d\n", 255); // Max level
820 
821  for (unsigned int i = 0; i < I.getHeight(); ++i) {
822  for (unsigned int j = 0; j < I.getWidth(); ++j) {
823  vpRGBa v = I[i][j];
824  unsigned char rgb[3];
825  rgb[0] = v.R;
826  rgb[1] = v.G;
827  rgb[2] = v.B;
828 
829  size_t res = fwrite(&rgb, 1, 3, f);
830  if (res != 3) {
831  fclose(f);
832  throw(vpImageException(vpImageException::ioError, "cannot write file \"%s\"", filename.c_str()));
833  }
834  }
835  }
836 
837  fflush(f);
838  fclose(f);
839 }
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:85
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
@ ioError
Image io error.
unsigned int getWidth() const
Definition: vpImage.h:245
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:798
unsigned int getSize() const
Definition: vpImage.h:224
Type * bitmap
points toward the bitmap
Definition: vpImage.h:139
unsigned int getHeight() const
Definition: vpImage.h:184
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:2427
Definition: vpRGBa.h:61
unsigned char B
Blue component.
Definition: vpRGBa.h:139
unsigned char R
Red component.
Definition: vpRGBa.h:137
unsigned char G
Green component.
Definition: vpRGBa.h:138
@ alpha_default
Definition: vpRGBa.h:63
VISP_EXPORT float swapFloat(float f)
Definition: vpEndian.cpp:65