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