Commit a1d7e047 authored by Matthieu Garrigues's avatar Matthieu Garrigues
Browse files

improving PNM format support

	* img/test.fits:
	  a fits image

	* mln/io/internal:
		The functions to save and load ppm, pbm and pgm format
		looked quite similar. I add this directory to factorise
		all these similarities

	* mln/io/internal/abort.hh:
		the abort function used in loading functions
	* mln/io/internal/pnm/load.hh:
		functions to load pnm files, 8 or 16 bits.
	* mln/io/internal/pnm/load_header.hh:
		function to read a pnm header.
	* mln/io/internal/pnm/macros.hh:
		Some macros to identify the magic numbers of the formats
	* mln/io/internal/pnm/save.hh:
		functions to load pnm files, 8 or 16 bits.
	* mln/io/internal/pnm/save_header.hh:
		function to save a pnm header.

	* mln/io/internal/pnm:
		all internal treatments of pnm format, used by
		concrete formats (pbm, pgm, ppm)

	* mln/io/pbm/load.hh:
		loading of pbm format done
	* mln/io/pbm/save.hh:
		saving of pbm format done

	* mln/io/pfm/load.hh:
		loading of pfm format done

	* mln/io/pgm/load.hh:
		loading of pgm format done
	* mln/io/pgm/save.hh:
		saving of pgm 8/16 bits format done

	* mln/io/ppm/load.hh:
		loading of ppm 8/16 bits format done
	* mln/io/ppm/save.hh:
		loading of ppm 8/16 bits format done

	* mln/value/rgb.hh:
		To fix : we can't apply level:transform on rgb images
		   convert_< rgb8 > could be one part of the problem.

	* mln/value/rgb16.hh:
		add rgb16 type to test ppm 16bits

	* tests/io_pbm.cc:
		some tests
	* tests/io_pgm.cc:
		some tests
	* tests/io_ppm16.cc:
		some tests

