39#include "vpImageIoBackend.h"
40#include <visp3/core/vpImageConvert.h>
41#include <visp3/core/vpIoTools.h>
42#include <visp3/core/vpEndian.h>
46#ifndef DOXYGEN_SHOULD_SKIP_THIS
49void vp_decodeHeaderPNM(
const std::string &filename, std::ifstream &fd,
const std::string &magic,
unsigned int &w,
50 unsigned int &h,
unsigned int &maxval);
51void vp_decodeHeaderPFM(
const std::string &filename, std::ifstream &fd, std::string &magic,
unsigned int &w,
52 unsigned int &h,
double &scale,
bool &littleEndian);
63void vp_decodeHeaderPNM(
const std::string &filename, std::ifstream &fd,
const std::string &magic,
unsigned int &w,
64 unsigned int &h,
unsigned int &maxval)
67 unsigned int nb_elt = 4, cpt_elt = 0;
68 while (cpt_elt != nb_elt) {
70 while (std::getline(fd, line) && (line.compare(0, 1,
"#") == 0 || line.size() == 0)) {
80 if (header.size() == 0) {
86 if (header[0].compare(0, magic.size(), magic) != 0) {
92 header.erase(header.begin(),
95 while (header.size()) {
97 std::istringstream ss(header[0]);
100 header.erase(header.begin(),
103 else if (cpt_elt == 2) {
104 std::istringstream ss(header[0]);
107 header.erase(header.begin(),
110 else if (cpt_elt == 3) {
111 std::istringstream ss(header[0]);
114 header.erase(header.begin(),
121void vp_decodeHeaderPFM(
const std::string &filename, std::ifstream &fd, std::string &magic,
unsigned int &w,
122 unsigned int &h,
double &scale,
bool &littleEndian)
125 const unsigned int nb_elt = 4;
126 unsigned int cpt_elt = 0;
127 while (cpt_elt != nb_elt) {
129 while (std::getline(fd, line) && (line.compare(0, 1,
"#") == 0 || line.size() == 0)) {
139 if (header.empty()) {
146 if (magic !=
"PF" && magic !=
"Pf") {
149 "\"%s\" is not a PFM file with PF (RGB) or Pf (gray) magic number",
filename.c_str()));
152 header.erase(header.begin(),
155 while (header.size()) {
157 std::istringstream ss(header[0]);
160 header.erase(header.begin(),
163 else if (cpt_elt == 2) {
164 std::istringstream ss(header[0]);
167 header.erase(header.begin(),
170 else if (cpt_elt == 3) {
171 std::istringstream ss(header[0]);
173 littleEndian = scale < 0;
175 header.erase(header.begin(),
195void vp_writePFM(
const vpImage<float> &I,
const std::string &filename)
212 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
213 fprintf(fd,
"255\n");
217 size_t nbyte = I.getWidth() * I.getHeight();
219 ierr = fwrite(I.bitmap,
sizeof(
float), nbyte, fd);
230void vp_writePFM_HDR(
const vpImage<float> &I,
const std::string &filename)
237 FILE *fd = fopen(
filename.c_str(),
"wb");
244 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
245#ifdef VISP_LITTLE_ENDIAN
246 fprintf(fd,
"%f\n", -1.0f);
248 fprintf(fd,
"%f\n", 1.0f);
252 size_t nbyte = I.getWidth();
253 for (
int i =
static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
254 size_t ierr = fwrite(I[i],
sizeof(
float), nbyte, fd);
266void vp_writePFM_HDR(
const vpImage<vpRGBf> &I,
const std::string &filename)
273 FILE *fd = fopen(
filename.c_str(),
"wb");
280 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
281#ifdef VISP_LITTLE_ENDIAN
282 fprintf(fd,
"%f\n", -1.0f);
284 fprintf(fd,
"%f\n", 1.0f);
288 size_t nbyte = I.getWidth() * 3;
289 for (
int i =
static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
290 size_t ierr = fwrite(I[i],
sizeof(
float), nbyte, fd);
330 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
331 fprintf(fd,
"255\n");
335 size_t nbyte = I.getWidth() * I.getHeight();
337 ierr = fwrite(I.bitmap,
sizeof(
unsigned char), nbyte, fd);
355void vp_writePGM(
const vpImage<short> &I,
const std::string &filename)
359 unsigned int ncols = I.getWidth();
363 for (
unsigned int i = 0;
i < nrows * ncols; ++
i)
364 Iuc.
bitmap[i] = (
unsigned char)I.bitmap[
i];
366 vp_writePGM(Iuc, filename);
395 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
396 fprintf(fd,
"255\n");
400 size_t nbyte = I.getWidth() * I.getHeight();
405 ierr = fwrite(Itmp.
bitmap,
sizeof(
unsigned char), nbyte, fd);
432 unsigned int w = 0,
h = 0, maxval = 0;
433 const unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
434 const std::string magic(
"P8");
436 std::ifstream fd(
filename.c_str(), std::ios::binary);
443 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
445 if (w > w_max || h > h_max) {
449 if (maxval > maxval_max) {
454 if ((h != I.getHeight()) || (w != I.getWidth())) {
458 unsigned int nbyte = I.getHeight() * I.getWidth();
459 fd.read((
char *)I.bitmap,
sizeof(
float) * nbyte);
484void vp_readPFM_HDR(
vpImage<float> &I,
const std::string &filename)
486 std::ifstream fd(
filename.c_str(), std::ios::binary);
493 const unsigned int w_max = 100000, h_max = 100000;
494 const std::string magicRGB(
"PF"), magicGray(
"Pf");
496 unsigned int w = 0,
h = 0;
498 bool littleEndian =
true;
499 vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
501 if (w > w_max || h > h_max) {
506 unsigned int channels = (magic == magicRGB) ? 3 : 1;
507 if (h != I.getHeight() || channels * w != I.getWidth()) {
508 I.resize(h, channels * w);
511#ifdef VISP_LITTLE_ENDIAN
512 bool swapEndianness = !littleEndian;
514 bool swapEndianness = littleEndian;
516 for (
int i = I.getHeight() - 1; i >= 0; i--) {
517 fd.read((
char *)I[i],
sizeof(
float) * w * channels);
518 if (swapEndianness) {
519 for (
unsigned int j = 0;
j <
w * channels; ++
j) {
532 if (std::fabs(scale) > 0.0f) {
533 for (
unsigned int i = 0;
i < I.getHeight(); ++
i) {
534 for (
unsigned int j = 0;
j < I.getWidth(); ++
j) {
535 I[
i][
j] *= 1.0f /
static_cast<float>(std::fabs(scale));
558 std::ifstream fd(
filename.c_str(), std::ios::binary);
565 const unsigned int w_max = 100000, h_max = 100000;
566 const std::string magicRGB(
"PF"), magicGray(
"Pf");
568 unsigned int w = 0,
h = 0;
570 bool littleEndian =
true;
571 vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
573 if (w > w_max || h > h_max) {
578 unsigned int channels = (magic == magicRGB) ? 3 : 1;
579 if (magic != magicRGB) {
582 if (h != I.getHeight() || w != I.getWidth()) {
586#ifdef VISP_LITTLE_ENDIAN
587 bool swapEndianness = !littleEndian;
589 bool swapEndianness = littleEndian;
591 for (
int i = I.getHeight() - 1; i >= 0; i--) {
592 fd.read((
char *)I[i],
sizeof(
float) * w * channels);
593 if (swapEndianness) {
594 for (
unsigned int j = 0;
j <
w; ++
j) {
609 if (std::fabs(scale) > 0.0f) {
610 for (
unsigned int i = 0;
i < I.getHeight(); ++
i) {
611 for (
unsigned int j = 0;
j < I.getWidth(); ++
j) {
612 I[
i][
j].R *= 1.0f /
static_cast<float>(std::fabs(scale));
613 I[
i][
j].G *= 1.0f /
static_cast<float>(std::fabs(scale));
614 I[
i][
j].B *= 1.0f /
static_cast<float>(std::fabs(scale));
636 unsigned int w = 0,
h = 0, maxval = 0;
637 unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
638 std::string magic(
"P5");
640 std::ifstream fd(
filename.c_str(), std::ios::binary);
647 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
649 if (w > w_max || h > h_max) {
653 if (maxval > maxval_max) {
658 if ((h != I.getHeight()) || (w != I.getWidth())) {
662 unsigned int nbyte = I.getHeight() * I.getWidth();
663 fd.read((
char *)I.bitmap, nbyte);
694 vp_readPGM(Itmp, filename);
722 vp_readPPM(Itmp, filename);
740 unsigned int w = 0,
h = 0, maxval = 0;
741 unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
742 std::string magic(
"P6");
744 std::ifstream fd(
filename.c_str(), std::ios::binary);
751 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
753 if (w > w_max || h > h_max) {
757 if (maxval > maxval_max) {
762 if ((h != I.getHeight()) || (w != I.getWidth())) {
766 for (
unsigned int i = 0;
i < I.getHeight(); ++
i) {
767 for (
unsigned int j = 0;
j < I.getWidth(); ++
j) {
768 unsigned char rgb[3];
769 fd.read((
char *)&rgb, 3);
774 (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3,
filename.c_str()));
801 vp_writePPM(Itmp, filename);
827 fprintf(f,
"%u %u\n", I.getWidth(), I.getHeight());
828 fprintf(f,
"%d\n", 255);
830 for (
unsigned int i = 0;
i < I.getHeight(); ++
i) {
831 for (
unsigned int j = 0;
j < I.getWidth(); ++
j) {
833 unsigned char rgb[3];
838 size_t res = fwrite(&rgb, 1, 3, f);
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
Error that can be emitted by the vpImage class and its derivatives.
Definition of the vpImage class member functions.
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
VISP_EXPORT float swapFloat(float f)