Blender V5.0
MOD_brightness_contrast.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cfloat>
10
11#include "BLI_math_base.h"
12#include "BLI_math_vector.hh"
13
14#include "BLT_translation.hh"
15
16#include "DNA_sequence_types.h"
17
18#include "SEQ_modifier.hh"
19#include "SEQ_modifiertypes.hh"
20
21#include "UI_interface.hh"
23
24#include "modifier.hh"
25
26namespace blender::seq {
27
29 float mul;
30 float add;
31
32 template<typename ImageT, typename MaskSampler>
33 void apply(ImageT *image, MaskSampler &mask, int image_x, IndexRange y_range)
34 {
35 image += y_range.first() * image_x * 4;
36 for (int64_t y : y_range) {
37 mask.begin_row(y);
38 for ([[maybe_unused]] int64_t x : IndexRange(image_x)) {
39 /* NOTE: arguably incorrect usage of "raw" values, should be un-premultiplied.
40 * Not changing behavior for now, but would be good to fix someday. */
42
44 result = input * this->mul + this->add;
45 result.w = input.w;
46
47 mask.apply_mask(input, result);
48 store_pixel_raw(result, image);
49 image += 4;
50 }
51 }
52 }
53};
54
57 ImBuf *mask)
58{
60
62
63 /* The algorithm is by Werner D. Streidt
64 * (http://visca.com/ffactory/archives/5-99/msg00021.html)
65 * Extracted from OpenCV `demhist.cpp`. */
66 const float brightness = bcmd->bright / 100.0f;
67 const float contrast = bcmd->contrast;
68 float delta = contrast / 200.0f;
69
70 if (contrast > 0) {
71 op.mul = 1.0f - delta * 2.0f;
72 op.mul = 1.0f / max_ff(op.mul, FLT_EPSILON);
73 op.add = op.mul * (brightness - delta);
74 }
75 else {
76 delta *= -1;
77 op.mul = max_ff(1.0f - delta * 2.0f, 0.0f);
78 op.add = op.mul * brightness + delta;
79 }
80
81 apply_modifier_op(op, context.image, mask, context.transform);
82}
83
84static void brightcontrast_panel_draw(const bContext *C, Panel *panel)
85{
86 uiLayout *layout = panel->layout;
88
89 layout->use_property_split_set(true);
90
91 layout->prop(ptr, "bright", UI_ITEM_NONE, std::nullopt, ICON_NONE);
92 layout->prop(ptr, "contrast", UI_ITEM_NONE, std::nullopt, ICON_NONE);
93
94 if (uiLayout *mask_input_layout = layout->panel_prop(
95 C, ptr, "open_mask_input_panel", IFACE_("Mask Input")))
96 {
97 draw_mask_input_type_settings(C, mask_input_layout, ptr);
98 }
99}
100
105
107 /*idname*/ "BrightContrast",
108 /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Brightness/Contrast"),
109 /*struct_name*/ "BrightContrastModifierData",
110 /*struct_size*/ sizeof(BrightContrastModifierData),
111 /*init_data*/ nullptr,
112 /*free_data*/ nullptr,
113 /*copy_data*/ nullptr,
114 /*apply*/ brightcontrast_apply,
115 /*panel_register*/ brightcontrast_register,
116 /*blend_write*/ nullptr,
117 /*blend_read*/ nullptr,
118};
119
120}; // namespace blender::seq
MINLINE float max_ff(float a, float b)
#define CTX_N_(context, msgid)
#define BLT_I18NCONTEXT_ID_SEQUENCE
#define IFACE_(msgid)
@ eSeqModifierType_BrightContrast
#define C
Definition RandGen.cpp:29
PointerRNA * UI_panel_custom_data_get(const Panel *panel)
#define UI_ITEM_NONE
long long int int64_t
constexpr int64_t first() const
#define input
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void store_pixel_raw(float4 pix, uchar *ptr)
void draw_mask_input_type_settings(const bContext *C, uiLayout *layout, PointerRNA *ptr)
void apply_modifier_op(T &op, ImBuf *ibuf, const ImBuf *mask, const float3x3 &mask_transform)
Definition modifier.hh:263
StripModifierTypeInfo seqModifierType_BrightContrast
static void brightcontrast_register(ARegionType *region_type)
float4 load_pixel_raw(const uchar *ptr)
static void brightcontrast_panel_draw(const bContext *C, Panel *panel)
static void brightcontrast_apply(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
PanelType * modifier_panel_register(ARegionType *region_type, const eStripModifierType type, PanelDrawFn draw)
VecBase< float, 4 > float4
struct uiLayout * layout
void apply(ImageT *image, MaskSampler &mask, int image_x, IndexRange y_range)
PanelLayout panel_prop(const bContext *C, PointerRNA *open_prop_owner, blender::StringRefNull open_prop_name)
void use_property_split_set(bool value)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
PointerRNA * ptr
Definition wm_files.cc:4238