Visual Servoing Platform  version 3.2.1 under development (2019-08-19)
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 #define STB_IMAGE_IMPLEMENTATION
68 #include <stb_image.h>
69 
70 #define STB_IMAGE_WRITE_IMPLEMENTATION
71 #include <stb_image_write.h>
72 #endif
73 #endif
74 
75 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
76  unsigned int &h, unsigned int &maxval);
77 
78 #ifndef DOXYGEN_SHOULD_SKIP_THIS
79 
88 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
89  unsigned int &h, unsigned int &maxval)
90 {
91  std::string line;
92  unsigned int nb_elt = 4, cpt_elt = 0;
93  while (cpt_elt != nb_elt) {
94  // Skip empty lines or lines starting with # (comment)
95  while (std::getline(fd, line) && (line.compare(0, 1, "#") == 0 || line.size() == 0)) {
96  };
97 
98  if (fd.eof()) {
99  fd.close();
100  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
101  }
102 
103  std::vector<std::string> header = vpIoTools::splitChain(line, std::string(" "));
104 
105  if (header.size() == 0) {
106  fd.close();
107  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
108  }
109 
110  if (cpt_elt == 0) { // decode magic
111  if (header[0].compare(0, magic.size(), magic) != 0) {
112  fd.close();
113  throw(vpImageException(vpImageException::ioError, "\"%s\" is not a PNM file with magic number %s",
114  filename.c_str(), magic.c_str()));
115  }
116  cpt_elt++;
117  header.erase(header.begin(),
118  header.begin() + 1); // erase first element that is processed
119  }
120  while (header.size()) {
121  if (cpt_elt == 1) { // decode width
122  std::istringstream ss(header[0]);
123  ss >> w;
124  cpt_elt++;
125  header.erase(header.begin(),
126  header.begin() + 1); // erase first element that is processed
127  } else if (cpt_elt == 2) { // decode height
128  std::istringstream ss(header[0]);
129  ss >> h;
130  cpt_elt++;
131  header.erase(header.begin(),
132  header.begin() + 1); // erase first element that is processed
133  } else if (cpt_elt == 3) { // decode maxval
134  std::istringstream ss(header[0]);
135  ss >> maxval;
136  cpt_elt++;
137  header.erase(header.begin(),
138  header.begin() + 1); // erase first element that is processed
139  }
140  }
141  }
142 }
143 #endif
144 
145 vpImageIo::vpImageFormatType vpImageIo::getFormat(const std::string &filename)
146 {
147  std::string ext = vpImageIo::getExtension(filename);
148 
149  if (ext.compare(".PGM") == 0)
150  return FORMAT_PGM;
151  else if (ext.compare(".pgm") == 0)
152  return FORMAT_PGM;
153  else if (ext.compare(".PPM") == 0)
154  return FORMAT_PPM;
155  else if (ext.compare(".ppm") == 0)
156  return FORMAT_PPM;
157  else if (ext.compare(".JPG") == 0)
158  return FORMAT_JPEG;
159  else if (ext.compare(".jpg") == 0)
160  return FORMAT_JPEG;
161  else if (ext.compare(".JPEG") == 0)
162  return FORMAT_JPEG;
163  else if (ext.compare(".jpeg") == 0)
164  return FORMAT_JPEG;
165  else if (ext.compare(".PNG") == 0)
166  return FORMAT_PNG;
167  else if (ext.compare(".png") == 0)
168  return FORMAT_PNG;
169  // Formats supported by opencv
170  else if (ext.compare(".TIFF") == 0)
171  return FORMAT_TIFF;
172  else if (ext.compare(".tiff") == 0)
173  return FORMAT_TIFF;
174  else if (ext.compare(".TIF") == 0)
175  return FORMAT_TIFF;
176  else if (ext.compare(".tif") == 0)
177  return FORMAT_TIFF;
178  else if (ext.compare(".BMP") == 0)
179  return FORMAT_BMP;
180  else if (ext.compare(".bmp") == 0)
181  return FORMAT_BMP;
182  else if (ext.compare(".DIB") == 0)
183  return FORMAT_DIB;
184  else if (ext.compare(".dib") == 0)
185  return FORMAT_DIB;
186  else if (ext.compare(".PBM") == 0)
187  return FORMAT_PBM;
188  else if (ext.compare(".pbm") == 0)
189  return FORMAT_PBM;
190  else if (ext.compare(".SR") == 0)
191  return FORMAT_RASTER;
192  else if (ext.compare(".sr") == 0)
193  return FORMAT_RASTER;
194  else if (ext.compare(".RAS") == 0)
195  return FORMAT_RASTER;
196  else if (ext.compare(".ras") == 0)
197  return FORMAT_RASTER;
198  else if (ext.compare(".JP2") == 0)
199  return FORMAT_JPEG2000;
200  else if (ext.compare(".jp2") == 0)
201  return FORMAT_JPEG2000;
202  else
203  return FORMAT_UNKNOWN;
204 }
205 
206 // return the extension of the file including the dot
207 std::string vpImageIo::getExtension(const std::string &filename)
208 {
209  // extract the extension
210  size_t dot = filename.find_last_of(".");
211  std::string ext = filename.substr(dot, filename.size() - 1);
212  return ext;
213 }
214 
234 void vpImageIo::read(vpImage<unsigned char> &I, const std::string &filename)
235 {
236  bool exist = vpIoTools::checkFilename(filename);
237  if (!exist) {
238  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
240  }
241 
242  // Allows to use ~ symbol or env variables in path
243  std::string final_filename = vpIoTools::path(filename);
244 
245  bool try_opencv_reader = false;
246 
247  switch (getFormat(final_filename)) {
248  case FORMAT_PGM:
249  readPGM(I, final_filename);
250  break;
251  case FORMAT_PPM:
252  readPPM(I, final_filename);
253  break;
254  case FORMAT_JPEG:
255 #ifdef VISP_HAVE_JPEG
256  readJPEG(I, final_filename);
257 #else
258  try_opencv_reader = true;
259 #endif
260  break;
261  case FORMAT_PNG:
262 #if defined(VISP_HAVE_PNG)
263  readPNG(I, final_filename);
264 #else
265  try_opencv_reader = true;
266 #endif
267  break;
268  case FORMAT_TIFF:
269  case FORMAT_BMP:
270  case FORMAT_DIB:
271  case FORMAT_PBM:
272  case FORMAT_RASTER:
273  case FORMAT_JPEG2000:
274  case FORMAT_UNKNOWN:
275  try_opencv_reader = true;
276  break;
277  }
278 
279  if (try_opencv_reader) {
280 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
281  // std::cout << "Use opencv to read the image" << std::endl;
282  cv::Mat cvI = cv::imread(final_filename, cv::IMREAD_GRAYSCALE);
283  if (cvI.cols == 0 && cvI.rows == 0) {
284  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
286  }
287  vpImageConvert::convert(cvI, I);
288 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
289  // std::cout << "Use opencv to read the image" << std::endl;
290  cv::Mat cvI = cv::imread(final_filename, CV_LOAD_IMAGE_GRAYSCALE);
291  if (cvI.cols == 0 && cvI.rows == 0) {
292  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
294  }
295  vpImageConvert::convert(cvI, I);
296 #else
297  switch (getFormat(final_filename)) {
298  case FORMAT_JPEG:
299  readJPEG(I, final_filename);
300  break;
301  case FORMAT_PNG:
302  readPNG(I, final_filename);
303  break;
304  case FORMAT_BMP:
305  case FORMAT_TIFF:
306  case FORMAT_DIB:
307  case FORMAT_PBM:
308  case FORMAT_RASTER:
309  case FORMAT_JPEG2000:
310  case FORMAT_UNKNOWN:
311  default:
312  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
314  }
315 #endif
316  }
317 }
318 
338 void vpImageIo::read(vpImage<vpRGBa> &I, const std::string &filename)
339 {
340  bool exist = vpIoTools::checkFilename(filename);
341  if (!exist) {
342  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
344  }
345  // Allows to use ~ symbol or env variables in path
346  std::string final_filename = vpIoTools::path(filename);
347 
348  bool try_opencv_reader = false;
349 
350  switch (getFormat(final_filename)) {
351  case FORMAT_PGM:
352  readPGM(I, final_filename);
353  break;
354  case FORMAT_PPM:
355  readPPM(I, final_filename);
356  break;
357  case FORMAT_JPEG:
358 #ifdef VISP_HAVE_JPEG
359  readJPEG(I, final_filename);
360 #else
361  try_opencv_reader = true;
362 #endif
363  break;
364  case FORMAT_PNG:
365 #if defined(VISP_HAVE_PNG)
366  readPNG(I, final_filename);
367 #else
368  try_opencv_reader = true;
369 #endif
370  break;
371  case FORMAT_TIFF:
372  case FORMAT_BMP:
373  case FORMAT_DIB:
374  case FORMAT_PBM:
375  case FORMAT_RASTER:
376  case FORMAT_JPEG2000:
377  case FORMAT_UNKNOWN:
378  try_opencv_reader = true;
379  break;
380  }
381 
382  if (try_opencv_reader) {
383 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
384  // std::cout << "Use opencv to read the image" << std::endl;
385  cv::Mat cvI = cv::imread(final_filename, cv::IMREAD_COLOR);
386  if (cvI.cols == 0 && cvI.rows == 0) {
387  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
389  }
390  vpImageConvert::convert(cvI, I);
391 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
392  // std::cout << "Use opencv to read the image" << std::endl;
393  cv::Mat cvI = cv::imread(final_filename, CV_LOAD_IMAGE_COLOR);
394  if (cvI.cols == 0 && cvI.rows == 0) {
395  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
397  }
398  vpImageConvert::convert(cvI, I);
399 #else
400  switch (getFormat(final_filename)) {
401  case FORMAT_JPEG:
402  readJPEG(I, final_filename);
403  break;
404  case FORMAT_PNG:
405  readPNG(I, final_filename);
406  break;
407  case FORMAT_BMP:
408  case FORMAT_TIFF:
409  case FORMAT_DIB:
410  case FORMAT_PBM:
411  case FORMAT_RASTER:
412  case FORMAT_JPEG2000:
413  case FORMAT_UNKNOWN:
414  default:
415  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
417  }
418 #endif
419  }
420 }
421 
436 void vpImageIo::write(const vpImage<unsigned char> &I, const std::string &filename)
437 {
438  bool try_opencv_writer = false;
439 
440  switch (getFormat(filename)) {
441  case FORMAT_PGM:
442  writePGM(I, filename);
443  break;
444  case FORMAT_PPM:
445  writePPM(I, filename);
446  break;
447  case FORMAT_JPEG:
448 #ifdef VISP_HAVE_JPEG
449  writeJPEG(I, filename);
450 #else
451  try_opencv_writer = true;
452 #endif
453  break;
454  case FORMAT_PNG:
455 #ifdef VISP_HAVE_PNG
456  writePNG(I, filename);
457 #else
458  try_opencv_writer = true;
459 #endif
460  break;
461  case FORMAT_TIFF:
462  case FORMAT_BMP:
463  case FORMAT_DIB:
464  case FORMAT_PBM:
465  case FORMAT_RASTER:
466  case FORMAT_JPEG2000:
467  case FORMAT_UNKNOWN:
468  try_opencv_writer = true;
469  break;
470  }
471 
472  if (try_opencv_writer) {
473 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
474  // std::cout << "Use opencv to write the image" << std::endl;
475  cv::Mat cvI;
476  vpImageConvert::convert(I, cvI);
477  cv::imwrite(filename, cvI);
478 #else
479  switch (getFormat(filename)) {
480  case FORMAT_JPEG:
481  writeJPEG(I, filename);
482  break;
483  case FORMAT_PNG:
484  writePNG(I, filename);
485  break;
486  case FORMAT_BMP:
487  case FORMAT_TIFF:
488  case FORMAT_DIB:
489  case FORMAT_PBM:
490  case FORMAT_RASTER:
491  case FORMAT_JPEG2000:
492  case FORMAT_UNKNOWN:
493  default:
494  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
495  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
496  }
497 #endif
498  }
499 }
500 
515 void vpImageIo::write(const vpImage<vpRGBa> &I, const std::string &filename)
516 {
517  bool try_opencv_writer = false;
518 
519  switch (getFormat(filename)) {
520  case FORMAT_PGM:
521  writePGM(I, filename);
522  break;
523  case FORMAT_PPM:
524  writePPM(I, filename);
525  break;
526  case FORMAT_JPEG:
527 #ifdef VISP_HAVE_JPEG
528  writeJPEG(I, filename);
529 #else
530  try_opencv_writer = true;
531 #endif
532  break;
533  case FORMAT_PNG:
534 #ifdef VISP_HAVE_PNG
535  writePNG(I, filename);
536 #else
537  try_opencv_writer = true;
538 #endif
539  break;
540  case FORMAT_TIFF:
541  case FORMAT_BMP:
542  case FORMAT_DIB:
543  case FORMAT_PBM:
544  case FORMAT_RASTER:
545  case FORMAT_JPEG2000:
546  case FORMAT_UNKNOWN:
547  try_opencv_writer = true;
548  break;
549  }
550 
551  if (try_opencv_writer) {
552 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
553  // std::cout << "Use opencv to write the image" << std::endl;
554  cv::Mat cvI;
555  vpImageConvert::convert(I, cvI);
556  cv::imwrite(filename, cvI);
557 #else
558  switch (getFormat(filename)) {
559  case FORMAT_JPEG:
560  writeJPEG(I, filename);
561  break;
562  case FORMAT_PNG:
563  writePNG(I, filename);
564  break;
565  case FORMAT_BMP:
566  case FORMAT_TIFF:
567  case FORMAT_DIB:
568  case FORMAT_PBM:
569  case FORMAT_RASTER:
570  case FORMAT_JPEG2000:
571  case FORMAT_UNKNOWN:
572  default:
573  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
574  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
575  }
576 #endif
577  }
578 }
579 
580 //--------------------------------------------------------------------------
581 // PFM
582 //--------------------------------------------------------------------------
583 
593 void vpImageIo::writePFM(const vpImage<float> &I, const std::string &filename)
594 {
595  FILE *fd;
596 
597  // Test the filename
598  if (filename.empty()) {
599  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
600  }
601 
602  fd = fopen(filename.c_str(), "wb");
603 
604  if (fd == NULL) {
605  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
606  }
607 
608  // Write the head
609  fprintf(fd, "P8\n"); // Magic number
610  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
611  fprintf(fd, "255\n"); // Max level
612 
613  // Write the bitmap
614  size_t ierr;
615  size_t nbyte = I.getWidth() * I.getHeight();
616 
617  ierr = fwrite(I.bitmap, sizeof(float), nbyte, fd);
618  if (ierr != nbyte) {
619  fclose(fd);
620  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
621  filename.c_str(), ierr, nbyte));
622  }
623 
624  fflush(fd);
625  fclose(fd);
626 }
627 //--------------------------------------------------------------------------
628 // PGM
629 //--------------------------------------------------------------------------
630 
639 void vpImageIo::writePGM(const vpImage<unsigned char> &I, const std::string &filename)
640 {
641 
642  FILE *fd;
643 
644  // Test the filename
645  if (filename.empty()) {
646  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
647  }
648 
649  fd = fopen(filename.c_str(), "wb");
650 
651  if (fd == NULL) {
652  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
653  }
654 
655  // Write the head
656  fprintf(fd, "P5\n"); // Magic number
657  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
658  fprintf(fd, "255\n"); // Max level
659 
660  // Write the bitmap
661  size_t ierr;
662  size_t nbyte = I.getWidth() * I.getHeight();
663 
664  ierr = fwrite(I.bitmap, sizeof(unsigned char), nbyte, fd);
665  if (ierr != nbyte) {
666  fclose(fd);
667  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
668  filename.c_str(), ierr, nbyte));
669  }
670 
671  fflush(fd);
672  fclose(fd);
673 }
674 
682 void vpImageIo::writePGM(const vpImage<short> &I, const std::string &filename)
683 {
685  unsigned int nrows = I.getHeight();
686  unsigned int ncols = I.getWidth();
687 
688  Iuc.resize(nrows, ncols);
689 
690  for (unsigned int i = 0; i < nrows * ncols; i++)
691  Iuc.bitmap[i] = (unsigned char)I.bitmap[i];
692 
693  vpImageIo::writePGM(Iuc, filename);
694 }
704 void vpImageIo::writePGM(const vpImage<vpRGBa> &I, const std::string &filename)
705 {
706 
707  FILE *fd;
708 
709  // Test the filename
710  if (filename.empty()) {
711  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
712  }
713 
714  fd = fopen(filename.c_str(), "wb");
715 
716  if (fd == NULL) {
717  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
718  }
719 
720  // Write the head
721  fprintf(fd, "P5\n"); // Magic number
722  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
723  fprintf(fd, "255\n"); // Max level
724 
725  // Write the bitmap
726  size_t ierr;
727  size_t nbyte = I.getWidth() * I.getHeight();
728 
730  vpImageConvert::convert(I, Itmp);
731 
732  ierr = fwrite(Itmp.bitmap, sizeof(unsigned char), nbyte, fd);
733  if (ierr != nbyte) {
734  fclose(fd);
735  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
736  filename.c_str(), ierr, nbyte));
737  }
738 
739  fflush(fd);
740  fclose(fd);
741 }
742 
759 void vpImageIo::readPFM(vpImage<float> &I, const std::string &filename)
760 {
761  unsigned int w = 0, h = 0, maxval = 0;
762  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
763  std::string magic("P8");
764 
765  std::ifstream fd(filename.c_str(), std::ios::binary);
766 
767  // Open the filename
768  if (!fd.is_open()) {
769  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
770  }
771 
772  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
773 
774  if (w > w_max || h > h_max) {
775  fd.close();
776  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
777  }
778  if (maxval > maxval_max) {
779  fd.close();
780  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
781  }
782 
783  if ((h != I.getHeight()) || (w != I.getWidth())) {
784  I.resize(h, w);
785  }
786 
787  unsigned int nbyte = I.getHeight() * I.getWidth();
788  fd.read((char *)I.bitmap, sizeof(float) * nbyte);
789  if (!fd) {
790  fd.close();
791  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
792  filename.c_str()));
793  }
794 
795  fd.close();
796 }
797 
813 void vpImageIo::readPGM(vpImage<unsigned char> &I, const std::string &filename)
814 {
815  unsigned int w = 0, h = 0, maxval = 0;
816  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
817  std::string magic("P5");
818 
819  std::ifstream fd(filename.c_str(), std::ios::binary);
820 
821  // Open the filename
822  if (!fd.is_open()) {
823  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
824  }
825 
826  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
827 
828  if (w > w_max || h > h_max) {
829  fd.close();
830  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
831  }
832  if (maxval > maxval_max) {
833  fd.close();
834  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
835  }
836 
837  if ((h != I.getHeight()) || (w != I.getWidth())) {
838  I.resize(h, w);
839  }
840 
841  unsigned int nbyte = I.getHeight() * I.getWidth();
842  fd.read((char *)I.bitmap, nbyte);
843  if (!fd) {
844  fd.close();
845  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
846  filename.c_str()));
847  }
848 
849  fd.close();
850 }
851 
870 void vpImageIo::readPGM(vpImage<vpRGBa> &I, const std::string &filename)
871 {
873 
874  vpImageIo::readPGM(Itmp, filename);
875 
876  vpImageConvert::convert(Itmp, I);
877 }
878 
879 //--------------------------------------------------------------------------
880 // PPM
881 //--------------------------------------------------------------------------
882 
899 void vpImageIo::readPPM(vpImage<unsigned char> &I, const std::string &filename)
900 {
901  vpImage<vpRGBa> Itmp;
902 
903  vpImageIo::readPPM(Itmp, filename);
904 
905  vpImageConvert::convert(Itmp, I);
906 }
907 
919 void vpImageIo::readPPM(vpImage<vpRGBa> &I, const std::string &filename)
920 {
921  unsigned int w = 0, h = 0, maxval = 0;
922  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
923  std::string magic("P6");
924 
925  std::ifstream fd(filename.c_str(), std::ios::binary);
926 
927  // Open the filename
928  if (!fd.is_open()) {
929  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
930  }
931 
932  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
933 
934  if (w > w_max || h > h_max) {
935  fd.close();
936  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
937  }
938  if (maxval > maxval_max) {
939  fd.close();
940  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
941  }
942 
943  if ((h != I.getHeight()) || (w != I.getWidth())) {
944  I.resize(h, w);
945  }
946 
947  for (unsigned int i = 0; i < I.getHeight(); i++) {
948  for (unsigned int j = 0; j < I.getWidth(); j++) {
949  unsigned char rgb[3];
950  fd.read((char *)&rgb, 3);
951 
952  if (!fd) {
953  fd.close();
954  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"",
955  (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
956  }
957 
958  I[i][j].R = rgb[0];
959  I[i][j].G = rgb[1];
960  I[i][j].B = rgb[2];
961  I[i][j].A = vpRGBa::alpha_default;
962  }
963  }
964 
965  fd.close();
966 }
967 
978 void vpImageIo::writePPM(const vpImage<unsigned char> &I, const std::string &filename)
979 {
980  vpImage<vpRGBa> Itmp;
981 
982  vpImageConvert::convert(I, Itmp);
983 
984  vpImageIo::writePPM(Itmp, filename);
985 }
986 
994 void vpImageIo::writePPM(const vpImage<vpRGBa> &I, const std::string &filename)
995 {
996  FILE *f;
997 
998  // Test the filename
999  if (filename.empty()) {
1000  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file: filename empty"));
1001  }
1002 
1003  f = fopen(filename.c_str(), "wb");
1004 
1005  if (f == NULL) {
1006  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file \"%s\"", filename.c_str()));
1007  }
1008 
1009  fprintf(f, "P6\n"); // Magic number
1010  fprintf(f, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
1011  fprintf(f, "%d\n", 255); // Max level
1012 
1013  for (unsigned int i = 0; i < I.getHeight(); i++) {
1014  for (unsigned int j = 0; j < I.getWidth(); j++) {
1015  vpRGBa v = I[i][j];
1016  unsigned char rgb[3];
1017  rgb[0] = v.R;
1018  rgb[1] = v.G;
1019  rgb[2] = v.B;
1020 
1021  size_t res = fwrite(&rgb, 1, 3, f);
1022  if (res != 3) {
1023  fclose(f);
1024  throw(vpImageException(vpImageException::ioError, "cannot write file \"%s\"", filename.c_str()));
1025  }
1026  }
1027  }
1028 
1029  fflush(f);
1030  fclose(f);
1031 }
1032 
1033 //--------------------------------------------------------------------------
1034 // JPEG
1035 //--------------------------------------------------------------------------
1036 
1037 #if defined(VISP_HAVE_JPEG)
1038 
1046 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1047 {
1048  struct jpeg_compress_struct cinfo;
1049  struct jpeg_error_mgr jerr;
1050  FILE *file;
1051 
1052  cinfo.err = jpeg_std_error(&jerr);
1053  jpeg_create_compress(&cinfo);
1054 
1055  // Test the filename
1056  if (filename.empty()) {
1057  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1058  }
1059 
1060  file = fopen(filename.c_str(), "wb");
1061 
1062  if (file == NULL) {
1063  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1064  }
1065 
1066  unsigned int width = I.getWidth();
1067  unsigned int height = I.getHeight();
1068 
1069  jpeg_stdio_dest(&cinfo, file);
1070 
1071  cinfo.image_width = width;
1072  cinfo.image_height = height;
1073  cinfo.input_components = 1;
1074  cinfo.in_color_space = JCS_GRAYSCALE;
1075  jpeg_set_defaults(&cinfo);
1076 
1077  jpeg_start_compress(&cinfo, TRUE);
1078 
1079  unsigned char *line;
1080  line = new unsigned char[width];
1081  unsigned char *input = (unsigned char *)I.bitmap;
1082  while (cinfo.next_scanline < cinfo.image_height) {
1083  for (unsigned int i = 0; i < width; i++) {
1084  line[i] = *(input);
1085  input++;
1086  }
1087  jpeg_write_scanlines(&cinfo, &line, 1);
1088  }
1089 
1090  jpeg_finish_compress(&cinfo);
1091  jpeg_destroy_compress(&cinfo);
1092  delete[] line;
1093  fclose(file);
1094 }
1095 
1103 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1104 {
1105  struct jpeg_compress_struct cinfo;
1106  struct jpeg_error_mgr jerr;
1107  FILE *file;
1108 
1109  cinfo.err = jpeg_std_error(&jerr);
1110  jpeg_create_compress(&cinfo);
1111 
1112  // Test the filename
1113  if (filename.empty()) {
1114  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1115  }
1116 
1117  file = fopen(filename.c_str(), "wb");
1118 
1119  if (file == NULL) {
1120  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1121  }
1122 
1123  unsigned int width = I.getWidth();
1124  unsigned int height = I.getHeight();
1125 
1126  jpeg_stdio_dest(&cinfo, file);
1127 
1128  cinfo.image_width = width;
1129  cinfo.image_height = height;
1130  cinfo.input_components = 3;
1131  cinfo.in_color_space = JCS_RGB;
1132  jpeg_set_defaults(&cinfo);
1133 
1134  jpeg_start_compress(&cinfo, TRUE);
1135 
1136  unsigned char *line;
1137  line = new unsigned char[3 * width];
1138  unsigned char *input = (unsigned char *)I.bitmap;
1139  while (cinfo.next_scanline < cinfo.image_height) {
1140  for (unsigned int i = 0; i < width; i++) {
1141  line[i * 3] = *(input);
1142  input++;
1143  line[i * 3 + 1] = *(input);
1144  input++;
1145  line[i * 3 + 2] = *(input);
1146  input++;
1147  input++;
1148  }
1149  jpeg_write_scanlines(&cinfo, &line, 1);
1150  }
1151 
1152  jpeg_finish_compress(&cinfo);
1153  jpeg_destroy_compress(&cinfo);
1154  delete[] line;
1155  fclose(file);
1156 }
1157 
1174 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1175 {
1176  struct jpeg_decompress_struct cinfo;
1177  struct jpeg_error_mgr jerr;
1178  FILE *file;
1179 
1180  cinfo.err = jpeg_std_error(&jerr);
1181  jpeg_create_decompress(&cinfo);
1182 
1183  // Test the filename
1184  if (filename.empty()) {
1185  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1186  }
1187 
1188  file = fopen(filename.c_str(), "rb");
1189 
1190  if (file == NULL) {
1191  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1192  }
1193 
1194  jpeg_stdio_src(&cinfo, file);
1195  jpeg_read_header(&cinfo, TRUE);
1196 
1197  unsigned int width = cinfo.image_width;
1198  unsigned int height = cinfo.image_height;
1199 
1200  if ((width != I.getWidth()) || (height != I.getHeight()))
1201  I.resize(height, width);
1202 
1203  jpeg_start_decompress(&cinfo);
1204 
1205  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1206  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1207 
1208  if (cinfo.out_color_space == JCS_RGB) {
1209  vpImage<vpRGBa> Ic(height, width);
1210  unsigned char *output = (unsigned char *)Ic.bitmap;
1211  while (cinfo.output_scanline < cinfo.output_height) {
1212  jpeg_read_scanlines(&cinfo, buffer, 1);
1213  for (unsigned int i = 0; i < width; i++) {
1214  *(output++) = buffer[0][i * 3];
1215  *(output++) = buffer[0][i * 3 + 1];
1216  *(output++) = buffer[0][i * 3 + 2];
1217  *(output++) = vpRGBa::alpha_default;
1218  }
1219  }
1220  vpImageConvert::convert(Ic, I);
1221  }
1222 
1223  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1224  while (cinfo.output_scanline < cinfo.output_height) {
1225  unsigned int row = cinfo.output_scanline;
1226  jpeg_read_scanlines(&cinfo, buffer, 1);
1227  memcpy(I[row], buffer[0], rowbytes);
1228  }
1229  }
1230 
1231  jpeg_finish_decompress(&cinfo);
1232  jpeg_destroy_decompress(&cinfo);
1233  fclose(file);
1234 }
1235 
1254 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1255 {
1256  struct jpeg_decompress_struct cinfo;
1257  struct jpeg_error_mgr jerr;
1258  FILE *file;
1259 
1260  cinfo.err = jpeg_std_error(&jerr);
1261  jpeg_create_decompress(&cinfo);
1262 
1263  // Test the filename
1264  if (filename.empty()) {
1265  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1266  }
1267 
1268  file = fopen(filename.c_str(), "rb");
1269 
1270  if (file == NULL) {
1271  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1272  }
1273 
1274  jpeg_stdio_src(&cinfo, file);
1275 
1276  jpeg_read_header(&cinfo, TRUE);
1277 
1278  unsigned int width = cinfo.image_width;
1279  unsigned int height = cinfo.image_height;
1280 
1281  if ((width != I.getWidth()) || (height != I.getHeight()))
1282  I.resize(height, width);
1283 
1284  jpeg_start_decompress(&cinfo);
1285 
1286  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1287  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1288 
1289  if (cinfo.out_color_space == JCS_RGB) {
1290  unsigned char *output = (unsigned char *)I.bitmap;
1291  while (cinfo.output_scanline < cinfo.output_height) {
1292  jpeg_read_scanlines(&cinfo, buffer, 1);
1293  for (unsigned int i = 0; i < width; i++) {
1294  *(output++) = buffer[0][i * 3];
1295  *(output++) = buffer[0][i * 3 + 1];
1296  *(output++) = buffer[0][i * 3 + 2];
1297  *(output++) = vpRGBa::alpha_default;
1298  }
1299  }
1300  }
1301 
1302  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1303  vpImage<unsigned char> Ig(height, width);
1304 
1305  while (cinfo.output_scanline < cinfo.output_height) {
1306  unsigned int row = cinfo.output_scanline;
1307  jpeg_read_scanlines(&cinfo, buffer, 1);
1308  memcpy(Ig[row], buffer[0], rowbytes);
1309  }
1310 
1311  vpImageConvert::convert(Ig, I);
1312  }
1313 
1314  jpeg_finish_decompress(&cinfo);
1315  jpeg_destroy_decompress(&cinfo);
1316  fclose(file);
1317 }
1318 
1319 #elif defined(VISP_HAVE_OPENCV)
1320 
1328 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1329 {
1330 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1331  cv::Mat Ip;
1332  vpImageConvert::convert(I, Ip);
1333  cv::imwrite(filename.c_str(), Ip);
1334 #else
1335  IplImage *Ip = NULL;
1336  vpImageConvert::convert(I, Ip);
1337 
1338  cvSaveImage(filename.c_str(), Ip);
1339 
1340  cvReleaseImage(&Ip);
1341 #endif
1342 }
1343 
1351 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1352 {
1353 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1354  cv::Mat Ip;
1355  vpImageConvert::convert(I, Ip);
1356  cv::imwrite(filename.c_str(), Ip);
1357 #else
1358  IplImage *Ip = NULL;
1359  vpImageConvert::convert(I, Ip);
1360 
1361  cvSaveImage(filename.c_str(), Ip);
1362 
1363  cvReleaseImage(&Ip);
1364 #endif
1365 }
1366 
1383 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1384 {
1385 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1386  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
1387  if (!Ip.empty())
1388  vpImageConvert::convert(Ip, I);
1389  else
1390  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1391 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1392  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1393  if (!Ip.empty())
1394  vpImageConvert::convert(Ip, I);
1395  else
1396  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1397 #else
1398  IplImage *Ip = NULL;
1399  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1400  if (Ip != NULL)
1401  vpImageConvert::convert(Ip, I);
1402  else
1403  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1404  cvReleaseImage(&Ip);
1405 #endif
1406 }
1407 
1426 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1427 {
1428 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1429  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
1430  if (!Ip.empty())
1431  vpImageConvert::convert(Ip, I);
1432  else
1433  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1434 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1435  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1436  if (!Ip.empty())
1437  vpImageConvert::convert(Ip, I);
1438  else
1439  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1440 #else
1441  IplImage *Ip = NULL;
1442  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
1443  if (Ip != NULL)
1444  vpImageConvert::convert(Ip, I);
1445  else
1446  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1447  cvReleaseImage(&Ip);
1448 #endif
1449 }
1450 #else
1451 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1452 {
1453  int width = 0, height = 0, channels = 0;
1454  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
1455  if (image == NULL) {
1456  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1457  }
1458  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1459  stbi_image_free(image);
1460 }
1461 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1462 {
1463  int width = 0, height = 0, channels = 0;
1464  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
1465  if (image == NULL) {
1466  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
1467  }
1468  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
1469  stbi_image_free(image);
1470 }
1471 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1472 {
1473  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
1474  reinterpret_cast<void*>(I.bitmap), 90);
1475  if (res == 0) {
1476  throw(vpImageException(vpImageException::ioError, "JPEG write error"));
1477  }
1478 }
1479 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1480 {
1481  int res = stbi_write_jpg(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
1482  reinterpret_cast<void*>(I.bitmap), 90);
1483  if (res == 0) {
1484  throw(vpImageException(vpImageException::ioError, "JEPG write error"));
1485  }
1486 }
1487 #endif
1488 
1489 //--------------------------------------------------------------------------
1490 // PNG
1491 //--------------------------------------------------------------------------
1492 
1493 #if defined(VISP_HAVE_PNG)
1494 
1502 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1503 {
1504  FILE *file;
1505 
1506  // Test the filename
1507  if (filename.empty()) {
1508  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1509  }
1510 
1511  file = fopen(filename.c_str(), "wb");
1512 
1513  if (file == NULL) {
1514  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1515  }
1516 
1517  /* create a png info struct */
1518  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1519  if (!png_ptr) {
1520  fclose(file);
1521  vpERROR_TRACE("Error during png_create_write_struct()\n");
1522  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1523  }
1524 
1525  png_infop info_ptr = png_create_info_struct(png_ptr);
1526  if (!info_ptr) {
1527  fclose(file);
1528  png_destroy_write_struct(&png_ptr, NULL);
1529  vpERROR_TRACE("Error during png_create_info_struct()\n");
1530  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1531  }
1532 
1533  /* initialize the setjmp for returning properly after a libpng error occured
1534  */
1535  if (setjmp(png_jmpbuf(png_ptr))) {
1536  fclose(file);
1537  png_destroy_write_struct(&png_ptr, &info_ptr);
1538  vpERROR_TRACE("Error during init_io\n");
1539  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1540  }
1541 
1542  /* setup libpng for using standard C fwrite() function with our FILE pointer
1543  */
1544  png_init_io(png_ptr, file);
1545 
1546  unsigned int width = I.getWidth();
1547  unsigned int height = I.getHeight();
1548  int bit_depth = 8;
1549  int color_type = PNG_COLOR_TYPE_GRAY;
1550  /* set some useful information from header */
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 write header\n");
1556  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1557  }
1558 
1559  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1560  PNG_FILTER_TYPE_BASE);
1561 
1562  png_write_info(png_ptr, info_ptr);
1563 
1564  png_bytep *row_ptrs = new png_bytep[height];
1565  for (unsigned int i = 0; i < height; i++)
1566  row_ptrs[i] = new png_byte[width];
1567 
1568  unsigned char *input = (unsigned char *)I.bitmap;
1569 
1570  for (unsigned int i = 0; i < height; i++) {
1571  png_byte *row = row_ptrs[i];
1572  for (unsigned int j = 0; j < width; j++) {
1573  row[j] = *(input);
1574  input++;
1575  }
1576  }
1577 
1578  png_write_image(png_ptr, row_ptrs);
1579 
1580  png_write_end(png_ptr, NULL);
1581 
1582  for (unsigned int j = 0; j < height; j++)
1583  delete[] row_ptrs[j];
1584 
1585  delete[] row_ptrs;
1586 
1587  png_destroy_write_struct(&png_ptr, &info_ptr);
1588 
1589  fclose(file);
1590 }
1591 
1599 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1600 {
1601  FILE *file;
1602 
1603  // Test the filename
1604  if (filename.empty()) {
1605  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1606  }
1607 
1608  file = fopen(filename.c_str(), "wb");
1609 
1610  if (file == NULL) {
1611  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1612  }
1613 
1614  /* create a png info struct */
1615  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1616  if (!png_ptr) {
1617  fclose(file);
1618  vpERROR_TRACE("Error during png_create_write_struct()\n");
1619  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1620  }
1621 
1622  png_infop info_ptr = png_create_info_struct(png_ptr);
1623  if (!info_ptr) {
1624  fclose(file);
1625  png_destroy_write_struct(&png_ptr, NULL);
1626  vpERROR_TRACE("Error during png_create_info_struct()\n");
1627  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1628  }
1629 
1630  /* initialize the setjmp for returning properly after a libpng error occured
1631  */
1632  if (setjmp(png_jmpbuf(png_ptr))) {
1633  fclose(file);
1634  png_destroy_write_struct(&png_ptr, &info_ptr);
1635  vpERROR_TRACE("Error during init_io\n");
1636  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1637  }
1638 
1639  /* setup libpng for using standard C fwrite() function with our FILE pointer
1640  */
1641  png_init_io(png_ptr, file);
1642 
1643  unsigned int width = I.getWidth();
1644  unsigned int height = I.getHeight();
1645  int bit_depth = 8;
1646  int color_type = PNG_COLOR_TYPE_RGB;
1647  /* set some useful information from header */
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 write header\n");
1653  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1654  }
1655 
1656  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1657  PNG_FILTER_TYPE_BASE);
1658 
1659  png_write_info(png_ptr, info_ptr);
1660 
1661  png_bytep *row_ptrs = new png_bytep[height];
1662  for (unsigned int i = 0; i < height; i++)
1663  row_ptrs[i] = new png_byte[3 * width];
1664 
1665  unsigned char *input = (unsigned char *)I.bitmap;
1666  ;
1667 
1668  for (unsigned int i = 0; i < height; i++) {
1669  png_byte *row = row_ptrs[i];
1670  for (unsigned int j = 0; j < width; j++) {
1671  row[3 * j] = *(input);
1672  input++;
1673  row[3 * j + 1] = *(input);
1674  input++;
1675  row[3 * j + 2] = *(input);
1676  input++;
1677  input++;
1678  }
1679  }
1680 
1681  png_write_image(png_ptr, row_ptrs);
1682 
1683  png_write_end(png_ptr, NULL);
1684 
1685  for (unsigned int j = 0; j < height; j++)
1686  delete[] row_ptrs[j];
1687 
1688  delete[] row_ptrs;
1689 
1690  png_destroy_write_struct(&png_ptr, &info_ptr);
1691 
1692  fclose(file);
1693 }
1694 
1711 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1712 {
1713  FILE *file;
1714  png_byte magic[8];
1715  // Test the filename
1716  if (filename.empty()) {
1717  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1718  }
1719 
1720  file = fopen(filename.c_str(), "rb");
1721 
1722  if (file == NULL) {
1723  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1724  }
1725 
1726  /* read magic number */
1727  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1728  fclose(file);
1729  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1730  }
1731 
1732  /* check for valid magic number */
1733  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1734  fclose(file);
1735  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1736  filename.c_str()));
1737  }
1738 
1739  /* create a png read struct */
1740  // printf("version %s\n", PNG_LIBPNG_VER_STRING);
1741  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1742  if (png_ptr == NULL) {
1743  fprintf(stderr, "error: can't create a png read structure!\n");
1744  fclose(file);
1745  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1746  }
1747 
1748  /* create a png info struct */
1749  png_infop info_ptr = png_create_info_struct(png_ptr);
1750  if (info_ptr == NULL) {
1751  fprintf(stderr, "error: can't create a png info structure!\n");
1752  fclose(file);
1753  png_destroy_read_struct(&png_ptr, NULL, NULL);
1754  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1755  }
1756 
1757  /* initialize the setjmp for returning properly after a libpng error occured
1758  */
1759  if (setjmp(png_jmpbuf(png_ptr))) {
1760  fclose(file);
1761  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1762  vpERROR_TRACE("Error during init io\n");
1763  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1764  }
1765 
1766  /* setup libpng for using standard C fread() function with our FILE pointer
1767  */
1768  png_init_io(png_ptr, file);
1769 
1770  /* tell libpng that we have already read the magic number */
1771  png_set_sig_bytes(png_ptr, sizeof(magic));
1772 
1773  /* read png info */
1774  png_read_info(png_ptr, info_ptr);
1775 
1776  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1777  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1778 
1779  unsigned int bit_depth, channels, color_type;
1780  /* get some useful information from header */
1781  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1782  channels = png_get_channels(png_ptr, info_ptr);
1783  color_type = png_get_color_type(png_ptr, info_ptr);
1784 
1785  /* convert index color images to RGB images */
1786  if (color_type == PNG_COLOR_TYPE_PALETTE)
1787  png_set_palette_to_rgb(png_ptr);
1788 
1789  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1790  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1791  png_set_expand(png_ptr);
1792 
1793  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1794  // png_set_tRNS_to_alpha (png_ptr);
1795 
1796  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1797  png_set_strip_alpha(png_ptr);
1798 
1799  if (bit_depth == 16)
1800  png_set_strip_16(png_ptr);
1801  else if (bit_depth < 8)
1802  png_set_packing(png_ptr);
1803 
1804  /* update info structure to apply transformations */
1805  png_read_update_info(png_ptr, info_ptr);
1806 
1807  channels = png_get_channels(png_ptr, info_ptr);
1808 
1809  if ((width != I.getWidth()) || (height != I.getHeight()))
1810  I.resize(height, width);
1811 
1812  png_bytep *rowPtrs = new png_bytep[height];
1813 
1814  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1815  unsigned char *data = new unsigned char[stride * height];
1816 
1817  for (unsigned int i = 0; i < height; i++)
1818  rowPtrs[i] = (png_bytep)data + (i * stride);
1819 
1820  png_read_image(png_ptr, rowPtrs);
1821 
1822  vpImage<vpRGBa> Ic(height, width);
1823  unsigned char *output;
1824 
1825  switch (channels) {
1826  case 1:
1827  output = (unsigned char *)I.bitmap;
1828  for (unsigned int i = 0; i < width * height; i++) {
1829  *(output++) = data[i];
1830  }
1831  break;
1832 
1833  case 2:
1834  output = (unsigned char *)I.bitmap;
1835  for (unsigned int i = 0; i < width * height; i++) {
1836  *(output++) = data[i * 2];
1837  }
1838  break;
1839 
1840  case 3:
1841  output = (unsigned char *)Ic.bitmap;
1842  for (unsigned int i = 0; i < width * height; i++) {
1843  *(output++) = data[i * 3];
1844  *(output++) = data[i * 3 + 1];
1845  *(output++) = data[i * 3 + 2];
1846  *(output++) = vpRGBa::alpha_default;
1847  }
1848  vpImageConvert::convert(Ic, I);
1849  break;
1850 
1851  case 4:
1852  output = (unsigned char *)Ic.bitmap;
1853  for (unsigned int i = 0; i < width * height; i++) {
1854  *(output++) = data[i * 4];
1855  *(output++) = data[i * 4 + 1];
1856  *(output++) = data[i * 4 + 2];
1857  *(output++) = data[i * 4 + 3];
1858  }
1859  vpImageConvert::convert(Ic, I);
1860  break;
1861  }
1862 
1863  delete[](png_bytep) rowPtrs;
1864  delete[] data;
1865  png_read_end(png_ptr, NULL);
1866  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1867  fclose(file);
1868 }
1869 
1888 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
1889 {
1890  FILE *file;
1891  png_byte magic[8];
1892 
1893  // Test the filename
1894  if (filename.empty()) {
1895  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1896  }
1897 
1898  file = fopen(filename.c_str(), "rb");
1899 
1900  if (file == NULL) {
1901  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1902  }
1903 
1904  /* read magic number */
1905  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1906  fclose(file);
1907  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1908  }
1909 
1910  /* check for valid magic number */
1911  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1912  fclose(file);
1913  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1914  filename.c_str()));
1915  }
1916 
1917  /* create a png read struct */
1918  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1919  if (!png_ptr) {
1920  fclose(file);
1921  vpERROR_TRACE("Error during png_create_read_struct()\n");
1922  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1923  }
1924 
1925  /* create a png info struct */
1926  png_infop info_ptr = png_create_info_struct(png_ptr);
1927  if (!info_ptr) {
1928  fclose(file);
1929  png_destroy_read_struct(&png_ptr, NULL, NULL);
1930  vpERROR_TRACE("Error during png_create_info_struct()\n");
1931  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1932  }
1933 
1934  /* initialize the setjmp for returning properly after a libpng error occured
1935  */
1936  if (setjmp(png_jmpbuf(png_ptr))) {
1937  fclose(file);
1938  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1939  vpERROR_TRACE("Error during init io\n");
1940  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1941  }
1942 
1943  /* setup libpng for using standard C fread() function with our FILE pointer
1944  */
1945  png_init_io(png_ptr, file);
1946 
1947  /* tell libpng that we have already read the magic number */
1948  png_set_sig_bytes(png_ptr, sizeof(magic));
1949 
1950  /* read png info */
1951  png_read_info(png_ptr, info_ptr);
1952 
1953  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1954  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1955 
1956  unsigned int bit_depth, channels, color_type;
1957  /* get some useful information from header */
1958  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1959  channels = png_get_channels(png_ptr, info_ptr);
1960  color_type = png_get_color_type(png_ptr, info_ptr);
1961 
1962  /* convert index color images to RGB images */
1963  if (color_type == PNG_COLOR_TYPE_PALETTE)
1964  png_set_palette_to_rgb(png_ptr);
1965 
1966  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1967  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1968  png_set_expand(png_ptr);
1969 
1970  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1971  // png_set_tRNS_to_alpha (png_ptr);
1972 
1973  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1974  png_set_strip_alpha(png_ptr);
1975 
1976  if (bit_depth == 16)
1977  png_set_strip_16(png_ptr);
1978  else if (bit_depth < 8)
1979  png_set_packing(png_ptr);
1980 
1981  /* update info structure to apply transformations */
1982  png_read_update_info(png_ptr, info_ptr);
1983 
1984  channels = png_get_channels(png_ptr, info_ptr);
1985 
1986  if ((width != I.getWidth()) || (height != I.getHeight()))
1987  I.resize(height, width);
1988 
1989  png_bytep *rowPtrs = new png_bytep[height];
1990 
1991  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1992  unsigned char *data = new unsigned char[stride * height];
1993 
1994  for (unsigned int i = 0; i < height; i++)
1995  rowPtrs[i] = (png_bytep)data + (i * stride);
1996 
1997  png_read_image(png_ptr, rowPtrs);
1998 
1999  vpImage<unsigned char> Ig(height, width);
2000  unsigned char *output;
2001 
2002  switch (channels) {
2003  case 1:
2004  output = (unsigned char *)Ig.bitmap;
2005  for (unsigned int i = 0; i < width * height; i++) {
2006  *(output++) = data[i];
2007  }
2008  vpImageConvert::convert(Ig, I);
2009  break;
2010 
2011  case 2:
2012  output = (unsigned char *)Ig.bitmap;
2013  for (unsigned int i = 0; i < width * height; i++) {
2014  *(output++) = data[i * 2];
2015  }
2016  vpImageConvert::convert(Ig, I);
2017  break;
2018 
2019  case 3:
2020  output = (unsigned char *)I.bitmap;
2021  for (unsigned int i = 0; i < width * height; i++) {
2022  *(output++) = data[i * 3];
2023  *(output++) = data[i * 3 + 1];
2024  *(output++) = data[i * 3 + 2];
2025  *(output++) = vpRGBa::alpha_default;
2026  }
2027  break;
2028 
2029  case 4:
2030  output = (unsigned char *)I.bitmap;
2031  for (unsigned int i = 0; i < width * height; i++) {
2032  *(output++) = data[i * 4];
2033  *(output++) = data[i * 4 + 1];
2034  *(output++) = data[i * 4 + 2];
2035  *(output++) = data[i * 4 + 3];
2036  }
2037  break;
2038  }
2039 
2040  delete[](png_bytep) rowPtrs;
2041  delete[] data;
2042  png_read_end(png_ptr, NULL);
2043  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
2044  fclose(file);
2045 }
2046 
2047 #elif defined(VISP_HAVE_OPENCV)
2048 
2056 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2057 {
2058 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2059  cv::Mat Ip;
2060  vpImageConvert::convert(I, Ip);
2061  cv::imwrite(filename.c_str(), Ip);
2062 #else
2063  IplImage *Ip = NULL;
2064  vpImageConvert::convert(I, Ip);
2065 
2066  cvSaveImage(filename.c_str(), Ip);
2067 
2068  cvReleaseImage(&Ip);
2069 #endif
2070 }
2071 
2079 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2080 {
2081 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2082  cv::Mat Ip;
2083  vpImageConvert::convert(I, Ip);
2084  cv::imwrite(filename.c_str(), Ip);
2085 #else
2086  IplImage *Ip = NULL;
2087  vpImageConvert::convert(I, Ip);
2088 
2089  cvSaveImage(filename.c_str(), Ip);
2090 
2091  cvReleaseImage(&Ip);
2092 #endif
2093 }
2094 
2111 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2112 {
2113 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
2114  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
2115  if (!Ip.empty())
2116  vpImageConvert::convert(Ip, I);
2117  else
2118  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2119 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2120  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2121  if (!Ip.empty())
2122  vpImageConvert::convert(Ip, I);
2123  else
2124  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2125 #else
2126  IplImage *Ip = NULL;
2127  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2128  if (Ip != NULL)
2129  vpImageConvert::convert(Ip, I);
2130  else
2131  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2132  cvReleaseImage(&Ip);
2133 #endif
2134 }
2135 
2154 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2155 {
2156 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
2157  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
2158  if (!Ip.empty())
2159  vpImageConvert::convert(Ip, I);
2160  else
2161  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2162 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2163  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2164  if (!Ip.empty())
2165  vpImageConvert::convert(Ip, I);
2166  else
2167  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2168 #else
2169  IplImage *Ip = NULL;
2170  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
2171  if (Ip != NULL)
2172  vpImageConvert::convert(Ip, I);
2173  else
2174  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2175  cvReleaseImage(&Ip);
2176 #endif
2177 }
2178 #else
2179 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
2180 {
2181  int width = 0, height = 0, channels = 0;
2182  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_grey);
2183  if (image == NULL) {
2184  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2185  }
2186  I.init(image, static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2187  stbi_image_free(image);
2188 }
2189 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2190 {
2191  int width = 0, height = 0, channels = 0;
2192  unsigned char *image = stbi_load(filename.c_str(), &width, &height, &channels, STBI_rgb_alpha);
2193  if (image == NULL) {
2194  throw(vpImageException(vpImageException::ioError, "Can't read the image: %s", filename.c_str()));
2195  }
2196  I.init(reinterpret_cast<vpRGBa*>(image), static_cast<unsigned int>(height), static_cast<unsigned int>(width), true);
2197  stbi_image_free(image);
2198 }
2199 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
2200 {
2201  const int stride_in_bytes = static_cast<int>(I.getWidth());
2202  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_grey,
2203  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2204  if (res == 0) {
2205  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2206  }
2207 }
2208 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
2209 {
2210  const int stride_in_bytes = static_cast<int>(4 * I.getWidth());
2211  int res = stbi_write_png(filename.c_str(), static_cast<int>(I.getWidth()), static_cast<int>(I.getHeight()), STBI_rgb_alpha,
2212  reinterpret_cast<void*>(I.bitmap), stride_in_bytes);
2213  if (res == 0) {
2214  throw(vpImageException(vpImageException::ioError, "PNG write error: %s", filename.c_str()));
2215  }
2216 }
2217 #endif
static void writeJPEG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1046
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 init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:665
#define vpCERROR
Definition: vpDebug.h:365
unsigned char B
Blue component.
Definition: vpRGBa.h:150
Type * bitmap
points toward the bitmap
Definition: vpImage.h:141
#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:950
static void writePPM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:978
Definition: vpRGBa.h:66
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:436
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:899
static void writePFM(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:593
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:879
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1786
static void readPFM(vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:759
unsigned int getHeight() const
Definition: vpImage.h:186
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:234
unsigned int getSize() const
Definition: vpImage.h:225
static void readPNG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1711
unsigned char R
Red component.
Definition: vpRGBa.h:148
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:749
static void readPGM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:813
unsigned int getWidth() const
Definition: vpImage.h:244
static void writePGM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:639
static void readJPEG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1174
static void writePNG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1502