$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fld/load.hh
1 // Copyright (C) 2008, 2009, 2010, 2011, 2012 EPITA Research and
2 // Development Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef MLN_IO_FLD_LOAD_HH
28 # define MLN_IO_FLD_LOAD_HH
29 
46 
47 # include <fstream>
48 # include <iostream>
49 
50 # include <mln/core/concept/image.hh>
51 # include <mln/io/fld/header.hh>
52 # include <mln/io/fld/load_header.hh>
53 # include <mln/io/fld/max_components.hh>
54 
55 # include <mln/algebra/vec.hh>
56 # include <mln/value/rgb.hh>
57 # include <mln/value/int_u8.hh>
58 
59 # include <mln/geom/nsites.hh>
60 
61 # include <mln/convert/from_to.hh>
62 
63 namespace mln
64 {
65 
66  namespace io
67  {
68 
69  namespace fld
70  {
71 
79  template <typename I>
80  inline
81  void
82  load(Image<I>& ima_, const char* filename);
83 
84 # ifndef MLN_INCLUDE_ONLY
85 
86  namespace internal
87  {
88 
89  inline
90  void
91  abort_load(const char* msg, const char* filename)
92  {
93  std::cerr << "Error: file '" << filename << "'"
94  << "cannot be loaded." << std::endl
95  << "Error description: " << msg << std::endl;
96  abort();
97  }
98 
99  // Read a Milena rgb value (sizeof(int_u8) != 1).
100  template <unsigned int n>
101  inline
102  void read_value(std::ifstream& file, value::rgb<n>& v)
103  {
104  typedef typename value::int_u<n>::enc E;
105 
106  E c;
107  file.read((char*)(&c), sizeof(E));
108  v.red() = c;
109  file.read((char*)(&c), sizeof(E));
110  v.green() = c;
111  file.read((char*)(&c), sizeof(E));
112  v.blue() = c;
113  }
114 
115  // Read a Milena scalar value (sizeof(int_u8) != 1).
116  template <class V>
117  inline
118  void read_value(std::ifstream& file, value::Scalar<V>& v)
119  {
120  typedef typename V::enc E;
121 
122  E c;
123  file.read((char*)(&c), sizeof(E));
124  exact(v) = c;
125  }
126 
127  // Read a builtin scalar value.
128  template <typename V>
129  inline
130  void read_value(std::ifstream& file, V& v)
131  {
132  V c;
133  file.read((char*)(&c), sizeof(V));
134  v = c;
135  }
136 
137  // used when (sizeof(int_u8) != 1)
138  template <typename I>
139  inline
140  void load_raw_uncontiguous(std::ifstream& file, I& ima)
141  {
142  mln_piter(I) p(ima.domain());
143  read_value(file, ima(p));
144  }
145 
146  // used in g++ > 2.95
147  template <typename I>
148  inline
149  void load_raw_contiguous(std::ifstream& file, I& ima)
150  {
151  mln_site(I) pmin = ima.domain().pmin();
152  mln_site(I) pmax = ima.domain().pmax();
153 
154  typedef mln_site(I) P;
155  enum { dim = P::dim };
156 
157  // The first array index varies most quickly (FORTRAN-style).
158  typedef mln_value(I) V;
159 
160 
161  std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
162  std::size_t n = len * sizeof(V);
163 
164  P p = pmin;
165  if (dim == 1)
166  {
167  file.read((char*)(&ima(p)), n);
168  return;
169  }
170 
171  while (true)
172  {
173  file.read((char*)(&ima(p)), n);
174  ++p[dim - 2];
175 
176  for (int i = dim - 2; p[i] > pmax[i]; --i)
177  {
178  if (i == 0)
179  return;
180  p[i] = pmin[i];
181  ++p[i - 1];
182  }
183  }
184  }
185 
186  template <typename I>
187  inline
188  void load_raw(std::ifstream& file, I& ima)
189  {
190  if (sizeof(value::int_u8) == 1)
191  load_raw_contiguous(file, ima);
192  else
193  load_raw_uncontiguous(file, ima);
194  }
195 
196  } // end of mln::io::internal
197 
198  template <typename I>
199  inline
200  void
201  load(Image<I>& ima_, const char* filename)
202  {
203  mln_trace("mln::io::fld::load");
204 
205  std::ifstream file(filename);
206  if (! file)
207  internal::abort_load("Fail to open the file.", filename);
208 
209  typedef mln_value(I) V;
210  typedef mln_site(I) P;
211 
212  I& ima = exact(ima_);
213  fld_header hder = fld::read_header(file);
214  int nspace = P::dim;
215  int veclen = mln_dim(V);
216 
217  if (nspace != hder.nspace)
218  internal::abort_load("The dimension of the input does not match the one from the file.", filename);
219  if (nspace > 3)
220  internal::abort_load("The loader does not handle image dimension greater than three.", filename);
221  if (veclen != hder.veclen)
222  internal::abort_load("The dimension of the value does not match the one from the file.", filename);
223  if (max_component(V ()) != max_component(hder.data))
224  internal::abort_load("The data type of the input mismatches the one from the file.", filename);
225 
226  box<mln_site(I)> bbox;
227  for (int i = 0; i < hder.ndim; ++i)
228  {
229  convert::from_to(hder.min_ext[i], bbox.pmin()[i]);
230  convert::from_to(hder.max_ext[i], bbox.pmax()[i]);
231  }
232 
233  ima.init_(bbox);
234  internal::load_raw(file, ima);
235 
236  file.close();
237  }
238 
239 # endif // ! MLN_INCLUDE_ONLY
240 
241  } // end of namespace mln::io::fld
242 
243  } // end of namespace mln::io
244 
245 } // end of namespace mln
246 
247 #endif // !MLN_IO_FLD_LOAD_HH