Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
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 
1357 #endif
1358 
1359 //--------------------------------------------------------------------------
1360 // PNG
1361 //--------------------------------------------------------------------------
1362 
1363 #if defined(VISP_HAVE_PNG)
1364 
1372 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1373 {
1374  FILE *file;
1375 
1376  // Test the filename
1377  if (filename.empty()) {
1378  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1379  }
1380 
1381  file = fopen(filename.c_str(), "wb");
1382 
1383  if (file == NULL) {
1384  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1385  }
1386 
1387  /* create a png info struct */
1388  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1389  if (!png_ptr) {
1390  fclose(file);
1391  vpERROR_TRACE("Error during png_create_write_struct()\n");
1392  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1393  }
1394 
1395  png_infop info_ptr = png_create_info_struct(png_ptr);
1396  if (!info_ptr) {
1397  fclose(file);
1398  png_destroy_write_struct(&png_ptr, NULL);
1399  vpERROR_TRACE("Error during png_create_info_struct()\n");
1400  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1401  }
1402 
1403  /* initialize the setjmp for returning properly after a libpng error occured
1404  */
1405  if (setjmp(png_jmpbuf(png_ptr))) {
1406  fclose(file);
1407  png_destroy_write_struct(&png_ptr, &info_ptr);
1408  vpERROR_TRACE("Error during init_io\n");
1409  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1410  }
1411 
1412  /* setup libpng for using standard C fwrite() function with our FILE pointer
1413  */
1414  png_init_io(png_ptr, file);
1415 
1416  unsigned int width = I.getWidth();
1417  unsigned int height = I.getHeight();
1418  int bit_depth = 8;
1419  int color_type = PNG_COLOR_TYPE_GRAY;
1420  /* set some useful information from header */
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 write header\n");
1426  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1427  }
1428 
1429  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1430  PNG_FILTER_TYPE_BASE);
1431 
1432  png_write_info(png_ptr, info_ptr);
1433 
1434  png_bytep *row_ptrs = new png_bytep[height];
1435  for (unsigned int i = 0; i < height; i++)
1436  row_ptrs[i] = new png_byte[width];
1437 
1438  unsigned char *input = (unsigned char *)I.bitmap;
1439 
1440  for (unsigned int i = 0; i < height; i++) {
1441  png_byte *row = row_ptrs[i];
1442  for (unsigned int j = 0; j < width; j++) {
1443  row[j] = *(input);
1444  input++;
1445  }
1446  }
1447 
1448  png_write_image(png_ptr, row_ptrs);
1449 
1450  png_write_end(png_ptr, NULL);
1451 
1452  for (unsigned int j = 0; j < height; j++)
1453  delete[] row_ptrs[j];
1454 
1455  delete[] row_ptrs;
1456 
1457  png_destroy_write_struct(&png_ptr, &info_ptr);
1458 
1459  fclose(file);
1460 }
1461 
1469 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1470 {
1471  FILE *file;
1472 
1473  // Test the filename
1474  if (filename.empty()) {
1475  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file: filename empty"));
1476  }
1477 
1478  file = fopen(filename.c_str(), "wb");
1479 
1480  if (file == NULL) {
1481  throw(vpImageException(vpImageException::ioError, "Cannot create PNG file \"%s\"", filename.c_str()));
1482  }
1483 
1484  /* create a png info struct */
1485  png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1486  if (!png_ptr) {
1487  fclose(file);
1488  vpERROR_TRACE("Error during png_create_write_struct()\n");
1489  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1490  }
1491 
1492  png_infop info_ptr = png_create_info_struct(png_ptr);
1493  if (!info_ptr) {
1494  fclose(file);
1495  png_destroy_write_struct(&png_ptr, NULL);
1496  vpERROR_TRACE("Error during png_create_info_struct()\n");
1497  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1498  }
1499 
1500  /* initialize the setjmp for returning properly after a libpng error occured
1501  */
1502  if (setjmp(png_jmpbuf(png_ptr))) {
1503  fclose(file);
1504  png_destroy_write_struct(&png_ptr, &info_ptr);
1505  vpERROR_TRACE("Error during init_io\n");
1506  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1507  }
1508 
1509  /* setup libpng for using standard C fwrite() function with our FILE pointer
1510  */
1511  png_init_io(png_ptr, file);
1512 
1513  unsigned int width = I.getWidth();
1514  unsigned int height = I.getHeight();
1515  int bit_depth = 8;
1516  int color_type = PNG_COLOR_TYPE_RGB;
1517  /* set some useful information from header */
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 write header\n");
1523  throw(vpImageException(vpImageException::ioError, "PNG write error"));
1524  }
1525 
1526  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1527  PNG_FILTER_TYPE_BASE);
1528 
1529  png_write_info(png_ptr, info_ptr);
1530 
1531  png_bytep *row_ptrs = new png_bytep[height];
1532  for (unsigned int i = 0; i < height; i++)
1533  row_ptrs[i] = new png_byte[3 * width];
1534 
1535  unsigned char *input = (unsigned char *)I.bitmap;
1536  ;
1537 
1538  for (unsigned int i = 0; i < height; i++) {
1539  png_byte *row = row_ptrs[i];
1540  for (unsigned int j = 0; j < width; j++) {
1541  row[3 * j] = *(input);
1542  input++;
1543  row[3 * j + 1] = *(input);
1544  input++;
1545  row[3 * j + 2] = *(input);
1546  input++;
1547  input++;
1548  }
1549  }
1550 
1551  png_write_image(png_ptr, row_ptrs);
1552 
1553  png_write_end(png_ptr, NULL);
1554 
1555  for (unsigned int j = 0; j < height; j++)
1556  delete[] row_ptrs[j];
1557 
1558  delete[] row_ptrs;
1559 
1560  png_destroy_write_struct(&png_ptr, &info_ptr);
1561 
1562  fclose(file);
1563 }
1564 
1581 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1582 {
1583  FILE *file;
1584  png_byte magic[8];
1585  // Test the filename
1586  if (filename.empty()) {
1587  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1588  }
1589 
1590  file = fopen(filename.c_str(), "rb");
1591 
1592  if (file == NULL) {
1593  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1594  }
1595 
1596  /* read magic number */
1597  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1598  fclose(file);
1599  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1600  }
1601 
1602  /* check for valid magic number */
1603  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1604  fclose(file);
1605  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1606  filename.c_str()));
1607  }
1608 
1609  /* create a png read struct */
1610  // printf("version %s\n", PNG_LIBPNG_VER_STRING);
1611  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1612  if (png_ptr == NULL) {
1613  fprintf(stderr, "error: can't create a png read structure!\n");
1614  fclose(file);
1615  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1616  }
1617 
1618  /* create a png info struct */
1619  png_infop info_ptr = png_create_info_struct(png_ptr);
1620  if (info_ptr == NULL) {
1621  fprintf(stderr, "error: can't create a png info structure!\n");
1622  fclose(file);
1623  png_destroy_read_struct(&png_ptr, NULL, NULL);
1624  throw(vpImageException(vpImageException::ioError, "error reading png file"));
1625  }
1626 
1627  /* initialize the setjmp for returning properly after a libpng error occured
1628  */
1629  if (setjmp(png_jmpbuf(png_ptr))) {
1630  fclose(file);
1631  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1632  vpERROR_TRACE("Error during init io\n");
1633  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1634  }
1635 
1636  /* setup libpng for using standard C fread() function with our FILE pointer
1637  */
1638  png_init_io(png_ptr, file);
1639 
1640  /* tell libpng that we have already read the magic number */
1641  png_set_sig_bytes(png_ptr, sizeof(magic));
1642 
1643  /* read png info */
1644  png_read_info(png_ptr, info_ptr);
1645 
1646  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1647  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1648 
1649  unsigned int bit_depth, channels, color_type;
1650  /* get some useful information from header */
1651  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1652  channels = png_get_channels(png_ptr, info_ptr);
1653  color_type = png_get_color_type(png_ptr, info_ptr);
1654 
1655  /* convert index color images to RGB images */
1656  if (color_type == PNG_COLOR_TYPE_PALETTE)
1657  png_set_palette_to_rgb(png_ptr);
1658 
1659  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1660  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1661  png_set_expand(png_ptr);
1662 
1663  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1664  // png_set_tRNS_to_alpha (png_ptr);
1665 
1666  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1667  png_set_strip_alpha(png_ptr);
1668 
1669  if (bit_depth == 16)
1670  png_set_strip_16(png_ptr);
1671  else if (bit_depth < 8)
1672  png_set_packing(png_ptr);
1673 
1674  /* update info structure to apply transformations */
1675  png_read_update_info(png_ptr, info_ptr);
1676 
1677  channels = png_get_channels(png_ptr, info_ptr);
1678 
1679  if ((width != I.getWidth()) || (height != I.getHeight()))
1680  I.resize(height, width);
1681 
1682  png_bytep *rowPtrs = new png_bytep[height];
1683 
1684  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1685  unsigned char *data = new unsigned char[stride * height];
1686 
1687  for (unsigned int i = 0; i < height; i++)
1688  rowPtrs[i] = (png_bytep)data + (i * stride);
1689 
1690  png_read_image(png_ptr, rowPtrs);
1691 
1692  vpImage<vpRGBa> Ic(height, width);
1693  unsigned char *output;
1694 
1695  switch (channels) {
1696  case 1:
1697  output = (unsigned char *)I.bitmap;
1698  for (unsigned int i = 0; i < width * height; i++) {
1699  *(output++) = data[i];
1700  }
1701  break;
1702 
1703  case 2:
1704  output = (unsigned char *)I.bitmap;
1705  for (unsigned int i = 0; i < width * height; i++) {
1706  *(output++) = data[i * 2];
1707  }
1708  break;
1709 
1710  case 3:
1711  output = (unsigned char *)Ic.bitmap;
1712  for (unsigned int i = 0; i < width * height; i++) {
1713  *(output++) = data[i * 3];
1714  *(output++) = data[i * 3 + 1];
1715  *(output++) = data[i * 3 + 2];
1716  *(output++) = vpRGBa::alpha_default;
1717  }
1718  vpImageConvert::convert(Ic, I);
1719  break;
1720 
1721  case 4:
1722  output = (unsigned char *)Ic.bitmap;
1723  for (unsigned int i = 0; i < width * height; i++) {
1724  *(output++) = data[i * 4];
1725  *(output++) = data[i * 4 + 1];
1726  *(output++) = data[i * 4 + 2];
1727  *(output++) = data[i * 4 + 3];
1728  }
1729  vpImageConvert::convert(Ic, I);
1730  break;
1731  }
1732 
1733  delete[](png_bytep) rowPtrs;
1734  delete[] data;
1735  png_read_end(png_ptr, NULL);
1736  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1737  fclose(file);
1738 }
1739 
1758 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
1759 {
1760  FILE *file;
1761  png_byte magic[8];
1762 
1763  // Test the filename
1764  if (filename.empty()) {
1765  throw(vpImageException(vpImageException::ioError, "Cannot read PNG image: filename empty"));
1766  }
1767 
1768  file = fopen(filename.c_str(), "rb");
1769 
1770  if (file == NULL) {
1771  throw(vpImageException(vpImageException::ioError, "Cannot read file \"%s\"", filename.c_str()));
1772  }
1773 
1774  /* read magic number */
1775  if (fread(magic, 1, sizeof(magic), file) != sizeof(magic)) {
1776  fclose(file);
1777  throw(vpImageException(vpImageException::ioError, "Cannot read magic number in file \"%s\"", filename.c_str()));
1778  }
1779 
1780  /* check for valid magic number */
1781  if (png_sig_cmp(magic, 0, sizeof(magic))) {
1782  fclose(file);
1783  throw(vpImageException(vpImageException::ioError, "Cannot read PNG file: \"%s\" is not a valid PNG image",
1784  filename.c_str()));
1785  }
1786 
1787  /* create a png read struct */
1788  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1789  if (!png_ptr) {
1790  fclose(file);
1791  vpERROR_TRACE("Error during png_create_read_struct()\n");
1792  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1793  }
1794 
1795  /* create a png info struct */
1796  png_infop info_ptr = png_create_info_struct(png_ptr);
1797  if (!info_ptr) {
1798  fclose(file);
1799  png_destroy_read_struct(&png_ptr, NULL, NULL);
1800  vpERROR_TRACE("Error during png_create_info_struct()\n");
1801  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1802  }
1803 
1804  /* initialize the setjmp for returning properly after a libpng error occured
1805  */
1806  if (setjmp(png_jmpbuf(png_ptr))) {
1807  fclose(file);
1808  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1809  vpERROR_TRACE("Error during init io\n");
1810  throw(vpImageException(vpImageException::ioError, "PNG read error"));
1811  }
1812 
1813  /* setup libpng for using standard C fread() function with our FILE pointer
1814  */
1815  png_init_io(png_ptr, file);
1816 
1817  /* tell libpng that we have already read the magic number */
1818  png_set_sig_bytes(png_ptr, sizeof(magic));
1819 
1820  /* read png info */
1821  png_read_info(png_ptr, info_ptr);
1822 
1823  unsigned int width = png_get_image_width(png_ptr, info_ptr);
1824  unsigned int height = png_get_image_height(png_ptr, info_ptr);
1825 
1826  unsigned int bit_depth, channels, color_type;
1827  /* get some useful information from header */
1828  bit_depth = png_get_bit_depth(png_ptr, info_ptr);
1829  channels = png_get_channels(png_ptr, info_ptr);
1830  color_type = png_get_color_type(png_ptr, info_ptr);
1831 
1832  /* convert index color images to RGB images */
1833  if (color_type == PNG_COLOR_TYPE_PALETTE)
1834  png_set_palette_to_rgb(png_ptr);
1835 
1836  /* convert 1-2-4 bits grayscale images to 8 bits grayscale. */
1837  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
1838  png_set_expand(png_ptr);
1839 
1840  // if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
1841  // png_set_tRNS_to_alpha (png_ptr);
1842 
1843  if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
1844  png_set_strip_alpha(png_ptr);
1845 
1846  if (bit_depth == 16)
1847  png_set_strip_16(png_ptr);
1848  else if (bit_depth < 8)
1849  png_set_packing(png_ptr);
1850 
1851  /* update info structure to apply transformations */
1852  png_read_update_info(png_ptr, info_ptr);
1853 
1854  channels = png_get_channels(png_ptr, info_ptr);
1855 
1856  if ((width != I.getWidth()) || (height != I.getHeight()))
1857  I.resize(height, width);
1858 
1859  png_bytep *rowPtrs = new png_bytep[height];
1860 
1861  unsigned int stride = png_get_rowbytes(png_ptr, info_ptr);
1862  unsigned char *data = new unsigned char[stride * height];
1863 
1864  for (unsigned int i = 0; i < height; i++)
1865  rowPtrs[i] = (png_bytep)data + (i * stride);
1866 
1867  png_read_image(png_ptr, rowPtrs);
1868 
1869  vpImage<unsigned char> Ig(height, width);
1870  unsigned char *output;
1871 
1872  switch (channels) {
1873  case 1:
1874  output = (unsigned char *)Ig.bitmap;
1875  for (unsigned int i = 0; i < width * height; i++) {
1876  *(output++) = data[i];
1877  }
1878  vpImageConvert::convert(Ig, I);
1879  break;
1880 
1881  case 2:
1882  output = (unsigned char *)Ig.bitmap;
1883  for (unsigned int i = 0; i < width * height; i++) {
1884  *(output++) = data[i * 2];
1885  }
1886  vpImageConvert::convert(Ig, I);
1887  break;
1888 
1889  case 3:
1890  output = (unsigned char *)I.bitmap;
1891  for (unsigned int i = 0; i < width * height; i++) {
1892  *(output++) = data[i * 3];
1893  *(output++) = data[i * 3 + 1];
1894  *(output++) = data[i * 3 + 2];
1895  *(output++) = vpRGBa::alpha_default;
1896  }
1897  break;
1898 
1899  case 4:
1900  output = (unsigned char *)I.bitmap;
1901  for (unsigned int i = 0; i < width * height; i++) {
1902  *(output++) = data[i * 4];
1903  *(output++) = data[i * 4 + 1];
1904  *(output++) = data[i * 4 + 2];
1905  *(output++) = data[i * 4 + 3];
1906  }
1907  break;
1908  }
1909 
1910  delete[](png_bytep) rowPtrs;
1911  delete[] data;
1912  png_read_end(png_ptr, NULL);
1913  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
1914  fclose(file);
1915 }
1916 
1917 #elif defined(VISP_HAVE_OPENCV)
1918 
1926 void vpImageIo::writePNG(const vpImage<unsigned char> &I, const std::string &filename)
1927 {
1928 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1929  cv::Mat Ip;
1930  vpImageConvert::convert(I, Ip);
1931  cv::imwrite(filename.c_str(), Ip);
1932 #else
1933  IplImage *Ip = NULL;
1934  vpImageConvert::convert(I, Ip);
1935 
1936  cvSaveImage(filename.c_str(), Ip);
1937 
1938  cvReleaseImage(&Ip);
1939 #endif
1940 }
1941 
1949 void vpImageIo::writePNG(const vpImage<vpRGBa> &I, const std::string &filename)
1950 {
1951 #if (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1952  cv::Mat Ip;
1953  vpImageConvert::convert(I, Ip);
1954  cv::imwrite(filename.c_str(), Ip);
1955 #else
1956  IplImage *Ip = NULL;
1957  vpImageConvert::convert(I, Ip);
1958 
1959  cvSaveImage(filename.c_str(), Ip);
1960 
1961  cvReleaseImage(&Ip);
1962 #endif
1963 }
1964 
1981 void vpImageIo::readPNG(vpImage<unsigned char> &I, const std::string &filename)
1982 {
1983 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1984  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
1985  if (!Ip.empty())
1986  vpImageConvert::convert(Ip, I);
1987  else
1988  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1989 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
1990  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1991  if (!Ip.empty())
1992  vpImageConvert::convert(Ip, I);
1993  else
1994  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
1995 #else
1996  IplImage *Ip = NULL;
1997  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
1998  if (Ip != NULL)
1999  vpImageConvert::convert(Ip, I);
2000  else
2001  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2002  cvReleaseImage(&Ip);
2003 #endif
2004 }
2005 
2024 void vpImageIo::readPNG(vpImage<vpRGBa> &I, const std::string &filename)
2025 {
2026 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
2027  cv::Mat Ip = cv::imread(filename.c_str(), cv::IMREAD_GRAYSCALE);
2028  if (!Ip.empty())
2029  vpImageConvert::convert(Ip, I);
2030  else
2031  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2032 #elif (VISP_HAVE_OPENCV_VERSION >= 0x020408)
2033  cv::Mat Ip = cv::imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
2034  if (!Ip.empty())
2035  vpImageConvert::convert(Ip, I);
2036  else
2037  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2038 #else
2039  IplImage *Ip = NULL;
2040  Ip = cvLoadImage(filename.c_str(), CV_LOAD_IMAGE_COLOR);
2041  if (Ip != NULL)
2042  vpImageConvert::convert(Ip, I);
2043  else
2044  throw(vpImageException(vpImageException::ioError, "Can't read the image"));
2045  cvReleaseImage(&Ip);
2046 #endif
2047 }
2048 
2049 #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:239
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:133
#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:941
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:675
static void readPPM(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:805
unsigned int getSize() const
Definition: vpImage.h:219
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:866
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1771
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:1581
unsigned char R
Red component.
Definition: vpRGBa.h:148
unsigned int getHeight() const
Definition: vpImage.h:178
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:1372