Milena (Olena)
User documentation 2.0a Id
|
00001 // Copyright (C) 2008, 2009, 2010, 2011 EPITA Research and Development 00002 // Laboratory (LRDE) 00003 // 00004 // This file is part of Olena. 00005 // 00006 // Olena is free software: you can redistribute it and/or modify it under 00007 // the terms of the GNU General Public License as published by the Free 00008 // Software Foundation, version 2 of the License. 00009 // 00010 // Olena is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Olena. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software project without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to produce 00022 // an executable, this file does not by itself cause the resulting 00023 // executable to be covered by the GNU General Public License. This 00024 // exception does not however invalidate any other reasons why the 00025 // executable file might be covered by the GNU General Public License. 00026 00027 #ifndef MLN_IO_FLD_LOAD_HH 00028 # define MLN_IO_FLD_LOAD_HH 00029 00046 00047 # include <fstream> 00048 # include <iostream> 00049 00050 # include <mln/core/concept/image.hh> 00051 # include <mln/io/fld/header.hh> 00052 # include <mln/io/fld/load_header.hh> 00053 # include <mln/io/fld/max_components.hh> 00054 00055 # include <mln/algebra/vec.hh> 00056 # include <mln/value/rgb.hh> 00057 # include <mln/value/int_u8.hh> 00058 00059 # include <mln/geom/nsites.hh> 00060 00061 # include <mln/convert/from_to.hh> 00062 00063 namespace mln 00064 { 00065 00066 namespace io 00067 { 00068 00069 namespace fld 00070 { 00071 00077 template <typename I> 00078 inline 00079 void 00080 load(Image<I>& ima_, const char* filename); 00081 00082 # ifndef MLN_INCLUDE_ONLY 00083 00084 namespace internal 00085 { 00086 00087 inline 00088 void 00089 abort_load(const char* msg, const char* filename) 00090 { 00091 std::cerr << "Error: file '" << filename << "'" 00092 << "cannot be loaded." << std::endl 00093 << "Error description: " << msg << std::endl; 00094 abort(); 00095 } 00096 00097 // Read a Milena rgb value (sizeof(int_u8) != 1). 00098 template <unsigned int n> 00099 inline 00100 void read_value(std::ifstream& file, value::rgb<n>& v) 00101 { 00102 typedef typename value::int_u<n>::enc E; 00103 00104 E c; 00105 file.read((char*)(&c), sizeof(E)); 00106 v.red() = c; 00107 file.read((char*)(&c), sizeof(E)); 00108 v.green() = c; 00109 file.read((char*)(&c), sizeof(E)); 00110 v.blue() = c; 00111 } 00112 00113 // Read a Milena scalar value (sizeof(int_u8) != 1). 00114 template <class V> 00115 inline 00116 void read_value(std::ifstream& file, value::Scalar<V>& v) 00117 { 00118 typedef typename V::enc E; 00119 00120 E c; 00121 file.read((char*)(&c), sizeof(E)); 00122 exact(v) = c; 00123 } 00124 00125 // Read a builtin scalar value. 00126 template <typename V> 00127 inline 00128 void read_value(std::ifstream& file, V& v) 00129 { 00130 V c; 00131 file.read((char*)(&c), sizeof(V)); 00132 v = c; 00133 } 00134 00135 // used when (sizeof(int_u8) != 1) 00136 template <typename I> 00137 inline 00138 void load_raw_uncontiguous(std::ifstream& file, I& ima) 00139 { 00140 mln_piter(I) p(ima.domain()); 00141 read_value(file, ima(p)); 00142 } 00143 00144 // used in g++ > 2.95 00145 template <typename I> 00146 inline 00147 void load_raw_contiguous(std::ifstream& file, I& ima) 00148 { 00149 mln_site(I) pmin = ima.domain().pmin(); 00150 mln_site(I) pmax = ima.domain().pmax(); 00151 00152 typedef mln_site(I) P; 00153 enum { dim = P::dim }; 00154 00155 // The first array index varies most quickly (FORTRAN-style). 00156 typedef mln_value(I) V; 00157 00158 00159 std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1; 00160 std::size_t n = len * sizeof(V); 00161 00162 P p = pmin; 00163 if (dim == 1) 00164 { 00165 file.read((char*)(&ima(p)), n); 00166 return; 00167 } 00168 00169 while (true) 00170 { 00171 file.read((char*)(&ima(p)), n); 00172 ++p[dim - 2]; 00173 00174 for (int i = dim - 2; p[i] > pmax[i]; --i) 00175 { 00176 if (i == 0) 00177 return; 00178 p[i] = pmin[i]; 00179 ++p[i - 1]; 00180 } 00181 } 00182 } 00183 00184 template <typename I> 00185 inline 00186 void load_raw(std::ifstream& file, I& ima) 00187 { 00188 if (sizeof(value::int_u8) == 1) 00189 load_raw_contiguous(file, ima); 00190 else 00191 load_raw_uncontiguous(file, ima); 00192 } 00193 00194 } // end of mln::io::internal 00195 00196 template <typename I> 00197 inline 00198 void 00199 load(Image<I>& ima_, const char* filename) 00200 { 00201 trace::entering("mln::io::fld::load"); 00202 00203 std::ifstream file(filename); 00204 if (! file) 00205 internal::abort_load("Fail to open the file.", filename); 00206 00207 typedef mln_value(I) V; 00208 typedef mln_site(I) P; 00209 00210 I& ima = exact(ima_); 00211 fld_header hder = fld::read_header(file); 00212 int nspace = P::dim; 00213 int veclen = mln_dim(V); 00214 00215 if (nspace != hder.nspace) 00216 internal::abort_load("The dimension of the input does not match the one from the file.", filename); 00217 if (nspace > 3) 00218 internal::abort_load("The loader does not handle image dimension greater than three.", filename); 00219 if (veclen != hder.veclen) 00220 internal::abort_load("The dimension of the value does not match the one from the file.", filename); 00221 if (max_component(V ()) != max_component(hder.data)) 00222 internal::abort_load("The data type of the input mismatches the one from the file.", filename); 00223 00224 box<mln_site(I)> bbox; 00225 for (int i = 0; i < hder.ndim; ++i) 00226 { 00227 convert::from_to(hder.min_ext[i], bbox.pmin()[i]); 00228 convert::from_to(hder.max_ext[i], bbox.pmax()[i]); 00229 } 00230 00231 ima.init_(bbox); 00232 internal::load_raw(file, ima); 00233 00234 file.close(); 00235 trace::exiting("mln::io::fld::load"); 00236 } 00237 00238 # endif // ! MLN_INCLUDE_ONLY 00239 00240 } // end of namespace mln::io::fld 00241 00242 } // end of namespace mln::io 00243 00244 } // end of namespace mln 00245 00246 #endif // !MLN_IO_FLD_LOAD_HH