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
00027 #ifndef MLN_IO_PNM_SAVE_HH
00028 # define MLN_IO_PNM_SAVE_HH
00029
00034
00035 # include <iostream>
00036 # include <fstream>
00037
00038 # include <mln/core/concept/image.hh>
00039 # include <mln/core/alias/point2d.hh>
00040 # include <mln/value/concept/scalar.hh>
00041
00042 # include <mln/value/rgb.hh>
00043 # include <mln/value/rgb8.hh>
00044 # include <mln/value/int_u8.hh>
00045
00046 # include <mln/metal/templated_by.hh>
00047 # include <mln/metal/not_equal.hh>
00048
00049 # include <mln/io/pnm/save_header.hh>
00050 # include <mln/io/pnm/macros.hh>
00051
00052 # include <mln/geom/size2d.hh>
00053
00054
00055 namespace mln
00056 {
00057
00058 namespace io
00059 {
00060
00061 namespace pnm
00062 {
00063
00071 template <typename I>
00072 void save(char type, const Image<I>& ima_, const std::string& filename);
00073
00074
00075
00076 # ifndef MLN_INCLUDE_ONLY
00077
00078 namespace impl
00079 {
00080
00081
00082 template <unsigned int n>
00083 inline
00084 void write_value(std::ofstream& file,
00085 const value::rgb<n>& c)
00086 {
00087 typedef typename value::int_u<n>::enc E;
00088
00089 E v = c.red().to_enc();
00090 file.write((char*)&v, sizeof(E));
00091 v = c.green().to_enc();
00092 file.write((char*)&v, sizeof(E));
00093 v = c.blue().to_enc();
00094 file.write((char*)&v, sizeof(E));
00095 }
00096
00097
00098 template <typename V>
00099 inline
00100 void write_value(std::ofstream& file,
00101 const V& v)
00102 {
00103 mlc_not_equal(V,bool)::check();
00104 file.write((char*)(&v), sizeof(V));
00105 }
00106
00107
00108 template <typename S>
00109 inline
00110 void write_value(std::ofstream& file,
00111 const value::Scalar<S>& s)
00112 {
00113 typedef typename S::enc E;
00114
00115 E c = s.to_enc();
00116 file.write((char*)(&c), sizeof(E));
00117 }
00118
00119
00120 template <typename I>
00121 inline
00122 void save_data_uncontiguous(std::ofstream& file,
00123 const I& ima)
00124 {
00125 const def::coord
00126 min_row = geom::min_row(ima),
00127 max_row = geom::max_row(ima),
00128 min_col = geom::min_col(ima),
00129 max_col = geom::max_col(ima);
00130
00131 point2d p;
00132 for (p.row() = min_row; p.row() <= max_row; ++p.row())
00133 for (p.col() = min_col; p.col() <= max_col; ++p.col())
00134 write_value(file, ima(p));
00135 }
00136
00137
00138
00139 template <typename I>
00140 inline
00141 void save_data_contiguous(std::ofstream& file,
00142 const I& ima_)
00143 {
00144 const I& ima = exact(ima_);
00145 const def::coord
00146 min_row = geom::min_row(ima),
00147 max_row = geom::max_row(ima);
00148 point2d p;
00149 p.col() = geom::min_col(ima);
00150 std::size_t len = geom::ncols(ima) * sizeof(mln_value(I));
00151 for (p.row() = min_row; p.row() <= max_row; ++p.row())
00152 file.write((char*)(& ima(p)), len);
00153 }
00154
00155
00156
00157 template <typename I>
00158 inline
00159 void save_data_(std::ofstream& file,
00160 trait::image::speed::fastest, const I& ima)
00161 {
00162
00163 if (sizeof(value::int_u8) == 1)
00164 save_data_contiguous(file, ima);
00165 else
00166 save_data_uncontiguous(file, ima);
00167 }
00168
00169
00170 template <typename I>
00171 inline
00172 void save_data_(std::ofstream& file,
00173 trait::image::speed::any, const I& ima)
00174 {
00175 save_data_uncontiguous(file, ima);
00176 }
00177
00178 }
00179
00180
00181
00182
00183 template <typename I>
00184 inline
00185 void save(char type, const Image<I>& ima_, const std::string& filename)
00186 {
00187 trace::entering("mln::io::pnm::save");
00188 const I& ima = exact(ima_);
00189 std::ofstream file(filename.c_str());
00190 io::pnm::save_header(type, ima, filename, file);
00191
00192 impl::save_data_(file,
00193 mln_trait_image_speed(I)(), ima);
00194 trace::exiting("mln::io::pnm::save");
00195 }
00196
00197 # endif // ! MLN_INCLUDE_ONLY
00198
00199 }
00200
00201 }
00202
00203 }
00204
00205
00206 #endif // ! MLN_IO_PNM_SAVE_HH