Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
fld/save.hh
1 // Copyright (C) 2008, 2009, 2010 EPITA Research and Development
2 // 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_SAVE_HH
28 # define MLN_IO_FLD_SAVE_HH
29 
34 
35 # include <fstream>
36 
37 # include <mln/core/concept/image.hh>
38 # include <mln/core/concept/gpoint.hh>
39 # include <mln/io/fld/header.hh>
40 # include <mln/io/fld/write_header.hh>
41 # include <mln/io/fld/max_components.hh>
42 
43 # include <mln/algebra/vec.hh>
44 
45 # include <mln/geom/bbox.hh>
46 
47 namespace mln
48 {
49 
50  namespace io
51  {
52 
53  namespace fld
54  {
55 
56  template <typename I>
57  void save(const Image<I>& ima_, const char* filename);
58 
59 
60 # ifndef MLN_INCLUDE_ONLY
61 
62  namespace internal
63  {
64  template <typename I>
65  inline
66  void save_data_contiguous(std::ofstream& file, const I& ima)
67  {
68  typedef mln_site(I) P;
69  typedef mln_value(I) V;
70  enum { dim = P::dim };
71 
72  P pmin = ima.domain().pmin();
73  P pmax = ima.domain().pmax();
74 
75  std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
76  std::size_t n = len * sizeof(V);
77  P p = pmin;
78  if (dim == 1)
79  {
80  file.write((char*)(&ima(p)), n);
81  return;
82  }
83 
84  while (true)
85  {
86  file.write((char*)(&ima(p)), n);
87  ++p[dim - 2];
88 
89  for (int i = dim - 2; p[i] > pmax[i]; --i)
90  {
91  if (i == 0)
92  return;
93  p[i] = pmin[i];
94  ++p[i - 1];
95  }
96  }
97  }
98 
99  template <typename I>
100  inline
101  fld::fld_header make_header(const I& ima)
102  {
103  fld_header hdr;
104  typedef mln_site(I) P;
105  typedef mln_value(I) V;
106  enum { dim = P::dim };
107 
108  hdr.ndim = dim;
109  hdr.nspace = dim;
110  hdr.veclen = mln_dim(V);
111  hdr.dim = new int[dim];
112  hdr.min_ext = new float[dim];
113  hdr.max_ext = new float[dim];
114 
115  box<P> bbox = geom::bbox(ima);
116  P pmin = bbox.pmin();
117  P pmax = bbox.pmax();
118 
119  for (unsigned i = 0; i < dim; i++)
120  {
121  hdr.dim[i] = pmax[i] - pmin[i] + 1;
122  hdr.min_ext[i] = pmin[i];
123  hdr.max_ext[i] = pmax[i];
124  }
125 
126  unsigned max_c = max_component(V ());
127  if (max_c == max_component(data_type::BYTE))
128  hdr.data = data_type::BYTE;
129  else if (max_c == max_component(data_type::SHORT))
130  hdr.data = data_type::SHORT;
131  else if (max_c == max_component(data_type::INTEGER))
132  hdr.data = data_type::INTEGER;
133  else if (max_c == max_component(data_type::FLOAT))
134  hdr.data = data_type::FLOAT;
135  else if (max_c == max_component(data_type::DOUBLE))
136  hdr.data = data_type::DOUBLE;
137  else
138  hdr.data = data_type::UNKNOWN;
139 
140  hdr.field = field_type::UNIFORM;
141 
142  return hdr;
143  }
144 
145  } // end of namespace mln::io::fld::internal
146 
147  template <typename I>
148  void save(const Image<I>& ima_, const char* filename)
149  {
150  trace::entering("mln::io::fld::save");
151  // For the moment, just the fast version.
152  mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
153 
154  const I& ima = exact(ima_);
155  mln_precondition(ima.is_valid());
156 
157  std::ofstream file(filename);
158  fld_header hdr = internal::make_header(ima);
159 
160  write_header(file, hdr);
161  internal::save_data_contiguous(file, ima);
162 
163  file.close();
164  trace::exiting("mln::io::fld::save");
165  }
166 
167 
168 # endif // ! MLN_INCLUDE_ONLY
169 
170  } // end of namespace mln::io::fld
171 
172  } // end of namespace mln::io
173 
174 } // end of namespace mln
175 #endif // !MLN_IO_FLD_SAVE_HH