00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 void
00088 abort_load(const char* msg, const char* filename)
00089 {
00090 std::cerr << "Error: file '" << filename << "'"
00091 << "cannot be loaded." << std::endl
00092 << "Error description: " << msg << std::endl;
00093 abort();
00094 }
00095
00096
00097 template <unsigned int n>
00098 inline
00099 void read_value(std::ifstream& file, value::rgb<n>& v)
00100 {
00101 typedef typename value::int_u<n>::enc E;
00102
00103 E c;
00104 file.read((char*)(&c), sizeof(E));
00105 v.red() = c;
00106 file.read((char*)(&c), sizeof(E));
00107 v.green() = c;
00108 file.read((char*)(&c), sizeof(E));
00109 v.blue() = c;
00110 }
00111
00112
00113 template <class V>
00114 inline
00115 void read_value(std::ifstream& file, value::Scalar<V>& v)
00116 {
00117 typedef typename V::enc E;
00118
00119 E c;
00120 file.read((char*)(&c), sizeof(E));
00121 exact(v) = c;
00122 }
00123
00124
00125 template <typename V>
00126 inline
00127 void read_value(std::ifstream& file, V& v)
00128 {
00129 V c;
00130 file.read((char*)(&c), sizeof(V));
00131 v = c;
00132 }
00133
00134
00135 template <typename I>
00136 inline
00137 void load_raw_uncontiguous(std::ifstream& file, I& ima)
00138 {
00139 mln_piter(I) p(ima.domain());
00140 read_value(file, ima(p));
00141 }
00142
00143
00144 template <typename I>
00145 inline
00146 void load_raw_contiguous(std::ifstream& file, I& ima)
00147 {
00148 mln_site(I) pmin = ima.domain().pmin();
00149 mln_site(I) pmax = ima.domain().pmax();
00150
00151 typedef mln_site(I) P;
00152 enum { dim = P::dim };
00153
00154
00155 typedef mln_value(I) V;
00156
00157
00158 std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
00159 std::size_t n = len * sizeof(V);
00160
00161 P p = pmin;
00162 if (dim == 1)
00163 {
00164 file.read((char*)(&ima(p)), n);
00165 return;
00166 }
00167
00168 while (true)
00169 {
00170 file.read((char*)(&ima(p)), n);
00171 ++p[dim - 2];
00172
00173 for (int i = dim - 2; p[i] > pmax[i]; --i)
00174 {
00175 if (i == 0)
00176 return;
00177 p[i] = pmin[i];
00178 ++p[i - 1];
00179 }
00180 }
00181 }
00182
00183 template <typename I>
00184 inline
00185 void load_raw(std::ifstream& file, I& ima)
00186 {
00187 if (sizeof(value::int_u8) == 1)
00188 load_raw_contiguous(file, ima);
00189 else
00190 load_raw_uncontiguous(file, ima);
00191 }
00192
00193 }
00194
00195 template <typename I>
00196 inline
00197 void
00198 load(Image<I>& ima_, const char* filename)
00199 {
00200 trace::entering("mln::io::fld::load");
00201
00202 std::ifstream file(filename);
00203 if (! file)
00204 internal::abort_load("Fail to open the file.", filename);
00205
00206 typedef mln_value(I) V;
00207 typedef mln_site(I) P;
00208
00209 I& ima = exact(ima_);
00210 fld_header hder = fld::read_header(file);
00211 int nspace = P::dim;
00212 int veclen = mln_dim(V);
00213
00214 if (nspace != hder.nspace)
00215 internal::abort_load("The dimension of the input does not match the one from the file.", filename);
00216 if (nspace > 3)
00217 internal::abort_load("The loader does not handle image dimension greater than three.", filename);
00218 if (veclen != hder.veclen)
00219 internal::abort_load("The dimension of the value does not match the one from the file.", filename);
00220 if (max_component(V ()) != max_component(hder.data))
00221 internal::abort_load("The data type of the input mismatches the one from the file.", filename);
00222
00223 box<mln_site(I)> bbox;
00224 for (int i = 0; i < hder.ndim; ++i)
00225 {
00226 convert::from_to(hder.min_ext[i], bbox.pmin()[i]);
00227 convert::from_to(hder.max_ext[i], bbox.pmax()[i]);
00228 }
00229
00230 ima.init_(bbox);
00231 internal::load_raw(file, ima);
00232
00233 file.close();
00234 trace::exiting("mln::io::fld::load");
00235 }
00236
00237 # endif // ! MLN_INCLUDE_ONLY
00238
00239 }
00240
00241 }
00242
00243 }
00244
00245 #endif // !MLN_IO_FLD_LOAD_HH