URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-10-16 Edwin Carlinet <carlinet(a)lrde.epita.fr>
Add AVS field file support.
* mln/io/all.hh: Update.
* mln/io/fld/all.hh: New.
* mln/io/fld/header.hh: New.
* mln/io/fld/load.hh: New.
* mln/io/fld/load_header.hh: New.
* mln/io/fld/max_components.hh: New.
* mln/io/fld/save.hh: New.
* mln/io/fld/write_header.hh: New.
* mln/io/fld: New.
* tests/io/Makefile.am: Add rules.
* tests/io/fld/Makefile.am: New.
* tests/io/fld/fld1d.cc: New.
* tests/io/fld/fld2d.cc: New.
* tests/io/fld/fld3d.cc: New.
* tests/io/fld: New.
---
mln/io/all.hh | 1
mln/io/fld/all.hh | 49 ++++++++
mln/io/fld/header.hh | 94 ++++++++++++++++
mln/io/fld/load.hh | 242 +++++++++++++++++++++++++++++++++++++++++++
mln/io/fld/load_header.hh | 220 +++++++++++++++++++++++++++++++++++++++
mln/io/fld/max_components.hh | 102 ++++++++++++++++++
mln/io/fld/save.hh | 173 ++++++++++++++++++++++++++++++
mln/io/fld/write_header.hh | 129 ++++++++++++++++++++++
tests/io/Makefile.am | 3
tests/io/fld/Makefile.am | 31 +++++
tests/io/fld/fld1d.cc | 57 ++++++++++
tests/io/fld/fld2d.cc | 108 +++++++++++++++++++
tests/io/fld/fld3d.cc | 59 ++++++++++
13 files changed, 1267 insertions(+), 1 deletion(-)
Index: trunk/milena/mln/io/fld/write_header.hh
===================================================================
--- trunk/milena/mln/io/fld/write_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/write_header.hh (revision 4637)
@@ -0,0 +1,129 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_WRITE_HEADER_HH
+# define MLN_IO_FLD_WRITE_HEADER_HH
+
+///
+/// \brief Write AVS headers in a file.
+///
+///
+///
+
+
+# include <mln/io/fld/header.hh>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+ /// Write the AVS header in a file.
+ ///
+ /// \param file The file to write.
+ /// \param h The AVS header.
+ ///
+ void write_header(std::ostream& file, const fld_header& h);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ void
+ write_header(std::ostream& file, const fld_header& h)
+ {
+ file << "# AVS field file" << std::endl;
+ file << "# Generated by Milena 1.0
http://olena.lrde.epita.fr" <<
std::endl;
+ file << "# EPITA Research and Development Laboratory (LRDE)" <<
std::endl;
+
+ file << "ndim=" << h.ndim << std::endl;
+ for (int i = 0; i < h.ndim; i++)
+ file << "dim" << (i + 1) << "=" <<
h.dim[i] << std::endl;
+ file << "nspace=" << h.nspace << std::endl
+ << "veclen=" << h.veclen << std::endl;
+
+ switch (h.data)
+ {
+ case data_type::BYTE :
+ file << "data=byte" << std::endl;
+ break;
+ case data_type::SHORT :
+ file << "data=short" << std::endl;
+ break;
+ case data_type::INTEGER :
+ file << "data=integer" << std::endl;
+ break;
+ case data_type::FLOAT :
+ file << "data=float" << std::endl;
+ break;
+ case data_type::DOUBLE :
+ file << "data=double" << std::endl;
+ break;
+ default:
+ std::cerr << "Data type not supported: abort().";
+ abort();
+ }
+
+ switch (h.field)
+ {
+ case field_type::UNIFORM :
+ file << "field=uniform" << std::endl;
+ break;
+ case field_type::IRREGULAR :
+ file << "field=irregular" << std::endl;
+ break;
+ case field_type::RECTILINEAR :
+ file << "field=rectilinear" << std::endl;
+ break;
+ default:
+ std::cerr << "Field type not suported: abort().";
+ abort();
+ }
+
+ file << "min_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.min_ext[i] << " ";
+ file << std::endl;
+
+ file << "max_ext=";
+ for (int i = 0; i < h.nspace; i++)
+ file << h.max_ext[i] << " ";
+ file << std::endl;
+
+ file << "\f\f";
+ }
+
+#endif // !MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_WRITE_HEADER_HH
Index: trunk/milena/mln/io/fld/load_header.hh
===================================================================
--- trunk/milena/mln/io/fld/load_header.hh (revision 0)
+++ trunk/milena/mln/io/fld/load_header.hh (revision 4637)
@@ -0,0 +1,220 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_LOAD_HEADER_HH
+# define MLN_IO_FLD_LOAD_HEADER_HH
+
+///
+/// \brief Read AVS header from a file.
+///
+///
+
+# include <mln/io/fld/header.hh>
+# include <cstdlib>
+# include <locale>
+# include <iostream>
+# include <sstream>
+# include <string>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Read the header form an AVS field file.
+ ///
+ /// \param ins The file to read.
+ ///
+ /// \return The header.
+ ///
+ fld_header read_header(std::istream& ins);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ void
+ abort_fld_reader(const char* msg, unsigned line = 0)
+ {
+ std::cerr << "AVS field file reader: " << msg << " on
line " << line << std::endl;
+ abort();
+ }
+
+ }
+
+ inline
+ fld_header
+ read_header(std::istream& file)
+ {
+ std::stringstream ins;
+ std::string line_str, lhs, rhs;
+ fld_header header;
+ unsigned line;
+
+ std::getline(file, line_str);
+ line = 1;
+ if (line_str.compare(0, 5, "# AVS"))
+ internal::abort_fld_reader("Invalid format", line);
+
+ while (file.good() && file.peek() != '\f')
+ {
+ std::getline(file, line_str);
+ ++line;
+
+ ins.clear();
+ ins.str(line_str);
+ rhs.clear();
+ lhs.clear();
+
+ { // Parse the line
+ char c = ins.get();
+ while (isspace(c))
+ ins.get(c);
+ if (c == '#') // Comments
+ continue;
+ while (isalnum(c) || c == '_')
+ {
+ lhs.push_back(c);
+ ins.get(c);
+ }
+ while (isspace(c))
+ ins.get(c);
+ if (c != '=')
+ internal::abort_fld_reader("Parse error", line);
+ while (isspace(ins.peek()))
+ ins.ignore();
+ }
+
+ if (lhs == "ndim")
+ {
+ ins >> header.ndim;
+ if (header.ndim < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ header.dim = new int[header.ndim];
+ std::fill(header.dim, header.dim + header.ndim, -1);
+ }
+ else if (lhs.compare(0, 3, "dim") == 0)
+ {
+ std::stringstream ss(lhs.substr(3));
+ int dim;
+ ss >> dim;
+ if (dim < 1 || dim > header.ndim)
+ internal::abort_fld_reader("Invalid dimension", line);
+ if (!ss.eof())
+ internal::abort_fld_reader("Parse error", line);
+ ins >> header.dim[dim - 1];
+ if (header.dim[dim - 1] < 1)
+ internal::abort_fld_reader("Invalid dimension", line);
+ }
+ else if (lhs == "nspace")
+ {
+ ins >> header.nspace;
+ if (header.nspace < 1)
+ internal::abort_fld_reader("Invalid space dimension", line);
+ header.min_ext = new float[header.nspace];
+ header.max_ext = new float[header.nspace];
+ }
+ else if (lhs == "veclen")
+ {
+ ins >> header.veclen;
+ if (header.veclen == -1)
+ internal::abort_fld_reader("Invalid vector length", line);
+ }
+ else if (lhs == "data")
+ {
+ ins >> rhs;
+ if (rhs == "byte")
+ header.data = data_type::BYTE;
+ else if (rhs == "short")
+ header.data = data_type::SHORT;
+ else if (rhs == "integer")
+ header.data = data_type::INTEGER;
+ else if (rhs == "float")
+ header.data = data_type::FLOAT;
+ else if (rhs == "double")
+ header.data = data_type::DOUBLE;
+ else
+ internal::abort_fld_reader("Invalid data type", line);
+ }
+ else if (lhs == "field")
+ {
+ ins >> rhs;
+ if (rhs != "uniform")
+ internal::abort_fld_reader("Unhandled field type", line);
+ header.field = field_type::UNIFORM;
+ }
+ else if (lhs == "min_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.min_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else if (lhs == "max_ext")
+ {
+ for (int i = 0; i < header.ndim; ++i)
+ {
+ ins >> header.max_ext[i];
+ if (ins.peek() == ',')
+ ins.ignore();
+ }
+ }
+ else
+ internal::abort_fld_reader("Parse error", line);
+
+ rhs.clear();
+ ins >> rhs;
+ if (!rhs.empty() && rhs[0] != '#')
+ internal::abort_fld_reader("Parse error", line);
+ }
+
+ file.ignore();
+ if (file.get() != '\f')
+ internal::abort_fld_reader("Parse error", line);
+
+ if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
+ header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
+ internal::abort_fld_reader("Invalid format", line);
+ for (int i = 0; i < header.ndim; ++i)
+ if (header.dim[i] == -1)
+ internal::abort_fld_reader("Invalid format", line);
+ return header;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HEADER_HH
Index: trunk/milena/mln/io/fld/all.hh
===================================================================
--- trunk/milena/mln/io/fld/all.hh (revision 0)
+++ trunk/milena/mln/io/fld/all.hh (revision 4637)
@@ -0,0 +1,49 @@
+// Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_ALL_HH
+# define MLN_IO_FLD_ALL_HH
+
+/// \file
+/// \brief Inclusion of all AVS field file I/O routines.
+
+
+namespace mln
+{
+
+ namespace io
+ {
+ /// Namespace of pgm input/output handling.
+ namespace fld {}
+ }
+
+}
+
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/load.hh>
+# include <mln/io/fld/save.hh>
+
+#endif // ! MLN_IO_FLD_ALL_HH
Index: trunk/milena/mln/io/fld/header.hh
===================================================================
--- trunk/milena/mln/io/fld/header.hh (revision 0)
+++ trunk/milena/mln/io/fld/header.hh (revision 4637)
@@ -0,0 +1,94 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_HEADER_HH
+# define MLN_IO_FLD_HEADER_HH
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+
+ struct data_type { enum E { UNKNOWN, BYTE, SHORT, INTEGER, FLOAT, DOUBLE }; };
+ struct field_type { enum E { UNKNOWN, UNIFORM, RECTILINEAR, IRREGULAR }; };
+
+ ///
+ /// \brief Define the header structure of an AVS field data file.
+ ///
+ struct fld_header
+ {
+ int ndim; // The number of computational dimensions in the field.
+ int* dim; // The dimension size of each axis.
+ int nspace; // The number of physical coordinates per field element.
+ int veclen; // The number of data values for each field element.
+ data_type::E data; // The primitive data type of all the data values.
+ field_type::E field; // The field type.
+ float* min_ext; // The minimum coordinate value that any member data point occupies in
space.
+ float* max_ext; // The maximum coordinate value that any member data point occupies in
space.
+ // std::vector<std::string> label; // Not handled.
+ // std::vector<std::string> unit; // Not handled.
+ // void* min_val; // The minimum data value in the field. (Not used)
+ // void* max_val; // The maximum data value in the field. (Not used)
+ // struct {...} variable; // Not handled.
+ // struct {...} coord; // Not handled.
+
+ fld_header();
+ ~fld_header();
+ };
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ fld_header::fld_header()
+ : ndim (-1),
+ dim (0),
+ nspace (-1),
+ veclen (-1),
+ data (data_type::UNKNOWN),
+ field (field_type::UNKNOWN)
+ {
+ }
+
+ fld_header::~fld_header()
+ {
+ delete [] dim;
+ delete [] max_ext;
+ delete [] min_ext;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_HEADER_HH
Index: trunk/milena/mln/io/fld/max_components.hh
===================================================================
--- trunk/milena/mln/io/fld/max_components.hh (revision 0)
+++ trunk/milena/mln/io/fld/max_components.hh (revision 4637)
@@ -0,0 +1,102 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_MAX_COMPONENTS_HH
+# define MLN_IO_FLD_MAX_COMPONENTS_HH
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/io/fld/header.hh>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&);
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v);
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&);
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ unsigned int max_component(const V&)
+ {
+ return mln_max(V);
+ }
+
+
+ template <unsigned n, typename V>
+ inline
+ unsigned int max_component(const algebra::vec<n, V>& v)
+ {
+ return mln_max(V);
+ }
+
+ template <unsigned n>
+ inline
+ unsigned int max_component(const value::rgb<n>&)
+ {
+ return mln_max(mln::value::int_u<n>);
+ }
+
+ inline
+ unsigned int max_component(const fld::data_type::E& t)
+ {
+ switch (t)
+ {
+ case data_type::BYTE: return mln_max(unsigned char);
+ case data_type::SHORT: return mln_max(unsigned short);
+ case data_type::INTEGER: return mln_max(unsigned);
+ case data_type::FLOAT: return mln_max(float);
+ case data_type::DOUBLE: return mln_max(double);
+ default: return 0;
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+ }
+
+ }
+
+}
+
+#endif // !MLN_IO_FLD_MAX_COMPONENTS_HH
Index: trunk/milena/mln/io/fld/save.hh
===================================================================
--- trunk/milena/mln/io/fld/save.hh (revision 0)
+++ trunk/milena/mln/io/fld/save.hh (revision 4637)
@@ -0,0 +1,173 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_SAVE_HH
+# define MLN_IO_FLD_SAVE_HH
+/// \file
+/// \brief Save an image to AVS field file format.
+///
+/// \todo Handle not high speed images.
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/gpoint.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/write_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+
+# include <mln/geom/nsites.hh>
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+ template <typename I>
+ inline
+ void save_data_contiguous(std::ofstream& file, const I& ima)
+ {
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ P pmin = ima.domain().pmin();
+ P pmax = ima.domain().pmax();
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.write((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.write((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ fld::fld_header make_header(const I& ima)
+ {
+ fld_header hdr;
+ typedef mln_site(I) P;
+ typedef mln_value(I) V;
+ enum { dim = P::dim };
+
+ hdr.ndim = dim;
+ hdr.nspace = dim;
+ hdr.veclen = mln_dim(V);
+ hdr.dim = new int[dim];
+ hdr.min_ext = new float[dim];
+ hdr.max_ext = new float[dim];
+
+ box<P> bbox = geom::bbox(ima);
+ P pmin = bbox.pmin();
+ P pmax = bbox.pmax();
+
+ for (unsigned i = 0; i < dim; i++)
+ {
+ hdr.dim[i] = pmax[i] - pmin[i] + 1;
+ hdr.min_ext[i] = pmin[i];
+ hdr.max_ext[i] = pmax[i];
+ }
+
+ unsigned max_c = max_component(V ());
+ if (max_c == max_component(data_type::BYTE))
+ hdr.data = data_type::BYTE;
+ else if (max_c == max_component(data_type::SHORT))
+ hdr.data = data_type::SHORT;
+ else if (max_c == max_component(data_type::INTEGER))
+ hdr.data = data_type::INTEGER;
+ else if (max_c == max_component(data_type::FLOAT))
+ hdr.data = data_type::FLOAT;
+ else if (max_c == max_component(data_type::DOUBLE))
+ hdr.data = data_type::DOUBLE;
+ else
+ hdr.data = data_type::UNKNOWN;
+
+ hdr.field = field_type::UNIFORM;
+
+ return hdr;
+ }
+
+ } // end of namespace mln::io::fld::internal
+
+ template <typename I>
+ void save(const Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::save");
+ // For the moment, just the fast version.
+ mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
+
+ const I& ima = exact(ima_);
+ mln_precondition(ima.is_valid());
+
+ std::ofstream file(filename);
+ fld_header hdr = internal::make_header(ima);
+
+ write_header(file, hdr);
+ internal::save_data_contiguous(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::save");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+#endif // !MLN_IO_FLD_SAVE_HH
Index: trunk/milena/mln/io/fld/load.hh
===================================================================
--- trunk/milena/mln/io/fld/load.hh (revision 0)
+++ trunk/milena/mln/io/fld/load.hh (revision 4637)
@@ -0,0 +1,242 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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_FLD_LOAD_HH
+# define MLN_IO_FLD_LOAD_HH
+
+/// \file
+///
+/// \brief Load an image from an AVS field file.
+///
+/// \note The current loader does not follow the whole specifications
+/// of the format. Actually, it has the following restrictions:
+/// - the dimension of the field and the space must be the same.
+/// - the number of dimension is limited to 1D, 2D and 3D.
+/// - the data format must be native (float, integer...) (XDR extension is not
supported)
+/// - the field must uniform (regular grid).
+/// - dim1, dim2... dimn are parsed but ignored.
+/// - min_ext and max_ext (pmin and pmax of the bbox) are not computed and are
compulsory.
+/// - label and unit keyword are not supported.
+/// - external data source ('coord', and 'variable') is not supported.
+///
+/// FIXME: pnm::load uses special implementation if sizeof(int_u8) != 1 ?? what ??
+
+# include <mln/core/concept/image.hh>
+# include <mln/io/fld/header.hh>
+# include <mln/io/fld/load_header.hh>
+# include <mln/io/fld/max_components.hh>
+
+# include <mln/algebra/vec.hh>
+# include <mln/value/rgb.hh>
+# include <mln/value/int_u8.hh>
+
+# include <mln/geom/nsites.hh>
+
+# include <fstream>
+# include <iostream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace fld
+ {
+
+ /// Load an image from an AVS field file.
+ ///
+ /// \param[in,out] ima_ The image to load.
+ /// \param[in] filename The path to the AVS file.
+ ///
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ void
+ abort_load(const char* msg, const char* filename)
+ {
+ std::cerr << "Error: file '" << filename <<
"'"
+ << "cannot be loaded." << std::endl
+ << "Error description: " << msg << std::endl;
+ abort();
+ }
+
+ // Read a Milena rgb value (sizeof(int_u8) != 1).
+ template <unsigned int n>
+ inline
+ void read_value(std::ifstream& file, value::rgb<n>& v)
+ {
+ typedef typename value::int_u<n>::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ v.red() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.green() = c;
+ file.read((char*)(&c), sizeof(E));
+ v.blue() = c;
+ }
+
+ // Read a Milena scalar value (sizeof(int_u8) != 1).
+ template <class V>
+ inline
+ void read_value(std::ifstream& file, value::Scalar<V>& v)
+ {
+ typedef typename V::enc E;
+
+ E c;
+ file.read((char*)(&c), sizeof(E));
+ exact(v) = c;
+ }
+
+ // Read a builtin scalar value.
+ template <typename V>
+ inline
+ void read_value(std::ifstream& file, V& v)
+ {
+ V c;
+ file.read((char*)(&c), sizeof(V));
+ v = c;
+ }
+
+ // used when (sizeof(int_u8) != 1)
+ template <typename I>
+ inline
+ void load_raw_uncontiguous(std::ifstream& file, I& ima)
+ {
+ mln_piter(I) p(ima.domain());
+ read_value(file, ima(p));
+ }
+
+ // used in g++ > 2.95
+ template <typename I>
+ inline
+ void load_raw_contiguous(std::ifstream& file, I& ima)
+ {
+ mln_site(I) pmin = ima.domain().pmin();
+ mln_site(I) pmax = ima.domain().pmax();
+
+ typedef mln_site(I) P;
+ enum { dim = P::dim };
+
+ // The first array index varies most quickly (FORTRAN-style).
+ typedef mln_value(I) V;
+
+
+ std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
+ std::size_t n = len * sizeof(V);
+
+ P p = pmin;
+ if (dim == 1)
+ {
+ file.read((char*)(&ima(p)), n);
+ return;
+ }
+
+ while (true)
+ {
+ file.read((char*)(&ima(p)), n);
+ ++p[dim - 2];
+
+ for (int i = dim - 2; p[i] > pmax[i]; --i)
+ {
+ if (i == 0)
+ return;
+ p[i] = pmin[i];
+ ++p[i - 1];
+ }
+ }
+ }
+
+ template <typename I>
+ inline
+ void load_raw(std::ifstream& file, I& ima)
+ {
+ if (sizeof(value::int_u8) == 1)
+ load_raw_contiguous(file, ima);
+ else
+ load_raw_uncontiguous(file, ima);
+ }
+
+ } // end of mln::io::internal
+
+ template <typename I>
+ inline
+ void
+ load(Image<I>& ima_, const char* filename)
+ {
+ trace::entering("mln::io::fld::load");
+
+ std::ifstream file(filename);
+ if (! file)
+ internal::abort_load("Fail to open the file.", filename);
+
+ typedef mln_value(I) V;
+ typedef mln_site(I) P;
+
+ I& ima = exact(ima_);
+ fld_header hder = fld::read_header(file);
+ int nspace = P::dim;
+ int veclen = mln_dim(V);
+
+ if (nspace != hder.nspace)
+ internal::abort_load("The dimension of the input does not match the one from the
file.", filename);
+ if (nspace > 3)
+ internal::abort_load("The loader does not handle image dimension greater than
three.", filename);
+ if (veclen != hder.veclen)
+ internal::abort_load("The dimension of the value does not match the one from the
file.", filename);
+ if (max_component(V ()) != max_component(hder.data))
+ internal::abort_load("The data type of the input mismatches the one from the
file.", filename);
+
+ box<mln_site(I)> bbox;
+ for (int i = 0; i < hder.ndim; ++i)
+ {
+ bbox.pmin()[i] = hder.min_ext[i];
+ bbox.pmax()[i] = hder.max_ext[i];
+ }
+
+ ima.init_(bbox);
+ internal::load_raw(file, ima);
+
+ file.close();
+ trace::exiting("mln::io::fld::load");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::fld
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+#endif // !MLN_IO_FLD_LOAD_HH
Index: trunk/milena/mln/io/all.hh
===================================================================
--- trunk/milena/mln/io/all.hh (revision 4636)
+++ trunk/milena/mln/io/all.hh (revision 4637)
@@ -57,6 +57,7 @@
# include <mln/io/ppm/all.hh>
# include <mln/io/txt/all.hh>
# include <mln/io/off/all.hh>
+# include <mln/io/fld/all.hh>
/*--------------------------------------------------.
Index: trunk/milena/tests/io/fld/fld2d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld2d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld2d.cc (revision 4637)
@@ -0,0 +1,108 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test fld IO on 2D images.
+///
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/int_u16.hh>
+#include <mln/data/compare.hh>
+#include "tests/data.hh"
+
+#include <stdio.h>
+#include <float.h>
+#include <time.h>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::int_u16;
+
+ // Test on int_u8.
+ // Veclen = 1, data = byte
+ {
+ image2d<int_u8> ori, test;
+ io::pgm::load(ori, MLN_IMG_DIR "/lena.pgm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on RGB 16
+ // Veclen = 3, data = short
+ {
+ image2d<int_u16> ori, test;
+ io::ppm::load(ori, MLN_IMG_DIR "/lena_16.ppm");
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+ }
+
+ // Test on 32-bits data type
+ // Veclen = 1, data = float
+ {
+ image2d<float> ori, test;
+ box<point2d> domain(8, 9);
+
+ srand(time(NULL));
+ ori.init_(domain);
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ ori(p) = random() / RAND_MAX;
+ }
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ {
+ mln_piter_(image2d<float>) p(domain);
+ for_all(p)
+ mln_assertion(fabs(ori(p) - test(p)) < FLT_EPSILON);
+ }
+ }
+
+}
Index: trunk/milena/tests/io/fld/fld3d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld3d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld3d.cc (revision 4637)
@@ -0,0 +1,59 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test AVS field file IO with 3D image.
+///
+///
+///
+
+#include <mln/core/image/image3d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/debug/println.hh>
+#include <mln/data/compare.hh>
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image3d<int_u8> ori, test;
+ box<point3d> b(8, 9, 10);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/fld/Makefile.am
===================================================================
--- trunk/milena/tests/io/fld/Makefile.am (revision 0)
+++ trunk/milena/tests/io/fld/Makefile.am (revision 4637)
@@ -0,0 +1,31 @@
+# Copyright (C) 2007, 2009 EPITA Research and Development Laboratory (LRDE).
+#
+# This file is part of Olena.
+#
+# Olena is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, version 2 of the License.
+#
+# Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+#
+
+## Process this file through Automake to create Makefile.in.
+
+include $(top_srcdir)/milena/tests/tests.mk
+
+check_PROGRAMS = \
+ fld2d \
+ fld1d \
+ fld3d
+
+fld2d_SOURCES = fld2d.cc
+fld3d_SOURCES = fld3d.cc
+fld1d_SOURCES = fld1d.cc
+
+TESTS = $(check_PROGRAMS)
\ No newline at end of file
Index: trunk/milena/tests/io/fld/fld1d.cc
===================================================================
--- trunk/milena/tests/io/fld/fld1d.cc (revision 0)
+++ trunk/milena/tests/io/fld/fld1d.cc (revision 4637)
@@ -0,0 +1,57 @@
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena 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 Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project 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.
+
+///
+/// \brief Test AVS field file IO with 1D image.
+///
+///
+///
+
+#include <mln/core/image/image1d.hh>
+#include <mln/io/fld/load.hh>
+#include <mln/io/fld/save.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/debug/iota.hh>
+#include <mln/data/compare.hh>
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+
+ image1d<int_u8> ori, test;
+ box<point1d> b(9);
+ ori.init_(b);
+ debug::iota(ori);
+
+ io::fld::save(ori, "out.fld");
+ io::fld::load(test, "out.fld");
+
+ // Clean output.
+ std::remove("out.fld");
+
+ mln_assertion(ori == test);
+}
Index: trunk/milena/tests/io/Makefile.am
===================================================================
--- trunk/milena/tests/io/Makefile.am (revision 4636)
+++ trunk/milena/tests/io/Makefile.am (revision 4637)
@@ -33,7 +33,8 @@
pgms \
pnm \
ppm \
- ppms
+ ppms \
+ fld
## ------------------------------------------------- ##
## I/O routines depending on a third-party library. ##