git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1109 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent eb6147aa
2007-09-14 Matthieu Garrigues <garrigues@lrde.epita.fr>
improving PNM format support
* img/test.fits:
a fits image
* mln/io/internal:
The functions to save and load ppm, pbm and pgm format
looked quite similar. I add this directory to factorise
all these similarities
* mln/io/internal/abort.hh:
the abort function used in loading functions
* mln/io/internal/pnm/load.hh:
functions to load pnm files, 8 or 16 bits.
* mln/io/internal/pnm/load_header.hh:
function to read a pnm header.
* mln/io/internal/pnm/macros.hh:
Some macros to identify the magic numbers of the formats
* mln/io/internal/pnm/save.hh:
functions to load pnm files, 8 or 16 bits.
* mln/io/internal/pnm/save_header.hh:
function to save a pnm header.
* mln/io/internal/pnm:
all internal treatments of pnm format, used by
concrete formats (pbm, pgm, ppm)
* mln/io/pbm/load.hh:
loading of pbm format done
* mln/io/pbm/save.hh:
saving of pbm format done
* mln/io/pfm/load.hh:
loading of pfm format done
* mln/io/pgm/load.hh:
loading of pgm format done
* mln/io/pgm/save.hh:
saving of pgm 8/16 bits format done
* mln/io/ppm/load.hh:
loading of ppm 8/16 bits format done
* mln/io/ppm/save.hh:
loading of ppm 8/16 bits format done
* mln/value/rgb.hh:
To fix : we can't apply level:transform on rgb images
convert_< rgb8 > could be one part of the problem.
* mln/value/rgb16.hh:
add rgb16 type to test ppm 16bits
* tests/io_pbm.cc:
some tests
* tests/io_pgm.cc:
some tests
* tests/io_ppm16.cc:
some tests
2007-09-13 Simon Nivault <simon.nivault@lrde.epita.fr>
disk2d windows well created, fix on sym
......
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License. This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_IO_ABORT_HH
# define MLN_IO_ABORT_HH
namespace mln
{
namespace io
{
namespace internal
{
void abort()
{
std::cerr << " aborting." << std::endl;
exit(0);
}
} // end of namespace mln::io::internal
} // end of namespace mln::io
} // end of namespace mln
#endif // ! MLN_IO_ABORT_HH
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License. This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_IO_PNM_LOAD_HH
# define MLN_IO_PNM_LOAD_HH
# include <iostream>
# include <fstream>
# include <string>
# include <mln/core/image2d_b.hh>
# include <mln/value/int_u8.hh>
# include <mln/value/rgb.hh>
# include <mln/io/internal/pnm/load_header.hh>
# include <mln/io/internal/pnm/macros.hh>
namespace mln
{
namespace io
{
namespace internal
{
namespace pnm
{
template <unsigned int n>
void load_raw_2d_uncontiguous(std::ifstream& file,
image2d_b< value::rgb<n> >& ima)
{
typedef typename value::rgb<n>::enc E;
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima),
min_col = geom::min_col(ima),
max_col = geom::max_col(ima);
point2d p;
std::cout << "g++ == 2.95 load as rgb\n";
for (p.row() = min_row; p.row() <= max_row; ++p.row())
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
E c;
file.read((char*)(&c), sizeof(E));
ima(p).red() = c;
file.read((char*)(&c), sizeof(E));
ima(p).green() = c;
file.read((char*)(&c), sizeof(E));
ima(p).blue() = c;
}
}
template <unsigned int n>
void load_raw_2d_uncontiguous(std::ifstream& file,
image2d_b< value::int_u<n> >& ima)
{
typedef typename value::int_u<n>::enc E;
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima),
min_col = geom::min_col(ima),
max_col = geom::max_col(ima);
point2d p;
for (p.row() = min_row; p.row() <= max_row; ++p.row())
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
E c;
file.read((char*)(&c), sizeof(E));
ima(p) = c;
}
}
template <typename I>
void load_raw_2d_contiguous(std::ifstream& file, I& ima)
{
point2d p = make::point2d(0, ima.domain().pmin().col());
typedef mln_value(I) V;
const mln_coord(I)
min_row = geom::min_row(ima),
max_row = geom::max_row(ima);
size_t len = geom::ncols(ima) * sizeof(V);
for (p.row() = min_row; p.row() <= max_row; ++p.row())
file.read((char*)(&ima(p)), len);
}
/// load_ascii.
template <typename I>
void load_ascii(std::ifstream& file, I& ima)
{
mln_fwd_piter(I) p(ima.domain());
for_all(p)
{
unsigned value;
file >> value;
ima(p) = value;
// FIXME: Test alt code below.
// file >> ima(p);
}
}
/// load_raw_2d.
/// for all pnm 8/16 bits formats
template <typename I>
void load_raw_2d(std::ifstream& file, I& ima)
{
if (sizeof(value::int_u8) == 1)
load_raw_2d_contiguous(file, ima);
else
load_raw_2d_uncontiguous(file, ima);
}
/// load pnm format
template <typename V>
image2d_b<V> load(char type_, const std::string& filename)
{
std::ifstream file(filename.c_str());
if (! file)
{
std::cerr << "error: file '" << filename
<< "' not found!";
abort();
}
char type = 0;
int nrows, ncols;
io::internal::pnm::read_header(type_ - 3, type_, file, type, nrows, ncols);
image2d_b<V> ima(nrows, ncols);
if (type == type_)
io::internal::pnm::load_raw_2d(file, ima);
else
if (type == (type_ - 3))
io::internal::pnm::load_ascii(file, ima);
return ima;
}
} // end of namespace mln::io::internal::pnm
} // end of namespace mln::io::internal
} // end of namespace mln::io
} // end of namespace mln
#endif // ! MLN_IO_PNM_LOAD_HH
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License. This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_IO_PNM_LOAD_HEADER_HH
# define MLN_IO_PNM_LOAD_HEADER_HH
# include <iostream>
# include <fstream>
# include <string>
namespace mln
{
namespace io
{
namespace internal
{
namespace pnm
{
bool read_header(std::istream& istr,
char& type,
int& nrows, int& ncols,
bool test = false)
{
// check magic
if (istr.get() != 'P' )
goto err;
type = istr.get();
if (type < '1' || type > '6')
goto err;
if (istr.get() != '\n')
goto err;
// skip comments
while (istr.peek() == '#')
{
std::string line;
std::getline(istr, line);
}
// get size
istr >> ncols >> nrows;
if (nrows <= 0 || ncols <= 0)
goto err;
// skip maxvalue
if (istr.get() != '\n')
goto err;
if (type != '1' && type != '4')
{
std::string line;
std::getline(istr, line);
}
return true;
err:
if (! test)
{
std::cerr << "error: badly formed header!";
abort();
}
return false;
}
void read_header(char ascii, char raw,
std::istream& istr,
char& type,
int& nrows, int& ncols)
{
read_header(istr, type, nrows, ncols);
if (! (type == ascii || type == raw))
{
std::cerr << "error: bad pnm type; "
<< "expected P" << ascii
<< " or P" << raw
<< ", get P" << type << "!";
abort();
}
}
} // end of namespace mln::io::internal::pnm
} // end of namespace mln::io::internal
} // end of namespace mln::io
} // end of namespace mln
#endif // ! MLN_IO_PNM_LOAD_HEADER_HH
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License. This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_IO_PNM_MACROS_HH
# define MLN_IO_PNM_MACROS_HH
/*! \file mln/io/internal/pnm/macros.hh
*
* \brief Definition of pnm formats macros.
*/
/// Portable Pixel Map Format
# define PPM '6'
# define PPM_ASCII '3'
/// Portable Gray Map Format
# define PGM '5'
# define PGM_ASCII '2'
/// Portable Bit Map Format
# define PBM '4'
# define PBM_ASCII '1'
#endif // ! MLN_IO_PNM_LOAD_HH
// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 EPITA
// Research and Development Laboratory
//
// This file is part of the Olena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License version 2 as published by the
// Free Software Foundation.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this library; see the file COPYING. If not, write to
// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
// Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free
// software library without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to
// produce an executable, this file does not by itself cause the
// resulting executable to be covered by the GNU General Public
// License. This exception does not however invalidate any other
// reasons why the executable file might be covered by the GNU General
// Public License.
#ifndef MLN_IO_PNM_SAVE_HH
# define MLN_IO_PNM_SAVE_HH
# include <iostream>
# include <fstream>
# include <mln/core/concept/image.hh>
# include <mln/value/rgb.hh>
# include <mln/value/int_u8.hh>
# include <mln/io/internal/pnm/save_header.hh>
# include <mln/io/internal/pnm/macros.hh>
# include <mln/metal/instance_of.hh>
# include <mln/geom/size2d.hh>
/*! \file mln/level/transform.hh
*
* \brief save pgm,
*
*/
namespace mln
{
namespace io
{
namespace internal
{
# ifndef MLN_INCLUDE_ONLY
namespace pnm
{
// for 3dimensionals values (rgb)
template <unsigned int n>
void save_data_uncontiguous(std::ofstream& file,
const image2d_b< value::rgb<n> >& ima)
{
typedef typename value::rgb<n>::enc V;
typedef typename value::rgb<n>::enc::enc E;
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima),
min_col = geom::min_col(ima),
max_col = geom::max_col(ima);
point2d p;
for (p.row() = min_row; p.row() <= max_row; ++p.row())
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
const V* buf = ima(p).buffer();
E v = buf[0].to_enc();
file.write((char*)&v, sizeof(E));
v = ima(p).green().to_enc();
file.write((char*)&v, sizeof(E));
v = ima(p).blue().to_enc();
file.write((char*)&v, sizeof(E));
}
}
// for scalar value
template <typename V>
void save_data_uncontiguous(std::ofstream& file,
const image2d_b<V>& ima)
{
typedef typename V::enc E;
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima),
min_col = geom::min_col(ima),
max_col = geom::max_col(ima);
point2d p;
for (p.row() = min_row; p.row() <= max_row; ++p.row())
for (p.col() = min_col; p.col() <= max_col; ++p.col())
{
E c = ima(p).to_enc();
file.write((char*)(&c), sizeof(E));
}
}
template <typename I>
void save_data(std::ofstream& file,
const I& ima)
{
const int
min_row = geom::min_row(ima),
max_row = geom::max_row(ima);
point2d p;
p.col() = geom::min_col(ima);
size_t len = geom::ncols(ima) * sizeof(mln_value(I));
for (p.row() = min_row; p.row() <= max_row; ++p.row())
file.write((char*)(& ima(p)), len);
}
template <typename I>
void save(const int type, const Fast_Image<I>& ima_, const std::string& filename)
{
const I& ima = exact(ima_);
std::ofstream file(filename.c_str());
io::internal::pnm::save_header(type, mln_max(mln_value(I)::enc),
ima, filename, file);
if (sizeof(value::int_u8) == 1)
save_data(file, ima);
else
save_data_uncontiguous(file, ima);
}