Visual Servoing Platform  version 3.4.0
vpImageIo.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Read/write images.
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
44 #include <visp3/core/vpImage.h>
45 #include <visp3/core/vpImageConvert.h> //image conversion
46 #include <visp3/core/vpIoTools.h>
47 #include <visp3/io/vpImageIo.h>
48 
49 #if defined(_WIN32)
50 // Include WinSock2.h before windows.h to ensure that winsock.h is not
51 // included by windows.h since winsock.h and winsock2.h are incompatible
52 #include <WinSock2.h>
53 #include <windows.h>
54 #endif
55 
56 #if defined(VISP_HAVE_JPEG)
57 #include <jerror.h>
58 #include <jpeglib.h>
59 #endif
60 
61 #if defined(VISP_HAVE_PNG)
62 #include <png.h>
63 #endif
64 
65 #if !defined(VISP_HAVE_OPENCV)
66 #if !defined(VISP_HAVE_JPEG) || !defined(VISP_HAVE_PNG)
67 
68 #if defined __SSE2__ || defined _M_X64 || (defined _M_IX86_FP && _M_IX86_FP >= 2)
69 # define VISP_HAVE_SSE2 1
70 #endif
71 
72 #ifndef VISP_HAVE_SSE2
73 # define STBI_NO_SIMD
74 #endif
75 
76 #define STB_IMAGE_IMPLEMENTATION
77 #include <stb_image.h>
78 
79 #define STB_IMAGE_WRITE_IMPLEMENTATION
80 #include <stb_image_write.h>
81 #endif
82 #endif
83 
84 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
85  unsigned int &h, unsigned int &maxval);
86 
87 #ifndef DOXYGEN_SHOULD_SKIP_THIS
88 
97 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
98  unsigned int &h, unsigned int &maxval)
99 {
100  std::string line;
101  unsigned int nb_elt = 4, cpt_elt = 0;
102  while (cpt_elt != nb_elt) {
103  // Skip empty lines or lines starting with # (comment)
104  while (std::getline(fd, line) && (line.compare(0, 1, "#") == 0 || line.size() == 0)) {
105  };
106 
107  if (fd.eof()) {
108  fd.close();
109  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
110  }
111 
112  std::vector<std::string> header = vpIoTools::splitChain(line, std::string(" "));
113 
114  if (header.size() == 0) {
115  fd.close();
116  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
117  }
118 
119  if (cpt_elt == 0) { // decode magic
120  if (header[0].compare(0, magic.size(), magic) != 0) {
121  fd.close();
122  throw(vpImageException(vpImageException::ioError, "\"%s\" is not a PNM file with magic number %s",
123  filename.c_str(), magic.c_str()));
124  }
125  cpt_elt++;
126  header.erase(header.begin(),
127  header.begin() + 1); // erase first element that is processed
128  }
129  while (header.size()) {
130  if (cpt_elt == 1) { // decode width
131  std::istringstream ss(header[0]);
132  ss >> w;
133  cpt_elt++;
134  header.erase(header.begin(),
135  header.begin() + 1); // erase first element that is processed
136  } else if (cpt_elt == 2) { // decode height
137  std::istringstream ss(header[0]);
138  ss >> h;
139  cpt_elt++;
140  header.erase(header.begin(),
141  header.begin() + 1); // erase first element that is processed
142  } else if (cpt_elt == 3) { // decode maxval
143  std::istringstream ss(header[0]);
144  ss >> maxval;
145  cpt_elt++;
146  header.erase(header.begin(),
147  header.begin() + 1); // erase first element that is processed
148  }
149  }
150  }
151 }
152 #endif
153 
154 vpImageIo::vpImageFormatType vpImageIo::getFormat(const std::string &filename)
155 {
156  std::string ext = vpImageIo::getExtension(filename);
157 
158  if (ext.compare(".PGM") == 0)
159  return FORMAT_PGM;
160  else if (ext.compare(".pgm") == 0)
161  return FORMAT_PGM;
162  else if (ext.compare(".PPM") == 0)
163  return FORMAT_PPM;
164  else if (ext.compare(".ppm") == 0)
165  return FORMAT_PPM;
166  else if (ext.compare(".JPG") == 0)
167  return FORMAT_JPEG;
168  else if (ext.compare(".jpg") == 0)
169  return FORMAT_JPEG;
170  else if (ext.compare(".JPEG") == 0)
171  return FORMAT_JPEG;
172  else if (ext.compare(".jpeg") == 0)
173  return FORMAT_JPEG;
174  else if (ext.compare(".PNG") == 0)
175  return FORMAT_PNG;
176  else if (ext.compare(".png") == 0)
177  return FORMAT_PNG;
178  // Formats supported by opencv
179  else if (ext.compare(".TIFF") == 0)
180  return FORMAT_TIFF;
181  else if (ext.compare(".tiff") == 0)
182  return FORMAT_TIFF;
183  else if (ext.compare(".TIF") == 0)
184  return FORMAT_TIFF;
185  else if (ext.compare(".tif") == 0)
186  return FORMAT_TIFF;
187  else if (ext.compare(".BMP") == 0)
188  return FORMAT_BMP;
189  else if (ext.compare(".bmp") == 0)
190  return FORMAT_BMP;
191  else if (ext.compare(".DIB") == 0)
192  return FORMAT_DIB;
193  else if (ext.compare(".dib") == 0)
194  return FORMAT_DIB;
195  else if (ext.compare(".PBM") == 0)
196  return FORMAT_PBM;
197  else if (ext.compare(".pbm") == 0)
198  return FORMAT_PBM;
199  else if (ext.compare(".SR") == 0)
200  return FORMAT_RASTER;
201  else if (ext.compare(".sr") == 0)
202  return FORMAT_RASTER;
203  else if (ext.compare(".RAS") == 0)
204  return FORMAT_RASTER;
205  else if (ext.compare(".ras") == 0)
206  return FORMAT_RASTER;
207  else if (ext.compare(".JP2") == 0)
208  return FORMAT_JPEG2000;
209  else if (ext.compare(".jp2") == 0)
210  return FORMAT_JPEG2000;
211  else
212  return FORMAT_UNKNOWN;
213 }
214 
215 // return the extension of the file including the dot
216 std::string vpImageIo::getExtension(const std::string &filename)
217 {
218  // extract the extension
219  size_t dot = filename.find_last_of(".");
220  std::string ext = filename.substr(dot, filename.size() - 1);
221  return ext;
222 }
223 
244 void vpImageIo::read(vpImage<unsigned char> &I, const std::string &filename)
245 {
246  bool exist = vpIoTools::checkFilename(filename);
247  if (!exist) {
248  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
250  }
251 
252  // Allows to use ~ symbol or env variables in path
253  std::string final_filename = vpIoTools::path(filename);
254 
255  bool try_opencv_reader = false;
256 
257  switch (getFormat(final_filename)) {
258  case FORMAT_PGM:
259  readPGM(I, final_filename);
260  break;
261  case FORMAT_PPM:
262  readPPM(I, final_filename);
263  break;
264  case FORMAT_JPEG:
265 #ifdef VISP_HAVE_JPEG
266  readJPEG(I, final_filename);
267 #else
268  try_opencv_reader = true;
269 #endif
270  break;
271  case FORMAT_PNG:
272 #if defined(VISP_HAVE_PNG)
273  readPNG(I, final_filename);
274 #else
275  try_opencv_reader = true;
276 #endif
277  break;
278  case FORMAT_TIFF:
279  case FORMAT_BMP:
280  case FORMAT_DIB:
281  case FORMAT_PBM:
282  case FORMAT_RASTER:
283  case FORMAT_JPEG2000:
284  case FORMAT_UNKNOWN:
285  try_opencv_reader = true;
286  break;
287  }
288 
289  if (try_opencv_reader) {
290 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
291 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
292  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
293 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
294  int flags = cv::IMREAD_GRAYSCALE;
295 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
296  int flags = CV_LOAD_IMAGE_GRAYSCALE;
297 #endif
298  // std::cout << "Use opencv to read the image" << std::endl;
299  cv::Mat cvI = cv::imread(final_filename, flags);
300  if (cvI.cols == 0 && cvI.rows == 0) {
301  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
303  }
304  vpImageConvert::convert(cvI, I);
305 #else
306  switch (getFormat(final_filename)) {
307  case FORMAT_JPEG:
308  readJPEG(I, final_filename);
309  break;
310  case FORMAT_PNG:
311  readPNG(I, final_filename);
312  break;
313  case FORMAT_BMP:
314  case FORMAT_TIFF:
315  case FORMAT_DIB:
316  case FORMAT_PBM:
317  case FORMAT_RASTER:
318  case FORMAT_JPEG2000:
319  case FORMAT_UNKNOWN:
320  default:
321  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
323  }
324 #endif
325  }
326 }
327 
348 void vpImageIo::read(vpImage<vpRGBa> &I, const std::string &filename)
349 {
350  bool exist = vpIoTools::checkFilename(filename);
351  if (!exist) {
352  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
354  }
355  // Allows to use ~ symbol or env variables in path
356  std::string final_filename = vpIoTools::path(filename);
357 
358  bool try_opencv_reader = false;
359 
360  switch (getFormat(final_filename)) {
361  case FORMAT_PGM:
362  readPGM(I, final_filename);
363  break;
364  case FORMAT_PPM:
365  readPPM(I, final_filename);
366  break;
367  case FORMAT_JPEG:
368 #ifdef VISP_HAVE_JPEG
369  readJPEG(I, final_filename);
370 #else
371  try_opencv_reader = true;
372 #endif
373  break;
374  case FORMAT_PNG:
375 #if defined(VISP_HAVE_PNG)
376  readPNG(I, final_filename);
377 #else
378  try_opencv_reader = true;
379 #endif
380  break;
381  case FORMAT_TIFF:
382  case FORMAT_BMP:
383  case FORMAT_DIB:
384  case FORMAT_PBM:
385  case FORMAT_RASTER:
386  case FORMAT_JPEG2000:
387  case FORMAT_UNKNOWN:
388  try_opencv_reader = true;
389  break;
390  }
391 
392  if (try_opencv_reader) {
393 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
394 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
395  int flags = cv::IMREAD_COLOR | cv::IMREAD_IGNORE_ORIENTATION;
396 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
397  int flags = cv::IMREAD_COLOR;
398 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
399  int flags = CV_LOAD_IMAGE_COLOR;
400 #endif
401  // std::cout << "Use opencv to read the image" << std::endl;
402  cv::Mat cvI = cv::imread(final_filename, flags);
403  if (cvI.cols == 0 && cvI.rows == 0) {
404  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
406  }
407  vpImageConvert::convert(cvI, I);
408 #else
409  switch (getFormat(final_filename)) {
410  case FORMAT_JPEG:
411  readJPEG(I, final_filename);
412  break;
413  case FORMAT_PNG:
414  readPNG(I, final_filename);
415  break;
416  case FORMAT_BMP:
417  case FORMAT_TIFF:
418  case FORMAT_DIB:
419  case FORMAT_PBM:
420  case FORMAT_RASTER:
421  case FORMAT_JPEG2000:
422  case FORMAT_UNKNOWN:
423  default:
424  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
426  }
427 #endif
428  }
429 }
430 
445 void vpImageIo::write(const vpImage<unsigned char> &I, const std::string &filename)
446 {
447  bool try_opencv_writer = false;
448 
449  switch (getFormat(filename)) {
450  case FORMAT_PGM:
451  writePGM(I, filename);
452  break;
453  case FORMAT_PPM:
454  writePPM(I, filename);
455  break;
456  case FORMAT_JPEG:
457 #ifdef VISP_HAVE_JPEG
458  writeJPEG(I, filename);
459 #else
460  try_opencv_writer = true;
461 #endif
462  break;
463  case FORMAT_PNG:
464 #ifdef VISP_HAVE_PNG
465  writePNG(I, filename);
466 #else
467  try_opencv_writer = true;
468 #endif
469  break;
470  case FORMAT_TIFF:
471  case FORMAT_BMP:
472  case FORMAT_DIB:
473  case FORMAT_PBM:
474  case FORMAT_RASTER:
475  case FORMAT_JPEG2000:
476  case FORMAT_UNKNOWN:
477  try_opencv_writer = true;
478  break;
479  }
480 
481  if (try_opencv_writer) {
482 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
483  // std::cout << "Use opencv to write the image" << std::endl;
484  cv::Mat cvI;
485  vpImageConvert::convert(I, cvI);
486  cv::imwrite(filename, cvI);
487 #else
488  switch (getFormat(filename)) {
489  case FORMAT_JPEG:
490  writeJPEG(I, filename);
491  break;
492  case FORMAT_PNG:
493  writePNG(I, filename);
494  break;
495  case FORMAT_BMP:
496  case FORMAT_TIFF:
497  case FORMAT_DIB:
498  case FORMAT_PBM:
499  case FORMAT_RASTER:
500  case FORMAT_JPEG2000:
501  case FORMAT_UNKNOWN:
502  default:
503  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
504  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
505  }
506 #endif
507  }
508 }
509 
524 void vpImageIo::write(const vpImage<vpRGBa> &I, const std::string &filename)
525 {
526  bool try_opencv_writer = false;
527 
528  switch (getFormat(filename)) {
529  case FORMAT_PGM:
530  writePGM(I, filename);
531  break;
532  case FORMAT_PPM:
533  writePPM(I, filename);
534  break;
535  case FORMAT_JPEG:
536 #ifdef VISP_HAVE_JPEG
537  writeJPEG(I, filename);
538 #else
539  try_opencv_writer = true;
540 #endif
541  break;
542  case FORMAT_PNG:
543 #ifdef VISP_HAVE_PNG
544  writePNG(I, filename);
545 #else
546  try_opencv_writer = true;
547 #endif
548  break;
549  case FORMAT_TIFF:
550  case FORMAT_BMP:
551  case FORMAT_DIB:
552  case FORMAT_PBM:
553  case FORMAT_RASTER:
554  case FORMAT_JPEG2000:
555  case FORMAT_UNKNOWN:
556  try_opencv_writer = true;
557  break;
558  }
559 
560  if (try_opencv_writer) {
561 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
562  // std::cout << "Use opencv to write the image" << std::endl;
563  cv::Mat cvI;
564  vpImageConvert::convert(I, cvI);
565  cv::imwrite(filename, cvI);
566 #else
567  switch (getFormat(filename)) {
568  case FORMAT_JPEG:
569  writeJPEG(I, filename);
570  break;
571  case FORMAT_PNG:
572  writePNG(I, filename);
573  break;
574  case FORMAT_BMP:
575  case FORMAT_TIFF:
576  case FORMAT_DIB:
577  case FORMAT_PBM:
578  case FORMAT_RASTER:
579  case FORMAT_JPEG2000:
580  case FORMAT_UNKNOWN:
581  default:
582  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
583  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
584  }
585 #endif
586  }
587 }
588 
589 //--------------------------------------------------------------------------
590 // PFM
591 //--------------------------------------------------------------------------
592 
602 void vpImageIo::writePFM(const vpImage<float> &I, const std::string &filename)
603 {
604  FILE *fd;
605 
606  // Test the filename
607  if (filename.empty()) {
608  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
609  }
610 
611  fd = fopen(filename.c_str(), "wb");
612 
613  if (fd == NULL) {
614  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
615  }
616 
617  // Write the head
618  fprintf(fd, "P8\n"); // Magic number
619  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
620  fprintf(fd, "255\n"); // Max level
621 
622  // Write the bitmap
623  size_t ierr;
624  size_t nbyte = I.getWidth() * I.getHeight();
625 
626  ierr = fwrite(I.bitmap, sizeof(float), nbyte, fd);
627  if (ierr != nbyte) {
628  fclose(fd);
629  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
630  filename.c_str(), ierr, nbyte));
631  }
632 
633  fflush(fd);
634  fclose(fd);
635 }
636 //--------------------------------------------------------------------------
637 // PGM
638 //--------------------------------------------------------------------------
639 
648 void vpImageIo::writePGM(const vpImage<unsigned char> &I, const std::string &filename)
649 {
650 
651  FILE *fd;
652 
653  // Test the filename
654  if (filename.empty()) {
655  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
656  }
657 
658  fd = fopen(filename.c_str(), "wb");
659 
660  if (fd == NULL) {
661  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
662  }
663 
664  // Write the head
665  fprintf(fd, "P5\n"); // Magic number
666  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
667  fprintf(fd, "255\n"); // Max level
668 
669  // Write the bitmap
670  size_t ierr;
671  size_t nbyte = I.getWidth() * I.getHeight();
672 
673  ierr = fwrite(I.bitmap, sizeof(unsigned char), nbyte, fd);
674  if (ierr != nbyte) {
675  fclose(fd);
676  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
677  filename.c_str(), ierr, nbyte));
678  }
679 
680  fflush(fd);
681  fclose(fd);
682 }
683 
691 void vpImageIo::writePGM(const vpImage<short> &I, const std::string &filename)
692 {
694  unsigned int nrows = I.getHeight();
695  unsigned int ncols = I.getWidth();
696 
697  Iuc.resize(nrows, ncols);
698 
699  for (unsigned int i = 0; i < nrows * ncols; i++)
700  Iuc.bitmap[i] = (unsigned char)I.bitmap[i];
701 
702  vpImageIo::writePGM(Iuc, filename);
703 }
713 void vpImageIo::writePGM(const vpImage<vpRGBa> &I, const std::string &filename)
714 {
715 
716  FILE *fd;
717 
718  // Test the filename
719  if (filename.empty()) {
720  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
721  }
722 
723  fd = fopen(filename.c_str(), "wb");
724 
725  if (fd == NULL) {
726  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
727  }
728 
729  // Write the head
730  fprintf(fd, "P5\n"); // Magic number
731  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
732  fprintf(fd, "255\n"); // Max level
733 
734  // Write the bitmap
735  size_t ierr;
736  size_t nbyte = I.getWidth() * I.getHeight();
737 
739  vpImageConvert::convert(I, Itmp);
740 
741  ierr = fwrite(Itmp.bitmap, sizeof(unsigned char), nbyte, fd);
742  if (ierr != nbyte) {
743  fclose(fd);
744  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
745  filename.c_str(), ierr, nbyte));
746  }
747 
748  fflush(fd);
749  fclose(fd);
750 }
751 
768 void vpImageIo::readPFM(vpImage<float> &I, const std::string &filename)
769 {
770  unsigned int w = 0, h = 0, maxval = 0;
771  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
772  std::string magic("P8");
773 
774  std::ifstream fd(filename.c_str(), std::ios::binary);
775 
776  // Open the filename
777  if (!fd.is_open()) {
778  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
779  }
780 
781  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
782 
783  if (w > w_max || h > h_max) {
784  fd.close();
785  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
786  }
787  if (maxval > maxval_max) {
788  fd.close();
789  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
790  }
791 
792  if ((h != I.getHeight()) || (w != I.getWidth())) {
793  I.resize(h, w);
794  }
795 
796  unsigned int nbyte = I.getHeight() * I.getWidth();
797  fd.read((char *)I.bitmap, sizeof(float) * nbyte);
798  if (!fd) {
799  fd.close();
800  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
801  filename.c_str()));
802  }
803 
804  fd.close();
805 }
806 
822 void vpImageIo::readPGM(vpImage<unsigned char> &I, const std::string &filename)
823 {
824  unsigned int w = 0, h = 0, maxval = 0;
825  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
826  std::string magic("P5");
827 
828  std::ifstream fd(filename.c_str(), std::ios::binary);
829 
830  // Open the filename
831  if (!fd.is_open()) {
832  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
833  }
834 
835  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
836 
837  if (w > w_max || h > h_max) {
838  fd.close();
839  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
840  }
841  if (maxval > maxval_max) {
842  fd.close();
843  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
844  }
845 
846  if ((h != I.getHeight()) || (w != I.getWidth())) {
847  I.resize(h, w);
848  }
849 
850  unsigned int nbyte = I.getHeight() * I.getWidth();
851  fd.read((char *)I.bitmap, nbyte);
852  if (!fd) {
853  fd.close();
854  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
855  filename.c_str()));
856  }
857 
858  fd.close();
859 }
860 
879 void vpImageIo::readPGM(vpImage<vpRGBa> &I, const std::string &filename)
880 {
882 
883  vpImageIo::readPGM(Itmp, filename);
884 
885  vpImageConvert::convert(Itmp, I);
886 }
887 
888 //--------------------------------------------------------------------------
889 // PPM
890 //--------------------------------------------------------------------------
891 
908 void vpImageIo::readPPM(vpImage<unsigned char> &I, const std::string &filename)
909 {
910  vpImage<vpRGBa> Itmp;
911 
912  vpImageIo::readPPM(Itmp, filename);
913 
914  vpImageConvert::convert(Itmp, I);
915 }
916 
928 void vpImageIo::readPPM(vpImage<vpRGBa> &I, const std::string &filename)
929 {
930  unsigned int w = 0, h = 0, maxval = 0;
931  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
932  std::string magic("P6");
933 
934  std::ifstream fd(filename.c_str(), std::ios::binary);
935 
936  // Open the filename
937  if (!fd.is_open()) {
938  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
939  }
940 
941  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
942 
943  if (w > w_max || h > h_max) {
944  fd.close();
945  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
946  }
947  if (maxval > maxval_max) {
948  fd.close();
949  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
950  }
951 
952  if ((h != I.getHeight()) || (w != I.getWidth())) {
953  I.resize(h, w);
954  }
955 
956  for (unsigned int i = 0; i < I.getHeight(); i++) {
957  for (unsigned int j = 0; j < I.getWidth(); j++) {
958  unsigned char rgb[3];
959  fd.read((char *)&rgb, 3);
960 
961  if (!fd) {
962  fd.close();
963  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"",
964  (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
965  }
966 
967  I[i][j].R = rgb[0];
968  I[i][j].G = rgb[1];
969  I[i][j].B = rgb[2];
970  I[i][j].A = vpRGBa::alpha_default;
971  }
972  }
973 
974  fd.close();
975 }
976 
987 void vpImageIo::writePPM(const vpImage<unsigned char> &I, const std::string &filename)
988 {
989  vpImage<vpRGBa> Itmp;
990 
991  vpImageConvert::convert(I, Itmp);
992 
993  vpImageIo::writePPM(Itmp, filename);
994 }
995 
1003 void vpImageIo::writePPM(const vpImage<vpRGBa> &I, const std::string &filename)
1004 {
1005  FILE *f;
1006 
1007  // Test the filename
1008  if (filename.empty()) {
1009  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file: filename empty"));
1010  }
1011 
1012  f = fopen(filename.c_str(), "wb");
1013 
1014  if (f == NULL) {
1015  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file \"%s\"", filename.c_str()));
1016  }
1017 
1018  fprintf(f, "P6\n"); // Magic number
1019  fprintf(f, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
1020  fprintf(f, "%d\n", 255); // Max level
1021 
1022  for (unsigned int i = 0; i < I.getHeight(); i++) {
1023  for (unsigned int j = 0; j < I.getWidth(); j++) {
1024  vpRGBa v = I[i][j];
1025  unsigned char rgb[3];
1026  rgb[0] = v.R;
1027  rgb[1] = v.G;
1028  rgb[2] = v.B;
1029 
1030  size_t res = fwrite(&rgb, 1, 3, f);
1031  if (res != 3) {
1032  fclose(f);
1033  throw(vpImageException(vpImageException::ioError, "cannot write file \"%s\"", filename.c_str()));
1034  }
1035  }
1036  }
1037 
1038  fflush(f);
1039  fclose(f);
1040 }
1041 
1042 //--------------------------------------------------------------------------
1043 // JPEG
1044 //--------------------------------------------------------------------------
1045 
1046 #if defined(VISP_HAVE_JPEG)
1047 
1055 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1056 {
1057  struct jpeg_compress_struct cinfo;
1058  struct jpeg_error_mgr jerr;
1059  FILE *file;
1060 
1061  cinfo.err = jpeg_std_error(&jerr);
1062  jpeg_create_compress(&cinfo);
1063 
1064  // Test the filename
1065  if (filename.empty()) {
1066  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1067  }
1068 
1069  file = fopen(filename.c_str(), "wb");
1070 
1071  if (file == NULL) {
1072  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1073  }
1074 
1075  unsigned int width = I.getWidth();
1076  unsigned int height = I.getHeight();
1077 
1078  jpeg_stdio_dest(&cinfo, file);
1079 
1080  cinfo.image_width = width;
1081  cinfo.image_height = height;
1082  cinfo.input_components = 1;
1083  cinfo.in_color_space = JCS_GRAYSCALE;
1084  jpeg_set_defaults(&cinfo);
1085 
1086  jpeg_start_compress(&cinfo, TRUE);
1087 
1088  unsigned char *line;
1089  line = new unsigned char[width];
1090  unsigned char *input = (unsigned char *)I.bitmap;
1091  while (cinfo.next_scanline < cinfo.image_height) {
1092  for (unsigned int i = 0; i < width; i++) {
1093  line[i] = *(input);
1094  input++;
1095  }
1096  jpeg_write_scanlines(&cinfo, &line, 1);
1097  }
1098 
1099  jpeg_finish_compress(&cinfo);
1100  jpeg_destroy_compress(&cinfo);
1101  delete[] line;
1102  fclose(file);
1103 }
1104 
1112 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1113 {
1114  struct jpeg_compress_struct cinfo;
1115  struct jpeg_error_mgr jerr;
1116  FILE *file;
1117 
1118  cinfo.err = jpeg_std_error(&jerr);
1119  jpeg_create_compress(&cinfo);
1120 
1121  // Test the filename
1122  if (filename.empty()) {
1123  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1124  }
1125 
1126  file = fopen(filename.c_str(), "wb");
1127 
1128  if (file == NULL) {
1129  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1130  }
1131 
1132  unsigned int width = I.getWidth();
1133  unsigned int height = I.getHeight();
1134 
1135  jpeg_stdio_dest(&cinfo, file);
1136 
1137  cinfo.image_width = width;
1138  cinfo.image_height = height;
1139  cinfo.input_components = 3;
1140  cinfo.in_color_space = JCS_RGB;
1141  jpeg_set_defaults(&cinfo);
1142 
1143  jpeg_start_compress(&cinfo, TRUE);
1144 
1145  unsigned char *line;
1146  line = new unsigned char[3 * width];
1147  unsigned char *input = (unsigned char *)I.bitmap;
1148  while (cinfo.next_scanline < cinfo.image_height) {
1149  for (unsigned int i = 0; i < width; i++) {
1150  line[i * 3] = *(input);
1151  input++;
1152  line[i * 3 + 1] = *(input);
1153  input++;
1154  line[i * 3 + 2] = *(input);
1155  input++;
1156  input++;
1157  }
1158  jpeg_write_scanlines(&cinfo, &line, 1);
1159  }
1160 
1161  jpeg_finish_compress(&cinfo);
1162  jpeg_destroy_compress(&cinfo);
1163  delete[] line;
1164  fclose(file);
1165 }
1166 
1183 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1184 {
1185  struct jpeg_decompress_struct cinfo;
1186  struct jpeg_error_mgr jerr;
1187  FILE *file;
1188 
1189  cinfo.err = jpeg_std_error(&jerr);
1190  jpeg_create_decompress(&cinfo);
1191 
1192  // Test the filename
1193  if (filename.empty()) {
1194  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1195  }
1196 
1197  file = fopen(filename.c_str(), "rb");
1198 
1199  if (file == NULL) {
1200  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1201  }
1202 
1203  jpeg_stdio_src(&cinfo, file);
1204  jpeg_read_header(&cinfo, TRUE);
1205 
1206  unsigned int width = cinfo.image_width;
1207  unsigned int height = cinfo.image_height;
1208 
1209  if ((width != I.getWidth()) || (height != I.getHeight()))
1210  I.resize(height, width);
1211 
1212  jpeg_start_decompress(&cinfo);
1213 
1214  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1215  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1216 
1217  if (cinfo.out_color_space == JCS_RGB) {
1218  vpImage<vpRGBa> Ic(height, width);
1219  unsigned char *output = (unsigned char *)Ic.bitmap;
1220  while (cinfo.output_scanline < cinfo.output_height) {
1221  jpeg_read_scanlines(&cinfo, buffer, 1);
1222  for (unsigned int i = 0; i < width; i++) {
1223  *(output++) = buffer[0][i * 3];
1224  *(output++) = buffer[0][i * 3 + 1];
1225  *(output++) = buffer[0][i * 3 + 2];
1226  *(output++) = vpRGBa::alpha_default;
1227  }
1228  }
1229  vpImageConvert::convert(Ic, I);
1230  }
1231 
1232  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1233  while (cinfo.output_scanline < cinfo.output_height) {
1234  unsigned int row = cinfo.output_scanline;
1235  jpeg_read_scanlines(&cinfo, buffer, 1);
1236  memcpy(I[row], buffer[0], rowbytes);
1237  }
1238  }
1239 
1240  jpeg_finish_decompress(&cinfo);
1241  jpeg_destroy_decompress(&cinfo);
1242  fclose(file);
1243 }
1244 
1263 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1264 {
1265  struct jpeg_decompress_struct cinfo;
1266  struct jpeg_error_mgr jerr;
1267  FILE *file;
1268 
1269  cinfo.err = jpeg_std_error(&jerr);
1270  jpeg_create_decompress(&cinfo);
1271 
1272  // Test the filename
1273  if (filename.empty()) {
1274  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1275  }
1276 
1277  file = fopen(filename.c_str(), "rb");
1278 
1279  if (file == NULL) {
1280  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1281  }
1282 
1283  jpeg_stdio_src(&cinfo, file);
1284 
1285  jpeg_read_header(&cinfo, TRUE);
1286 
1287  unsigned int width = cinfo.image_width;
1288  unsigned int height = cinfo.image_height;
1289 
1290  if ((width != I.getWidth()) || (height != I.getHeight()))
1291  I.resize(height, width);
1292 
1293  jpeg_start_decompress(&cinfo);
1294 
1295  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1296  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1297 
1298  if (cinfo.out_color_space == JCS_RGB) {
1299  unsigned char *output = (unsigned char *)I.bitmap;
1300  while (cinfo.output_scanline < cinfo.output_height) {
1301  jpeg_read_scanlines(&cinfo, buffer, 1);
1302  for (unsigned int i = 0; i < width; i++) {
1303  *(output++) = buffer[0][i * 3];
1304  *(output++) = buffer[0][i * 3 + 1];
1305  *(output++) = buffer[0][i * 3 + 2];
1306  *(output++) = vpRGBa::alpha_default;
1307  }
1308  }
1309  }
1310 
1311  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1312  vpImage<unsigned char> Ig(height, width);
1313 
1314  while (cinfo.output_scanline < cinfo.output_height) {
1315  unsigned int row = cinfo.output_scanline;
1316  jpeg_read_scanlines(&cinfo, buffer, 1);
1317  memcpy(Ig[row], buffer[0], rowbytes);
1318  }
1319 
1320  vpImageConvert::convert(Ig, I);
1321  }
1322 
1323  jpeg_finish_decompress(&cinfo);
1324  jpeg_destroy_decompress(&cinfo);
1325  fclose(file);
1326 }
1327 
1328 #elif defined(VISP_HAVE_OPENCV)
1329 
1337 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1338 {
1339 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1340  cv::Mat Ip;
1341  vpImageConvert::convert(I, Ip);
1342  cv::imwrite(filename.c_str(), Ip);
1343 #else
1344  IplImage *Ip = NULL;
1345  vpImageConvert::convert(I, Ip);
1346 
1347  cvSaveImage(filename.c_str(), Ip);
1348 
1349  cvReleaseImage(&Ip);
1350 #endif
1351 }
1352 
1360 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1361 {
1362 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1363  cv::Mat Ip;
1364  vpImageConvert::convert(I, Ip);
1365  cv::imwrite(filename.c_str(), Ip);
1366 #else
1367  IplImage *Ip = NULL;
1368  vpImageConvert::convert(I, Ip);
1369 
1370  cvSaveImage(filename.c_str(), Ip);
1371 
1372  cvReleaseImage(&Ip);
1373 #endif
1374 }
1375 
1394 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1395 {
1396 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
1397 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
1398  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
1399 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
1400  int flags = cv::IMREAD_GRAYSCALE;
1401 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
1402  int flags = CV_LOAD_IMAGE_GRAYSCALE;
1403 #endif
1404  cv::Mat Ip = cv::imread(filename.c_str(), flags);
1405  if (!Ip.empty())
1406  vpImageConvert::convert(Ip, I);
1407  else
1408  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1409 #else
1410  IplImage *Ip = NULL;
1411  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1412  if (Ip != NULL)
1413  vpImageConvert::convert(Ip, I);
1414  else
1415  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1416  cvReleaseImage(&Ip);
1417 #endif
1418 }
1419 
1440 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1441 {
1442 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
1443 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
1444  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
1445 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
1446  int flags = cv::IMREAD_GRAYSCALE;
1447 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
1448  int flags = CV_LOAD_IMAGE_GRAYSCALE;
1449 #endif
1450  cv::Mat Ip = cv::imread(filename.c_str(), flags);
1451  if (!Ip.empty())
1452  vpImageConvert::convert(Ip, I);
1453  else
1454  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1455 #else
1456  IplImage *Ip = NULL;
1457  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
1458  if (Ip != NULL)
1459  vpImageConvert::convert(Ip, I);
1460  else
1461  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1462  cvReleaseImage(&Ip);
1463 #endif
1464 }
1465 #else
1466 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1467 {
1468  int width = 0, height = 0, channels = 0;
1469  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
1470  if (image == NULL) {
1471  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1472  }
1473  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1474  stbi_image_free(image);
1475 }
1476 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1477 {
1478  int width = 0, height = 0, channels = 0;
1479  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
1480  if (image == NULL) {
1481  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1482  }
1483  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1484  stbi_image_free(image);
1485 }
1486 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1487 {
1488  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
1489  reinterpret_cast<void*>(I.bitmap), 90);
1490  if (res == 0) {
1491  throw(vpImageException(vpImageException::ioError, "JPEG write error"));
1492  }
1493 }
1494 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1495 {
1496  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
1497  reinterpret_cast<void*>(I.bitmap), 90);
1498  if (res == 0) {
1499  throw(vpImageException(vpImageException::ioError, "JEPG write error"));
1500  }
1501 }
1502 #endif
1503 
1504 //--------------------------------------------------------------------------
1505 // PNG
1506 //--------------------------------------------------------------------------
1507 
1508 #if defined(VISP_HAVE_PNG)
1509 
1517 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1518 {
1519  FILE *file;
1520 
1521  // Test the filename
1522  if (filename.empty()) {
1523  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1524  }
1525 
1526  file = fopen(filename.c_str(), "wb");
1527 
1528  if (file == NULL) {
1529  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1530  }
1531 
1532  /* create a png info struct */
1533  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1534  if (!png_ptr) {
1535  fclose(file);
1536  vpERROR_TRACE("Error during png_create_write_struct()\n");
1537  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1538  }
1539 
1540  png_infop info_ptr = png_create_info_struct(png_ptr);
1541  if (!info_ptr) {
1542  fclose(file);
1543  png_destroy_write_struct(&png_ptr, NULL);
1544  vpERROR_TRACE("Error during png_create_info_struct()\n");
1545  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1546  }
1547 
1548  /* initialize the setjmp for returning properly after a libpng error occured
1549  */
1550  if (setjmp(png_jmpbuf(png_ptr))) {
1551  fclose(file);
1552  png_destroy_write_struct(&png_ptr, &info_ptr);
1553  vpERROR_TRACE("Error during init_io\n");
1554  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1555  }
1556 
1557  /* setup libpng for using standard C fwrite() function with our FILE pointer
1558  */
1559  png_init_io(png_ptr, file);
1560 
1561  unsigned int width = I.getWidth();
1562  unsigned int height = I.getHeight();
1563  int bit_depth = 8;
1564  int color_type = PNG_COLOR_TYPE_GRAY;
1565  /* set some useful information from header */
1566 
1567  if (setjmp(png_jmpbuf(png_ptr))) {
1568  fclose(file);
1569  png_destroy_write_struct(&png_ptr, &info_ptr);
1570  vpERROR_TRACE("Error during write header\n");
1571  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1572  }
1573 
1574  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1575  PNG_FILTER_TYPE_BASE);
1576 
1577  png_write_info(png_ptr, info_ptr);
1578 
1579  png_bytep *row_ptrs = new png_bytep[height];
1580  for (unsigned int i = 0; i < height; i++)
1581  row_ptrs[i] = new png_byte[width];
1582 
1583  unsigned char *input = (unsigned char *)I.bitmap;
1584 
1585  for (unsigned int i = 0; i < height; i++) {
1586  png_byte *row = row_ptrs[i];
1587  for (unsigned int j = 0; j < width; j++) {
1588  row[j] = *(input);
1589  input++;
1590  }
1591  }
1592 
1593  png_write_image(png_ptr, row_ptrs);
1594 
1595  png_write_end(png_ptr, NULL);
1596 
1597  for (unsigned int j = 0; j < height; j++)
1598  delete[] row_ptrs[j];
1599 
1600  delete[] row_ptrs;
1601 
1602  png_destroy_write_struct(&png_ptr, &info_ptr);
1603 
1604  fclose(file);
1605 }
1606 
1614 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1615 {
1616  FILE *file;
1617 
1618  // Test the filename
1619  if (filename.empty()) {
1620  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1621  }
1622 
1623  file = fopen(filename.c_str(), "wb");
1624 
1625  if (file == NULL) {
1626  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1627  }
1628 
1629  /* create a png info struct */
1630  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1631  if (!png_ptr) {
1632  fclose(file);
1633  vpERROR_TRACE("Error during png_create_write_struct()\n");
1634  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1635  }
1636 
1637  png_infop info_ptr = png_create_info_struct(png_ptr);
1638  if (!info_ptr) {
1639  fclose(file);
1640  png_destroy_write_struct(&png_ptr, NULL);
1641  vpERROR_TRACE("Error during png_create_info_struct()\n");
1642  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1643  }
1644 
1645  /* initialize the setjmp for returning properly after a libpng error occured
1646  */
1647  if (setjmp(png_jmpbuf(png_ptr))) {
1648  fclose(file);
1649  png_destroy_write_struct(&png_ptr, &info_ptr);
1650  vpERROR_TRACE("Error during init_io\n");
1651  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1652  }
1653 
1654  /* setup libpng for using standard C fwrite() function with our FILE pointer
1655  */
1656  png_init_io(png_ptr, file);
1657 
1658  unsigned int width = I.getWidth();
1659  unsigned int height = I.getHeight();
1660  int bit_depth = 8;
1661  int color_type = PNG_COLOR_TYPE_RGB;
1662  /* set some useful information from header */
1663 
1664  if (setjmp(png_jmpbuf(png_ptr))) {
1665  fclose(file);
1666  png_destroy_write_struct(&png_ptr, &info_ptr);
1667  vpERROR_TRACE("Error during write header\n");
1668  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1669  }
1670 
1671  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1672  PNG_FILTER_TYPE_BASE);
1673 
1674  png_write_info(png_ptr, info_ptr);
1675 
1676  png_bytep *row_ptrs = new png_bytep[height];
1677  for (unsigned int i = 0; i < height; i++)
1678  row_ptrs[i] = new png_byte[3 * width];
1679 
1680  unsigned char *input = (unsigned char *)I.bitmap;
1681  ;
1682 
1683  for (unsigned int i = 0; i < height; i++) {
1684  png_byte *row = row_ptrs[i];
1685  for (unsigned int j = 0; j < width; j++) {
1686  row[3 * j] = *(input);
1687  input++;
1688  row[3 * j + 1] = *(input);
1689  input++;
1690  row[3 * j + 2] = *(input);
1691  input++;
1692  input++;
1693  }
1694  }
1695 
1696  png_write_image(png_ptr, row_ptrs);
1697 
1698  png_write_end(png_ptr, NULL);
1699 
1700  for (unsigned int j = 0; j < height; j++)
1701  delete[] row_ptrs[j];
1702 
1703  delete[] row_ptrs;
1704 
1705  png_destroy_write_struct(&png_ptr, &info_ptr);
1706 
1707  fclose(file);
1708 }
1709 
1726 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1727 {
1728  FILE *file;
1729  png_byte magic[8];
1730  // Test the filename
1731  if (filename.empty()) {
1732  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1733  }
1734 
1735  file = fopen(filename.c_str(), "rb");
1736 
1737  if (file == NULL) {
1738  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1739  }
1740 
1741  /* read magic number */
1742  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1743  fclose(file);
1744  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1745  }
1746 
1747  /* check for valid magic number */
1748  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1749  fclose(file);
1750  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1751  filename.c_str()));
1752  }
1753 
1754  /* create a png read struct */
1755  // printf("version %s\n", PNG_LIBPNG_VER_STRING);
1756  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1757  if (png_ptr == NULL) {
1758  fprintf(stderr, "error: can't create a png read structure!\n");
1759  fclose(file);
1760  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1761  }
1762 
1763  /* create a png info struct */
1764  png_infop info_ptr = png_create_info_struct(png_ptr);
1765  if (info_ptr == NULL) {
1766  fprintf(stderr, "error: can't create a png info structure!\n");
1767  fclose(file);
1768  png_destroy_read_struct(&png_ptr, NULL, NULL);
1769  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1770  }
1771 
1772  /* initialize the setjmp for returning properly after a libpng error occured
1773  */
1774  if (setjmp(png_jmpbuf(png_ptr))) {
1775  fclose(file);
1776  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1777  vpERROR_TRACE("Error during init io\n");
1778  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1779  }
1780 
1781  /* setup libpng for using standard C fread() function with our FILE pointer
1782  */
1783  png_init_io(png_ptr, file);
1784 
1785  /* tell libpng that we have already read the magic number */
1786  png_set_sig_bytes(png_ptr, sizeof(magic));
1787 
1788  /* read png info */
1789  png_read_info(png_ptr, info_ptr);
1790 
1791  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1792  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1793 
1794  unsigned int bit_depth, channels, color_type;
1795  /* get some useful information from header */
1796  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1797  channels = png_get_channels(png_ptr, info_ptr);
1798  color_type = png_get_color_type(png_ptr, info_ptr);
1799 
1800  /* convert index color images to RGB images */
1801  if (color_type == PNG_COLOR_TYPE_PALETTE)
1802  png_set_palette_to_rgb(png_ptr);
1803 
1804  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1805  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1806  png_set_expand(png_ptr);
1807 
1808  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1809  // png_set_tRNS_to_alpha (png_ptr);
1810 
1811  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1812  png_set_strip_alpha(png_ptr);
1813 
1814  if (bit_depth == 16)
1815  png_set_strip_16(png_ptr);
1816  else if (bit_depth < 8)
1817  png_set_packing(png_ptr);
1818 
1819  /* update info structure to apply transformations */
1820  png_read_update_info(png_ptr, info_ptr);
1821 
1822  channels = png_get_channels(png_ptr, info_ptr);
1823 
1824  if ((width != I.getWidth()) || (height != I.getHeight()))
1825  I.resize(height, width);
1826 
1827  png_bytep *rowPtrs = new png_bytep[height];
1828 
1829  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1830  unsigned char *data = new unsigned char[stride * height];
1831 
1832  for (unsigned int i = 0; i < height; i++)
1833  rowPtrs[i] = (png_bytep)data + (i * stride);
1834 
1835  png_read_image(png_ptr, rowPtrs);
1836 
1837  vpImage<vpRGBa> Ic(height, width);
1838  unsigned char *output;
1839 
1840  switch (channels) {
1841  case 1:
1842  output = (unsigned char *)I.bitmap;
1843  for (unsigned int i = 0; i < width * height; i++) {
1844  *(output++) = data[i];
1845  }
1846  break;
1847 
1848  case 2:
1849  output = (unsigned char *)I.bitmap;
1850  for (unsigned int i = 0; i < width * height; i++) {
1851  *(output++) = data[i * 2];
1852  }
1853  break;
1854 
1855  case 3:
1856  output = (unsigned char *)Ic.bitmap;
1857  for (unsigned int i = 0; i < width * height; i++) {
1858  *(output++) = data[i * 3];
1859  *(output++) = data[i * 3 + 1];
1860  *(output++) = data[i * 3 + 2];
1861  *(output++) = vpRGBa::alpha_default;
1862  }
1863  vpImageConvert::convert(Ic, I);
1864  break;
1865 
1866  case 4:
1867  output = (unsigned char *)Ic.bitmap;
1868  for (unsigned int i = 0; i < width * height; i++) {
1869  *(output++) = data[i * 4];
1870  *(output++) = data[i * 4 + 1];
1871  *(output++) = data[i * 4 + 2];
1872  *(output++) = data[i * 4 + 3];
1873  }
1874  vpImageConvert::convert(Ic, I);
1875  break;
1876  }
1877 
1878  delete[](png_bytep) rowPtrs;
1879  delete[] data;
1880  png_read_end(png_ptr, NULL);
1881  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1882  fclose(file);
1883 }
1884 
1903 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
1904 {
1905  FILE *file;
1906  png_byte magic[8];
1907 
1908  // Test the filename
1909  if (filename.empty()) {
1910  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1911  }
1912 
1913  file = fopen(filename.c_str(), "rb");
1914 
1915  if (file == NULL) {
1916  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1917  }
1918 
1919  /* read magic number */
1920  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1921  fclose(file);
1922  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1923  }
1924 
1925  /* check for valid magic number */
1926  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1927  fclose(file);
1928  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1929  filename.c_str()));
1930  }
1931 
1932  /* create a png read struct */
1933  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1934  if (!png_ptr) {
1935  fclose(file);
1936  vpERROR_TRACE("Error during png_create_read_struct()\n");
1937  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1938  }
1939 
1940  /* create a png info struct */
1941  png_infop info_ptr = png_create_info_struct(png_ptr);
1942  if (!info_ptr) {
1943  fclose(file);
1944  png_destroy_read_struct(&png_ptr, NULL, NULL);
1945  vpERROR_TRACE("Error during png_create_info_struct()\n");
1946  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1947  }
1948 
1949  /* initialize the setjmp for returning properly after a libpng error occured
1950  */
1951  if (setjmp(png_jmpbuf(png_ptr))) {
1952  fclose(file);
1953  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1954  vpERROR_TRACE("Error during init io\n");
1955  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1956  }
1957 
1958  /* setup libpng for using standard C fread() function with our FILE pointer
1959  */
1960  png_init_io(png_ptr, file);
1961 
1962  /* tell libpng that we have already read the magic number */
1963  png_set_sig_bytes(png_ptr, sizeof(magic));
1964 
1965  /* read png info */
1966  png_read_info(png_ptr, info_ptr);
1967 
1968  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1969  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1970 
1971  unsigned int bit_depth, channels, color_type;
1972  /* get some useful information from header */
1973  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1974  channels = png_get_channels(png_ptr, info_ptr);
1975  color_type = png_get_color_type(png_ptr, info_ptr);
1976 
1977  /* convert index color images to RGB images */
1978  if (color_type == PNG_COLOR_TYPE_PALETTE)
1979  png_set_palette_to_rgb(png_ptr);
1980 
1981  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1982  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1983  png_set_expand(png_ptr);
1984 
1985  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1986  // png_set_tRNS_to_alpha (png_ptr);
1987 
1988  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1989  png_set_strip_alpha(png_ptr);
1990 
1991  if (bit_depth == 16)
1992  png_set_strip_16(png_ptr);
1993  else if (bit_depth < 8)
1994  png_set_packing(png_ptr);
1995 
1996  /* update info structure to apply transformations */
1997  png_read_update_info(png_ptr, info_ptr);
1998 
1999  channels = png_get_channels(png_ptr, info_ptr);
2000 
2001  if ((width != I.getWidth()) || (height != I.getHeight()))
2002  I.resize(height, width);
2003 
2004  png_bytep *rowPtrs = new png_bytep[height];
2005 
2006  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
2007  unsigned char *data = new unsigned char[stride * height];
2008 
2009  for (unsigned int i = 0; i < height; i++)
2010  rowPtrs[i] = (png_bytep)data + (i * stride);
2011 
2012  png_read_image(png_ptr, rowPtrs);
2013 
2014  vpImage<unsigned char> Ig(height, width);
2015  unsigned char *output;
2016 
2017  switch (channels) {
2018  case 1:
2019  output = (unsigned char *)Ig.bitmap;
2020  for (unsigned int i = 0; i < width * height; i++) {
2021  *(output++) = data[i];
2022  }
2023  vpImageConvert::convert(Ig, I);
2024  break;
2025 
2026  case 2:
2027  output = (unsigned char *)Ig.bitmap;
2028  for (unsigned int i = 0; i < width * height; i++) {
2029  *(output++) = data[i * 2];
2030  }
2031  vpImageConvert::convert(Ig, I);
2032  break;
2033 
2034  case 3:
2035  output = (unsigned char *)I.bitmap;
2036  for (unsigned int i = 0; i < width * height; i++) {
2037  *(output++) = data[i * 3];
2038  *(output++) = data[i * 3 + 1];
2039  *(output++) = data[i * 3 + 2];
2040  *(output++) = vpRGBa::alpha_default;
2041  }
2042  break;
2043 
2044  case 4:
2045  output = (unsigned char *)I.bitmap;
2046  for (unsigned int i = 0; i < width * height; i++) {
2047  *(output++) = data[i * 4];
2048  *(output++) = data[i * 4 + 1];
2049  *(output++) = data[i * 4 + 2];
2050  *(output++) = data[i * 4 + 3];
2051  }
2052  break;
2053  }
2054 
2055  delete[](png_bytep) rowPtrs;
2056  delete[] data;
2057  png_read_end(png_ptr, NULL);
2058  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2059  fclose(file);
2060 }
2061 
2062 #elif defined(VISP_HAVE_OPENCV)
2063 
2071 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2072 {
2073 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2074  cv::Mat Ip;
2075  vpImageConvert::convert(I, Ip);
2076  cv::imwrite(filename.c_str(), Ip);
2077 #else
2078  IplImage *Ip = NULL;
2079  vpImageConvert::convert(I, Ip);
2080 
2081  cvSaveImage(filename.c_str(), Ip);
2082 
2083  cvReleaseImage(&Ip);
2084 #endif
2085 }
2086 
2094 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2095 {
2096 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2097  cv::Mat Ip;
2098  vpImageConvert::convert(I, Ip);
2099  cv::imwrite(filename.c_str(), Ip);
2100 #else
2101  IplImage *Ip = NULL;
2102  vpImageConvert::convert(I, Ip);
2103 
2104  cvSaveImage(filename.c_str(), Ip);
2105 
2106  cvReleaseImage(&Ip);
2107 #endif
2108 }
2109 
2128 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2129 {
2130 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
2131 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
2132  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
2133 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
2134  int flags = cv::IMREAD_GRAYSCALE;
2135 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
2136  int flags = CV_LOAD_IMAGE_GRAYSCALE;
2137 #endif
2138  cv::Mat Ip = cv::imread(filename.c_str(), flags);
2139  if (!Ip.empty())
2140  vpImageConvert::convert(Ip, I);
2141  else
2142  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2143 #else
2144  IplImage *Ip = NULL;
2145  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2146  if (Ip != NULL)
2147  vpImageConvert::convert(Ip, I);
2148  else
2149  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2150  cvReleaseImage(&Ip);
2151 #endif
2152 }
2153 
2174 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2175 {
2176 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
2177 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
2178  int flags = cv::IMREAD_COLOR | cv::IMREAD_IGNORE_ORIENTATION;
2179 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
2180  int flags = cv::IMREAD_COLOR;
2181 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
2182  int flags = CV_LOAD_IMAGE_COLOR;
2183 #endif
2184  cv::Mat Ip = cv::imread(filename.c_str(), flags);
2185  if (!Ip.empty())
2186  vpImageConvert::convert(Ip, I);
2187  else
2188  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2189 #else
2190  IplImage *Ip = NULL;
2191  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
2192  if (Ip != NULL)
2193  vpImageConvert::convert(Ip, I);
2194  else
2195  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2196  cvReleaseImage(&Ip);
2197 #endif
2198 }
2199 #else
2200 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2201 {
2202  int width = 0, height = 0, channels = 0;
2203  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
2204  if (image == NULL) {
2205  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2206  }
2207  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2208  stbi_image_free(image);
2209 }
2210 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2211 {
2212  int width = 0, height = 0, channels = 0;
2213  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
2214  if (image == NULL) {
2215  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2216  }
2217  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2218  stbi_image_free(image);
2219 }
2220 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2221 {
2222  const int stride_in_bytes = static_cast<int>(I.getWidth());
2223  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
2224  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2225  if (res == 0) {
2226  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2227  }
2228 }
2229 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2230 {
2231  const int stride_in_bytes = static_cast<int>(4 * I.getWidth());
2232  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
2233  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2234  if (res == 0) {
2235  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2236  }
2237 }
2238 #endif
static void writeJPEG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1055
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
unsigned int getWidth() const
Definition: vpImage.h:246
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:800
#define vpCERROR
Definition: vpDebug.h:365
unsigned char B
Blue component.
Definition: vpRGBa.h:150
Type * bitmap
points toward the bitmap
Definition: vpImage.h:143
#define vpERROR_TRACE
Definition: vpDebug.h:393
error that can be emited by ViSP classes.
Definition: vpException.h:71
Error that can be emited by the vpImage class and its derivates.
unsigned char G
Green component.
Definition: vpRGBa.h:149
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:841
static void writePPM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:987
Definition: vpRGBa.h:66
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:445
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:908
unsigned int getSize() const
Definition: vpImage.h:227
static void writePFM(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:602
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:643
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1676
static void readPFM(vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:768
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:244
static void readPNG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1726
unsigned char R
Red component.
Definition: vpRGBa.h:148
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:640
unsigned int getHeight() const
Definition: vpImage.h:188
static void readPGM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:822
static void writePGM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:648
static void readJPEG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1183
static void writePNG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1517