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