Milena (Olena)
User documentation 2.0a Id
|
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 typedef mln_value(I) V; 00201 if (sizeof(V) == 1) 00202 load_raw_2d_contiguous(file, ima); 00203 else 00204 load_raw_2d_uncontiguous(file, ima); 00205 } 00206 00208 template <typename V> 00209 inline 00210 image2d<V> load(char type_, const std::string& filename) 00211 { 00212 trace::entering("mln::io::pnm::load"); 00213 00214 std::ifstream file(filename.c_str()); 00215 if (! file) 00216 { 00217 std::cerr << "error: file '" << filename 00218 << "' not found!"; 00219 abort(); 00220 } 00221 char type = 0; 00222 int nrows, ncols; 00223 unsigned int maxval; 00224 read_header(static_cast<char>(type_ - 3), type_, file, type, 00225 nrows, ncols, maxval); 00226 00227 if (max_component(V()) != maxval) 00228 { 00229 std::cerr << "error: file '" << filename 00230 << "' cannot be loaded into this type of image" 00231 << std::endl; 00232 00233 std::cerr << "input image have " << maxval 00234 << " as maximum value while the destination's one is " 00235 << max_component(V()) << " (should be the same)." 00236 << std::endl; 00237 abort(); 00238 } 00239 00240 image2d<V> ima(nrows, ncols); 00241 if (type == type_) 00242 load_raw_2d(file, ima); 00243 else 00244 if (type == (type_ - 3)) 00245 pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(V, mln::Value)()); 00246 00247 trace::exiting("mln::io::pnm::load"); 00248 00249 return ima; 00250 } 00251 00255 template <typename I> 00256 inline 00257 void load(char type_, 00258 Image<I>& ima_, 00259 const std::string& filename) 00260 { 00261 trace::entering("mln::io::pnm::load"); 00262 00263 std::ifstream file(filename.c_str()); 00264 if (! file) 00265 { 00266 std::cerr << "error: file '" << filename 00267 << "' not found!"; 00268 abort(); 00269 } 00270 00271 I& ima = exact(ima_); 00272 00273 char type = 0; 00274 int nrows, ncols; 00275 unsigned int maxval; 00276 read_header(static_cast<char>(type_ - 3), type_, file, type, 00277 nrows, ncols, maxval); 00278 00279 if (max_component(mln_value(I)()) != maxval) 00280 { 00281 std::cerr << "error: file '" << filename 00282 << "' cannot be loaded into this type of image" 00283 << std::endl; 00284 00285 std::cerr << "input image have " << maxval 00286 << " as maximum value while the destination's one is " 00287 << max_component(mln_value(I)()) << "." 00288 << std::endl; 00289 abort(); 00290 } 00291 00292 ima.init_(make::box2d(nrows, ncols)); 00293 if (type == type_) 00294 load_raw_2d(file, ima); 00295 else 00296 if (type == (type_ - 3)) 00297 pnm::internal::load_ascii_dispatch(file, ima, mlc_is_a(mln_value(I), mln::Value)()); 00298 00299 trace::exiting("mln::io::pnm::load"); 00300 } 00301 00302 # endif // ! MLN_INCLUDE_ONLY 00303 00304 } // end of namespace mln::io::pnm 00305 00306 } // end of namespace mln::io 00307 00308 } // end of namespace mln 00309 00310 00311 #endif // ! MLN_IO_PNM_LOAD_HH