-private:
- std::map<std::string, int *> params_int;
- std::map<std::string, float *> params_float;
- std::map<std::string, float *> params_vec3;
-};
-
-bool Effect::set_int(const std::string &key, int value)
-{
- if (params_int.count(key) == 0) {
- return false;
- }
- *params_int[key] = value;
- return true;
-}
-
-bool Effect::set_float(const std::string &key, float value)
-{
- if (params_float.count(key) == 0) {
- return false;
- }
- *params_float[key] = value;
- return true;
-}
-
-bool Effect::set_vec3(const std::string &key, const float *values)
-{
- if (params_vec3.count(key) == 0) {
- return false;
- }
- memcpy(params_vec3[key], values, sizeof(float) * 3);
- return true;
-}
-
-void Effect::register_int(const std::string &key, int *value)
-{
- assert(params_int.count(key) == 0);
- params_int[key] = value;
-}
-
-void Effect::register_float(const std::string &key, float *value)
-{
- assert(params_float.count(key) == 0);
- params_float[key] = value;
-}
-
-void Effect::register_vec3(const std::string &key, float *values)
-{
- assert(params_vec3.count(key) == 0);
- params_vec3[key] = values;
-}
-
-// 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)