Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
dump/load.hh
1 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef MLN_IO_DUMP_LOAD_HH
27 # define MLN_IO_DUMP_LOAD_HH
28 
32 
33 # include <iostream>
34 # include <fstream>
35 
36 # include <mln/core/concept/image.hh>
37 # include <mln/core/routine/initialize.hh>
38 # include <mln/core/box_runstart_piter.hh>
39 # include <mln/core/pixel.hh>
40 # include <mln/data/memcpy_.hh>
41 
42 namespace mln
43 {
44 
45  namespace io
46  {
47 
48  namespace dump
49  {
50 
55  template <typename I>
56  void load(Image<I>& ima_, const std::string& filename);
57 
58 
59 # ifndef MLN_INCLUDE_ONLY
60 
61  namespace internal
62  {
63 
64  template <typename P>
65  inline
66  void read_point(std::ifstream& file, P& p)
67  {
68  char tmp[sizeof (P)];
69  file.read(tmp, sizeof (P));
70  p = *(P*)(void*)(&tmp);
71  }
72 
73 
74  template <typename I>
75  inline
76  void load_header(Image<I>& ima, std::ifstream& file,
77  const std::string& filename)
78  {
79  // Milena's file type ?
80  std::string file_type;
81  file >> file_type;
82  if (file_type != "milena/dump")
83  {
84  std::cerr << "io::dump::load - Error: invalid file type. '"
85  << filename
86  << "' is NOT a valid milena/dump file!"
87  << std::endl;
88  abort();
89  }
90 
91  // Dimension ?
92  unsigned dim;
93  file >> dim;
94  typedef mln_site(I) P;
95  if (P::dim != dim)
96  {
97  std::cerr << "io::dump::load - Error: invalid image dimension. '"
98  << filename << "' is a " << dim << "-D image "
99  << "but you try to load it into a " << P::dim
100  << "-D image!"
101  << std::endl;
102  abort();
103  }
104 
105  // Size information - Skip it, useless.
106  std::string tmp;
107  for (unsigned i = 0; i < dim; ++i)
108  file >> tmp;
109  // Skipping endline.
110  char c;
111  file.get(c);
112 
113  // Value type name ?
114  // WARNING: value type name limited to 255 characters...
115  char value_type[255];
116  file.getline(value_type, 255);
117  if (mln_trait_value_name(mln_value(I)) != std::string(value_type))
118  {
119  std::cerr << "io::dump::load - Error: invalid image value type. '"
120  << filename << "' is an image of '" << value_type
121  << "' but you try to load it into an image of '"
122  << mln_trait_value_name(mln_value(I)) << "'!"
123  << std::endl;
124  abort();
125  }
126 
127  // Empty line - may be used for a new information.
128  file.get(c);
129 
130  // Empty line - may be used for a new information.
131  file.get(c);
132 
133  // Pmin
134  P pmin;
135  read_point<P>(file, pmin);
136 
137  // Pmax
138  P pmax;
139  read_point<P>(file, pmax);
140 
141  // Initialize the image buffer.
142  mln_concrete(I) result(box<P>(pmin, pmax));
143  initialize(ima, result);
144  mln_assertion(exact(ima).is_valid());
145  }
146 
147 
148  template <typename I>
149  inline
150  void load_data(Image<I>& ima_, std::ifstream& file)
151  {
152  I& ima = exact(ima_);
153 
154  // Handle padding.
155  unsigned data_size = sizeof (mln_value(I)) + sizeof (mln_value(I)) % 2;
156 
157  mln_box_runstart_piter(I) p(ima.domain());
158  for_all(p)
159  {
160  pixel<I> src(ima, p);
161  file.read((char*) (&src.val()), p.run_length() * data_size);
162  }
163 
164  }
165 
166  } // end of namespace mln::io::dump::internal
167 
168 
169 
170  template <typename I>
171  void load(Image<I>& ima, const std::string& filename)
172  {
173  trace::entering("mln::io::dump::load");
174 
175  std::ifstream file(filename.c_str());
176  if (! file)
177  {
178  std::cerr << "io::dump::load - Error: cannot open file '"
179  << filename << "'!"
180  << std::endl;
181  abort();
182  }
183 
184  internal::load_header(ima, file, filename);
185  internal::load_data(ima, file);
186 
187  mln_postcondition(exact(ima).is_valid());
188 
189  trace::exiting("mln::io::dump::load");
190  }
191 
192 
193 # endif // ! MLN_INCLUDE_ONLY
194 
195  } // end of namespace mln::io::dump
196 
197  } // end of namespace mln::io
198 
199 } // end of namespace mln
200 
201 #endif // ! MLN_IO_DUMP_LOAD_HH