From f9a21bb54b5103ce5b891297f0daebfd493bddd0 Mon Sep 17 00:00:00 2001 From: Elvish_Hunter Date: Wed, 11 Mar 2015 12:37:14 +0100 Subject: [PATCH] ImagePathWML: added ~SEPIA() function --- src/image_modifications.cpp | 11 ++++++++++ src/image_modifications.hpp | 8 +++++++ src/sdl/utils.cpp | 42 +++++++++++++++++++++++++++++++++++++ src/sdl/utils.hpp | 1 + 4 files changed, 62 insertions(+) diff --git a/src/image_modifications.cpp b/src/image_modifications.cpp index b3c70b14d9d7..6c4759d0dbc4 100644 --- a/src/image_modifications.cpp +++ b/src/image_modifications.cpp @@ -200,6 +200,11 @@ surface gs_modification::operator()(const surface& src) const return greyscale_image(src); } +surface sepia_modification::operator()(const surface &src) const +{ + return sepia_image(src); +} + surface plot_alpha_modification::operator()(const surface& src) const { return alpha_to_greyscale(src); @@ -744,6 +749,12 @@ REGISTER_MOD_PARSER(GS, ) return new gs_modification; } +// Sepia +REGISTER_MOD_PARSER(SEPIA, ) +{ + return new sepia_modification; +} + // Plot Alpha REGISTER_MOD_PARSER(PLOT_ALPHA, ) { diff --git a/src/image_modifications.hpp b/src/image_modifications.hpp index c0d23a98b327..96f8ed41e6b5 100644 --- a/src/image_modifications.hpp +++ b/src/image_modifications.hpp @@ -221,6 +221,14 @@ class gs_modification : public modification virtual surface operator()(const surface& src) const; }; +/** + * Give to the image a sepia tint (SEPIA) + */ +struct sepia_modification : modification +{ + virtual surface operator()(const surface &src) const; +}; + /** * Plot Alpha (Alpha) modification */ diff --git a/src/sdl/utils.cpp b/src/sdl/utils.cpp index a59ac5b64fdd..f19f946dedae 100644 --- a/src/sdl/utils.cpp +++ b/src/sdl/utils.cpp @@ -989,6 +989,48 @@ surface greyscale_image(const surface &surf, bool optimize) return optimize ? create_optimized_surface(nsurf) : nsurf; } +surface sepia_image(const surface &surf, bool optimize) +{ + if(surf == NULL) + return NULL; + + surface nsurf(make_neutral_surface(surf)); + if(nsurf == NULL) { + std::cerr << "failed to make neutral surface\n"; + return NULL; + } + + { + surface_lock lock(nsurf); + Uint32* beg = lock.pixels(); + Uint32* end = beg + nsurf->w*surf->h; + + while(beg != end) { + Uint8 alpha = (*beg) >> 24; + + if(alpha) { + Uint8 r, g, b; + r = (*beg) >> 16; + g = (*beg) >> 8; + b = (*beg); + + // this is the formula for applying a sepia effect + // that can be found on various web sites + // for example here: https://software.intel.com/sites/default/files/article/346220/sepiafilter-intelcilkplus.pdf + Uint8 outRed = std::min(255, static_cast((r * 0.393) + (g * 0.769) + (b * 0.189))); + Uint8 outGreen = std::min(255, static_cast((r * 0.349) + (g * 0.686) + (b * 0.168))); + Uint8 outBlue = std::min(255, static_cast((r * 0.272) + (g * 0.534) + (b * 0.131))); + + *beg = (alpha << 24) | (outRed << 16) | (outGreen << 8) | (outBlue); + } + + ++beg; + } + } + + return optimize ? create_optimized_surface(nsurf) : nsurf; +} + surface alpha_to_greyscale(const surface &surf, bool optimize) { if(surf == NULL) diff --git a/src/sdl/utils.hpp b/src/sdl/utils.hpp index 7aef9804438b..00e80ad9649a 100644 --- a/src/sdl/utils.hpp +++ b/src/sdl/utils.hpp @@ -246,6 +246,7 @@ surface tile_surface(const surface &surf, int w, int h, bool optimize=true); surface adjust_surface_color(const surface &surf, int r, int g, int b, bool optimize=true); surface greyscale_image(const surface &surf, bool optimize=true); +surface sepia_image(const surface &surf, bool optimize=true); surface alpha_to_greyscale(const surface & surf, bool optimize=true); surface wipe_alpha(const surface & surf, bool optimize=true); /** create an heavy shadow of the image, by blurring, increasing alpha and darkening */