From 6da2b27aecd1e3ccea21abc6f57e219cd811aab6 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Wed, 10 Oct 2012 22:30:35 +0200 Subject: [PATCH] Add an unsharp mask effect, to complement the more expensive deconvolution sharpening. --- Makefile | 1 + unsharp_mask_effect.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ unsharp_mask_effect.h | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 unsharp_mask_effect.cpp create mode 100644 unsharp_mask_effect.h diff --git a/Makefile b/Makefile index c33d20a..301aa2f 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ OBJS += mirror_effect.o OBJS += blur_effect.o OBJS += diffusion_effect.o OBJS += glow_effect.o +OBJS += unsharp_mask_effect.o OBJS += mix_effect.o OBJS += resize_effect.o OBJS += deconvolution_sharpen_effect.o diff --git a/unsharp_mask_effect.cpp b/unsharp_mask_effect.cpp new file mode 100644 index 0000000..db8ccd2 --- /dev/null +++ b/unsharp_mask_effect.cpp @@ -0,0 +1,40 @@ +#include +#include + +#include "unsharp_mask_effect.h" +#include "blur_effect.h" +#include "mix_effect.h" +#include "effect_chain.h" +#include "util.h" + +UnsharpMaskEffect::UnsharpMaskEffect() + : blur(new BlurEffect), + mix(new MixEffect) +{ + mix->set_float("strength_first", 1.0f); + mix->set_float("strength_second", -0.3f); +} + +void UnsharpMaskEffect::rewrite_graph(EffectChain *graph, Node *self) +{ + assert(self->incoming_links.size() == 1); + Node *input = self->incoming_links[0]; + + Node *blur_node = graph->add_node(blur); + Node *mix_node = graph->add_node(mix); + graph->replace_receiver(self, mix_node); + graph->connect_nodes(input, blur_node); + graph->connect_nodes(blur_node, mix_node); + graph->replace_sender(self, mix_node); + + self->disabled = true; +} + +bool UnsharpMaskEffect::set_float(const std::string &key, float value) { + printf("%s = %f\n", key.c_str(), value); + if (key == "amount") { + bool ok = mix->set_float("strength_first", 1.0f + value); + return ok && mix->set_float("strength_second", -value); + } + return blur->set_float(key, value); +} diff --git a/unsharp_mask_effect.h b/unsharp_mask_effect.h new file mode 100644 index 0000000..45a04f0 --- /dev/null +++ b/unsharp_mask_effect.h @@ -0,0 +1,40 @@ +#ifndef _UNSHARP_MASK_EFFECT_H +#define _UNSHARP_MASK_EFFECT_H 1 + +// Unsharp mask is probably the most popular way of doing sharpening today, +// although it does not always deliver the best results (it is very prone +// to haloing). It simply consists of removing a blurred copy of the image from +// itself (multiplied by some strength factor). In this aspect, it's similar to +// glow, except by subtracting instead of adding. +// +// See DeconvolutionSharpenEffect for a different, possibly better +// sharpening algorithm. + +#include "effect.h" + +class BlurEffect; +class MixEffect; + +class UnsharpMaskEffect : public Effect { +public: + UnsharpMaskEffect(); + virtual std::string effect_type_id() const { return "UnsharpMaskEffect"; } + + virtual bool needs_srgb_primaries() const { return false; } + + virtual void rewrite_graph(EffectChain *graph, Node *self); + virtual bool set_float(const std::string &key, float value); + + virtual std::string output_fragment_shader() { + assert(false); + } + virtual void set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num) { + assert(false); + } + +private: + BlurEffect *blur; + MixEffect *mix; +}; + +#endif // !defined(_UNSHARP_MASK_EFFECT_H) -- 2.39.2