Visual Servoing Platform  version 3.6.0 under development (2023-09-29)
vpImageIo.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Read/write images.
32  */
33 
39 #include <visp3/core/vpIoTools.h>
40 #include <visp3/io/vpImageIo.h>
41 
42 #include "private/vpImageIoBackend.h"
43 
44 vpImageIo::vpImageFormatType vpImageIo::getFormat(const std::string &filename)
45 {
46  std::string ext = vpImageIo::getExtension(filename);
47 
48  if (ext.compare(".PGM") == 0)
49  return FORMAT_PGM;
50  else if (ext.compare(".pgm") == 0)
51  return FORMAT_PGM;
52  else if (ext.compare(".PPM") == 0)
53  return FORMAT_PPM;
54  else if (ext.compare(".ppm") == 0)
55  return FORMAT_PPM;
56  else if (ext.compare(".JPG") == 0)
57  return FORMAT_JPEG;
58  else if (ext.compare(".jpg") == 0)
59  return FORMAT_JPEG;
60  else if (ext.compare(".JPEG") == 0)
61  return FORMAT_JPEG;
62  else if (ext.compare(".jpeg") == 0)
63  return FORMAT_JPEG;
64  else if (ext.compare(".PNG") == 0)
65  return FORMAT_PNG;
66  else if (ext.compare(".png") == 0)
67  return FORMAT_PNG;
68  // Formats supported by opencv
69  else if (ext.compare(".TIFF") == 0)
70  return FORMAT_TIFF;
71  else if (ext.compare(".tiff") == 0)
72  return FORMAT_TIFF;
73  else if (ext.compare(".TIF") == 0)
74  return FORMAT_TIFF;
75  else if (ext.compare(".tif") == 0)
76  return FORMAT_TIFF;
77  else if (ext.compare(".BMP") == 0)
78  return FORMAT_BMP;
79  else if (ext.compare(".bmp") == 0)
80  return FORMAT_BMP;
81  else if (ext.compare(".DIB") == 0)
82  return FORMAT_DIB;
83  else if (ext.compare(".dib") == 0)
84  return FORMAT_DIB;
85  else if (ext.compare(".PBM") == 0)
86  return FORMAT_PBM;
87  else if (ext.compare(".pbm") == 0)
88  return FORMAT_PBM;
89  else if (ext.compare(".SR") == 0)
90  return FORMAT_RASTER;
91  else if (ext.compare(".sr") == 0)
92  return FORMAT_RASTER;
93  else if (ext.compare(".RAS") == 0)
94  return FORMAT_RASTER;
95  else if (ext.compare(".ras") == 0)
96  return FORMAT_RASTER;
97  else if (ext.compare(".JP2") == 0)
98  return FORMAT_JPEG2000;
99  else if (ext.compare(".jp2") == 0)
100  return FORMAT_JPEG2000;
101  else
102  return FORMAT_UNKNOWN;
103 }
104 
105 // return the extension of the file including the dot
106 std::string vpImageIo::getExtension(const std::string &filename)
107 {
108  // extract the extension
109  size_t dot = filename.find_last_of(".");
110  std::string ext = filename.substr(dot, filename.size() - 1);
111  return ext;
112 }
113 
143 void vpImageIo::read(vpImage<unsigned char> &I, const std::string &filename, int backend)
144 {
145  bool exist = vpIoTools::checkFilename(filename);
146  if (!exist) {
147  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
149  }
150 
151  // Allows to use ~ symbol or env variables in path
152  std::string final_filename = vpIoTools::path(filename);
153 
154  bool try_opencv_reader = false;
155 
156  switch (getFormat(final_filename)) {
157  case FORMAT_PGM:
158  readPGM(I, final_filename);
159  break;
160  case FORMAT_PPM:
161  readPPM(I, final_filename);
162  break;
163  case FORMAT_JPEG:
164  readJPEG(I, final_filename, backend);
165  break;
166  case FORMAT_PNG:
167  readPNG(I, final_filename, backend);
168  break;
169  case FORMAT_TIFF:
170  case FORMAT_BMP:
171  case FORMAT_DIB:
172  case FORMAT_PBM:
173  case FORMAT_RASTER:
174  case FORMAT_JPEG2000:
175  case FORMAT_UNKNOWN:
176  try_opencv_reader = true;
177  break;
178  }
179 
180  if (try_opencv_reader) {
181 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
182  readOpenCV(I, filename);
183 #else
184  std::string message = "Cannot read file \"" + filename + "\": No backend able to support this image format";
186 #endif
187  }
188 }
189 
219 void vpImageIo::read(vpImage<vpRGBa> &I, const std::string &filename, int backend)
220 {
221  bool exist = vpIoTools::checkFilename(filename);
222  if (!exist) {
223  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
225  }
226  // Allows to use ~ symbol or env variables in path
227  std::string final_filename = vpIoTools::path(filename);
228 
229  bool try_opencv_reader = false;
230 
231  switch (getFormat(final_filename)) {
232  case FORMAT_PGM:
233  readPGM(I, final_filename);
234  break;
235  case FORMAT_PPM:
236  readPPM(I, final_filename);
237  break;
238  case FORMAT_JPEG:
239  readJPEG(I, final_filename, backend);
240  break;
241  case FORMAT_PNG:
242  readPNG(I, final_filename, backend);
243  break;
244  case FORMAT_TIFF:
245  case FORMAT_BMP:
246  case FORMAT_DIB:
247  case FORMAT_PBM:
248  case FORMAT_RASTER:
249  case FORMAT_JPEG2000:
250  case FORMAT_UNKNOWN:
251  try_opencv_reader = true;
252  break;
253  }
254 
255  if (try_opencv_reader) {
256 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
257  readOpenCV(I, filename);
258 #else
259  std::string message = "Cannot read file \"" + filename + "\": No backend able to support this image format";
261 #endif
262  }
263 }
264 
287 void vpImageIo::write(const vpImage<unsigned char> &I, const std::string &filename, int backend)
288 {
289  bool try_opencv_writer = false;
290 
291  switch (getFormat(filename)) {
292  case FORMAT_PGM:
293  writePGM(I, filename);
294  break;
295  case FORMAT_PPM:
296  writePPM(I, filename);
297  break;
298  case FORMAT_JPEG:
299  writeJPEG(I, filename, backend);
300  break;
301  case FORMAT_PNG:
302  writePNG(I, filename, backend);
303  break;
304  case FORMAT_TIFF:
305  case FORMAT_BMP:
306  case FORMAT_DIB:
307  case FORMAT_PBM:
308  case FORMAT_RASTER:
309  case FORMAT_JPEG2000:
310  case FORMAT_UNKNOWN:
311  try_opencv_writer = true;
312  break;
313  }
314 
315  if (try_opencv_writer) {
316 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
317  writeOpenCV(I, filename, 90);
318 #else
319  std::string message = "Cannot write file \"" + filename + "\": No backend able to support this image format";
321 #endif
322  }
323 }
324 
347 void vpImageIo::write(const vpImage<vpRGBa> &I, const std::string &filename, int backend)
348 {
349  bool try_opencv_writer = false;
350 
351  switch (getFormat(filename)) {
352  case FORMAT_PGM:
353  writePGM(I, filename);
354  break;
355  case FORMAT_PPM:
356  writePPM(I, filename);
357  break;
358  case FORMAT_JPEG:
359  writeJPEG(I, filename, backend);
360  break;
361  case FORMAT_PNG:
362  writePNG(I, filename, backend);
363  break;
364  case FORMAT_TIFF:
365  case FORMAT_BMP:
366  case FORMAT_DIB:
367  case FORMAT_PBM:
368  case FORMAT_RASTER:
369  case FORMAT_JPEG2000:
370  case FORMAT_UNKNOWN:
371  try_opencv_writer = true;
372  break;
373  }
374 
375  if (try_opencv_writer) {
376 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
377  writeOpenCV(I, filename, 90);
378 #else
379  std::string message = "Cannot write file \"" + filename + "\": No backend able to support this image format";
381 #endif
382  }
383 }
384 
393 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
394 // Default: 1. opencv, 2. system, 3. stb_image
395 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename, int backend)
396 {
397  if (backend == IO_SYSTEM_LIB_BACKEND) {
398 #if !defined(VISP_HAVE_JPEG)
399  std::string message =
400  "Libjpeg backend is not available to read file \"" + filename + "\": switch to stb_image backend";
401  backend = IO_STB_IMAGE_BACKEND;
402 #endif
403  } else if (backend == IO_OPENCV_BACKEND) {
404 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
405  std::string message =
406  "OpenCV backend is not available to read file \"" + filename + "\": switch to stb_image backend";
407  backend = IO_STB_IMAGE_BACKEND;
408 #endif
409  } else if (backend == IO_DEFAULT_BACKEND) {
410 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
411  backend = IO_OPENCV_BACKEND;
412 #elif defined(VISP_HAVE_JPEG)
413  backend = IO_SYSTEM_LIB_BACKEND;
414 #else
415  backend = IO_STB_IMAGE_BACKEND;
416 #endif
417  }
418 
419  if (backend == IO_SYSTEM_LIB_BACKEND) {
420 #if defined(VISP_HAVE_JPEG)
421  readJPEGLibjpeg(I, filename);
422 #endif
423  } else if (backend == IO_OPENCV_BACKEND) {
424 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
425  readOpenCV(I, filename);
426 #endif
427  } else if (backend == IO_STB_IMAGE_BACKEND) {
428  readStb(I, filename);
429  } else if (backend == IO_SIMDLIB_BACKEND) {
430  readSimdlib(I, filename);
431  }
432 }
433 
442 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
443 // Default: 1. opencv, 2. system, 3. stb_image
444 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename, int backend)
445 {
446  if (backend == IO_SYSTEM_LIB_BACKEND) {
447 #if !defined(VISP_HAVE_JPEG)
448  std::string message =
449  "Libjpeg backend is not available to read file \"" + filename + "\": switch to stb_image backend";
450  backend = IO_STB_IMAGE_BACKEND;
451 #endif
452  } else if (backend == IO_OPENCV_BACKEND) {
453 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
454  std::string message =
455  "OpenCV backend is not available to read file \"" + filename + "\": switch to stb_image backend";
456  backend = IO_STB_IMAGE_BACKEND;
457 #endif
458  } else if (backend == IO_DEFAULT_BACKEND) {
459 #if defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS)
460  backend = IO_OPENCV_BACKEND;
461 #elif defined(VISP_HAVE_JPEG)
462  backend = IO_SYSTEM_LIB_BACKEND;
463 #else
464  backend = IO_STB_IMAGE_BACKEND;
465 #endif
466  }
467 
468  if (backend == IO_SYSTEM_LIB_BACKEND) {
469 #if defined(VISP_HAVE_JPEG)
470  readJPEGLibjpeg(I, filename);
471 #endif
472  } else if (backend == IO_OPENCV_BACKEND) {
473 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
474  readOpenCV(I, filename);
475 #endif
476  } else if (backend == IO_STB_IMAGE_BACKEND) {
477  readStb(I, filename);
478  } else if (backend == IO_SIMDLIB_BACKEND) {
479  readSimdlib(I, filename);
480  }
481 }
482 
491 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
492 // Default: 1. system, 2. opencv, 3. stb_image
493 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename, int backend)
494 {
495  if (backend == IO_SYSTEM_LIB_BACKEND) {
496 #if !defined(VISP_HAVE_PNG)
497  std::string message =
498  "Libpng backend is not available to read file \"" + filename + "\": switch to stb_image backend";
499  backend = IO_STB_IMAGE_BACKEND;
500 #endif
501  } else if (backend == IO_OPENCV_BACKEND) {
502 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
503  std::string message =
504  "OpenCV backend is not available to read file \"" + filename + "\": switch to stb_image backend";
505  backend = IO_STB_IMAGE_BACKEND;
506 #endif
507  } else if (backend == IO_DEFAULT_BACKEND) {
508 #if defined(VISP_HAVE_PNG)
509  backend = IO_SYSTEM_LIB_BACKEND;
510 #elif defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS)
511  backend = IO_OPENCV_BACKEND;
512 #else
513  backend = IO_STB_IMAGE_BACKEND;
514 #endif
515  }
516 
517  if (backend == IO_SYSTEM_LIB_BACKEND) {
518 #if defined(VISP_HAVE_PNG)
519  readPNGLibpng(I, filename);
520 #endif
521  } else if (backend == IO_OPENCV_BACKEND) {
522 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
523  readOpenCV(I, filename);
524 #endif
525  } else if (backend == IO_STB_IMAGE_BACKEND) {
526  readStb(I, filename);
527  } else if (backend == IO_SIMDLIB_BACKEND) {
528  readSimdlib(I, filename);
529  }
530 }
531 
540 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
541 // Default: 1. opencv, 2. stb_image
542 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename, int backend)
543 {
544  if (backend == IO_SYSTEM_LIB_BACKEND) {
545 #if !defined(VISP_HAVE_PNG)
546  std::string message =
547  "Libpng backend is not available to read file \"" + filename + "\": switch to stb_image backend";
548  backend = IO_STB_IMAGE_BACKEND;
549 #endif
550  } else if (backend == IO_OPENCV_BACKEND) {
551 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
552  std::string message =
553  "OpenCV backend is not available to read file \"" + filename + "\": switch to stb_image backend";
554  backend = IO_STB_IMAGE_BACKEND;
555 #endif
556  } else if (backend == IO_DEFAULT_BACKEND) {
557 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
558  backend = IO_OPENCV_BACKEND;
559 #else
560  backend = IO_STB_IMAGE_BACKEND;
561 #endif
562  }
563 
564  if (backend == IO_SYSTEM_LIB_BACKEND) {
565 #if defined(VISP_HAVE_PNG)
566  readPNGLibpng(I, filename);
567 #endif
568  } else if (backend == IO_OPENCV_BACKEND) {
569 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
570  readOpenCV(I, filename);
571 #endif
572  } else if (backend == IO_STB_IMAGE_BACKEND) {
573  readStb(I, filename);
574  } else if (backend == IO_SIMDLIB_BACKEND) {
575  readSimdlib(I, filename);
576  }
577 }
578 
587 void vpImageIo::readEXR(vpImage<float> &I, const std::string &filename, int backend)
588 {
589  if (backend == IO_SYSTEM_LIB_BACKEND || backend == IO_SIMDLIB_BACKEND || backend == IO_STB_IMAGE_BACKEND) {
590  std::string message =
591  "This backend cannot read file \"" + filename + "\": switch to the default TinyEXR backend";
592  backend = IO_DEFAULT_BACKEND;
593  } else if (backend == IO_OPENCV_BACKEND) {
594 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
595  std::string message =
596  "OpenCV backend is not available to read file \"" + filename + "\": switch to the default TinyEXR backend";
597  backend = IO_DEFAULT_BACKEND;
598 #endif
599  }
600 
601  if (backend == IO_OPENCV_BACKEND) {
602 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
603  readOpenCV(I, filename);
604 #endif
605  } else if (backend == IO_DEFAULT_BACKEND) {
606 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
607  readEXRTiny(I, filename);
608 #else
609  (void)I;
610  std::string message =
611  "TinyEXR backend is not available to read file \"" + filename + "\": cxx standard should be greater or equal to cxx11";
613 #endif
614  }
615 }
616 
625 void vpImageIo::readEXR(vpImage<vpRGBf> &I, const std::string &filename, int backend)
626 {
627  if (backend == IO_SYSTEM_LIB_BACKEND || backend == IO_SIMDLIB_BACKEND || backend == IO_STB_IMAGE_BACKEND) {
628  std::string message =
629  "This backend cannot read file \"" + filename + "\": switch to the default TinyEXR backend";
630  backend = IO_DEFAULT_BACKEND;
631  } else if (backend == IO_OPENCV_BACKEND) {
632 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
633  std::string message =
634  "OpenCV backend is not available to read file \"" + filename + "\": switch to the default TinyEXR backend";
635  backend = IO_DEFAULT_BACKEND;
636 #endif
637  }
638 
639  if (backend == IO_OPENCV_BACKEND) {
640 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
641  readOpenCV(I, filename);
642 #endif
643  } else if (backend == IO_DEFAULT_BACKEND) {
644 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
645  readEXRTiny(I, filename);
646 #else
647  (void)I;
648  std::string message =
649  "TinyEXR backend is not available to read file \"" + filename + "\": cxx standard should be greater or equal to cxx11";
651 #endif
652  }
653 }
654 
664 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
665 // Default: 1. system, 2. opencv, 3. simd
666 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename, int backend, int quality)
667 {
668  if (backend == IO_SYSTEM_LIB_BACKEND) {
669 #if !defined(VISP_HAVE_JPEG)
670  std::string message = "Libjpeg backend is not available to save file \"" + filename + "\": switch to simd backend";
671  backend = IO_SIMDLIB_BACKEND;
672 #endif
673  } else if (backend == IO_OPENCV_BACKEND) {
674 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
675  std::string message = "OpenCV backend is not available to save file \"" + filename + "\": switch to simd backend";
676  backend = IO_SIMDLIB_BACKEND;
677 #endif
678  } else if (backend == IO_DEFAULT_BACKEND) {
679 #if defined(VISP_HAVE_JPEG)
680  backend = IO_SYSTEM_LIB_BACKEND;
681 #elif defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS)
682  backend = IO_OPENCV_BACKEND;
683 #else
684  backend = IO_SIMDLIB_BACKEND;
685 #endif
686  }
687 
688  if (backend == IO_SYSTEM_LIB_BACKEND) {
689 #if defined(VISP_HAVE_JPEG)
690  writeJPEGLibjpeg(I, filename, quality);
691 #endif
692  } else if (backend == IO_OPENCV_BACKEND) {
693 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
694  writeOpenCV(I, filename, quality);
695 #endif
696  } else if (backend == IO_SIMDLIB_BACKEND) {
697  writeJPEGSimdlib(I, filename, quality);
698  } else if (backend == IO_STB_IMAGE_BACKEND) {
699  writeJPEGStb(I, filename, quality);
700  }
701 }
702 
712 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
713 // Default: 1. system, 2. opencv, , 3. simd
714 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename, int backend, int quality)
715 {
716  if (backend == IO_SYSTEM_LIB_BACKEND) {
717 #if !defined(VISP_HAVE_JPEG)
718  std::string message = "Libjpeg backend is not available to save file \"" + filename + "\": switch to simd backend";
719  backend = IO_SIMDLIB_BACKEND;
720 #endif
721  } else if (backend == IO_OPENCV_BACKEND) {
722 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
723  std::string message = "OpenCV backend is not available to save file \"" + filename + "\": switch to simd backend";
724  backend = IO_SIMDLIB_BACKEND;
725 #endif
726  } else if (backend == IO_DEFAULT_BACKEND) {
727 #if defined(VISP_HAVE_JPEG)
728  backend = IO_SYSTEM_LIB_BACKEND;
729 #elif defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS)
730  backend = IO_OPENCV_BACKEND;
731 #else
732  backend = IO_SIMDLIB_BACKEND;
733 #endif
734  }
735 
736  if (backend == IO_SYSTEM_LIB_BACKEND) {
737 #if defined(VISP_HAVE_JPEG)
738  writeJPEGLibjpeg(I, filename, quality);
739 #endif
740  } else if (backend == IO_OPENCV_BACKEND) {
741 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
742  writeOpenCV(I, filename, quality);
743 #endif
744  } else if (backend == IO_SIMDLIB_BACKEND) {
745  writeJPEGSimdlib(I, filename, quality);
746  } else if (backend == IO_STB_IMAGE_BACKEND) {
747  writeJPEGStb(I, filename, quality);
748  }
749 }
750 
759 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
760 // Default: 1. opencv, 2. simd
761 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename, int backend)
762 {
763  if (backend == IO_SYSTEM_LIB_BACKEND) {
764 #if !defined(VISP_HAVE_PNG)
765  std::string message = "Libpng backend is not available to save file \"" + filename + "\": switch to simd backend";
766  backend = IO_SIMDLIB_BACKEND;
767 #endif
768  } else if (backend == IO_OPENCV_BACKEND) {
769 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
770  std::string message = "OpenCV backend is not available to save file \"" + filename + "\": switch to simd backend";
771  backend = IO_SIMDLIB_BACKEND;
772 #endif
773  } else if (backend == IO_DEFAULT_BACKEND) {
774 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
775  backend = IO_OPENCV_BACKEND;
776 #else
777  backend = IO_SIMDLIB_BACKEND;
778 #endif
779  }
780 
781  if (backend == IO_OPENCV_BACKEND) {
782 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
783  writeOpenCV(I, filename, 90);
784 #endif
785  } else if (backend == IO_SIMDLIB_BACKEND) {
786  writePNGSimdlib(I, filename);
787  } else if (backend == IO_STB_IMAGE_BACKEND) {
788  writePNGStb(I, filename);
789  } else if (backend == IO_SYSTEM_LIB_BACKEND) {
790 #if defined(VISP_HAVE_PNG)
791  writePNGLibpng(I, filename);
792 #endif
793  }
794 }
795 
804 // Strategy based on benchmark: see https://github.com/lagadic/visp/pull/1004
805 // Default: 1. opencv, 2. system, 3. simd
806 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename, int backend)
807 {
808  if (backend == IO_SYSTEM_LIB_BACKEND) {
809 #if !defined(VISP_HAVE_PNG)
810  std::string message = "Libpng backend is not available to save file \"" + filename + "\": switch to simd backend";
811  backend = IO_SIMDLIB_BACKEND;
812 #endif
813  } else if (backend == IO_OPENCV_BACKEND) {
814 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
815  std::string message = "OpenCV backend is not available to save file \"" + filename + "\": switch to simd backend";
816  backend = IO_SIMDLIB_BACKEND;
817 #endif
818  } else if (backend == IO_DEFAULT_BACKEND) {
819 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
820  backend = IO_OPENCV_BACKEND;
821 #else
822  backend = IO_SIMDLIB_BACKEND;
823 #endif
824  }
825 
826  if (backend == IO_OPENCV_BACKEND) {
827 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
828  writeOpenCV(I, filename, 90);
829 #endif
830  } else if (backend == IO_SIMDLIB_BACKEND) {
831  writePNGSimdlib(I, filename);
832  } else if (backend == IO_STB_IMAGE_BACKEND) {
833  writePNGStb(I, filename);
834  } else if (backend == IO_SYSTEM_LIB_BACKEND) {
835 #if defined(VISP_HAVE_PNG)
836  writePNGLibpng(I, filename);
837 #endif
838  }
839 }
840 
849 void vpImageIo::writeEXR(const vpImage<float> &I, const std::string &filename, int backend)
850 {
851  if (backend == IO_SYSTEM_LIB_BACKEND || backend == IO_SIMDLIB_BACKEND || backend == IO_STB_IMAGE_BACKEND) {
852  std::string message =
853  "This backend cannot save file \"" + filename + "\": switch to the default TinyEXR backend";
854  backend = IO_DEFAULT_BACKEND;
855  } else if (backend == IO_OPENCV_BACKEND) {
856 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
857  (void)I;
858  std::string message =
859  "OpenCV backend is not available to save file \"" + filename + "\": switch to the default TinyEXR backend";
860  backend = IO_DEFAULT_BACKEND;
861 #endif
862  }
863 
864  if (backend == IO_OPENCV_BACKEND) {
865 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
866  writeOpenCV(I, filename);
867 #endif
868  } else if (backend == IO_DEFAULT_BACKEND) {
869 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
870  writeEXRTiny(I, filename);
871 #else
872  std::string message =
873  "TinyEXR backend is not available to save file \"" + filename + "\": cxx standard should be greater or equal to cxx11";
875 #endif
876  }
877 }
878 
887 void vpImageIo::writeEXR(const vpImage<vpRGBf> &I, const std::string &filename, int backend)
888 {
889  if (backend == IO_SYSTEM_LIB_BACKEND || backend == IO_SIMDLIB_BACKEND || backend == IO_STB_IMAGE_BACKEND) {
890  std::string message =
891  "This backend cannot save file \"" + filename + "\": switch to the default TinyEXR backend";
892  backend = IO_DEFAULT_BACKEND;
893  } else if (backend == IO_OPENCV_BACKEND) {
894 #if !(defined(VISP_HAVE_OPENCV) && defined(HAVE_OPENCV_IMGCODECS))
895  (void)I;
896  std::string message =
897  "OpenCV backend is not available to save file \"" + filename + "\": switch to the default TinyEXR backend";
898  backend = IO_DEFAULT_BACKEND;
899 #endif
900  }
901 
902  if (backend == IO_OPENCV_BACKEND) {
903 #if ((VISP_HAVE_OPENCV_VERSION >= 0x030000) && defined(HAVE_OPENCV_IMGCODECS)) || ((VISP_HAVE_OPENCV_VERSION < 0x030000) && defined(HAVE_OPENCV_HIGHGUI) && defined(HAVE_OPENCV_IMGPROC))
904  writeOpenCV(I, filename);
905 #endif
906  } else if (backend == IO_DEFAULT_BACKEND) {
907 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
908  writeEXRTiny(I, filename);
909 #else
910  std::string message =
911  "TinyEXR backend is not available to save file \"" + filename + "\": cxx standard should be greater or equal to cxx11";
913 #endif
914  }
915 }
916 
922 void vpImageIo::writePFM(const vpImage<float> &I, const std::string &filename) { vp_writePFM(I, filename); }
923 
930 void vpImageIo::writePFM_HDR(const vpImage<float> &I, const std::string &filename) { vp_writePFM_HDR(I, filename); }
931 
938 void vpImageIo::writePFM_HDR(const vpImage<vpRGBf> &I, const std::string &filename) { vp_writePFM_HDR(I, filename); }
939 
945 void vpImageIo::writePGM(const vpImage<unsigned char> &I, const std::string &filename) { vp_writePGM(I, filename); }
946 
952 void vpImageIo::writePGM(const vpImage<short> &I, const std::string &filename) { vp_writePGM(I, filename); }
953 
959 void vpImageIo::writePGM(const vpImage<vpRGBa> &I, const std::string &filename) { vp_writePGM(I, filename); }
960 
966 void vpImageIo::readPFM(vpImage<float> &I, const std::string &filename) { vp_readPFM(I, filename); }
967 
973 void vpImageIo::readPFM_HDR(vpImage<float> &I, const std::string &filename) { vp_readPFM_HDR(I, filename); }
974 
980 void vpImageIo::readPFM_HDR(vpImage<vpRGBf> &I, const std::string &filename) { vp_readPFM_HDR(I, filename); }
981 
987 void vpImageIo::readPGM(vpImage<unsigned char> &I, const std::string &filename) { vp_readPGM(I, filename); }
988 
994 void vpImageIo::readPGM(vpImage<vpRGBa> &I, const std::string &filename) { vp_readPGM(I, filename); }
995 
1001 void vpImageIo::readPPM(vpImage<unsigned char> &I, const std::string &filename) { vp_readPPM(I, filename); }
1002 
1008 void vpImageIo::readPPM(vpImage<vpRGBa> &I, const std::string &filename) { vp_readPPM(I, filename); }
1009 
1015 void vpImageIo::writePPM(const vpImage<unsigned char> &I, const std::string &filename) { vp_writePPM(I, filename); }
1016 
1022 void vpImageIo::writePPM(const vpImage<vpRGBa> &I, const std::string &filename) { vp_writePPM(I, filename); }
Error that can be emitted by the vpImage class and its derivatives.
@ ioError
Image io error.
static void writePFM(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:922
static void readPGM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:987
@ IO_STB_IMAGE_BACKEND
Use embedded stb_image library.
Definition: vpImageIo.h:126
@ IO_DEFAULT_BACKEND
Default backend.
Definition: vpImageIo.h:122
@ IO_SIMDLIB_BACKEND
Use embedded simd library.
Definition: vpImageIo.h:125
@ IO_SYSTEM_LIB_BACKEND
Use system libraries like libpng or libjpeg.
Definition: vpImageIo.h:123
@ IO_OPENCV_BACKEND
Use OpenCV.
Definition: vpImageIo.h:124
static void writeJPEG(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND, int quality=90)
Definition: vpImageIo.cpp:666
static void readJPEG(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:395
static void readPFM(vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:966
static void writePNG(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:761
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:143
static void readPFM_HDR(vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:973
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1001
static void writePFM_HDR(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:930
static void readEXR(vpImage< float > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:587
static void writePGM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:945
static void writeEXR(const vpImage< float > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:849
static void readPNG(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:493
static void writePPM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1015
static void write(const vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:287
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:1052
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:835