• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

load.hh

00001 // Copyright (C) 2008, 2009, 2010 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         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         // Read a Milena rgb value (sizeof(int_u8) != 1).
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         // Read a Milena scalar value (sizeof(int_u8) != 1).
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         // Read a builtin scalar value.
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         // used when (sizeof(int_u8) != 1)
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         // used in g++ > 2.95
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           // The first array index varies most quickly (FORTRAN-style).
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       } // end of mln::io::internal
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     } // end of namespace mln::io::fld
00240 
00241   } // end of namespace mln::io
00242 
00243 } // end of namespace mln
00244 
00245 #endif // !MLN_IO_FLD_LOAD_HH

Generated on Tue Oct 4 2011 15:24:02 for Milena (Olena) by  doxygen 1.7.1