Ocean
FrameInterpolatorBilinearAlpha.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_FRAME_INTERPOLATOR_BILINEAR_ALPHA_H
9 #define META_OCEAN_CV_FRAME_INTERPOLATOR_BILINEAR_ALPHA_H
10 
11 #include "ocean/cv/CV.h"
12 #include "ocean/cv/FrameBlender.h"
13 
14 #include "ocean/base/Frame.h"
15 #include "ocean/base/Worker.h"
16 
18 #include "ocean/math/Vector2.h"
19 
20 namespace Ocean
21 {
22 
23 namespace CV
24 {
25 
26 /**
27  * This class implements bilinear frame interpolator functions for frames holding an alpha channel.
28  * @tparam tAlphaAtFront True, if the alpha channel is in the front of the data channels
29  * @tparam tTransparentIs0xFF True, if 0xFF is interpreted as fully transparent
30  * @ingroup cv
31  */
32 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
34 {
35  public:
36 
37  /**
38  * The following comfort class provides comfortable functions simplifying prototyping applications but also increasing binary size of the resulting applications.
39  * Best practice is to avoid using these functions if binary size matters,<br>
40  * as for every comfort function a corresponding function exists with specialized functionality not increasing binary size significantly.<br>
41  */
42  class OCEAN_CV_EXPORT Comfort
43  {
44  public:
45 
46  /**
47  * Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame.
48  * This function uses an integer interpolation with a precision of 1/128.
49  * @param frame The frame to determine the pixel values from, must be valid
50  * @param channels Number of channels of the given frame, with range [1, 8]
51  * @param width The width of the frame in pixel, with range [1, infinity)
52  * @param height The height of the frame in pixel, with range [1, infinity)
53  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
54  * @param pixelCenter The pixel center to be used during interpolation, either 'PC_TOP_LEFT' or 'PC_CENTER'
55  * @param position The position for which the interpolated pixel will be determined, with ranges [0, width - 1]x[0, height - 1] for PC_TOP_LEFT, [0, width]x[0, height] for PC_CENTER
56  * @param result Resulting pixel values, must be valid, must be valid
57  * @return True, if succeeded
58  * @tparam TScalar The scalar data type of the sub-pixel position
59  */
60  template <typename TScalar = Scalar>
61  static bool interpolatePixel8BitPerChannel(const uint8_t* frame, const unsigned int channels, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const PixelCenter pixelCenter, const VectorT2<TScalar>& position, uint8_t* result);
62  };
63 
64  public:
65 
66  /**
67  * Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame.
68  * This function uses an integer interpolation with a precision of 1/128.
69  * @param frame The frame to determine the pixel values from, must be valid
70  * @param width The width of the frame in pixel, with range [1, infinity)
71  * @param height The height of the frame in pixel, with range [1, infinity)
72  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
73  * @param position The position for which the interpolated pixel will be determined, with ranges [0, width - 1]x[0, height - 1] for PC_TOP_LEFT, [0, width]x[0, height] for PC_CENTER
74  * @param result Resulting pixel values, must be valid, must be valid
75  * @tparam tChannels Number of channels of the given frame, with range [1, infinity)
76  * @tparam tPixelCenter The pixel center to be used during interpolation, either 'PC_TOP_LEFT' or 'PC_CENTER'
77  * @tparam TScalar The scalar data type of the sub-pixel position
78  */
79  template <unsigned int tChannels, PixelCenter tPixelCenter = PC_TOP_LEFT, typename TScalar = Scalar>
80  static inline void interpolatePixel8BitPerChannel(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const VectorT2<TScalar>& position, uint8_t* result);
81 
82  /**
83  * Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame with alpha channel.
84  * The center of each pixel is located with an offset of (0.5 x 0.5) in relation to the real pixel position.<br>
85  * The given frame is virtually extended by a fully transparent border so that this functions supports arbitrary interpolation positions.<br>
86  * If the given position lies inside the frame area of (-0.5, -0.5) -> (width + 0.5, height + 0.5) the resulting interpolation result will contain color information of the frame, otherwise a fully transparent interpolation result is provided.<br>
87  * @param frame The frame to determine the pixel values from, must be valid, with range [1, infinity)
88  * @param width The width of the frame in pixel, with range [1, infinity)
89  * @param height The height of the frame in pixel, with range [1, infinity)
90  * @param framePaddingElements The number of padding elements at the end of each frame row, in elements, with range [0, infinity)
91  * @param position The position to determine the interpolated pixel values for, with range (-infinity, infinity)x(-infinity, infinity)
92  * @param result Resulting pixel values, must be valid, with range [1, infinity)
93  * @tparam tChannels Number of channels of the given frame, with range [1, infinity)
94  */
95  template <unsigned int tChannels>
96  static inline void interpolateInfiniteBorder8BitPerChannel(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vector2& position, uint8_t* result);
97 
98  protected:
99 
100  /**
101  * Returns the offset that is applied to access the alpha channel.
102  * @return Offset for the alpha channel
103  * @tparam tChannelsWithAlpha Number of channels in the source frame (including the alpha channel)
104  */
105  template <unsigned int tChannelsWithAlpha>
106  static inline unsigned int alphaOffset();
107 
108  /**
109  * Returns the offset that is applied to access the first data channel.
110  * @return Offset for the first data channel
111  */
112  static inline unsigned int dataOffset();
113 };
114 
115 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
116 template <typename TScalar>
117 bool FrameInterpolatorBilinearAlpha<tAlphaAtFront, tTransparentIs0xFF>::Comfort::interpolatePixel8BitPerChannel(const uint8_t* frame, const unsigned int channels, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const PixelCenter pixelCenter, const VectorT2<TScalar>& position, uint8_t* result)
118 {
119  ocean_assert(frame != nullptr);
120  ocean_assert(channels >= 1u && channels <= 8u);
121 
122  if (pixelCenter == PC_TOP_LEFT)
123  {
124  switch (channels)
125  {
126  case 1u:
128  return true;
129 
130  case 2u:
132  return true;
133 
134  case 3u:
136  return true;
137 
138  case 4u:
140  return true;
141 
142  case 5u:
144  return true;
145 
146  case 6u:
148  return true;
149 
150  case 7u:
152  return true;
153 
154  case 8u:
156  return true;
157  }
158  }
159  else
160  {
161  ocean_assert(pixelCenter == PC_CENTER);
162 
163  switch (channels)
164  {
165  case 1u:
167  return true;
168 
169  case 2u:
171  return true;
172 
173  case 3u:
175  return true;
176 
177  case 4u:
179  return true;
180 
181  case 5u:
183  return true;
184 
185  case 6u:
187  return true;
188 
189  case 7u:
191  return true;
192 
193  case 8u:
195  return true;
196  }
197  }
198 
199  ocean_assert(false && "Invalid channel number");
200  return false;
201 }
202 
203 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
204 template <unsigned int tChannels, PixelCenter tPixelCenter, typename TScalar>
205 inline void FrameInterpolatorBilinearAlpha<tAlphaAtFront, tTransparentIs0xFF>::interpolatePixel8BitPerChannel(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const VectorT2<TScalar>& position, uint8_t* result)
206 {
207  static_assert(tChannels != 0u, "Invalid channel number!");
208 
209  ocean_assert(frame != nullptr && result != nullptr);
210  ocean_assert(width > 0u && height > 0u);
211 
212  ocean_assert(position.x() >= TScalar(0));
213  ocean_assert(position.y() >= TScalar(0));
214 
215  if constexpr (tPixelCenter == PC_TOP_LEFT)
216  {
217  ocean_assert(position.x() <= TScalar(width - 1u));
218  ocean_assert(position.y() <= TScalar(height - 1u));
219  }
220  else
221  {
222  ocean_assert(tPixelCenter == PC_CENTER);
223 
224  ocean_assert(position.x() <= TScalar(width));
225  ocean_assert(position.y() <= TScalar(height));
226  }
227 
228  const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
229 
230  const TScalar xShifted = tPixelCenter == PC_TOP_LEFT ? position.x() : std::max(TScalar(0.0), position.x() - TScalar(0.5));
231  const TScalar yShifted = tPixelCenter == PC_TOP_LEFT ? position.y() : std::max(TScalar(0.0), position.y() - TScalar(0.5));
232 
233  const unsigned int left = (unsigned int)(xShifted);
234  const unsigned int top = (unsigned int)(yShifted);
235 
236  ocean_assert(left < width);
237  ocean_assert(top < height);
238 
239  const unsigned int rightOffset = left + 1u < width ? tChannels : 0u;
240  const unsigned int bottomOffset = top + 1u < height ? frameStrideElements : 0u;
241 
242  const uint8_t* topLeft = frame + top * frameStrideElements + left * tChannels;
243 
244  const TScalar sFactorRight = xShifted - TScalar(left);
245  const TScalar sFactorBottom = yShifted - TScalar(top);
246 
247  const unsigned int factorRight = (unsigned int)(sFactorRight * TScalar(128) + TScalar(0.5));
248  const unsigned int factorBottom = (unsigned int)(sFactorBottom * TScalar(128) + TScalar(0.5));
249 
250  const unsigned int factorLeft = 128u - factorRight;
251  const unsigned int factorTop = 128u - factorBottom;
252 
253  const unsigned int factorTopLeft = factorTop * factorLeft;
254  const unsigned int factorTopRight = factorTop * factorRight;
255  const unsigned int factorBottomLeft = factorBottom * factorLeft;
256  const unsigned int factorBottomRight = factorBottom * factorRight;
257 
258  const unsigned int factorTopLeftAlpha = factorTopLeft * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[alphaOffset<tChannels>()]);
259  const unsigned int factorTopRightAlpha = factorTopRight * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[rightOffset + alphaOffset<tChannels>()]);
260  const unsigned int factorBottomLeftAlpha = factorBottomLeft * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[bottomOffset + alphaOffset<tChannels>()]);
261  const unsigned int factorBottomRightAlpha = factorBottomRight * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[bottomOffset + rightOffset + alphaOffset<tChannels>()]);
262 
263  const unsigned int sumFactorsAlpha = factorTopLeftAlpha + factorTopRightAlpha + factorBottomLeftAlpha + factorBottomRightAlpha;
264 
265  const uint8_t* const pixelTopLeft = topLeft;
266  const uint8_t* const pixelTopRight = topLeft + rightOffset;
267  const uint8_t* const pixelBottomLeft = topLeft + bottomOffset;
268  const uint8_t* const pixelBottomRight = topLeft + bottomOffset + rightOffset;
269 
270  // determine interpolated color data channels
271  if (sumFactorsAlpha != 0u)
272  {
273  const unsigned int sumFactorsAlpha_2 = sumFactorsAlpha / 2u;
274 
275  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
276  {
277  result[n] = uint8_t((pixelTopLeft[n] * factorTopLeftAlpha + pixelTopRight[n] * factorTopRightAlpha + pixelBottomLeft[n] * factorBottomLeftAlpha + pixelBottomRight[n] * factorBottomRightAlpha + sumFactorsAlpha_2) / sumFactorsAlpha);
278  }
279  }
280  else
281  {
282  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
283  {
284  result[n] = uint8_t((pixelTopLeft[n] * factorTopLeft + pixelTopRight[n] * factorTopRight + pixelBottomLeft[n] * factorBottomLeft + pixelBottomRight[n] * factorBottomRight + 8192u) / 16384u);
285  }
286  }
287 
288  // determine interpolated transparency data channel (which is a standard bi-linear interpolation)
289  if constexpr (tTransparentIs0xFF)
290  {
291  result[alphaOffset<tChannels>()] = uint8_t((factorTopLeft * pixelTopLeft[alphaOffset<tChannels>()]
292  + factorTopRight * pixelTopRight[alphaOffset<tChannels>()]
293  + factorBottomLeft * pixelBottomLeft[alphaOffset<tChannels>()]
294  + factorBottomRight * pixelBottomRight[alphaOffset<tChannels>()] + 8192u) / 16384u);
295  }
296  else
297  {
298  result[alphaOffset<tChannels>()] = FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(uint8_t((sumFactorsAlpha + 8192u) / 16384u));
299  }
300 }
301 
302 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
303 template <unsigned int tChannels>
304 inline void FrameInterpolatorBilinearAlpha<tAlphaAtFront, tTransparentIs0xFF>::interpolateInfiniteBorder8BitPerChannel(const uint8_t* frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vector2& position, uint8_t* result)
305 {
306  static_assert(tChannels != 0u, "Invalid channel number!");
307 
308  ocean_assert(frame && result);
309 
310  const Vector2 pos(position.x() - Scalar(0.5), position.y() - Scalar(0.5));
311 
312  // check whether the position is outside the frame and will therefore be 100% transparent
313  if (pos.x() <= Scalar(-1) || pos.y() <= Scalar(-1) || pos.x() >= Scalar(width) || pos.y() >= Scalar(height))
314  {
315  for (unsigned int n = 0u; n < tChannels - 1u; ++n)
316  {
318  }
319 
320  result[FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()] = FrameBlender::fullTransparent8Bit<tTransparentIs0xFF>();
321  return;
322  }
323 
324  const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
325 
326  const int left = int(Numeric::floor(pos.x()));
327  const int top = int(Numeric::floor(pos.y()));
328 
329  ocean_assert(left >= -1 && left < int(width));
330  ocean_assert(top >= -1 && top < int(height));
331 
332  if ((unsigned int)left < width - 1u && (unsigned int)top < height - 1u)
333  {
334  // we have a valid pixel position for the left, top, right and bottom pixel
335 
336  const unsigned int txi = (unsigned int)((pos.x() - Scalar(left)) * Scalar(128) + Scalar(0.5));
337  const unsigned int txi_ = 128u - txi;
338 
339  const unsigned int tyi = (unsigned int)((pos.y() - Scalar(top)) * Scalar(128) + Scalar(0.5));
340  const unsigned int tyi_ = 128u - tyi;
341 
342  const uint8_t* topLeft = frame + top * frameStrideElements + left * tChannels;
343 
344  const unsigned int txty = txi * tyi * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[frameStrideElements + tChannels + alphaOffset<tChannels>()]);
345  const unsigned int txty_ = txi * tyi_ * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[tChannels + alphaOffset<tChannels>()]);
346  const unsigned int tx_ty = txi_ * tyi * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[frameStrideElements + alphaOffset<tChannels>()]);
347  const unsigned int tx_ty_ = txi_ * tyi_ * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[alphaOffset<tChannels>()]);
348 
349  const unsigned int denominator = tx_ty_ + txty_ + tx_ty + txty;
350 
351  // determine interpolated color data channels
352  if (denominator != 0u)
353  {
354  const unsigned int denominator_2 = denominator / 2u;
355 
356  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
357  {
358  result[n] = uint8_t((topLeft[n] * tx_ty_ + topLeft[tChannels + n] * txty_ + topLeft[frameStrideElements + n] * tx_ty + topLeft[frameStrideElements + tChannels + n] * txty + denominator_2) / denominator);
359  }
360  }
361  else
362  {
363  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
364  {
365  result[n] = uint8_t((topLeft[n] * txi_ * tyi_ + topLeft[tChannels + n] * txi * tyi_ + topLeft[frameStrideElements + n] * txi_ * tyi + topLeft[frameStrideElements + tChannels + n] * txi * tyi + 8192u) >> 14u);
366  }
367  }
368 
369  // determine interpolated transparency data channel (which is a standard bi-linear interpolation)
370  if constexpr (tTransparentIs0xFF)
371  {
372  // we have to handle this in a special way as we might get rounding errors otherwise
373  result[alphaOffset<tChannels>()] = uint8_t((txi_ * tyi_ * topLeft[alphaOffset<tChannels>()]
374  + txi * tyi_ * topLeft[tChannels + alphaOffset<tChannels>()]
375  + txi_ * tyi * topLeft[frameStrideElements + alphaOffset<tChannels>()]
376  + txi * tyi * topLeft[frameStrideElements + tChannels + alphaOffset<tChannels>()] + 8192u) >> 14u);
377  }
378  else
379  {
380  result[alphaOffset<tChannels>()] = FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(uint8_t((denominator + 8192u) >> 14u));
381  }
382  }
383  else
384  {
385  // we do not have a valid pixel for all 4-neighborhood pixels
386 
387  const unsigned int txi = (unsigned int)((pos.x() - Scalar(left)) * Scalar(128) + Scalar(0.5));
388  const unsigned int txi_ = 128u - txi;
389 
390  const unsigned int tyi = (unsigned int)((pos.y() - Scalar(top)) * Scalar(128) + Scalar(0.5));
391  const unsigned int tyi_ = 128u - tyi;
392 
393  const unsigned int rightOffset = (left >= 0 && left + 1u < width) ? tChannels : 0u;
394  const unsigned int bottomOffset = (top >= 0 && top + 1u < height) ? frameStrideElements : 0u;
395 
396  ocean_assert(left < int(width) && top < int(height));
397  const uint8_t* topLeft = frame + max(0, top) * frameStrideElements + max(0, left) * tChannels;
398 
399  const uint8_t alphaTopLeft = (left >= 0 && top >= 0) ? FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()])
400  : FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(FrameBlender::fullTransparent8Bit<tTransparentIs0xFF>());
401 
402  const uint8_t alphaTopRight = (left + 1u < width && top >= 0) ? FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[rightOffset + FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()])
403  : FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(FrameBlender::fullTransparent8Bit<tTransparentIs0xFF>());
404 
405  const uint8_t alphaBottomLeft = (left >= 0 && top + 1u < height) ? FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[bottomOffset + FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()])
406  : FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(FrameBlender::fullTransparent8Bit<tTransparentIs0xFF>());
407 
408  const uint8_t alphaBottomRight = (left + 1u < width && top + 1u < height) ? FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(topLeft[bottomOffset + rightOffset + FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()])
409  : FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(FrameBlender::fullTransparent8Bit<tTransparentIs0xFF>());
410 
411  const unsigned int txty = txi * tyi * alphaBottomRight;
412  const unsigned int txty_ = txi * tyi_ * alphaTopRight;
413  const unsigned int tx_ty = txi_ * tyi * alphaBottomLeft;
414  const unsigned int tx_ty_ = txi_ * tyi_ * alphaTopLeft;
415 
416  const unsigned int denominator = tx_ty_ + txty_ + tx_ty + txty;
417 
418  // determine interpolated color data channels
419  if (denominator != 0u)
420  {
421  const unsigned int denominator_2 = denominator / 2u;
422 
423  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
424  {
425  result[n] = uint8_t((topLeft[n] * tx_ty_ + topLeft[rightOffset + n] * txty_ + topLeft[bottomOffset + n] * tx_ty + topLeft[bottomOffset + rightOffset + n] * txty + denominator_2) / denominator);
426  }
427  }
428  else
429  {
430  for (unsigned int n = dataOffset(); n < tChannels + dataOffset() - 1u; ++n)
431  {
432  result[n] = uint8_t((topLeft[n] * txi_ * tyi_ + topLeft[rightOffset + n] * txi * tyi_ + topLeft[bottomOffset + n] * txi_ * tyi + topLeft[bottomOffset + rightOffset + n] * txi * tyi + 8192u) >> 14u);
433  }
434  }
435 
436  if constexpr (tTransparentIs0xFF)
437  {
438  // we have to handle this in a special way as we might get rounding errors otherwise
439  result[FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()] = uint8_t((txi_ * tyi_ * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(alphaTopLeft)
440  + txi * tyi_ * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(alphaTopRight)
441  + txi_ * tyi * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(alphaBottomLeft)
442  + txi * tyi * FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(alphaBottomRight) + 8192u) >> 14u);
443  }
444  else
445  {
446  result[FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannels>()] = FrameBlender::alpha8BitToOpaqueIs0xFF<tTransparentIs0xFF>(uint8_t((denominator + 8192u) >> 14u));
447  }
448  }
449 }
450 
451 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
452 template <unsigned int tChannelsWithAlpha>
454 {
455  return FrameBlender::SourceOffset<tAlphaAtFront>::template alpha<tChannelsWithAlpha>();
456 }
457 
458 template <bool tAlphaAtFront, bool tTransparentIs0xFF>
460 {
462 }
463 
464 }
465 
466 }
467 
468 #endif // META_OCEAN_CV_FRAME_INTERPOLATOR_BILINEAR_ALPHA_H
Helper class allowing to determine the offset that is necessary to access the alpha channel.
Definition: FrameBlender.h:60
static constexpr unsigned int data()
Returns the offset that is applied to access the first data channel.
Definition: FrameBlender.h:1160
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition: FrameInterpolatorBilinearAlpha.h:43
static bool interpolatePixel8BitPerChannel(const uint8_t *frame, const unsigned int channels, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const PixelCenter pixelCenter, const VectorT2< TScalar > &position, uint8_t *result)
Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame.
Definition: FrameInterpolatorBilinearAlpha.h:117
This class implements bilinear frame interpolator functions for frames holding an alpha channel.
Definition: FrameInterpolatorBilinearAlpha.h:34
static void interpolatePixel8BitPerChannel(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const VectorT2< TScalar > &position, uint8_t *result)
Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame.
Definition: FrameInterpolatorBilinearAlpha.h:205
static void interpolateInfiniteBorder8BitPerChannel(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const Vector2 &position, uint8_t *result)
Determines the interpolated pixel values for a given pixel position in an 8 bit per channel frame wit...
Definition: FrameInterpolatorBilinearAlpha.h:304
static unsigned int dataOffset()
Returns the offset that is applied to access the first data channel.
Definition: FrameInterpolatorBilinearAlpha.h:459
static unsigned int alphaOffset()
Returns the offset that is applied to access the alpha channel.
Definition: FrameInterpolatorBilinearAlpha.h:453
static T floor(const T value)
Returns the largest integer value that is not greater than the given value.
Definition: Numeric.h:2026
This class implements a vector with two elements.
Definition: Vector2.h:96
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
PixelCenter
Definition of individual centers of pixels.
Definition: CV.h:117
@ PC_TOP_LEFT
The center of a pixel is in the upper-left corner of each pixel's square.
Definition: CV.h:133
@ PC_CENTER
The center of a pixel is located in the center of each pixel's square (with an offset of 0....
Definition: CV.h:150
float Scalar
Definition of a scalar type.
Definition: Math.h:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15