diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-05-08 18:20:57 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2013-05-08 18:20:57 +0400 |
commit | f25e7d62b3023812eb594250d22e142c02533482 (patch) | |
tree | cd1654a7700147e0620f944b9079b7767c617916 /source/blender/blenkernel | |
parent | 89eb80fb686c14fc1f34ced450ceb03a7d871fec (diff) |
Mask modifier for sequences
This modifier uses a mask set in the modifier settings
and multiplies strip by it. Alpha channel will also be
multiplied by mask, which makes it easy to mask some
objects on footage and alpha-over them in sequencer.
Actually, this modifier sets alpha for byte strips
directly (since byte is always straight alpha) and
multiplies float buffer by mask (flaots are premulled)
so in both cases masked strip could be easy alpha-overed
without any artifacts.
It uses own structure with only SequenceModifierData
property in to preserve both forward and backwards
compatibilities (using new structure ensures modifier
will be ignored on load in older blenders, the same
happens for mesh modifiers actually).
Request from Pablo Vazquez.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/intern/seqmodifier.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c index 1787bd11298..b374fb14657 100644 --- a/source/blender/blenkernel/intern/seqmodifier.c +++ b/source/blender/blenkernel/intern/seqmodifier.c @@ -487,6 +487,71 @@ static SequenceModifierTypeInfo seqModifier_BrightContrast = { brightcontrast_apply /* apply */ }; +/* **** Mask Modifier **** */ + +static void maskmodifier_apply_threaded(int width, int height, unsigned char *rect, float *rect_float, + unsigned char *mask_rect, float *mask_rect_float, void *UNUSED(data_v)) +{ + int x, y; + + if (rect && !mask_rect) + return; + + if (rect_float && !mask_rect_float) + return; + + 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; + unsigned char *mask_pixel = mask_rect + pixel_index; + unsigned char mask = min_iii(mask_pixel[0], mask_pixel[1], mask_pixel[2]); + + /* byte buffer is straight, so only affect on alpha itself, + * this is the only way to alpha-over byte strip after + * applying mask modifier. + */ + pixel[3] = (float)(pixel[3] * mask) / 255.0f; + } + else if (rect_float) { + int c; + float *pixel = rect_float + pixel_index; + float *mask_pixel = mask_rect_float + pixel_index; + float mask = min_fff(mask_pixel[0], mask_pixel[1], mask_pixel[2]); + + /* float buffers are premultiplied, so need to premul color + * as well to make it easy to alpha-over masted strip. + */ + for (c = 0; c < 4; c++) + pixel[c] = pixel[c] * mask; + } + } + } +} + +static void maskmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) +{ + BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd; + BrightContrastThreadData data; + + data.bright = bcmd->bright; + data.contrast = bcmd->contrast; + + modifier_apply_threaded(ibuf, mask, maskmodifier_apply_threaded, &data); +} + +static SequenceModifierTypeInfo seqModifier_Mask = { + CTX_N_(BLF_I18NCONTEXT_ID_SEQUENCE, "Mask"), /* name */ + "SequencerMaskModifierData", /* struct_name */ + sizeof(SequencerMaskModifierData), /* struct_size */ + NULL, /* init_data */ + NULL, /* free_data */ + NULL, /* copy_data */ + maskmodifier_apply /* apply */ +}; + /*********************** Modifier functions *************************/ static void sequence_modifier_type_info_init(void) @@ -497,6 +562,7 @@ static void sequence_modifier_type_info_init(void) INIT_TYPE(Curves); INIT_TYPE(HueCorrect); INIT_TYPE(BrightContrast); + INIT_TYPE(Mask); #undef INIT_TYPE } |