MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / ApplyCustomMaskBlend

Method ApplyCustomMaskBlend

src/effects/Saturation.cpp:41–92  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

39}
40
41void Saturation::ApplyCustomMaskBlend(std::shared_ptr<QImage> original_image, std::shared_ptr<QImage> effected_image,
42 std::shared_ptr<QImage> mask_image, int64_t frame_number) const {
43 (void) frame_number;
44 if (!original_image || !effected_image || !mask_image)
45 return;
46 if (original_image->size() != effected_image->size() || effected_image->size() != mask_image->size())
47 return;
48
49 unsigned char* original_pixels = reinterpret_cast<unsigned char*>(original_image->bits());
50 unsigned char* effected_pixels = reinterpret_cast<unsigned char*>(effected_image->bits());
51 unsigned char* mask_pixels = reinterpret_cast<unsigned char*>(mask_image->bits());
52 const int pixel_count = effected_image->width() * effected_image->height();
53
54 if (mask_invert) {
55 #pragma omp parallel for schedule(static)
56 for (int i = 0; i < pixel_count; ++i) {
57 const int idx = i * 4;
58 float factor = static_cast<float>(qGray(mask_pixels[idx], mask_pixels[idx + 1], mask_pixels[idx + 2])) / 255.0f;
59 factor = 1.0f - factor;
60 // Use a non-linear response curve for custom saturation drive mode.
61 factor = factor * factor;
62 const float inverse = 1.0f - factor;
63
64 // Drive saturation strength with mask while preserving source alpha.
65 effected_pixels[idx] = static_cast<unsigned char>(
66 (original_pixels[idx] * inverse) + (effected_pixels[idx] * factor));
67 effected_pixels[idx + 1] = static_cast<unsigned char>(
68 (original_pixels[idx + 1] * inverse) + (effected_pixels[idx + 1] * factor));
69 effected_pixels[idx + 2] = static_cast<unsigned char>(
70 (original_pixels[idx + 2] * inverse) + (effected_pixels[idx + 2] * factor));
71 effected_pixels[idx + 3] = original_pixels[idx + 3];
72 }
73 } else {
74 #pragma omp parallel for schedule(static)
75 for (int i = 0; i < pixel_count; ++i) {
76 const int idx = i * 4;
77 float factor = static_cast<float>(qGray(mask_pixels[idx], mask_pixels[idx + 1], mask_pixels[idx + 2])) / 255.0f;
78 // Use a non-linear response curve for custom saturation drive mode.
79 factor = factor * factor;
80 const float inverse = 1.0f - factor;
81
82 // Drive saturation strength with mask while preserving source alpha.
83 effected_pixels[idx] = static_cast<unsigned char>(
84 (original_pixels[idx] * inverse) + (effected_pixels[idx] * factor));
85 effected_pixels[idx + 1] = static_cast<unsigned char>(
86 (original_pixels[idx + 1] * inverse) + (effected_pixels[idx + 1] * factor));
87 effected_pixels[idx + 2] = static_cast<unsigned char>(
88 (original_pixels[idx + 2] * inverse) + (effected_pixels[idx + 2] * factor));
89 effected_pixels[idx + 3] = original_pixels[idx + 3];
90 }
91 }
92}
93
94// Init effect settings
95void Saturation::init_effect_details()

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected