7#ifndef KOCOMPOSITEOP_FUNCTIONS_H_
8#define KOCOMPOSITEOP_FUNCTIONS_H_
22template<
typename channels_type>
23inline void possiblyFixNegativeValuesNearZeroPoint(
float& dstR,
float& dstG,
float& dstB)
30 if constexpr (!std::numeric_limits<channels_type>::is_integer) {
31 dstR = qMax(dstR, 0.0f);
32 dstG = qMax(dstG, 0.0f);
33 dstB = qMax(dstB, 0.0f);
37template<
typename channels_type>
38inline void possiblyClampValuesToSDR(
float& dstR,
float& dstG,
float& dstB)
45 if constexpr (!std::numeric_limits<channels_type>::is_integer) {
46 dstR = qBound(0.0f, dstR, 1.0f);
47 dstG = qBound(0.0f, dstG, 1.0f);
48 dstB = qBound(0.0f, dstB, 1.0f);
53template<
typename channels_type>
56 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
66 if (isZeroValueFuzzy(srcB)) {
81 float k = (tx*ux+ty*uy+tz*uz)/tz;
86 float finalLength = rx*rx+ry*ry+rz*rz;
94 if (isZeroValueStrict(finalLength)) {
98 k = 1 / sqrt(finalLength);
108template<
class HSXType,
typename channels_type>
111 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
113 float lum = getLightness<HSXType>(dstR, dstG, dstB);
117 setLightness<HSXType>(dstR, dstG, dstB, lum);
118 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
122template<
class HSXType,
typename channels_type>
125 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
130 const float light = getLightness<HSXType>(dstR, dstG, dstB);
131 const float oneMinusLight = unitValue<float>() - light;
132 dstR = light + srcR * oneMinusLight;
133 dstG = light + srcG * oneMinusLight;
134 dstB = light + srcB * oneMinusLight;
138template<
class HSXType,
typename channels_type>
141 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
142 float tr = srcR * dstR * (1.0 / 0.215686);
143 float tg = srcG * dstG * (1.0 / 0.215686);
144 float tb = srcB * dstB * (1.0 / 0.215686);
147 dstR = 1.0 + (tr - 1.0) * (tr - 1.0) * 0.01925;
154 dstG = 1.0 + (tg - 1.0) * (tg - 1.0) * 0.01925;
161 dstB = 1.0 + (tb - 1.0) * (tb - 1.0) * 0.01925;
167 ToneMapping<HSXType, float>(dstR, dstG, dstB);
171template<
class HSXType,
typename channels_type>
174 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
175 float tr = srcR * dstR * 2.0;
176 float tg = srcG * dstG * 2.0;
177 float tb = srcB * dstB * 2.0;
180 dstR = 1.0 + (tr - 1.0) * (tr - 1.0) * 0.4;
187 dstG = 1.0 + (tg - 1.0) * (tg - 1.0) * 0.4;
194 dstB = 1.0 + (tb - 1.0) * (tb - 1.0) * 0.4;
200 ToneMapping<HSXType, float>(dstR, dstG, dstB);
204template<
class HSXType,
typename channels_type>
207 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
208 setLightness<HSXType>(dstR, dstG, dstB, getLightness<HSXType>(srcR, srcG, srcB));
209 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
214template<
class HSXType,
typename channels_type>
217 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
218 addLightness<HSXType>(dstR, dstG, dstB, getLightness<HSXType>(srcR, srcG, srcB));
219 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
223template<
class HSXType,
typename channels_type>
226 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
227 addLightness<HSXType>(dstR, dstG, dstB, getLightness<HSXType>(srcR, srcG, srcB) - 1.0f);
228 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
232template<
class HSXType,
typename channels_type>
235 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
236 float sat = getSaturation<HSXType>(srcR, srcG, srcB);
237 float light = getLightness<HSXType>(dstR, dstG, dstB);
238 setSaturation<HSXType>(dstR, dstG, dstB, sat);
239 setLightness<HSXType>(dstR, dstG, dstB, light);
240 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
244template<
class HSXType,
typename channels_type>
247 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
249 float sat =
lerp(getSaturation<HSXType>(dstR, dstG, dstB), unitValue<float>(), getSaturation<HSXType>(srcR, srcG, srcB));
250 float light = getLightness<HSXType>(dstR, dstG, dstB);
251 setSaturation<HSXType>(dstR, dstG, dstB, sat);
252 setLightness<HSXType>(dstR, dstG, dstB, light);
253 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
257template<
class HSXType,
typename channels_type>
260 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
262 float sat =
lerp(zeroValue<float>(), getSaturation<HSXType>(dstR, dstG, dstB), getSaturation<HSXType>(srcR, srcG, srcB));
263 float light = getLightness<HSXType>(dstR, dstG, dstB);
264 setSaturation<HSXType>(dstR, dstG, dstB, sat);
265 setLightness<HSXType>(dstR, dstG, dstB, light);
266 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
270template<
class HSXType,
typename channels_type>
273 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
274 float sat = getSaturation<HSXType>(dstR, dstG, dstB);
275 float lum = getLightness<HSXType>(dstR, dstG, dstB);
281 setSaturation<HSXType>(dstR, dstG, dstB, sat);
282 setLightness<HSXType>(dstR, dstG, dstB, lum);
283 possiblyFixNegativeValuesNearZeroPoint<channels_type>(dstR, dstG, dstB);
287template<
typename channels_type>
290 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
292 const float half = halfValue<float>();
293 dstR = srcR + (dstR - half);
294 dstG = srcG + (dstG - half);
295 dstB = srcB + (dstB - unitValue<float>());
296 possiblyClampValuesToSDR<channels_type>(dstR, dstG, dstB);
300template<
class HSXType,
typename channels_type>
303 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
304 const float lum = getLightness<HSXType>(dstR, dstG, dstB);
305 const float lum2 = getLightness<HSXType>(srcR, srcG, srcB);
314template<
class HSXType,
typename channels_type>
317 static void composeChannels(
float srcR,
float srcG,
float srcB,
float& dstR,
float& dstG,
float& dstB) {
318 const float lum = getLightness<HSXType>(dstR, dstG, dstB);
319 const float lum2 = getLightness<HSXType>(srcR, srcG, srcB);
338 if (isUnitValueStrict(dst)) {
339 return unitValue<T>();
342 if constexpr (std::numeric_limits<T>::is_integer) {
345 if (isZeroValueStrict(src)) {
346 return zeroValue<T>();
351 composite_type divisionResult = div(inv(dst), src);
353 if constexpr (!std::numeric_limits<T>::is_integer) {
354 if (!std::isfinite(divisionResult)) {
355 return zeroValue<T>();
359 return inv<T>(clampToSDR<T>(divisionResult));
365 template <
typename>
typename ClampPolicy>
369 using clamp_policy = ClampPolicy<T>;
372 return clamp_policy::clampResult(composite_type(src) + dst - unitValue<T>());
377 template <
typename>
typename ClampPolicy>
381 using clamp_policy = ClampPolicy<T>;
393 if (isUnitValueStrict(src)) {
397 return clamp_policy::clampResultAllowNegative(
398 clamp_policy::fixInfiniteAfterDivision(
408 return Arithmetic::clamp<T>(composite_type(src) + dst);
415 return clamp<T>(composite_type(dst) - src);
423 return clamp<T>(composite_type(dst) - inv(src));
433 composite_type x = mul(src, dst);
434 return clamp<T>(composite_type(dst) + src - (x + x));
446 if (isZeroValueStrict(dst)) {
447 return zeroValue<T>();
450 if (isZeroValueStrict(src)) {
451 return unitValue<T>();
454 composite_type result = div(dst, src);
461 return clampToSDRTop<T>(result);
471 if (isHalfValueFuzzy(src)) {
475 composite_type src2 = composite_type(src) + src;
477 if(src > halfValue<T>()) {
479 src2 -= unitValue<T>();
500 qreal fsrc = scale<qreal>(src);
501 qreal fdst = scale<qreal>(dst);
504 qreal
D = (fdst > 0.25) ? sqrt(fdst) : ((16.0*fdst - 12.0)*fdst + 4.0)*fdst;
505 return scale<T>(fdst + (2.0*fsrc - 1.0) * (
D - fdst));
508 return scale<T>(fdst - (1.0 - 2.0 * fsrc) * fdst * (1.0 - fdst));
518 qreal fsrc = scale<qreal>(src);
519 qreal fdst = scale<qreal>(dst);
523 return scale<T>(fdst + (2.0 * fsrc - 1.0) * (sqrt(fdst) - fdst));
527 return scale<T>(fdst - (1.0 - 2.0*fsrc) * fdst * (1.0 - fdst));
532 template <
typename>
typename ClampPolicy>
536 using clamp_policy = ClampPolicy<T>;
539 if (src < halfValue<T>()) {
540 if (isZeroValueStrict(src)) {
541 return isUnitValueClampedStrict(dst) ? clamp_policy::clampResultAllowNegative(dst) : zeroValue<T>();
545 composite_type src2 = composite_type(src) + src;
546 composite_type dsti = inv(dst);
547 return clamp_policy::clampResult(
549 clamp_policy::fixInfiniteAfterDivision(
550 divideInCompositeSpace<T>(dsti, src2)
555 if (isUnitValueStrict(src)) {
556 return isZeroValueClampedStrict(dst) ? zeroValue<T>() : unitValue<T>();
560 composite_type srci2 = inv(src);
562 return clamp_policy::clampResultAllowNegative(
563 clamp_policy::fixInfiniteAfterDivision(
564 divideInCompositeSpace<T>(composite_type(dst), srci2)
578 composite_type src2 = composite_type(src) + src;
579 composite_type a = qMin<composite_type>(dst, src2);
580 composite_type b = qMax<composite_type>(src2-Arithmetic::unitValue<T>(), a);
593 return scale<T>(2.0 * atan2(scale<qreal>(src), scale<qreal>(dst)) /
Arithmetic::pi);
601 return T((composite_type(src) + dst) * halfValue<T>() / unitValue<T>());
610 return clamp<T>((composite_type(src) + src + dst) - unitValue<T>());
619 const bool srcIsSafe = !isUnsafeAsDivisor(src);
620 const bool dstIsSafe = !isUnsafeAsDivisor(dst);
622 if (!srcIsSafe || !dstIsSafe) {
623 return zeroValue<T>();
627 composite_type unit = unitValue<T>();
628 composite_type s = div<T>(unit, src);
629 composite_type d = div<T>(unit, dst);
631 return clamp<T>((unit+unit) * unit / (d+s));
642 composite_type x = qAbs(composite_type(dst) - src);
652 return clampToSDR<T>(composite_type(dst) + src - halfValue<T>());
661 return clampToSDR<T>(composite_type(dst) - src + halfValue<T>());
666 template <
typename>
typename ClampPolicy>
676 return dst > halfValue<T>() ?
688 const composite_type sum = composite_type(src) + dst;
690 return sum > unitValue<T>() ? unitValue<T>() : zeroValue<T>();
704 const composite_type srcScaleFactor =
static_cast<composite_type
>(2);
705 const composite_type dstScaleFactor =
static_cast<composite_type
>(3);
707 return clampToSDR<T>(dstScaleFactor * dst - srcScaleFactor * inv(src));
717 qreal x = sqrt(scale<qreal>(dst)) - sqrt(scale<qreal>(src));
718 return scale<T>(qAbs(x));
727 const qreal dstReal = scale<qreal>(dst);
729 if (isZeroValueFuzzy(dstReal)) {
730 return zeroValue<T>();
733 if (isUnitValueFuzzy(dstReal)) {
734 return unitValue<T>();
739 const qreal srcReal = scale<qreal>(src);
740 const qreal exponent = 1.0 / srcReal;
742 if (std::isfinite(exponent)) {
744 std::min<qreal>(pow(dstReal, exponent),
747 return zeroValue<T>();
757 const qreal dstReal = scale<qreal>(dst);
759 if (isZeroValueFuzzy(dstReal)) {
760 return zeroValue<T>();
763 if (isUnitValueFuzzy(dstReal)) {
764 return unitValue<T>();
767 const qreal srcReal = scale<qreal>(src);
769 return scale<T>(pow(dstReal, srcReal));
786 if (isUnitValueFuzzy(src) && isUnitValueFuzzy(dst)) {
787 return unitValue<T>();
790 return scale<T>(sqrt(scale<qreal>(dst) * scale<qreal>(src)));
795inline T
cfOver(T src, T dst) { Q_UNUSED(dst);
return src; }
808 template <
typename>
typename ClampPolicy>
812 using clamp_policy = ClampPolicy<T>;
815 if (isZeroValueStrict(dst)) {
816 return zeroValue<T>();
819 if (isUnitValueStrict(src)) {
820 return clamp_policy::clippedMaxValue();
823 if(src >= halfValue<T>()) {
824 return clamp_policy::clampResultAllowNegative(
825 clamp_policy::fixInfiniteAfterDivision(
826 divideInCompositeSpace<T>(composite_type(dst),
827 2 * composite_type(inv(src)))
832 return clamp_policy::clampResultAllowNegative(
833 multiplyInCompositeSpace<T>(composite_type(dst),
834 2 * composite_type(src))
840inline T
cfDifference(T src, T dst) {
return qMax(src,dst) - qMin(src,dst); }
856 if (dst == unitValue<T>()) {
857 return unitValue<T>();
860 return clamp<T>(div(mul(src, src), inv(dst)));
868 return clamp<T>(
cfGlow(dst,src));
875 if(src == unitValue<T>()) {
876 return unitValue<T>();
879 if(dst == zeroValue<T>()) {
880 return zeroValue<T>();
883 return inv(clamp<T>(div(mul(inv(src), inv(src)),dst)));
903 if (isZeroValueFuzzy<T>(src)) {
904 return zeroValue<T>();
920 if (isZeroValueFuzzy<T>(dst)) {
921 return zeroValue<T>();
934 if(isUnitValueFuzzy<T>(dst)) {
935 return unitValue<T>();
966 qreal fsrc = scale<qreal>(src);
967 qreal fdst = scale<qreal>(dst);
969 if(dst == zeroValue<T>() && src == zeroValue<T>()) {
970 return zeroValue<T>();
973 return scale<T>(.5f-.25f*cos(pi*(fsrc))-.25f*cos(pi*(fdst)));
990 if (dst == unitValue<T>()) {
991 return unitValue<T>();
993 if (dst + src < unitValue<T>()) {
996 if (src == zeroValue<T>()) {
997 return zeroValue<T>();
1000 return inv(clamp<T>(div(inv(dst),src)/2));
1008 if (dst == unitValue<T>()) {
1009 return unitValue<T>();
1034 qreal fsrc = scale<qreal>(src);
1035 qreal fdst = scale<qreal>(dst);
1037 return scale<T>(pow(fdst,pow(2.0,(mul(2.0,.5f-fsrc)))));
1054 composite_type unit = unitValue<T>();
1055 composite_type a = unit - src - dst;
1056 composite_type s = std::abs(a);
1057 composite_type d = unit - s;
1067 return and(src,dst);
1081 return xor(src,dst);
1088 return cfXor(src,inv(dst));
1095 return cfNor(inv(src),inv(dst));
1102 return cfNand(inv(src),inv(dst));
1109 return cfOr(inv(src),dst);
1116 return cfAnd(src,inv(dst));
1123 return cfOr(src,inv(dst));
1130 return cfAnd(inv(src),dst);
1138 return clamp<T>(pow(pow((
float)dst, 2.3333333333333333) + pow((
float)src, 2.3333333333333333), 0.428571428571434));
1146 return clamp<T>(pow(pow(dst,4)+pow(src,4),0.25));
1154 qreal fsrc = scale<qreal>(src);
1155 qreal fdst = scale<qreal>(dst);
1158 return scale<T>(inv(pow(pow(inv(fdst),2.875)+pow(inv(2.0*fsrc),2.875),1.0/2.875)));
1161 return scale<T>(pow(pow(fdst,2.875)+pow(2.0*fsrc-1.0,2.875),1.0/2.875));
1169 qreal fsrc = scale<qreal>(src);
1170 qreal fdst = scale<qreal>(dst);
1172 return scale<T>(fsrc*inv(fdst)+sqrt(fdst));
1180 qreal fsrc = scale<qreal>(src);
1181 qreal fdst = scale<qreal>(dst);
1183 return scale<T>(inv((inv(fdst)*fsrc)+sqrt(inv(fsrc))));
1191 qreal fsrc = scale<qreal>(src);
1192 qreal fdst = scale<qreal>(dst);
1195 return scale<T>(inv(inv(fsrc)*fsrc)-inv(fdst)*inv(fsrc));
1198 return scale<T>(fsrc-inv(fdst)*inv(fsrc)+pow(inv(fsrc),2));
1206 qreal fsrc = scale<qreal>(src);
1207 qreal fdst = scale<qreal>(dst);
1210 return scale<T>(inv(fsrc)*fsrc+fsrc*fdst);
1213 return scale<T>(fsrc*fdst+fsrc-pow(fsrc,2));
1220 return mod(dst,src);
1226 qreal fsrc = scale<qreal>(src);
1227 qreal fdst = scale<qreal>(dst);
1229 if (fsrc == 1.0 && fdst == 0.0) {
1230 return scale<T>(0.0);
1234 return scale<T>(mod((fdst+fsrc),1.0000000000));
1241 qreal fsrc = scale<qreal>(src);
1242 qreal fdst = scale<qreal>(dst);
1244 if (fsrc == 1.0 && fdst == 0.0) {
1245 return scale<T>(1.0);
1248 return scale<T>((
int(ceil(fdst+fsrc)) % 2 != 0) || (fdst == zeroValue<T>()) ?
cfModuloShift(fsrc,fdst) : inv(
cfModuloShift(fsrc,fdst)));
1256 qreal fsrc = scale<qreal>(src);
1257 qreal fdst = scale<qreal>(dst);
1259 if (fsrc == zeroValue<T>()) {
1260 return scale<T>(mod(((1.0000000000/epsilon<T>()) * fdst),1.0000000000));
1263 return scale<T>(mod(((1.0000000000/fsrc) * fdst),1.0000000000));
1270 qreal fsrc = scale<qreal>(src);
1271 qreal fdst = scale<qreal>(dst);
1273 if (fdst == zeroValue<T>()) {
1274 return zeroValue<T>();
1277 if (fsrc == zeroValue<T>()) {
1297 qreal fsrc = scale<qreal>(src);
1298 qreal fdst = scale<qreal>(dst);
1301 return scale<T>(1.0);}
1304 return scale<T>(pow(fdst,mul(inv(fsrc != 1.0 ? fsrc : .999999999999),1.039999999)));
1312 qreal fsrc = scale<qreal>(src);
1313 qreal fdst = scale<qreal>(dst);
1316 return scale<T>(inv(pow(inv(fsrc != 1.0 ? fsrc : .999999999999),mul(fdst,1.039999999))));
1324 if (isZeroValueFuzzy<T>(src)) {
1325 return zeroValue<T>();
1335template<
class HSXType,
class TReal>
1342 composite_type newsrc;
1343 newsrc = mul(src, sa);
1344 dst = clamp<TReal>(newsrc + dst);
T cfNotImplies(T src, T dst)
T cfMultiply(T src, T dst)
T cfDarkenOnly(T src, T dst)
T cfModuloShiftContinuous(T src, T dst)
T cfModuloContinuous(T src, T dst)
T cfInterpolation(T src, T dst)
T cfLinearLight(T src, T dst)
T cfSoftLightPegtopDelphi(T src, T dst)
T cfPenumbraC(T src, T dst)
T cfSoftLightIFSIllusions(T src, T dst)
T cfAddition(T src, T dst)
T cfDivisiveModuloContinuous(T src, T dst)
T cfPenumbraD(T src, T dst)
T cfFogLightenIFSIllusions(T src, T dst)
T cfDifference(T src, T dst)
T cfEasyBurn(T src, T dst)
T cfConverse(T src, T dst)
T cfSubtract(T src, T dst)
T cfFogDarkenIFSIllusions(T src, T dst)
T cfLightenOnly(T src, T dst)
void cfAdditionSAI(TReal src, TReal sa, TReal &dst, TReal &da)
T cfNotConverse(T src, T dst)
T cfImplies(T src, T dst)
T cfModuloShift(T src, T dst)
T cfInterpolationB(T src, T dst)
T cfArcTangent(T src, T dst)
T cfSuperLight(T src, T dst)
T cfShadeIFSIllusions(T src, T dst)
T cfDivisiveModulo(T src, T dst)
T cfTintIFSIllusions(T src, T dst)
T cfAllanon(T src, T dst)
T cfEasyDodge(T src, T dst)
T cfReflect(T src, T dst)
qreal D(qreal t, const QPointF &P0, const QPointF &P1, const QPointF &P2, const QPointF &P3, const QPointF &p)
QPointF lerp(const QPointF &p1, const QPointF &p2, qreal t)
T unionShapeOpacity(T a, T b)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static T composeChannel(T src, T dst)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static T composeChannel(T src, T dst)
static T composeChannel(T src, T dst)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static void composeChannels(float srcR, float srcG, float srcB, float &dstR, float &dstG, float &dstB)
static T composeChannel(T src, T dst)