8#ifndef META_OCEAN_CV_FRAME_BLENDER_H
9#define META_OCEAN_CV_FRAME_BLENDER_H
52 typedef void (*BlendFunction)(uint8_t*,
const uint8_t);
58 template <
bool tAlphaAtFront>
68 template <
unsigned int tChannelsWithAlpha>
69 static constexpr unsigned int alpha();
75 static constexpr unsigned int data();
81 template <
bool tSourceHasAlpha>
82 static constexpr unsigned int data();
89 template <
bool tTargetHasAlpha>
99 template <
unsigned int tChannelsWithAlpha>
100 static constexpr unsigned int channels();
107 template <
bool tAlphaAtFront>
108 static constexpr unsigned int data();
115 template <
bool tHasAlpha>
125 template <
unsigned int tChannels>
126 static constexpr unsigned int dataChannels();
133 template <
unsigned int tChannelsWithAlpha>
134 static constexpr unsigned int channels();
153 template <
bool tTransparentIs0xFF>
154 static bool blend(
const Frame& source,
Frame& target,
const uint8_t alphaValue,
Worker* worker =
nullptr);
169 template <
bool tTransparentIs0xFF, AlphaTargetModulation tAlphaTargetModulation>
170 static bool blend(
const Frame& sourceWithAlpha,
Frame& target,
Worker* worker =
nullptr);
183 template <
bool tTransparentIs0xFF, AlphaTargetModulation tAlphaTargetModulation>
184 static bool blend(
const Frame& sourceWithAlpha,
Frame& result,
const uint8_t* backgroundColor,
Worker* worker =
nullptr);
203 template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
204 static bool blend(
const Frame& sourceWithAlpha,
Frame& target,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
Worker* worker =
nullptr);
224 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
225 static inline void blend8BitPerChannel(
const uint8_t* source, uint8_t* target,
const uint8_t alphaValue,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
245 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
246 static inline void blend8BitPerChannel(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
263 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, AlphaTargetModulation tAlphaTargetModulation>
264 static inline void blend8BitPerChannel(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourceWithAlphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
279 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
280 static inline void blend8BitPerChannel(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const uint8_t* value,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
295 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
296 static inline void blend8BitPerChannel(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const BlendFunction blendFunction,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
320 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
321 static inline void blend8BitPerChannel(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
346 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
347 static inline void blend8BitPerChannel(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker =
nullptr);
354 template <
bool tTransparentIs0xFF>
355 static inline uint8_t fullTransparent8Bit();
362 template <
bool tTransparentIs0xFF>
363 static inline uint8_t fullOpaque8Bit();
371 template <
bool tTransparentIs0xFF>
372 static inline uint8_t alpha8BitToTransparentIs0xFF(
const uint8_t alpha);
380 template <
bool tTransparentIs0xFF>
381 static inline uint8_t alpha8BitToOpaqueIs0xFF(
const uint8_t alpha);
398 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
399 static void blend8BitPerChannelSubset(
const uint8_t* source, uint8_t* target,
const uint8_t alphaValue,
const unsigned int width,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
415 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
416 static void blend8BitPerChannelSubset(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
434 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, AlphaTargetModulation tAlphaTargetModulation>
435 static void blend8BitPerChannelSubset(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourceWithAlphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
451 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
452 static void blend8BitPerChannelSubset(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const uint8_t* value,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
468 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
469 static void blend8BitPerChannelSubset(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const BlendFunction blendFunction,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
478 template <
bool tTransparentIs0xFF>
479 static uint8_t
inline sourceBlendFactor(
const uint8_t alpha);
488 template <
bool tTransparentIs0xFF>
489 static inline uint8_t targetBlendFactor(
const uint8_t alpha);
492template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
499 ocean_assert(
false &&
"Invalid pixel format!");
504 if (!sourceHasCorrectInfo)
506 ocean_assert(
false &&
"Invalid pixel format!");
510 bool alphaIsLastChannel =
false;
513 ocean_assert_and_suppress_unused(sourceHasAlpha, sourceHasAlpha);
521 if (alphaIsLastChannel)
525 blend8BitPerChannel<2u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
529 blend8BitPerChannel<2u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
536 blend8BitPerChannel<2u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
540 blend8BitPerChannel<2u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
549 if (alphaIsLastChannel)
553 blend8BitPerChannel<3u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
557 blend8BitPerChannel<3u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
564 blend8BitPerChannel<3u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
568 blend8BitPerChannel<3u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
577 if (alphaIsLastChannel)
581 blend8BitPerChannel<4u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
585 blend8BitPerChannel<4u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(),sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
592 blend8BitPerChannel<4u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
596 blend8BitPerChannel<4u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
603 ocean_assert(
false &&
"Invalid pixel format!");
609template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
619 return blend<tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha, result, worker);
622template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
623bool FrameBlender::blend(
const Frame& sourceWithAlpha,
Frame& target,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
Worker* worker)
628 || sourceLeft + width > sourceWithAlpha.
width() || sourceTop + height > sourceWithAlpha.
height()
629 || targetLeft + width > target.
width() || targetTop + height > target.
height())
631 ocean_assert(
false &&
"Invalid pixel format!");
637 bool alphaIsLastChannel =
false;
640 ocean_assert_and_suppress_unused(hasAlpha, hasAlpha);
648 if (alphaIsLastChannel)
652 blend8BitPerChannel<2u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
656 blend8BitPerChannel<2u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
663 blend8BitPerChannel<2u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
667 blend8BitPerChannel<2u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
676 if (alphaIsLastChannel)
680 blend8BitPerChannel<3u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
684 blend8BitPerChannel<3u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
691 blend8BitPerChannel<3u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
695 blend8BitPerChannel<3u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
704 if (alphaIsLastChannel)
708 blend8BitPerChannel<4u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
712 blend8BitPerChannel<4u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
719 blend8BitPerChannel<4u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
723 blend8BitPerChannel<4u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), target.
width(), target.
height(), sourceLeft, sourceTop, targetLeft, targetTop, width, height, sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
735 ocean_assert(
false &&
"Invalid pixel format!");
739template <
bool tTransparentIs0xFF>
742 ocean_assert(source && target);
771 ocean_assert(
false &&
"Invalid frame type!");
775template <
unsigned int tChannels,
bool tTransparentIs0xFF>
776inline void FrameBlender::blend8BitPerChannel(
const uint8_t* source, uint8_t* target,
const uint8_t alphaValue,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
778 static_assert(tChannels >= 1u,
"Invalid channel number!");
780 ocean_assert(source !=
nullptr && target !=
nullptr);
784 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, source, target, alphaValue, width, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 6u, 7u, 20u);
788 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(source, target, alphaValue, width, sourcePaddingElements, targetPaddingElements, 0u, height);
792template <
unsigned int tChannels,
bool tTransparentIs0xFF>
793inline void FrameBlender::blend8BitPerChannel(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
795 static_assert(tChannels >= 1u,
"Invalid channel number!");
797 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
801 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, source, alpha, target, width, sourcePaddingElements, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
805 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(source, alpha, target, width, sourcePaddingElements, alphaPaddingElements, targetPaddingElements, 0u, height);
809template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
810inline void FrameBlender::blend8BitPerChannel(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourceWithAlphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
812 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
813 ocean_assert(sourceWithAlpha && target);
817 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>, sourceWithAlpha, target, width, height, sourceWithAlphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 6u, 7u, 20u);
821 blend8BitPerChannelSubset<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha, target, width, height, sourceWithAlphaPaddingElements, targetPaddingElements, 0u, height);
825template <
unsigned int tChannels,
bool tTransparentIs0xFF>
826inline void FrameBlender::blend8BitPerChannel(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const uint8_t* value,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
828 static_assert(tChannels >= 1u,
"Invalid channel number!");
830 ocean_assert(alpha !=
nullptr && target !=
nullptr && value !=
nullptr);
834 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, alpha, target, width, height, value, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
838 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(alpha, target, width, height, value, alphaPaddingElements, targetPaddingElements, 0u, height);
842template <
unsigned int tChannels,
bool tTransparentIs0xFF>
843inline void FrameBlender::blend8BitPerChannel(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const BlendFunction blendFunction,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
845 static_assert(tChannels >= 1u,
"Invalid channel number!");
846 ocean_assert(alpha && target && blendFunction);
850 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, alpha, target, width, height, blendFunction, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
854 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(alpha, target, width, height, blendFunction, alphaPaddingElements, targetPaddingElements, 0u, height);
858template <
unsigned int tChannels,
bool tTransparentIs0xFF>
859inline void FrameBlender::blend8BitPerChannel(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
861 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
863 const unsigned int sourceStrideElements = sourceWidth * tChannels + sourcePaddingElements;
864 const unsigned int alphaStrideElements = sourceWidth + alphaPaddingElements;
865 const unsigned int targetStrideElements = targetWidth * tChannels + targetPaddingElements;
867 const uint8_t*
const sourceTopLeft = source + sourceTop * sourceStrideElements + sourceLeft * tChannels;
868 const uint8_t*
const alphaTopLeft = alpha + sourceTop * alphaStrideElements + sourceLeft;
869 uint8_t*
const targetTopLeft = target + targetTop * targetStrideElements + targetLeft * tChannels;
871 ocean_assert_and_suppress_unused(width <= sourceWidth && height <= sourceHeight, sourceHeight);
872 ocean_assert_and_suppress_unused(width <= targetWidth && height <= targetHeight, targetHeight);
874 const unsigned int subSourcePaddingElements = (sourceWidth - width) * tChannels + sourcePaddingElements;
875 const unsigned int subAlphaPaddingElements = (sourceWidth - width) + alphaPaddingElements;
876 const unsigned int subTargetPaddingElements = (targetWidth - width) * tChannels + targetPaddingElements;
878 blend8BitPerChannel<tChannels, tTransparentIs0xFF>(sourceTopLeft, alphaTopLeft, targetTopLeft, width, height, subSourcePaddingElements, subAlphaPaddingElements, subTargetPaddingElements, worker);
881template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
882inline void FrameBlender::blend8BitPerChannel(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int targetWidth,
const unsigned int targetHeight,
const unsigned int sourceLeft,
const unsigned int sourceTop,
const unsigned int targetLeft,
const unsigned int targetTop,
const unsigned int width,
const unsigned int height,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
Worker* worker)
884 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
886 ocean_assert(sourceWithAlpha !=
nullptr && target !=
nullptr);
890 const unsigned int sourceStrideElements = sourceWidth * tChannelsWithAlpha + sourcePaddingElements;
891 const unsigned int targetStrideElements = targetWidth * tTargetChannels + targetPaddingElements;
893 const uint8_t*
const sourceTopLeft = sourceWithAlpha + sourceTop * sourceStrideElements + sourceLeft * tChannelsWithAlpha;
894 uint8_t*
const targetTopLeft = target + targetTop * targetStrideElements + targetLeft * tTargetChannels;
896 ocean_assert_and_suppress_unused(width <= sourceWidth && height <= sourceHeight, sourceHeight);
897 ocean_assert_and_suppress_unused(width <= targetWidth && height <= targetHeight, targetHeight);
899 const unsigned int subSourcePaddingElements = (sourceWidth - width) * tChannelsWithAlpha + sourcePaddingElements;
900 const unsigned int subTargetPaddingElements = (targetWidth - width) * tTargetChannels + targetPaddingElements;
902 blend8BitPerChannel<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>(sourceTopLeft, targetTopLeft, width, height, subSourcePaddingElements, subTargetPaddingElements, worker);
905template <
bool tTransparentIs0xFF>
912inline uint8_t FrameBlender::fullTransparent8Bit<false>()
917template <
bool tTransparentIs0xFF>
920 return 0xFF - fullTransparent8Bit<tTransparentIs0xFF>();
923template <
bool tTransparentIs0xFF>
930inline uint8_t FrameBlender::alpha8BitToTransparentIs0xFF<false>(
const uint8_t alpha)
935template <
bool tTransparentIs0xFF>
942inline uint8_t FrameBlender::alpha8BitToOpaqueIs0xFF<false>(
const uint8_t alpha)
947template <
unsigned int tChannels,
bool tTransparentIs0xFF>
948void FrameBlender::blend8BitPerChannelSubset(
const uint8_t* source, uint8_t* target,
const uint8_t alphaValue,
const unsigned int width,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
950 static_assert(tChannels >= 1u,
"Invalid channel number!");
952 ocean_assert(source !=
nullptr && target !=
nullptr);
954 const uint8_t sourceFactor = sourceBlendFactor<tTransparentIs0xFF>(alphaValue);
955 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(alphaValue);
957 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
958 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
960 source += firstRow * sourceStrideElements;
961 target += firstRow * targetStrideElements;
963 for (
unsigned int r = 0u; r < numberRows; ++r)
965 for (
unsigned int x = 0u; x < width; ++x)
967 for (
unsigned int n = 0u; n < tChannels; ++n)
976 source += sourcePaddingElements;
977 target += targetPaddingElements;
981template <
unsigned int tChannels,
bool tTransparentIs0xFF>
982void FrameBlender::blend8BitPerChannelSubset(
const uint8_t* source,
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int sourcePaddingElements,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
984 static_assert(tChannels >= 1u,
"Invalid channel number!");
986 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
988 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
989 const unsigned int alphaStrideElements = width + alphaPaddingElements;
990 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
992 source += firstRow * sourceStrideElements;
993 alpha += firstRow * alphaStrideElements;
994 target += firstRow * targetStrideElements;
996 for (
unsigned int r = 0u; r < numberRows; ++r)
998 for (
unsigned int x = 0u; x < width; ++x)
1000 const uint8_t sourceFactor = sourceBlendFactor<tTransparentIs0xFF>(alpha[0]);
1001 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(alpha[0]);
1003 for (
unsigned int n = 0u; n < tChannels; ++n)
1008 source += tChannels;
1010 target += tChannels;
1013 source += sourcePaddingElements;
1014 alpha += alphaPaddingElements;
1015 target += targetPaddingElements;
1019template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
1020void FrameBlender::blend8BitPerChannelSubset(
const uint8_t* sourceWithAlpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const unsigned int sourceWithAlphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
1022 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
1023 ocean_assert(sourceWithAlpha !=
nullptr && target !=
nullptr);
1025 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1027 const unsigned int sourceWithAlphaStrideElements = width * tChannelsWithAlpha + sourceWithAlphaPaddingElements;
1030 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1032 const uint8_t* sourceWithAlphaData = sourceWithAlpha + y * sourceWithAlphaStrideElements;
1033 uint8_t* targetData = target + y * targetStrideElements;
1035 for (
unsigned int x = 0u; x < width; ++x)
1040 for (
unsigned int n = 0u; n < tChannelsWithAlpha - 1u; ++n)
1045 if constexpr (tTargetHasAlpha && tAlphaTargetModulation ==
ATM_BLEND)
1047 if constexpr (tTransparentIs0xFF)
1063 sourceWithAlphaData += tChannelsWithAlpha;
1069template <
unsigned int tChannels,
bool tTransparentIs0xFF>
1070void FrameBlender::blend8BitPerChannelSubset(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const uint8_t* value,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
1072 static_assert(tChannels >= 1u,
"Invalid channel number!");
1074 ocean_assert(alpha !=
nullptr && target !=
nullptr && value !=
nullptr);
1075 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1077 const unsigned int alphaStrideElements = width + alphaPaddingElements;
1078 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
1080 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1082 const uint8_t* alphaRow = alpha + y * alphaStrideElements;
1083 uint8_t* targetRow = target + y * targetStrideElements;
1085 for (
unsigned int x = 0u; x < width; ++x)
1087 const uint8_t valueFactor = sourceBlendFactor<tTransparentIs0xFF>(*alphaRow);
1088 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(*alphaRow);
1090 for (
unsigned int n = 0u; n < tChannels; ++n)
1096 targetRow += tChannels;
1101template <
unsigned int tChannels,
bool tTransparentIs0xFF>
1102void FrameBlender::blend8BitPerChannelSubset(
const uint8_t* alpha, uint8_t* target,
const unsigned int width,
const unsigned int height,
const BlendFunction blendFunction,
const unsigned int alphaPaddingElements,
const unsigned int targetPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows)
1104 static_assert(tChannels >= 1u,
"Invalid channel number!");
1106 ocean_assert(alpha !=
nullptr && target !=
nullptr && blendFunction !=
nullptr);
1107 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1109 const unsigned int alphaStrideElements = width + alphaPaddingElements;
1110 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
1112 alpha += firstRow * alphaStrideElements;
1113 target += firstRow * targetStrideElements;
1115 for (
unsigned int n = 0u; n < numberRows; ++n)
1117 for (
unsigned int x = 0u; x < width; ++x)
1119 blendFunction(target, targetBlendFactor<tTransparentIs0xFF>(*alpha));
1122 target += tChannels;
1125 alpha += alphaPaddingElements;
1126 target += targetPaddingElements;
1130template <
bool tTransparentIs0xFF>
1133 return 0xFFu - alpha;
1137inline uint8_t FrameBlender::sourceBlendFactor<false>(
const uint8_t alpha)
1142template <
bool tTransparentIs0xFF>
1149inline uint8_t FrameBlender::targetBlendFactor<false>(
const uint8_t alpha)
1151 return 0xFFu - alpha;
1154template <
bool tAlphaAtFront>
1155template <
unsigned int tChannelsWithAlpha>
1162template <
unsigned int tChannelsWithAlpha>
1165 static_assert(tChannelsWithAlpha >= 1u,
"Invalid channel number!");
1167 return tChannelsWithAlpha - 1u;
1170template <
bool tAlphaAtFront>
1182template <
bool tAlphaAtFront>
1183template <
bool tSourceHasAlpha>
1186 return tSourceHasAlpha ? 1u : 0u;
1203template <
bool tTargetHasAlpha>
1204template <
unsigned int tChannelsWithAlpha>
1207 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1209 return tChannelsWithAlpha;
1213template <
unsigned int tChannelsWithAlpha>
1216 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel number!");
1218 return tChannelsWithAlpha - 1u;
1221template <
bool tTargetHasAlpha>
1222template <
bool tAlphaAtFront>
1235template <
bool tHasAlpha>
1236template <
unsigned int tChannels>
1239 static_assert(tChannels >= 2u,
"Invalid channel input!");
1242 return tChannels - 1u;
1246template <
unsigned int tChannels>
1249 static_assert(tChannels >= 1u,
"Invalid channel input!");
1255template <
bool tHasAlpha>
1256template <
unsigned int tChannelsWithAlpha>
1259 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1262 return tChannelsWithAlpha;
1266template <
unsigned int tChannelsWithAlpha>
1269 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1272 return tChannelsWithAlpha - 1u;
Helper class allowing to determine the number of channels of a frame.
Definition FrameBlender.h:117
static constexpr unsigned int channels()
Returns the number of channels of a frame for that is known whether is has an alpha channel or not.
Definition FrameBlender.h:1257
static constexpr unsigned int dataChannels()
Returns the number of channels of a frame not counting the possible alpha channel.
Definition FrameBlender.h:1237
Helper class allowing to determine the offset that is necessary to access the alpha channel.
Definition FrameBlender.h:60
static constexpr unsigned int alpha()
Returns the offset that is applied to access the alpha channel.
Definition FrameBlender.h:1156
static constexpr unsigned int data()
Returns the offset that is applied to access the first data channel.
static constexpr unsigned int data()
Returns the offset that is applied to access the first data channel.
Definition FrameBlender.h:1171
Helper class allowing to determine the number of channels of the target frame.
Definition FrameBlender.h:91
static constexpr unsigned int channels()
Returns the number of channels of the target frame.
Definition FrameBlender.h:1205
static constexpr unsigned int data()
Returns the offset that is applied to access the first data channel.
Definition FrameBlender.h:1223
This class implements a frame blender using an alpha channel to blend frames.
Definition FrameBlender.h:30
static uint8_t alpha8BitToTransparentIs0xFF(const uint8_t alpha)
Converts a given alpha value so that 0xFF is interpreted as fully transparent.
Definition FrameBlender.h:924
static void blend8BitPerChannel(const uint8_t *source, uint8_t *target, const uint8_t alphaValue, const unsigned int width, const unsigned int height, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker *worker=nullptr)
Blends two 8 bit per channel frames with same frame type by application of one unique blending factor...
Definition FrameBlender.h:776
static uint8_t fullTransparent8Bit()
Returns the alpha value for a fully transparent pixel.
Definition FrameBlender.h:906
static bool blend(const Frame &source, Frame &target, const uint8_t alphaValue, Worker *worker=nullptr)
Blends two frames with same frame type by application of one unique blending factor for all pixels.
Definition FrameBlender.h:740
static uint8_t alpha8BitToOpaqueIs0xFF(const uint8_t alpha)
Converts a given alpha value so that 0xFF is interpreted as fully opaque.
Definition FrameBlender.h:936
static uint8_t fullOpaque8Bit()
Returns the alpha value for a fully opaque pixel.
Definition FrameBlender.h:918
AlphaTargetModulation
Definition of individual target alpha channel modulation functions.
Definition FrameBlender.h:37
@ ATM_CONSTANT
The target alpha channel is constant and is not changed.
Definition FrameBlender.h:41
@ ATM_BLEND
The target alpha channel is blended by alphaResult = alphaTarget + alphaSource * (1 - alphaTarget).
Definition FrameBlender.h:43
static void blend8BitPerChannelSubset(const uint8_t *source, uint8_t *target, const uint8_t alphaValue, const unsigned int width, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Blends a subset of two 8 bit per channels frames by application of one unique blending factor for all...
Definition FrameBlender.h:948
static uint8_t sourceBlendFactor(const uint8_t alpha)
Returns the blend factor for the source frame depending whether 0xFF is interpreted as transparent or...
Definition FrameBlender.h:1131
static uint8_t targetBlendFactor(const uint8_t alpha)
Returns the blend factor for the target frame depending whether 0xFF is interpreted as transparent or...
Definition FrameBlender.h:1143
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2877
This class implements Ocean's image class.
Definition Frame.h:1808
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition Frame.h:4251
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4242
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4531
bool set(const FrameType &frameType, const bool forceOwner, const bool forceWritable=false, const Indices32 &planePaddingElements=Indices32(), const Timestamp ×tamp=Timestamp(false), bool *reallocated=nullptr)
Sets a new frame type for this frame.
bool setValue(const uint8_t value, const unsigned int planeIndex=0u, const bool skipPaddingData=true)
Sets the memory of the frame to a specified byte value (the memory of one plane).
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition Frame.h:4125
Definition of a frame type composed by the frame dimension, pixel format and pixel origin.
Definition Frame.h:30
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3170
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition Frame.h:3215
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition Frame.h:3210
static PixelFormat formatRemoveAlphaChannel(const PixelFormat pixelFormat)
Removes an alpha channel from a given pixel format.
static bool areFrameTypesCompatible(const FrameType &frameTypeA, const FrameType &frameTypeB, const bool allowDifferentPixelOrigins)
Returns whether two given frame types are compatible.
static bool formatHasAlphaChannel(const PixelFormat pixelFormat, bool *isLastChannel=nullptr)
Returns whether a given pixel format holds an alpha channel.
PixelFormat pixelFormat() const
Returns the pixel format of the frame.
Definition Frame.h:3180
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition Frame.h:41
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3175
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3200
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition Frame.h:3190
static unsigned char divideBy255(const unsigned int value)
This function applies a fast division by 255 for unsigned integer values.
Definition base/Utilities.h:878
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
The namespace covering the entire Ocean framework.
Definition Accessor.h:15