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 #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 }
00088
00089
00090
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
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
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
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
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
00183
00184
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 }
00305
00306 }
00307
00308 }
00309
00310
00311 #endif // ! MLN_IO_PNM_LOAD_HH