
* mln/io/magick/load.hh, * mln/io/magick/save.hh: Use pointers to access image data. --- milena/ChangeLog | 7 ++++++ milena/mln/io/magick/load.hh | 50 ++++++++++++++++++++++++++---------------- milena/mln/io/magick/save.hh | 24 ++++++++++++++++---- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 10d8482..f853179 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,10 @@ +2010-11-19 Guillaume Lazzara <z@lrde.epita.fr> + + Add a fastest implementation in io::magick. + + * mln/io/magick/load.hh, + * mln/io/magick/save.hh: Use pointers to access image data. + 2010-10-28 Roland Levillain <roland@lrde.epita.fr> Handle properly non 8-bit Magick::Quantum's. diff --git a/milena/mln/io/magick/load.hh b/milena/mln/io/magick/load.hh index 60e857e..2acd668 100644 --- a/milena/mln/io/magick/load.hh +++ b/milena/mln/io/magick/load.hh @@ -155,33 +155,45 @@ namespace mln mln_concrete(I) result(box<mln_site(I)>(pmin, pmax)); initialize(ima, result); + def::coord + minrow = geom::min_row(ima), + mincol = geom::min_col(ima), + maxrow = geom::max_row(ima), + maxcol = geom::max_col(ima); + Magick::Pixels view(magick_ima); // Note that `ncols' is passed before `nrows'. Magick::PixelPacket* pixels = view.get(0, 0, ima.ncols(), ima.nrows()); - mln_piter(I) p(ima.domain()); - for_all(p) - { - /* Each channel of a Magick++ image is coded on a - Magick::Quantum value, which can be an 8-, 16- or 32-bit - integer. Load the most significant bits of each channel - into a component of an mln::value::rgb8 value (i.e., into - an mln::value::int_u8 value). */ - value::rgb8 c(pixels->red >> 8 * (sizeof(Magick::Quantum) - - sizeof(value::rgb8::red_t)), - pixels->green >> 8 * (sizeof(Magick::Quantum) - - sizeof(value::rgb8::green_t)), - pixels->blue >> 8 * (sizeof(Magick::Quantum) - - sizeof(value::rgb8::blue_t))); - mln_value(I) res; - if (!impl::do_it(c, res)) + mln_value(I) *ptr_ima = &ima(ima.domain().pmin()); + + unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols)); + + for (def::coord row = minrow; row <= maxrow; + ++row, ptr_ima += row_offset) + for (def::coord col = mincol; col <= maxcol; ++col) + { + + /* Each channel of a Magick++ image is coded on a + Magick::Quantum value, which can be an 8-, 16- or 32-bit + integer. Load the most significant bits of each channel + into a component of an mln::value::rgb8 value (i.e., into + an mln::value::int_u8 value). */ + value::rgb8 c(pixels->red >> 8 * (sizeof(Magick::Quantum) + - sizeof(value::rgb8::red_t)), + pixels->green >> 8 * (sizeof(Magick::Quantum) + - sizeof(value::rgb8::green_t)), + pixels->blue >> 8 * (sizeof(Magick::Quantum) + - sizeof(value::rgb8::blue_t))); + mln_value(I) res; + if (!impl::do_it(c, res)) { std::cerr << "while trying to load `" << filename << "'" << std::endl; abort(); } - ima(p) = res; - ++pixels; - } + *ptr_ima++ = res; + ++pixels; + } trace::exiting("mln::io::magick::load"); } diff --git a/milena/mln/io/magick/save.hh b/milena/mln/io/magick/save.hh index 7a91ee0..7282414 100644 --- a/milena/mln/io/magick/save.hh +++ b/milena/mln/io/magick/save.hh @@ -150,18 +150,32 @@ namespace mln const I& ima = exact(ima_); + def::coord + minrow = geom::min_row(ima), + mincol = geom::min_col(ima), + maxrow = geom::max_row(ima), + maxcol = geom::max_col(ima), + ncols = geom::ncols(ima), + nrows = geom::nrows(ima); + + Magick::Image magick_ima; // In the construction of a Geometry object, the width (i.e. // `ncols') comes first, then the height (i.e. `nrows') // follows. - magick_ima.size(Magick::Geometry(ima.ncols(), ima.nrows())); + magick_ima.size(Magick::Geometry(ncols, nrows)); Magick::Pixels view(magick_ima); // As above, `ncols' is passed before `nrows'. - Magick::PixelPacket* pixels = view.get(0, 0, ima.ncols(), ima.nrows()); - mln_piter(I) p(ima.domain()); - for_all(p) - *pixels++ = impl::get_color(ima(p)); + Magick::PixelPacket* pixels = view.get(0, 0, ncols, nrows); + const mln_value(I) *ptr_ima = &ima(ima.domain().pmin()); + + unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols)); + + for (def::coord row = minrow; row <= maxrow; + ++row, ptr_ima += row_offset) + for (def::coord col = mincol; col <= maxcol; ++col) + *pixels++ = impl::get_color(*ptr_ima++); view.sync(); magick_ima.write(filename); -- 1.5.6.5