$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fld/load_header.hh
1 // Copyright (C) 2008, 2009, 2011, 2012 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_LOAD_HEADER_HH
28 # define MLN_IO_FLD_LOAD_HEADER_HH
29 
34 
35 # include <mln/io/fld/header.hh>
36 # include <cstdlib>
37 # include <locale>
38 # include <iostream>
39 # include <sstream>
40 # include <string>
41 
42 namespace mln
43 {
44 
45  namespace io
46  {
47 
48  namespace fld
49  {
50 
59  fld_header read_header(std::istream& ins);
60 
61 # ifndef MLN_INCLUDE_ONLY
62 
63  namespace internal
64  {
65 
66  inline
67  void
68  abort_fld_reader(const char* msg, unsigned line = 0)
69  {
70  std::cerr << "AVS field file reader: " << msg << " on line " << line << std::endl;
71  abort();
72  }
73 
74  }
75 
76  inline
77  fld_header
78  read_header(std::istream& file)
79  {
80  std::stringstream ins;
81  std::string line_str, lhs, rhs;
82  fld_header header;
83  unsigned line;
84 
85  std::getline(file, line_str);
86  line = 1;
87  if (line_str.compare(0, 5, "# AVS"))
88  internal::abort_fld_reader("Invalid format", line);
89 
90  while (file.good() && file.peek() != '\f')
91  {
92  std::getline(file, line_str);
93  ++line;
94 
95  ins.clear();
96  ins.str(line_str);
97  rhs.clear();
98  lhs.clear();
99 
100  { // Parse the line
101  char c = ins.get();
102  while (isspace(c))
103  ins.get(c);
104  if (c == '#') // Comments
105  continue;
106  while (isalnum(c) || c == '_')
107  {
108  lhs.push_back(c);
109  ins.get(c);
110  }
111  while (isspace(c))
112  ins.get(c);
113  if (c != '=')
114  internal::abort_fld_reader("Parse error", line);
115  while (isspace(ins.peek()))
116  ins.ignore();
117  }
118 
119  if (lhs == "ndim")
120  {
121  ins >> header.ndim;
122  if (header.ndim < 1)
123  internal::abort_fld_reader("Invalid dimension", line);
124  header.dim = new int[header.ndim];
125  std::fill(header.dim, header.dim + header.ndim, -1);
126  }
127  else if (lhs.compare(0, 3, "dim") == 0)
128  {
129  std::stringstream ss(lhs.substr(3));
130  int dim;
131  ss >> dim;
132  if (dim < 1 || dim > header.ndim)
133  internal::abort_fld_reader("Invalid dimension", line);
134  if (!ss.eof())
135  internal::abort_fld_reader("Parse error", line);
136  ins >> header.dim[dim - 1];
137  if (header.dim[dim - 1] < 1)
138  internal::abort_fld_reader("Invalid dimension", line);
139  }
140  else if (lhs == "nspace")
141  {
142  ins >> header.nspace;
143  if (header.nspace < 1)
144  internal::abort_fld_reader("Invalid space dimension", line);
145  header.min_ext = new float[header.nspace];
146  header.max_ext = new float[header.nspace];
147  }
148  else if (lhs == "veclen")
149  {
150  ins >> header.veclen;
151  if (header.veclen == -1)
152  internal::abort_fld_reader("Invalid vector length", line);
153  }
154  else if (lhs == "data")
155  {
156  ins >> rhs;
157  if (rhs == "byte")
158  header.data = data_type::BYTE;
159  else if (rhs == "short")
160  header.data = data_type::SHORT;
161  else if (rhs == "integer")
162  header.data = data_type::INTEGER;
163  else if (rhs == "float")
164  header.data = data_type::FLOAT;
165  else if (rhs == "double")
166  header.data = data_type::DOUBLE;
167  else
168  internal::abort_fld_reader("Invalid data type", line);
169  }
170  else if (lhs == "field")
171  {
172  ins >> rhs;
173  if (rhs != "uniform")
174  internal::abort_fld_reader("Unhandled field type", line);
175  header.field = field_type::UNIFORM;
176  }
177  else if (lhs == "min_ext")
178  {
179  for (int i = 0; i < header.ndim; ++i)
180  {
181  ins >> header.min_ext[i];
182  if (ins.peek() == ',')
183  ins.ignore();
184  }
185  }
186  else if (lhs == "max_ext")
187  {
188  for (int i = 0; i < header.ndim; ++i)
189  {
190  ins >> header.max_ext[i];
191  if (ins.peek() == ',')
192  ins.ignore();
193  }
194  }
195  else
196  internal::abort_fld_reader("Parse error", line);
197 
198  rhs.clear();
199  ins >> rhs;
200  if (!rhs.empty() && rhs[0] != '#')
201  internal::abort_fld_reader("Parse error", line);
202  }
203 
204  file.ignore();
205  if (file.get() != '\f')
206  internal::abort_fld_reader("Parse error", line);
207 
208  if (header.ndim == -1 || header.nspace == -1 || header.veclen == -1 ||
209  header.data == data_type::UNKNOWN || header.field == field_type::UNKNOWN)
210  internal::abort_fld_reader("Invalid format", line);
211  for (int i = 0; i < header.ndim; ++i)
212  if (header.dim[i] == -1)
213  internal::abort_fld_reader("Invalid format", line);
214  return header;
215  }
216 
217 # endif // ! MLN_INCLUDE_ONLY
218 
219  } // end of namespace mln::io::fld
220 
221  } // end of namespace mln::io
222 
223 } // end of namespace mln
224 
225 #endif // !MLN_IO_FLD_LOAD_HEADER_HH