From 6c0afb8b33a1586b2e5bb5543edca5103769af0e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 10 Jul 2020 11:23:25 +0300 Subject: libcamera: geometry: Add helper functions to the Size class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pipeline handlers commonly have to calculate the minimum or maximum of multiple sizes, or align a size's width and height. Add helper functions to the Size class to perform those tasks. Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Reviewed-by: Niklas Söderlund --- include/libcamera/geometry.h | 33 +++++++++++++++++++++++++++++++++ src/libcamera/geometry.cpp | 36 ++++++++++++++++++++++++++++++++++++ test/geometry.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 7d4b8bcf..d217cfd5 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -8,6 +8,7 @@ #ifndef __LIBCAMERA_GEOMETRY_H__ #define __LIBCAMERA_GEOMETRY_H__ +#include #include namespace libcamera { @@ -43,6 +44,38 @@ struct Size { bool isNull() const { return !width && !height; } const std::string toString() const; + + Size alignedDownTo(unsigned int hAlignment, unsigned int vAlignment) const + { + return { + width / hAlignment * hAlignment, + height / vAlignment * vAlignment + }; + } + + Size alignedUpTo(unsigned int hAlignment, unsigned int vAlignment) const + { + return { + (width + hAlignment - 1) / hAlignment * hAlignment, + (height + vAlignment - 1) / vAlignment * vAlignment + }; + } + + Size boundedTo(const Size &bound) const + { + return { + std::min(width, bound.width), + std::min(height, bound.height) + }; + } + + Size expandedTo(const Size &expand) const + { + return { + std::max(width, expand.width), + std::max(height, expand.height) + }; + } }; bool operator==(const Size &lhs, const Size &rhs); diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp index 24c44fb4..4594f9ff 100644 --- a/src/libcamera/geometry.cpp +++ b/src/libcamera/geometry.cpp @@ -122,6 +122,42 @@ const std::string Size::toString() const return std::to_string(width) + "x" + std::to_string(height); } +/** + * \fn Size::alignedDownTo(unsigned int hAlignment, unsigned int vAlignment) + * \brief Align the size down horizontally and vertically + * \param[in] hAlignment Horizontal alignment + * \param[in] vAlignment Vertical alignment + * \return A Size whose width and height are equal to the width and height of + * this size rounded down to the nearest multiple of \a hAlignment and + * \a vAlignment respectively + */ + +/** + * \fn Size::alignedUpTo(unsigned int hAlignment, unsigned int vAlignment) + * \brief Align the size up horizontally and vertically + * \param[in] hAlignment Horizontal alignment + * \param[in] vAlignment Vertical alignment + * \return A Size whose width and height are equal to the width and height of + * this size rounded up to the nearest multiple of \a hAlignment and + * \a vAlignment respectively + */ + +/** + * \fn Size::boundedTo(const Size &bound) + * \brief Bound the size to \a bound + * \param[in] bound The maximum size + * \return A Size whose width and height are the minimum of the width and + * height of this size and the \a bound size + */ + +/** + * \fn Size::expandedTo(const Size &expand) + * \brief Expand the size to \a expand + * \param[in] expand The minimum size + * \return A Size whose width and height are the maximum of the width and + * height of this size and the \a expand size + */ + /** * \brief Compare sizes for equality * \return True if the two sizes are equal, false otherwise diff --git a/test/geometry.cpp b/test/geometry.cpp index 904ad92c..fd0132c0 100644 --- a/test/geometry.cpp +++ b/test/geometry.cpp @@ -46,6 +46,35 @@ protected: return TestFail; } + /* Test alignedDownTo(), alignedUpTo(), boundedTo() and expandedTo() */ + if (Size(0, 0).alignedDownTo(16, 8) != Size(0, 0) || + Size(1, 1).alignedDownTo(16, 8) != Size(0, 0) || + Size(16, 8).alignedDownTo(16, 8) != Size(16, 8)) { + cout << "Size::alignedDownTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).alignedUpTo(16, 8) != Size(0, 0) || + Size(1, 1).alignedUpTo(16, 8) != Size(16, 8) || + Size(16, 8).alignedUpTo(16, 8) != Size(16, 8)) { + cout << "Size::alignedUpTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) || + Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) || + Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) { + cout << "Size::boundedTo() test failed" << endl; + return TestFail; + } + + if (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) || + Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) || + Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) { + cout << "Size::expandedTo() test failed" << endl; + return TestFail; + } + /* Test Size equality and inequality. */ if (!compare(Size(100, 100), Size(100, 100), &operator==, "==", true)) return TestFail; -- cgit v1.2.1