diff options
author | Thomas Beck <software@plasmasolutions.de> | 2015-12-28 13:55:14 +0300 |
---|---|---|
committer | Thomas Beck <software@plasmasolutions.de> | 2015-12-28 14:16:48 +0300 |
commit | daf6f5f81e241484ea8afc5d70ef3027969e5ac1 (patch) | |
tree | 723d322d646da66ce8beda142b493652463d9422 /source/blender/blenkernel | |
parent | 225b02fcd66052b1d6dfa4a146798e41c44e0cd4 (diff) |
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
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_sequencer.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/seqmodifier.c | 87 |
2 files changed, 87 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 3f2712e0ae1..4582d113941 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -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); diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 07242aa2f6e..f12faacd677 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -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)); |