Sequencer: bright/contrast modifier

Behaves in exactly the same way as bright/contrast compositor node.

Some code could be de-duplicated, like contrast formula and mask
influence, but wouldn't call it stopper for commit since it's
already needed for grading Mango.
This commit is contained in:
Sergey Sharybin
2012-08-24 09:07:04 +00:00
parent 93d89ec768
commit 501efb0e7c
4 changed files with 138 additions and 0 deletions

View File

@@ -930,6 +930,10 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
box.template_curve_mapping(mod, "curve_mapping", type='COLOR')
elif mod.type == 'HUE_CORRECT':
box.template_curve_mapping(mod, "curve_mapping", type='HUE')
elif mod.type == 'BRIGHT_CONTRAST':
col = box.column()
col.prop(mod, "bright")
col.prop(mod, "contrast")
if __name__ == "__main__": # only for live edit.

View File

@@ -394,6 +394,106 @@ static SequenceModifierTypeInfo seqModifier_HueCorrect = {
hue_correct_apply /* apply */
};
/* **** Bright/Contrast Modifier **** */
typedef struct BrightContrastThreadData {
float bright;
float contrast;
} BrightContrastThreadData;
void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
unsigned char *mask_rect, float *mask_rect_float, void *data_v)
{
BrightContrastThreadData *data = (BrightContrastThreadData *) data_v;
int x, y;
float i;
int c;
float a, b, v;
float brightness = data->bright / 100.0f;
float contrast = data->contrast;
float delta = contrast / 200.0f;
a = 1.0f - delta * 2.0f;
/*
* The algorithm is by Werner D. Streidt
* (http://visca.com/ffactory/archives/5-99/msg00021.html)
* Extracted of OpenCV demhist.c
*/
if (contrast > 0) {
a = 1.0f / a;
b = a * (brightness - delta);
}
else {
delta *= -1;
b = a * (brightness + delta);
}
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int pixel_index = (y * width + x) * 4;
if (rect) {
unsigned char *pixel = rect + pixel_index;
for (c = 0; c < 3; c++) {
i = pixel[c];
v = a * i + b;
if (mask_rect) {
unsigned char *m = mask_rect + pixel_index;
float t = (float) m[c] / 255.0f;
pixel[c] = pixel[c] * (1.0f - t) + v * t;
}
else
pixel[c] = v;
}
}
else if (rect_float) {
float *pixel = rect_float + pixel_index;
for (c = 0; c < 3; c++) {
i = pixel[c];
v = a * i + b;
if (mask_rect_float) {
float *m = mask_rect_float + pixel_index;
pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
}
else
pixel[c] = v;
}
}
}
}
}
ImBuf *brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd;
BrightContrastThreadData data;
ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
data.bright = bcmd->bright;
data.contrast = bcmd->contrast;
modifier_apply_threaded(ibuf_new, mask, brightcontrast_apply_threaded, &data);
return ibuf_new;
}
static SequenceModifierTypeInfo seqModifier_BrightContrast = {
"Bright/Contrast", /* name */
"BrightContrastModifierData", /* struct_name */
sizeof(BrightContrastModifierData), /* struct_size */
NULL, /* init_data */
NULL, /* free_data */
NULL, /* copy_data */
brightcontrast_apply /* apply */
};
/*********************** Modifier functions *************************/
static void sequence_modifier_type_info_init(void)
@@ -403,6 +503,7 @@ static void sequence_modifier_type_info_init(void)
INIT_TYPE(ColorBalance);
INIT_TYPE(Curves);
INIT_TYPE(HueCorrect);
INIT_TYPE(BrightContrast);
#undef INIT_TYPE
}

View File

@@ -271,6 +271,13 @@ typedef struct HueCorrectModifierData {
struct CurveMapping curve_mapping;
} HueCorrectModifierData;
typedef struct BrightContrastModifierData {
SequenceModifierData modifier;
float bright;
float contrast;
} BrightContrastModifierData;
#define MAXSEQ 32
#define SELECT 1
@@ -401,6 +408,7 @@ enum {
seqModifierType_ColorBalance = 1,
seqModifierType_Curves = 2,
seqModifierType_HueCorrect = 3,
seqModifierType_BrightContrast = 4,
NUM_SEQUENCE_MODIFIER_TYPES
};

View File

@@ -63,6 +63,7 @@ EnumPropertyItem sequence_modifier_type_items[] = {
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Bright/Contrast", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -918,6 +919,8 @@ static StructRNA *rna_SequenceModifier_refine(struct PointerRNA *ptr)
return &RNA_CurvesModifier;
case seqModifierType_HueCorrect:
return &RNA_HueCorrectModifier;
case seqModifierType_BrightContrast:
return &RNA_BrightContrastModifier;
default:
return &RNA_SequenceModifier;
}
@@ -2340,12 +2343,34 @@ static void rna_def_hue_modifier(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_brightcontrast_modifier(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "BrightContrastModifier", "SequenceModifier");
RNA_def_struct_sdna(srna, "BrightContrastModifierData");
RNA_def_struct_ui_text(srna, "BrightContrastModifier", "Bright/contrast modifier data for sequence strip");
prop = RNA_def_property(srna, "bright", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "bright");
RNA_def_property_ui_text(prop, "Bright", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "contrast");
RNA_def_property_ui_text(prop, "Contrast", "");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
static void rna_def_modifiers(BlenderRNA *brna)
{
rna_def_modifier(brna);
rna_def_colorbalance_modifier(brna);
rna_def_curves_modifier(brna);
rna_def_hue_modifier(brna);
rna_def_brightcontrast_modifier(brna);
}
void RNA_def_sequencer(BlenderRNA *brna)