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_FLD_SAVE_HH
00027 # define MLN_IO_FLD_SAVE_HH
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/gpoint.hh>
00035 # include <mln/io/fld/header.hh>
00036 # include <mln/io/fld/write_header.hh>
00037 # include <mln/io/fld/max_components.hh>
00038
00039 # include <mln/algebra/vec.hh>
00040
00041 # include <mln/geom/nsites.hh>
00042 # include <fstream>
00043 # include <iostream>
00044
00045 namespace mln
00046 {
00047
00048 namespace io
00049 {
00050
00051 namespace fld
00052 {
00053
00054 template <typename I>
00055 void save(const Image<I>& ima_, const char* filename);
00056
00057
00058 # ifndef MLN_INCLUDE_ONLY
00059
00060 namespace internal
00061 {
00062 template <typename I>
00063 inline
00064 void save_data_contiguous(std::ofstream& file, const I& ima)
00065 {
00066 typedef mln_site(I) P;
00067 typedef mln_value(I) V;
00068 enum { dim = P::dim };
00069
00070 P pmin = ima.domain().pmin();
00071 P pmax = ima.domain().pmax();
00072
00073 std::size_t len = pmax[dim - 1] - pmin[dim - 1] + 1;
00074 std::size_t n = len * sizeof(V);
00075 P p = pmin;
00076 if (dim == 1)
00077 {
00078 file.write((char*)(&ima(p)), n);
00079 return;
00080 }
00081
00082 while (true)
00083 {
00084 file.write((char*)(&ima(p)), n);
00085 ++p[dim - 2];
00086
00087 for (int i = dim - 2; p[i] > pmax[i]; --i)
00088 {
00089 if (i == 0)
00090 return;
00091 p[i] = pmin[i];
00092 ++p[i - 1];
00093 }
00094 }
00095 }
00096
00097 template <typename I>
00098 inline
00099 fld::fld_header make_header(const I& ima)
00100 {
00101 fld_header hdr;
00102 typedef mln_site(I) P;
00103 typedef mln_value(I) V;
00104 enum { dim = P::dim };
00105
00106 hdr.ndim = dim;
00107 hdr.nspace = dim;
00108 hdr.veclen = mln_dim(V);
00109 hdr.dim = new int[dim];
00110 hdr.min_ext = new float[dim];
00111 hdr.max_ext = new float[dim];
00112
00113 box<P> bbox = geom::bbox(ima);
00114 P pmin = bbox.pmin();
00115 P pmax = bbox.pmax();
00116
00117 for (unsigned i = 0; i < dim; i++)
00118 {
00119 hdr.dim[i] = pmax[i] - pmin[i] + 1;
00120 hdr.min_ext[i] = pmin[i];
00121 hdr.max_ext[i] = pmax[i];
00122 }
00123
00124 unsigned max_c = max_component(V ());
00125 if (max_c == max_component(data_type::BYTE))
00126 hdr.data = data_type::BYTE;
00127 else if (max_c == max_component(data_type::SHORT))
00128 hdr.data = data_type::SHORT;
00129 else if (max_c == max_component(data_type::INTEGER))
00130 hdr.data = data_type::INTEGER;
00131 else if (max_c == max_component(data_type::FLOAT))
00132 hdr.data = data_type::FLOAT;
00133 else if (max_c == max_component(data_type::DOUBLE))
00134 hdr.data = data_type::DOUBLE;
00135 else
00136 hdr.data = data_type::UNKNOWN;
00137
00138 hdr.field = field_type::UNIFORM;
00139
00140 return hdr;
00141 }
00142
00143 }
00144
00145 template <typename I>
00146 void save(const Image<I>& ima_, const char* filename)
00147 {
00148 trace::entering("mln::io::fld::save");
00149
00150 mlc_is(mln_trait_image_speed(I), trait::image::speed::fastest)::check();
00151
00152 const I& ima = exact(ima_);
00153 mln_precondition(ima.is_valid());
00154
00155 std::ofstream file(filename);
00156 fld_header hdr = internal::make_header(ima);
00157
00158 write_header(file, hdr);
00159 internal::save_data_contiguous(file, ima);
00160
00161 file.close();
00162 trace::exiting("mln::io::fld::save");
00163 }
00164
00165
00166 # endif // ! MLN_INCLUDE_ONLY
00167
00168 }
00169
00170 }
00171
00172 }
00173 #endif // !MLN_IO_FLD_SAVE_HH