diff --git a/bitmap_image.hpp b/bitmap_image.hpp index 13ac766..702ead7 100644 --- a/bitmap_image.hpp +++ b/bitmap_image.hpp @@ -318,18 +318,37 @@ class bitmap_image return true; } - void reflective_image(bitmap_image& image) + void reflective_image(bitmap_image& image, const bool include_diagnols = false) { image.setwidth_height(3 * width_, 3 * height_,true); - image.copy_from(*this,width_,height_); + + image.copy_from(*this, width_, height_); + vertical_flip(); - image.copy_from(*this,width_,0); - image.copy_from(*this,width_,2 * height_); + + image.copy_from(*this, width_, 0); + image.copy_from(*this, width_, 2 * height_); + vertical_flip(); horizontal_flip(); - image.copy_from(*this,0,height_); - image.copy_from(*this,2 * width_,height_); + + image.copy_from(*this, 0, height_); + image.copy_from(*this, 2 * width_, height_); + horizontal_flip(); + + if (include_diagnols) + { + bitmap_image tile = *this; + + tile.vertical_flip(); + tile.horizontal_flip(); + + image.copy_from(tile, 0 , 0); + image.copy_from(tile, 2 * width_, 0); + image.copy_from(tile, 2 * width_, 2 * height_); + image.copy_from(tile, 0, 2 * height_); + } } inline unsigned int width() const @@ -1529,28 +1548,28 @@ class bitmap_image std::vector data_; }; -struct rgb_store +struct rgb_t { - unsigned char red; + unsigned char red; unsigned char green; - unsigned char blue; + unsigned char blue; }; -bool operator==(const rgb_store& c0, const rgb_store& c1) +bool operator==(const rgb_t& c0, const rgb_t& c1) { return (c0.red == c1 .red) && (c0.green == c1.green) && (c0.blue == c1 .blue); } -bool operator!=(const rgb_store& c0, const rgb_store& c1) +bool operator!=(const rgb_t& c0, const rgb_t& c1) { return (c0.red != c1 .red) || (c0.green != c1.green) || (c0.blue != c1 .blue); } -std::size_t hamming_distance(const rgb_store& c0, const rgb_store& c1) +std::size_t hamming_distance(const rgb_t& c0, const rgb_t& c1) { std::size_t result = 0; @@ -1561,6 +1580,62 @@ std::size_t hamming_distance(const rgb_store& c0, const rgb_store& c1) return result; } +inline rgb_t make_colour(const unsigned int& red, const unsigned int& green, const unsigned int& blue) +{ + rgb_t result; + + result.red = static_cast(red ); + result.green = static_cast(green); + result.blue = static_cast(blue ); + + return result; +} + +template +inline void generate_colours(const std::size_t& steps, const rgb_t c0, const rgb_t& c1, OutputIterator out) +{ + double dr = ((double)c1.red - (double)c0.red ) / steps; + double dg = ((double)c1.green - (double)c0.green ) / steps; + double db = ((double)c1.blue - (double)c0.blue ) / steps; + + for (std::size_t i = 0; i < steps; ++i) + { + rgb_t c; + + c.red = static_cast(c0.red + (i * dr)); + c.green = static_cast(c0.green + (i * dg)); + c.blue = static_cast(c0.blue + (i * db)); + + *(out++) = c; + } +} + +template +inline std::size_t convert_rsp_to_image(const ResponseImage& resp_image, const Palette& palette, bitmap_image& image) +{ + if ( + (resp_image.width () > image.width ()) || + (resp_image.height() > image.height()) + ) + return 0; + + for (std::size_t y = 0; y < resp_image.height(); ++y) + { + for (std::size_t x = 0; x < resp_image.width(); ++x) + { + const double v = resp_image(x,y); + + unsigned int index = static_cast((v < 0) ? 0 : v > (palette.size()) ? (palette.size() - 1) : v); + + rgb_t c = palette[index]; + + image.set_pixel(x,y,c.red,c.green,c.blue); + } + } + + return (resp_image.width() * resp_image.height()); +} + inline void rgb_to_ycbcr(const unsigned int& length, double* red, double* green, double* blue, double* y, double* cb, double* cr) { @@ -1810,7 +1885,7 @@ inline void plasma(bitmap_image& image, const double& c1, const double& c2, const double& c3, const double& c4, const double& roughness = 3.0, - const rgb_store colormap[] = 0) + const rgb_t colormap[] = 0) { // Note: c1,c2,c3,c4 -> [0.0,1.0] @@ -1836,7 +1911,7 @@ inline void plasma(bitmap_image& image, } else { - rgb_store color = colormap[static_cast(1000.0 * ((c1 + c2 + c3 + c4) / 4.0)) % 1000]; + rgb_t color = colormap[static_cast(1000.0 * ((c1 + c2 + c3 + c4) / 4.0)) % 1000]; image.set_pixel(static_cast(x),static_cast(y),color.red,color.green,color.blue); } } @@ -1889,7 +1964,7 @@ inline void hierarchical_psnr_r(const double& x, const double& y, const bitmap_image& image1, bitmap_image& image2, const double& threshold, - const rgb_store colormap[]) + const rgb_t colormap[]) { if ((width <= 4.0) || (height <= 4.0)) { @@ -1903,7 +1978,7 @@ inline void hierarchical_psnr_r(const double& x, const double& y, if (psnr < threshold) { - rgb_store c = colormap[static_cast(1000.0 * (1.0 - (psnr / threshold)))]; + rgb_t c = colormap[static_cast(1000.0 * (1.0 - (psnr / threshold)))]; image2.set_region( static_cast(x), @@ -1926,7 +2001,7 @@ inline void hierarchical_psnr_r(const double& x, const double& y, } } -inline void hierarchical_psnr(bitmap_image& image1,bitmap_image& image2, const double threshold, const rgb_store colormap[]) +inline void hierarchical_psnr(bitmap_image& image1,bitmap_image& image2, const double threshold, const rgb_t colormap[]) { if ( (image1.width() != image2.width ()) || @@ -2517,7 +2592,7 @@ class cartesian_canvas image_drawer draw_; }; -rgb_store convert_wave_length_nm_to_rgb(const double wave_length_nm) +rgb_t convert_wave_length_nm_to_rgb(const double wave_length_nm) { // Credits: Dan Bruton http://www.physics.sfasu.edu/astro/color.html double red = 0.0; @@ -2572,7 +2647,7 @@ rgb_store convert_wave_length_nm_to_rgb(const double wave_length_nm) else factor = 0.0; - rgb_store result; + rgb_t result; const double gamma = 0.8; const double intensity_max = 255.0; @@ -2598,20 +2673,20 @@ double weighted_distance(const unsigned char r0, const unsigned char g0, const u return std::sqrt((diff_r * diff_r) + (diff_g * diff_g) + (diff_b * diff_b)); } -double weighted_distance(const rgb_store c0, const rgb_store c1) +double weighted_distance(const rgb_t c0, const rgb_t c1) { return weighted_distance(c0.red, c0.green, c0.blue, c1.red, c1.green, c1.blue); } template -rgb_store find_nearest_color(const rgb_store& c, const Iterator begin, const Iterator end) +rgb_t find_nearest_color(const rgb_t& c, const Iterator begin, const Iterator end) { if (0 == std::distance(begin,end)) return c; double min_d = std::numeric_limits::max(); - rgb_store result = *begin; + rgb_t result = *begin; for (Iterator itr = begin; itr != end; ++itr) { @@ -2634,18 +2709,18 @@ rgb_store find_nearest_color(const rgb_store& c, const Iterator begin, const Ite template