Visual Servoing Platform  version 3.2.1 under development (2019-05-26)
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 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
50  unsigned int &h, unsigned int &maxval);
51 
52 #ifndef DOXYGEN_SHOULD_SKIP_THIS
53 
62 void vp_decodeHeaderPNM(const std::string &filename, std::ifstream &fd, const std::string &magic, unsigned int &w,
63  unsigned int &h, unsigned int &maxval)
64 {
65  std::string line;
66  unsigned int nb_elt = 4, cpt_elt = 0;
67  while (cpt_elt != nb_elt) {
68  // Skip empty lines or lines starting with # (comment)
69  while (std::getline(fd, line) && (line.compare(0, 1, "#") == 0 || line.size() == 0)) {
70  };
71 
72  if (fd.eof()) {
73  fd.close();
74  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
75  }
76 
77  std::vector<std::string> header = vpIoTools::splitChain(line, std::string(" "));
78 
79  if (header.size() == 0) {
80  fd.close();
81  throw(vpImageException(vpImageException::ioError, "Cannot read header of file \"%s\"", filename.c_str()));
82  }
83 
84  if (cpt_elt == 0) { // decode magic
85  if (header[0].compare(0, magic.size(), magic) != 0) {
86  fd.close();
87  throw(vpImageException(vpImageException::ioError, "\"%s\" is not a PNM file with magic number %s",
88  filename.c_str(), magic.c_str()));
89  }
90  cpt_elt++;
91  header.erase(header.begin(),
92  header.begin() + 1); // erase first element that is processed
93  }
94  while (header.size()) {
95  if (cpt_elt == 1) { // decode width
96  std::istringstream ss(header[0]);
97  ss >> w;
98  cpt_elt++;
99  header.erase(header.begin(),
100  header.begin() + 1); // erase first element that is processed
101  } else if (cpt_elt == 2) { // decode height
102  std::istringstream ss(header[0]);
103  ss >> h;
104  cpt_elt++;
105  header.erase(header.begin(),
106  header.begin() + 1); // erase first element that is processed
107  } else if (cpt_elt == 3) { // decode maxval
108  std::istringstream ss(header[0]);
109  ss >> maxval;
110  cpt_elt++;
111  header.erase(header.begin(),
112  header.begin() + 1); // erase first element that is processed
113  }
114  }
115  }
116 }
117 #endif
118 
119 vpImageIo::vpImageFormatType vpImageIo::getFormat(const std::string &filename)
120 {
121  std::string ext = vpImageIo::getExtension(filename);
122 
123  if (ext.compare(".PGM") == 0)
124  return FORMAT_PGM;
125  else if (ext.compare(".pgm") == 0)
126  return FORMAT_PGM;
127  else if (ext.compare(".PPM") == 0)
128  return FORMAT_PPM;
129  else if (ext.compare(".ppm") == 0)
130  return FORMAT_PPM;
131  else if (ext.compare(".JPG") == 0)
132  return FORMAT_JPEG;
133  else if (ext.compare(".jpg") == 0)
134  return FORMAT_JPEG;
135  else if (ext.compare(".JPEG") == 0)
136  return FORMAT_JPEG;
137  else if (ext.compare(".jpeg") == 0)
138  return FORMAT_JPEG;
139  else if (ext.compare(".PNG") == 0)
140  return FORMAT_PNG;
141  else if (ext.compare(".png") == 0)
142  return FORMAT_PNG;
143  // Formats supported by opencv
144  else if (ext.compare(".TIFF") == 0)
145  return FORMAT_TIFF;
146  else if (ext.compare(".tiff") == 0)
147  return FORMAT_TIFF;
148  else if (ext.compare(".TIF") == 0)
149  return FORMAT_TIFF;
150  else if (ext.compare(".tif") == 0)
151  return FORMAT_TIFF;
152  else if (ext.compare(".BMP") == 0)
153  return FORMAT_BMP;
154  else if (ext.compare(".bmp") == 0)
155  return FORMAT_BMP;
156  else if (ext.compare(".DIB") == 0)
157  return FORMAT_DIB;
158  else if (ext.compare(".dib") == 0)
159  return FORMAT_DIB;
160  else if (ext.compare(".PBM") == 0)
161  return FORMAT_PBM;
162  else if (ext.compare(".pbm") == 0)
163  return FORMAT_PBM;
164  else if (ext.compare(".SR") == 0)
165  return FORMAT_RASTER;
166  else if (ext.compare(".sr") == 0)
167  return FORMAT_RASTER;
168  else if (ext.compare(".RAS") == 0)
169  return FORMAT_RASTER;
170  else if (ext.compare(".ras") == 0)
171  return FORMAT_RASTER;
172  else if (ext.compare(".JP2") == 0)
173  return FORMAT_JPEG2000;
174  else if (ext.compare(".jp2") == 0)
175  return FORMAT_JPEG2000;
176  else
177  return FORMAT_UNKNOWN;
178 }
179 
180 // return the extension of the file including the dot
181 std::string vpImageIo::getExtension(const std::string &filename)
182 {
183  // extract the extension
184  size_t dot = filename.find_last_of(".");
185  std::string ext = filename.substr(dot, filename.size() - 1);
186  return ext;
187 }
188 
207 void vpImageIo::read(vpImage<unsigned char> &I, const std::string &filename)
208 {
209  bool exist = vpIoTools::checkFilename(filename);
210  if (!exist) {
211  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
213  }
214 
215  // Allows to use ~ symbol or env variables in path
216  std::string final_filename = vpIoTools::path(filename);
217 
218  bool try_opencv_reader = false;
219 
220  switch (getFormat(final_filename)) {
221  case FORMAT_PGM:
222  readPGM(I, final_filename);
223  break;
224  case FORMAT_PPM:
225  readPPM(I, final_filename);
226  break;
227  case FORMAT_JPEG:
228 #ifdef VISP_HAVE_JPEG
229  readJPEG(I, final_filename);
230 #else
231  try_opencv_reader = true;
232 #endif
233  break;
234  case FORMAT_PNG:
235 #if defined(VISP_HAVE_PNG)
236  readPNG(I, final_filename);
237 #else
238  try_opencv_reader = true;
239 #endif
240  break;
241  case FORMAT_TIFF:
242  case FORMAT_BMP:
243  case FORMAT_DIB:
244  case FORMAT_PBM:
245  case FORMAT_RASTER:
246  case FORMAT_JPEG2000:
247  case FORMAT_UNKNOWN:
248  try_opencv_reader = true;
249  break;
250  }
251 
252  if (try_opencv_reader) {
253 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
254  // std::cout << "Use opencv to read the image" << std::endl;
255  cv::Mat cvI = cv::imread(final_filename, cv::IMREAD_GRAYSCALE);
256  if (cvI.cols == 0 && cvI.rows == 0) {
257  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
259  }
260  vpImageConvert::convert(cvI, I);
261 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
262  // std::cout << "Use opencv to read the image" << std::endl;
263  cv::Mat cvI = cv::imread(final_filename, CV_LOAD_IMAGE_GRAYSCALE);
264  if (cvI.cols == 0 && cvI.rows == 0) {
265  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
267  }
268  vpImageConvert::convert(cvI, I);
269 #else
270  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
272 #endif
273  }
274 }
275 
294 void vpImageIo::read(vpImage<vpRGBa> &I, const std::string &filename)
295 {
296  bool exist = vpIoTools::checkFilename(filename);
297  if (!exist) {
298  std::string message = "Cannot read file: \"" + std::string(filename) + "\" doesn't exist";
300  }
301  // Allows to use ~ symbol or env variables in path
302  std::string final_filename = vpIoTools::path(filename);
303 
304  bool try_opencv_reader = false;
305 
306  switch (getFormat(final_filename)) {
307  case FORMAT_PGM:
308  readPGM(I, final_filename);
309  break;
310  case FORMAT_PPM:
311  readPPM(I, final_filename);
312  break;
313  case FORMAT_JPEG:
314 #ifdef VISP_HAVE_JPEG
315  readJPEG(I, final_filename);
316 #else
317  try_opencv_reader = true;
318 #endif
319  break;
320  case FORMAT_PNG:
321 #if defined(VISP_HAVE_PNG)
322  readPNG(I, final_filename);
323 #else
324  try_opencv_reader = true;
325 #endif
326  break;
327  case FORMAT_TIFF:
328  case FORMAT_BMP:
329  case FORMAT_DIB:
330  case FORMAT_PBM:
331  case FORMAT_RASTER:
332  case FORMAT_JPEG2000:
333  case FORMAT_UNKNOWN:
334  try_opencv_reader = true;
335  break;
336  }
337 
338  if (try_opencv_reader) {
339 #if VISP_HAVE_OPENCV_VERSION >= 0x030000
340  // std::cout << "Use opencv to read the image" << std::endl;
341  cv::Mat cvI = cv::imread(final_filename, cv::IMREAD_COLOR);
342  if (cvI.cols == 0 && cvI.rows == 0) {
343  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
345  }
346  vpImageConvert::convert(cvI, I);
347 #elif VISP_HAVE_OPENCV_VERSION >= 0x020100
348  // std::cout << "Use opencv to read the image" << std::endl;
349  cv::Mat cvI = cv::imread(final_filename, CV_LOAD_IMAGE_COLOR);
350  if (cvI.cols == 0 && cvI.rows == 0) {
351  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
353  }
354  vpImageConvert::convert(cvI, I);
355 #else
356  std::string message = "Cannot read file \"" + std::string(final_filename) + "\": Image format not supported";
358 #endif
359  }
360 }
361 
375 void vpImageIo::write(const vpImage<unsigned char> &I, const std::string &filename)
376 {
377  bool try_opencv_writer = false;
378 
379  switch (getFormat(filename)) {
380  case FORMAT_PGM:
381  writePGM(I, filename);
382  break;
383  case FORMAT_PPM:
384  writePPM(I, filename);
385  break;
386  case FORMAT_JPEG:
387 #ifdef VISP_HAVE_JPEG
388  writeJPEG(I, filename);
389 #else
390  try_opencv_writer = true;
391 #endif
392  break;
393  case FORMAT_PNG:
394 #ifdef VISP_HAVE_PNG
395  writePNG(I, filename);
396 #else
397  try_opencv_writer = true;
398 #endif
399  break;
400  case FORMAT_TIFF:
401  case FORMAT_BMP:
402  case FORMAT_DIB:
403  case FORMAT_PBM:
404  case FORMAT_RASTER:
405  case FORMAT_JPEG2000:
406  case FORMAT_UNKNOWN:
407  try_opencv_writer = true;
408  break;
409  }
410 
411  if (try_opencv_writer) {
412 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
413  // std::cout << "Use opencv to write the image" << std::endl;
414  cv::Mat cvI;
415  vpImageConvert::convert(I, cvI);
416  cv::imwrite(filename, cvI);
417 #else
418  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
419  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
420 #endif
421  }
422 }
423 
437 void vpImageIo::write(const vpImage<vpRGBa> &I, const std::string &filename)
438 {
439  bool try_opencv_writer = false;
440 
441  switch (getFormat(filename)) {
442  case FORMAT_PGM:
443  writePGM(I, filename);
444  break;
445  case FORMAT_PPM:
446  writePPM(I, filename);
447  break;
448  case FORMAT_JPEG:
449 #ifdef VISP_HAVE_JPEG
450  writeJPEG(I, filename);
451 #else
452  try_opencv_writer = true;
453 #endif
454  break;
455  case FORMAT_PNG:
456 #ifdef VISP_HAVE_PNG
457  writePNG(I, filename);
458 #else
459  try_opencv_writer = true;
460 #endif
461  break;
462  case FORMAT_TIFF:
463  case FORMAT_BMP:
464  case FORMAT_DIB:
465  case FORMAT_PBM:
466  case FORMAT_RASTER:
467  case FORMAT_JPEG2000:
468  case FORMAT_UNKNOWN:
469  try_opencv_writer = true;
470  break;
471  }
472 
473  if (try_opencv_writer) {
474 #if VISP_HAVE_OPENCV_VERSION >= 0x020100
475  // std::cout << "Use opencv to write the image" << std::endl;
476  cv::Mat cvI;
477  vpImageConvert::convert(I, cvI);
478  cv::imwrite(filename, cvI);
479 #else
480  vpCERROR << "Cannot write file: Image format not supported..." << std::endl;
481  throw(vpImageException(vpImageException::ioError, "Cannot write file: Image format not supported"));
482 #endif
483  }
484 }
485 
486 //--------------------------------------------------------------------------
487 // PFM
488 //--------------------------------------------------------------------------
489 
499 void vpImageIo::writePFM(const vpImage<float> &I, const std::string &filename)
500 {
501  FILE *fd;
502 
503  // Test the filename
504  if (filename.empty()) {
505  throw(vpImageException(vpImageException::ioError, "Cannot write PFM image: filename empty"));
506  }
507 
508  fd = fopen(filename.c_str(), "wb");
509 
510  if (fd == NULL) {
511  throw(vpImageException(vpImageException::ioError, "Cannot create PFM file \"%s\"", filename.c_str()));
512  }
513 
514  // Write the head
515  fprintf(fd, "P8\n"); // Magic number
516  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
517  fprintf(fd, "255\n"); // Max level
518 
519  // Write the bitmap
520  size_t ierr;
521  size_t nbyte = I.getWidth() * I.getHeight();
522 
523  ierr = fwrite(I.bitmap, sizeof(float), nbyte, fd);
524  if (ierr != nbyte) {
525  fclose(fd);
526  throw(vpImageException(vpImageException::ioError, "Cannot save PFM file \"%s\": only %d bytes over %d saved ",
527  filename.c_str(), ierr, nbyte));
528  }
529 
530  fflush(fd);
531  fclose(fd);
532 }
533 //--------------------------------------------------------------------------
534 // PGM
535 //--------------------------------------------------------------------------
536 
545 void vpImageIo::writePGM(const vpImage<unsigned char> &I, const std::string &filename)
546 {
547 
548  FILE *fd;
549 
550  // Test the filename
551  if (filename.empty()) {
552  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
553  }
554 
555  fd = fopen(filename.c_str(), "wb");
556 
557  if (fd == NULL) {
558  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
559  }
560 
561  // Write the head
562  fprintf(fd, "P5\n"); // Magic number
563  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
564  fprintf(fd, "255\n"); // Max level
565 
566  // Write the bitmap
567  size_t ierr;
568  size_t nbyte = I.getWidth() * I.getHeight();
569 
570  ierr = fwrite(I.bitmap, sizeof(unsigned char), nbyte, fd);
571  if (ierr != nbyte) {
572  fclose(fd);
573  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
574  filename.c_str(), ierr, nbyte));
575  }
576 
577  fflush(fd);
578  fclose(fd);
579 }
580 
588 void vpImageIo::writePGM(const vpImage<short> &I, const std::string &filename)
589 {
591  unsigned int nrows = I.getHeight();
592  unsigned int ncols = I.getWidth();
593 
594  Iuc.resize(nrows, ncols);
595 
596  for (unsigned int i = 0; i < nrows * ncols; i++)
597  Iuc.bitmap[i] = (unsigned char)I.bitmap[i];
598 
599  vpImageIo::writePGM(Iuc, filename);
600 }
610 void vpImageIo::writePGM(const vpImage<vpRGBa> &I, const std::string &filename)
611 {
612 
613  FILE *fd;
614 
615  // Test the filename
616  if (filename.empty()) {
617  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file: filename empty"));
618  }
619 
620  fd = fopen(filename.c_str(), "wb");
621 
622  if (fd == NULL) {
623  throw(vpImageException(vpImageException::ioError, "Cannot create PGM file \"%s\"", filename.c_str()));
624  }
625 
626  // Write the head
627  fprintf(fd, "P5\n"); // Magic number
628  fprintf(fd, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
629  fprintf(fd, "255\n"); // Max level
630 
631  // Write the bitmap
632  size_t ierr;
633  size_t nbyte = I.getWidth() * I.getHeight();
634 
636  vpImageConvert::convert(I, Itmp);
637 
638  ierr = fwrite(Itmp.bitmap, sizeof(unsigned char), nbyte, fd);
639  if (ierr != nbyte) {
640  fclose(fd);
641  throw(vpImageException(vpImageException::ioError, "Cannot save PGM file \"%s\": only %d over %d bytes saved",
642  filename.c_str(), ierr, nbyte));
643  }
644 
645  fflush(fd);
646  fclose(fd);
647 }
648 
665 void vpImageIo::readPFM(vpImage<float> &I, const std::string &filename)
666 {
667  unsigned int w = 0, h = 0, maxval = 0;
668  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
669  std::string magic("P8");
670 
671  std::ifstream fd(filename.c_str(), std::ios::binary);
672 
673  // Open the filename
674  if (!fd.is_open()) {
675  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
676  }
677 
678  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
679 
680  if (w > w_max || h > h_max) {
681  fd.close();
682  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
683  }
684  if (maxval > maxval_max) {
685  fd.close();
686  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
687  }
688 
689  if ((h != I.getHeight()) || (w != I.getWidth())) {
690  I.resize(h, w);
691  }
692 
693  unsigned int nbyte = I.getHeight() * I.getWidth();
694  fd.read((char *)I.bitmap, sizeof(float) * nbyte);
695  if (!fd) {
696  fd.close();
697  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
698  filename.c_str()));
699  }
700 
701  fd.close();
702 }
703 
719 void vpImageIo::readPGM(vpImage<unsigned char> &I, const std::string &filename)
720 {
721  unsigned int w = 0, h = 0, maxval = 0;
722  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
723  std::string magic("P5");
724 
725  std::ifstream fd(filename.c_str(), std::ios::binary);
726 
727  // Open the filename
728  if (!fd.is_open()) {
729  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
730  }
731 
732  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
733 
734  if (w > w_max || h > h_max) {
735  fd.close();
736  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
737  }
738  if (maxval > maxval_max) {
739  fd.close();
740  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
741  }
742 
743  if ((h != I.getHeight()) || (w != I.getWidth())) {
744  I.resize(h, w);
745  }
746 
747  unsigned int nbyte = I.getHeight() * I.getWidth();
748  fd.read((char *)I.bitmap, nbyte);
749  if (!fd) {
750  fd.close();
751  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"", fd.gcount(), nbyte,
752  filename.c_str()));
753  }
754 
755  fd.close();
756 }
757 
776 void vpImageIo::readPGM(vpImage<vpRGBa> &I, const std::string &filename)
777 {
779 
780  vpImageIo::readPGM(Itmp, filename);
781 
782  vpImageConvert::convert(Itmp, I);
783 }
784 
785 //--------------------------------------------------------------------------
786 // PPM
787 //--------------------------------------------------------------------------
788 
805 void vpImageIo::readPPM(vpImage<unsigned char> &I, const std::string &filename)
806 {
807  vpImage<vpRGBa> Itmp;
808 
809  vpImageIo::readPPM(Itmp, filename);
810 
811  vpImageConvert::convert(Itmp, I);
812 }
813 
825 void vpImageIo::readPPM(vpImage<vpRGBa> &I, const std::string &filename)
826 {
827  unsigned int w = 0, h = 0, maxval = 0;
828  unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
829  std::string magic("P6");
830 
831  std::ifstream fd(filename.c_str(), std::ios::binary);
832 
833  // Open the filename
834  if (!fd.is_open()) {
835  throw(vpImageException(vpImageException::ioError, "Cannot open file \"%s\"", filename.c_str()));
836  }
837 
838  vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
839 
840  if (w > w_max || h > h_max) {
841  fd.close();
842  throw(vpException(vpException::badValue, "Bad image size in \"%s\"", filename.c_str()));
843  }
844  if (maxval > maxval_max) {
845  fd.close();
846  throw(vpImageException(vpImageException::ioError, "Bad maxval in \"%s\"", filename.c_str()));
847  }
848 
849  if ((h != I.getHeight()) || (w != I.getWidth())) {
850  I.resize(h, w);
851  }
852 
853  for (unsigned int i = 0; i < I.getHeight(); i++) {
854  for (unsigned int j = 0; j < I.getWidth(); j++) {
855  unsigned char rgb[3];
856  fd.read((char *)&rgb, 3);
857 
858  if (!fd) {
859  fd.close();
860  throw(vpImageException(vpImageException::ioError, "Read only %d of %d bytes in file \"%s\"",
861  (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
862  }
863 
864  I[i][j].R = rgb[0];
865  I[i][j].G = rgb[1];
866  I[i][j].B = rgb[2];
867  I[i][j].A = vpRGBa::alpha_default;
868  }
869  }
870 
871  fd.close();
872 }
873 
884 void vpImageIo::writePPM(const vpImage<unsigned char> &I, const std::string &filename)
885 {
886  vpImage<vpRGBa> Itmp;
887 
888  vpImageConvert::convert(I, Itmp);
889 
890  vpImageIo::writePPM(Itmp, filename);
891 }
892 
900 void vpImageIo::writePPM(const vpImage<vpRGBa> &I, const std::string &filename)
901 {
902  FILE *f;
903 
904  // Test the filename
905  if (filename.empty()) {
906  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file: filename empty"));
907  }
908 
909  f = fopen(filename.c_str(), "wb");
910 
911  if (f == NULL) {
912  throw(vpImageException(vpImageException::ioError, "Cannot create PPM file \"%s\"", filename.c_str()));
913  }
914 
915  fprintf(f, "P6\n"); // Magic number
916  fprintf(f, "%u %u\n", I.getWidth(), I.getHeight()); // Image size
917  fprintf(f, "%d\n", 255); // Max level
918 
919  for (unsigned int i = 0; i < I.getHeight(); i++) {
920  for (unsigned int j = 0; j < I.getWidth(); j++) {
921  vpRGBa v = I[i][j];
922  unsigned char rgb[3];
923  rgb[0] = v.R;
924  rgb[1] = v.G;
925  rgb[2] = v.B;
926 
927  size_t res = fwrite(&rgb, 1, 3, f);
928  if (res != 3) {
929  fclose(f);
930  throw(vpImageException(vpImageException::ioError, "cannot write file \"%s\"", filename.c_str()));
931  }
932  }
933  }
934 
935  fflush(f);
936  fclose(f);
937 }
938 
939 //--------------------------------------------------------------------------
940 // JPEG
941 //--------------------------------------------------------------------------
942 
943 #if defined(VISP_HAVE_JPEG)
944 
952 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
953 {
954  struct jpeg_compress_struct cinfo;
955  struct jpeg_error_mgr jerr;
956  FILE *file;
957 
958  cinfo.err = jpeg_std_error(&jerr);
959  jpeg_create_compress(&cinfo);
960 
961  // Test the filename
962  if (filename.empty()) {
963  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
964  }
965 
966  file = fopen(filename.c_str(), "wb");
967 
968  if (file == NULL) {
969  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
970  }
971 
972  unsigned int width = I.getWidth();
973  unsigned int height = I.getHeight();
974 
975  jpeg_stdio_dest(&cinfo, file);
976 
977  cinfo.image_width = width;
978  cinfo.image_height = height;
979  cinfo.input_components = 1;
980  cinfo.in_color_space = JCS_GRAYSCALE;
981  jpeg_set_defaults(&cinfo);
982 
983  jpeg_start_compress(&cinfo, TRUE);
984 
985  unsigned char *line;
986  line = new unsigned char[width];
987  unsigned char *input = (unsigned char *)I.bitmap;
988  while (cinfo.next_scanline < cinfo.image_height) {
989  for (unsigned int i = 0; i < width; i++) {
990  line[i] = *(input);
991  input++;
992  }
993  jpeg_write_scanlines(&cinfo, &line, 1);
994  }
995 
996  jpeg_finish_compress(&cinfo);
997  jpeg_destroy_compress(&cinfo);
998  delete[] line;
999  fclose(file);
1000 }
1001 
1009 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1010 {
1011  struct jpeg_compress_struct cinfo;
1012  struct jpeg_error_mgr jerr;
1013  FILE *file;
1014 
1015  cinfo.err = jpeg_std_error(&jerr);
1016  jpeg_create_compress(&cinfo);
1017 
1018  // Test the filename
1019  if (filename.empty()) {
1020  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file: filename empty"));
1021  }
1022 
1023  file = fopen(filename.c_str(), "wb");
1024 
1025  if (file == NULL) {
1026  throw(vpImageException(vpImageException::ioError, "Cannot create JPEG file \"%s\"", filename.c_str()));
1027  }
1028 
1029  unsigned int width = I.getWidth();
1030  unsigned int height = I.getHeight();
1031 
1032  jpeg_stdio_dest(&cinfo, file);
1033 
1034  cinfo.image_width = width;
1035  cinfo.image_height = height;
1036  cinfo.input_components = 3;
1037  cinfo.in_color_space = JCS_RGB;
1038  jpeg_set_defaults(&cinfo);
1039 
1040  jpeg_start_compress(&cinfo, TRUE);
1041 
1042  unsigned char *line;
1043  line = new unsigned char[3 * width];
1044  unsigned char *input = (unsigned char *)I.bitmap;
1045  while (cinfo.next_scanline < cinfo.image_height) {
1046  for (unsigned int i = 0; i < width; i++) {
1047  line[i * 3] = *(input);
1048  input++;
1049  line[i * 3 + 1] = *(input);
1050  input++;
1051  line[i * 3 + 2] = *(input);
1052  input++;
1053  input++;
1054  }
1055  jpeg_write_scanlines(&cinfo, &line, 1);
1056  }
1057 
1058  jpeg_finish_compress(&cinfo);
1059  jpeg_destroy_compress(&cinfo);
1060  delete[] line;
1061  fclose(file);
1062 }
1063 
1080 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1081 {
1082  struct jpeg_decompress_struct cinfo;
1083  struct jpeg_error_mgr jerr;
1084  FILE *file;
1085 
1086  cinfo.err = jpeg_std_error(&jerr);
1087  jpeg_create_decompress(&cinfo);
1088 
1089  // Test the filename
1090  if (filename.empty()) {
1091  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1092  }
1093 
1094  file = fopen(filename.c_str(), "rb");
1095 
1096  if (file == NULL) {
1097  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1098  }
1099 
1100  jpeg_stdio_src(&cinfo, file);
1101  jpeg_read_header(&cinfo, TRUE);
1102 
1103  unsigned int width = cinfo.image_width;
1104  unsigned int height = cinfo.image_height;
1105 
1106  if ((width != I.getWidth()) || (height != I.getHeight()))
1107  I.resize(height, width);
1108 
1109  jpeg_start_decompress(&cinfo);
1110 
1111  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1112  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1113 
1114  if (cinfo.out_color_space == JCS_RGB) {
1115  vpImage<vpRGBa> Ic(height, width);
1116  unsigned char *output = (unsigned char *)Ic.bitmap;
1117  while (cinfo.output_scanline < cinfo.output_height) {
1118  jpeg_read_scanlines(&cinfo, buffer, 1);
1119  for (unsigned int i = 0; i < width; i++) {
1120  *(output++) = buffer[0][i * 3];
1121  *(output++) = buffer[0][i * 3 + 1];
1122  *(output++) = buffer[0][i * 3 + 2];
1123  *(output++) = vpRGBa::alpha_default;
1124  }
1125  }
1126  vpImageConvert::convert(Ic, I);
1127  }
1128 
1129  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1130  while (cinfo.output_scanline < cinfo.output_height) {
1131  unsigned int row = cinfo.output_scanline;
1132  jpeg_read_scanlines(&cinfo, buffer, 1);
1133  memcpy(I[row], buffer[0], rowbytes);
1134  }
1135  }
1136 
1137  jpeg_finish_decompress(&cinfo);
1138  jpeg_destroy_decompress(&cinfo);
1139  fclose(file);
1140 }
1141 
1160 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1161 {
1162  struct jpeg_decompress_struct cinfo;
1163  struct jpeg_error_mgr jerr;
1164  FILE *file;
1165 
1166  cinfo.err = jpeg_std_error(&jerr);
1167  jpeg_create_decompress(&cinfo);
1168 
1169  // Test the filename
1170  if (filename.empty()) {
1171  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG image: filename empty"));
1172  }
1173 
1174  file = fopen(filename.c_str(), "rb");
1175 
1176  if (file == NULL) {
1177  throw(vpImageException(vpImageException::ioError, "Cannot read JPEG file \"%s\"", filename.c_str()));
1178  }
1179 
1180  jpeg_stdio_src(&cinfo, file);
1181 
1182  jpeg_read_header(&cinfo, TRUE);
1183 
1184  unsigned int width = cinfo.image_width;
1185  unsigned int height = cinfo.image_height;
1186 
1187  if ((width != I.getWidth()) || (height != I.getHeight()))
1188  I.resize(height, width);
1189 
1190  jpeg_start_decompress(&cinfo);
1191 
1192  unsigned int rowbytes = cinfo.output_width * (unsigned int)(cinfo.output_components);
1193  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, rowbytes, 1);
1194 
1195  if (cinfo.out_color_space == JCS_RGB) {
1196  unsigned char *output = (unsigned char *)I.bitmap;
1197  while (cinfo.output_scanline < cinfo.output_height) {
1198  jpeg_read_scanlines(&cinfo, buffer, 1);
1199  for (unsigned int i = 0; i < width; i++) {
1200  *(output++) = buffer[0][i * 3];
1201  *(output++) = buffer[0][i * 3 + 1];
1202  *(output++) = buffer[0][i * 3 + 2];
1203  *(output++) = vpRGBa::alpha_default;
1204  }
1205  }
1206  }
1207 
1208  else if (cinfo.out_color_space == JCS_GRAYSCALE) {
1209  vpImage<unsigned char> Ig(height, width);
1210 
1211  while (cinfo.output_scanline < cinfo.output_height) {
1212  unsigned int row = cinfo.output_scanline;
1213  jpeg_read_scanlines(&cinfo, buffer, 1);
1214  memcpy(Ig[row], buffer[0], rowbytes);
1215  }
1216 
1217  vpImageConvert::convert(Ig, I);
1218  }
1219 
1220  jpeg_finish_decompress(&cinfo);
1221  jpeg_destroy_decompress(&cinfo);
1222  fclose(file);
1223 }
1224 
1225 #elif defined(VISP_HAVE_OPENCV)
1226 
1234 void vpImageIo::writeJPEG(const vpImage<unsigned char> &I, const std::string &filename)
1235 {
1236 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1237  cv::Mat Ip;
1238  vpImageConvert::convert(I, Ip);
1239  cv::imwrite(filename.c_str(), Ip);
1240 #else
1241  IplImage *Ip = NULL;
1242  vpImageConvert::convert(I, Ip);
1243 
1244  cvSaveImage(filename.c_str(), Ip);
1245 
1246  cvReleaseImage(&Ip);
1247 #endif
1248 }
1249 
1257 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &I, const std::string &filename)
1258 {
1259 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1260  cv::Mat Ip;
1261  vpImageConvert::convert(I, Ip);
1262  cv::imwrite(filename.c_str(), Ip);
1263 #else
1264  IplImage *Ip = NULL;
1265  vpImageConvert::convert(I, Ip);
1266 
1267  cvSaveImage(filename.c_str(), Ip);
1268 
1269  cvReleaseImage(&Ip);
1270 #endif
1271 }
1272 
1289 void vpImageIo::readJPEG(vpImage<unsigned char> &I, const std::string &filename)
1290 {
1291 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1292  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
1293  if (!Ip.empty())
1294  vpImageConvert::convert(Ip, I);
1295  else
1296  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1297 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1298  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1299  if (!Ip.empty())
1300  vpImageConvert::convert(Ip, I);
1301  else
1302  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1303 #else
1304  IplImage *Ip = NULL;
1305  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1306  if (Ip != NULL)
1307  vpImageConvert::convert(Ip, I);
1308  else
1309  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1310  cvReleaseImage(&Ip);
1311 #endif
1312 }
1313 
1332 void vpImageIo::readJPEG(vpImage<vpRGBa> &I, const std::string &filename)
1333 {
1334 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1335  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
1336  if (!Ip.empty())
1337  vpImageConvert::convert(Ip, I);
1338  else
1339  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1340 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1341  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1342  if (!Ip.empty())
1343  vpImageConvert::convert(Ip, I);
1344  else
1345  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1346 #else
1347  IplImage *Ip = NULL;
1348  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
1349  if (Ip != NULL)
1350  vpImageConvert::convert(Ip, I);
1351  else
1352  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1353  cvReleaseImage(&Ip);
1354 #endif
1355 }
1356 #else
1357 // jpeg interface not available (nor with libjpeg, nor with OpenCV
1358 void vpImageIo::readJPEG(vpImage<unsigned char> &, const std::string &)
1359 {
1360  throw(vpException(vpException::fatalError, "Cannot read jpeg image since ViSP in not built with OpenCV or libjpeg 3rd parties"));
1361 }
1362 void vpImageIo::readJPEG(vpImage<vpRGBa> &, const std::string &)
1363 {
1364  throw(vpException(vpException::fatalError, "Cannot read jpeg image since ViSP in not built with OpenCV or libjpeg 3rd parties"));
1365 }
1366 void vpImageIo::writeJPEG(const vpImage<unsigned char> &, const std::string &)
1367 {
1368  throw(vpException(vpException::fatalError, "Cannot read jpeg image since ViSP in not built with OpenCV or libjpeg 3rd parties"));
1369 }
1370 void vpImageIo::writeJPEG(const vpImage<vpRGBa> &, const std::string &)
1371 {
1372  throw(vpException(vpException::fatalError, "Cannot read jpeg image since ViSP in not built with OpenCV or libjpeg 3rd parties"));
1373 }
1374 #endif
1375 
1376 //--------------------------------------------------------------------------
1377 // PNG
1378 //--------------------------------------------------------------------------
1379 
1380 #if defined(VISP_HAVE_PNG)
1381 
1389 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1390 {
1391  FILE *file;
1392 
1393  // Test the filename
1394  if (filename.empty()) {
1395  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1396  }
1397 
1398  file = fopen(filename.c_str(), "wb");
1399 
1400  if (file == NULL) {
1401  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1402  }
1403 
1404  /* create a png info struct */
1405  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1406  if (!png_ptr) {
1407  fclose(file);
1408  vpERROR_TRACE("Error during png_create_write_struct()\n");
1409  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1410  }
1411 
1412  png_infop info_ptr = png_create_info_struct(png_ptr);
1413  if (!info_ptr) {
1414  fclose(file);
1415  png_destroy_write_struct(&png_ptr, NULL);
1416  vpERROR_TRACE("Error during png_create_info_struct()\n");
1417  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1418  }
1419 
1420  /* initialize the setjmp for returning properly after a libpng error occured
1421  */
1422  if (setjmp(png_jmpbuf(png_ptr))) {
1423  fclose(file);
1424  png_destroy_write_struct(&png_ptr, &info_ptr);
1425  vpERROR_TRACE("Error during init_io\n");
1426  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1427  }
1428 
1429  /* setup libpng for using standard C fwrite() function with our FILE pointer
1430  */
1431  png_init_io(png_ptr, file);
1432 
1433  unsigned int width = I.getWidth();
1434  unsigned int height = I.getHeight();
1435  int bit_depth = 8;
1436  int color_type = PNG_COLOR_TYPE_GRAY;
1437  /* set some useful information from header */
1438 
1439  if (setjmp(png_jmpbuf(png_ptr))) {
1440  fclose(file);
1441  png_destroy_write_struct(&png_ptr, &info_ptr);
1442  vpERROR_TRACE("Error during write header\n");
1443  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1444  }
1445 
1446  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1447  PNG_FILTER_TYPE_BASE);
1448 
1449  png_write_info(png_ptr, info_ptr);
1450 
1451  png_bytep *row_ptrs = new png_bytep[height];
1452  for (unsigned int i = 0; i < height; i++)
1453  row_ptrs[i] = new png_byte[width];
1454 
1455  unsigned char *input = (unsigned char *)I.bitmap;
1456 
1457  for (unsigned int i = 0; i < height; i++) {
1458  png_byte *row = row_ptrs[i];
1459  for (unsigned int j = 0; j < width; j++) {
1460  row[j] = *(input);
1461  input++;
1462  }
1463  }
1464 
1465  png_write_image(png_ptr, row_ptrs);
1466 
1467  png_write_end(png_ptr, NULL);
1468 
1469  for (unsigned int j = 0; j < height; j++)
1470  delete[] row_ptrs[j];
1471 
1472  delete[] row_ptrs;
1473 
1474  png_destroy_write_struct(&png_ptr, &info_ptr);
1475 
1476  fclose(file);
1477 }
1478 
1486 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1487 {
1488  FILE *file;
1489 
1490  // Test the filename
1491  if (filename.empty()) {
1492  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1493  }
1494 
1495  file = fopen(filename.c_str(), "wb");
1496 
1497  if (file == NULL) {
1498  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1499  }
1500 
1501  /* create a png info struct */
1502  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1503  if (!png_ptr) {
1504  fclose(file);
1505  vpERROR_TRACE("Error during png_create_write_struct()\n");
1506  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1507  }
1508 
1509  png_infop info_ptr = png_create_info_struct(png_ptr);
1510  if (!info_ptr) {
1511  fclose(file);
1512  png_destroy_write_struct(&png_ptr, NULL);
1513  vpERROR_TRACE("Error during png_create_info_struct()\n");
1514  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1515  }
1516 
1517  /* initialize the setjmp for returning properly after a libpng error occured
1518  */
1519  if (setjmp(png_jmpbuf(png_ptr))) {
1520  fclose(file);
1521  png_destroy_write_struct(&png_ptr, &info_ptr);
1522  vpERROR_TRACE("Error during init_io\n");
1523  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1524  }
1525 
1526  /* setup libpng for using standard C fwrite() function with our FILE pointer
1527  */
1528  png_init_io(png_ptr, file);
1529 
1530  unsigned int width = I.getWidth();
1531  unsigned int height = I.getHeight();
1532  int bit_depth = 8;
1533  int color_type = PNG_COLOR_TYPE_RGB;
1534  /* set some useful information from header */
1535 
1536  if (setjmp(png_jmpbuf(png_ptr))) {
1537  fclose(file);
1538  png_destroy_write_struct(&png_ptr, &info_ptr);
1539  vpERROR_TRACE("Error during write header\n");
1540  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1541  }
1542 
1543  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1544  PNG_FILTER_TYPE_BASE);
1545 
1546  png_write_info(png_ptr, info_ptr);
1547 
1548  png_bytep *row_ptrs = new png_bytep[height];
1549  for (unsigned int i = 0; i < height; i++)
1550  row_ptrs[i] = new png_byte[3 * width];
1551 
1552  unsigned char *input = (unsigned char *)I.bitmap;
1553  ;
1554 
1555  for (unsigned int i = 0; i < height; i++) {
1556  png_byte *row = row_ptrs[i];
1557  for (unsigned int j = 0; j < width; j++) {
1558  row[3 * j] = *(input);
1559  input++;
1560  row[3 * j + 1] = *(input);
1561  input++;
1562  row[3 * j + 2] = *(input);
1563  input++;
1564  input++;
1565  }
1566  }
1567 
1568  png_write_image(png_ptr, row_ptrs);
1569 
1570  png_write_end(png_ptr, NULL);
1571 
1572  for (unsigned int j = 0; j < height; j++)
1573  delete[] row_ptrs[j];
1574 
1575  delete[] row_ptrs;
1576 
1577  png_destroy_write_struct(&png_ptr, &info_ptr);
1578 
1579  fclose(file);
1580 }
1581 
1598 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1599 {
1600  FILE *file;
1601  png_byte magic[8];
1602  // Test the filename
1603  if (filename.empty()) {
1604  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1605  }
1606 
1607  file = fopen(filename.c_str(), "rb");
1608 
1609  if (file == NULL) {
1610  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1611  }
1612 
1613  /* read magic number */
1614  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1615  fclose(file);
1616  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1617  }
1618 
1619  /* check for valid magic number */
1620  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1621  fclose(file);
1622  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1623  filename.c_str()));
1624  }
1625 
1626  /* create a png read struct */
1627  // printf("version %s\n", PNG_LIBPNG_VER_STRING);
1628  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1629  if (png_ptr == NULL) {
1630  fprintf(stderr, "error: can't create a png read structure!\n");
1631  fclose(file);
1632  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1633  }
1634 
1635  /* create a png info struct */
1636  png_infop info_ptr = png_create_info_struct(png_ptr);
1637  if (info_ptr == NULL) {
1638  fprintf(stderr, "error: can't create a png info structure!\n");
1639  fclose(file);
1640  png_destroy_read_struct(&png_ptr, NULL, NULL);
1641  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1642  }
1643 
1644  /* initialize the setjmp for returning properly after a libpng error occured
1645  */
1646  if (setjmp(png_jmpbuf(png_ptr))) {
1647  fclose(file);
1648  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1649  vpERROR_TRACE("Error during init io\n");
1650  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1651  }
1652 
1653  /* setup libpng for using standard C fread() function with our FILE pointer
1654  */
1655  png_init_io(png_ptr, file);
1656 
1657  /* tell libpng that we have already read the magic number */
1658  png_set_sig_bytes(png_ptr, sizeof(magic));
1659 
1660  /* read png info */
1661  png_read_info(png_ptr, info_ptr);
1662 
1663  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1664  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1665 
1666  unsigned int bit_depth, channels, color_type;
1667  /* get some useful information from header */
1668  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1669  channels = png_get_channels(png_ptr, info_ptr);
1670  color_type = png_get_color_type(png_ptr, info_ptr);
1671 
1672  /* convert index color images to RGB images */
1673  if (color_type == PNG_COLOR_TYPE_PALETTE)
1674  png_set_palette_to_rgb(png_ptr);
1675 
1676  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1677  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1678  png_set_expand(png_ptr);
1679 
1680  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1681  // png_set_tRNS_to_alpha (png_ptr);
1682 
1683  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1684  png_set_strip_alpha(png_ptr);
1685 
1686  if (bit_depth == 16)
1687  png_set_strip_16(png_ptr);
1688  else if (bit_depth < 8)
1689  png_set_packing(png_ptr);
1690 
1691  /* update info structure to apply transformations */
1692  png_read_update_info(png_ptr, info_ptr);
1693 
1694  channels = png_get_channels(png_ptr, info_ptr);
1695 
1696  if ((width != I.getWidth()) || (height != I.getHeight()))
1697  I.resize(height, width);
1698 
1699  png_bytep *rowPtrs = new png_bytep[height];
1700 
1701  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1702  unsigned char *data = new unsigned char[stride * height];
1703 
1704  for (unsigned int i = 0; i < height; i++)
1705  rowPtrs[i] = (png_bytep)data + (i * stride);
1706 
1707  png_read_image(png_ptr, rowPtrs);
1708 
1709  vpImage<vpRGBa> Ic(height, width);
1710  unsigned char *output;
1711 
1712  switch (channels) {
1713  case 1:
1714  output = (unsigned char *)I.bitmap;
1715  for (unsigned int i = 0; i < width * height; i++) {
1716  *(output++) = data[i];
1717  }
1718  break;
1719 
1720  case 2:
1721  output = (unsigned char *)I.bitmap;
1722  for (unsigned int i = 0; i < width * height; i++) {
1723  *(output++) = data[i * 2];
1724  }
1725  break;
1726 
1727  case 3:
1728  output = (unsigned char *)Ic.bitmap;
1729  for (unsigned int i = 0; i < width * height; i++) {
1730  *(output++) = data[i * 3];
1731  *(output++) = data[i * 3 + 1];
1732  *(output++) = data[i * 3 + 2];
1733  *(output++) = vpRGBa::alpha_default;
1734  }
1735  vpImageConvert::convert(Ic, I);
1736  break;
1737 
1738  case 4:
1739  output = (unsigned char *)Ic.bitmap;
1740  for (unsigned int i = 0; i < width * height; i++) {
1741  *(output++) = data[i * 4];
1742  *(output++) = data[i * 4 + 1];
1743  *(output++) = data[i * 4 + 2];
1744  *(output++) = data[i * 4 + 3];
1745  }
1746  vpImageConvert::convert(Ic, I);
1747  break;
1748  }
1749 
1750  delete[](png_bytep) rowPtrs;
1751  delete[] data;
1752  png_read_end(png_ptr, NULL);
1753  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1754  fclose(file);
1755 }
1756 
1775 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
1776 {
1777  FILE *file;
1778  png_byte magic[8];
1779 
1780  // Test the filename
1781  if (filename.empty()) {
1782  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1783  }
1784 
1785  file = fopen(filename.c_str(), "rb");
1786 
1787  if (file == NULL) {
1788  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1789  }
1790 
1791  /* read magic number */
1792  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1793  fclose(file);
1794  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1795  }
1796 
1797  /* check for valid magic number */
1798  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1799  fclose(file);
1800  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1801  filename.c_str()));
1802  }
1803 
1804  /* create a png read struct */
1805  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1806  if (!png_ptr) {
1807  fclose(file);
1808  vpERROR_TRACE("Error during png_create_read_struct()\n");
1809  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1810  }
1811 
1812  /* create a png info struct */
1813  png_infop info_ptr = png_create_info_struct(png_ptr);
1814  if (!info_ptr) {
1815  fclose(file);
1816  png_destroy_read_struct(&png_ptr, NULL, NULL);
1817  vpERROR_TRACE("Error during png_create_info_struct()\n");
1818  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1819  }
1820 
1821  /* initialize the setjmp for returning properly after a libpng error occured
1822  */
1823  if (setjmp(png_jmpbuf(png_ptr))) {
1824  fclose(file);
1825  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1826  vpERROR_TRACE("Error during init io\n");
1827  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1828  }
1829 
1830  /* setup libpng for using standard C fread() function with our FILE pointer
1831  */
1832  png_init_io(png_ptr, file);
1833 
1834  /* tell libpng that we have already read the magic number */
1835  png_set_sig_bytes(png_ptr, sizeof(magic));
1836 
1837  /* read png info */
1838  png_read_info(png_ptr, info_ptr);
1839 
1840  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1841  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1842 
1843  unsigned int bit_depth, channels, color_type;
1844  /* get some useful information from header */
1845  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1846  channels = png_get_channels(png_ptr, info_ptr);
1847  color_type = png_get_color_type(png_ptr, info_ptr);
1848 
1849  /* convert index color images to RGB images */
1850  if (color_type == PNG_COLOR_TYPE_PALETTE)
1851  png_set_palette_to_rgb(png_ptr);
1852 
1853  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1854  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1855  png_set_expand(png_ptr);
1856 
1857  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1858  // png_set_tRNS_to_alpha (png_ptr);
1859 
1860  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1861  png_set_strip_alpha(png_ptr);
1862 
1863  if (bit_depth == 16)
1864  png_set_strip_16(png_ptr);
1865  else if (bit_depth < 8)
1866  png_set_packing(png_ptr);
1867 
1868  /* update info structure to apply transformations */
1869  png_read_update_info(png_ptr, info_ptr);
1870 
1871  channels = png_get_channels(png_ptr, info_ptr);
1872 
1873  if ((width != I.getWidth()) || (height != I.getHeight()))
1874  I.resize(height, width);
1875 
1876  png_bytep *rowPtrs = new png_bytep[height];
1877 
1878  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1879  unsigned char *data = new unsigned char[stride * height];
1880 
1881  for (unsigned int i = 0; i < height; i++)
1882  rowPtrs[i] = (png_bytep)data + (i * stride);
1883 
1884  png_read_image(png_ptr, rowPtrs);
1885 
1886  vpImage<unsigned char> Ig(height, width);
1887  unsigned char *output;
1888 
1889  switch (channels) {
1890  case 1:
1891  output = (unsigned char *)Ig.bitmap;
1892  for (unsigned int i = 0; i < width * height; i++) {
1893  *(output++) = data[i];
1894  }
1895  vpImageConvert::convert(Ig, I);
1896  break;
1897 
1898  case 2:
1899  output = (unsigned char *)Ig.bitmap;
1900  for (unsigned int i = 0; i < width * height; i++) {
1901  *(output++) = data[i * 2];
1902  }
1903  vpImageConvert::convert(Ig, I);
1904  break;
1905 
1906  case 3:
1907  output = (unsigned char *)I.bitmap;
1908  for (unsigned int i = 0; i < width * height; i++) {
1909  *(output++) = data[i * 3];
1910  *(output++) = data[i * 3 + 1];
1911  *(output++) = data[i * 3 + 2];
1912  *(output++) = vpRGBa::alpha_default;
1913  }
1914  break;
1915 
1916  case 4:
1917  output = (unsigned char *)I.bitmap;
1918  for (unsigned int i = 0; i < width * height; i++) {
1919  *(output++) = data[i * 4];
1920  *(output++) = data[i * 4 + 1];
1921  *(output++) = data[i * 4 + 2];
1922  *(output++) = data[i * 4 + 3];
1923  }
1924  break;
1925  }
1926 
1927  delete[](png_bytep) rowPtrs;
1928  delete[] data;
1929  png_read_end(png_ptr, NULL);
1930  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1931  fclose(file);
1932 }
1933 
1934 #elif defined(VISP_HAVE_OPENCV)
1935 
1943 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1944 {
1945 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1946  cv::Mat Ip;
1947  vpImageConvert::convert(I, Ip);
1948  cv::imwrite(filename.c_str(), Ip);
1949 #else
1950  IplImage *Ip = NULL;
1951  vpImageConvert::convert(I, Ip);
1952 
1953  cvSaveImage(filename.c_str(), Ip);
1954 
1955  cvReleaseImage(&Ip);
1956 #endif
1957 }
1958 
1966 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1967 {
1968 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1969  cv::Mat Ip;
1970  vpImageConvert::convert(I, Ip);
1971  cv::imwrite(filename.c_str(), Ip);
1972 #else
1973  IplImage *Ip = NULL;
1974  vpImageConvert::convert(I, Ip);
1975 
1976  cvSaveImage(filename.c_str(), Ip);
1977 
1978  cvReleaseImage(&Ip);
1979 #endif
1980 }
1981 
1998 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1999 {
2000 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
2001  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
2002  if (!Ip.empty())
2003  vpImageConvert::convert(Ip, I);
2004  else
2005  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2006 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2007  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2008  if (!Ip.empty())
2009  vpImageConvert::convert(Ip, I);
2010  else
2011  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2012 #else
2013  IplImage *Ip = NULL;
2014  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2015  if (Ip != NULL)
2016  vpImageConvert::convert(Ip, I);
2017  else
2018  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2019  cvReleaseImage(&Ip);
2020 #endif
2021 }
2022 
2041 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2042 {
2043 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
2044  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
2045  if (!Ip.empty())
2046  vpImageConvert::convert(Ip, I);
2047  else
2048  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2049 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2050  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2051  if (!Ip.empty())
2052  vpImageConvert::convert(Ip, I);
2053  else
2054  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2055 #else
2056  IplImage *Ip = NULL;
2057  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
2058  if (Ip != NULL)
2059  vpImageConvert::convert(Ip, I);
2060  else
2061  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2062  cvReleaseImage(&Ip);
2063 #endif
2064 }
2065 #else
2066 // png interface not available (nor with libpng, nor with OpenCV)
2067 void vpImageIo::readPNG(vpImage<unsigned char> &, const std::string &)
2068 {
2069  throw(vpException(vpException::fatalError, "Cannot read png image since ViSP in not built with OpenCV or libpng 3rd parties"));
2070 }
2071 void vpImageIo::readPNG(vpImage<vpRGBa> &, const std::string &)
2072 {
2073  throw(vpException(vpException::fatalError, "Cannot read png image since ViSP in not built with OpenCV or libpng 3rd parties"));
2074 }
2075 void vpImageIo::writePNG(const vpImage<unsigned char> &, const std::string &)
2076 {
2077  throw(vpException(vpException::fatalError, "Cannot read png image since ViSP in not built with OpenCV or libpng 3rd parties"));
2078 }
2079 void vpImageIo::writePNG(const vpImage<vpRGBa> &, const std::string &)
2080 {
2081  throw(vpException(vpException::fatalError, "Cannot read png image since ViSP in not built with OpenCV or libpng 3rd parties"));
2082 }
2083 #endif
static void writeJPEG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:952
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
unsigned int getWidth() const
Definition: vpImage.h:237
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
#define vpCERROR
Definition: vpDebug.h:365
unsigned char B
Blue component.
Definition: vpRGBa.h:150
Type * bitmap
points toward the bitmap
Definition: vpImage.h:134
#define vpERROR_TRACE
Definition: vpDebug.h:393
error that can be emited by ViSP classes.
Definition: vpException.h:71
static std::string path(const char *pathname)
Definition: vpIoTools.cpp:958
Error that can be emited by the vpImage class and its derivates.
unsigned char G
Green component.
Definition: vpRGBa.h:149
static void writePPM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:884
Definition: vpRGBa.h:66
static void write(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:375
static bool checkFilename(const char *filename)
Definition: vpIoTools.cpp:692
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:805
unsigned int getSize() const
Definition: vpImage.h:218
static void writePFM(const vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:499
void resize(const unsigned int h, const unsigned int w)
resize the image : Image initialization
Definition: vpImage.h:863
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1806
static void readPFM(vpImage< float > &I, const std::string &filename)
Definition: vpImageIo.cpp:665
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:207
static void readPNG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1598
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned int getHeight() const
Definition: vpImage.h:179
static void readPGM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:719
static void writePGM(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:545
static void readJPEG(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1080
static void writePNG(const vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:1389