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