+enum EffectType {
+ WHITE_BALANCE_EFFECT,
+ RESAMPLE_EFFECT,
+ PADDING_EFFECT,
+ INTEGRAL_PADDING_EFFECT,
+ OVERLAY_EFFECT,
+ RESIZE_EFFECT,
+ MULTIPLY_EFFECT,
+ MIX_EFFECT,
+ LIFT_GAMMA_GAIN_EFFECT
+};
+
+Effect *instantiate_effect(EffectChain *chain, EffectType effect_type)
+{
+ switch (effect_type) {
+ case WHITE_BALANCE_EFFECT:
+ return new WhiteBalanceEffect;
+ case RESAMPLE_EFFECT:
+ return new ResampleEffect;
+ case PADDING_EFFECT:
+ return new PaddingEffect;
+ case INTEGRAL_PADDING_EFFECT:
+ return new IntegralPaddingEffect;
+ case OVERLAY_EFFECT:
+ return new OverlayEffect;
+ case RESIZE_EFFECT:
+ return new ResizeEffect;
+ case MULTIPLY_EFFECT:
+ return new MultiplyEffect;
+ case MIX_EFFECT:
+ return new MixEffect;
+ case LIFT_GAMMA_GAIN_EFFECT:
+ return new LiftGammaGainEffect;
+ default:
+ fprintf(stderr, "Unhandled effect type %d\n", effect_type);
+ abort();
+ }
+}
+
+// An EffectBlueprint refers to an Effect before it's being added to the graph.
+// It contains enough information to instantiate the effect, including any
+// parameters that were set before it was added to the graph. Once it is
+// instantiated, it forwards its calls on to the real Effect instead.
+struct EffectBlueprint {
+ EffectBlueprint(EffectType effect_type) : effect_type(effect_type) {}
+
+ EffectType effect_type;
+ map<string, int> int_parameters;
+ map<string, float> float_parameters;
+ map<string, array<float, 3>> vec3_parameters;
+ map<string, array<float, 4>> vec4_parameters;
+
+ Effect *effect = nullptr; // Gets filled out when it's instantiated.
+};
+
+Effect *get_effect_from_blueprint(EffectChain *chain, lua_State *L, int idx)