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:
Diffstat (limited to 'source/blender/blenkernel/intern/seqmodifier.c')
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c1439
1 files changed, 741 insertions, 698 deletions
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index ce0928f8ff1..29a5d556aef 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -49,611 +49,660 @@ static bool modifierTypesInit = false;
/*********************** Modifiers *************************/
-typedef void (*modifier_apply_threaded_cb) (int width, int height, unsigned char *rect, float *rect_float,
- unsigned char *mask_rect, float *mask_rect_float, void *data_v);
+typedef void (*modifier_apply_threaded_cb)(int width,
+ int height,
+ unsigned char *rect,
+ float *rect_float,
+ unsigned char *mask_rect,
+ float *mask_rect_float,
+ void *data_v);
typedef struct ModifierInitData {
- ImBuf *ibuf;
- ImBuf *mask;
- void *user_data;
+ ImBuf *ibuf;
+ ImBuf *mask;
+ void *user_data;
- modifier_apply_threaded_cb apply_callback;
+ modifier_apply_threaded_cb apply_callback;
} ModifierInitData;
typedef struct ModifierThread {
- int width, height;
+ int width, height;
- unsigned char *rect, *mask_rect;
- float *rect_float, *mask_rect_float;
+ unsigned char *rect, *mask_rect;
+ float *rect_float, *mask_rect_float;
- void *user_data;
+ void *user_data;
- modifier_apply_threaded_cb apply_callback;
+ modifier_apply_threaded_cb apply_callback;
} ModifierThread;
-
-static ImBuf *modifier_mask_get(SequenceModifierData *smd, const SeqRenderData *context, int cfra, int fra_offset, bool make_float)
+static ImBuf *modifier_mask_get(SequenceModifierData *smd,
+ const SeqRenderData *context,
+ int cfra,
+ int fra_offset,
+ bool make_float)
{
- return BKE_sequencer_render_mask_input(context, smd->mask_input_type, smd->mask_sequence, smd->mask_id, cfra, fra_offset, make_float);
+ return BKE_sequencer_render_mask_input(context,
+ smd->mask_input_type,
+ smd->mask_sequence,
+ smd->mask_id,
+ cfra,
+ fra_offset,
+ make_float);
}
static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v)
{
- ModifierThread *handle = (ModifierThread *) handle_v;
- ModifierInitData *init_data = (ModifierInitData *) init_data_v;
- ImBuf *ibuf = init_data->ibuf;
- ImBuf *mask = init_data->mask;
+ ModifierThread *handle = (ModifierThread *)handle_v;
+ ModifierInitData *init_data = (ModifierInitData *)init_data_v;
+ ImBuf *ibuf = init_data->ibuf;
+ ImBuf *mask = init_data->mask;
- int offset = 4 * start_line * ibuf->x;
+ int offset = 4 * start_line * ibuf->x;
- memset(handle, 0, sizeof(ModifierThread));
+ memset(handle, 0, sizeof(ModifierThread));
- handle->width = ibuf->x;
- handle->height = tot_line;
- handle->apply_callback = init_data->apply_callback;
- handle->user_data = init_data->user_data;
+ handle->width = ibuf->x;
+ handle->height = tot_line;
+ handle->apply_callback = init_data->apply_callback;
+ handle->user_data = init_data->user_data;
- if (ibuf->rect)
- handle->rect = (unsigned char *) ibuf->rect + offset;
+ if (ibuf->rect)
+ handle->rect = (unsigned char *)ibuf->rect + offset;
- if (ibuf->rect_float)
- handle->rect_float = ibuf->rect_float + offset;
+ 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) {
+ 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;
- }
+ if (mask->rect_float)
+ handle->mask_rect_float = mask->rect_float + offset;
+ }
+ else {
+ handle->mask_rect = NULL;
+ handle->mask_rect_float = NULL;
+ }
}
static void *modifier_do_thread(void *thread_data_v)
{
- ModifierThread *td = (ModifierThread *) thread_data_v;
+ ModifierThread *td = (ModifierThread *)thread_data_v;
- td->apply_callback(td->width, td->height, td->rect, td->rect_float, td->mask_rect, td->mask_rect_float, td->user_data);
+ td->apply_callback(td->width,
+ td->height,
+ td->rect,
+ td->rect_float,
+ td->mask_rect,
+ td->mask_rect_float,
+ td->user_data);
- return NULL;
+ return NULL;
}
-static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_threaded_cb apply_callback, void *user_data)
+static void modifier_apply_threaded(ImBuf *ibuf,
+ ImBuf *mask,
+ modifier_apply_threaded_cb apply_callback,
+ void *user_data)
{
- ModifierInitData init_data;
+ ModifierInitData init_data;
- init_data.ibuf = ibuf;
- init_data.mask = mask;
- init_data.user_data = user_data;
+ init_data.ibuf = ibuf;
+ init_data.mask = mask;
+ init_data.user_data = user_data;
- init_data.apply_callback = apply_callback;
+ init_data.apply_callback = apply_callback;
- IMB_processor_apply_threaded(ibuf->y, sizeof(ModifierThread), &init_data,
- modifier_init_handle, modifier_do_thread);
+ IMB_processor_apply_threaded(
+ ibuf->y, sizeof(ModifierThread), &init_data, modifier_init_handle, modifier_do_thread);
}
/* **** Color Balance Modifier **** */
static void colorBalance_init_data(SequenceModifierData *smd)
{
- ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
- int c;
+ ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd;
+ int c;
- cbmd->color_multiply = 1.0f;
+ cbmd->color_multiply = 1.0f;
- for (c = 0; c < 3; c++) {
- cbmd->color_balance.lift[c] = 1.0f;
- cbmd->color_balance.gamma[c] = 1.0f;
- cbmd->color_balance.gain[c] = 1.0f;
- }
+ for (c = 0; c < 3; c++) {
+ cbmd->color_balance.lift[c] = 1.0f;
+ cbmd->color_balance.gamma[c] = 1.0f;
+ cbmd->color_balance.gain[c] = 1.0f;
+ }
}
static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
- ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
+ ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd;
- BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
+ BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask);
}
static SequenceModifierTypeInfo seqModifier_ColorBalance = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Color Balance"), /* name */
- "ColorBalanceModifierData", /* struct_name */
- sizeof(ColorBalanceModifierData), /* struct_size */
- colorBalance_init_data, /* init_data */
- NULL, /* free_data */
- NULL, /* copy_data */
- colorBalance_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Color Balance"), /* name */
+ "ColorBalanceModifierData", /* struct_name */
+ sizeof(ColorBalanceModifierData), /* struct_size */
+ colorBalance_init_data, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ 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);
+ WhiteBalanceModifierData *cbmd = (WhiteBalanceModifierData *)smd;
+ copy_v3_fl(cbmd->white_value, 1.0f);
}
typedef struct WhiteBalanceThreadData {
- float white[3];
+ 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)
+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];
+ int x, y;
+ float multiplier[3];
- WhiteBalanceThreadData *data = (WhiteBalanceThreadData *) data_v;
+ WhiteBalanceThreadData *data = (WhiteBalanceThreadData *)data_v;
- multiplier[0] = (data->white[0] != 0.0f) ? 1.0f / data->white[0] : FLT_MAX;
- multiplier[1] = (data->white[1] != 0.0f) ? 1.0f / data->white[1] : FLT_MAX;
- multiplier[2] = (data->white[2] != 0.0f) ? 1.0f / data->white[2] : FLT_MAX;
+ multiplier[0] = (data->white[0] != 0.0f) ? 1.0f / data->white[0] : FLT_MAX;
+ multiplier[1] = (data->white[1] != 0.0f) ? 1.0f / data->white[1] : FLT_MAX;
+ multiplier[2] = (data->white[2] != 0.0f) ? 1.0f / data->white[2] : FLT_MAX;
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- int pixel_index = (y * width + x) * 4;
- float rgba[4], result[4], mask[3] = {1.0f, 1.0f, 1.0f};
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+ float rgba[4], result[4], mask[3] = {1.0f, 1.0f, 1.0f};
- if (rect_float) {
- copy_v3_v3(rgba, rect_float + pixel_index);
- }
- else {
- straight_uchar_to_premul_float(rgba, rect + pixel_index);
- }
+ if (rect_float) {
+ copy_v3_v3(rgba, rect_float + pixel_index);
+ }
+ else {
+ straight_uchar_to_premul_float(rgba, rect + pixel_index);
+ }
- copy_v4_v4(result, rgba);
+ copy_v4_v4(result, rgba);
#if 0
- mul_v3_v3(result, multiplier);
+ mul_v3_v3(result, multiplier);
#else
- /* similar to division without the clipping */
- for (int i = 0; i < 3; i++) {
- result[i] = 1.0f - powf(1.0f - rgba[i], multiplier[i]);
- }
+ /* similar to division without the clipping */
+ for (int i = 0; i < 3; i++) {
+ result[i] = 1.0f - powf(1.0f - rgba[i], multiplier[i]);
+ }
#endif
- 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] = rgba[0] * (1.0f - mask[0]) + result[0] * mask[0];
- result[1] = rgba[1] * (1.0f - mask[1]) + result[1] * mask[1];
- result[2] = rgba[2] * (1.0f - mask[2]) + result[2] * mask[2];
-
- if (rect_float) {
- copy_v3_v3(rect_float + pixel_index, result);
- }
- else {
- premul_float_to_straight_uchar(rect + pixel_index, result);
- }
- }
- }
+ 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] = rgba[0] * (1.0f - mask[0]) + result[0] * mask[0];
+ result[1] = rgba[1] * (1.0f - mask[1]) + result[1] * mask[1];
+ result[2] = rgba[2] * (1.0f - mask[2]) + result[2] * mask[2];
+
+ if (rect_float) {
+ copy_v3_v3(rect_float + pixel_index, result);
+ }
+ else {
+ 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;
+ WhiteBalanceThreadData data;
+ WhiteBalanceModifierData *wbmd = (WhiteBalanceModifierData *)smd;
- copy_v3_v3(data.white, wbmd->white_value);
+ copy_v3_v3(data.white, wbmd->white_value);
- modifier_apply_threaded(ibuf, mask, whiteBalance_apply_threaded, &data);
+ 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 */
+ 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)
{
- CurvesModifierData *cmd = (CurvesModifierData *) smd;
+ CurvesModifierData *cmd = (CurvesModifierData *)smd;
- curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
+ curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
}
static void curves_free_data(SequenceModifierData *smd)
{
- CurvesModifierData *cmd = (CurvesModifierData *) smd;
+ CurvesModifierData *cmd = (CurvesModifierData *)smd;
- curvemapping_free_data(&cmd->curve_mapping);
+ curvemapping_free_data(&cmd->curve_mapping);
}
static void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
- CurvesModifierData *cmd = (CurvesModifierData *) smd;
- CurvesModifierData *cmd_target = (CurvesModifierData *) target;
+ CurvesModifierData *cmd = (CurvesModifierData *)smd;
+ CurvesModifierData *cmd_target = (CurvesModifierData *)target;
- curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
+ curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
}
-static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
- unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+static void curves_apply_threaded(int width,
+ int height,
+ unsigned char *rect,
+ float *rect_float,
+ unsigned char *mask_rect,
+ float *mask_rect_float,
+ void *data_v)
{
- CurveMapping *curve_mapping = (CurveMapping *) data_v;
- int x, y;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- int pixel_index = (y * width + x) * 4;
-
- if (rect_float) {
- float *pixel = rect_float + pixel_index;
- float result[3];
-
- curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
-
- if (mask_rect_float) {
- const float *m = mask_rect_float + pixel_index;
-
- pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
- pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
- pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
- }
- else {
- pixel[0] = result[0];
- pixel[1] = result[1];
- pixel[2] = result[2];
- }
- }
- if (rect) {
- unsigned char *pixel = rect + pixel_index;
- float result[3], tempc[4];
-
- straight_uchar_to_premul_float(tempc, pixel);
-
- curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
-
- if (mask_rect) {
- float t[3];
-
- rgb_uchar_to_float(t, mask_rect + pixel_index);
-
- tempc[0] = tempc[0] * (1.0f - t[0]) + result[0] * t[0];
- tempc[1] = tempc[1] * (1.0f - t[1]) + result[1] * t[1];
- tempc[2] = tempc[2] * (1.0f - t[2]) + result[2] * t[2];
- }
- else {
- tempc[0] = result[0];
- tempc[1] = result[1];
- tempc[2] = result[2];
- }
-
- premul_float_to_straight_uchar(pixel, tempc);
- }
- }
- }
+ CurveMapping *curve_mapping = (CurveMapping *)data_v;
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+
+ if (rect_float) {
+ float *pixel = rect_float + pixel_index;
+ float result[3];
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, pixel);
+
+ if (mask_rect_float) {
+ const float *m = mask_rect_float + pixel_index;
+
+ pixel[0] = pixel[0] * (1.0f - m[0]) + result[0] * m[0];
+ pixel[1] = pixel[1] * (1.0f - m[1]) + result[1] * m[1];
+ pixel[2] = pixel[2] * (1.0f - m[2]) + result[2] * m[2];
+ }
+ else {
+ pixel[0] = result[0];
+ pixel[1] = result[1];
+ pixel[2] = result[2];
+ }
+ }
+ if (rect) {
+ unsigned char *pixel = rect + pixel_index;
+ float result[3], tempc[4];
+
+ straight_uchar_to_premul_float(tempc, pixel);
+
+ curvemapping_evaluate_premulRGBF(curve_mapping, result, tempc);
+
+ if (mask_rect) {
+ float t[3];
+
+ rgb_uchar_to_float(t, mask_rect + pixel_index);
+
+ tempc[0] = tempc[0] * (1.0f - t[0]) + result[0] * t[0];
+ tempc[1] = tempc[1] * (1.0f - t[1]) + result[1] * t[1];
+ tempc[2] = tempc[2] * (1.0f - t[2]) + result[2] * t[2];
+ }
+ else {
+ tempc[0] = result[0];
+ tempc[1] = result[1];
+ tempc[2] = result[2];
+ }
+
+ premul_float_to_straight_uchar(pixel, tempc);
+ }
+ }
+ }
}
static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
- CurvesModifierData *cmd = (CurvesModifierData *) smd;
+ CurvesModifierData *cmd = (CurvesModifierData *)smd;
- float black[3] = {0.0f, 0.0f, 0.0f};
- float white[3] = {1.0f, 1.0f, 1.0f};
+ float black[3] = {0.0f, 0.0f, 0.0f};
+ float white[3] = {1.0f, 1.0f, 1.0f};
- curvemapping_initialize(&cmd->curve_mapping);
+ curvemapping_initialize(&cmd->curve_mapping);
- curvemapping_premultiply(&cmd->curve_mapping, 0);
- curvemapping_set_black_white(&cmd->curve_mapping, black, white);
+ curvemapping_premultiply(&cmd->curve_mapping, 0);
+ curvemapping_set_black_white(&cmd->curve_mapping, black, white);
- modifier_apply_threaded(ibuf, mask, curves_apply_threaded, &cmd->curve_mapping);
+ modifier_apply_threaded(ibuf, mask, curves_apply_threaded, &cmd->curve_mapping);
- curvemapping_premultiply(&cmd->curve_mapping, 1);
+ curvemapping_premultiply(&cmd->curve_mapping, 1);
}
static SequenceModifierTypeInfo seqModifier_Curves = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Curves"), /* name */
- "CurvesModifierData", /* struct_name */
- sizeof(CurvesModifierData), /* struct_size */
- curves_init_data, /* init_data */
- curves_free_data, /* free_data */
- curves_copy_data, /* copy_data */
- curves_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Curves"), /* name */
+ "CurvesModifierData", /* struct_name */
+ sizeof(CurvesModifierData), /* struct_size */
+ curves_init_data, /* init_data */
+ curves_free_data, /* free_data */
+ curves_copy_data, /* copy_data */
+ curves_apply, /* apply */
};
/* **** Hue Correct Modifier **** */
static void hue_correct_init_data(SequenceModifierData *smd)
{
- HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
- int c;
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
+ int c;
- curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
+ curvemapping_set_defaults(&hcmd->curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
+ hcmd->curve_mapping.preset = CURVE_PRESET_MID9;
- for (c = 0; c < 3; c++) {
- CurveMap *cuma = &hcmd->curve_mapping.cm[c];
+ for (c = 0; c < 3; c++) {
+ CurveMap *cuma = &hcmd->curve_mapping.cm[c];
- curvemap_reset(cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE);
- }
+ curvemap_reset(
+ cuma, &hcmd->curve_mapping.clipr, hcmd->curve_mapping.preset, CURVEMAP_SLOPE_POSITIVE);
+ }
- /* default to showing Saturation */
- hcmd->curve_mapping.cur = 1;
+ /* default to showing Saturation */
+ hcmd->curve_mapping.cur = 1;
}
static void hue_correct_free_data(SequenceModifierData *smd)
{
- HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
- curvemapping_free_data(&hcmd->curve_mapping);
+ curvemapping_free_data(&hcmd->curve_mapping);
}
static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
- HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
- HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target;
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
+ HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *)target;
- curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
+ curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
}
-static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
- unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+static void hue_correct_apply_threaded(int width,
+ int height,
+ unsigned char *rect,
+ float *rect_float,
+ unsigned char *mask_rect,
+ float *mask_rect_float,
+ void *data_v)
{
- CurveMapping *curve_mapping = (CurveMapping *) data_v;
- int x, y;
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- int pixel_index = (y * width + x) * 4;
- float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
- float hsv[3], f;
-
- if (rect_float)
- copy_v3_v3(pixel, rect_float + pixel_index);
- else
- rgb_uchar_to_float(pixel, rect + pixel_index);
-
- rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
-
- /* adjust hue, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
- hsv[0] += f - 0.5f;
-
- /* adjust saturation, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
- hsv[1] *= (f * 2.0f);
-
- /* adjust value, scaling returned default 0.5 up to 1 */
- f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
- hsv[2] *= (f * 2.f);
-
- hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
- CLAMP(hsv[1], 0.0f, 1.0f);
-
- /* convert back to rgb */
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
-
- 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] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
- result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
- result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
-
- if (rect_float)
- copy_v3_v3(rect_float + pixel_index, result);
- else
- rgb_float_to_uchar(rect + pixel_index, result);
- }
- }
+ CurveMapping *curve_mapping = (CurveMapping *)data_v;
+ int x, y;
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+ float pixel[3], result[3], mask[3] = {1.0f, 1.0f, 1.0f};
+ float hsv[3], f;
+
+ if (rect_float)
+ copy_v3_v3(pixel, rect_float + pixel_index);
+ else
+ rgb_uchar_to_float(pixel, rect + pixel_index);
+
+ rgb_to_hsv(pixel[0], pixel[1], pixel[2], hsv, hsv + 1, hsv + 2);
+
+ /* adjust hue, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 0, hsv[0]);
+ hsv[0] += f - 0.5f;
+
+ /* adjust saturation, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 1, hsv[0]);
+ hsv[1] *= (f * 2.0f);
+
+ /* adjust value, scaling returned default 0.5 up to 1 */
+ f = curvemapping_evaluateF(curve_mapping, 2, hsv[0]);
+ hsv[2] *= (f * 2.f);
+
+ hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */
+ CLAMP(hsv[1], 0.0f, 1.0f);
+
+ /* convert back to rgb */
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], result, result + 1, result + 2);
+
+ 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] = pixel[0] * (1.0f - mask[0]) + result[0] * mask[0];
+ result[1] = pixel[1] * (1.0f - mask[1]) + result[1] * mask[1];
+ result[2] = pixel[2] * (1.0f - mask[2]) + result[2] * mask[2];
+
+ if (rect_float)
+ copy_v3_v3(rect_float + pixel_index, result);
+ else
+ rgb_float_to_uchar(rect + pixel_index, result);
+ }
+ }
}
static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
- HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
+ HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
- curvemapping_initialize(&hcmd->curve_mapping);
+ curvemapping_initialize(&hcmd->curve_mapping);
- modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
+ modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
}
static SequenceModifierTypeInfo seqModifier_HueCorrect = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Hue Correct"), /* name */
- "HueCorrectModifierData", /* struct_name */
- sizeof(HueCorrectModifierData), /* struct_size */
- hue_correct_init_data, /* init_data */
- hue_correct_free_data, /* free_data */
- hue_correct_copy_data, /* copy_data */
- hue_correct_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Hue Correct"), /* name */
+ "HueCorrectModifierData", /* struct_name */
+ sizeof(HueCorrectModifierData), /* struct_size */
+ hue_correct_init_data, /* init_data */
+ hue_correct_free_data, /* free_data */
+ hue_correct_copy_data, /* copy_data */
+ hue_correct_apply, /* apply */
};
/* **** Bright/Contrast Modifier **** */
typedef struct BrightContrastThreadData {
- float bright;
- float contrast;
+ float bright;
+ float contrast;
} BrightContrastThreadData;
-static 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)
+static 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 = (float) pixel[c] / 255.0f;
- v = a * i + b;
-
- if (mask_rect) {
- unsigned char *m = mask_rect + pixel_index;
- float t = (float) m[c] / 255.0f;
-
- v = (float) pixel[c] / 255.0f * (1.0f - t) + v * t;
- }
-
- pixel[c] = unit_float_to_uchar_clamp(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) {
- const float *m = mask_rect_float + pixel_index;
-
- pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
- }
- else
- pixel[c] = 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 = (float)pixel[c] / 255.0f;
+ v = a * i + b;
+
+ if (mask_rect) {
+ unsigned char *m = mask_rect + pixel_index;
+ float t = (float)m[c] / 255.0f;
+
+ v = (float)pixel[c] / 255.0f * (1.0f - t) + v * t;
+ }
+
+ pixel[c] = unit_float_to_uchar_clamp(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) {
+ const float *m = mask_rect_float + pixel_index;
+
+ pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
+ }
+ else
+ pixel[c] = v;
+ }
+ }
+ }
+ }
}
static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
- BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd;
- BrightContrastThreadData data;
+ BrightContrastModifierData *bcmd = (BrightContrastModifierData *)smd;
+ BrightContrastThreadData data;
- data.bright = bcmd->bright;
- data.contrast = bcmd->contrast;
+ data.bright = bcmd->bright;
+ data.contrast = bcmd->contrast;
- modifier_apply_threaded(ibuf, mask, brightcontrast_apply_threaded, &data);
+ modifier_apply_threaded(ibuf, mask, brightcontrast_apply_threaded, &data);
}
static SequenceModifierTypeInfo seqModifier_BrightContrast = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Bright/Contrast"), /* name */
- "BrightContrastModifierData", /* struct_name */
- sizeof(BrightContrastModifierData), /* struct_size */
- NULL, /* init_data */
- NULL, /* free_data */
- NULL, /* copy_data */
- brightcontrast_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Bright/Contrast"), /* name */
+ "BrightContrastModifierData", /* struct_name */
+ sizeof(BrightContrastModifierData), /* struct_size */
+ NULL, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ 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))
+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;
- const 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;
- }
- }
- }
+ 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;
+ const 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 *UNUSED(smd), ImBuf *ibuf, ImBuf *mask)
{
- // SequencerMaskModifierData *bcmd = (SequencerMaskModifierData *)smd;
+ // SequencerMaskModifierData *bcmd = (SequencerMaskModifierData *)smd;
- modifier_apply_threaded(ibuf, mask, maskmodifier_apply_threaded, NULL);
+ modifier_apply_threaded(ibuf, mask, maskmodifier_apply_threaded, NULL);
}
static SequenceModifierTypeInfo seqModifier_Mask = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Mask"), /* name */
- "SequencerMaskModifierData", /* struct_name */
- sizeof(SequencerMaskModifierData), /* struct_size */
- NULL, /* init_data */
- NULL, /* free_data */
- NULL, /* copy_data */
- maskmodifier_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Mask"), /* name */
+ "SequencerMaskModifierData", /* struct_name */
+ sizeof(SequencerMaskModifierData), /* struct_size */
+ NULL, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ maskmodifier_apply, /* apply */
};
/* **** Tonemap Modifier **** */
typedef struct AvgLogLum {
- SequencerTonemapModifierData *tmmd;
- struct ColorSpace *colorspace;
- float al;
- float auto_key;
- float lav;
- float cav[4];
- float igm;
+ SequencerTonemapModifierData *tmmd;
+ struct ColorSpace *colorspace;
+ float al;
+ float auto_key;
+ float lav;
+ float cav[4];
+ float igm;
} AvgLogLum;
static void tonemapmodifier_init_data(SequenceModifierData *smd)
{
- SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *) smd;
- /* Same as tonemap compositor node. */
- tmmd->type = SEQ_TONEMAP_RD_PHOTORECEPTOR;
- tmmd->key = 0.18f;
- tmmd->offset = 1.0f;
- tmmd->gamma = 1.0f;
- tmmd->intensity = 0.0f;
- tmmd->contrast = 0.0f;
- tmmd->adaptation = 1.0f;
- tmmd->correction = 0.0f;
+ SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *)smd;
+ /* Same as tonemap compositor node. */
+ tmmd->type = SEQ_TONEMAP_RD_PHOTORECEPTOR;
+ tmmd->key = 0.18f;
+ tmmd->offset = 1.0f;
+ tmmd->gamma = 1.0f;
+ tmmd->intensity = 0.0f;
+ tmmd->contrast = 0.0f;
+ tmmd->adaptation = 1.0f;
+ tmmd->correction = 0.0f;
}
static void tonemapmodifier_apply_threaded_simple(int width,
@@ -664,55 +713,55 @@ static void tonemapmodifier_apply_threaded_simple(int width,
float *mask_rect_float,
void *data_v)
{
- AvgLogLum *avg = (AvgLogLum *)data_v;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- int pixel_index = (y * width + x) * 4;
- float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
- /* Get input value. */
- if (rect_float) {
- copy_v4_v4(input, &rect_float[pixel_index]);
- }
- else {
- straight_uchar_to_premul_float(input, &rect[pixel_index]);
- }
- IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace);
- copy_v4_v4(output, input);
- /* Get mask value. */
- 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);
- }
- /* Apply correction. */
- mul_v3_fl(output, avg->al);
- float dr = output[0] + avg->tmmd->offset;
- float dg = output[1] + avg->tmmd->offset;
- float db = output[2] + avg->tmmd->offset;
- output[0] /= ((dr == 0.0f) ? 1.0f : dr);
- output[1] /= ((dg == 0.0f) ? 1.0f : dg);
- output[2] /= ((db == 0.0f) ? 1.0f : db);
- const float igm = avg->igm;
- if (igm != 0.0f) {
- output[0] = powf(max_ff(output[0], 0.0f), igm);
- output[1] = powf(max_ff(output[1], 0.0f), igm);
- output[2] = powf(max_ff(output[2], 0.0f), igm);
- }
- /* Apply mask. */
- output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
- output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
- output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
- /* Copy result back. */
- IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace);
- if (rect_float) {
- copy_v4_v4(&rect_float[pixel_index], output);
- }
- else {
- premul_float_to_straight_uchar(&rect[pixel_index], output);
- }
- }
- }
+ AvgLogLum *avg = (AvgLogLum *)data_v;
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+ float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
+ /* Get input value. */
+ if (rect_float) {
+ copy_v4_v4(input, &rect_float[pixel_index]);
+ }
+ else {
+ straight_uchar_to_premul_float(input, &rect[pixel_index]);
+ }
+ IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace);
+ copy_v4_v4(output, input);
+ /* Get mask value. */
+ 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);
+ }
+ /* Apply correction. */
+ mul_v3_fl(output, avg->al);
+ float dr = output[0] + avg->tmmd->offset;
+ float dg = output[1] + avg->tmmd->offset;
+ float db = output[2] + avg->tmmd->offset;
+ output[0] /= ((dr == 0.0f) ? 1.0f : dr);
+ output[1] /= ((dg == 0.0f) ? 1.0f : dg);
+ output[2] /= ((db == 0.0f) ? 1.0f : db);
+ const float igm = avg->igm;
+ if (igm != 0.0f) {
+ output[0] = powf(max_ff(output[0], 0.0f), igm);
+ output[1] = powf(max_ff(output[1], 0.0f), igm);
+ output[2] = powf(max_ff(output[2], 0.0f), igm);
+ }
+ /* Apply mask. */
+ output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
+ output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
+ output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
+ /* Copy result back. */
+ IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace);
+ if (rect_float) {
+ copy_v4_v4(&rect_float[pixel_index], output);
+ }
+ else {
+ premul_float_to_straight_uchar(&rect[pixel_index], output);
+ }
+ }
+ }
}
static void tonemapmodifier_apply_threaded_photoreceptor(int width,
@@ -723,132 +772,123 @@ static void tonemapmodifier_apply_threaded_photoreceptor(int width,
float *mask_rect_float,
void *data_v)
{
- AvgLogLum *avg = (AvgLogLum *)data_v;
- const float f = expf(-avg->tmmd->intensity);
- const float m = (avg->tmmd->contrast > 0.0f) ? avg->tmmd->contrast : (0.3f + 0.7f * powf(avg->auto_key, 1.4f));
- const float ic = 1.0f - avg->tmmd->correction, ia = 1.0f - avg->tmmd->adaptation;
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- int pixel_index = (y * width + x) * 4;
- float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
- /* Get input value. */
- if (rect_float) {
- copy_v4_v4(input, &rect_float[pixel_index]);
- }
- else {
- straight_uchar_to_premul_float(input, &rect[pixel_index]);
- }
- IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace);
- copy_v4_v4(output, input);
- /* Get mask value. */
- 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);
- }
- /* Apply correction. */
- const float L = IMB_colormanagement_get_luminance(output);
- float I_l = output[0] + ic * (L - output[0]);
- float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]);
- float I_a = I_l + ia * (I_g - I_l);
- output[0] /= (output[0] + powf(f * I_a, m));
- I_l = output[1] + ic * (L - output[1]);
- I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]);
- I_a = I_l + ia * (I_g - I_l);
- output[1] /= (output[1] + powf(f * I_a, m));
- I_l = output[2] + ic * (L - output[2]);
- I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]);
- I_a = I_l + ia * (I_g - I_l);
- output[2] /= (output[2] + powf(f * I_a, m));
- /* Apply mask. */
- output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
- output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
- output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
- /* Copy result back. */
- IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace);
- if (rect_float) {
- copy_v4_v4(&rect_float[pixel_index], output);
- }
- else {
- premul_float_to_straight_uchar(&rect[pixel_index], output);
- }
- }
- }
+ AvgLogLum *avg = (AvgLogLum *)data_v;
+ const float f = expf(-avg->tmmd->intensity);
+ const float m = (avg->tmmd->contrast > 0.0f) ? avg->tmmd->contrast :
+ (0.3f + 0.7f * powf(avg->auto_key, 1.4f));
+ const float ic = 1.0f - avg->tmmd->correction, ia = 1.0f - avg->tmmd->adaptation;
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+ float input[4], output[4], mask[3] = {1.0f, 1.0f, 1.0f};
+ /* Get input value. */
+ if (rect_float) {
+ copy_v4_v4(input, &rect_float[pixel_index]);
+ }
+ else {
+ straight_uchar_to_premul_float(input, &rect[pixel_index]);
+ }
+ IMB_colormanagement_colorspace_to_scene_linear_v3(input, avg->colorspace);
+ copy_v4_v4(output, input);
+ /* Get mask value. */
+ 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);
+ }
+ /* Apply correction. */
+ const float L = IMB_colormanagement_get_luminance(output);
+ float I_l = output[0] + ic * (L - output[0]);
+ float I_g = avg->cav[0] + ic * (avg->lav - avg->cav[0]);
+ float I_a = I_l + ia * (I_g - I_l);
+ output[0] /= (output[0] + powf(f * I_a, m));
+ I_l = output[1] + ic * (L - output[1]);
+ I_g = avg->cav[1] + ic * (avg->lav - avg->cav[1]);
+ I_a = I_l + ia * (I_g - I_l);
+ output[1] /= (output[1] + powf(f * I_a, m));
+ I_l = output[2] + ic * (L - output[2]);
+ I_g = avg->cav[2] + ic * (avg->lav - avg->cav[2]);
+ I_a = I_l + ia * (I_g - I_l);
+ output[2] /= (output[2] + powf(f * I_a, m));
+ /* Apply mask. */
+ output[0] = input[0] * (1.0f - mask[0]) + output[0] * mask[0];
+ output[1] = input[1] * (1.0f - mask[1]) + output[1] * mask[1];
+ output[2] = input[2] * (1.0f - mask[2]) + output[2] * mask[2];
+ /* Copy result back. */
+ IMB_colormanagement_scene_linear_to_colorspace_v3(output, avg->colorspace);
+ if (rect_float) {
+ copy_v4_v4(&rect_float[pixel_index], output);
+ }
+ else {
+ premul_float_to_straight_uchar(&rect[pixel_index], output);
+ }
+ }
+ }
}
-static void tonemapmodifier_apply(struct SequenceModifierData *smd,
- ImBuf *ibuf,
- ImBuf *mask)
+static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
- SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *) smd;
- AvgLogLum data;
- data.tmmd = tmmd;
- data.colorspace = (ibuf->rect_float != NULL)
- ? ibuf->float_colorspace
- : ibuf->rect_colorspace;
- float lsum = 0.0f;
- int p = ibuf->x * ibuf->y;
- float *fp = ibuf->rect_float;
- unsigned char *cp = (unsigned char *)ibuf->rect;
- float avl, maxl = -FLT_MAX, minl = FLT_MAX;
- const float sc = 1.0f / p;
- float Lav = 0.f;
- float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- while (p--) {
- float pixel[4];
- if (fp != NULL) {
- copy_v4_v4(pixel, fp);
- }
- else {
- straight_uchar_to_premul_float(pixel, cp);
- }
- IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, data.colorspace);
- float L = IMB_colormanagement_get_luminance(pixel);
- Lav += L;
- add_v3_v3(cav, pixel);
- lsum += logf(max_ff(L, 0.0f) + 1e-5f);
- maxl = (L > maxl) ? L : maxl;
- minl = (L < minl) ? L : minl;
- if (fp != NULL) {
- fp += 4;
- }
- else {
- cp += 4;
- }
- }
- data.lav = Lav * sc;
- mul_v3_v3fl(data.cav, cav, sc);
- maxl = logf(maxl + 1e-5f);
- minl = logf(minl + 1e-5f);
- avl = lsum * sc;
- data.auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f;
- float al = expf(avl);
- data.al = (al == 0.0f) ? 0.0f : (tmmd->key / al);
- data.igm = (tmmd->gamma == 0.0f) ? 1.0f : (1.0f / tmmd->gamma);
-
- if (tmmd->type == SEQ_TONEMAP_RD_PHOTORECEPTOR) {
- modifier_apply_threaded(ibuf,
- mask,
- tonemapmodifier_apply_threaded_photoreceptor,
- &data);
- }
- else /* if (tmmd->type == SEQ_TONEMAP_RD_SIMPLE) */ {
- modifier_apply_threaded(ibuf,
- mask,
- tonemapmodifier_apply_threaded_simple,
- &data);
- }
+ SequencerTonemapModifierData *tmmd = (SequencerTonemapModifierData *)smd;
+ AvgLogLum data;
+ data.tmmd = tmmd;
+ data.colorspace = (ibuf->rect_float != NULL) ? ibuf->float_colorspace : ibuf->rect_colorspace;
+ float lsum = 0.0f;
+ int p = ibuf->x * ibuf->y;
+ float *fp = ibuf->rect_float;
+ unsigned char *cp = (unsigned char *)ibuf->rect;
+ float avl, maxl = -FLT_MAX, minl = FLT_MAX;
+ const float sc = 1.0f / p;
+ float Lav = 0.f;
+ float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ while (p--) {
+ float pixel[4];
+ if (fp != NULL) {
+ copy_v4_v4(pixel, fp);
+ }
+ else {
+ straight_uchar_to_premul_float(pixel, cp);
+ }
+ IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, data.colorspace);
+ float L = IMB_colormanagement_get_luminance(pixel);
+ Lav += L;
+ add_v3_v3(cav, pixel);
+ lsum += logf(max_ff(L, 0.0f) + 1e-5f);
+ maxl = (L > maxl) ? L : maxl;
+ minl = (L < minl) ? L : minl;
+ if (fp != NULL) {
+ fp += 4;
+ }
+ else {
+ cp += 4;
+ }
+ }
+ data.lav = Lav * sc;
+ mul_v3_v3fl(data.cav, cav, sc);
+ maxl = logf(maxl + 1e-5f);
+ minl = logf(minl + 1e-5f);
+ avl = lsum * sc;
+ data.auto_key = (maxl > minl) ? ((maxl - avl) / (maxl - minl)) : 1.0f;
+ float al = expf(avl);
+ data.al = (al == 0.0f) ? 0.0f : (tmmd->key / al);
+ data.igm = (tmmd->gamma == 0.0f) ? 1.0f : (1.0f / tmmd->gamma);
+
+ if (tmmd->type == SEQ_TONEMAP_RD_PHOTORECEPTOR) {
+ modifier_apply_threaded(ibuf, mask, tonemapmodifier_apply_threaded_photoreceptor, &data);
+ }
+ else /* if (tmmd->type == SEQ_TONEMAP_RD_SIMPLE) */ {
+ modifier_apply_threaded(ibuf, mask, tonemapmodifier_apply_threaded_simple, &data);
+ }
}
static SequenceModifierTypeInfo seqModifier_Tonemap = {
- CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Tonemap"), /* name */
- "SequencerTonemapModifierData", /* struct_name */
- sizeof(SequencerTonemapModifierData), /* struct_size */
- tonemapmodifier_init_data, /* init_data */
- NULL, /* free_data */
- NULL, /* copy_data */
- tonemapmodifier_apply, /* apply */
+ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Tonemap"), /* name */
+ "SequencerTonemapModifierData", /* struct_name */
+ sizeof(SequencerTonemapModifierData), /* struct_size */
+ tonemapmodifier_init_data, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ tonemapmodifier_apply, /* apply */
};
/*********************** Modifier functions *************************/
@@ -857,171 +897,174 @@ static void sequence_modifier_type_info_init(void)
{
#define INIT_TYPE(typeName) (modifiersTypes[seqModifierType_##typeName] = &seqModifier_##typeName)
- INIT_TYPE(ColorBalance);
- INIT_TYPE(Curves);
- INIT_TYPE(HueCorrect);
- INIT_TYPE(BrightContrast);
- INIT_TYPE(Mask);
- INIT_TYPE(WhiteBalance);
- INIT_TYPE(Tonemap);
+ INIT_TYPE(ColorBalance);
+ INIT_TYPE(Curves);
+ INIT_TYPE(HueCorrect);
+ INIT_TYPE(BrightContrast);
+ INIT_TYPE(Mask);
+ INIT_TYPE(WhiteBalance);
+ INIT_TYPE(Tonemap);
#undef INIT_TYPE
}
const SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type)
{
- if (!modifierTypesInit) {
- sequence_modifier_type_info_init();
- modifierTypesInit = true;
- }
+ if (!modifierTypesInit) {
+ sequence_modifier_type_info_init();
+ modifierTypesInit = true;
+ }
- return modifiersTypes[type];
+ return modifiersTypes[type];
}
SequenceModifierData *BKE_sequence_modifier_new(Sequence *seq, const char *name, int type)
{
- SequenceModifierData *smd;
- const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
+ SequenceModifierData *smd;
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(type);
- smd = MEM_callocN(smti->struct_size, "sequence modifier");
+ smd = MEM_callocN(smti->struct_size, "sequence modifier");
- smd->type = type;
- smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
+ smd->type = type;
+ smd->flag |= SEQUENCE_MODIFIER_EXPANDED;
- if (!name || !name[0])
- BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
- else
- BLI_strncpy(smd->name, name, sizeof(smd->name));
+ if (!name || !name[0])
+ BLI_strncpy(smd->name, smti->name, sizeof(smd->name));
+ else
+ BLI_strncpy(smd->name, name, sizeof(smd->name));
- BLI_addtail(&seq->modifiers, smd);
+ BLI_addtail(&seq->modifiers, smd);
- BKE_sequence_modifier_unique_name(seq, smd);
+ BKE_sequence_modifier_unique_name(seq, smd);
- if (smti->init_data)
- smti->init_data(smd);
+ if (smti->init_data)
+ smti->init_data(smd);
- return smd;
+ return smd;
}
bool BKE_sequence_modifier_remove(Sequence *seq, SequenceModifierData *smd)
{
- if (BLI_findindex(&seq->modifiers, smd) == -1)
- return false;
+ if (BLI_findindex(&seq->modifiers, smd) == -1)
+ return false;
- BLI_remlink(&seq->modifiers, smd);
- BKE_sequence_modifier_free(smd);
+ BLI_remlink(&seq->modifiers, smd);
+ BKE_sequence_modifier_free(smd);
- return true;
+ return true;
}
void BKE_sequence_modifier_clear(Sequence *seq)
{
- SequenceModifierData *smd, *smd_next;
+ SequenceModifierData *smd, *smd_next;
- for (smd = seq->modifiers.first; smd; smd = smd_next) {
- smd_next = smd->next;
- BKE_sequence_modifier_free(smd);
- }
+ for (smd = seq->modifiers.first; smd; smd = smd_next) {
+ smd_next = smd->next;
+ BKE_sequence_modifier_free(smd);
+ }
- BLI_listbase_clear(&seq->modifiers);
+ BLI_listbase_clear(&seq->modifiers);
}
void BKE_sequence_modifier_free(SequenceModifierData *smd)
{
- const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
- if (smti && smti->free_data) {
- smti->free_data(smd);
- }
+ if (smti && smti->free_data) {
+ smti->free_data(smd);
+ }
- MEM_freeN(smd);
+ MEM_freeN(smd);
}
void BKE_sequence_modifier_unique_name(Sequence *seq, SequenceModifierData *smd)
{
- const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
-
- BLI_uniquename(&seq->modifiers, smd, CTX_DATA_(BLT_I18NCONTEXT_ID_SEQUENCE, smti->name), '.',
- offsetof(SequenceModifierData, name), sizeof(smd->name));
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ BLI_uniquename(&seq->modifiers,
+ smd,
+ CTX_DATA_(BLT_I18NCONTEXT_ID_SEQUENCE, smti->name),
+ '.',
+ offsetof(SequenceModifierData, name),
+ sizeof(smd->name));
}
SequenceModifierData *BKE_sequence_modifier_find_by_name(Sequence *seq, const char *name)
{
- return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
+ return BLI_findstring(&(seq->modifiers), name, offsetof(SequenceModifierData, name));
}
-ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context, Sequence *seq, ImBuf *ibuf, int cfra)
+ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context,
+ Sequence *seq,
+ ImBuf *ibuf,
+ int cfra)
{
- SequenceModifierData *smd;
- ImBuf *processed_ibuf = ibuf;
-
- if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
- processed_ibuf = IMB_dupImBuf(ibuf);
- BKE_sequencer_imbuf_from_sequencer_space(context->scene, processed_ibuf);
- }
-
- for (smd = seq->modifiers.first; smd; smd = smd->next) {
- const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
-
- /* could happen if modifier is being removed or not exists in current version of blender */
- if (!smti)
- continue;
-
- /* modifier is muted, do nothing */
- if (smd->flag & SEQUENCE_MODIFIER_MUTE)
- continue;
-
- if (smti->apply) {
- int frame_offset;
- if (smd->mask_time == SEQUENCE_MASK_TIME_RELATIVE) {
- frame_offset = seq->start;
- }
- else /*if (smd->mask_time == SEQUENCE_MASK_TIME_ABSOLUTE)*/ {
- frame_offset = 0;
- }
-
- ImBuf *mask = modifier_mask_get(smd,
- context,
- cfra,
- frame_offset,
- ibuf->rect_float != NULL);
-
- if (processed_ibuf == ibuf)
- processed_ibuf = IMB_dupImBuf(ibuf);
-
- smti->apply(smd, processed_ibuf, mask);
-
- if (mask)
- IMB_freeImBuf(mask);
- }
- }
-
- if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
- BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
- }
-
- return processed_ibuf;
+ SequenceModifierData *smd;
+ ImBuf *processed_ibuf = ibuf;
+
+ if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
+ processed_ibuf = IMB_dupImBuf(ibuf);
+ BKE_sequencer_imbuf_from_sequencer_space(context->scene, processed_ibuf);
+ }
+
+ for (smd = seq->modifiers.first; smd; smd = smd->next) {
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+
+ /* could happen if modifier is being removed or not exists in current version of blender */
+ if (!smti)
+ continue;
+
+ /* modifier is muted, do nothing */
+ if (smd->flag & SEQUENCE_MODIFIER_MUTE)
+ continue;
+
+ if (smti->apply) {
+ int frame_offset;
+ if (smd->mask_time == SEQUENCE_MASK_TIME_RELATIVE) {
+ frame_offset = seq->start;
+ }
+ else /*if (smd->mask_time == SEQUENCE_MASK_TIME_ABSOLUTE)*/ {
+ frame_offset = 0;
+ }
+
+ ImBuf *mask = modifier_mask_get(smd, context, cfra, frame_offset, ibuf->rect_float != NULL);
+
+ if (processed_ibuf == ibuf)
+ processed_ibuf = IMB_dupImBuf(ibuf);
+
+ smti->apply(smd, processed_ibuf, mask);
+
+ if (mask)
+ IMB_freeImBuf(mask);
+ }
+ }
+
+ if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
+ BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, false);
+ }
+
+ return processed_ibuf;
}
void BKE_sequence_modifier_list_copy(Sequence *seqn, Sequence *seq)
{
- SequenceModifierData *smd;
+ SequenceModifierData *smd;
- for (smd = seq->modifiers.first; smd; smd = smd->next) {
- SequenceModifierData *smdn;
- const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
+ for (smd = seq->modifiers.first; smd; smd = smd->next) {
+ SequenceModifierData *smdn;
+ const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
- smdn = MEM_dupallocN(smd);
+ smdn = MEM_dupallocN(smd);
- if (smti && smti->copy_data)
- smti->copy_data(smdn, smd);
+ if (smti && smti->copy_data)
+ smti->copy_data(smdn, smd);
- smdn->next = smdn->prev = NULL;
- BLI_addtail(&seqn->modifiers, smdn);
- }
+ smdn->next = smdn->prev = NULL;
+ BLI_addtail(&seqn->modifiers, smdn);
+ }
}
int BKE_sequence_supports_modifiers(Sequence *seq)
{
- return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD);
+ return !ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD);
}