Visual Servoing Platform  version 3.3.1 under development (2020-12-02)
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  std::cout << "appelle readPNG()" << std::endl;
376 
377 #if defined(VISP_HAVE_PNG)
378  readPNG(I, final_filename);
379 #else
380  try_opencv_reader = true;
381 #endif
382  break;
383  case FORMAT_TIFF:
384  case FORMAT_BMP:
385  case FORMAT_DIB:
386  case FORMAT_PBM:
387  case FORMAT_RASTER:
388  case FORMAT_JPEG2000:
389  case FORMAT_UNKNOWN:
390  try_opencv_reader = true;
391  break;
392  }
393 
394  if (try_opencv_reader) {
395 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
396 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
397  int flags = cv::IMREAD_COLOR | cv::IMREAD_IGNORE_ORIENTATION;
398 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
399  int flags = cv::IMREAD_COLOR;
400 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
401  int flags = CV_LOAD_IMAGE_COLOR;
402 #endif
403  // std::cout << "Use opencv to read the image" << std::endl;
404  cv::Mat cvI = cv::imread(final_filename, flags);
405  if (cvI.cols == 0 && cvI.rows == 0) {
406  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
408  }
409  vpImageConvert::convert(cvI, I);
410 #else
411  switch (getFormat(final_filename)) {
412  case FORMAT_JPEG:
413  readJPEG(I, final_filename);
414  break;
415  case FORMAT_PNG:
416  readPNG(I, final_filename);
417  break;
418  case FORMAT_BMP:
419  case FORMAT_TIFF:
420  case FORMAT_DIB:
421  case FORMAT_PBM:
422  case FORMAT_RASTER:
423  case FORMAT_JPEG2000:
424  case FORMAT_UNKNOWN:
425  default:
426  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
428  }
429 #endif
430  }
431 }
432 
447 void vpImageIo::write(const vpImage<unsigned char> &I, const std::string &filename)
448 {
449  bool try_opencv_writer = false;
450 
451  switch (getFormat(filename)) {
452  case FORMAT_PGM:
453  writePGM(I, filename);
454  break;
455  case FORMAT_PPM:
456  writePPM(I, filename);
457  break;
458  case FORMAT_JPEG:
459 #ifdef VISP_HAVE_JPEG
460  writeJPEG(I, filename);
461 #else
462  try_opencv_writer = true;
463 #endif
464  break;
465  case FORMAT_PNG:
466 #ifdef VISP_HAVE_PNG
467  writePNG(I, filename);
468 #else
469  try_opencv_writer = true;
470 #endif
471  break;
472  case FORMAT_TIFF:
473  case FORMAT_BMP:
474  case FORMAT_DIB:
475  case FORMAT_PBM:
476  case FORMAT_RASTER:
477  case FORMAT_JPEG2000:
478  case FORMAT_UNKNOWN:
479  try_opencv_writer = true;
480  break;
481  }
482 
483  if (try_opencv_writer) {
484 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
485  // std::cout << "Use opencv to write the image" << std::endl;
486  cv::Mat cvI;
487  vpImageConvert::convert(I, cvI);
488  cv::imwrite(filename, cvI);
489 #else
490  switch (getFormat(filename)) {
491  case FORMAT_JPEG:
492  writeJPEG(I, filename);
493  break;
494  case FORMAT_PNG:
495  writePNG(I, filename);
496  break;
497  case FORMAT_BMP:
498  case FORMAT_TIFF:
499  case FORMAT_DIB:
500  case FORMAT_PBM:
501  case FORMAT_RASTER:
502  case FORMAT_JPEG2000:
503  case FORMAT_UNKNOWN:
504  default:
505  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
506  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
507  }
508 #endif
509  }
510 }
511 
526 void vpImageIo::write(const vpImage<vpRGBa> &I, const std::string &filename)
527 {
528  bool try_opencv_writer = false;
529 
530  switch (getFormat(filename)) {
531  case FORMAT_PGM:
532  writePGM(I, filename);
533  break;
534  case FORMAT_PPM:
535  writePPM(I, filename);
536  break;
537  case FORMAT_JPEG:
538 #ifdef VISP_HAVE_JPEG
539  writeJPEG(I, filename);
540 #else
541  try_opencv_writer = true;
542 #endif
543  break;
544  case FORMAT_PNG:
545 #ifdef VISP_HAVE_PNG
546  writePNG(I, filename);
547 #else
548  try_opencv_writer = true;
549 #endif
550  break;
551  case FORMAT_TIFF:
552  case FORMAT_BMP:
553  case FORMAT_DIB:
554  case FORMAT_PBM:
555  case FORMAT_RASTER:
556  case FORMAT_JPEG2000:
557  case FORMAT_UNKNOWN:
558  try_opencv_writer = true;
559  break;
560  }
561 
562  if (try_opencv_writer) {
563 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
564  // std::cout << "Use opencv to write the image" << std::endl;
565  cv::Mat cvI;
566  vpImageConvert::convert(I, cvI);
567  cv::imwrite(filename, cvI);
568 #else
569  switch (getFormat(filename)) {
570  case FORMAT_JPEG:
571  writeJPEG(I, filename);
572  break;
573  case FORMAT_PNG:
574  writePNG(I, filename);
575  break;
576  case FORMAT_BMP:
577  case FORMAT_TIFF:
578  case FORMAT_DIB:
579  case FORMAT_PBM:
580  case FORMAT_RASTER:
581  case FORMAT_JPEG2000:
582  case FORMAT_UNKNOWN:
583  default:
584  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
585  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
586  }
587 #endif
588  }
589 }
590 
591 //--------------------------------------------------------------------------
592 // PFM
593 //--------------------------------------------------------------------------
594 
604 void vpImageIo::writePFM(const vpImage<float> &I, const std::string &filename)
605 {
606  FILE *fd;
607 
608  // Test the filename
609  if (filename.empty()) {
610  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
611  }
612 
613  fd = fopen(filename.c_str(), "wb");
614 
615  if (fd == NULL) {
616  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
617  }
618 
619  // Write the head
620  fprintf(fd, "P8\n"); // Magic number
621  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
622  fprintf(fd, "255\n"); // Max level
623 
624  // Write the bitmap
625  size_t ierr;
626  size_t nbyte = I.getWidth() * I.getHeight();
627 
628  ierr = fwrite(I.bitmap, sizeof(float), nbyte, fd);
629  if (ierr != nbyte) {
630  fclose(fd);
631  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
632  filename.c_str(), ierr, nbyte));
633  }
634 
635  fflush(fd);
636  fclose(fd);
637 }
638 //--------------------------------------------------------------------------
639 // PGM
640 //--------------------------------------------------------------------------
641 
650 void vpImageIo::writePGM(const vpImage<unsigned char> &I, const std::string &filename)
651 {
652 
653  FILE *fd;
654 
655  // Test the filename
656  if (filename.empty()) {
657  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
658  }
659 
660  fd = fopen(filename.c_str(), "wb");
661 
662  if (fd == NULL) {
663  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
664  }
665 
666  // Write the head
667  fprintf(fd, "P5\n"); // Magic number
668  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
669  fprintf(fd, "255\n"); // Max level
670 
671  // Write the bitmap
672  size_t ierr;
673  size_t nbyte = I.getWidth() * I.getHeight();
674 
675  ierr = fwrite(I.bitmap, sizeof(unsigned char), nbyte, fd);
676  if (ierr != nbyte) {
677  fclose(fd);
678  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
679  filename.c_str(), ierr, nbyte));
680  }
681 
682  fflush(fd);
683  fclose(fd);
684 }
685 
693 void vpImageIo::writePGM(const vpImage<short> &I, const std::string &filename)
694 {
696  unsigned int nrows = I.getHeight();
697  unsigned int ncols = I.getWidth();
698 
699  Iuc.resize(nrows, ncols);
700 
701  for (unsigned int i = 0; i < nrows * ncols; i++)
702  Iuc.bitmap[i] = (unsigned char)I.bitmap[i];
703 
704  vpImageIo::writePGM(Iuc, filename);
705 }
715 void vpImageIo::writePGM(const vpImage<vpRGBa> &I, const std::string &filename)
716 {
717 
718  FILE *fd;
719 
720  // Test the filename
721  if (filename.empty()) {
722  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
723  }
724 
725  fd = fopen(filename.c_str(), "wb");
726 
727  if (fd == NULL) {
728  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
729  }
730 
731  // Write the head
732  fprintf(fd, "P5\n"); // Magic number
733  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
734  fprintf(fd, "255\n"); // Max level
735 
736  // Write the bitmap
737  size_t ierr;
738  size_t nbyte = I.getWidth() * I.getHeight();
739 
741  vpImageConvert::convert(I, Itmp);
742 
743  ierr = fwrite(Itmp.bitmap, sizeof(unsigned char), nbyte, fd);
744  if (ierr != nbyte) {
745  fclose(fd);
746  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
747  filename.c_str(), ierr, nbyte));
748  }
749 
750  fflush(fd);
751  fclose(fd);
752 }
753 
770 void vpImageIo::readPFM(vpImage<float> &I, const std::string &filename)
771 {
772  unsigned int w = 0, h = 0, maxval = 0;
773  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
774  std::string magic("P8");
775 
776  std::ifstream fd(filename.c_str(), std::ios::binary);
777 
778  // Open the filename
779  if (!fd.is_open()) {
780  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
781  }
782 
783  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
784 
785  if (w > w_max || h > h_max) {
786  fd.close();
787  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
788  }
789  if (maxval > maxval_max) {
790  fd.close();
791  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
792  }
793 
794  if ((h != I.getHeight()) || (w != I.getWidth())) {
795  I.resize(h, w);
796  }
797 
798  unsigned int nbyte = I.getHeight() * I.getWidth();
799  fd.read((char *)I.bitmap, sizeof(float) * nbyte);
800  if (!fd) {
801  fd.close();
802  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
803  filename.c_str()));
804  }
805 
806  fd.close();
807 }
808 
824 void vpImageIo::readPGM(vpImage<unsigned char> &I, const std::string &filename)
825 {
826  unsigned int w = 0, h = 0, maxval = 0;
827  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
828  std::string magic("P5");
829 
830  std::ifstream fd(filename.c_str(), std::ios::binary);
831 
832  // Open the filename
833  if (!fd.is_open()) {
834  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
835  }
836 
837  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
838 
839  if (w > w_max || h > h_max) {
840  fd.close();
841  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
842  }
843  if (maxval > maxval_max) {
844  fd.close();
845  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
846  }
847 
848  if ((h != I.getHeight()) || (w != I.getWidth())) {
849  I.resize(h, w);
850  }
851 
852  unsigned int nbyte = I.getHeight() * I.getWidth();
853  fd.read((char *)I.bitmap, nbyte);
854  if (!fd) {
855  fd.close();
856  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
857  filename.c_str()));
858  }
859 
860  fd.close();
861 }
862 
881 void vpImageIo::readPGM(vpImage<vpRGBa> &I, const std::string &filename)
882 {
884 
885  vpImageIo::readPGM(Itmp, filename);
886 
887  vpImageConvert::convert(Itmp, I);
888 }
889 
890 //--------------------------------------------------------------------------
891 // PPM
892 //--------------------------------------------------------------------------
893 
910 void vpImageIo::readPPM(vpImage<unsigned char> &I, const std::string &filename)
911 {
912  vpImage<vpRGBa> Itmp;
913 
914  vpImageIo::readPPM(Itmp, filename);
915 
916  vpImageConvert::convert(Itmp, I);
917 }
918 
930 void vpImageIo::readPPM(vpImage<vpRGBa> &I, const std::string &filename)
931 {
932  unsigned int w = 0, h = 0, maxval = 0;
933  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
934  std::string magic("P6");
935 
936  std::ifstream fd(filename.c_str(), std::ios::binary);
937 
938  // Open the filename
939  if (!fd.is_open()) {
940  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
941  }
942 
943  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
944 
945  if (w > w_max || h > h_max) {
946  fd.close();
947  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
948  }
949  if (maxval > maxval_max) {
950  fd.close();
951  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
952  }
953 
954  if ((h != I.getHeight()) || (w != I.getWidth())) {
955  I.resize(h, w);
956  }
957 
958  for (unsigned int i = 0; i < I.getHeight(); i++) {
959  for (unsigned int j = 0; j < I.getWidth(); j++) {
960  unsigned char rgb[3];
961  fd.read((char *)&rgb, 3);
962 
963  if (!fd) {
964  fd.close();
965  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"",
966  (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
967  }
968 
969  I[i][j].R = rgb[0];
970  I[i][j].G = rgb[1];
971  I[i][j].B = rgb[2];
972  I[i][j].A = vpRGBa::alpha_default;
973  }
974  }
975 
976  fd.close();
977 }
978 
989 void vpImageIo::writePPM(const vpImage<unsigned char> &I, const std::string &filename)
990 {
991  vpImage<vpRGBa> Itmp;
992 
993  vpImageConvert::convert(I, Itmp);
994 
995  vpImageIo::writePPM(Itmp, filename);
996 }
997 
1005 void vpImageIo::writePPM(const vpImage<vpRGBa> &I, const std::string &filename)
1006 {
1007  FILE *f;
1008 
1009  // Test the filename
1010  if (filename.empty()) {
1011  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file: filename empty"));
1012  }
1013 
1014  f = fopen(filename.c_str(), "wb");
1015 
1016  if (f == NULL) {
1017  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file \"%s\"", filename.c_str()));
1018  }
1019 
1020  fprintf(f, "P6\n"); // Magic number
1021  fprintf(f, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
1022  fprintf(f, "%d\n", 255); // Max level
1023 
1024  for (unsigned int i = 0; i < I.getHeight(); i++) {
1025  for (unsigned int j = 0; j < I.getWidth(); j++) {
1026  vpRGBa v = I[i][j];
1027  unsigned char rgb[3];
1028  rgb[0] = v.R;
1029  rgb[1] = v.G;
1030  rgb[2] = v.B;
1031 
1032  size_t res = fwrite(&rgb, 1, 3, f);
1033  if (res != 3) {
1034  fclose(f);
1035  throw(vpImageException(vpImageException::ioError, "cannot write file \"%s\"", filename.c_str()));
1036  }
1037  }
1038  }
1039 
1040  fflush(f);
1041  fclose(f);
1042 }
1043 
1044 //--------------------------------------------------------------------------
1045 // JPEG
1046 //--------------------------------------------------------------------------
1047 
1048 #if defined(VISP_HAVE_JPEG)
1049 
1057 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1058 {
1059  struct jpeg_compress_struct cinfo;
1060  struct jpeg_error_mgr jerr;
1061  FILE *file;
1062 
1063  cinfo.err = jpeg_std_error(&jerr);
1064  jpeg_create_compress(&cinfo);
1065 
1066  // Test the filename
1067  if (filename.empty()) {
1068  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1069  }
1070 
1071  file = fopen(filename.c_str(), "wb");
1072 
1073  if (file == NULL) {
1074  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1075  }
1076 
1077  unsigned int width = I.getWidth();
1078  unsigned int height = I.getHeight();
1079 
1080  jpeg_stdio_dest(&cinfo, file);
1081 
1082  cinfo.image_width = width;
1083  cinfo.image_height = height;
1084  cinfo.input_components = 1;
1085  cinfo.in_color_space = JCS_GRAYSCALE;
1086  jpeg_set_defaults(&cinfo);
1087 
1088  jpeg_start_compress(&cinfo, TRUE);
1089 
1090  unsigned char *line;
1091  line = new unsigned char[width];
1092  unsigned char *input = (unsigned char *)I.bitmap;
1093  while (cinfo.next_scanline < cinfo.image_height) {
1094  for (unsigned int i = 0; i < width; i++) {
1095  line[i] = *(input);
1096  input++;
1097  }
1098  jpeg_write_scanlines(&cinfo, &line, 1);
1099  }
1100 
1101  jpeg_finish_compress(&cinfo);
1102  jpeg_destroy_compress(&cinfo);
1103  delete[] line;
1104  fclose(file);
1105 }
1106 
1114 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1115 {
1116  struct jpeg_compress_struct cinfo;
1117  struct jpeg_error_mgr jerr;
1118  FILE *file;
1119 
1120  cinfo.err = jpeg_std_error(&jerr);
1121  jpeg_create_compress(&cinfo);
1122 
1123  // Test the filename
1124  if (filename.empty()) {
1125  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1126  }
1127 
1128  file = fopen(filename.c_str(), "wb");
1129 
1130  if (file == NULL) {
1131  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1132  }
1133 
1134  unsigned int width = I.getWidth();
1135  unsigned int height = I.getHeight();
1136 
1137  jpeg_stdio_dest(&cinfo, file);
1138 
1139  cinfo.image_width = width;
1140  cinfo.image_height = height;
1141  cinfo.input_components = 3;
1142  cinfo.in_color_space = JCS_RGB;
1143  jpeg_set_defaults(&cinfo);
1144 
1145  jpeg_start_compress(&cinfo, TRUE);
1146 
1147  unsigned char *line;
1148  line = new unsigned char[3 * width];
1149  unsigned char *input = (unsigned char *)I.bitmap;
1150  while (cinfo.next_scanline < cinfo.image_height) {
1151  for (unsigned int i = 0; i < width; i++) {
1152  line[i * 3] = *(input);
1153  input++;
1154  line[i * 3 + 1] = *(input);
1155  input++;
1156  line[i * 3 + 2] = *(input);
1157  input++;
1158  input++;
1159  }
1160  jpeg_write_scanlines(&cinfo, &line, 1);
1161  }
1162 
1163  jpeg_finish_compress(&cinfo);
1164  jpeg_destroy_compress(&cinfo);
1165  delete[] line;
1166  fclose(file);
1167 }
1168 
1185 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1186 {
1187  struct jpeg_decompress_struct cinfo;
1188  struct jpeg_error_mgr jerr;
1189  FILE *file;
1190 
1191  cinfo.err = jpeg_std_error(&jerr);
1192  jpeg_create_decompress(&cinfo);
1193 
1194  // Test the filename
1195  if (filename.empty()) {
1196  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1197  }
1198 
1199  file = fopen(filename.c_str(), "rb");
1200 
1201  if (file == NULL) {
1202  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1203  }
1204 
1205  jpeg_stdio_src(&cinfo, file);
1206  jpeg_read_header(&cinfo, TRUE);
1207 
1208  unsigned int width = cinfo.image_width;
1209  unsigned int height = cinfo.image_height;
1210 
1211  if ((width != I.getWidth()) || (height != I.getHeight()))
1212  I.resize(height, width);
1213 
1214  jpeg_start_decompress(&cinfo);
1215 
1216  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1217  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1218 
1219  if (cinfo.out_color_space == JCS_RGB) {
1220  vpImage<vpRGBa> Ic(height, width);
1221  unsigned char *output = (unsigned char *)Ic.bitmap;
1222  while (cinfo.output_scanline < cinfo.output_height) {
1223  jpeg_read_scanlines(&cinfo, buffer, 1);
1224  for (unsigned int i = 0; i < width; i++) {
1225  *(output++) = buffer[0][i * 3];
1226  *(output++) = buffer[0][i * 3 + 1];
1227  *(output++) = buffer[0][i * 3 + 2];
1228  *(output++) = vpRGBa::alpha_default;
1229  }
1230  }
1231  vpImageConvert::convert(Ic, I);
1232  }
1233 
1234  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1235  while (cinfo.output_scanline < cinfo.output_height) {
1236  unsigned int row = cinfo.output_scanline;
1237  jpeg_read_scanlines(&cinfo, buffer, 1);
1238  memcpy(I[row], buffer[0], rowbytes);
1239  }
1240  }
1241 
1242  jpeg_finish_decompress(&cinfo);
1243  jpeg_destroy_decompress(&cinfo);
1244  fclose(file);
1245 }
1246 
1265 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1266 {
1267  struct jpeg_decompress_struct cinfo;
1268  struct jpeg_error_mgr jerr;
1269  FILE *file;
1270 
1271  cinfo.err = jpeg_std_error(&jerr);
1272  jpeg_create_decompress(&cinfo);
1273 
1274  // Test the filename
1275  if (filename.empty()) {
1276  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1277  }
1278 
1279  file = fopen(filename.c_str(), "rb");
1280 
1281  if (file == NULL) {
1282  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1283  }
1284 
1285  jpeg_stdio_src(&cinfo, file);
1286 
1287  jpeg_read_header(&cinfo, TRUE);
1288 
1289  unsigned int width = cinfo.image_width;
1290  unsigned int height = cinfo.image_height;
1291 
1292  if ((width != I.getWidth()) || (height != I.getHeight()))
1293  I.resize(height, width);
1294 
1295  jpeg_start_decompress(&cinfo);
1296 
1297  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1298  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1299 
1300  if (cinfo.out_color_space == JCS_RGB) {
1301  unsigned char *output = (unsigned char *)I.bitmap;
1302  while (cinfo.output_scanline < cinfo.output_height) {
1303  jpeg_read_scanlines(&cinfo, buffer, 1);
1304  for (unsigned int i = 0; i < width; i++) {
1305  *(output++) = buffer[0][i * 3];
1306  *(output++) = buffer[0][i * 3 + 1];
1307  *(output++) = buffer[0][i * 3 + 2];
1308  *(output++) = vpRGBa::alpha_default;
1309  }
1310  }
1311  }
1312 
1313  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1314  vpImage<unsigned char> Ig(height, width);
1315 
1316  while (cinfo.output_scanline < cinfo.output_height) {
1317  unsigned int row = cinfo.output_scanline;
1318  jpeg_read_scanlines(&cinfo, buffer, 1);
1319  memcpy(Ig[row], buffer[0], rowbytes);
1320  }
1321 
1322  vpImageConvert::convert(Ig, I);
1323  }
1324 
1325  jpeg_finish_decompress(&cinfo);
1326  jpeg_destroy_decompress(&cinfo);
1327  fclose(file);
1328 }
1329 
1330 #elif defined(VISP_HAVE_OPENCV)
1331 
1339 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1340 {
1341 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1342  cv::Mat Ip;
1343  vpImageConvert::convert(I, Ip);
1344  cv::imwrite(filename.c_str(), Ip);
1345 #else
1346  IplImage *Ip = NULL;
1347  vpImageConvert::convert(I, Ip);
1348 
1349  cvSaveImage(filename.c_str(), Ip);
1350 
1351  cvReleaseImage(&Ip);
1352 #endif
1353 }
1354 
1362 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1363 {
1364 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1365  cv::Mat Ip;
1366  vpImageConvert::convert(I, Ip);
1367  cv::imwrite(filename.c_str(), Ip);
1368 #else
1369  IplImage *Ip = NULL;
1370  vpImageConvert::convert(I, Ip);
1371 
1372  cvSaveImage(filename.c_str(), Ip);
1373 
1374  cvReleaseImage(&Ip);
1375 #endif
1376 }
1377 
1396 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1397 {
1398 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
1399 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
1400  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
1401 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
1402  int flags = cv::IMREAD_GRAYSCALE;
1403 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
1404  int flags = CV_LOAD_IMAGE_GRAYSCALE;
1405 #endif
1406  cv::Mat Ip = cv::imread(filename.c_str(), flags);
1407  if (!Ip.empty())
1408  vpImageConvert::convert(Ip, I);
1409  else
1410  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1411 #else
1412  IplImage *Ip = NULL;
1413  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1414  if (Ip != NULL)
1415  vpImageConvert::convert(Ip, I);
1416  else
1417  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1418  cvReleaseImage(&Ip);
1419 #endif
1420 }
1421 
1442 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1443 {
1444 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
1445 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
1446  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
1447 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
1448  int flags = cv::IMREAD_GRAYSCALE;
1449 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
1450  int flags = CV_LOAD_IMAGE_GRAYSCALE;
1451 #endif
1452  cv::Mat Ip = cv::imread(filename.c_str(), flags);
1453  if (!Ip.empty())
1454  vpImageConvert::convert(Ip, I);
1455  else
1456  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1457 #else
1458  IplImage *Ip = NULL;
1459  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
1460  if (Ip != NULL)
1461  vpImageConvert::convert(Ip, I);
1462  else
1463  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1464  cvReleaseImage(&Ip);
1465 #endif
1466 }
1467 #else
1468 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1469 {
1470  int width = 0, height = 0, channels = 0;
1471  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
1472  if (image == NULL) {
1473  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1474  }
1475  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1476  stbi_image_free(image);
1477 }
1478 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1479 {
1480  int width = 0, height = 0, channels = 0;
1481  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
1482  if (image == NULL) {
1483  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1484  }
1485  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1486  stbi_image_free(image);
1487 }
1488 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1489 {
1490  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
1491  reinterpret_cast<void*>(I.bitmap), 90);
1492  if (res == 0) {
1493  throw(vpImageException(vpImageException::ioError, "JPEG write error"));
1494  }
1495 }
1496 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1497 {
1498  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
1499  reinterpret_cast<void*>(I.bitmap), 90);
1500  if (res == 0) {
1501  throw(vpImageException(vpImageException::ioError, "JEPG write error"));
1502  }
1503 }
1504 #endif
1505 
1506 //--------------------------------------------------------------------------
1507 // PNG
1508 //--------------------------------------------------------------------------
1509 
1510 #if defined(VISP_HAVE_PNG)
1511 
1519 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1520 {
1521  FILE *file;
1522 
1523  // Test the filename
1524  if (filename.empty()) {
1525  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1526  }
1527 
1528  file = fopen(filename.c_str(), "wb");
1529 
1530  if (file == NULL) {
1531  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1532  }
1533 
1534  /* create a png info struct */
1535  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1536  if (!png_ptr) {
1537  fclose(file);
1538  vpERROR_TRACE("Error during png_create_write_struct()\n");
1539  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1540  }
1541 
1542  png_infop info_ptr = png_create_info_struct(png_ptr);
1543  if (!info_ptr) {
1544  fclose(file);
1545  png_destroy_write_struct(&png_ptr, NULL);
1546  vpERROR_TRACE("Error during png_create_info_struct()\n");
1547  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1548  }
1549 
1550  /* initialize the setjmp for returning properly after a libpng error occured
1551  */
1552  if (setjmp(png_jmpbuf(png_ptr))) {
1553  fclose(file);
1554  png_destroy_write_struct(&png_ptr, &info_ptr);
1555  vpERROR_TRACE("Error during init_io\n");
1556  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1557  }
1558 
1559  /* setup libpng for using standard C fwrite() function with our FILE pointer
1560  */
1561  png_init_io(png_ptr, file);
1562 
1563  unsigned int width = I.getWidth();
1564  unsigned int height = I.getHeight();
1565  int bit_depth = 8;
1566  int color_type = PNG_COLOR_TYPE_GRAY;
1567  /* set some useful information from header */
1568 
1569  if (setjmp(png_jmpbuf(png_ptr))) {
1570  fclose(file);
1571  png_destroy_write_struct(&png_ptr, &info_ptr);
1572  vpERROR_TRACE("Error during write header\n");
1573  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1574  }
1575 
1576  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1577  PNG_FILTER_TYPE_BASE);
1578 
1579  png_write_info(png_ptr, info_ptr);
1580 
1581  png_bytep *row_ptrs = new png_bytep[height];
1582  for (unsigned int i = 0; i < height; i++)
1583  row_ptrs[i] = new png_byte[width];
1584 
1585  unsigned char *input = (unsigned char *)I.bitmap;
1586 
1587  for (unsigned int i = 0; i < height; i++) {
1588  png_byte *row = row_ptrs[i];
1589  for (unsigned int j = 0; j < width; j++) {
1590  row[j] = *(input);
1591  input++;
1592  }
1593  }
1594 
1595  png_write_image(png_ptr, row_ptrs);
1596 
1597  png_write_end(png_ptr, NULL);
1598 
1599  for (unsigned int j = 0; j < height; j++)
1600  delete[] row_ptrs[j];
1601 
1602  delete[] row_ptrs;
1603 
1604  png_destroy_write_struct(&png_ptr, &info_ptr);
1605 
1606  fclose(file);
1607 }
1608 
1616 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1617 {
1618  FILE *file;
1619 
1620  // Test the filename
1621  if (filename.empty()) {
1622  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1623  }
1624 
1625  file = fopen(filename.c_str(), "wb");
1626 
1627  if (file == NULL) {
1628  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1629  }
1630 
1631  /* create a png info struct */
1632  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1633  if (!png_ptr) {
1634  fclose(file);
1635  vpERROR_TRACE("Error during png_create_write_struct()\n");
1636  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1637  }
1638 
1639  png_infop info_ptr = png_create_info_struct(png_ptr);
1640  if (!info_ptr) {
1641  fclose(file);
1642  png_destroy_write_struct(&png_ptr, NULL);
1643  vpERROR_TRACE("Error during png_create_info_struct()\n");
1644  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1645  }
1646 
1647  /* initialize the setjmp for returning properly after a libpng error occured
1648  */
1649  if (setjmp(png_jmpbuf(png_ptr))) {
1650  fclose(file);
1651  png_destroy_write_struct(&png_ptr, &info_ptr);
1652  vpERROR_TRACE("Error during init_io\n");
1653  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1654  }
1655 
1656  /* setup libpng for using standard C fwrite() function with our FILE pointer
1657  */
1658  png_init_io(png_ptr, file);
1659 
1660  unsigned int width = I.getWidth();
1661  unsigned int height = I.getHeight();
1662  int bit_depth = 8;
1663  int color_type = PNG_COLOR_TYPE_RGB;
1664  /* set some useful information from header */
1665 
1666  if (setjmp(png_jmpbuf(png_ptr))) {
1667  fclose(file);
1668  png_destroy_write_struct(&png_ptr, &info_ptr);
1669  vpERROR_TRACE("Error during write header\n");
1670  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1671  }
1672 
1673  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1674  PNG_FILTER_TYPE_BASE);
1675 
1676  png_write_info(png_ptr, info_ptr);
1677 
1678  png_bytep *row_ptrs = new png_bytep[height];
1679  for (unsigned int i = 0; i < height; i++)
1680  row_ptrs[i] = new png_byte[3 * width];
1681 
1682  unsigned char *input = (unsigned char *)I.bitmap;
1683  ;
1684 
1685  for (unsigned int i = 0; i < height; i++) {
1686  png_byte *row = row_ptrs[i];
1687  for (unsigned int j = 0; j < width; j++) {
1688  row[3 * j] = *(input);
1689  input++;
1690  row[3 * j + 1] = *(input);
1691  input++;
1692  row[3 * j + 2] = *(input);
1693  input++;
1694  input++;
1695  }
1696  }
1697 
1698  png_write_image(png_ptr, row_ptrs);
1699 
1700  png_write_end(png_ptr, NULL);
1701 
1702  for (unsigned int j = 0; j < height; j++)
1703  delete[] row_ptrs[j];
1704 
1705  delete[] row_ptrs;
1706 
1707  png_destroy_write_struct(&png_ptr, &info_ptr);
1708 
1709  fclose(file);
1710 }
1711 
1728 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1729 {
1730  FILE *file;
1731  png_byte magic[8];
1732  // Test the filename
1733  if (filename.empty()) {
1734  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1735  }
1736 
1737  file = fopen(filename.c_str(), "rb");
1738 
1739  if (file == NULL) {
1740  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1741  }
1742 
1743  /* read magic number */
1744  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1745  fclose(file);
1746  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1747  }
1748 
1749  /* check for valid magic number */
1750  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1751  fclose(file);
1752  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1753  filename.c_str()));
1754  }
1755 
1756  /* create a png read struct */
1757  // printf("version %s\n", PNG_LIBPNG_VER_STRING);
1758  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1759  if (png_ptr == NULL) {
1760  fprintf(stderr, "error: can't create a png read structure!\n");
1761  fclose(file);
1762  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1763  }
1764 
1765  /* create a png info struct */
1766  png_infop info_ptr = png_create_info_struct(png_ptr);
1767  if (info_ptr == NULL) {
1768  fprintf(stderr, "error: can't create a png info structure!\n");
1769  fclose(file);
1770  png_destroy_read_struct(&png_ptr, NULL, NULL);
1771  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1772  }
1773 
1774  /* initialize the setjmp for returning properly after a libpng error occured
1775  */
1776  if (setjmp(png_jmpbuf(png_ptr))) {
1777  fclose(file);
1778  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1779  vpERROR_TRACE("Error during init io\n");
1780  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1781  }
1782 
1783  /* setup libpng for using standard C fread() function with our FILE pointer
1784  */
1785  png_init_io(png_ptr, file);
1786 
1787  /* tell libpng that we have already read the magic number */
1788  png_set_sig_bytes(png_ptr, sizeof(magic));
1789 
1790  /* read png info */
1791  png_read_info(png_ptr, info_ptr);
1792 
1793  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1794  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1795 
1796  unsigned int bit_depth, channels, color_type;
1797  /* get some useful information from header */
1798  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1799  channels = png_get_channels(png_ptr, info_ptr);
1800  color_type = png_get_color_type(png_ptr, info_ptr);
1801 
1802  /* convert index color images to RGB images */
1803  if (color_type == PNG_COLOR_TYPE_PALETTE)
1804  png_set_palette_to_rgb(png_ptr);
1805 
1806  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1807  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1808  png_set_expand(png_ptr);
1809 
1810  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1811  // png_set_tRNS_to_alpha (png_ptr);
1812 
1813  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1814  png_set_strip_alpha(png_ptr);
1815 
1816  if (bit_depth == 16)
1817  png_set_strip_16(png_ptr);
1818  else if (bit_depth < 8)
1819  png_set_packing(png_ptr);
1820 
1821  /* update info structure to apply transformations */
1822  png_read_update_info(png_ptr, info_ptr);
1823 
1824  channels = png_get_channels(png_ptr, info_ptr);
1825 
1826  if ((width != I.getWidth()) || (height != I.getHeight()))
1827  I.resize(height, width);
1828 
1829  png_bytep *rowPtrs = new png_bytep[height];
1830 
1831  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1832  unsigned char *data = new unsigned char[stride * height];
1833 
1834  for (unsigned int i = 0; i < height; i++)
1835  rowPtrs[i] = (png_bytep)data + (i * stride);
1836 
1837  png_read_image(png_ptr, rowPtrs);
1838 
1839  vpImage<vpRGBa> Ic(height, width);
1840  unsigned char *output;
1841 
1842  switch (channels) {
1843  case 1:
1844  output = (unsigned char *)I.bitmap;
1845  for (unsigned int i = 0; i < width * height; i++) {
1846  *(output++) = data[i];
1847  }
1848  break;
1849 
1850  case 2:
1851  output = (unsigned char *)I.bitmap;
1852  for (unsigned int i = 0; i < width * height; i++) {
1853  *(output++) = data[i * 2];
1854  }
1855  break;
1856 
1857  case 3:
1858  output = (unsigned char *)Ic.bitmap;
1859  for (unsigned int i = 0; i < width * height; i++) {
1860  *(output++) = data[i * 3];
1861  *(output++) = data[i * 3 + 1];
1862  *(output++) = data[i * 3 + 2];
1863  *(output++) = vpRGBa::alpha_default;
1864  }
1865  vpImageConvert::convert(Ic, I);
1866  break;
1867 
1868  case 4:
1869  output = (unsigned char *)Ic.bitmap;
1870  for (unsigned int i = 0; i < width * height; i++) {
1871  *(output++) = data[i * 4];
1872  *(output++) = data[i * 4 + 1];
1873  *(output++) = data[i * 4 + 2];
1874  *(output++) = data[i * 4 + 3];
1875  }
1876  vpImageConvert::convert(Ic, I);
1877  break;
1878  }
1879 
1880  delete[](png_bytep) rowPtrs;
1881  delete[] data;
1882  png_read_end(png_ptr, NULL);
1883  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1884  fclose(file);
1885 }
1886 
1905 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
1906 {
1907  FILE *file;
1908  png_byte magic[8];
1909 
1910  // Test the filename
1911  if (filename.empty()) {
1912  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1913  }
1914 
1915  file = fopen(filename.c_str(), "rb");
1916 
1917  if (file == NULL) {
1918  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1919  }
1920 
1921  /* read magic number */
1922  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1923  fclose(file);
1924  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1925  }
1926 
1927  /* check for valid magic number */
1928  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1929  fclose(file);
1930  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1931  filename.c_str()));
1932  }
1933 
1934  /* create a png read struct */
1935  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1936  if (!png_ptr) {
1937  fclose(file);
1938  vpERROR_TRACE("Error during png_create_read_struct()\n");
1939  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1940  }
1941 
1942  /* create a png info struct */
1943  png_infop info_ptr = png_create_info_struct(png_ptr);
1944  if (!info_ptr) {
1945  fclose(file);
1946  png_destroy_read_struct(&png_ptr, NULL, NULL);
1947  vpERROR_TRACE("Error during png_create_info_struct()\n");
1948  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1949  }
1950 
1951  /* initialize the setjmp for returning properly after a libpng error occured
1952  */
1953  if (setjmp(png_jmpbuf(png_ptr))) {
1954  fclose(file);
1955  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1956  vpERROR_TRACE("Error during init io\n");
1957  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1958  }
1959 
1960  /* setup libpng for using standard C fread() function with our FILE pointer
1961  */
1962  png_init_io(png_ptr, file);
1963 
1964  /* tell libpng that we have already read the magic number */
1965  png_set_sig_bytes(png_ptr, sizeof(magic));
1966 
1967  /* read png info */
1968  png_read_info(png_ptr, info_ptr);
1969 
1970  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1971  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1972 
1973  unsigned int bit_depth, channels, color_type;
1974  /* get some useful information from header */
1975  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1976  channels = png_get_channels(png_ptr, info_ptr);
1977  color_type = png_get_color_type(png_ptr, info_ptr);
1978 
1979  /* convert index color images to RGB images */
1980  if (color_type == PNG_COLOR_TYPE_PALETTE)
1981  png_set_palette_to_rgb(png_ptr);
1982 
1983  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1984  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1985  png_set_expand(png_ptr);
1986 
1987  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1988  // png_set_tRNS_to_alpha (png_ptr);
1989 
1990  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1991  png_set_strip_alpha(png_ptr);
1992 
1993  if (bit_depth == 16)
1994  png_set_strip_16(png_ptr);
1995  else if (bit_depth < 8)
1996  png_set_packing(png_ptr);
1997 
1998  /* update info structure to apply transformations */
1999  png_read_update_info(png_ptr, info_ptr);
2000 
2001  channels = png_get_channels(png_ptr, info_ptr);
2002 
2003  if ((width != I.getWidth()) || (height != I.getHeight()))
2004  I.resize(height, width);
2005 
2006  png_bytep *rowPtrs = new png_bytep[height];
2007 
2008  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
2009  unsigned char *data = new unsigned char[stride * height];
2010 
2011  for (unsigned int i = 0; i < height; i++)
2012  rowPtrs[i] = (png_bytep)data + (i * stride);
2013 
2014  png_read_image(png_ptr, rowPtrs);
2015 
2016  vpImage<unsigned char> Ig(height, width);
2017  unsigned char *output;
2018 
2019  switch (channels) {
2020  case 1:
2021  output = (unsigned char *)Ig.bitmap;
2022  for (unsigned int i = 0; i < width * height; i++) {
2023  *(output++) = data[i];
2024  }
2025  vpImageConvert::convert(Ig, I);
2026  break;
2027 
2028  case 2:
2029  output = (unsigned char *)Ig.bitmap;
2030  for (unsigned int i = 0; i < width * height; i++) {
2031  *(output++) = data[i * 2];
2032  }
2033  vpImageConvert::convert(Ig, I);
2034  break;
2035 
2036  case 3:
2037  output = (unsigned char *)I.bitmap;
2038  for (unsigned int i = 0; i < width * height; i++) {
2039  *(output++) = data[i * 3];
2040  *(output++) = data[i * 3 + 1];
2041  *(output++) = data[i * 3 + 2];
2042  *(output++) = vpRGBa::alpha_default;
2043  }
2044  break;
2045 
2046  case 4:
2047  output = (unsigned char *)I.bitmap;
2048  for (unsigned int i = 0; i < width * height; i++) {
2049  *(output++) = data[i * 4];
2050  *(output++) = data[i * 4 + 1];
2051  *(output++) = data[i * 4 + 2];
2052  *(output++) = data[i * 4 + 3];
2053  }
2054  break;
2055  }
2056 
2057  delete[](png_bytep) rowPtrs;
2058  delete[] data;
2059  png_read_end(png_ptr, NULL);
2060  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2061  fclose(file);
2062 }
2063 
2064 #elif defined(VISP_HAVE_OPENCV)
2065 
2073 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2074 {
2075 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2076  cv::Mat Ip;
2077  vpImageConvert::convert(I, Ip);
2078  cv::imwrite(filename.c_str(), Ip);
2079 #else
2080  IplImage *Ip = NULL;
2081  vpImageConvert::convert(I, Ip);
2082 
2083  cvSaveImage(filename.c_str(), Ip);
2084 
2085  cvReleaseImage(&Ip);
2086 #endif
2087 }
2088 
2096 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2097 {
2098 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2099  cv::Mat Ip;
2100  vpImageConvert::convert(I, Ip);
2101  cv::imwrite(filename.c_str(), Ip);
2102 #else
2103  IplImage *Ip = NULL;
2104  vpImageConvert::convert(I, Ip);
2105 
2106  cvSaveImage(filename.c_str(), Ip);
2107 
2108  cvReleaseImage(&Ip);
2109 #endif
2110 }
2111 
2130 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2131 {
2132 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
2133 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
2134  int flags = cv::IMREAD_GRAYSCALE | cv::IMREAD_IGNORE_ORIENTATION;
2135 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
2136  int flags = cv::IMREAD_GRAYSCALE;
2137 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
2138  int flags = CV_LOAD_IMAGE_GRAYSCALE;
2139 #endif
2140  cv::Mat Ip = cv::imread(filename.c_str(), flags);
2141  if (!Ip.empty())
2142  vpImageConvert::convert(Ip, I);
2143  else
2144  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2145 #else
2146  IplImage *Ip = NULL;
2147  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2148  if (Ip != NULL)
2149  vpImageConvert::convert(Ip, I);
2150  else
2151  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2152  cvReleaseImage(&Ip);
2153 #endif
2154 }
2155 
2176 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2177 {
2178 #if defined(VISP_HAVE_OPENCV) && VISP_HAVE_OPENCV_VERSION >= 0x020100
2179 #if VISP_HAVE_OPENCV_VERSION >= 0x030200
2180  int flags = cv::IMREAD_COLOR | cv::IMREAD_IGNORE_ORIENTATION;
2181 #elif VISP_HAVE_OPENCV_VERSION >= 0x030000
2182  int flags = cv::IMREAD_COLOR;
2183 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
2184  int flags = CV_LOAD_IMAGE_COLOR;
2185 #endif
2186  cv::Mat Ip = cv::imread(filename.c_str(), flags);
2187  if (!Ip.empty())
2188  vpImageConvert::convert(Ip, I);
2189  else
2190  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2191 #else
2192  IplImage *Ip = NULL;
2193  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
2194  if (Ip != NULL)
2195  vpImageConvert::convert(Ip, I);
2196  else
2197  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2198  cvReleaseImage(&Ip);
2199 #endif
2200 }
2201 #else
2202 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2203 {
2204  int width = 0, height = 0, channels = 0;
2205  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
2206  if (image == NULL) {
2207  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2208  }
2209  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2210  stbi_image_free(image);
2211 }
2212 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2213 {
2214  int width = 0, height = 0, channels = 0;
2215  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
2216  if (image == NULL) {
2217  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2218  }
2219  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2220  stbi_image_free(image);
2221 }
2222 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2223 {
2224  const int stride_in_bytes = static_cast<int>(I.getWidth());
2225  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
2226  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2227  if (res == 0) {
2228  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2229  }
2230 }
2231 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2232 {
2233  const int stride_in_bytes = static_cast<int>(4 * I.getWidth());
2234  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
2235  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2236  if (res == 0) {
2237  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2238  }
2239 }
2240 #endif
static void writeJPEG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1057
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
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:989
Definition: vpRGBa.h:66
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:447
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:910
static void writePFM(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:604
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:770
unsigned int getHeight() const
Definition: vpImage.h:188
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:244
unsigned int getSize() const
Definition: vpImage.h:227
static void readPNG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1728
unsigned char R
Red component.
Definition: vpRGBa.h:148
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:640
static void readPGM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:824
unsigned int getWidth() const
Definition: vpImage.h:246
static void writePGM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:650
static void readJPEG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1185
static void writePNG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1519