Damien Thivolle <damien(a)lrde.epita.fr> writes:
Index: ChangeLog
from Damien Thivolle <damien(a)lrde.epita.fr>
* oln/io/write_image_2d_pnm.hh: Add ppm and pbm output methods.
* oln/io/read_image_2d_pnm.hh: Add ppm and pbm input methods.
* oln/io/utils.hh: Fix an error occuring when writing pbm headers.
* oln/core/abstract/image_with_data.hh: Remove an unexpected `return'.
* oln/core/2d/image2d.hh: Fix circular inclusion problem.
core/2d/image2d.hh | 8 +
core/abstract/image_with_data.hh | 4
io/read_image_2d_pnm.hh | 163 +++++++++++++++++++++++++++++++--------
io/utils.hh | 8 -
io/write_image_2d_pnm.hh | 102 ++++++++++++++++++++++--
6 files changed, 242 insertions(+), 45 deletions(-)
Index: oln/io/write_image_2d_pnm.hh
--- oln/io/write_image_2d_pnm.hh (revision 44)
+++ oln/io/write_image_2d_pnm.hh (working copy)
@@ -53,16 +53,16 @@
namespace impl {
template <typename I>
- struct write_image_2d_pgm_raw
- : public oln::abstract::void_op<write_image_2d_pgm_raw<I> >
+ struct write_image_2d_raw
+ : public oln::abstract::void_op<write_image_2d_raw<I> >
{
typedef oln_value_type(I) value_type;
- typedef typename mlc::traits<value_type>::encoding_type out_type;
+ typedef ntg_io_type(value_type) io_type;
const I& to_write_;
std::ofstream& ostr_;
- write_image_2d_pgm_raw(const I& to_write, std::ofstream& ostr):
+ write_image_2d_raw(const I& to_write, std::ofstream& ostr):
to_write_(to_write),
ostr_(ostr)
{}
@@ -70,19 +70,57 @@
void impl_run()
{
point2d p;
- out_type c;
+ value_type c;
+ bool b;
for (p.row() = 0; p.row() < to_write_.size().nrows(); ++p.row())
for (p.col() = 0; p.col() < to_write_.size().ncols(); ++p.col())
{
c = to_write_[p];
- ostr_ << c;
+ b = write_value_type(c);
}
+ while (b == false)
+ b = write_value_type(c);
ostr_.close();
}
+ bool write_value_type(const ntg::integer<value_type> &c)
+ {
+ ostr_ << (io_type)(c.exact());
+ return true;
+ }
+
+ bool write_value_type(const ntg::color<value_type> &c)
+ {
+ assert ((ntg_nb_comp(value_type) == 3));
+
+ for (unsigned i = 0; i < 3; i++)
+ ostr_ << (io_type)(c[i]);
+ return true;
+ }
+
+ bool write_value_type(const ntg::enum_value<value_type> &c)
+ {
+ assert ((ntg_max_val(value_type) == 1));
+ static int offset = 7;
+ static unsigned char v = 0;
+ bool ret = false;
+
+ if (offset == -1)
+ {
+ ostr_ << v;
+ offset = 7;
+ v = 0;
+ ret = true;
+ }
+ if (c == 1)
+ v |= 1 << offset;
+ offset--;
+ return ret;
+ }
};
+
template <typename I, typename T>
void write(const abstract::image2d<I>& to_write,
const ntg::integer<T>&,
@@ -98,7 +136,7 @@
s.ncols(), s.nrows(),
ntg_max_val(T)))
{
- write_image_2d_pgm_raw<I> tmp(to_write.exact(), ostr);
+ write_image_2d_raw<I> tmp(to_write.exact(), ostr);
tmp.run();
}
else
@@ -108,6 +146,56 @@
<< " file extension (`" << ext << "')"
<< std::endl;
}
+ template <typename I, typename T>
+ void write(const abstract::image2d<I>& to_write,
+ const ntg::color<T>&,
+ const std::string& name,
+ const std::string& ext)
+ {
+ std::ofstream ostr;
+ point2d p;
+ size2d s = to_write.size();
+
+ if (ext == "ppm")
+ if (internal::write_pnm_header(ostr, name, "P6",
+ s.ncols(), s.nrows(),
+ ntg_max_val(T)))
+ {
+ write_image_2d_raw<I> tmp(to_write.exact(), ostr);
+ tmp.run();
+ }
+ else
+ std::cerr << "error: unable to write header" << std::endl;
+ else
+ std::cerr << "error: image data type (`color') does not match"
+ << " file extension (`" << ext << "')"
<< std::endl;
+ }
+
+ template <typename I, typename T>
+ void write(const abstract::image2d<I>& to_write,
+ const ntg::enum_value<T>&,
+ const std::string& name,
+ const std::string& ext)
+ {
+ std::ofstream ostr;
+ point2d p;
+ size2d s = to_write.size();
+
+ if (ext == "pbm")
+ if (internal::write_pnm_header(ostr, name, "P4",
+ s.ncols(), s.nrows(),
+ ntg_max_val(T)))
+ {
+ write_image_2d_raw<I> tmp(to_write.exact(), ostr);
+ tmp.run();
+ }
+ else
+ std::cerr << "error: unable to write header" << std::endl;
+ else
+ std::cerr << "error: image data type (`enum_value') does not
match"
+ << " file extension (`" << ext << "')"
<< std::endl;
+ }
+
}
}
Index: oln/io/read_image_2d_pnm.hh
--- oln/io/read_image_2d_pnm.hh (revision 44)
+++ oln/io/read_image_2d_pnm.hh (working copy)
@@ -28,27 +28,56 @@
namespace impl {
+ template <typename I>
+ struct read_image_2d_raw;
+ }
+
+ }
+
+ template <typename I>
+ struct category_type< io::impl::read_image_2d_raw<I> >
+ {
+ typedef cat::image ret;
+ };
+
+ template <typename I>
+ struct props <cat::image, io::impl::read_image_2d_raw<I> >
+ : public props<cat::image, I>
+ {
+ typedef I delegated_type;
+ };
+
+
+
+ namespace io {
+
+ namespace impl {
+
template <typename I>
- struct read_image_2d_pgm_raw:
- oln::abstract::void_op<read_image_2d_pgm_raw<I> >
+ struct read_image_2d_raw:
+ oln::abstract::op<I, read_image_2d_raw<I> >
{
+
+ typedef oln::abstract::op<I, read_image_2d_raw<I> > super_type;
+ typedef oln_value_type(I) value_type;
+ typedef ntg_io_type(value_type) io_type;
+
mlc::box<I> image_;
std::ifstream& istr_;
internal::pnm_info& info_;
- read_image_2d_pgm_raw(I& image,
- std::ifstream &istr,
- internal::pnm_info &info) :
+ read_image_2d_raw(I& image,
+ std::ifstream &istr,
+ internal::pnm_info &info) :
+ super_type(image),
image_(image),
istr_(istr),
info_(info)
{}
- typedef oln_value_type(I) value_type;
- typedef typename mlc::traits<value_type>::encoding_type encoding_type;
- read_image_2d_pgm_raw<I>& output(I& output)
+ read_image_2d_raw<I>& output(I& output)
{
output = *image_;
return *this;
@@ -56,7 +85,9 @@
void impl_run()
{
- encoding_type c;
+ value_type c;
+ point2d p;
+ oln::image2d<value_type> tmp(info_.rows, info_.cols);
if (info_.max_val > ntg_max_val(value_type))
{
@@ -64,26 +95,57 @@
<< std::endl;
return;
}
- point2d p;
- oln::image2d<value_type> tmp(info_.rows, info_.cols);
- std::cout << info_.cols << "," << info_.rows <<
","
- << info_.max_val << std::endl;
-
-
for (p.row() = 0; p.row() < info_.rows && !istr_.eof(); ++p.row())
for (p.col() = 0; p.col() < info_.cols && !istr_.eof(); ++p.col())
{
- istr_.read(&c, sizeof (encoding_type));
+ read_value_type(c);
tmp[p] = c;
}
istr_.close();
*image_ = tmp;
- std::cout << "debug : size = " << image_->size() <<
std::endl;
}
+
+ void read_value_type(ntg::integer<value_type> &c)
+ {
+ io_type v;
+ istr_.read(&v, sizeof (io_type));
+ c = v;
+ }
+
+ void read_value_type(ntg::color<value_type> &c)
+ {
+ assert((ntg_nb_comp(value_type) == 3));
+ io_type v;
+
+ for (unsigned i = 0; i < 3; i++)
+ {
+ istr_.read(&v, sizeof (v));
+ c[i] = v;
+ }
+ }
+
+ void read_value_type(ntg::enum_value<value_type> &c)
+ {
+ static io_type v;
+ static int offset = -1;
+
+ if (offset == -1)
+ {
+ istr_.read((char *)(&v), sizeof (v));
+ offset = 7;
+ }
+ if ((int)(v & (1<<offset--)) == 0)
+ c = 0;
+ else
+ c = 1;
+ }
+
+
};
+
template <typename I, typename T>
void read(abstract::image2d<I>& ima,
const ntg::integer<T>&,
@@ -97,27 +159,25 @@
if (ext == "pgm")
if (info.type == "P5")
{
- read_image_2d_pgm_raw<I> tmp(ima.exact(), istr, info);
+ read_image_2d_raw<I> tmp(ima.exact(), istr, info);
tmp.run();
tmp.output(ima.exact());
}
+ else if (info.type == "P2")
+ std::cerr << "error: read_image_2d_pgm_ascii not implemented"
+ << std::endl;
else
- if (info.type == "P2")
- std::cerr << "error: read_image_2d_pgm_ascii not implemented"
- << std::endl;
- else
- std::cerr << "error: file header (`" << info.type
- << "') does not match file extension (`"
- << ext << "')" << std::endl;
+ std::cerr << "error: file header (`" << info.type
+ << "') does not match file extension (`"
+ << ext << "')" << std::endl;
else
std::cerr << "error: image data type (`integer') does not
match"
<< " file extension (`" << ext << "')"
<< std::endl;
else
std::cerr << "error: unable to get a valid header" <<
std::endl;
- std::cout << "debug : size = " << ima.size() << std::endl;
+ }
- }
template <typename I, typename T>
void read(abstract::image2d<I>& ima,
@@ -125,7 +185,29 @@
const std::string& filename,
const std::string& ext)
{
- std::cout << "read for image2d<color>" << std::endl;
+ std::ifstream istr;
+ internal::pnm_info info;
+
+ if (internal::read_pnm_header(istr, info, filename))
+ if (ext == "ppm")
+ if (info.type == "P6")
+ {
+ read_image_2d_raw<I> tmp(ima.exact(), istr, info);
+ tmp.run();
+ tmp.output(ima.exact());
+ }
+ else if (info.type == "P3")
+ std::cerr << "error: read_image_2d_ppm_ascii not implemented"
+ << std::endl;
+ else
+ std::cerr << "error: file header (`" << info.type
+ << "') does not match file extension (`"
+ << ext << "')" << std::endl;
+ else
+ std::cerr << "error: image data type (`color') does not match"
+ << " file extension (`" << ext << "')"
<< std::endl;
+ else
+ std::cerr << "error: unable to get a valid header" <<
std::endl;
}
template <typename I, typename T>
@@ -134,10 +216,31 @@
const std::string& filename,
const std::string& ext)
{
- std::cout << "read for image2d<enum>" << std::endl;
+ std::ifstream istr;
+ internal::pnm_info info;
+
+ if (internal::read_pnm_header(istr, info, filename))
+ if (ext == "pbm")
+ if (info.type == "P4")
+ {
+ read_image_2d_raw<I> tmp(ima.exact(), istr, info);
+ tmp.run();
+ tmp.output(ima.exact());
+ }
+ else if (info.type == "P1")
+ std::cerr << "error: read_image_2d_ppm_ascii not implemented"
+ << std::endl;
+ else
+ std::cerr << "error: file header (`" << info.type
+ << "') does not match file extension (`"
+ << ext << "')" << std::endl;
+ else
+ std::cerr << "error: image data type (`enum_value') does not
match"
+ << " file extension (`" << ext << "')"
<< std::endl;
+ else
+ std::cerr << "error: unable to get a valid header" <<
std::endl;
}
-
}
}
Index: oln/io/utils.hh
--- oln/io/utils.hh (revision 44)
+++ oln/io/utils.hh (working copy)
@@ -160,11 +160,11 @@
return false;
}
-
- ostr << "P5" << std::endl
+ ostr << type << std::endl
<< "# Olena 1.0" << std::endl
- << ncols << " " << nrows << std::endl
- << max_val << std::endl;
+ << ncols << " " << nrows << std::endl;
+ if (type != "P1" && type != "P4")
+ ostr << max_val << std::endl;
return true;
}
Index: oln/core/abstract/image_with_data.hh
--- oln/core/abstract/image_with_data.hh (revision 44)
+++ oln/core/abstract/image_with_data.hh (working copy)
@@ -121,7 +121,7 @@
template <typename V>
void impl_set(const oln_point_type(E)& p, const V& v)
{
- return this->data_->set(p, v);
+ this->data_->set(p, v);
}
/*! \brief True if the image contains data.
@@ -130,8 +130,8 @@
{
return data_ != 0;
}
-
+
protected:
/*! \brief Constructor (protected) with no memory allocation for
Index: oln/core/2d/image2d.hh
--- oln/core/2d/image2d.hh (revision 44)
+++ oln/core/2d/image2d.hh (working copy)
@@ -34,14 +34,20 @@
# include <oln/core/abstract/image_with_data.hh>
# include <oln/core/2d/array2d.hh>
# include <oln/core/2d/fwd_piter2d.hh>
-# include <oln/io/read_image.hh>
/*! \namespace oln
** \brief oln namespace.
*/
namespace oln {
+ namespace io {
+ struct filename;
+
+ template <typename I>
+ void do_read(abstract::image<I>&, const filename&);
+ }
+
// fwd decl
template <typename T> class image2d;
Those functions will be changed to macros as soon as possible.
--
Damien Thivolle
damien(a)lrde.epita.fr