Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-08-11 18:37:58 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-08-11 18:37:58 +0400
commita794e19346ab6ee30e14e8175c153b03fa6cb7a5 (patch)
tree611279ea79071664c525cc978758b92758b652a5 /source/blender/blenkernel/intern/sequencer.c
parentbe4ae581fff820cefc21d150080e13f621b99cdd (diff)
Sequencer: support for masked color balance
This implements option which could be used to color balance only specified area. Currently done by adding Mask input to Adjustment effect. Affects on color balance and multiply settings. Supporting masked saturation control is in the list, not supported in this commit. Also show value slider in the right of color wheel.
Diffstat (limited to 'source/blender/blenkernel/intern/sequencer.c')
-rw-r--r--source/blender/blenkernel/intern/sequencer.c180
1 files changed, 121 insertions, 59 deletions
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 4f1b324bc28..920588d9f47 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1426,12 +1426,13 @@ static void make_cb_table_float(float lift, float gain, float gamma,
}
}
-static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, int width, int height, float mul)
+static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, unsigned char *mask_rect, int width, int height, float mul)
{
unsigned char cb_tab[3][256];
int c;
unsigned char *p = rect;
unsigned char *e = p + width * 4 * height;
+ unsigned char *m = mask_rect;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
@@ -1440,20 +1441,32 @@ static void color_balance_byte_byte(Sequence *seq, unsigned char *rect, int widt
}
while (p < e) {
- p[0] = cb_tab[0][p[0]];
- p[1] = cb_tab[1][p[1]];
- p[2] = cb_tab[2][p[2]];
+ if (m) {
+ float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+
+ p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
+ p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
+ p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+
+ m += 4;
+ }
+ else {
+ p[0] = cb_tab[0][p[0]];
+ p[1] = cb_tab[1][p[1]];
+ p[2] = cb_tab[2][p[2]];
+ }
p += 4;
}
}
-static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, int width, int height, float mul)
+static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *rect_float, unsigned char *mask_rect, int width, int height, float mul)
{
float cb_tab[4][256];
int c, i;
unsigned char *p = rect;
unsigned char *e = p + width * 4 * height;
+ unsigned char *m = mask_rect;
float *o;
StripColorBalance cb;
@@ -1470,27 +1483,48 @@ static void color_balance_byte_float(Sequence *seq, unsigned char *rect, float *
}
while (p < e) {
- o[0] = cb_tab[0][p[0]];
- o[1] = cb_tab[1][p[1]];
- o[2] = cb_tab[2][p[2]];
+ if (m) {
+ float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+
+ p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
+ p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
+ p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]];
+
+ m += 4;
+ }
+ else {
+ o[0] = cb_tab[0][p[0]];
+ o[1] = cb_tab[1][p[1]];
+ o[2] = cb_tab[2][p[2]];
+ }
+
o[3] = cb_tab[3][p[3]];
p += 4; o += 4;
}
}
-static void color_balance_float_float(Sequence *seq, float *rect_float, int width, int height, float mul)
+static void color_balance_float_float(Sequence *seq, float *rect_float, float *mask_rect_float, int width, int height, float mul)
{
float *p = rect_float;
float *e = rect_float + width * 4 * height;
+ float *m = mask_rect_float;
StripColorBalance cb = calc_cb(seq->strip->color_balance);
while (p < e) {
int c;
for (c = 0; c < 3; c++) {
- p[c] = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
+ float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul);
+
+ if (m)
+ p[c] = p[c] * (1.0f - m[c]) + t * m[c];
+ else
+ p[c] = t;
}
+
p += 4;
+ if (m)
+ m += 4;
}
}
@@ -1498,6 +1532,7 @@ typedef struct ColorBalanceInitData {
Sequence *seq;
ImBuf *ibuf;
float mul;
+ ImBuf *mask;
} ColorBalanceInitData;
typedef struct ColorBalanceThread {
@@ -1506,8 +1541,8 @@ typedef struct ColorBalanceThread {
int width, height;
- unsigned char *rect;
- float *rect_float;
+ unsigned char *rect, *mask_rect;
+ float *rect_float, *mask_rect_float;
} ColorBalanceThread;
static void color_balance_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
@@ -1515,6 +1550,7 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
ColorBalanceThread *handle = (ColorBalanceThread *) handle_v;
ColorBalanceInitData *init_data = (ColorBalanceInitData *) init_data_v;
ImBuf *ibuf = init_data->ibuf;
+ ImBuf *mask = init_data->mask;
int offset = 4 * start_line * ibuf->x;
@@ -1530,6 +1566,18 @@ static void color_balance_init_handle(void *handle_v, int start_line, int tot_li
if (ibuf->rect_float)
handle->rect_float = ibuf->rect_float + offset;
+
+ if (mask) {
+ if (mask->rect)
+ handle->mask_rect = (unsigned char *) mask->rect + offset;
+
+ if (mask->rect_float)
+ handle->mask_rect_float = mask->rect_float + offset;
+ }
+ else {
+ handle->mask_rect = NULL;
+ handle->mask_rect_float = NULL;
+ }
}
static void *color_balance_do_thread(void *thread_data_v)
@@ -1538,53 +1586,60 @@ static void *color_balance_do_thread(void *thread_data_v)
Sequence *seq = thread_data->seq;
int width = thread_data->width, height = thread_data->height;
unsigned char *rect = thread_data->rect;
+ unsigned char *mask_rect = thread_data->mask_rect;
float *rect_float = thread_data->rect_float;
+ float *mask_rect_float = thread_data->mask_rect_float;
float mul = thread_data->mul;
if (rect_float) {
- color_balance_float_float(seq, rect_float, width, height, mul);
+ color_balance_float_float(seq, rect_float, mask_rect_float, width, height, mul);
}
else if (seq->flag & SEQ_MAKE_FLOAT) {
- color_balance_byte_float(seq, rect, rect_float, width, height, mul);
+ color_balance_byte_float(seq, rect, rect_float, mask_rect, width, height, mul);
}
else {
- color_balance_byte_byte(seq, rect, width, height, mul);
+ color_balance_byte_byte(seq, rect, mask_rect, width, height, mul);
}
return NULL;
}
-static void color_balance(Sequence *seq, ImBuf *ibuf, float mul)
+static void color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
{
+ ColorBalanceInitData init_data;
+
if (!ibuf->rect_float && seq->flag & SEQ_MAKE_FLOAT)
imb_addrectfloatImBuf(ibuf);
- if (BLI_thread_is_main()) {
- /* color balance could have been called from prefetching job which
- * is already multithreaded, so doing threading here makes no sense
- */
- ColorBalanceInitData init_data;
-
- init_data.seq = seq;
- init_data.ibuf = ibuf;
- init_data.mul = mul;
-
- IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
- color_balance_init_handle, color_balance_do_thread);
+ init_data.seq = seq;
+ init_data.ibuf = ibuf;
+ init_data.mul = mul;
+ init_data.mask = NULL;
+
+ if (seq->mask_sequence) {
+ if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
+ ImBuf *mask = seq_render_strip(context, seq->mask_sequence, cfra);
+
+ if (mask) {
+ if (ibuf->rect_float) {
+ if (!mask->rect_float)
+ IMB_float_from_rect(mask);
+ }
+ else {
+ if (!mask->rect)
+ IMB_rect_from_float(mask);
+ }
+ init_data.mask = mask;
+ }
+ }
}
- else {
- ColorBalanceThread handle;
- handle.seq = seq;
- handle.mul = mul;
- handle.width = ibuf->x;
- handle.height = ibuf->y;
- handle.rect = (unsigned char *)ibuf->rect;
- handle.rect_float = ibuf->rect_float;
+ IMB_processor_apply_threaded(ibuf->y, sizeof(ColorBalanceThread), &init_data,
+ color_balance_init_handle, color_balance_do_thread);
- color_balance_do_thread(&handle);
- }
+ if (init_data.mask)
+ IMB_freeImBuf(init_data.mask);
}
/*
@@ -1632,7 +1687,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
return FALSE;
}
-static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float UNUSED(cfra), ImBuf *ibuf,
+static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra, ImBuf *ibuf,
int is_proxy_image, int is_preprocessed)
{
float mul;
@@ -1727,7 +1782,7 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float UNUSE
}
if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
- color_balance(seq, ibuf, mul);
+ color_balance(context, seq, ibuf, mul, cfra);
mul = 1.0;
}
@@ -2784,11 +2839,34 @@ static void free_anim_seq(Sequence *seq)
}
}
+/* check whether sequence cur depends on seq */
+int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
+{
+ /* sequences are not intersecting in time, assume no dependency exists between them */
+ if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp)
+ return FALSE;
+
+ /* checking sequence is below reference one, not dependent on it */
+ if (cur->machine < seq->machine)
+ return FALSE;
+
+ /* sequence is not blending with lower machines, no dependency here occurs
+ * check for non-effects only since effect could use lower machines as input
+ */
+ if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
+ ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
+ (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
{
Editing *ed = scene->ed;
Sequence *cur;
- int left = seq->startdisp, right = seq->enddisp;
/* invalidate cache for current sequence */
BKE_sequencer_cache_cleanup_sequence(seq);
@@ -2796,27 +2874,11 @@ void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
/* invalidate cache for all dependent sequences */
SEQ_BEGIN (ed, cur)
{
- int cur_left = cur->startdisp, cur_right = cur->enddisp;
-
if (cur == seq)
continue;
- /* sequence is outside of changed one, shouldn't be invalidated */
- if (cur_right < left || cur_left > right)
- continue;
-
- /* sequence is below changed one, not dependent on it */
- if (cur->machine < seq->machine)
- continue;
-
- /* sequence is not blending with lower machines, no need to invalidate */
- if ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
- (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f))
- {
- continue;
- }
-
- BKE_sequencer_cache_cleanup_sequence(cur);
+ if (BKE_sequence_check_depend(seq, cur))
+ BKE_sequencer_cache_cleanup_sequence(cur);
}
SEQ_END
}