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.");
952 ocean_assert(
false &&
"Invalid frame type!");
956template <
unsigned int tChannels,
unsigned int tSize>
959 static_assert(tChannels >= 1u,
"Invalid channel number!");
960 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
962 ocean_assert(frame !=
nullptr);
964 const Vector2 direction(end - start);
967 const uint8_t zeroValue[tChannels] = {0x00};
968 const uint8_t*
const color = value ? value : zeroValue;
972 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, start, color,
FilterFactors<tSize>(), framePaddingElements);
976 const Vector2 step = direction / length;
978 for (
unsigned int n = 0u; n <= (
unsigned int)(length); ++n)
982 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))
984 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, position, color,
FilterFactors<tSize>(), framePaddingElements);
990template <
unsigned int tSize>
993 return Canvas::line<tSize>(frame,
line.point0(),
line.point1(), value);
996template <
unsigned int tSize>
1001 if (!Canvas::line<tSize>(frame,
line, value))
1010template <
unsigned int tChannels,
unsigned int tSize>
1013 static_assert(tChannels >= 1u,
"Invalid channel number!");
1014 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1016 ocean_assert(frame !=
nullptr);
1017 ocean_assert(width >= 1u && height >= 1u);
1018 ocean_assert(
line.isValid());
1020 Canvas::line8BitPerChannel<tChannels, tSize>(frame, width, height,
line.point0(),
line.point1(), value, framePaddingElements);
1023template <
unsigned int tSize>
1026 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1028 ocean_assert(frame.
isValid());
1052 ocean_assert(
false &&
"Invalid frame type!");
1056template <
unsigned int tSize>
1061 if (!Canvas::line<tSize>(frame,
line, value))
1070template <
unsigned int tChannels,
unsigned int tSize>
1071void Canvas::line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Line2& line,
const uint8_t* value,
const unsigned int framePaddingElements)
1073 static_assert(tChannels >= 1u,
"Invalid channel number!");
1074 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1076 ocean_assert(frame !=
nullptr);
1077 ocean_assert(width >= 1u && height >= 1u);
1078 ocean_assert(
line.isValid());
1083 line8BitPerChannel<tChannels, tSize>(frame, width, height, x0, y0, x1, y1, value, framePaddingElements);
1087template <
unsigned int tSize>
1090 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1092 ocean_assert(frame.
isValid());
1116 ocean_assert(
false &&
"Invalid frame type!");
1120template <
unsigned int tChannels,
unsigned int tSize>
1121void Canvas::box8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Box2& box,
const uint8_t* value,
const unsigned int paddingElements)
1123 ocean_assert(frame !=
nullptr);
1124 ocean_assert(width >= 1u && height >= 1u);
1125 ocean_assert(
box.isValid());
1127 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.top(),
box.left(),
box.bottom(), value, paddingElements);
1128 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.bottom(),
box.right(),
box.bottom(), value, paddingElements);
1129 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.bottom(),
box.right(),
box.top(), value, paddingElements);
1130 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.top(),
box.left(),
box.top(), value, paddingElements);
1133template <
unsigned int tChannels>
1134void 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)
1136 ocean_assert(frame);
1137 ocean_assert(position.
x() < width);
1138 ocean_assert(position.
y() < height);
1140 ocean_assert(horizontal >= 3u);
1141 ocean_assert(vertical >= 3u);
1142 ocean_assert(horizontal % 2u == 1u);
1143 ocean_assert(vertical % 2u == 1u);
1150 const unsigned int horizontalHalf = horizontal >> 1u;
1151 const unsigned int verticalHalf = vertical >> 1u;
1153 if (horizontalHalf < 199u && verticalHalf < 199u)
1155 ellipse8BitPerChannel<unsigned int, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1159 ellipse8BitPerChannel<unsigned long long, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1163template <
unsigned int tChannels>
1164void 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)
1166 static_assert(tChannels != 0u,
"Invalid channel number!");
1168 ocean_assert(frame != 0u);
1169 ocean_assert(width >= 1u && height >= 1u);
1171 const int clampedLeft = max(0, left);
1172 const int clampedTop = max(0, top);
1174 const int clampedRightEnd = min(left +
int(xSize),
int(width));
1175 const int clampedBottomEnd = min(top +
int(ySize),
int(height));
1177 if (clampedRightEnd <= clampedLeft || clampedBottomEnd <= clampedTop)
1185 const uint8_t
black[tChannels] = {0u};
1186 const PixelType pixelValue = value ? *(
const PixelType*)value : *(
const PixelType*)
black;
1188 const unsigned int clampedWidth = (
unsigned int)(clampedRightEnd - clampedLeft);
1189 const unsigned int clampedHeight = (
unsigned int)(clampedBottomEnd - clampedTop);
1191 ocean_assert(clampedWidth <= xSize);
1192 ocean_assert(clampedHeight <= ySize);
1194 ocean_assert(clampedLeft + clampedWidth <= width);
1195 ocean_assert(clampedTop + clampedHeight <= height);
1197 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1199 for (
unsigned int y = clampedTop; y < clampedTop + clampedHeight; ++y)
1201 PixelType*
const rowLeft = (PixelType*)(frame + y * frameStrideElements) + clampedLeft;
1203 for (
unsigned int x = 0u; x < clampedWidth; ++x)
1205 rowLeft[x] = pixelValue;
1210template <
unsigned int tSize, PixelCenter tPixelCenter>
1213 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1214 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1216 ocean_assert(frame);
1240 ocean_assert(
false &&
"Invalid frame type!");
1245template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1246void Canvas::point8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& position,
const uint8_t* value,
const unsigned int framePaddingElements)
1248 static_assert(tChannels >= 1u,
"Invalid channel number!");
1249 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1250 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1252 ocean_assert(frame !=
nullptr);
1254 const uint8_t explicitValue[tChannels] = {0x00};
1256 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value ? value : explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1259template <
unsigned int tSize, PixelCenter tPixelCenter>
1262 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1263 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1265 ocean_assert(frame);
1289 ocean_assert(
false &&
"Invalid frame type!");
1294template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1297 static_assert(tChannels >= 1u,
"Invalid channel number!");
1298 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1299 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1301 ocean_assert(frame !=
nullptr);
1305 for (
const Vector2& position : positions)
1307 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value,
FilterFactors<tSize>(), framePaddingElements);
1312 const uint8_t explicitValue[tChannels] = {0x00};
1314 for (
const Vector2& position : positions)
1316 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1321template <
typename T,
unsigned int tChannels>
1322void 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)
1324 static_assert(tChannels != 0u,
"Invalid number of channels!");
1326 ocean_assert(frame);
1327 ocean_assert(verticalHalf > 0u);
1328 ocean_assert(horizontalHalf > 0u);
1329 ocean_assert(position.
x() < width);
1330 ocean_assert(position.
y() < height);
1332 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1335 const uint8_t valueZero[tChannels] = {uint8_t(0)};
1337 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1349 const T a2 = (
sqr(horizontalHalf) +
sqr(horizontalHalf + 1u)) / 2u;
1350 const T b2 = (
sqr(verticalHalf) +
sqr(verticalHalf + 1u)) / 2u;
1351 const T ab2 = a2 * b2;
1353 for (
unsigned int y = position.
y(); y <= position.
y() + verticalHalf; ++y)
1355 unsigned int left = position.
x();
1356 unsigned int right = position.
x() + horizontalHalf + 1u;
1358 const T ySqra2 = T(
sqr(y - position.
y())) * a2;
1360 while (left + 1u < right)
1362 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1364 const unsigned int mid = (left + right) / 2u;
1366 if (T(
sqr(mid - position.
x())) * b2 + ySqra2 <= ab2)
1376 ocean_assert(left + 1u == right);
1377 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1378 ocean_assert(T(
sqr(right - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 > ab2);
1380 const unsigned int frameLeft = max(0,
int(2u * position.
x() - left));
1381 const unsigned int frameRight = min(right, width);
1383 ocean_assert(frameLeft < width);
1384 ocean_assert(frameRight <= width);
1385 ocean_assert(frameLeft < frameRight);
1388 if (2u * position.
y() >= y)
1390 const unsigned int frameTop = 2u * position.
y() - y;
1391 ocean_assert(frameTop < height);
1393 PixelType* pointer = (PixelType*)(frame + frameTop * frameStrideElements) + frameLeft;
1394 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1396 while (pointer != pointerEnd)
1398 *pointer++ = *pixelValue;
1405 PixelType* pointer = (PixelType*)(frame + y * frameStrideElements) + frameLeft;
1406 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1408 while (pointer != pointerEnd)
1410 *pointer++ = *pixelValue;
1416template <
unsigned int tChannels>
1419 static_assert(tChannels != 0u,
"Invalid number of channels!");
1421 ocean_assert(frame);
1422 ocean_assert(position.
x() < width);
1423 ocean_assert(position.
y() < height);
1425 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1428 const uint8_t valueZero[tChannels] = {0u};
1430 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1442 const uint8_t radius = uint8_t(max(horizontalHalf, verticalHalf));
1444 for (
unsigned int y = max(0,
int(position.
y() - radius)); y <= min(position.
y() + radius, height); ++y)
1446 for (
unsigned int x = max(0,
int(position.
x() - radius)); x <= min(position.
x() + radius, width); ++x)
1449 Vector3 invertedPosition(invertedRotation * position3);
1453 *((PixelType*)(frame + y * frameStrideElements) + x) = *pixelValue;
1459template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1462 static_assert(tChannels >= 1u,
"Invalid channel number!");
1463 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1464 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1466 ocean_assert(frame !=
nullptr);
1468 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1476 const unsigned int xFactor = (
unsigned int)((
Scalar(left) +
Scalar(1.5) - shiftedPosition.
x()) *
Scalar(128) +
Scalar(0.5));
1477 const unsigned int yFactor = (
unsigned int)((
Scalar(top) +
Scalar(1.5) - shiftedPosition.
y()) *
Scalar(128) +
Scalar(0.5));
1479 ocean_assert(xFactor <= 128u && yFactor <= 128u);
1483 for (
unsigned int y = 0u; y <= tSize; ++y)
1485 const unsigned int yInFrame = top + int(y) - int(tSize / 2u);
1487 if (yInFrame < height)
1489 for (
unsigned int x = 0u; x <= tSize; ++x)
1491 const unsigned int xInFrame = left + int(x) - int(tSize / 2u);
1493 if (xInFrame < width)
1495 const unsigned int factor = (128u - yFactor) * factors.
clampedFactor(
int(y - 1u)) * (128u - xFactor) * factors.
clampedFactor(
int(x - 1u))
1500 const unsigned int _factor = 16384 * sqrMaximalFilter - factor;
1502 uint8_t*
const pixel = frame + yInFrame * frameStrideElements + xInFrame * tChannels;
1504 for (
unsigned int n = 0u; n < tChannels; ++n)
1506 pixel[n] = uint8_t((pixel[n] * _factor + value[n] * factor + (16384u * sqrMaximalFilter) / 2u) / (16384u * sqrMaximalFilter));
1514template <
unsigned int tChannels>
1517 static_assert(tChannels != 0u,
"Invalid channel number!");
1519 ocean_assert(frame);
1520 ocean_assert(width >= 1u && height >= 1u);
1522 ocean_assert(position.
x() < width && position.
y() < height);
1526 const uint8_t zeroValue[tChannels] = {0u};
1527 const PixelType pixelValue = value ? *((PixelType*)value) : *((PixelType*)zeroValue);
1529 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1531 const unsigned int offset = position.
y() * frameStrideElements + position.
x() * tChannels;
1534 if (*(
const PixelType*)(frame + offset) == pixelValue)
1539 const PixelType areaPixelValue = *(
const PixelType*)(frame + offset);
1540 *(PixelType*)(frame + offset) = pixelValue;
1543 std::vector<PixelPosition> stack;
1544 stack.reserve((width * height) / 16u);
1547 if (position.
x() != 0u && *((
const PixelType*)(frame + offset) - 1) == areaPixelValue)
1549 stack.push_back(position.
west());
1553 if (position.
x() != width - 1u && *((
const PixelType*)(frame + offset) + 1) == areaPixelValue)
1555 stack.push_back(position.
east());
1559 if (position.
y() != 0u && *((
const PixelType*)(frame + offset - frameStrideElements)) == areaPixelValue)
1561 stack.push_back(position.
north());
1565 if (position.
y() != height - 1u && *((
const PixelType*)(frame + offset + frameStrideElements)) == areaPixelValue)
1567 stack.push_back(position.
south());
1570 while (!stack.empty())
1575 const unsigned int testOffset = pixel.
y() * frameStrideElements + pixel.
x() * tChannels;
1577 ocean_assert(*(
const PixelType*)(frame + testOffset) == areaPixelValue);
1579 *(PixelType*)(frame + testOffset) = pixelValue;
1582 if (pixel.
x() != 0u && *((
const PixelType*)(frame + testOffset) - 1) == areaPixelValue)
1584 stack.push_back(pixel.
west());
1588 if (pixel.
x() != width - 1u && *((
const PixelType*)(frame + testOffset) + 1) == areaPixelValue)
1590 stack.push_back(pixel.
east());
1594 if (pixel.
y() != 0u && *((
const PixelType*)(frame + testOffset - frameStrideElements)) == areaPixelValue)
1596 stack.push_back(pixel.
north());
1600 if (pixel.
y() != height - 1u && *((
const PixelType*)(frame + testOffset + frameStrideElements)) == areaPixelValue)
1602 stack.push_back(pixel.
south());
1607template <
unsigned int tSize>
1610 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1612 ocean_assert(frame.
isValid());
1619 polygon8BitPerChannel<1u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1623 polygon8BitPerChannel<2u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1627 polygon8BitPerChannel<3u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1631 polygon8BitPerChannel<4u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1636 ocean_assert(
false &&
"Invalid pixel format!");
1640template <
unsigned int tChannels,
unsigned int tSize>
1641void 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)
1643 static_assert(tChannels >= 1u,
"Invalid channel number!");
1644 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1646 ocean_assert(frame !=
nullptr);
1647 ocean_assert(width >= 1u && height >= 1u);
1649 if (numberPoints >= 2)
1651 for (
size_t n = 1; n < numberPoints; ++n)
1653 line8BitPerChannel<tChannels, tSize>(frame, width, height,
points[n - 1],
points[n], value, framePaddingElements);
1656 if (numberPoints >= 3 && closeLoop)
1658 line8BitPerChannel<tChannels, tSize>(frame, width, height,
points[numberPoints - 1],
points[0], value, framePaddingElements);
This class implements bresenham 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:162
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:1246
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:1608
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:1641
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:1515
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:1417
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:1134
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:1260
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:1164
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:1121
static bool point(Frame &frame, const Vector2 &position, const uint8_t *value=nullptr)
Paints a point with sub-pixel accuracy.
Definition Canvas.h:1211
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:1295
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:1088
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:1808
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition Frame.h:4242
bool isValid() const
Returns whether this frame is valid.
Definition Frame.h:4531
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition Frame.h:4125
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:3170
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition Frame.h:3210
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition Frame.h:41
unsigned int height() const
Returns the height of the frame in pixel.
Definition Frame.h:3175
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition Frame.h:3200
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition Frame.h:3190
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:2029
static constexpr T sqr(const T value)
Returns the square of a given value.
Definition Numeric.h:1495
static constexpr T binomialCoefficient(const T &n, const T &k)
Returns the binomial coefficient for two binomial parameters.
Definition Numeric.h:1960
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:1053
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
RotationT< Scalar > Rotation
Definition of the Rotation object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag either with ...
Definition Rotation.h:38
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition Line2.h:57
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition FiniteLine2.h:57
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition Vector2.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15
Default definition of a type with tBytes bytes.
Definition DataType.h:32