39#include "vpImageIoBackend.h"
40#include <visp3/core/vpImageConvert.h>
41#include <visp3/core/vpIoTools.h>
42#include <visp3/core/vpEndian.h>
44#ifndef DOXYGEN_SHOULD_SKIP_THIS
54void vp_decodeHeaderPNM(
const std::string &filename, std::ifstream &fd,
const std::string &magic,
unsigned int &w,
55 unsigned int &h,
unsigned int &maxval)
58 unsigned int nb_elt = 4, cpt_elt = 0;
59 while (cpt_elt != nb_elt) {
61 while (std::getline(fd, line) && (line.compare(0, 1,
"#") == 0 || line.size() == 0)) {
71 if (header.size() == 0) {
77 if (header[0].compare(0, magic.size(), magic) != 0) {
80 filename.c_str(), magic.c_str()));
83 header.erase(header.begin(),
86 while (header.size()) {
88 std::istringstream ss(header[0]);
91 header.erase(header.begin(),
93 }
else if (cpt_elt == 2) {
94 std::istringstream ss(header[0]);
97 header.erase(header.begin(),
99 }
else if (cpt_elt == 3) {
100 std::istringstream ss(header[0]);
103 header.erase(header.begin(),
110void vp_decodeHeaderPFM(
const std::string &filename, std::ifstream &fd, std::string &magic,
unsigned int &w,
111 unsigned int &h,
double &scale,
bool &littleEndian)
114 const unsigned int nb_elt = 4;
115 unsigned int cpt_elt = 0;
116 while (cpt_elt != nb_elt) {
118 while (std::getline(fd, line) && (line.compare(0, 1,
"#") == 0 || line.size() == 0)) {
128 if (header.empty()) {
135 if (magic !=
"PF" && magic !=
"Pf") {
138 "\"%s\" is not a PFM file with PF (RGB) or Pf (gray) magic number", filename.c_str()));
141 header.erase(header.begin(),
144 while (header.size()) {
146 std::istringstream ss(header[0]);
149 header.erase(header.begin(),
151 }
else if (cpt_elt == 2) {
152 std::istringstream ss(header[0]);
155 header.erase(header.begin(),
157 }
else if (cpt_elt == 3) {
158 std::istringstream ss(header[0]);
160 littleEndian = scale < 0;
162 header.erase(header.begin(),
182void vp_writePFM(
const vpImage<float> &I,
const std::string &filename)
187 if (filename.empty()) {
191 fd = fopen(filename.c_str(),
"wb");
199 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
200 fprintf(fd,
"255\n");
204 size_t nbyte = I.getWidth() * I.getHeight();
206 ierr = fwrite(I.bitmap,
sizeof(
float), nbyte, fd);
210 filename.c_str(), ierr, nbyte));
217void vp_writePFM_HDR(
const vpImage<float> &I,
const std::string &filename)
220 if (filename.empty()) {
224 FILE *fd = fopen(filename.c_str(),
"wb");
231 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
232#ifdef VISP_LITTLE_ENDIAN
233 fprintf(fd,
"%f\n", -1.0f);
235 fprintf(fd,
"%f\n", 1.0f);
239 size_t nbyte = I.getWidth();
240 for (
int i =
static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
241 size_t ierr = fwrite(I[i],
sizeof(
float), nbyte, fd);
245 filename.c_str(), ierr, nbyte));
253void vp_writePFM_HDR(
const vpImage<vpRGBf> &I,
const std::string &filename)
256 if (filename.empty()) {
260 FILE *fd = fopen(filename.c_str(),
"wb");
267 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
268#ifdef VISP_LITTLE_ENDIAN
269 fprintf(fd,
"%f\n", -1.0f);
271 fprintf(fd,
"%f\n", 1.0f);
275 size_t nbyte = I.getWidth() * 3;
276 for (
int i =
static_cast<int>(I.getHeight()) - 1; i >= 0; i--) {
277 size_t ierr = fwrite(I[i],
sizeof(
float), nbyte, fd);
281 filename.c_str(), ierr, nbyte));
305 if (filename.empty()) {
309 fd = fopen(filename.c_str(),
"wb");
317 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
318 fprintf(fd,
"255\n");
322 size_t nbyte = I.getWidth() * I.getHeight();
324 ierr = fwrite(I.bitmap,
sizeof(
unsigned char), nbyte, fd);
328 filename.c_str(), ierr, nbyte));
342void vp_writePGM(
const vpImage<short> &I,
const std::string &filename)
346 unsigned int ncols = I.getWidth();
350 for (
unsigned int i = 0; i < nrows * ncols; i++)
351 Iuc.
bitmap[i] = (
unsigned char)I.bitmap[i];
353 vp_writePGM(Iuc, filename);
370 if (filename.empty()) {
374 fd = fopen(filename.c_str(),
"wb");
382 fprintf(fd,
"%u %u\n", I.getWidth(), I.getHeight());
383 fprintf(fd,
"255\n");
387 size_t nbyte = I.getWidth() * I.getHeight();
392 ierr = fwrite(Itmp.
bitmap,
sizeof(
unsigned char), nbyte, fd);
396 filename.c_str(), ierr, nbyte));
419 unsigned int w = 0, h = 0, maxval = 0;
420 const unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
421 const std::string magic(
"P8");
423 std::ifstream fd(filename.c_str(), std::ios::binary);
430 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
432 if (w > w_max || h > h_max) {
436 if (maxval > maxval_max) {
441 if ((h != I.getHeight()) || (w != I.getWidth())) {
445 unsigned int nbyte = I.getHeight() * I.getWidth();
446 fd.read((
char *)I.bitmap,
sizeof(
float) * nbyte);
471void vp_readPFM_HDR(
vpImage<float> &I,
const std::string &filename)
473 std::ifstream fd(filename.c_str(), std::ios::binary);
480 const unsigned int w_max = 100000, h_max = 100000;
481 const std::string magicRGB(
"PF"), magicGray(
"Pf");
483 unsigned int w = 0, h = 0;
485 bool littleEndian =
true;
486 vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
488 if (w > w_max || h > h_max) {
493 unsigned int channels = (magic == magicRGB) ? 3 : 1;
494 if (h != I.getHeight() || channels * w != I.getWidth()) {
495 I.resize(h, channels * w);
498#ifdef VISP_LITTLE_ENDIAN
499 bool swapEndianness = !littleEndian;
501 bool swapEndianness = littleEndian;
503 for (
int i = I.getHeight() - 1; i >= 0; i--) {
504 fd.read((
char *)I[i],
sizeof(
float) * w * channels);
505 if (swapEndianness) {
506 for (
unsigned int j = 0; j < w * channels; j++) {
519 if (std::fabs(scale) > 0.0f) {
520 for (
unsigned int i = 0; i < I.getHeight(); i++) {
521 for (
unsigned int j = 0; j < I.getWidth(); j++) {
522 I[i][j] *= 1.0f /
static_cast<float>(std::fabs(scale));
545 std::ifstream fd(filename.c_str(), std::ios::binary);
552 const unsigned int w_max = 100000, h_max = 100000;
553 const std::string magicRGB(
"PF"), magicGray(
"Pf");
555 unsigned int w = 0, h = 0;
557 bool littleEndian =
true;
558 vp_decodeHeaderPFM(filename, fd, magic, w, h, scale, littleEndian);
560 if (w > w_max || h > h_max) {
565 unsigned int channels = (magic == magicRGB) ? 3 : 1;
566 if (magic != magicRGB) {
569 if (h != I.getHeight() || w != I.getWidth()) {
573#ifdef VISP_LITTLE_ENDIAN
574 bool swapEndianness = !littleEndian;
576 bool swapEndianness = littleEndian;
578 for (
int i = I.getHeight() - 1; i >= 0; i--) {
579 fd.read((
char *)I[i],
sizeof(
float) * w * channels);
580 if (swapEndianness) {
581 for (
unsigned int j = 0; j < w; j++) {
596 if (std::fabs(scale) > 0.0f) {
597 for (
unsigned int i = 0; i < I.getHeight(); i++) {
598 for (
unsigned int j = 0; j < I.getWidth(); j++) {
599 I[i][j].R *= 1.0f /
static_cast<float>(std::fabs(scale));
600 I[i][j].G *= 1.0f /
static_cast<float>(std::fabs(scale));
601 I[i][j].B *= 1.0f /
static_cast<float>(std::fabs(scale));
623 unsigned int w = 0, h = 0, maxval = 0;
624 unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
625 std::string magic(
"P5");
627 std::ifstream fd(filename.c_str(), std::ios::binary);
634 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
636 if (w > w_max || h > h_max) {
640 if (maxval > maxval_max) {
645 if ((h != I.getHeight()) || (w != I.getWidth())) {
649 unsigned int nbyte = I.getHeight() * I.getWidth();
650 fd.read((
char *)I.bitmap, nbyte);
681 vp_readPGM(Itmp, filename);
709 vp_readPPM(Itmp, filename);
727 unsigned int w = 0, h = 0, maxval = 0;
728 unsigned int w_max = 100000, h_max = 100000, maxval_max = 255;
729 std::string magic(
"P6");
731 std::ifstream fd(filename.c_str(), std::ios::binary);
738 vp_decodeHeaderPNM(filename, fd, magic, w, h, maxval);
740 if (w > w_max || h > h_max) {
744 if (maxval > maxval_max) {
749 if ((h != I.getHeight()) || (w != I.getWidth())) {
753 for (
unsigned int i = 0; i < I.getHeight(); i++) {
754 for (
unsigned int j = 0; j < I.getWidth(); j++) {
755 unsigned char rgb[3];
756 fd.read((
char *)&rgb, 3);
761 (i * I.getWidth() + j) * 3 + fd.gcount(), I.getSize() * 3, filename.c_str()));
788 vp_writePPM(Itmp, filename);
803 if (filename.empty()) {
807 f = fopen(filename.c_str(),
"wb");
814 fprintf(f,
"%u %u\n", I.getWidth(), I.getHeight());
815 fprintf(f,
"%d\n", 255);
817 for (
unsigned int i = 0; i < I.getHeight(); i++) {
818 for (
unsigned int j = 0; j < I.getWidth(); j++) {
820 unsigned char rgb[3];
825 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
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
VISP_EXPORT float swapFloat(float f)