forked from bartvdbraak/blender
White Balance modifier for the VSE
This snippet creates a white balance modifier for the video sequence editor. It is useful for everyone who likes to set a new white point in the video source (easily via the eyedropper). Just select a point in the source file where you know that it should be white. The algorithm will then shift the colors towards your new white point. See attached the image for a quick demo. {F270576} Reviewers: psy-fi Reviewed By: psy-fi Subscribers: Blendify Projects: #bf_blender Differential Revision: https://developer.blender.org/D1698
This commit is contained in:
parent
225b02fcd6
commit
daf6f5f81e
@ -1125,7 +1125,9 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
|
||||
col = box.column()
|
||||
col.prop(mod, "bright")
|
||||
col.prop(mod, "contrast")
|
||||
|
||||
elif mod.type == 'WHITE_BALANCE':
|
||||
col = box.column()
|
||||
col.prop(mod, "white_value")
|
||||
|
||||
class SEQUENCER_PT_grease_pencil(GreasePencilDataPanel, SequencerButtonsPanel_Output, Panel):
|
||||
bl_space_type = 'SEQUENCE_EDITOR'
|
||||
|
@ -458,7 +458,7 @@ typedef struct SequenceModifierTypeInfo {
|
||||
|
||||
const struct SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type);
|
||||
|
||||
struct SequenceModifierData *BKE_sequence_modifier_new(struct Sequence *seq, const char *name, int type);
|
||||
struct SequenceModifierData *BKE_sequence_modifier_new(struct Sequence *seq, const char *name, int type, struct Scene *scene);
|
||||
bool BKE_sequence_modifier_remove(struct Sequence *seq, struct SequenceModifierData *smd);
|
||||
void BKE_sequence_modifier_clear(struct Sequence *seq);
|
||||
void BKE_sequence_modifier_free(struct SequenceModifierData *smd);
|
||||
|
@ -42,12 +42,14 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "DNA_sequence_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_sequencer.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES];
|
||||
static bool modifierTypesInit = false;
|
||||
@ -173,6 +175,87 @@ static SequenceModifierTypeInfo seqModifier_ColorBalance = {
|
||||
colorBalance_apply /* apply */
|
||||
};
|
||||
|
||||
/* **** White Balance Modifier **** */
|
||||
|
||||
static void whiteBalance_init_data(SequenceModifierData *smd)
|
||||
{
|
||||
WhiteBalanceModifierData *cbmd = (WhiteBalanceModifierData *) smd;
|
||||
copy_v3_fl(cbmd->white_value, 1.0f);
|
||||
}
|
||||
|
||||
typedef struct WhiteBalanceThreadData {
|
||||
struct ColorSpace* colorspace;
|
||||
float white[3];
|
||||
} WhiteBalanceThreadData;
|
||||
|
||||
static void whiteBalance_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
|
||||
unsigned char *mask_rect, float *mask_rect_float, void *data_v)
|
||||
{
|
||||
int x, y;
|
||||
float multiplier[3];
|
||||
|
||||
WhiteBalanceThreadData *data = (WhiteBalanceThreadData *) data_v;
|
||||
|
||||
multiplier[0] = 1.0f/data->white[0];
|
||||
multiplier[1] = 1.0f/data->white[1];
|
||||
multiplier[2] = 1.0f/data->white[2];
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
int pixel_index = (y * width + x) * 4;
|
||||
float result[3], mask[3] = {1.0f, 1.0f, 1.0f};
|
||||
|
||||
if (rect_float)
|
||||
copy_v3_v3(result, rect_float + pixel_index);
|
||||
else
|
||||
{
|
||||
straight_uchar_to_premul_float(result, rect + pixel_index);
|
||||
IMB_colormanagement_colorspace_to_scene_linear_v3(result, data->colorspace);
|
||||
}
|
||||
|
||||
mul_v3_v3(result, multiplier);
|
||||
|
||||
if (mask_rect_float)
|
||||
copy_v3_v3(mask, mask_rect_float + pixel_index);
|
||||
else if (mask_rect)
|
||||
rgb_uchar_to_float(mask, mask_rect + pixel_index);
|
||||
|
||||
result[0] = result[0] * (1.0f - mask[0]) + result[0] * mask[0];
|
||||
result[1] = result[1] * (1.0f - mask[1]) + result[1] * mask[1];
|
||||
result[2] = result[2] * (1.0f - mask[2]) + result[2] * mask[2];
|
||||
|
||||
if (rect_float)
|
||||
copy_v3_v3(rect_float + pixel_index, result);
|
||||
else
|
||||
IMB_colormanagement_scene_linear_to_colorspace_v3(result, data->colorspace);
|
||||
premul_float_to_straight_uchar(rect + pixel_index, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void whiteBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
|
||||
{
|
||||
WhiteBalanceThreadData data;
|
||||
WhiteBalanceModifierData *wbmd = (WhiteBalanceModifierData *) smd;
|
||||
|
||||
copy_v3_v3(data.white, wbmd->white_value);
|
||||
IMB_colormanagement_display_to_scene_linear_v3(data.white,
|
||||
IMB_colormanagement_display_get_named(wbmd->modifier.scene->display_settings.display_device));
|
||||
data.colorspace = ibuf->rect_colorspace;
|
||||
|
||||
modifier_apply_threaded(ibuf, mask, whiteBalance_apply_threaded, &data);
|
||||
}
|
||||
|
||||
static SequenceModifierTypeInfo seqModifier_WhiteBalance = {
|
||||
CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "White Balance"), /* name */
|
||||
"WhiteBalanceModifierData", /* struct_name */
|
||||
sizeof(WhiteBalanceModifierData), /* struct_size */
|
||||
whiteBalance_init_data, /* init_data */
|
||||
NULL, /* free_data */
|
||||
NULL, /* copy_data */
|
||||
whiteBalance_apply /* apply */
|
||||
};
|
||||
|
||||
/* **** Curves Modifier **** */
|
||||
|
||||
static void curves_init_data(SequenceModifierData *smd)
|
||||
@ -559,6 +642,7 @@ static void sequence_modifier_type_info_init(void)
|
||||
INIT_TYPE(HueCorrect);
|
||||
INIT_TYPE(BrightContrast);
|
||||
INIT_TYPE(Mask);
|
||||
INIT_TYPE(WhiteBalance);
|
||||
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
@ -573,7 +657,7 @@ const SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
|
||||
return modifiersTypes[type];
|
||||
}
|
||||
|
||||
SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type)
|
||||
SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type, struct Scene *scene)
|
||||
{
|
||||
SequenceModifierData *smd;
|
||||
const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
|
||||
@ -582,6 +666,7 @@ SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name,
|
||||
|
||||
smd->type = type;
|
||||
smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
|
||||
smd->scene = scene;
|
||||
|
||||
if (!name || !name[0])
|
||||
BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
|
||||
|
@ -5486,6 +5486,7 @@ static void lib_link_sequence_modifiers(FileData *fd, Scene *scene, ListBase *lb
|
||||
for (smd = lb->first; smd; smd = smd->next) {
|
||||
if (smd->mask_id)
|
||||
smd->mask_id = newlibadr_us(fd, scene->id.lib, smd->mask_id);
|
||||
smd->scene = scene;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1503,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
|
||||
SequenceModifierData *smd;
|
||||
ColorBalanceModifierData *cbmd;
|
||||
|
||||
smd = BKE_sequence_modifier_new(seq, NULL, seqModifierType_ColorBalance);
|
||||
smd = BKE_sequence_modifier_new(seq, NULL, seqModifierType_ColorBalance, scene);
|
||||
cbmd = (ColorBalanceModifierData *) smd;
|
||||
|
||||
cbmd->color_balance = *strip->color_balance;
|
||||
|
@ -71,7 +71,7 @@ static int strip_modifier_add_exec(bContext *C, wmOperator *op)
|
||||
Sequence *seq = BKE_sequencer_active_get(scene);
|
||||
int type = RNA_enum_get(op->ptr, "type");
|
||||
|
||||
BKE_sequence_modifier_new(seq, NULL, type);
|
||||
BKE_sequence_modifier_new(seq, NULL, type, scene);
|
||||
|
||||
BKE_sequence_invalidate_cache(scene, seq);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
|
@ -307,11 +307,12 @@ typedef struct SequenceModifierData {
|
||||
int type, flag;
|
||||
char name[64]; /* MAX_NAME */
|
||||
|
||||
/* mask input, either sequence or maks ID */
|
||||
/* mask input, either sequence or mask ID */
|
||||
int mask_input_type, pad;
|
||||
|
||||
struct Sequence *mask_sequence;
|
||||
struct Mask *mask_id;
|
||||
struct Scene *scene;
|
||||
} SequenceModifierData;
|
||||
|
||||
typedef struct ColorBalanceModifierData {
|
||||
@ -344,6 +345,13 @@ typedef struct SequencerMaskModifierData {
|
||||
SequenceModifierData modifier;
|
||||
} SequencerMaskModifierData;
|
||||
|
||||
typedef struct WhiteBalanceModifierData {
|
||||
SequenceModifierData modifier;
|
||||
|
||||
float white_value[3];
|
||||
float pad;
|
||||
} WhiteBalanceModifierData;
|
||||
|
||||
/* ***************** Scopes ****************** */
|
||||
|
||||
typedef struct SequencerScopes {
|
||||
@ -519,6 +527,7 @@ enum {
|
||||
seqModifierType_HueCorrect = 3,
|
||||
seqModifierType_BrightContrast = 4,
|
||||
seqModifierType_Mask = 5,
|
||||
seqModifierType_WhiteBalance = 6,
|
||||
|
||||
NUM_SEQUENCE_MODIFIER_TYPES
|
||||
};
|
||||
|
@ -66,6 +66,7 @@ EnumPropertyItem rna_enum_sequence_modifier_type_items[] = {
|
||||
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
|
||||
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Bright/Contrast", ""},
|
||||
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""},
|
||||
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
@ -955,6 +956,8 @@ static StructRNA *rna_SequenceModifier_refine(struct PointerRNA *ptr)
|
||||
return &RNA_HueCorrectModifier;
|
||||
case seqModifierType_BrightContrast:
|
||||
return &RNA_BrightContrastModifier;
|
||||
case seqModifierType_WhiteBalance:
|
||||
return &RNA_WhiteBalanceModifier;
|
||||
default:
|
||||
return &RNA_SequenceModifier;
|
||||
}
|
||||
@ -1043,7 +1046,7 @@ static SequenceModifierData *rna_Sequence_modifier_new(Sequence *seq, bContext *
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
SequenceModifierData *smd;
|
||||
|
||||
smd = BKE_sequence_modifier_new(seq, name, type);
|
||||
smd = BKE_sequence_modifier_new(seq, name, type, scene);
|
||||
|
||||
BKE_sequence_invalidate_cache_for_modifier(scene, seq);
|
||||
|
||||
@ -2496,6 +2499,22 @@ static void rna_def_colorbalance_modifier(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_whitebalance_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "WhiteBalanceModifier", "SequenceModifier");
|
||||
RNA_def_struct_sdna(srna, "WhiteBalanceModifierData");
|
||||
RNA_def_struct_ui_text(srna, "WhiteBalanceModifier", "White balance modifier for sequence strip");
|
||||
|
||||
prop = RNA_def_property(srna, "white_value", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "white_value");
|
||||
RNA_def_property_ui_text(prop, "White value", "This color defines white in the strip");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_curves_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -2558,6 +2577,7 @@ static void rna_def_modifiers(BlenderRNA *brna)
|
||||
rna_def_curves_modifier(brna);
|
||||
rna_def_hue_modifier(brna);
|
||||
rna_def_brightcontrast_modifier(brna);
|
||||
rna_def_whitebalance_modifier(brna);
|
||||
}
|
||||
|
||||
void RNA_def_sequencer(BlenderRNA *brna)
|
||||
|
Loading…
Reference in New Issue
Block a user