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

load.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
00025 
00026 #ifndef MLN_IO_PNM_LOAD_HH
00027 # define MLN_IO_PNM_LOAD_HH
00028 
00033 
00034 # include <iostream>
00035 # include <fstream>
00036 # include <string>
00037 
00038 # include <mln/core/image/image2d.hh>
00039 
00040 # include <mln/value/int_u8.hh>
00041 # include <mln/value/rgb.hh>
00042 
00043 # include <mln/io/pnm/load_header.hh>
00044 # include <mln/io/pnm/max_component.hh>
00045 # include <mln/io/pnm/macros.hh>
00046 
00047 # include <mln/metal/is_a.hh>
00048 
00049 namespace mln
00050 {
00051 
00052   namespace io
00053   {
00054 
00055     namespace pnm
00056     {
00057 
00058 
00059 # ifndef MLN_INCLUDE_ONLY
00060 
00061       template <typename I>
00062       void load_ascii_value(std::ifstream& file, I& ima);
00063 
00064       template <typename I>
00065       void load_ascii_builtin(std::ifstream& file, I& ima);
00066 
00067 
00068       namespace internal
00069       {
00070 
00071         template <typename I>
00072         inline
00073         void
00074         load_ascii_dispatch(std::ifstream& file, I& ima, const metal::bool_<true>&)
00075         {
00076           load_ascii_value(file, ima);
00077         }
00078 
00079         template <typename I>
00080         inline
00081         void
00082         load_ascii_dispatch(std::ifstream& file, I& ima, const metal::bool_<false>&)
00083         {
00084           load_ascii_builtin(file, ima);
00085         }
00086 
00087       } // end of namespace mln::io::pnm::internal
00088 
00089 
00090       // Read a Milena rgb value (sizeof(int_u8) != 1).
00091       template <unsigned int n>
00092       inline
00093       void read_value(std::ifstream& file, value::rgb<n>& v)
00094       {
00095         typedef typename value::int_u<n>::enc E;
00096 
00097         E c;
00098         file.read((char*)(&c), sizeof(E));
00099         v.red() = c;
00100         file.read((char*)(&c), sizeof(E));
00101         v.green() = c;
00102         file.read((char*)(&c), sizeof(E));
00103         v.blue() = c;
00104       }
00105 
00106       // Read a Milena scalar value (sizeof(int_u8) != 1).
00107       template <class V>
00108       inline
00109       void read_value(std::ifstream& file, value::Scalar<V>& v)
00110       {
00111         typedef typename V::enc E;
00112 
00113         E c;
00114         file.read((char*)(&c), sizeof(E));
00115         exact(v) = c;
00116       }
00117 
00118       // Read a builtin scalar value.
00119       template <typename V>
00120       inline
00121       void read_value(std::ifstream& file, V& v)
00122       {
00123         V c;
00124         file.read((char*)(&c), sizeof(V));
00125         v = c;
00126       }
00127 
00128       // used when (sizeof(int_u8) != 1)
00129       template <typename V>
00130       inline
00131       void load_raw_2d_uncontiguous(std::ifstream& file, image2d<V>& ima)
00132       {
00133         const def::coord
00134           min_row = geom::min_row(ima),
00135           max_row = geom::max_row(ima),
00136           min_col = geom::min_col(ima),
00137           max_col = geom::max_col(ima);
00138 
00139         point2d p;
00140         for (p.row() = min_row; p.row() <= max_row; ++p.row())
00141           for (p.col() = min_col; p.col() <= max_col; ++p.col())
00142             read_value(file, ima(p));
00143       }
00144 
00145       // used in g++ > 2.95
00146       template <typename I>
00147       inline
00148       void load_raw_2d_contiguous(std::ifstream& file, I& ima)
00149       {
00150         point2d p = point2d(0, ima.domain().pmin().col());
00151         typedef mln_value(I) V;
00152         const mln_deduce(I, site, coord)
00153           min_row = geom::min_row(ima),
00154           max_row = geom::max_row(ima);
00155 
00156         std::size_t len = geom::ncols(ima) * sizeof(V);
00157         for (p.row() = min_row; p.row() <= max_row; ++p.row())
00158           file.read((char*)(&ima(p)), len);
00159       }
00160 
00162       template <typename I>
00163       inline
00164       void load_ascii_value(std::ifstream& file, I& ima)
00165       {
00166         mln_equiv(mln_value_(I)) c;
00167         mln_fwd_piter(I) p(ima.domain());
00168         for_all(p)
00169         {
00170           file >> c;
00171           ima(p) = c;
00172         }
00173       }
00174 
00176       template <typename I>
00177       inline
00178       void load_ascii_builtin(std::ifstream& file, I& ima)
00179       {
00180         mln_fwd_piter(I) p(ima.domain());
00181 
00182         // FIXME: May be wrong!
00183         // Worked out with an image with a max value of 255
00184         // loaded in an image2d<unsigned char>.
00185         unsigned n;
00186 
00187         for_all(p)
00188         {
00189           file >> n;
00190           ima(p) = n;
00191         }
00192       }
00193 
00196       template <typename I>
00197       inline
00198       void load_raw_2d(std::ifstream& file, I& ima)
00199       {
00200         if (sizeof(value::int_u8) == 1)
00201           load_raw_2d_contiguous(file, ima);
00202         else
00203           load_raw_2d_uncontiguous(file, ima);
00204       }
00205 
00207       template <typename V>
00208       inline
00209       image2d<V> load(char type_, const std::string& filename)
00210       {
00211         trace::entering("mln::io::pnm::load");
00212 
00213         std::ifstream file(filename.c_str());
00214         if (! file)
00215         {
00216           std::cerr << "error: file '" << filename
00217                     << "' not found!";
00218           abort();
00219         }
00220         char type = 0;
00221         int nrows, ncols;
00222         unsigned int maxval;
00223         read_header(static_cast<char>(type_ - 3), type_, file, type,
00224                     nrows, ncols, maxval);
00225 
00226         if (max_component(V()) != maxval)
00227         {
00228           std::cerr << "error: file '" << filename
00229                     << "' cannot be loaded into this type of image"
00230                     << std::endl;
00231 
00232           std::cerr << "input image have " << maxval
00233                     << " as maximum value while the destination's one is "
00234                     << max_component(V()) << " (should be the same)."
00235                     << std::endl;
00236           abort();
00237         }
00238 
00239         image2d<V> ima(nrows, ncols);
00240         if (type == type_)
00241           load_raw_2d(file, ima);
00242         else
00243           if (type == (type_ - 3))
00244             pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(V, mln::Value)());
00245 
00246         trace::exiting("mln::io::pnm::load");
00247 
00248         return ima;
00249       }
00250 
00254       template <typename I>
00255       inline
00256       void load(char type_,
00257                 Image<I>& ima_,
00258                 const std::string& filename)
00259       {
00260         trace::entering("mln::io::pnm::load");
00261 
00262         std::ifstream file(filename.c_str());
00263         if (! file)
00264         {
00265           std::cerr << "error: file '" << filename
00266                     << "' not found!";
00267           abort();
00268         }
00269 
00270         I& ima = exact(ima_);
00271 
00272         char type = 0;
00273         int nrows, ncols;
00274         unsigned int maxval;
00275         read_header(static_cast<char>(type_ - 3), type_, file, type,
00276                     nrows, ncols, maxval);
00277 
00278         if (max_component(mln_value(I)()) != maxval)
00279         {
00280           std::cerr << "error: file '" << filename
00281                     << "' cannot be loaded into this type of image"
00282                     << std::endl;
00283 
00284           std::cerr << "input image have " << maxval
00285                     << " as maximum value while the destination's one is "
00286                     << max_component(mln_value(I)()) << "."
00287                     << std::endl;
00288           abort();
00289         }
00290 
00291         ima.init_(make::box2d(nrows, ncols));
00292         if (type == type_)
00293           load_raw_2d(file, ima);
00294         else
00295           if (type == (type_ - 3))
00296             pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(mln_value(I), mln::Value)());
00297 
00298         trace::exiting("mln::io::pnm::load");
00299       }
00300 
00301 # endif // ! MLN_INCLUDE_ONLY
00302 
00303     } // end of namespace mln::io::pnm
00304 
00305   } // end of namespace mln::io
00306 
00307 } // end of namespace mln
00308 
00309 
00310 #endif // ! MLN_IO_PNM_LOAD_HH

Generated on Thu Sep 8 2011 18:32:04 for Milena (Olena) by  doxygen 1.7.1