Message ID | 20200712150537.22946-1-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Commit | 6c0afb8b33a1586b2e5bb5543edca5103769af0e |
Headers | show |
Series |
|
Related | show |
Hi Laurent, Thanks for your work. On 2020-07-12 18:05:37 +0300, Laurent Pinchart wrote: > 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 <laurent.pinchart@ideasonboard.com> > Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> > --- > Changes since v1: > > - Rename aligneTo() to alignedUpTo() > - Add alignDownTo() > --- > 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 7d4b8bcfe3d8..d217cfd50c86 100644 > --- a/include/libcamera/geometry.h > +++ b/include/libcamera/geometry.h > @@ -8,6 +8,7 @@ > #ifndef __LIBCAMERA_GEOMETRY_H__ > #define __LIBCAMERA_GEOMETRY_H__ > > +#include <algorithm> > #include <string> > > 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 24c44fb43acf..4594f9ff435f 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 904ad92c9448..fd0132c03b02 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; > -- > Regards, > > Laurent Pinchart > > _______________________________________________ > libcamera-devel mailing list > libcamera-devel@lists.libcamera.org > https://lists.libcamera.org/listinfo/libcamera-devel
diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h index 7d4b8bcfe3d8..d217cfd50c86 100644 --- a/include/libcamera/geometry.h +++ b/include/libcamera/geometry.h @@ -8,6 +8,7 @@ #ifndef __LIBCAMERA_GEOMETRY_H__ #define __LIBCAMERA_GEOMETRY_H__ +#include <algorithm> #include <string> 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 24c44fb43acf..4594f9ff435f 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 904ad92c9448..fd0132c03b02 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;