8#ifndef META_OCEAN_CV_CANVAS_H
9#define META_OCEAN_CV_CANVAS_H
68 template <
unsigned int tFilterSize>
83 inline unsigned int factor(
const unsigned int index)
const;
91 inline unsigned int clampedFactor(
const int index)
const;
97 inline unsigned int maximalFactor()
const;
102 unsigned int factors_[tFilterSize];
105 unsigned int maximalFactor_ = 0u;
156 bool paint(
Frame& frame,
const int left,
const int top,
const uint8_t* foregroundColor,
const uint8_t* backgroundColor =
nullptr)
const;
178 uint8_t data_[2 + 32];
199 bool drawText(
Frame& frame,
const std::string& text,
const int left,
const int top,
const uint8_t* foregroundColor,
const uint8_t* backgroundColor =
nullptr)
const;
208 bool textExtent(
const std::string& text,
unsigned int& width,
unsigned int& height)
const;
294 static bool line(
Frame& frame,
const int xStart,
const int yStart,
const int xEnd,
const int yEnd,
const uint8_t* value =
nullptr);
306 static bool lines(
Frame& frame,
const PixelPosition* positions,
const unsigned int numberPositions,
const uint8_t* value =
nullptr);
323 template <
unsigned int tChannels>
324 static void line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const int xStart,
const int yStart,
const int xEnd,
const int yEnd,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
339 template <
unsigned int tChannels>
340 static void lines8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition* positions,
const unsigned int numberPositions,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
355 template <
unsigned int tSize>
356 static bool line(
Frame& frame,
const Scalar xStart,
const Scalar yStart,
const Scalar xEnd,
const Scalar yEnd,
const uint8_t* value =
nullptr);
374 template <
unsigned int tChannels,
unsigned int tSize>
375 static void line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Scalar xStart,
const Scalar yStart,
const Scalar xEnd,
const Scalar yEnd,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
388 template <
unsigned int tSize>
389 static bool line(
Frame& frame,
const Vector2& start,
const Vector2& end,
const uint8_t* value =
nullptr);
405 template <
unsigned int tChannels,
unsigned int tSize>
406 static void line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& start,
const Vector2& end,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
418 template <
unsigned int tSize>
419 static bool line(
Frame& frame,
const FiniteLine2& line,
const uint8_t* value =
nullptr);
431 template <
unsigned int tSize>
432 static inline bool lines(
Frame& frame,
const FiniteLines2& lines,
const uint8_t* value =
nullptr);
447 template <
unsigned int tChannels,
unsigned int tSize>
448 static void line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const FiniteLine2& line,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
459 template <
unsigned int tSize>
460 static bool line(
Frame& frame,
const Line2& line,
const uint8_t* value =
nullptr);
471 template <
unsigned int tSize>
472 static inline bool lines(
Frame& frame,
const Lines2& lines,
const uint8_t* value =
nullptr);
486 template <
unsigned int tChannels,
unsigned int tSize>
487 static void line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Line2& line,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
498 template <
unsigned int tSize>
499 static bool box(
Frame& frame,
const Box2& box,
const uint8_t* value =
nullptr);
513 template <
unsigned int tChannels,
unsigned int tSize>
514 static void box8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Box2& box,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
526 static bool ellipse(
Frame& frame,
const PixelPosition& position,
const unsigned int horizontal,
const unsigned int vertical,
const uint8_t* value =
nullptr);
541 template <
unsigned int tChannels>
542 static inline void ellipse8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const unsigned int horizontal,
const unsigned int vertical,
const uint8_t* value =
nullptr,
const unsigned int paddingElements = 0u);
567 static bool rectangle(
Frame& frame,
const int left,
const int top,
const unsigned int xSize,
const unsigned int ySize,
const uint8_t* value =
nullptr);
582 template <
unsigned int tChannels>
583 static void rectangle8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const int left,
const int top,
const unsigned int xSize,
const unsigned int ySize,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
594 template <
unsigned int tSize, PixelCenter tPixelCenter = CV::PC_CENTER>
595 static bool point(
Frame& frame,
const Vector2& position,
const uint8_t* value =
nullptr);
609 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter = CV::PC_CENTER>
610 static void point8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& position,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
621 template <
unsigned int tSize, PixelCenter tPixelCenter = CV::PC_CENTER>
622 static bool points(
Frame& frame,
const Vectors2& positions,
const uint8_t* value =
nullptr);
636 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter = CV::PC_CENTER>
637 static void points8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vectors2& positions,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
660 template <
unsigned int tChannels>
661 static void fill8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const uint8_t* value =
nullptr,
const unsigned int framePaddingElements = 0u);
673 template <
unsigned int tSize>
674 static bool polygon(
Frame& frame,
const Vector2* points,
size_t numberPoints,
const uint8_t* value =
nullptr,
const bool closeLoop =
true);
689 template <
unsigned int tChannels,
unsigned int tSize>
690 static void polygon8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2* points,
size_t numberPoints,
const uint8_t* value =
nullptr,
const bool closeLoop =
true,
const unsigned int framePaddingElements = 0u);
705 static bool drawText(
Frame& frame,
const std::string& text,
const int left,
const int top,
const uint8_t* foregroundColor,
const uint8_t* backgroundColor =
nullptr);
715 static bool textExtent(
const std::string& text,
unsigned int& width,
unsigned int& height);
738 template <
typename T,
unsigned int tChannels>
739 static void ellipse8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const unsigned int horizontalHalf,
const unsigned int verticalHalf,
const uint8_t* value,
const unsigned int paddingElements = 0u);
754 template <
unsigned int tChannels>
755 static void rotatedEllipse8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const unsigned int horizontalHalf,
const unsigned int verticalHalf,
const Scalar angle,
const uint8_t* value,
const unsigned int paddingElements = 0u);
770 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
771 static void point8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& position,
const uint8_t* value,
const FilterFactors<tSize>& factors,
const unsigned int framePaddingElements = 0u);
774template <
unsigned int tFilterSize>
777 static_assert(tFilterSize % 2u == 1u,
"Invalid aliasing direction filter size.");
781 if constexpr (tFilterSize <= 5u)
783 for (
unsigned int k = 0u; k <= tFilterSize / 2; ++k)
790 for (
unsigned int k = 0u; k <= tFilterSize / 2u; ++k)
805 for (
unsigned int k = tFilterSize / 2u + 1u; k < tFilterSize; ++k)
807 factors_[k] = factors_[tFilterSize - k - 1u];
810 maximalFactor_ = factors_[tFilterSize / 2u];
813template <
unsigned int tFilterSize>
816 ocean_assert(index < tFilterSize);
818 return factors_[index];
821template <
unsigned int tFilterSize>
824 if (index < 0 || index >=
int(tFilterSize))
829 return factors_[index];
832template <
unsigned int tFilterSize>
835 return maximalFactor_;
838template <
unsigned int tChannels>
839void Canvas::line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const int xStart,
const int yStart,
const int xEnd,
const int yEnd,
const uint8_t* value,
const unsigned int framePaddingElements)
841 static_assert(tChannels >= 1u,
"Invalid channel number!");
843 ocean_assert(frame !=
nullptr);
844 ocean_assert(width != 0u && height != 0u);
846 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
848 const uint8_t zeroValue[tChannels] = {0u};
849 const uint8_t*
const color = value ? value : zeroValue;
854 Bresenham bresenham(x, y,
int(xEnd),
int(yEnd));
860 if ((
unsigned int)x < width && (
unsigned int)y < height)
862 uint8_t*
const pixel = frame + y * frameStrideElements + x * tChannels;
864 for (
unsigned int n = 0u; n < tChannels; ++n)
872 while (x !=
int(xEnd) || y !=
int(yEnd));
876 ocean_assert(x ==
int(xEnd) || y ==
int(yEnd));
878 if ((
unsigned int)x < width && (
unsigned int)y < height)
880 uint8_t*
const pixel = frame + y * frameStrideElements + x * tChannels;
882 for (
unsigned int n = 0u; n < tChannels; ++n)
889template <
unsigned int tChannels>
890void Canvas::lines8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition* positions,
const unsigned int numberPositions,
const uint8_t* value,
const unsigned int framePaddingElements)
892 static_assert(tChannels >= 1u,
"Invalid channel number!");
894 ocean_assert(frame !=
nullptr);
895 ocean_assert(width != 0u && height != 0u);
897 if (numberPositions == 0u)
902 ocean_assert(positions !=
nullptr);
904 for (
unsigned int n = 0u; n < numberPositions - 1u; n += 2u)
906 ocean_assert(n + 1u < numberPositions);
907 line8BitPerChannel<tChannels>(frame, width, height, positions[n].x(), positions[n].y(), positions[n + 1].x(), positions[n + 1].y(), value, framePaddingElements);
911template <
unsigned int tSize>
914 return line<tSize>(frame,
Vector2(xStart, yStart),
Vector2(xEnd, yEnd), value);
917template <
unsigned int tChannels,
unsigned int tSize>
920 line8BitPerChannel<tChannels, tSize>(frame, width, height,
Vector2(xStart, yStart),
Vector2(xEnd, yEnd), value, framePaddingElements);
923template <
unsigned int tSize>
926 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
955 ocean_assert(
false &&
"Invalid frame type!");
959template <
unsigned int tChannels,
unsigned int tSize>
962 static_assert(tChannels >= 1u,
"Invalid channel number!");
963 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
965 ocean_assert(frame !=
nullptr);
967 const Vector2 direction(end - start);
970 const uint8_t zeroValue[tChannels] = {0x00};
971 const uint8_t*
const color = value ? value : zeroValue;
975 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, start, color,
FilterFactors<tSize>(), framePaddingElements);
979 const Vector2 step = direction / length;
981 for (
unsigned int n = 0u; n <= (
unsigned int)(length); ++n)
985 if (position.
x() >= -
Scalar(tSize / 2u) - 1 && position.
y() >= -
Scalar(tSize / 2u) - 1 && position.
x() <=
Scalar(width + tSize / 2u) && position.
y() <=
Scalar(height + tSize / 2u))
987 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, position, color,
FilterFactors<tSize>(), framePaddingElements);
993template <
unsigned int tSize>
996 return Canvas::line<tSize>(frame,
line.point0(),
line.point1(), value);
999template <
unsigned int tSize>
1004 if (!Canvas::line<tSize>(frame,
line, value))
1013template <
unsigned int tChannels,
unsigned int tSize>
1016 static_assert(tChannels >= 1u,
"Invalid channel number!");
1017 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1019 ocean_assert(frame !=
nullptr);
1020 ocean_assert(width >= 1u && height >= 1u);
1021 ocean_assert(
line.isValid());
1023 Canvas::line8BitPerChannel<tChannels, tSize>(frame, width, height,
line.point0(),
line.point1(), value, framePaddingElements);
1026template <
unsigned int tSize>
1029 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1031 ocean_assert(frame.
isValid());
1058 ocean_assert(
false &&
"Invalid frame type!");
1062template <
unsigned int tSize>
1067 if (!Canvas::line<tSize>(frame,
line, value))
1076template <
unsigned int tChannels,
unsigned int tSize>
1077void Canvas::line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Line2& line,
const uint8_t* value,
const unsigned int framePaddingElements)
1079 static_assert(tChannels >= 1u,
"Invalid channel number!");
1080 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1082 ocean_assert(frame !=
nullptr);
1083 ocean_assert(width >= 1u && height >= 1u);
1084 ocean_assert(
line.isValid());
1089 line8BitPerChannel<tChannels, tSize>(frame, width, height, x0, y0, x1, y1, value, framePaddingElements);
1093template <
unsigned int tSize>
1096 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1098 ocean_assert(frame.
isValid());
1125 ocean_assert(
false &&
"Invalid frame type!");
1129template <
unsigned int tChannels,
unsigned int tSize>
1130void Canvas::box8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Box2& box,
const uint8_t* value,
const unsigned int paddingElements)
1132 ocean_assert(frame !=
nullptr);
1133 ocean_assert(width >= 1u && height >= 1u);
1134 ocean_assert(
box.isValid());
1136 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.top(),
box.left(),
box.bottom(), value, paddingElements);
1137 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.bottom(),
box.right(),
box.bottom(), value, paddingElements);
1138 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.bottom(),
box.right(),
box.top(), value, paddingElements);
1139 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.top(),
box.left(),
box.top(), value, paddingElements);
1142template <
unsigned int tChannels>
1143void Canvas::ellipse8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const unsigned int horizontal,
const unsigned int vertical,
const uint8_t* value,
const unsigned int paddingElements)
1145 ocean_assert(frame);
1146 ocean_assert(position.
x() < width);
1147 ocean_assert(position.
y() < height);
1149 ocean_assert(horizontal >= 3u);
1150 ocean_assert(vertical >= 3u);
1151 ocean_assert(horizontal % 2u == 1u);
1152 ocean_assert(vertical % 2u == 1u);
1159 const unsigned int horizontalHalf = horizontal >> 1u;
1160 const unsigned int verticalHalf = vertical >> 1u;
1162 if (horizontalHalf < 199u && verticalHalf < 199u)
1164 ellipse8BitPerChannel<unsigned int, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1168 ellipse8BitPerChannel<unsigned long long, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1172template <
unsigned int tChannels>
1173void Canvas::rectangle8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const int left,
const int top,
const unsigned int xSize,
const unsigned int ySize,
const uint8_t* value,
const unsigned int framePaddingElements)
1175 static_assert(tChannels != 0u,
"Invalid channel number!");
1177 ocean_assert(frame != 0u);
1178 ocean_assert(width >= 1u && height >= 1u);
1180 const int clampedLeft = max(0, left);
1181 const int clampedTop = max(0, top);
1183 const int clampedRightEnd = min(left +
int(xSize),
int(width));
1184 const int clampedBottomEnd = min(top +
int(ySize),
int(height));
1186 if (clampedRightEnd <= clampedLeft || clampedBottomEnd <= clampedTop)
1194 const uint8_t
black[tChannels] = {0u};
1195 const PixelType pixelValue = value ? *(
const PixelType*)value : *(
const PixelType*)
black;
1197 const unsigned int clampedWidth = (
unsigned int)(clampedRightEnd - clampedLeft);
1198 const unsigned int clampedHeight = (
unsigned int)(clampedBottomEnd - clampedTop);
1200 ocean_assert(clampedWidth <= xSize);
1201 ocean_assert(clampedHeight <= ySize);
1203 ocean_assert(clampedLeft + clampedWidth <= width);
1204 ocean_assert(clampedTop + clampedHeight <= height);
1206 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1208 for (
unsigned int y = clampedTop; y < clampedTop + clampedHeight; ++y)
1210 PixelType*
const rowLeft = (PixelType*)(frame + y * frameStrideElements) + clampedLeft;
1212 for (
unsigned int x = 0u; x < clampedWidth; ++x)
1214 rowLeft[x] = pixelValue;
1219template <
unsigned int tSize, PixelCenter tPixelCenter>
1222 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1223 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1225 ocean_assert(frame);
1252 ocean_assert(
false &&
"Invalid frame type!");
1257template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1258void Canvas::point8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& position,
const uint8_t* value,
const unsigned int framePaddingElements)
1260 static_assert(tChannels >= 1u,
"Invalid channel number!");
1261 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1262 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1264 ocean_assert(frame !=
nullptr);
1266 const uint8_t explicitValue[tChannels] = {0x00};
1268 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value ? value : explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1271template <
unsigned int tSize, PixelCenter tPixelCenter>
1274 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1275 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1277 ocean_assert(frame);
1304 ocean_assert(
false &&
"Invalid frame type!");
1309template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1312 static_assert(tChannels >= 1u,
"Invalid channel number!");
1313 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1314 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1316 ocean_assert(frame !=
nullptr);
1320 for (
const Vector2& position : positions)
1322 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value,
FilterFactors<tSize>(), framePaddingElements);
1327 const uint8_t explicitValue[tChannels] = {0x00};
1329 for (
const Vector2& position : positions)
1331 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1336template <
typename T,
unsigned int tChannels>
1337void Canvas::ellipse8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const PixelPosition& position,
const unsigned int horizontalHalf,
const unsigned int verticalHalf,
const uint8_t* value,
const unsigned int paddingElements)
1339 static_assert(tChannels != 0u,
"Invalid number of channels!");
1341 ocean_assert(frame);
1342 ocean_assert(verticalHalf > 0u);
1343 ocean_assert(horizontalHalf > 0u);
1344 ocean_assert(position.
x() < width);
1345 ocean_assert(position.
y() < height);
1347 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1350 const uint8_t valueZero[tChannels] = {uint8_t(0)};
1352 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1364 const T a2 = (
sqr(horizontalHalf) +
sqr(horizontalHalf + 1u)) / 2u;
1365 const T b2 = (
sqr(verticalHalf) +
sqr(verticalHalf + 1u)) / 2u;
1366 const T ab2 = a2 * b2;
1368 for (
unsigned int y = position.
y(); y <= position.
y() + verticalHalf; ++y)
1370 unsigned int left = position.
x();
1371 unsigned int right = position.
x() + horizontalHalf + 1u;
1373 const T ySqra2 = T(
sqr(y - position.
y())) * a2;
1375 while (left + 1u < right)
1377 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1379 const unsigned int mid = (left + right) / 2u;
1381 if (T(
sqr(mid - position.
x())) * b2 + ySqra2 <= ab2)
1391 ocean_assert(left + 1u == right);
1392 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1393 ocean_assert(T(
sqr(right - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 > ab2);
1395 const unsigned int frameLeft = max(0,
int(2u * position.
x() - left));
1396 const unsigned int frameRight = min(right, width);
1398 ocean_assert(frameLeft < width);
1399 ocean_assert(frameRight <= width);
1400 ocean_assert(frameLeft < frameRight);
1403 if (2u * position.
y() >= y)
1405 const unsigned int frameTop = 2u * position.
y() - y;
1406 ocean_assert(frameTop < height);
1408 PixelType* pointer = (PixelType*)(frame + frameTop * frameStrideElements) + frameLeft;
1409 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1411 while (pointer != pointerEnd)
1413 *pointer++ = *pixelValue;
1420 PixelType* pointer = (PixelType*)(frame + y * frameStrideElements) + frameLeft;
1421 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1423 while (pointer != pointerEnd)
1425 *pointer++ = *pixelValue;
1431template <
unsigned int tChannels>
1434 static_assert(tChannels != 0u,
"Invalid number of channels!");
1436 ocean_assert(frame);
1437 ocean_assert(position.
x() < width);
1438 ocean_assert(position.
y() < height);
1440 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1443 const uint8_t valueZero[tChannels] = {0u};
1445 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1457 const uint8_t radius = uint8_t(max(horizontalHalf, verticalHalf));
1459 for (
unsigned int y = max(0,
int(position.
y() - radius)); y <= min(position.
y() + radius, height); ++y)
1461 for (
unsigned int x = max(0,
int(position.
x() - radius)); x <= min(position.
x() + radius, width); ++x)
1464 Vector3 invertedPosition(invertedRotation * position3);
1468 *((PixelType*)(frame + y * frameStrideElements) + x) = *pixelValue;
1474template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1477 static_assert(tChannels >= 1u,
"Invalid channel number!");
1478 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1479 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1481 ocean_assert(frame !=
nullptr);
1483 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1491 const unsigned int xFactor = (
unsigned int)((
Scalar(left) +
Scalar(1.5) - shiftedPosition.
x()) *
Scalar(128) +
Scalar(0.5));
1492 const unsigned int yFactor = (
unsigned int)((
Scalar(top) +
Scalar(1.5) - shiftedPosition.
y()) *
Scalar(128) +
Scalar(0.5));
1494 ocean_assert(xFactor <= 128u && yFactor <= 128u);
1498 for (
unsigned int y = 0u; y <= tSize; ++y)
1500 const unsigned int yInFrame = top + int(y) - int(tSize / 2u);
1502 if (yInFrame < height)
1504 for (
unsigned int x = 0u; x <= tSize; ++x)
1506 const unsigned int xInFrame = left + int(x) - int(tSize / 2u);
1508 if (xInFrame < width)
1510 const unsigned int factor = (128u - yFactor) * factors.
clampedFactor(
int(y - 1u)) * (128u - xFactor) * factors.
clampedFactor(
int(x - 1u))
1515 const unsigned int _factor = 16384 * sqrMaximalFilter - factor;
1517 uint8_t*
const pixel = frame + yInFrame * frameStrideElements + xInFrame * tChannels;
1519 for (
unsigned int n = 0u; n < tChannels; ++n)
1521 pixel[n] = uint8_t((pixel[n] * _factor + value[n] * factor + (16384u * sqrMaximalFilter) / 2u) / (16384u * sqrMaximalFilter));
1529template <
unsigned int tChannels>
1532 static_assert(tChannels != 0u,
"Invalid channel number!");
1534 ocean_assert(frame);
1535 ocean_assert(width >= 1u && height >= 1u);
1537 ocean_assert(position.
x() < width && position.
y() < height);
1541 const uint8_t zeroValue[tChannels] = {0u};
1542 const PixelType pixelValue = value ? *((PixelType*)value) : *((PixelType*)zeroValue);
1544 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1546 const unsigned int offset = position.
y() * frameStrideElements + position.
x() * tChannels;
1549 if (*(
const PixelType*)(frame + offset) == pixelValue)
1554 const PixelType areaPixelValue = *(
const PixelType*)(frame + offset);
1555 *(PixelType*)(frame + offset) = pixelValue;
1558 std::vector<PixelPosition> stack;
1559 stack.reserve((width * height) / 16u);
1562 if (position.
x() != 0u && *((
const PixelType*)(frame + offset) - 1) == areaPixelValue)
1564 stack.push_back(position.
west());
1568 if (position.
x() != width - 1u && *((
const PixelType*)(frame + offset) + 1) == areaPixelValue)
1570 stack.push_back(position.
east());
1574 if (position.
y() != 0u && *((
const PixelType*)(frame + offset - frameStrideElements)) == areaPixelValue)
1576 stack.push_back(position.
north());
1580 if (position.
y() != height - 1u && *((
const PixelType*)(frame + offset + frameStrideElements)) == areaPixelValue)
1582 stack.push_back(position.
south());
1585 while (!stack.empty())
1590 const unsigned int testOffset = pixel.
y() * frameStrideElements + pixel.
x() * tChannels;
1592 ocean_assert(*(
const PixelType*)(frame + testOffset) == areaPixelValue);
1594 *(PixelType*)(frame + testOffset) = pixelValue;
1597 if (pixel.
x() != 0u && *((
const PixelType*)(frame + testOffset) - 1) == areaPixelValue)
1599 stack.push_back(pixel.
west());
1603 if (pixel.
x() != width - 1u && *((
const PixelType*)(frame + testOffset) + 1) == areaPixelValue)
1605 stack.push_back(pixel.
east());
1609 if (pixel.
y() != 0u && *((
const PixelType*)(frame + testOffset - frameStrideElements)) == areaPixelValue)
1611 stack.push_back(pixel.
north());
1615 if (pixel.
y() != height - 1u && *((
const PixelType*)(frame + testOffset + frameStrideElements)) == areaPixelValue)
1617 stack.push_back(pixel.
south());
1622template <
unsigned int tSize>
1625 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1627 ocean_assert(frame.
isValid());
1634 polygon8BitPerChannel<1u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1638 polygon8BitPerChannel<2u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1642 polygon8BitPerChannel<3u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1646 polygon8BitPerChannel<4u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1654 ocean_assert(
false &&
"Invalid pixel format!");
1658template <
unsigned int tChannels,
unsigned int tSize>
1659void Canvas::polygon8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2* points,
size_t numberPoints,
const uint8_t* value,
const bool closeLoop,
const unsigned int framePaddingElements)
1661 static_assert(tChannels >= 1u,
"Invalid channel number!");
1662 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1664 ocean_assert(frame !=
nullptr);
1665 ocean_assert(width >= 1u && height >= 1u);
1667 if (numberPoints >= 2)
1669 for (
size_t n = 1; n < numberPoints; ++n)
1671 line8BitPerChannel<tChannels, tSize>(frame, width, height,
points[n - 1],
points[n], value, framePaddingElements);
1674 if (numberPoints >= 3 && closeLoop)
1676 line8BitPerChannel<tChannels, tSize>(frame, width, height,
points[numberPoints - 1],
points[0], value, framePaddingElements);
This class implements Bresenham's line algorithms.
Definition Bresenham.h:27
void findNext(int &x, int &y)
Applies one Bresenham step to find the next pixel.
static bool borderIntersection(const Line2 &line, const int leftBorder, const int topBorder, const int rightBorder, const int bottomBorder, int &x0, int &y0, int &x1, int &y1)
Computes the pixel-precise border intersection (the begin and end position) of a sub-pixel-precise 2D...
bool isValid() const
Returns whether this object holds a valid line.
Definition Bresenham.h:161
The following comfort class provides comfortable functions simplifying prototyping applications but a...
Definition Canvas.h:47
static bool point(Frame &frame, const Vector2 &position, const PixelCenter pixelCenter, const unsigned int size, const uint8_t *value=nullptr)
Paints a point with sub-pixel accuracy.
This class implements a helper class that provides binomial filter parameters for a specific filter s...
Definition Canvas.h:70
unsigned int maximalFactor() const
Returns the maximal (center) filter parameter for the specified filter size.
Definition Canvas.h:833
unsigned int clampedFactor(const int index) const
Returns the filter factor for a specific index.
Definition Canvas.h:822
unsigned int factor(const unsigned int index) const
Returns the filter factor for a specific index.
Definition Canvas.h:814
FilterFactors()
Creates a new filter factor object.
Definition Canvas.h:775
This class implements one character of a font for which each pixel has as size of at most 16x16.
Definition Canvas.h:121
bool paint(Frame &frame, const int left, const int top, const uint8_t *foregroundColor, const uint8_t *backgroundColor=nullptr) const
Paints the character at the specific location in a given frame.
Frame frame(const FrameType::PixelFormat pixelFormat, const uint8_t *foregroundColor, const uint8_t *backgroundColor) const
Creates a new frame and paints the character in the frame.
Character()
Creates an invalid character object.
bool isValid() const
Returns whether this character holds valid data.
Character(const Frame &frame, const uint8_t *color)
Creates a new character from a given image in which the actual character is visible.
unsigned int height() const
Returns the height of this character in pixel.
unsigned int width() const
Returns the width of this character in pixel.
This class implements a standard font similar to a code-block like font.
Definition Canvas.h:112
Font()
The protected constructor creating a new font.
Characters characters_
The characters of this font.
Definition Canvas.h:222
bool drawText(Frame &frame, const std::string &text, const int left, const int top, const uint8_t *foregroundColor, const uint8_t *backgroundColor=nullptr) const
Paints a given text into a given frame using this font.
bool textExtent(const std::string &text, unsigned int &width, unsigned int &height) const
Returns the bounding box a given text will occupy in pixel space when using this font.
std::vector< Character > Characters
Definition of a vector holding characters.
Definition Canvas.h:184
This class implements canvas functions.
Definition Canvas.h:38
static bool drawText(Frame &frame, const std::string &text, const int left, const int top, const uint8_t *foregroundColor, const uint8_t *backgroundColor=nullptr)
Paints a given text into a given frame using the standard (code style) font supporting only one size.
static const uint8_t * white(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a white color.
static const uint8_t * blue(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a blue color.
static void point8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Vector2 &position, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints a point with sub-pixel accuracy.
Definition Canvas.h:1258
static bool line(Frame &frame, const int xStart, const int yStart, const int xEnd, const int yEnd, const uint8_t *value=nullptr)
Paints a line with specified start and end position with pixel accuracy.
static bool ellipse(Frame &frame, const PixelPosition &position, const unsigned int horizontal, const unsigned int vertical, const uint8_t *value=nullptr)
Paints an ellipse at a specified position with specified size.
static const uint8_t * green(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a green color.
static bool polygon(Frame &frame, const Vector2 *points, size_t numberPoints, const uint8_t *value=nullptr, const bool closeLoop=true)
Paints the outline of a polygon with sub-pixel accuracy.
Definition Canvas.h:1623
static void polygon8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Vector2 *points, size_t numberPoints, const uint8_t *value=nullptr, const bool closeLoop=true, const unsigned int framePaddingElements=0u)
Paints the outline of a polygon with sub-pixel accuracy.
Definition Canvas.h:1659
static const uint8_t * black(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a black color.
static const uint8_t * yellow(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a yellow color.
static const uint8_t * gray(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a gray color.
static const uint8_t * memoryBlock32Byte()
Returns a memory block to 32 bytes as a backup in case a requested color value does not exist for a s...
static void lines8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const PixelPosition *positions, const unsigned int numberPositions, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints several lines with specified start and end positions with pixel accuracy.
Definition Canvas.h:890
static void fill8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const PixelPosition &position, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Fills an image area with a given color, an recursive seed-fill-algorithm is implemented.
Definition Canvas.h:1530
static const uint8_t * red(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a red color.
static void rotatedEllipse8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const PixelPosition &position, const unsigned int horizontalHalf, const unsigned int verticalHalf, const Scalar angle, const uint8_t *value, const unsigned int paddingElements=0u)
Paints a rotated elliptic region at a specified position with specified size.
Definition Canvas.h:1432
static void ellipse8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const PixelPosition &position, const unsigned int horizontal, const unsigned int vertical, const uint8_t *value=nullptr, const unsigned int paddingElements=0u)
Paints an ellipse at a specified position with specified size.
Definition Canvas.h:1143
static bool fill(Frame &frame, const PixelPosition &position, const uint8_t *value=nullptr)
Fills an image area with a given color, an recursive seed-fill-algorithm is implemented.
static bool rotatedEllipse(Frame &frame, const PixelPosition &position, const unsigned int horizontal, const unsigned int vertical, const Scalar angle, const uint8_t *value=nullptr)
Paints a rotated elliptic region at a specified position with specified size and rotation angle.
static bool points(Frame &frame, const Vectors2 &positions, const uint8_t *value=nullptr)
Paints points with sub-pixel accuracy.
Definition Canvas.h:1272
static bool lines(Frame &frame, const PixelPosition *positions, const unsigned int numberPositions, const uint8_t *value=nullptr)
Paints several lines with specified start and end positions with pixel accuracy.
static bool textExtent(const std::string &text, unsigned int &width, unsigned int &height)
Returns the bounding box a given text will occupy in pixel space when using the standard font.
static void rectangle8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const int left, const int top, const unsigned int xSize, const unsigned int ySize, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints a rectangle at a specified position with specified size.
Definition Canvas.h:1173
static void line8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const int xStart, const int yStart, const int xEnd, const int yEnd, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints a line with specified start and end position with pixel accuracy.
Definition Canvas.h:839
static bool rectangle(Frame &frame, const int left, const int top, const unsigned int xSize, const unsigned int ySize, const uint8_t *value=nullptr)
Paints a rectangle at a specified position with specified size.
static void box8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Box2 &box, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints a 2D axis aligned bounding box with sub-pixel accuracy.
Definition Canvas.h:1130
static bool point(Frame &frame, const Vector2 &position, const uint8_t *value=nullptr)
Paints a point with sub-pixel accuracy.
Definition Canvas.h:1220
static void points8BitPerChannel(uint8_t *frame, const unsigned int width, const unsigned int height, const Vectors2 &positions, const uint8_t *value=nullptr, const unsigned int framePaddingElements=0u)
Paints points with sub-pixel accuracy.
Definition Canvas.h:1310
static bool box(Frame &frame, const Box2 &box, const uint8_t *value=nullptr)
Paints a 2D axis aligned bounding box with sub-pixel accuracy.
Definition Canvas.h:1094
PixelPositionT< T > west() const
Returns the pixel position west to this position.
Definition PixelPosition.h:558
PixelPositionT< T > north() const
Returns the pixel position north to this position.
Definition PixelPosition.h:546
PixelPositionT< T > east() const
Returns the pixel position east to this position.
Definition PixelPosition.h:582
T y() const
Returns the vertical coordinate position of this object.
Definition PixelPosition.h:468
T x() const
Returns the horizontal coordinate position of this object.
Definition PixelPosition.h:456
PixelPositionT< T > south() const
Returns the pixel position south to this position.
Definition PixelPosition.h:570
This class implements Ocean's image class.
Definition Frame.h:1879
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4323
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4612
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:4206
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition Frame.h:183
unsigned int width() const
Returns the width of the frame format in pixel.
Definition Frame.h:3241
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition Frame.h:3281
@ 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:3246
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3271
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition Frame.h:3261
This class implements an infinite line in 2D space.
Definition Line2.h:83
static T floor(const T value)
Returns the largest integer value that is not greater than the given value.
Definition Numeric.h:2035
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1499
static constexpr T binomialCoefficient(const T &n, const T &k)
Returns the binomial coefficient for two binomial parameters.
Definition Numeric.h:1966
This template class is the base class for all singleton objects.
Definition Singleton.h:71
const T & x() const noexcept
Returns the x value.
Definition Vector2.h:710
const T & y() const noexcept
Returns the y value.
Definition Vector2.h:722
T length() const
Returns the length of the vector.
Definition Vector2.h:627
const T & y() const noexcept
Returns the y value.
Definition Vector3.h:824
const T & x() const noexcept
Returns the x value.
Definition Vector3.h:812
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition base/Utilities.h:1099
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
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
float Scalar
Definition of a scalar type.
Definition Math.h:129
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
RotationT< Scalar > Rotation
Definition of the Rotation object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag either with ...
Definition Rotation.h:32
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition FiniteLine2.h:57
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition Line2.h:57
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32