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 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
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
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
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
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
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
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 }
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 }
00241
00242 }
00243
00244 }
00245
00246 #endif // !MLN_IO_FLD_LOAD_HH