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);
774 template <
unsigned int tFilterSize>
777 static_assert(tFilterSize % 2u == 1u,
"Invalid aliasing direction filter size.");
779 if constexpr (tFilterSize <= 5u)
781 for (
unsigned int k = 0u; k < tFilterSize; ++k)
790 for (
unsigned int k = 0u; k < tFilterSize; ++k)
796 else if (k >= tFilterSize - 5u / 2u)
810 template <
unsigned int tFilterSize>
813 ocean_assert(index < tFilterSize);
815 return factors_[index];
818 template <
unsigned int tFilterSize>
821 if (index < 0 || index >=
int(tFilterSize))
826 return factors_[index];
829 template <
unsigned int tFilterSize>
832 return maximalFactor_;
835 template <
unsigned int tChannels>
836 void 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)
838 static_assert(tChannels >= 1u,
"Invalid channel number!");
840 ocean_assert(frame !=
nullptr);
841 ocean_assert(width != 0u && height != 0u);
843 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
845 const uint8_t zeroValue[tChannels] = {0u};
846 const uint8_t*
const color = value ? value : zeroValue;
851 Bresenham bresenham(x, y,
int(xEnd),
int(yEnd));
857 if ((
unsigned int)x < width && (
unsigned int)y < height)
859 uint8_t*
const pixel = frame + y * frameStrideElements + x * tChannels;
861 for (
unsigned int n = 0u; n < tChannels; ++n)
869 while (x !=
int(xEnd) || y !=
int(yEnd));
873 ocean_assert(x ==
int(xEnd) || y ==
int(yEnd));
875 if ((
unsigned int)x < width && (
unsigned int)y < height)
877 uint8_t*
const pixel = frame + y * frameStrideElements + x * tChannels;
879 for (
unsigned int n = 0u; n < tChannels; ++n)
886 template <
unsigned int tChannels>
887 void 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)
889 static_assert(tChannels >= 1u,
"Invalid channel number!");
891 ocean_assert(frame !=
nullptr);
892 ocean_assert(width != 0u && height != 0u);
894 if (numberPositions == 0u)
899 ocean_assert(positions !=
nullptr);
901 for (
unsigned int n = 0u; n < numberPositions - 1u; n += 2u)
903 ocean_assert(n + 1u < numberPositions);
904 line8BitPerChannel<tChannels>(frame, width, height, positions[n].x(), positions[n].y(), positions[n + 1].x(), positions[n + 1].y(), value, framePaddingElements);
908 template <
unsigned int tSize>
911 return line<tSize>(frame,
Vector2(xStart, yStart),
Vector2(xEnd, yEnd), value);
914 template <
unsigned int tChannels,
unsigned int tSize>
917 line8BitPerChannel<tChannels, tSize>(frame, width, height,
Vector2(xStart, yStart),
Vector2(xEnd, yEnd), value, framePaddingElements);
920 template <
unsigned int tSize>
923 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
949 ocean_assert(
false &&
"Invalid frame type!");
953 template <
unsigned int tChannels,
unsigned int tSize>
956 static_assert(tChannels >= 1u,
"Invalid channel number!");
957 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
959 ocean_assert(frame !=
nullptr);
961 const Vector2 direction(end - start);
964 const uint8_t zeroValue[tChannels] = {0x00};
965 const uint8_t*
const color = value ? value : zeroValue;
969 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, start, color,
FilterFactors<tSize>(), framePaddingElements);
973 const Vector2 step = direction / length;
975 for (
unsigned int n = 0u; n <= (
unsigned int)(length); ++n)
979 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))
981 point8BitPerChannel<tChannels, tSize, PC_CENTER>(frame, width, height, position, color,
FilterFactors<tSize>(), framePaddingElements);
987 template <
unsigned int tSize>
990 return Canvas::line<tSize>(frame,
line.point0(),
line.point1(), value);
993 template <
unsigned int tSize>
998 if (!Canvas::line<tSize>(frame,
line, value))
1007 template <
unsigned int tChannels,
unsigned int tSize>
1010 static_assert(tChannels >= 1u,
"Invalid channel number!");
1011 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1013 ocean_assert(frame !=
nullptr);
1014 ocean_assert(width >= 1u && height >= 1u);
1015 ocean_assert(
line.isValid());
1017 Canvas::line8BitPerChannel<tChannels, tSize>(frame, width, height,
line.point0(),
line.point1(), value, framePaddingElements);
1020 template <
unsigned int tSize>
1023 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1025 ocean_assert(frame.
isValid());
1049 ocean_assert(
false &&
"Invalid frame type!");
1053 template <
unsigned int tSize>
1058 if (!Canvas::line<tSize>(frame,
line, value))
1067 template <
unsigned int tChannels,
unsigned int tSize>
1068 void Canvas::line8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Line2& line,
const uint8_t* value,
const unsigned int framePaddingElements)
1070 static_assert(tChannels >= 1u,
"Invalid channel number!");
1071 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1073 ocean_assert(frame !=
nullptr);
1074 ocean_assert(width >= 1u && height >= 1u);
1075 ocean_assert(
line.isValid());
1080 line8BitPerChannel<tChannels, tSize>(frame, width, height, x0, y0, x1, y1, value, framePaddingElements);
1084 template <
unsigned int tSize>
1087 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1089 ocean_assert(frame.
isValid());
1113 ocean_assert(
false &&
"Invalid frame type!");
1117 template <
unsigned int tChannels,
unsigned int tSize>
1118 void Canvas::box8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Box2& box,
const uint8_t* value,
const unsigned int paddingElements)
1120 ocean_assert(frame !=
nullptr);
1121 ocean_assert(width >= 1u && height >= 1u);
1122 ocean_assert(
box.isValid());
1124 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.top(),
box.left(),
box.bottom(), value, paddingElements);
1125 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.left(),
box.bottom(),
box.right(),
box.bottom(), value, paddingElements);
1126 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.bottom(),
box.right(),
box.top(), value, paddingElements);
1127 line8BitPerChannel<tChannels, tSize>(frame, width, height,
box.right(),
box.top(),
box.left(),
box.top(), value, paddingElements);
1130 template <
unsigned int tChannels>
1131 void 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)
1133 ocean_assert(frame);
1134 ocean_assert(position.
x() < width);
1135 ocean_assert(position.
y() < height);
1137 ocean_assert(horizontal >= 3u);
1138 ocean_assert(vertical >= 3u);
1139 ocean_assert(horizontal % 2u == 1u);
1140 ocean_assert(vertical % 2u == 1u);
1147 const unsigned int horizontalHalf = horizontal >> 1u;
1148 const unsigned int verticalHalf = vertical >> 1u;
1150 if (horizontalHalf < 199u && verticalHalf < 199u)
1152 ellipse8BitPerChannel<unsigned int, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1156 ellipse8BitPerChannel<unsigned long long, tChannels>(frame, width, height, position, horizontalHalf, verticalHalf, value, paddingElements);
1160 template <
unsigned int tChannels>
1161 void 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)
1163 static_assert(tChannels != 0u,
"Invalid channel number!");
1165 ocean_assert(frame != 0u);
1166 ocean_assert(width >= 1u && height >= 1u);
1168 const int clampedLeft = max(0, left);
1169 const int clampedTop = max(0, top);
1171 const int clampedRightEnd = min(left +
int(xSize),
int(width));
1172 const int clampedBottomEnd = min(top +
int(ySize),
int(height));
1174 if (clampedRightEnd <= clampedLeft || clampedBottomEnd <= clampedTop)
1182 const uint8_t
black[tChannels] = {0u};
1183 const PixelType pixelValue = value ? *(
const PixelType*)value : *(
const PixelType*)
black;
1185 const unsigned int clampedWidth = (
unsigned int)(clampedRightEnd - clampedLeft);
1186 const unsigned int clampedHeight = (
unsigned int)(clampedBottomEnd - clampedTop);
1188 ocean_assert(clampedWidth <= xSize);
1189 ocean_assert(clampedHeight <= ySize);
1191 ocean_assert(clampedLeft + clampedWidth <= width);
1192 ocean_assert(clampedTop + clampedHeight <= height);
1194 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1196 for (
unsigned int y = clampedTop; y < clampedTop + clampedHeight; ++y)
1198 PixelType*
const rowLeft = (PixelType*)(frame + y * frameStrideElements) + clampedLeft;
1200 for (
unsigned int x = 0u; x < clampedWidth; ++x)
1202 rowLeft[x] = pixelValue;
1207 template <
unsigned int tSize, PixelCenter tPixelCenter>
1210 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1211 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1213 ocean_assert(frame);
1237 ocean_assert(
false &&
"Invalid frame type!");
1242 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1243 void Canvas::point8BitPerChannel(uint8_t* frame,
const unsigned int width,
const unsigned int height,
const Vector2& position,
const uint8_t* value,
const unsigned int framePaddingElements)
1245 static_assert(tChannels >= 1u,
"Invalid channel number!");
1246 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1247 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1249 ocean_assert(frame !=
nullptr);
1251 const uint8_t explicitValue[tChannels] = {0x00};
1253 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value ? value : explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1256 template <
unsigned int tSize, PixelCenter tPixelCenter>
1259 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1260 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1262 ocean_assert(frame);
1286 ocean_assert(
false &&
"Invalid frame type!");
1291 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1294 static_assert(tChannels >= 1u,
"Invalid channel number!");
1295 static_assert(tSize % 2u == 1u,
"Invalid size parameter!");
1296 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1298 ocean_assert(frame !=
nullptr);
1302 for (
const Vector2& position : positions)
1304 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, value,
FilterFactors<tSize>(), framePaddingElements);
1309 const uint8_t explicitValue[tChannels] = {0x00};
1311 for (
const Vector2& position : positions)
1313 point8BitPerChannel<tChannels, tSize, tPixelCenter>(frame, width, height, position, explicitValue,
FilterFactors<tSize>(), framePaddingElements);
1318 template <
typename T,
unsigned int tChannels>
1319 void 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)
1321 static_assert(tChannels != 0u,
"Invalid number of channels!");
1323 ocean_assert(frame);
1324 ocean_assert(verticalHalf > 0u);
1325 ocean_assert(horizontalHalf > 0u);
1326 ocean_assert(position.
x() < width);
1327 ocean_assert(position.
y() < height);
1329 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1332 const uint8_t valueZero[tChannels] = {uint8_t(0)};
1334 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1346 const T a2 = (
sqr(horizontalHalf) +
sqr(horizontalHalf + 1u)) / 2u;
1347 const T b2 = (
sqr(verticalHalf) +
sqr(verticalHalf + 1u)) / 2u;
1348 const T ab2 = a2 * b2;
1350 for (
unsigned int y = position.
y(); y <= position.
y() + verticalHalf; ++y)
1352 unsigned int left = position.
x();
1353 unsigned int right = position.
x() + horizontalHalf + 1u;
1355 const T ySqra2 = T(
sqr(y - position.
y())) * a2;
1357 while (left + 1u < right)
1359 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1361 const unsigned int mid = (left + right) / 2u;
1363 if (T(
sqr(mid - position.
x())) * b2 + ySqra2 <= ab2)
1373 ocean_assert(left + 1u == right);
1374 ocean_assert(T(
sqr(left - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 <= ab2);
1375 ocean_assert(T(
sqr(right - position.
x())) * b2 + T(
sqr(y - position.
y())) * a2 > ab2);
1377 const unsigned int frameLeft = max(0,
int(2u * position.
x() - left));
1378 const unsigned int frameRight = min(right, width);
1380 ocean_assert(frameLeft < width);
1381 ocean_assert(frameRight <= width);
1382 ocean_assert(frameLeft < frameRight);
1385 if (2u * position.
y() >= y)
1387 const unsigned int frameTop = 2u * position.
y() - y;
1388 ocean_assert(frameTop < height);
1390 PixelType* pointer = (PixelType*)(frame + frameTop * frameStrideElements) + frameLeft;
1391 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1393 while (pointer != pointerEnd)
1395 *pointer++ = *pixelValue;
1402 PixelType* pointer = (PixelType*)(frame + y * frameStrideElements) + frameLeft;
1403 PixelType*
const pointerEnd = pointer + (frameRight - frameLeft);
1405 while (pointer != pointerEnd)
1407 *pointer++ = *pixelValue;
1413 template <
unsigned int tChannels>
1416 static_assert(tChannels != 0u,
"Invalid number of channels!");
1418 ocean_assert(frame);
1419 ocean_assert(position.
x() < width);
1420 ocean_assert(position.
y() < height);
1422 const unsigned int frameStrideElements = width * tChannels + paddingElements;
1425 const uint8_t valueZero[tChannels] = {0u};
1427 const PixelType*
const pixelValue = value ==
nullptr ? (PixelType*)valueZero : (PixelType*)value;
1439 const uint8_t radius = uint8_t(max(horizontalHalf, verticalHalf));
1441 for (
unsigned int y = max(0,
int(position.
y() - radius)); y <= min(position.
y() + radius, height); ++y)
1443 for (
unsigned int x = max(0,
int(position.
x() - radius)); x <= min(position.
x() + radius, width); ++x)
1446 Vector3 invertedPosition(invertedRotation * position3);
1450 *((PixelType*)(frame + y * frameStrideElements) + x) = *pixelValue;
1456 template <
unsigned int tChannels,
unsigned int tSize, PixelCenter tPixelCenter>
1459 static_assert(tChannels >= 1u,
"Invalid channel number!");
1460 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1461 static_assert(tPixelCenter ==
PC_TOP_LEFT || tPixelCenter ==
PC_CENTER,
"Invalid pixel center!");
1463 ocean_assert(frame !=
nullptr);
1465 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1473 const unsigned int xFactor = (
unsigned int)((
Scalar(left) +
Scalar(1.5) - shiftedPosition.
x()) *
Scalar(128) +
Scalar(0.5));
1474 const unsigned int yFactor = (
unsigned int)((
Scalar(top) +
Scalar(1.5) - shiftedPosition.
y()) *
Scalar(128) +
Scalar(0.5));
1476 ocean_assert(xFactor <= 128u && yFactor <= 128u);
1480 for (
unsigned int y = 0u; y <= tSize; ++y)
1482 const unsigned int yInFrame = top + int(y) - int(tSize / 2u);
1484 if (yInFrame < height)
1486 for (
unsigned int x = 0u; x <= tSize; ++x)
1488 const unsigned int xInFrame = left + int(x) - int(tSize / 2u);
1490 if (xInFrame < width)
1492 const unsigned int factor = (128u - yFactor) * factors.
clampedFactor(
int(y - 1u)) * (128u - xFactor) * factors.
clampedFactor(
int(x - 1u))
1497 const unsigned int _factor = 16384 * sqrMaximalFilter - factor;
1499 uint8_t*
const pixel = frame + yInFrame * frameStrideElements + xInFrame * tChannels;
1501 for (
unsigned int n = 0u; n < tChannels; ++n)
1503 pixel[n] = uint8_t((pixel[n] * _factor + value[n] * factor + (16384u * sqrMaximalFilter) / 2u) / (16384u * sqrMaximalFilter));
1511 template <
unsigned int tChannels>
1514 static_assert(tChannels != 0u,
"Invalid channel number!");
1516 ocean_assert(frame);
1517 ocean_assert(width >= 1u && height >= 1u);
1519 ocean_assert(position.
x() < width && position.
y() < height);
1523 const uint8_t zeroValue[tChannels] = {0u};
1524 const PixelType pixelValue = value ? *((PixelType*)value) : *((PixelType*)zeroValue);
1526 const unsigned int frameStrideElements = width * tChannels + framePaddingElements;
1528 const unsigned int offset = position.
y() * frameStrideElements + position.
x() * tChannels;
1531 if (*(
const PixelType*)(frame + offset) == pixelValue)
1536 const PixelType areaPixelValue = *(
const PixelType*)(frame + offset);
1537 *(PixelType*)(frame + offset) = pixelValue;
1540 std::vector<PixelPosition> stack;
1541 stack.reserve((width * height) / 16u);
1544 if (position.
x() != 0u && *((
const PixelType*)(frame + offset) - 1) == areaPixelValue)
1546 stack.push_back(position.
west());
1550 if (position.
x() != width - 1u && *((
const PixelType*)(frame + offset) + 1) == areaPixelValue)
1552 stack.push_back(position.
east());
1556 if (position.
y() != 0u && *((
const PixelType*)(frame + offset - frameStrideElements)) == areaPixelValue)
1558 stack.push_back(position.
north());
1562 if (position.
y() != height - 1u && *((
const PixelType*)(frame + offset + frameStrideElements)) == areaPixelValue)
1564 stack.push_back(position.
south());
1567 while (!stack.empty())
1572 const unsigned int testOffset = pixel.
y() * frameStrideElements + pixel.
x() * tChannels;
1574 ocean_assert(*(
const PixelType*)(frame + testOffset) == areaPixelValue);
1576 *(PixelType*)(frame + testOffset) = pixelValue;
1579 if (pixel.
x() != 0u && *((
const PixelType*)(frame + testOffset) - 1) == areaPixelValue)
1581 stack.push_back(pixel.
west());
1585 if (pixel.
x() != width - 1u && *((
const PixelType*)(frame + testOffset) + 1) == areaPixelValue)
1587 stack.push_back(pixel.
east());
1591 if (pixel.
y() != 0u && *((
const PixelType*)(frame + testOffset - frameStrideElements)) == areaPixelValue)
1593 stack.push_back(pixel.
north());
1597 if (pixel.
y() != height - 1u && *((
const PixelType*)(frame + testOffset + frameStrideElements)) == areaPixelValue)
1599 stack.push_back(pixel.
south());
1604 template <
unsigned int tSize>
1607 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1609 ocean_assert(frame.
isValid());
1616 polygon8BitPerChannel<1u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1620 polygon8BitPerChannel<2u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1624 polygon8BitPerChannel<3u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1628 polygon8BitPerChannel<4u, tSize>(frame.
data<uint8_t>(), frame.
width(), frame.
height(),
points, numberPoints, value, closeLoop);
1633 ocean_assert(
false &&
"Invalid pixel format!");
1637 template <
unsigned int tChannels,
unsigned int tSize>
1638 void 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)
1640 static_assert(tChannels >= 1u,
"Invalid channel number!");
1641 static_assert(tSize % 2u == 1u,
"Invalid size parameter.");
1643 ocean_assert(frame !=
nullptr);
1644 ocean_assert(width >= 1u && height >= 1u);
1646 if (numberPoints >= 2)
1648 for (
size_t n = 1; n < numberPoints; ++n)
1650 line8BitPerChannel<tChannels, tSize>(frame, width, height,
points[n - 1],
points[n], value, framePaddingElements);
1653 if (numberPoints >= 3 && closeLoop)
1655 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:830
unsigned int clampedFactor(const int index) const
Returns the filter factor for a specific index.
Definition: Canvas.h:819
unsigned int factor(const unsigned int index) const
Returns the filter factor for a specific index.
Definition: Canvas.h:811
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 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:1243
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 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 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:1605
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:1638
static const uint8_t * green(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a green 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 * white(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a white color.
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:887
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:1512
static const uint8_t * gray(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a gray 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:1414
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:1131
static const uint8_t * red(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a red color.
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:1257
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:1161
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:836
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 const uint8_t * black(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a black color.
static const uint8_t * blue(const FrameType::PixelFormat pixelFormat=FrameType::FORMAT_RGB24)
Returns the color values for a blue color.
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:1118
static bool point(Frame &frame, const Vector2 &position, const uint8_t *value=nullptr)
Paints a point with sub-pixel accuracy.
Definition: Canvas.h:1208
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:1292
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:1085
PixelPositionT< T > west() const
Returns the pixel position west to this position.
Definition: PixelPosition.h:561
PixelPositionT< T > north() const
Returns the pixel position north to this position.
Definition: PixelPosition.h:549
PixelPositionT< T > east() const
Returns the pixel position east to this position.
Definition: PixelPosition.h:585
T y() const
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:470
T x() const
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:458
PixelPositionT< T > south() const
Returns the pixel position south to this position.
Definition: PixelPosition.h:573
Template class allowing to define an array of data types.
Definition: DataType.h:27
This class implements Ocean's image class.
Definition: Frame.h:1792
T * data(const unsigned int planeIndex=0u)
Returns a pointer to the pixel data of a specific plane.
Definition: Frame.h:4159
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4448
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition: Frame.h:4042
PixelFormat
Definition of all pixel formats available in the Ocean framework.
Definition: Frame.h:183
@ FORMAT_RGB24
Pixel format with byte order RGB and 24 bits per pixel.
Definition: Frame.h:315
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
uint32_t numberPlanes() const
Returns the number of planes of the pixel format of this frame.
Definition: Frame.h:3183
@ DT_UNSIGNED_INTEGER_8
Unsigned 8 bit integer data type (uint8_t).
Definition: Frame.h:41
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3148
unsigned int channels() const
Returns the number of individual channels the frame has.
Definition: Frame.h:3173
DataType dataType() const
Returns the data type of the pixel format of this frame.
Definition: Frame.h:3163
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:2026
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:1957
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:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
T length() const
Returns the length of the vector.
Definition: Vector2.h:615
const T & y() const noexcept
Returns the y value.
Definition: Vector3.h:812
const T & x() const noexcept
Returns the x value.
Definition: Vector3.h:800
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
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:31
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Line2 > Lines2
Definition of a vector holding Line2 objects.
Definition: Line2.h:57
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition: FiniteLine2.h:57
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15