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);
492 template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
499 ocean_assert(
false &&
"Invalid pixel format!");
505 bool alphaIsLastChannel =
false;
508 ocean_assert_and_suppress_unused(sourceHasAlpha, sourceHasAlpha);
516 if (alphaIsLastChannel)
520 blend8BitPerChannel<2u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
524 blend8BitPerChannel<2u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
531 blend8BitPerChannel<2u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
535 blend8BitPerChannel<2u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
544 if (alphaIsLastChannel)
548 blend8BitPerChannel<3u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
552 blend8BitPerChannel<3u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
559 blend8BitPerChannel<3u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
563 blend8BitPerChannel<3u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
572 if (alphaIsLastChannel)
576 blend8BitPerChannel<4u, false, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
580 blend8BitPerChannel<4u, false, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(),sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
587 blend8BitPerChannel<4u, true, true, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
591 blend8BitPerChannel<4u, true, false, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha.
constdata<uint8_t>(), target.
data<uint8_t>(), sourceWithAlpha.
width(), sourceWithAlpha.
height(), sourceWithAlpha.
paddingElements(), target.
paddingElements(), worker);
600 ocean_assert(
false &&
"Invalid pixel format!");
604 template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
614 return blend<tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha, result, worker);
617 template <
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
618 bool 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)
623 || sourceLeft + width > sourceWithAlpha.
width() || sourceTop + height > sourceWithAlpha.
height()
624 || targetLeft + width > target.
width() || targetTop + height > target.
height())
626 ocean_assert(
false &&
"Invalid pixel format!");
632 bool alphaIsLastChannel =
false;
635 ocean_assert_and_suppress_unused(hasAlpha, hasAlpha);
643 if (alphaIsLastChannel)
647 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);
651 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);
658 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);
662 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);
671 if (alphaIsLastChannel)
675 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);
679 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);
686 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);
690 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);
699 if (alphaIsLastChannel)
703 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);
707 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);
714 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);
718 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);
727 ocean_assert(
false &&
"Invalid pixel format!");
731 template <
bool tTransparentIs0xFF>
734 ocean_assert(source && target);
760 ocean_assert(
false &&
"Invalid frame type!");
764 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
765 inline 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)
767 static_assert(tChannels >= 1u,
"Invalid channel number!");
769 ocean_assert(source !=
nullptr && target !=
nullptr);
773 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, source, target, alphaValue, width, sourcePaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 6u, 7u, 20u);
777 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(source, target, alphaValue, width, sourcePaddingElements, targetPaddingElements, 0u, height);
781 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
782 inline 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)
784 static_assert(tChannels >= 1u,
"Invalid channel number!");
786 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
790 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, source, alpha, target, width, sourcePaddingElements, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
794 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(source, alpha, target, width, sourcePaddingElements, alphaPaddingElements, targetPaddingElements, 0u, height);
798 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
799 inline 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)
801 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
802 ocean_assert(sourceWithAlpha && target);
806 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>, sourceWithAlpha, target, width, height, sourceWithAlphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 6u, 7u, 20u);
810 blend8BitPerChannelSubset<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>(sourceWithAlpha, target, width, height, sourceWithAlphaPaddingElements, targetPaddingElements, 0u, height);
814 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
815 inline 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)
817 static_assert(tChannels >= 1u,
"Invalid channel number!");
819 ocean_assert(alpha !=
nullptr && target !=
nullptr && value !=
nullptr);
823 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, alpha, target, width, height, value, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
827 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(alpha, target, width, height, value, alphaPaddingElements, targetPaddingElements, 0u, height);
831 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
832 inline 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)
834 static_assert(tChannels >= 1u,
"Invalid channel number!");
835 ocean_assert(alpha && target && blendFunction);
839 worker->
executeFunction(
Worker::Function::createStatic(&blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>, alpha, target, width, height, blendFunction, alphaPaddingElements, targetPaddingElements, 0u, 0u), 0u, height, 7u, 8u, 20u);
843 blend8BitPerChannelSubset<tChannels, tTransparentIs0xFF>(alpha, target, width, height, blendFunction, alphaPaddingElements, targetPaddingElements, 0u, height);
847 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
848 inline 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)
850 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
852 const unsigned int sourceStrideElements = sourceWidth * tChannels + sourcePaddingElements;
853 const unsigned int alphaStrideElements = sourceWidth + alphaPaddingElements;
854 const unsigned int targetStrideElements = targetWidth * tChannels + targetPaddingElements;
856 const uint8_t*
const sourceTopLeft = source + sourceTop * sourceStrideElements + sourceLeft * tChannels;
857 const uint8_t*
const alphaTopLeft = alpha + sourceTop * alphaStrideElements + sourceLeft;
858 uint8_t*
const targetTopLeft = target + targetTop * targetStrideElements + targetLeft * tChannels;
860 ocean_assert_and_suppress_unused(width <= sourceWidth && height <= sourceHeight, sourceHeight);
861 ocean_assert_and_suppress_unused(width <= targetWidth && height <= targetHeight, targetHeight);
863 const unsigned int subSourcePaddingElements = (sourceWidth - width) * tChannels + sourcePaddingElements;
864 const unsigned int subAlphaPaddingElements = (sourceWidth - width) + alphaPaddingElements;
865 const unsigned int subTargetPaddingElements = (targetWidth - width) * tChannels + targetPaddingElements;
867 blend8BitPerChannel<tChannels, tTransparentIs0xFF>(sourceTopLeft, alphaTopLeft, targetTopLeft, width, height, subSourcePaddingElements, subAlphaPaddingElements, subTargetPaddingElements, worker);
870 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
871 inline 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)
873 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
875 ocean_assert(sourceWithAlpha !=
nullptr && target !=
nullptr);
879 const unsigned int sourceStrideElements = sourceWidth * tChannelsWithAlpha + sourcePaddingElements;
880 const unsigned int targetStrideElements = targetWidth * tTargetChannels + targetPaddingElements;
882 const uint8_t*
const sourceTopLeft = sourceWithAlpha + sourceTop * sourceStrideElements + sourceLeft * tChannelsWithAlpha;
883 uint8_t*
const targetTopLeft = target + targetTop * targetStrideElements + targetLeft * tTargetChannels;
885 ocean_assert_and_suppress_unused(width <= sourceWidth && height <= sourceHeight, sourceHeight);
886 ocean_assert_and_suppress_unused(width <= targetWidth && height <= targetHeight, targetHeight);
888 const unsigned int subSourcePaddingElements = (sourceWidth - width) * tChannelsWithAlpha + sourcePaddingElements;
889 const unsigned int subTargetPaddingElements = (targetWidth - width) * tTargetChannels + targetPaddingElements;
891 blend8BitPerChannel<tChannelsWithAlpha, tAlphaAtFront, tTargetHasAlpha, tTransparentIs0xFF, tAlphaTargetModulation>(sourceTopLeft, targetTopLeft, width, height, subSourcePaddingElements, subTargetPaddingElements, worker);
894 template <
bool tTransparentIs0xFF>
901 inline uint8_t FrameBlender::fullTransparent8Bit<false>()
906 template <
bool tTransparentIs0xFF>
909 return 0xFF - fullTransparent8Bit<tTransparentIs0xFF>();
912 template <
bool tTransparentIs0xFF>
919 inline uint8_t FrameBlender::alpha8BitToTransparentIs0xFF<false>(
const uint8_t alpha)
924 template <
bool tTransparentIs0xFF>
931 inline uint8_t FrameBlender::alpha8BitToOpaqueIs0xFF<false>(
const uint8_t alpha)
936 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
937 void 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)
939 static_assert(tChannels >= 1u,
"Invalid channel number!");
941 ocean_assert(source !=
nullptr && target !=
nullptr);
943 const uint8_t sourceFactor = sourceBlendFactor<tTransparentIs0xFF>(alphaValue);
944 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(alphaValue);
946 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
947 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
949 source += firstRow * sourceStrideElements;
950 target += firstRow * targetStrideElements;
952 for (
unsigned int r = 0u; r < numberRows; ++r)
954 for (
unsigned int x = 0u; x < width; ++x)
956 for (
unsigned int n = 0u; n < tChannels; ++n)
965 source += sourcePaddingElements;
966 target += targetPaddingElements;
970 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
971 void 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)
973 static_assert(tChannels >= 1u,
"Invalid channel number!");
975 ocean_assert(source !=
nullptr && alpha !=
nullptr && target !=
nullptr);
977 const unsigned int sourceStrideElements = width * tChannels + sourcePaddingElements;
978 const unsigned int alphaStrideElements = width + alphaPaddingElements;
979 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
981 source += firstRow * sourceStrideElements;
982 alpha += firstRow * alphaStrideElements;
983 target += firstRow * targetStrideElements;
985 for (
unsigned int r = 0u; r < numberRows; ++r)
987 for (
unsigned int x = 0u; x < width; ++x)
989 const uint8_t sourceFactor = sourceBlendFactor<tTransparentIs0xFF>(alpha[0]);
990 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(alpha[0]);
992 for (
unsigned int n = 0u; n < tChannels; ++n)
1002 source += sourcePaddingElements;
1003 alpha += alphaPaddingElements;
1004 target += targetPaddingElements;
1008 template <
unsigned int tChannelsWithAlpha,
bool tAlphaAtFront,
bool tTargetHasAlpha,
bool tTransparentIs0xFF, FrameBlender::AlphaTargetModulation tAlphaTargetModulation>
1009 void 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)
1011 static_assert(tChannelsWithAlpha > 1u,
"Invalid channel number!");
1012 ocean_assert(sourceWithAlpha !=
nullptr && target !=
nullptr);
1014 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1016 const unsigned int sourceWithAlphaStrideElements = width * tChannelsWithAlpha + sourceWithAlphaPaddingElements;
1019 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1021 const uint8_t* sourceWithAlphaData = sourceWithAlpha + y * sourceWithAlphaStrideElements;
1022 uint8_t* targetData = target + y * targetStrideElements;
1024 for (
unsigned int x = 0u; x < width; ++x)
1029 for (
unsigned int n = 0u; n < tChannelsWithAlpha - 1u; ++n)
1034 if constexpr (tTargetHasAlpha && tAlphaTargetModulation ==
ATM_BLEND)
1036 if constexpr (tTransparentIs0xFF)
1052 sourceWithAlphaData += tChannelsWithAlpha;
1058 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
1059 void 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)
1061 static_assert(tChannels >= 1u,
"Invalid channel number!");
1063 ocean_assert(alpha !=
nullptr && target !=
nullptr && value !=
nullptr);
1064 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1066 const unsigned int alphaStrideElements = width + alphaPaddingElements;
1067 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
1069 for (
unsigned int y = firstRow; y < firstRow + numberRows; ++y)
1071 const uint8_t* alphaRow = alpha + y * alphaStrideElements;
1072 uint8_t* targetRow = target + y * targetStrideElements;
1074 for (
unsigned int x = 0u; x < width; ++x)
1076 const uint8_t valueFactor = sourceBlendFactor<tTransparentIs0xFF>(*alphaRow);
1077 const uint8_t targetFactor = targetBlendFactor<tTransparentIs0xFF>(*alphaRow);
1079 for (
unsigned int n = 0u; n < tChannels; ++n)
1085 targetRow += tChannels;
1090 template <
unsigned int tChannels,
bool tTransparentIs0xFF>
1091 void 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)
1093 static_assert(tChannels >= 1u,
"Invalid channel number!");
1095 ocean_assert(alpha !=
nullptr && target !=
nullptr && blendFunction !=
nullptr);
1096 ocean_assert_and_suppress_unused(firstRow + numberRows <= height, height);
1098 const unsigned int alphaStrideElements = width + alphaPaddingElements;
1099 const unsigned int targetStrideElements = width * tChannels + targetPaddingElements;
1101 alpha += firstRow * alphaStrideElements;
1102 target += firstRow * targetStrideElements;
1104 for (
unsigned int n = 0u; n < numberRows; ++n)
1106 for (
unsigned int x = 0u; x < width; ++x)
1108 blendFunction(target, targetBlendFactor<tTransparentIs0xFF>(*alpha));
1111 target += tChannels;
1114 alpha += alphaPaddingElements;
1115 target += targetPaddingElements;
1119 template <
bool tTransparentIs0xFF>
1122 return 0xFFu - alpha;
1126 inline uint8_t FrameBlender::sourceBlendFactor<false>(
const uint8_t alpha)
1131 template <
bool tTransparentIs0xFF>
1138 inline uint8_t FrameBlender::targetBlendFactor<false>(
const uint8_t alpha)
1140 return 0xFFu - alpha;
1143 template <
bool tAlphaAtFront>
1144 template <
unsigned int tChannelsWithAlpha>
1151 template <
unsigned int tChannelsWithAlpha>
1154 static_assert(tChannelsWithAlpha >= 1u,
"Invalid channel number!");
1156 return tChannelsWithAlpha - 1u;
1159 template <
bool tAlphaAtFront>
1171 template <
bool tAlphaAtFront>
1172 template <
bool tSourceHasAlpha>
1175 return tSourceHasAlpha ? 1u : 0u;
1192 template <
bool tTargetHasAlpha>
1193 template <
unsigned int tChannelsWithAlpha>
1196 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1198 return tChannelsWithAlpha;
1202 template <
unsigned int tChannelsWithAlpha>
1205 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel number!");
1207 return tChannelsWithAlpha - 1u;
1210 template <
bool tTargetHasAlpha>
1211 template <
bool tAlphaAtFront>
1224 template <
bool tHasAlpha>
1225 template <
unsigned int tChannels>
1228 static_assert(tChannels >= 2u,
"Invalid channel input!");
1231 return tChannels - 1u;
1235 template <
unsigned int tChannels>
1238 static_assert(tChannels >= 1u,
"Invalid channel input!");
1244 template <
bool tHasAlpha>
1245 template <
unsigned int tChannelsWithAlpha>
1248 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1251 return tChannelsWithAlpha;
1255 template <
unsigned int tChannelsWithAlpha>
1258 static_assert(tChannelsWithAlpha >= 2u,
"Invalid channel input!");
1261 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:1246
static constexpr unsigned int dataChannels()
Returns the number of channels of a frame not counting the possible alpha channel.
Definition: FrameBlender.h:1226
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:1145
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:1160
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:1194
static constexpr unsigned int data()
Returns the offset that is applied to access the first data channel.
Definition: FrameBlender.h:1212
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:913
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:765
static uint8_t fullTransparent8Bit()
Returns the alpha value for a fully transparent pixel.
Definition: FrameBlender.h:895
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:732
static uint8_t alpha8BitToOpaqueIs0xFF(const uint8_t alpha)
Converts a given alpha value so that 0xFF is interpreted as fully opaque.
Definition: FrameBlender.h:925
static uint8_t fullOpaque8Bit()
Returns the alpha value for a fully opaque pixel.
Definition: FrameBlender.h:907
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:937
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:1120
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:1132
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:2876
This class implements Ocean's image class.
Definition: Frame.h:1792
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:4168
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4159
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4448
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:4042
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:3143
PixelOrigin pixelOrigin() const
Returns the pixel origin of the frame.
Definition: Frame.h:3188
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition: Frame.h:3183
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:3153
@ 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:3148
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition: Frame.h:3173
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition: Frame.h:3163
static unsigned char divideBy255(const unsigned int value)
This function applies a fast division by 255 for unsigned integer values.
Definition: base/Utilities.h:854
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