
* milena/mln/io/raw/all.hh, * milena/mln/io/raw/get_header.hh, * milena/mln/io/raw/load.hh, * milena/mln/io/raw/save.hh: New. --- milena/ChangeLog | 9 +++ milena/mln/io/{dump => raw}/all.hh | 20 +++--- milena/mln/io/raw/get_header.hh | 135 +++++++++++++++++++++++++++++++++++ milena/mln/io/{dump => raw}/load.hh | 99 ++++++++++++++++---------- milena/mln/io/{dump => raw}/save.hh | 72 ++++++++++++------- 5 files changed, 262 insertions(+), 73 deletions(-) copy milena/mln/io/{dump => raw}/all.hh (76%) create mode 100644 milena/mln/io/raw/get_header.hh copy milena/mln/io/{dump => raw}/load.hh (64%) copy milena/mln/io/{dump => raw}/save.hh (65%) diff --git a/milena/ChangeLog b/milena/ChangeLog index 8d21753..f2af5eb 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,14 @@ 2010-02-16 Guillaume Lazzara <z@lrde.epita.fr> + First draft of raw format support. + + * milena/mln/io/raw/all.hh, + * milena/mln/io/raw/get_header.hh, + * milena/mln/io/raw/load.hh, + * milena/mln/io/raw/save.hh: New. + +2010-02-16 Guillaume Lazzara <z@lrde.epita.fr> + Add new 3D neighborhoods and windows. * milena/mln/core/alias/neighb3d.hh, diff --git a/milena/mln/io/dump/all.hh b/milena/mln/io/raw/all.hh similarity index 76% copy from milena/mln/io/dump/all.hh copy to milena/mln/io/raw/all.hh index ae405e8..48d5c3c 100644 --- a/milena/mln/io/dump/all.hh +++ b/milena/mln/io/raw/all.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -23,11 +24,11 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_IO_DUMP_ALL_HH -# define MLN_IO_DUMP_ALL_HH +#ifndef MLN_IO_RAW_ALL_HH +# define MLN_IO_RAW_ALL_HH /// \file -/// \brief Inclusion of all dump I/O routines. +/// \brief Inclusion of all raw I/O routines. namespace mln @@ -35,13 +36,14 @@ namespace mln namespace io { - /// Namespace of dump input/output handling. - namespace dump {} + /// Namespace of raw input/output handling. + namespace raw {} } } -# include <mln/io/dump/load.hh> -# include <mln/io/dump/save.hh> +# include <mln/io/raw/get_header.hh> +# include <mln/io/raw/load.hh> +# include <mln/io/raw/save.hh> -#endif // ! MLN_IO_DUMP_ALL_HH +#endif // ! MLN_IO_RAW_ALL_HH diff --git a/milena/mln/io/raw/get_header.hh b/milena/mln/io/raw/get_header.hh new file mode 100644 index 0000000..fa5dbf3 --- /dev/null +++ b/milena/mln/io/raw/get_header.hh @@ -0,0 +1,135 @@ +// Copyright (C) 2010 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_RAW_GET_HEADER_HH +# define MLN_IO_RAW_GET_HEADER_HH + +/// \file +/// +/// Load a Milena image rawed into a file. + +# include <iostream> +# include <fstream> + +# include <mln/core/concept/image.hh> +# include <mln/core/routine/initialize.hh> +# include <mln/core/box_runstart_piter.hh> +# include <mln/core/pixel.hh> +# include <mln/data/memcpy_.hh> + +namespace mln +{ + + namespace io + { + + namespace raw + { + + /// Store raw file header. + struct raw_header + { + unsigned dim; + std::string value_type; + util::array<unsigned> size; + }; + + + /// Retrieve header in a raw file. + raw_header get_header(const std::string& filename); + + +# ifndef MLN_INCLUDE_ONLY + + + raw_header get_header(const std::string& filename) + { + trace::entering("mln::io::raw::get_header"); + + raw_header header; + + std::string info_filename = filename + ".info"; + + std::ifstream info_file(info_filename.c_str()); + if (! info_file) + { + std::cerr << "io::raw::get_header - Error: cannot open file '" + << filename << "'!" + << std::endl; + abort(); + } + + std::string file_type; + info_file >> file_type; + if (file_type != "milena/raw") + { + std::cerr << "io::raw::load - Error: invalid file type. '" + << filename + << "' is NOT a valid milena/raw info file!" + << std::endl; + abort(); + } + + char dev_null[30]; + + // Dimension ? + // Reading line title "Dim: " + info_file.read(dev_null, 5); + info_file >> header.dim; + + // Size information - Skip it, useless. + header.size.resize(header.dim); + for (unsigned i = 0; i < header.dim; ++i) + info_file >> header.size[i]; + // Skipping endline. + char c; + info_file.get(c); + + + // Value type name ? + // Reading line title "data type: " + info_file.read(dev_null, 11); + // WARNING: value type name limited to 255 characters... + char value_type[255]; + info_file.getline(value_type, 255); + header.value_type = value_type; + + info_file.close(); + + trace::exiting("mln::io::raw::get_header"); + return header; + } + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::io::raw + + } // end of namespace mln::io + +} // end of namespace mln + +#endif // ! MLN_IO_RAW_GET_HEADER_HH + diff --git a/milena/mln/io/dump/load.hh b/milena/mln/io/raw/load.hh similarity index 64% copy from milena/mln/io/dump/load.hh copy to milena/mln/io/raw/load.hh index ab9892b..7715740 100644 --- a/milena/mln/io/dump/load.hh +++ b/milena/mln/io/raw/load.hh @@ -1,4 +1,5 @@ -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory +// (LRDE) // // This file is part of Olena. // @@ -23,12 +24,12 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_IO_DUMP_LOAD_HH -# define MLN_IO_DUMP_LOAD_HH +#ifndef MLN_IO_RAW_LOAD_HH +# define MLN_IO_RAW_LOAD_HH /// \file /// -/// Load a Milena image dumped into a file. +/// Load an image saved as a raw data file. # include <iostream> # include <fstream> @@ -45,13 +46,19 @@ namespace mln namespace io { - namespace dump + namespace raw { - /// Load a Milena image by dumped into a file. + /// Load an image saved as a raw data file. /// /// \param[in,out] ima_ The image to load. /// \param[in] filename the destination. + /// + /// This routine try to read two input files: 'filename' and + /// 'filename.info'. + /// 'filename' is the raw data. + /// 'filename.info' store various information about the image. + // template <typename I> void load(Image<I>& ima_, const std::string& filename); @@ -65,36 +72,41 @@ namespace mln inline void read_point(std::ifstream& file, P& p) { - char tmp[sizeof (P)]; - file.read(tmp, sizeof (P)); - p = *(P*)(void*)(&tmp); + for (unsigned i = 0; i < P::dim; ++i) + file >> p[i]; } template <typename I> inline - void load_header(Image<I>& ima, std::ifstream& file, + void load_header(Image<I>& ima, std::ifstream& info_file, const std::string& filename) { // Milena's file type ? std::string file_type; - file >> file_type; - if (file_type != "milena/dump") + info_file >> file_type; + if (file_type != "milena/raw") { - std::cerr << "io::dump::load - Error: invalid file type. '" + std::cerr << "io::raw::load - Error: invalid file type. '" << filename - << "' is NOT a valid milena/dump file!" + << "' is NOT a valid milena/raw info file!" << std::endl; abort(); } + char dev_null[255]; + // Dimension ? + // Reading line title "Dim: " + info_file.read(dev_null, 5); + unsigned dim; - file >> dim; + info_file >> dim; + typedef mln_site(I) P; if (P::dim != dim) { - std::cerr << "io::dump::load - Error: invalid image dimension. '" + std::cerr << "io::raw::load - Error: invalid image dimension. '" << filename << "' is a " << dim << "-D image " << "but you try to load it into a " << P::dim << "-D image!" @@ -105,18 +117,20 @@ namespace mln // Size information - Skip it, useless. std::string tmp; for (unsigned i = 0; i < dim; ++i) - file >> tmp; + info_file >> tmp; // Skipping endline. char c; - file.get(c); + info_file.get(c); // Value type name ? + // Reading line title "data type: " + info_file.read(dev_null, 11); // WARNING: value type name limited to 255 characters... char value_type[255]; - file.getline(value_type, 255); + info_file.getline(value_type, 255); if (mln_trait_value_name(mln_value(I)) != std::string(value_type)) { - std::cerr << "io::dump::load - Error: invalid image value type. '" + std::cerr << "io::raw::load - Error: invalid image value type. '" << filename << "' is an image of '" << value_type << "' but you try to load it into an image of '" << mln_trait_value_name(mln_value(I)) << "'!" @@ -124,19 +138,18 @@ namespace mln abort(); } - // Empty line - may be used for a new information. - file.get(c); - - // Empty line - may be used for a new information. - file.get(c); - // Pmin + // Reading line title "top left: " + info_file.read(dev_null, 10); P pmin; - read_point<P>(file, pmin); + read_point<P>(info_file, pmin); // Pmax + // Reading line title "bottom right: " + info_file.read(dev_null, 14); P pmax; - read_point<P>(file, pmax); + read_point<P>(info_file, pmax); + std::cout << pmax << std::endl; // Initialize the image buffer. mln_concrete(I) result(box<P>(pmin, pmax)); @@ -163,39 +176,51 @@ namespace mln } - } // end of namespace mln::io::dump::internal + } // end of namespace mln::io::raw::internal template <typename I> void load(Image<I>& ima, const std::string& filename) { - trace::entering("mln::io::dump::load"); + trace::entering("mln::io::raw::load"); std::ifstream file(filename.c_str()); if (! file) { - std::cerr << "io::dump::load - Error: cannot open file '" - << filename << "'!" - << std::endl; + std::cerr << "io::raw::load - error: cannot open file '" + << filename << "'!"; abort(); } - internal::load_header(ima, file, filename); + std::string info_filename = filename + ".info"; + std::ifstream info_file(info_filename.c_str()); + if (! info_file) + { + std::cerr << "io::raw::load - error: cannot open file '" + << info_filename << "'!"; + abort(); + } + + + internal::load_header(ima, info_file, info_filename); internal::load_data(ima, file); mln_postcondition(exact(ima).is_valid()); - trace::exiting("mln::io::dump::load"); + file.close(); + info_file.close(); + + trace::exiting("mln::io::raw::load"); } # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::io::dump + } // end of namespace mln::io::raw } // end of namespace mln::io } // end of namespace mln -#endif // ! MLN_IO_DUMP_LOAD_HH +#endif // ! MLN_IO_RAW_LOAD_HH diff --git a/milena/mln/io/dump/save.hh b/milena/mln/io/raw/save.hh similarity index 65% copy from milena/mln/io/dump/save.hh copy to milena/mln/io/raw/save.hh index a361856..f526e57 100644 --- a/milena/mln/io/dump/save.hh +++ b/milena/mln/io/raw/save.hh @@ -23,12 +23,12 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -#ifndef MLN_IO_DUMP_SAVE_HH -# define MLN_IO_DUMP_SAVE_HH +#ifndef MLN_IO_RAW_SAVE_HH +# define MLN_IO_RAW_SAVE_HH /// \file /// -/// Save a Milena image by dumping its data to a file. +/// Save a Milena image as a raw data file. /// /// \todo handle endianness. @@ -48,13 +48,18 @@ namespace mln namespace io { - namespace dump + namespace raw { - /// Save a Milena image by dumping its data to a file. + /// Save a Milena image as a raw data file. /// /// \param[in] ima_ The image to save. /// \param[in] filename the destination. + /// + /// This routine produce two output files: 'filename' and + /// 'filename.info'. + /// 'filename' is the raw data. + /// 'filename.info' store various information about the image. // template <typename I> void save(const Image<I>& ima_, const std::string& filename); @@ -69,15 +74,14 @@ namespace mln template <typename I> inline - void save_header(const I& ima, - std::ofstream& file) + void save_header(const I& ima, std::ofstream& file) { // Milena's file type - file << "milena/dump" << std::endl; + file << "milena/raw" << std::endl; // Dimension typedef mln_site(I) P; - file << P::dim << std::endl; + file << "dim: " << P::dim << std::endl; // Image size. typedef algebra::vec<P::dim, unsigned> vec_t; @@ -88,21 +92,20 @@ namespace mln // Value type name // WARNING: value type name limited to 255 characters... - file << mln_trait_value_name(mln_value(I)) << std::endl; - - // Empty line - may be used for a new information. - file << std::endl; - - // Empty line - may be used for a new information. - file << std::endl; + file << "data type: " << mln_trait_value_name(mln_value(I)) + << std::endl; // Pmin - mln_site(I) p = ima.domain().pmin(); - file.write((char*) (&p), sizeof (P)); + file << "top left: "; + for (unsigned i = 0; i < P::dim - 1; ++i) + file << ima.domain().pmin()[i] << " "; + file << ima.domain().pmin()[P::dim - 1] << std::endl; // Pmax - p = ima.domain().pmax(); - file.write((char*) (&p), sizeof (P)); + file << "bottom right: "; + for (unsigned i = 0; i < P::dim - 1; ++i) + file << ima.domain().pmax()[i] << " "; + file << ima.domain().pmax()[P::dim - 1] << std::endl; } @@ -111,7 +114,8 @@ namespace mln void save_data(I& ima, std::ofstream& file) { // Handle padding. - unsigned data_size = sizeof (mln_value(I)) + sizeof (mln_value(I)) % 2; + unsigned + data_size = sizeof (mln_value(I)) + sizeof (mln_value(I)) % 2; mln_box_runstart_piter(I) p(ima.domain()); for_all(p) @@ -121,7 +125,7 @@ namespace mln } } - } // end of namespace mln::io::dump::internal + } // end of namespace mln::io::raw::internal @@ -130,7 +134,9 @@ namespace mln template <typename I> void save(const Image<I>& ima_, const std::string& filename) { - trace::entering("mln::io::dump::save"); + trace::entering("mln::io::raw::save"); + + mlc_bool(mln_site_(I)::dim == 2 || mln_site_(I)::dim == 3)::check(); const I& ima = exact(ima_); @@ -141,19 +147,31 @@ namespace mln abort(); } - internal::save_header(ima, file); + std::string info_filename = filename + ".info"; + std::ofstream info_file(info_filename.c_str()); + if (! info_file) + { + std::cerr << "error: cannot open file '" << info_filename << "'!"; + abort(); + } + + + internal::save_header(ima, info_file); internal::save_data(ima, file); - trace::exiting("mln::io::dump::save"); + info_file.close(); + file.close(); + + trace::exiting("mln::io::raw::save"); } # endif // ! MLN_INCLUDE_ONLY - } // end of namespace mln::io::dump + } // end of namespace mln::io::raw } // end of namespace mln::io } // end of namespace mln -#endif // ! MLN_IO_DUMP_SAVE_HH +#endif // ! MLN_IO_RAW_SAVE_HH -- 1.5.6.5