CXX=g++
CXXFLAGS=-Wall
LDFLAGS=-lSDL -lSDL_image -lGL
-OBJS=main.o util.o widgets.o effect.o
+OBJS=main.o util.o widgets.o effect.o effect_chain.o
+OBJS += lift_gamma_gain_effect.o gamma_expansion_effect.o colorspace_conversion_effect.o
test: $(OBJS)
$(CXX) -o test $(OBJS) $(LDFLAGS)
--- /dev/null
+#include "colorspace_conversion_effect.h"
+
+ColorSpaceConversionEffect::ColorSpaceConversionEffect()
+ : source_space(COLORSPACE_sRGB),
+ destination_space(COLORSPACE_sRGB)
+{
+ register_int("source_space", (int *)&source_space);
+ register_int("destination_space", (int *)&destination_space);
+}
--- /dev/null
+#ifndef _COLORSPACE_CONVERSION_EFFECT_H
+#define _COLORSPACE_CONVERSION_EFFECT_H 1
+
+#include "effect.h"
+#include "effect_chain.h"
+
+class ColorSpaceConversionEffect : public Effect {
+public:
+ ColorSpaceConversionEffect();
+
+private:
+ ColorSpace source_space, destination_space;
+};
+
+#endif // !defined(_COLORSPACE_CONVERSION_EFFECT_H)
#include <map>
#include <string>
+// Can alias on a float[3].
+struct RGBTriplet {
+ RGBTriplet(float r, float g, float b)
+ : r(r), g(g), b(b) {}
+
+ float r, g, b;
+};
+
class Effect {
public:
virtual bool needs_linear_light() { return true; }
--- /dev/null
+#include <assert.h>
+
+#include "effect_chain.h"
+#include "gamma_expansion_effect.h"
+#include "lift_gamma_gain_effect.h"
+#include "colorspace_conversion_effect.h"
+
+EffectChain::EffectChain(unsigned width, unsigned height)
+ : width(width), height(height) {}
+
+void EffectChain::add_input(const ImageFormat &format)
+{
+ input_format = format;
+ current_color_space = format.color_space;
+ current_gamma_curve = format.gamma_curve;
+}
+
+void EffectChain::add_output(const ImageFormat &format)
+{
+ output_format = format;
+}
+
+Effect *instantiate_effect(EffectId effect)
+{
+ switch (effect) {
+ case GAMMA_CONVERSION:
+ return new GammaExpansionEffect();
+ case RGB_PRIMARIES_CONVERSION:
+ return new GammaExpansionEffect();
+ case LIFT_GAMMA_GAIN:
+ return new LiftGammaGainEffect();
+ }
+ assert(false);
+}
+
+Effect *EffectChain::add_effect(EffectId effect_id)
+{
+ Effect *effect = instantiate_effect(effect_id);
+
+ if (effect->needs_linear_light() && current_gamma_curve != GAMMA_LINEAR) {
+ GammaExpansionEffect *gamma_conversion = new GammaExpansionEffect();
+ gamma_conversion->set_int("source_curve", current_gamma_curve);
+ effects.push_back(gamma_conversion);
+ current_gamma_curve = GAMMA_LINEAR;
+ }
+
+ if (effect->needs_srgb_primaries() && current_color_space != COLORSPACE_sRGB) {
+ assert(current_gamma_curve == GAMMA_LINEAR);
+ ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect();
+ colorspace_conversion->set_int("source_space", current_color_space);
+ colorspace_conversion->set_int("destination_space", COLORSPACE_sRGB);
+ effects.push_back(colorspace_conversion);
+ current_color_space = COLORSPACE_sRGB;
+ }
+
+ effects.push_back(effect);
+ return effect;
+}
+
--- /dev/null
+#ifndef _EFFECT_CHAIN_H
+#define _EFFECT_CHAIN_H 1
+
+#include <vector>
+
+#include "effect.h"
+#include "effect_id.h"
+
+enum PixelFormat { FORMAT_RGB, FORMAT_RGBA };
+
+enum ColorSpace {
+ COLORSPACE_sRGB = 0,
+ COLORSPACE_REC_709 = 0, // Same as sRGB.
+ COLORSPACE_REC_601_525 = 1,
+ COLORSPACE_REC_601_625 = 2,
+};
+
+enum GammaCurve {
+ GAMMA_LINEAR = 0,
+ GAMMA_sRGB = 1,
+ GAMMA_REC_601 = 2,
+ GAMMA_REC_709 = 2, // Same as Rec. 601.
+};
+
+struct ImageFormat {
+ PixelFormat pixel_format;
+ ColorSpace color_space;
+ GammaCurve gamma_curve;
+};
+
+class EffectChain {
+public:
+ EffectChain(unsigned width, unsigned height);
+ void add_input(const ImageFormat &format);
+
+ // The pointer is owned by EffectChain.
+ Effect *add_effect(EffectId effect);
+
+ void add_output(const ImageFormat &format);
+
+ void render(unsigned char *src, unsigned char *dst);
+
+private:
+ unsigned width, height;
+ ImageFormat input_format, output_format;
+ std::vector<Effect *> effects;
+
+ ColorSpace current_color_space;
+ GammaCurve current_gamma_curve;
+};
+
+
+#endif // !defined(_EFFECT_CHAIN_H)
--- /dev/null
+#ifndef _EFFECT_ID_H
+#define _EFFECT_ID_H 1
+
+enum EffectId {
+ // Mostly for internal use.
+ GAMMA_CONVERSION = 0,
+ RGB_PRIMARIES_CONVERSION,
+
+ // Color.
+ LIFT_GAMMA_GAIN,
+};
+
+#endif // !defined(_EFFECT_ID_H)
--- /dev/null
+#include "gamma_expansion_effect.h"j
+
+GammaExpansionEffect::GammaExpansionEffect()
+ : source_curve(GAMMA_LINEAR)
+{
+ register_int("source_curve", (int *)&source_curve);
+}
--- /dev/null
+#ifndef _GAMMA_EXPANSION_EFFECT_H
+#define _GAMMA_EXPANSION_EFFECT_H 1
+
+#include "effect.h"
+#include "effect_chain.h"
+
+class GammaExpansionEffect : public Effect {
+public:
+ GammaExpansionEffect();
+
+private:
+ GammaCurve source_curve;
+};
+
+#endif // !defined(_GAMMA_EXPANSION_EFFECT_H)
--- /dev/null
+#include "lift_gamma_gain_effect.h"
+
+LiftGammaGainEffect::LiftGammaGainEffect()
+ : lift(0.0f, 0.0f, 0.0f),
+ gamma(1.0f, 1.0f, 1.0f),
+ gain(1.0f, 1.0f, 1.0f),
+ saturation(1.0f)
+{
+ register_vec3("lift", (float *)&lift);
+ register_vec3("gamma", (float *)&gamma);
+ register_vec3("gain", (float *)&gain);
+ register_float("saturation", &saturation);
+}
--- /dev/null
+#ifndef _LIFT_GAMMA_GAIN_EFFECT_H
+#define _LIFT_GAMMA_GAIN_EFFECT_H 1
+
+#include "effect.h"
+
+class LiftGammaGainEffect : public Effect {
+public:
+ LiftGammaGainEffect();
+
+private:
+ RGBTriplet lift, gamma, gain;
+ float saturation;
+};
+
+#endif // !defined(_LIFT_GAMMA_GAIN_EFFECT_H)
#include <GL/glext.h>
#include "effect.h"
+#include "effect_chain.h"
#include "util.h"
#include "widgets.h"
#include "texture_enum.h"
float gamma_r = 1.0f, gamma_g = 1.0f, gamma_b = 1.0f;
float gain_r = 1.0f, gain_g = 1.0f, gain_b = 1.0f;
-enum PixelFormat { FORMAT_RGB, FORMAT_RGBA };
-
-enum ColorSpace {
- COLORSPACE_sRGB = 0,
- COLORSPACE_REC_709 = 0, // Same as sRGB.
- COLORSPACE_REC_601_525 = 1,
- COLORSPACE_REC_601_625 = 2,
-};
-
-enum GammaCurve {
- GAMMA_LINEAR = 0,
- GAMMA_sRGB = 1,
- GAMMA_REC_601 = 2,
- GAMMA_REC_709 = 2, // Same as Rec. 601.
-};
-
-struct ImageFormat {
- PixelFormat pixel_format;
- ColorSpace color_space;
- GammaCurve gamma_curve;
-};
-
-enum EffectId {
- // Mostly for internal use.
- GAMMA_CONVERSION = 0,
- RGB_PRIMARIES_CONVERSION,
-
- // Color.
- LIFT_GAMMA_GAIN,
-};
-
-// Can alias on a float[3].
-struct RGBTriplet {
- RGBTriplet(float r, float g, float b)
- : r(r), g(g), b(b) {}
-
- float r, g, b;
-};
-
-class GammaExpansionEffect : public Effect {
-public:
- GammaExpansionEffect()
- : source_curve(GAMMA_LINEAR)
- {
- register_int("source_curve", (int *)&source_curve);
- }
-
-private:
- GammaCurve source_curve;
-};
-
-class ColorSpaceConversionEffect : public Effect {
-public:
- ColorSpaceConversionEffect()
- : source_space(COLORSPACE_sRGB),
- destination_space(COLORSPACE_sRGB)
- {
- register_int("source_space", (int *)&source_space);
- register_int("destination_space", (int *)&destination_space);
- }
-
-private:
- ColorSpace source_space, destination_space;
-};
-
-class ColorSpaceConversionEffect;
-
-class LiftGammaGainEffect : public Effect {
-public:
- LiftGammaGainEffect()
- : lift(0.0f, 0.0f, 0.0f),
- gamma(1.0f, 1.0f, 1.0f),
- gain(1.0f, 1.0f, 1.0f),
- saturation(1.0f)
- {
- register_vec3("lift", (float *)&lift);
- register_vec3("gamma", (float *)&gamma);
- register_vec3("gain", (float *)&gain);
- register_float("saturation", &saturation);
- }
-
-private:
- RGBTriplet lift, gamma, gain;
- float saturation;
-};
-
-class EffectChain {
-public:
- EffectChain(unsigned width, unsigned height);
- void add_input(const ImageFormat &format);
-
- // The pointer is owned by EffectChain.
- Effect *add_effect(EffectId effect);
-
- void add_output(const ImageFormat &format);
-
- void render(unsigned char *src, unsigned char *dst);
-
-private:
- unsigned width, height;
- ImageFormat input_format, output_format;
- std::vector<Effect *> effects;
-
- ColorSpace current_color_space;
- GammaCurve current_gamma_curve;
-};
-
-EffectChain::EffectChain(unsigned width, unsigned height)
- : width(width), height(height) {}
-
-void EffectChain::add_input(const ImageFormat &format)
-{
- input_format = format;
- current_color_space = format.color_space;
- current_gamma_curve = format.gamma_curve;
-}
-
-void EffectChain::add_output(const ImageFormat &format)
-{
- output_format = format;
-}
-
-Effect *instantiate_effect(EffectId effect)
-{
- switch (effect) {
- case GAMMA_CONVERSION:
- return new GammaExpansionEffect();
- case RGB_PRIMARIES_CONVERSION:
- return new GammaExpansionEffect();
- case LIFT_GAMMA_GAIN:
- return new LiftGammaGainEffect();
- }
- assert(false);
-}
-
-Effect *EffectChain::add_effect(EffectId effect_id)
-{
- Effect *effect = instantiate_effect(effect_id);
-
- if (effect->needs_linear_light() && current_gamma_curve != GAMMA_LINEAR) {
- GammaExpansionEffect *gamma_conversion = new GammaExpansionEffect();
- gamma_conversion->set_int("source_curve", current_gamma_curve);
- effects.push_back(gamma_conversion);
- current_gamma_curve = GAMMA_LINEAR;
- }
-
- if (effect->needs_srgb_primaries() && current_color_space != COLORSPACE_sRGB) {
- assert(current_gamma_curve == GAMMA_LINEAR);
- ColorSpaceConversionEffect *colorspace_conversion = new ColorSpaceConversionEffect();
- colorspace_conversion->set_int("source_space", current_color_space);
- colorspace_conversion->set_int("destination_space", COLORSPACE_sRGB);
- effects.push_back(colorspace_conversion);
- current_color_space = COLORSPACE_sRGB;
- }
-
- effects.push_back(effect);
- return effect;
-}
-
GLhandleARB read_shader(const char* filename, GLenum type)
{
static char buf[131072];