Milena (Olena)  User documentation 2.0a Id
load.hh
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
 All Classes Namespaces Functions Variables Typedefs Enumerator