diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/makesdna/DNA_sequence_types.h | 12 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sequencer.c | 61 | ||||
-rw-r--r-- | source/blender/sequencer/intern/modifier.c | 112 |
3 files changed, 170 insertions, 15 deletions
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 13bfa82b36d..a71f86eae9f 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -79,9 +79,13 @@ typedef struct StripTransform { } StripTransform; typedef struct StripColorBalance { + int method; float lift[3]; float gamma[3]; float gain[3]; + float slope[3]; + float offset[3]; + float power[3]; int flag; char _pad[4]; /* float exposure; */ @@ -434,6 +438,11 @@ typedef struct ColorBalanceModifierData { float color_multiply; } ColorBalanceModifierData; +enum { + SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN = 0, + SEQ_COLOR_BALANCE_METHOD_SLOPEOFFSETPOWER = 1, +}; + typedef struct CurvesModifierData { SequenceModifierData modifier; @@ -571,6 +580,9 @@ enum { #define SEQ_COLOR_BALANCE_INVERSE_GAIN 1 #define SEQ_COLOR_BALANCE_INVERSE_GAMMA 2 #define SEQ_COLOR_BALANCE_INVERSE_LIFT 4 +#define SEQ_COLOR_BALANCE_INVERSE_SLOPE 8 +#define SEQ_COLOR_BALANCE_INVERSE_OFFSET 16 +#define SEQ_COLOR_BALANCE_INVERSE_POWER 32 /* !!! has to be same as IMB_imbuf.h IMB_PROXY_... and IMB_TC_... */ diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 7303f6c920a..e519740259c 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1591,12 +1591,28 @@ static void rna_def_color_balance(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem method_items[] = { + {SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN, "LIFT_GAMMA_GAIN", 0, "Lift/Gamma/Gain", ""}, + {SEQ_COLOR_BALANCE_METHOD_SLOPEOFFSETPOWER, + "OFFSET_POWER_SLOPE", + 0, + "Offset/Power/Slope (ASC-CDL)", + "ASC-CDL standard color correction"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "SequenceColorBalanceData", NULL); RNA_def_struct_ui_text(srna, "Sequence Color Balance Data", "Color balance parameters for a sequence strip and its modifiers"); RNA_def_struct_sdna(srna, "StripColorBalance"); + prop = RNA_def_property(srna, "correction_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "method"); + RNA_def_property_enum_items(prop, method_items); + RNA_def_property_ui_text(prop, "Correction Method", ""); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + prop = RNA_def_property(srna, "lift", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_ui_text(prop, "Lift", "Color balance lift (shadows)"); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); @@ -1615,14 +1631,22 @@ static void rna_def_color_balance(BlenderRNA *brna) RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); - prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN); - RNA_def_property_ui_text(prop, "Inverse Gain", "Invert the gain color`"); + prop = RNA_def_property(srna, "slope", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Slope", "Correction for highlights"); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); - prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA); - RNA_def_property_ui_text(prop, "Inverse Gamma", "Invert the gamma color"); + prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Offset", "Correction for entire tonal range"); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + + prop = RNA_def_property(srna, "power", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_ui_text(prop, "Power", "Correction for midtones"); + RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); prop = RNA_def_property(srna, "invert_lift", PROP_BOOLEAN, PROP_NONE); @@ -1630,6 +1654,31 @@ static void rna_def_color_balance(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Inverse Lift", "Invert the lift color"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA); + RNA_def_property_ui_text(prop, "Inverse Gamma", "Invert the gamma color"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + + prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN); + RNA_def_property_ui_text(prop, "Inverse Gain", "Invert the gain color`"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + + prop = RNA_def_property(srna, "invert_slope", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_SLOPE); + RNA_def_property_ui_text(prop, "Inverse Slope", "Invert the slope color`"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + + prop = RNA_def_property(srna, "invert_offset", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_OFFSET); + RNA_def_property_ui_text(prop, "Inverse Offset", "Invert the offset color"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + + prop = RNA_def_property(srna, "invert_power", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_POWER); + RNA_def_property_ui_text(prop, "Inverse Power", "Invert the power color"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update"); + /* not yet used */ # if 0 prop = RNA_def_property(srna, "exposure", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c index 07d09f4ae17..8414599b225 100644 --- a/source/blender/sequencer/intern/modifier.c +++ b/source/blender/sequencer/intern/modifier.c @@ -216,7 +216,7 @@ static void modifier_apply_threaded(ImBuf *ibuf, /** \name Color Balance Modifier * \{ */ -static StripColorBalance calc_cb(StripColorBalance *cb_) +static StripColorBalance calc_cb_lgg(StripColorBalance *cb_) { StripColorBalance cb = *cb_; int c; @@ -262,8 +262,53 @@ static StripColorBalance calc_cb(StripColorBalance *cb_) return cb; } +static StripColorBalance calc_cb_sop(StripColorBalance *cb_) +{ + StripColorBalance cb = *cb_; + int c; + + for (c = 0; c < 3; c++) { + if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_SLOPE) { + if (cb.slope[c] != 0.0f) { + cb.slope[c] = 1.0f / cb.slope[c]; + } + else { + cb.slope[c] = 1000000; + } + } + + if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_OFFSET) { + cb.offset[c] = -1.0f * (cb.offset[c] - 1.0f); + } + else { + cb.offset[c] = cb.offset[c] - 1.0f; + } + + if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_POWER)) { + if (cb.power[c] != 0.0f) { + cb.power[c] = 1.0f / cb.power[c]; + } + else { + cb.power[c] = 1000000; + } + } + } + + return cb; +} + +static StripColorBalance calc_cb(StripColorBalance *cb_) +{ + if (cb_->method == SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN) { + return calc_cb_lgg(cb_); + } + else { /* cb_->method == SEQ_COLOR_BALANCE_METHOD_SLOPEOFFSETPOWER */ + return calc_cb_sop(cb_); + } +} + /* NOTE: lift is actually 2-lift. */ -MINLINE float color_balance_fl( +MINLINE float color_balance_fl_lgg( float in, const float lift, const float gain, const float gamma, const float mul) { float x = (((in - 1.0f) * lift) + 1.0f) * gain; @@ -278,12 +323,40 @@ MINLINE float color_balance_fl( return x; } -static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul) +MINLINE float color_balance_fl_sop(float in, + const float slope, + const float offset, + const float power, + const float pivot, + float mul) { - int y; + float x = in * slope + offset; + + /* prevent NaN */ + if (x < 0.0f) { + x = 0.0f; + } - for (y = 0; y < 256; y++) { - float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); + x = powf(x / pivot, power) * pivot; + x *= mul; + CLAMP(x, FLT_MIN, FLT_MAX); + return x; +} + +static void make_cb_table_float_lgg(float lift, float gain, float gamma, float *table, float mul) +{ + for (int y = 0; y < 256; y++) { + float v = color_balance_fl_lgg((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); + + table[y] = v; + } +} + +static void make_cb_table_float_sop( + float slope, float offset, float power, float pivot, float *table, float mul) +{ + for (int y = 0; y < 256; y++) { + float v = color_balance_fl_sop((float)y * (1.0f / 255.0f), slope, offset, power, pivot, mul); table[y] = v; } @@ -310,7 +383,13 @@ static void color_balance_byte_byte(StripColorBalance *cb_, straight_uchar_to_premul_float(p, cp); for (c = 0; c < 3; c++) { - float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + float t; + if (cb.method == SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN) { + t = color_balance_fl_lgg(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + } + else { + t = color_balance_fl_sop(p[c], cb.slope[c], cb.offset[c], cb.power[c], 1.0, mul); + } if (m) { float m_normal = (float)m[c] / 255.0f; @@ -352,7 +431,12 @@ static void color_balance_byte_float(StripColorBalance *cb_, cb = calc_cb(cb_); for (c = 0; c < 3; c++) { - make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); + if (cb.method == SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN) { + make_cb_table_float_lgg(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); + } + else { + make_cb_table_float_sop(cb.slope[c], cb.offset[c], cb.power[c], 1.0, cb_tab[c], mul); + } } for (i = 0; i < 256; i++) { @@ -397,7 +481,13 @@ static void color_balance_float_float(StripColorBalance *cb_, while (p < e) { int c; for (c = 0; c < 3; c++) { - float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + float t; + if (cb_->method == SEQ_COLOR_BALANCE_METHOD_LIFTGAMMAGAIN) { + t = color_balance_fl_lgg(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + } + else { + t = color_balance_fl_sop(p[c], cb.slope[c], cb.offset[c], cb.power[c], 1.0, mul); + } if (m) { p[c] = p[c] * (1.0f - m[c]) + t * m[c]; @@ -507,11 +597,15 @@ static void colorBalance_init_data(SequenceModifierData *smd) int c; cbmd->color_multiply = 1.0f; + cbmd->color_balance.method = 0; for (c = 0; c < 3; c++) { cbmd->color_balance.lift[c] = 1.0f; cbmd->color_balance.gamma[c] = 1.0f; cbmd->color_balance.gain[c] = 1.0f; + cbmd->color_balance.slope[c] = 1.0f; + cbmd->color_balance.offset[c] = 1.0f; + cbmd->color_balance.power[c] = 1.0f; } } |