diff --git a/image.cpp b/image.cpp index 8cb2994c..bfc454a0 100644 --- a/image.cpp +++ b/image.cpp @@ -5,16 +5,16 @@ * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. - * + * * libgim is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * - * Copyright 2011-2014 Danny Robson + * Copyright 2011-2015 Danny Robson */ @@ -26,6 +26,121 @@ #include +//----------------------------------------------------------------------------- +template +util::image::buffer::buffer (size_t _w, size_t _h, size_t _s): + w (_w), + h (_h), + s (_s), + data (std::make_unique (_w * _s)) +{ + CHECK_NEQ (w * h, 0); + CHECK_GE (s, w); +} + + +//----------------------------------------------------------------------------- +template +util::image::buffer::buffer (size_t _w, size_t _h): + buffer (_w, _h, _w) +{ ; } + + +//----------------------------------------------------------------------------- +template +util::image::buffer::buffer (size_t _w, + size_t _h, + size_t _s, + std::unique_ptr &&_data): + w (_w), + h (_h), + s (_s), + data (std::move (_data)) +{ + CHECK_NEQ (w * h, 0); + CHECK_GE (s, w); +} + + +//----------------------------------------------------------------------------- +template +template +util::image::buffer +util::image::buffer::alloc (void) const +{ + return buffer (w, h, s); +} + + +//----------------------------------------------------------------------------- +template +void +util::image::buffer::fill (const T v) +{ + std::fill (data.get (), data.get () + w * s, v); +} + + +//----------------------------------------------------------------------------- +template +static U +rescale (T v) +{ + return v * sizeof (U) / sizeof (T); +} + + +//----------------------------------------------------------------------------- +template +template +util::image::buffer +util::image::buffer::clone (void) const +{ + auto out = alloc (); + + std::transform (data.get (), + data.get () + w * s, + out.data.get (), + [] (auto v) { + return rescale (v); + }); + + return out; +} + + +//----------------------------------------------------------------------------- +template +util::image::buffer +util::image::buffer::downsample (unsigned factor) +{ + CHECK_GT (factor, 1); + + size_t w_ = w / factor; + size_t h_ = h / factor; + size_t s_ = w_; + + CHECK_NEQ (w_, 0); + CHECK_NEQ (h_, 0); + + buffer out { w_, h_, s_, std::make_unique (w_ * h_) }; + + // Do a really shitty nearest neighbour average in src-space. + for (size_t y = 0; y < out.h; ++y) + for (size_t x = 0; x < out.w; ++x) { + size_t src00 = ((y * factor) + 0) * s + (x * factor) + 0; + size_t src01 = ((y * factor) + 0) * s + (x * factor) + 1; + size_t src10 = ((y * factor) + 1) * s + (x * factor) + 0; + size_t src11 = ((y * factor) + 1) * s + (x * factor) + 1; + + size_t dst_offset = y * out.s + x; + out.data[dst_offset] = (src00 + src01 + src10 + src11) / 4; + } + + return out; +} + + //----------------------------------------------------------------------------- static void write_netpbm (const uint8_t *restrict pixels, @@ -82,3 +197,8 @@ util::ppm::write (const uint8_t *restrict pixels, static const char MAGIC[] = "P6"; write_netpbm (pixels, width, height, stride, path, MAGIC); } + + +//----------------------------------------------------------------------------- +template struct util::image::buffer; +template util::image::buffer util::image::buffer::alloc (void) const; diff --git a/image.hpp b/image.hpp index 4c62086e..fc4b38b0 100644 --- a/image.hpp +++ b/image.hpp @@ -5,16 +5,16 @@ * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. - * + * * libgim is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. - * + * * You should have received a copy of the GNU General Public License * along with libgim. If not, see . * - * Copyright 2011-2014 Danny Robson + * Copyright 2011-2015 Danny Robson */ #ifndef __UTIL_IMAGE_HPP @@ -22,9 +22,40 @@ #include #include +#include #include + namespace util { + namespace image { + template + struct buffer { + buffer (size_t w, size_t h); + buffer (size_t w, size_t h, size_t s); + buffer (size_t w, size_t h, size_t s, std::unique_ptr &&data); + + buffer (const buffer&) = delete; + buffer (buffer &&) = default; + + void fill (T); + + template + buffer alloc (void) const; + + template + buffer clone (void) const; + + buffer downsample (unsigned factor); + + size_t w; + size_t h; + size_t s; + + std::unique_ptr data; + }; + } + + struct pgm { static void write (const uint8_t *restrict pixels, size_t width,