43 using float_m =
typename float_v::batch_bool_type;
51 dataWrapper.read(src, src_c1, src_c2, src_c3, src_alpha);
53 const float_v msk_norm_alpha = [&](){;
55 const float_v uint8Rec1(1.0f / 255.0f);
57 return mask_vec * uint8Rec1 * src_alpha;
68 opacity = oparams.opacity;
69 const float_v opacity_vec(opacity);
71 src_alpha = msk_norm_alpha * opacity_vec;
80 dataWrapper.read(dst, dst_c1, dst_c2, dst_c3, dst_alpha);
82 const float_m empty_dst_pixels_mask = dst_alpha == zeroValue;
84 if (!xsimd::all(empty_dst_pixels_mask)) {
85 if (xsimd::none(empty_dst_pixels_mask)) {
86 dst_c1 = (src_c1 - dst_c1) * src_alpha + dst_c1;
87 dst_c2 = (src_c2 - dst_c2) * src_alpha + dst_c2;
88 dst_c3 = (src_c3 - dst_c3) * src_alpha + dst_c3;
91 dst_c1 = xsimd::select(empty_dst_pixels_mask, src_c1, (src_c1 - dst_c1) * src_alpha + dst_c1);
92 dst_c2 = xsimd::select(empty_dst_pixels_mask, src_c2, (src_c2 - dst_c2) * src_alpha + dst_c2);
93 dst_c3 = xsimd::select(empty_dst_pixels_mask, src_c3, (src_c3 - dst_c3) * src_alpha + dst_c3);
102 const float_v fullFlowAlpha = [&]() {
103 if (oparams.averageOpacity > opacity) {
104 const float_v average_opacity_vec(oparams.averageOpacity);
105 const float_m fullFlowAlpha_mask = average_opacity_vec > dst_alpha;
106 return xsimd::select(fullFlowAlpha_mask,
107 (average_opacity_vec - src_alpha)
108 * (dst_alpha / average_opacity_vec)
112 const float_m fullFlowAlpha_mask = opacity_vec > dst_alpha;
113 return xsimd::select(
115 (opacity_vec - dst_alpha) * msk_norm_alpha + dst_alpha,
121 if (oparams.flow == 1.0) {
122 return fullFlowAlpha;
125 const float_v zeroFlowAlpha = ParamsWrapper::calculateZeroFlowAlpha(src_alpha, dst_alpha);
126 const float_v flow_norm_vec(oparams.flow);
127 return (fullFlowAlpha - zeroFlowAlpha) * flow_norm_vec + zeroFlowAlpha;
131 dataWrapper.write(dst, dst_c1, dst_c2, dst_c3, dst_alpha);
141 const qint32 alpha_pos = 3;
143 const auto *src =
reinterpret_cast<const channels_type*
>(s);
144 auto *dst =
reinterpret_cast<channels_type*
>(d);
146 float dstAlphaNorm = dst[alpha_pos];
149 const float uint8Rec1 = 1.0f / 255.0f;
150 float mskAlphaNorm = haveMask ? float(*mask) * uint8Rec1 * src[alpha_pos] : src[alpha_pos];
154 opacity = oparams.opacity;
156 const float srcAlphaNorm = mskAlphaNorm * opacity;
158 if (dstAlphaNorm != 0) {
163 const auto *s =
reinterpret_cast<const Pixel*
>(src);
164 auto *d =
reinterpret_cast<Pixel*
>(dst);
168 const float flow = oparams.flow;
169 const float averageOpacity = oparams.averageOpacity;
171 const float fullFlowAlpha = [&]() {
172 if (averageOpacity > opacity) {
173 return averageOpacity > dstAlphaNorm ?
lerp(srcAlphaNorm, averageOpacity, dstAlphaNorm / averageOpacity) : dstAlphaNorm;
175 return opacity > dstAlphaNorm ?
lerp(dstAlphaNorm, opacity, mskAlphaNorm) : dstAlphaNorm;
179 dstAlphaNorm = [&]() {
181 return fullFlowAlpha;
183 const float zeroFlowAlpha = ParamsWrapper::calculateZeroFlowAlpha(srcAlphaNorm, dstAlphaNorm);
184 return lerp(zeroFlowAlpha, fullFlowAlpha, flow);