8 #ifndef META_OCEAN_CV_ADVANCED_ADVANCED_FRAME_SHRINKER_H
9 #define META_OCEAN_CV_ADVANCED_ADVANCED_FRAME_SHRINKER_H
51 static bool divideByTwo(
const Frame& source,
Frame& target,
const Frame& sourceMask,
Frame& targetMask,
const bool handleFullMaskPixel,
bool* targetMaskHasPixel =
nullptr,
Worker* worker =
nullptr);
77 template <
unsigned int tChannels>
78 static inline void divideByTwo8BitPerChannel(
const uint8_t* source, uint8_t* target,
const uint8_t* sourceMask, uint8_t* targetMask,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int sourceMaskPaddingElements,
const unsigned int targetMaskPaddingElements,
const bool handleFullMaskPixel,
bool* targetMaskHasPixel =
nullptr,
Worker* worker =
nullptr);
100 template <
unsigned int tChannels>
101 static void divideByTwo8BitPerChannelSubset(
const uint8_t* source, uint8_t* target,
const uint8_t* sourceMask, uint8_t* targetMask,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int sourceMaskPaddingElements,
const unsigned int targetMaskPaddingElements,
const bool handleFullMaskPixel,
bool* targetMaskHasPixel,
const unsigned int firstTargetRow,
const unsigned int numberTargetRows);
104 template <
unsigned int tChannels>
105 inline void AdvancedFrameShrinker::divideByTwo8BitPerChannel(
const uint8_t* source, uint8_t* target,
const uint8_t* sourceMask, uint8_t* targetMask,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int sourceMaskPaddingElements,
const unsigned int targetMaskPaddingElements,
const bool handleFullMaskPixel,
bool* targetMaskHasPixel,
Worker* worker)
107 static_assert(tChannels != 0u,
"Invalid channel number!");
109 ocean_assert(source && target);
110 ocean_assert(sourceMask && targetMask);
112 ocean_assert(sourceWidth >= 2u && sourceHeight >= 2u);
114 const unsigned int targetHeight = sourceHeight / 2u;
118 worker->
executeFunction(
Worker::Function::createStatic(&AdvancedFrameShrinker::divideByTwo8BitPerChannelSubset<tChannels>, source, target, sourceMask, targetMask, sourceWidth, sourceHeight, sourcePaddingElements, targetPaddingElements, sourceMaskPaddingElements, targetMaskPaddingElements, handleFullMaskPixel, targetMaskHasPixel, 0u, 0u), 0u, targetHeight);
122 divideByTwo8BitPerChannelSubset<tChannels>(source, target, sourceMask, targetMask, sourceWidth, sourceHeight, sourcePaddingElements, targetPaddingElements, sourceMaskPaddingElements, targetMaskPaddingElements, handleFullMaskPixel, targetMaskHasPixel, 0u, targetHeight);
126 template <
unsigned int tChannels>
127 void AdvancedFrameShrinker::divideByTwo8BitPerChannelSubset(
const uint8_t* source, uint8_t* target,
const uint8_t* sourceMask, uint8_t* targetMask,
const unsigned int sourceWidth,
const unsigned int sourceHeight,
const unsigned int sourcePaddingElements,
const unsigned int targetPaddingElements,
const unsigned int sourceMaskPaddingElements,
const unsigned int targetMaskPaddingElements,
const bool handleFullMaskPixel,
bool* targetMaskHasPixel,
const unsigned int firstTargetRow,
const unsigned int numberTargetRows)
129 static_assert(tChannels != 0u,
"Invalid channel number!");
131 ocean_assert(source !=
nullptr && target !=
nullptr);
132 ocean_assert(sourceMask !=
nullptr && targetMask !=
nullptr);
134 ocean_assert(sourceWidth >= 2u && sourceHeight >= 2u);
136 const unsigned int targetWidth = sourceWidth / 2u;
137 const unsigned int targetHeight = sourceHeight / 2u;
139 const unsigned int sourceStrideElements = sourceWidth * tChannels + sourcePaddingElements;
140 const unsigned int targetStrideElements = targetWidth * tChannels + targetPaddingElements;
142 const unsigned int sourceMaskStrideElements = sourceWidth + sourceMaskPaddingElements;
143 const unsigned int targetMaskStrideElements = targetWidth + targetMaskPaddingElements;
145 ocean_assert(firstTargetRow + numberTargetRows <= targetHeight);
147 const bool threeRightColumns = sourceWidth % 2u == 1u;
148 const bool threeBottomRows = sourceHeight % 2u == 1u && firstTargetRow + numberTargetRows == targetHeight;
150 ocean_assert(numberTargetRows >= 1u);
151 const unsigned int twoTargetRows = threeBottomRows ? numberTargetRows - 1u : numberTargetRows;
153 ocean_assert(targetWidth >= 1u);
154 const unsigned int twoTargetColumns = threeRightColumns ? targetWidth - 1u : targetWidth;
156 const uint8_t* sourceTop = source + firstTargetRow * 2u * sourceStrideElements;
157 const uint8_t* sourceBottom = sourceTop + sourceStrideElements;
159 const uint8_t* sourceMaskTop = sourceMask + firstTargetRow * 2u * sourceMaskStrideElements;
160 const uint8_t* sourceMaskBottom = sourceMaskTop + sourceMaskStrideElements;
162 target += firstTargetRow * targetStrideElements;
163 targetMask += firstTargetRow * targetMaskStrideElements;
165 for (
unsigned int ty = firstTargetRow; ty < firstTargetRow + twoTargetRows; ++ty)
167 for (
unsigned int tx = 0u; tx < twoTargetColumns; ++tx)
169 const uint32_t state = uint32_t(sourceMaskTop[0]) | uint32_t(sourceMaskTop[1]) << 8u
170 | uint32_t(sourceMaskBottom[0]) << 16u | uint32_t(sourceMaskBottom[1]) << 24u;
178 for (
unsigned int n = 0u; n < tChannels; ++n)
180 *target++ = uint8_t((sourceTop[n] + sourceTop[tChannels + n] + sourceBottom[n] + sourceBottom[tChannels + n] + 2u) / 4u);
182 *targetMask++ = 0xFF;
190 for (
unsigned int n = 0u; n < tChannels; ++n)
192 *target++ = uint8_t((sourceTop[tChannels + n] + sourceBottom[n] + sourceBottom[tChannels + n] + 1u) / 3u);
194 *targetMask++ = 0xFF;
202 for (
unsigned int n = 0u; n < tChannels; ++n)
204 *target++ = uint8_t((sourceTop[n] + sourceBottom[n] + sourceBottom[tChannels + n] + 1u) / 3u);
206 *targetMask++ = 0xFF;
214 for (
unsigned int n = 0u; n < tChannels; ++n)
216 *target++ = uint8_t((sourceTop[n] + sourceTop[tChannels + n] + sourceBottom[tChannels + n] + 1u) / 3u);
218 *targetMask++ = 0xFF;
226 for (
unsigned int n = 0u; n < tChannels; ++n)
228 *target++ = uint8_t((sourceTop[n] + sourceTop[tChannels + n] + sourceBottom[n] + 1u) / 3u);
230 *targetMask++ = 0xFF;
238 for (
unsigned int n = 0u; n < tChannels; ++n)
240 *target++ = uint8_t((sourceBottom[n] + sourceBottom[tChannels + n] + 1u) / 2u);
242 *targetMask++ = 0xFF;
250 for (
unsigned int n = 0u; n < tChannels; ++n)
252 *target++ = uint8_t((sourceTop[n] + sourceBottom[n] + 1u) / 2u);
254 *targetMask++ = 0xFF;
262 for (
unsigned int n = 0u; n < tChannels; ++n)
264 *target++ = uint8_t((sourceTop[n] + sourceTop[tChannels + n] + 1u) / 2u);
266 *targetMask++ = 0xFF;
274 for (
unsigned int n = 0u; n < tChannels; ++n)
276 *target++ = uint8_t((sourceTop[tChannels + n] + sourceBottom[tChannels + n] + 1u) / 2u);
278 *targetMask++ = 0xFF;
286 for (
unsigned int n = 0u; n < tChannels; ++n)
288 *target++ = uint8_t((sourceTop[tChannels + n] + sourceBottom[n] + 1u) / 2u);
290 *targetMask++ = 0xFF;
298 for (
unsigned int n = 0u; n < tChannels; ++n)
300 *target++ = uint8_t((sourceTop[n] + sourceBottom[tChannels + n] + 1u) / 2u);
302 *targetMask++ = 0xFF;
310 for (
unsigned int n = 0u; n < tChannels; ++n)
312 *target++ = sourceBottom[tChannels + n];
314 *targetMask++ = 0xFF;
322 for (
unsigned int n = 0u; n < tChannels; ++n)
324 *target++ = sourceTop[n];
326 *targetMask++ = 0xFF;
334 for (
unsigned int n = 0u; n < tChannels; ++n)
336 *target++ = sourceTop[tChannels + n];
338 *targetMask++ = 0xFF;
346 for (
unsigned int n = 0u; n < tChannels; ++n)
348 *target++ = sourceBottom[n];
350 *targetMask++ = 0xFF;
358 *targetMask++ = 0x00;
360 if (targetMaskHasPixel)
362 *targetMaskHasPixel =
true;
365 if (handleFullMaskPixel)
367 for (
unsigned int n = 0u; n < tChannels; ++n)
369 target[n] = uint8_t((sourceTop[n] + sourceTop[tChannels + n] + sourceBottom[n] + sourceBottom[tChannels + n] + 2u) / 4u);
378 ocean_assert(
false &&
"Invalid mask!");
383 sourceTop += tChannels * 2u;
384 sourceBottom += tChannels * 2u;
387 sourceMaskBottom += 2;
390 if (threeRightColumns)
392 unsigned int values[tChannels] = {0u};
393 unsigned int validPixels = 0u;
395 for (
unsigned int i = 0u; i < 3u; ++i)
397 if (sourceMaskTop[i] == 0xFF)
399 for (
unsigned int n = 0u; n < tChannels; ++n)
401 values[n] += sourceTop[i * tChannels + n];
408 for (
unsigned int i = 0u; i < 3u; ++i)
410 if (sourceMaskBottom[i] == 0xFF)
412 for (
unsigned int n = 0u; n < tChannels; ++n)
414 values[n] += sourceBottom[i * tChannels + n];
421 if (validPixels != 0u)
425 const unsigned int validPixels_2 = validPixels / 2u;
427 for (
unsigned int n = 0u; n < tChannels; ++n)
429 target[n] = (uint8_t)((values[n] + validPixels_2) / validPixels);
436 if (targetMaskHasPixel)
438 *targetMaskHasPixel =
true;
441 if (handleFullMaskPixel)
443 for (
unsigned int n = 0u; n < tChannels; ++n)
445 target[n] = (sourceTop[n] + sourceTop[tChannels + n] + sourceTop[tChannels * 2u + n] + sourceBottom[n] + sourceBottom[tChannels + n] + sourceBottom[tChannels * 2u + n] + 3u) / 6u;
450 sourceTop += tChannels * 3u;
451 sourceBottom += tChannels * 3u;
455 sourceMaskBottom += 3;
460 sourceTop = sourceBottom + sourcePaddingElements;
461 sourceBottom = sourceTop + sourceStrideElements;
463 sourceMaskTop = sourceMaskBottom + sourceMaskPaddingElements;
464 sourceMaskBottom = sourceMaskTop + sourceMaskStrideElements;
466 target += targetPaddingElements;
467 targetMask += targetMaskPaddingElements;
472 for (
unsigned int tx = 0u; tx < targetWidth; ++tx)
474 unsigned int values[tChannels] = {0u};
475 unsigned int validPixels = 0u;
477 const unsigned int patchWidth = tx < twoTargetColumns ? 2u : 3u;
479 for (
unsigned int i = 0u; i < patchWidth; ++i)
481 if (sourceMaskTop[i] == 0xFF)
483 for (
unsigned int n = 0u; n < tChannels; ++n)
485 values[n] += sourceTop[i * tChannels + n];
492 for (
unsigned int i = 0u; i < patchWidth; ++i)
494 if (sourceMaskBottom[i] == 0xFF)
496 for (
unsigned int n = 0u; n < tChannels; ++n)
498 values[n] += sourceBottom[i * tChannels + n];
505 for (
unsigned int i = 0u; i < patchWidth; ++i)
507 if (sourceMaskBottom[sourceMaskStrideElements + i] == 0xFF)
509 for (
unsigned int n = 0u; n < tChannels; ++n)
511 values[n] += sourceBottom[sourceStrideElements + i * tChannels + n];
518 if (validPixels != 0u)
522 const unsigned int validPixels_2 = validPixels / 2u;
524 for (
unsigned int n = 0u; n < tChannels; ++n)
526 target[n] = (uint8_t)((values[n] + validPixels_2) / validPixels);
533 if (targetMaskHasPixel)
535 *targetMaskHasPixel =
true;
538 if (handleFullMaskPixel)
540 for (
unsigned int i = 0u; i < patchWidth; ++i)
542 for (
unsigned int n = 0u; n < tChannels; ++n)
544 values[n] += sourceTop[i * tChannels + n];
545 values[n] += sourceBottom[i * tChannels + n];
546 values[n] += sourceBottom[sourceStrideElements + i * tChannels + n];
550 validPixels = patchWidth * 3u;
551 const unsigned int validPixels_2 = validPixels / 2u;
553 for (
unsigned int n = 0u; n < tChannels; ++n)
555 target[n] = uint8_t((values[n] + validPixels_2) / validPixels);
560 sourceTop += tChannels * 2u;
561 sourceBottom += tChannels * 2u;
565 sourceMaskBottom += 2;
This class implements an advanced frame shrinker e.g., not simply combining visual information from t...
Definition: AdvancedFrameShrinker.h:30
static void divideByTwo8BitPerChannel(const uint8_t *source, uint8_t *target, const uint8_t *sourceMask, uint8_t *targetMask, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int sourceMaskPaddingElements, const unsigned int targetMaskPaddingElements, const bool handleFullMaskPixel, bool *targetMaskHasPixel=nullptr, Worker *worker=nullptr)
Bisects a given frame with 8 bit per frame channel while taking a corresponding mask into account.
Definition: AdvancedFrameShrinker.h:105
static bool divideByTwo(const Frame &source, Frame &target, const Frame &sourceMask, Frame &targetMask, const bool handleFullMaskPixel, bool *targetMaskHasPixel=nullptr, Worker *worker=nullptr)
Bisects a given frame while taking a corresponding mask into account.
static void divideByTwo8BitPerChannelSubset(const uint8_t *source, uint8_t *target, const uint8_t *sourceMask, uint8_t *targetMask, const unsigned int sourceWidth, const unsigned int sourceHeight, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, const unsigned int sourceMaskPaddingElements, const unsigned int targetMaskPaddingElements, const bool handleFullMaskPixel, bool *targetMaskHasPixel, const unsigned int firstTargetRow, const unsigned int numberTargetRows)
Bisects a subset of a given frame with 8 bit per frame channel.
Definition: AdvancedFrameShrinker.h:127
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
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