[{"id":11317,"web_url":"https://patchwork.libcamera.org/comment/11317/","msgid":"<20200710100516.v32hylqd4z6arf2b@uno.localdomain>","date":"2020-07-10T10:05:16","subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Fri, Jul 10, 2020 at 11:24:55AM +0300, Laurent Pinchart wrote:\n> Pipeline handlers commonly have to calculate the minimum or maximum of\n> multiple sizes, or align a size's width and height. Add helper functions\n> to the Size class to perform those tasks.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/geometry.h | 25 +++++++++++++++++++++++++\n>  src/libcamera/geometry.cpp   | 26 ++++++++++++++++++++++++++\n>  test/geometry.cpp            | 22 ++++++++++++++++++++++\n>  3 files changed, 73 insertions(+)\n>\n> diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> index 7d4b8bcfe3d8..c1411290f163 100644\n> --- a/include/libcamera/geometry.h\n> +++ b/include/libcamera/geometry.h\n> @@ -8,6 +8,7 @@\n>  #ifndef __LIBCAMERA_GEOMETRY_H__\n>  #define __LIBCAMERA_GEOMETRY_H__\n>\n> +#include <algorithm>\n>  #include <string>\n>\n>  namespace libcamera {\n> @@ -43,6 +44,30 @@ struct Size {\n>\n>  \tbool isNull() const { return !width && !height; }\n>  \tconst std::string toString() const;\n> +\n> +\tSize alignedTo(unsigned int hAlignment, unsigned int vAlignment) const\n\nShould this take a Size ?\n\nAlso, is aligned always assumed to happen to next largest integer ?\nShouldn't this be alignIncrease or similar ?\n\n> +\t{\n> +\t\treturn {\n> +\t\t\t(width + hAlignment - 1) / hAlignment * hAlignment,\n> +\t\t\t(height + vAlignment - 1) / vAlignment * vAlignment\n> +\t\t};\n> +\t}\n> +\n> +\tSize boundedTo(const Size &bound) const\n> +\t{\n> +\t\treturn {\n> +\t\t\tstd::min(width, bound.width),\n> +\t\t\tstd::min(height, bound.height)\n> +\t\t};\n> +\t}\n> +\n> +\tSize expandedTo(const Size &expand) const\n> +\t{\n> +\t\treturn {\n> +\t\t\tstd::max(width, expand.width),\n> +\t\t\tstd::max(height, expand.height)\n> +\t\t};\n> +\t}\n>  };\n>\n>  bool operator==(const Size &lhs, const Size &rhs);\n> diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n> index 24c44fb43acf..d647c5efbdb1 100644\n> --- a/src/libcamera/geometry.cpp\n> +++ b/src/libcamera/geometry.cpp\n> @@ -122,6 +122,32 @@ const std::string Size::toString() const\n>  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n>  }\n>\n> +/**\n> + * \\fn Size::alignedTo(unsigned int hAlignment, unsigned int vAlignment)\n> + * \\brief Align the size horizontally and vertically\n> + * \\param[in] hAlignment Horizontal alignment\n> + * \\param[in] vAlignment Vertical alignment\n> + * \\return A Size whose width and height are equal to the width and height of\n> + * this size aligned to the next multiple of \\a hAlignment and \\a vAlignment\n> + * respectively\n> + */\n> +\n> +/**\n> + * \\fn Size::boundedTo(const Size &bound)\n> + * \\brief Bound the size to \\a bound\n> + * \\param[in] bound The maximum size\n> + * \\return A Size whose width and height are the minimum of the width and\n> + * height of this size and the \\a bound size\n> + */\n> +\n> +/**\n> + * \\fn Size::expandedTo(const Size &expand)\n> + * \\brief Expand the size to \\a expand\n> + * \\param[in] expand The minimum size\n> + * \\return A Size whose width and height are the maximum of the width and\n> + * height of this size and the \\a expand size\n> + */\n> +\n>  /**\n>   * \\brief Compare sizes for equality\n>   * \\return True if the two sizes are equal, false otherwise\n> diff --git a/test/geometry.cpp b/test/geometry.cpp\n> index 904ad92c9448..5ef7cb7c9014 100644\n> --- a/test/geometry.cpp\n> +++ b/test/geometry.cpp\n> @@ -46,6 +46,28 @@ protected:\n>  \t\t\treturn TestFail;\n>  \t\t}\n>\n> +\t\t/* Test alignedTo(), boundedTo() and expandedTo() */\n> +\t\tif (Size(0, 0).alignedTo(16, 8) != Size(0, 0) ||\n> +\t\t    Size(1, 1).alignedTo(16, 8) != Size(16, 8) ||\n> +\t\t    Size(16, 8).alignedTo(16, 8) != Size(16, 8)) {\n> +\t\t\tcout << \"Size::alignedTo() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||\n> +\t\t    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||\n> +\t\t    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {\n> +\t\t\tcout << \"Size::boundedTo() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||\n> +\t\t    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||\n> +\t\t    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {\n> +\t\t\tcout << \"Size::expandedTo() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n\nLooks good and will use it in the IPU3 series.\n\nThanks\n  j\n\n>  \t\t/* Test Size equality and inequality. */\n>  \t\tif (!compare(Size(100, 100), Size(100, 100), &operator==, \"==\", true))\n>  \t\t\treturn TestFail;\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 5B776BD792\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Jul 2020 10:01:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 05269613B3;\n\tFri, 10 Jul 2020 12:01:44 +0200 (CEST)","from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net\n\t[217.70.183.193])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0226561186\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jul 2020 12:01:42 +0200 (CEST)","from uno.localdomain (host-95-245-128-189.retail.telecomitalia.it\n\t[95.245.128.189]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 28884240002;\n\tFri, 10 Jul 2020 10:01:41 +0000 (UTC)"],"X-Originating-IP":"95.245.128.189","Date":"Fri, 10 Jul 2020 12:05:16 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200710100516.v32hylqd4z6arf2b@uno.localdomain>","References":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11320,"web_url":"https://patchwork.libcamera.org/comment/11320/","msgid":"<20200710113054.GI5964@pendragon.ideasonboard.com>","date":"2020-07-10T11:30:54","subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Fri, Jul 10, 2020 at 12:05:16PM +0200, Jacopo Mondi wrote:\n> On Fri, Jul 10, 2020 at 11:24:55AM +0300, Laurent Pinchart wrote:\n> > Pipeline handlers commonly have to calculate the minimum or maximum of\n> > multiple sizes, or align a size's width and height. Add helper functions\n> > to the Size class to perform those tasks.\n> >\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  include/libcamera/geometry.h | 25 +++++++++++++++++++++++++\n> >  src/libcamera/geometry.cpp   | 26 ++++++++++++++++++++++++++\n> >  test/geometry.cpp            | 22 ++++++++++++++++++++++\n> >  3 files changed, 73 insertions(+)\n> >\n> > diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> > index 7d4b8bcfe3d8..c1411290f163 100644\n> > --- a/include/libcamera/geometry.h\n> > +++ b/include/libcamera/geometry.h\n> > @@ -8,6 +8,7 @@\n> >  #ifndef __LIBCAMERA_GEOMETRY_H__\n> >  #define __LIBCAMERA_GEOMETRY_H__\n> >\n> > +#include <algorithm>\n> >  #include <string>\n> >\n> >  namespace libcamera {\n> > @@ -43,6 +44,30 @@ struct Size {\n> >\n> >  \tbool isNull() const { return !width && !height; }\n> >  \tconst std::string toString() const;\n> > +\n> > +\tSize alignedTo(unsigned int hAlignment, unsigned int vAlignment) const\n> \n> Should this take a Size ?\n\nI've thought about it, but it's really two alignments, not a size.\n\n> Also, is aligned always assumed to happen to next largest integer ?\n> Shouldn't this be alignIncrease or similar ?\n\nalignedUpTo and alignedDownTo ? roundedDownTo and roundedUpTo ? Do you\nneed both in the IPU3 pipeline handler ?\n\n> > +\t{\n> > +\t\treturn {\n> > +\t\t\t(width + hAlignment - 1) / hAlignment * hAlignment,\n> > +\t\t\t(height + vAlignment - 1) / vAlignment * vAlignment\n> > +\t\t};\n> > +\t}\n> > +\n> > +\tSize boundedTo(const Size &bound) const\n> > +\t{\n> > +\t\treturn {\n> > +\t\t\tstd::min(width, bound.width),\n> > +\t\t\tstd::min(height, bound.height)\n> > +\t\t};\n> > +\t}\n> > +\n> > +\tSize expandedTo(const Size &expand) const\n> > +\t{\n> > +\t\treturn {\n> > +\t\t\tstd::max(width, expand.width),\n> > +\t\t\tstd::max(height, expand.height)\n> > +\t\t};\n> > +\t}\n> >  };\n> >\n> >  bool operator==(const Size &lhs, const Size &rhs);\n> > diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n> > index 24c44fb43acf..d647c5efbdb1 100644\n> > --- a/src/libcamera/geometry.cpp\n> > +++ b/src/libcamera/geometry.cpp\n> > @@ -122,6 +122,32 @@ const std::string Size::toString() const\n> >  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n> >  }\n> >\n> > +/**\n> > + * \\fn Size::alignedTo(unsigned int hAlignment, unsigned int vAlignment)\n> > + * \\brief Align the size horizontally and vertically\n> > + * \\param[in] hAlignment Horizontal alignment\n> > + * \\param[in] vAlignment Vertical alignment\n> > + * \\return A Size whose width and height are equal to the width and height of\n> > + * this size aligned to the next multiple of \\a hAlignment and \\a vAlignment\n> > + * respectively\n> > + */\n> > +\n> > +/**\n> > + * \\fn Size::boundedTo(const Size &bound)\n> > + * \\brief Bound the size to \\a bound\n> > + * \\param[in] bound The maximum size\n> > + * \\return A Size whose width and height are the minimum of the width and\n> > + * height of this size and the \\a bound size\n> > + */\n> > +\n> > +/**\n> > + * \\fn Size::expandedTo(const Size &expand)\n> > + * \\brief Expand the size to \\a expand\n> > + * \\param[in] expand The minimum size\n> > + * \\return A Size whose width and height are the maximum of the width and\n> > + * height of this size and the \\a expand size\n> > + */\n> > +\n> >  /**\n> >   * \\brief Compare sizes for equality\n> >   * \\return True if the two sizes are equal, false otherwise\n> > diff --git a/test/geometry.cpp b/test/geometry.cpp\n> > index 904ad92c9448..5ef7cb7c9014 100644\n> > --- a/test/geometry.cpp\n> > +++ b/test/geometry.cpp\n> > @@ -46,6 +46,28 @@ protected:\n> >  \t\t\treturn TestFail;\n> >  \t\t}\n> >\n> > +\t\t/* Test alignedTo(), boundedTo() and expandedTo() */\n> > +\t\tif (Size(0, 0).alignedTo(16, 8) != Size(0, 0) ||\n> > +\t\t    Size(1, 1).alignedTo(16, 8) != Size(16, 8) ||\n> > +\t\t    Size(16, 8).alignedTo(16, 8) != Size(16, 8)) {\n> > +\t\t\tcout << \"Size::alignedTo() test failed\" << endl;\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\tif (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||\n> > +\t\t    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||\n> > +\t\t    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {\n> > +\t\t\tcout << \"Size::boundedTo() test failed\" << endl;\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> > +\t\tif (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||\n> > +\t\t    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||\n> > +\t\t    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {\n> > +\t\t\tcout << \"Size::expandedTo() test failed\" << endl;\n> > +\t\t\treturn TestFail;\n> > +\t\t}\n> > +\n> \n> Looks good and will use it in the IPU3 series.\n> \n> >  \t\t/* Test Size equality and inequality. */\n> >  \t\tif (!compare(Size(100, 100), Size(100, 100), &operator==, \"==\", true))\n> >  \t\t\treturn TestFail;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 8D3E8BD792\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Jul 2020 11:31:03 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2C91A613BD;\n\tFri, 10 Jul 2020 13:31:03 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 670C66118A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jul 2020 13:31:01 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D267F2C0;\n\tFri, 10 Jul 2020 13:31:00 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"NAydATiB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1594380661;\n\tbh=8jy/kuMC+e8+htbnD7p2PfJJWoYzKKAPAiM/UdNM8Ko=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=NAydATiBCd61NmQ/K088lf0vjn/hnBY2v3PZAlYMXJNrJNYuLRg4yByvIrNBPWY7v\n\t4NlPbwhLFKB6eCVmNGXUwrgkGTEi8/3UibCJGtOQnqnYRBM79QXfBbUnnu+5RLsXBd\n\tIfcHPFMc1kumGUrwrwh8FRvVkYT5CZS6yo7kwFm4=","Date":"Fri, 10 Jul 2020 14:30:54 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20200710113054.GI5964@pendragon.ideasonboard.com>","References":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>\n\t<20200710100516.v32hylqd4z6arf2b@uno.localdomain>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200710100516.v32hylqd4z6arf2b@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11331,"web_url":"https://patchwork.libcamera.org/comment/11331/","msgid":"<20200710124321.ypyiylt2z4qrkq4e@uno.localdomain>","date":"2020-07-10T12:43:21","subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Fri, Jul 10, 2020 at 02:30:54PM +0300, Laurent Pinchart wrote:\n> Hi Jacopo,\n>\n> On Fri, Jul 10, 2020 at 12:05:16PM +0200, Jacopo Mondi wrote:\n> > On Fri, Jul 10, 2020 at 11:24:55AM +0300, Laurent Pinchart wrote:\n> > > Pipeline handlers commonly have to calculate the minimum or maximum of\n> > > multiple sizes, or align a size's width and height. Add helper functions\n> > > to the Size class to perform those tasks.\n> > >\n> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > ---\n> > >  include/libcamera/geometry.h | 25 +++++++++++++++++++++++++\n> > >  src/libcamera/geometry.cpp   | 26 ++++++++++++++++++++++++++\n> > >  test/geometry.cpp            | 22 ++++++++++++++++++++++\n> > >  3 files changed, 73 insertions(+)\n> > >\n> > > diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> > > index 7d4b8bcfe3d8..c1411290f163 100644\n> > > --- a/include/libcamera/geometry.h\n> > > +++ b/include/libcamera/geometry.h\n> > > @@ -8,6 +8,7 @@\n> > >  #ifndef __LIBCAMERA_GEOMETRY_H__\n> > >  #define __LIBCAMERA_GEOMETRY_H__\n> > >\n> > > +#include <algorithm>\n> > >  #include <string>\n> > >\n> > >  namespace libcamera {\n> > > @@ -43,6 +44,30 @@ struct Size {\n> > >\n> > >  \tbool isNull() const { return !width && !height; }\n> > >  \tconst std::string toString() const;\n> > > +\n> > > +\tSize alignedTo(unsigned int hAlignment, unsigned int vAlignment) const\n> >\n> > Should this take a Size ?\n>\n> I've thought about it, but it's really two alignments, not a size.\n>\n\nAs soon as I used it, I realized using alignments is more natural.\n\n> > Also, is aligned always assumed to happen to next largest integer ?\n> > Shouldn't this be alignIncrease or similar ?\n>\n> alignedUpTo and alignedDownTo ? roundedDownTo and roundedUpTo ? Do you\n> need both in the IPU3 pipeline handler ?\n\nI don't and I don't think the 'down' versions are required. Just not\nassume alignment happens to the next larger integer. Are floor and\nceil mis-leading as names in your opinion ?\n\nHave I forgot my tag in the previous reply?\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n>\n> > > +\t{\n> > > +\t\treturn {\n> > > +\t\t\t(width + hAlignment - 1) / hAlignment * hAlignment,\n> > > +\t\t\t(height + vAlignment - 1) / vAlignment * vAlignment\n> > > +\t\t};\n> > > +\t}\n> > > +\n> > > +\tSize boundedTo(const Size &bound) const\n> > > +\t{\n> > > +\t\treturn {\n> > > +\t\t\tstd::min(width, bound.width),\n> > > +\t\t\tstd::min(height, bound.height)\n> > > +\t\t};\n> > > +\t}\n> > > +\n> > > +\tSize expandedTo(const Size &expand) const\n> > > +\t{\n> > > +\t\treturn {\n> > > +\t\t\tstd::max(width, expand.width),\n> > > +\t\t\tstd::max(height, expand.height)\n> > > +\t\t};\n> > > +\t}\n> > >  };\n> > >\n> > >  bool operator==(const Size &lhs, const Size &rhs);\n> > > diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n> > > index 24c44fb43acf..d647c5efbdb1 100644\n> > > --- a/src/libcamera/geometry.cpp\n> > > +++ b/src/libcamera/geometry.cpp\n> > > @@ -122,6 +122,32 @@ const std::string Size::toString() const\n> > >  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n> > >  }\n> > >\n> > > +/**\n> > > + * \\fn Size::alignedTo(unsigned int hAlignment, unsigned int vAlignment)\n> > > + * \\brief Align the size horizontally and vertically\n> > > + * \\param[in] hAlignment Horizontal alignment\n> > > + * \\param[in] vAlignment Vertical alignment\n> > > + * \\return A Size whose width and height are equal to the width and height of\n> > > + * this size aligned to the next multiple of \\a hAlignment and \\a vAlignment\n> > > + * respectively\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\fn Size::boundedTo(const Size &bound)\n> > > + * \\brief Bound the size to \\a bound\n> > > + * \\param[in] bound The maximum size\n> > > + * \\return A Size whose width and height are the minimum of the width and\n> > > + * height of this size and the \\a bound size\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\fn Size::expandedTo(const Size &expand)\n> > > + * \\brief Expand the size to \\a expand\n> > > + * \\param[in] expand The minimum size\n> > > + * \\return A Size whose width and height are the maximum of the width and\n> > > + * height of this size and the \\a expand size\n> > > + */\n> > > +\n> > >  /**\n> > >   * \\brief Compare sizes for equality\n> > >   * \\return True if the two sizes are equal, false otherwise\n> > > diff --git a/test/geometry.cpp b/test/geometry.cpp\n> > > index 904ad92c9448..5ef7cb7c9014 100644\n> > > --- a/test/geometry.cpp\n> > > +++ b/test/geometry.cpp\n> > > @@ -46,6 +46,28 @@ protected:\n> > >  \t\t\treturn TestFail;\n> > >  \t\t}\n> > >\n> > > +\t\t/* Test alignedTo(), boundedTo() and expandedTo() */\n> > > +\t\tif (Size(0, 0).alignedTo(16, 8) != Size(0, 0) ||\n> > > +\t\t    Size(1, 1).alignedTo(16, 8) != Size(16, 8) ||\n> > > +\t\t    Size(16, 8).alignedTo(16, 8) != Size(16, 8)) {\n> > > +\t\t\tcout << \"Size::alignedTo() test failed\" << endl;\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\tif (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||\n> > > +\t\t    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||\n> > > +\t\t    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {\n> > > +\t\t\tcout << \"Size::boundedTo() test failed\" << endl;\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> > > +\t\tif (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||\n> > > +\t\t    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||\n> > > +\t\t    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {\n> > > +\t\t\tcout << \"Size::expandedTo() test failed\" << endl;\n> > > +\t\t\treturn TestFail;\n> > > +\t\t}\n> > > +\n> >\n> > Looks good and will use it in the IPU3 series.\n> >\n> > >  \t\t/* Test Size equality and inequality. */\n> > >  \t\tif (!compare(Size(100, 100), Size(100, 100), &operator==, \"==\", true))\n> > >  \t\t\treturn TestFail;\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 6BC1FBD792\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Jul 2020 12:39:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 48FB0613CE;\n\tFri, 10 Jul 2020 14:39:49 +0200 (CEST)","from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C98F8611BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jul 2020 14:39:47 +0200 (CEST)","from uno.localdomain (host-95-245-128-189.retail.telecomitalia.it\n\t[95.245.128.189]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id EB6B81BF20C;\n\tFri, 10 Jul 2020 12:39:46 +0000 (UTC)"],"X-Originating-IP":"95.245.128.189","Date":"Fri, 10 Jul 2020 14:43:21 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200710124321.ypyiylt2z4qrkq4e@uno.localdomain>","References":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>\n\t<20200710100516.v32hylqd4z6arf2b@uno.localdomain>\n\t<20200710113054.GI5964@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200710113054.GI5964@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11332,"web_url":"https://patchwork.libcamera.org/comment/11332/","msgid":"<20200710124313.GU5964@pendragon.ideasonboard.com>","date":"2020-07-10T12:43:13","subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Fri, Jul 10, 2020 at 02:43:21PM +0200, Jacopo Mondi wrote:\n> On Fri, Jul 10, 2020 at 02:30:54PM +0300, Laurent Pinchart wrote:\n> > On Fri, Jul 10, 2020 at 12:05:16PM +0200, Jacopo Mondi wrote:\n> > > On Fri, Jul 10, 2020 at 11:24:55AM +0300, Laurent Pinchart wrote:\n> > > > Pipeline handlers commonly have to calculate the minimum or maximum of\n> > > > multiple sizes, or align a size's width and height. Add helper functions\n> > > > to the Size class to perform those tasks.\n> > > >\n> > > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > > ---\n> > > >  include/libcamera/geometry.h | 25 +++++++++++++++++++++++++\n> > > >  src/libcamera/geometry.cpp   | 26 ++++++++++++++++++++++++++\n> > > >  test/geometry.cpp            | 22 ++++++++++++++++++++++\n> > > >  3 files changed, 73 insertions(+)\n> > > >\n> > > > diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> > > > index 7d4b8bcfe3d8..c1411290f163 100644\n> > > > --- a/include/libcamera/geometry.h\n> > > > +++ b/include/libcamera/geometry.h\n> > > > @@ -8,6 +8,7 @@\n> > > >  #ifndef __LIBCAMERA_GEOMETRY_H__\n> > > >  #define __LIBCAMERA_GEOMETRY_H__\n> > > >\n> > > > +#include <algorithm>\n> > > >  #include <string>\n> > > >\n> > > >  namespace libcamera {\n> > > > @@ -43,6 +44,30 @@ struct Size {\n> > > >\n> > > >  \tbool isNull() const { return !width && !height; }\n> > > >  \tconst std::string toString() const;\n> > > > +\n> > > > +\tSize alignedTo(unsigned int hAlignment, unsigned int vAlignment) const\n> > >\n> > > Should this take a Size ?\n> >\n> > I've thought about it, but it's really two alignments, not a size.\n> \n> As soon as I used it, I realized using alignments is more natural.\n> \n> > > Also, is aligned always assumed to happen to next largest integer ?\n> > > Shouldn't this be alignIncrease or similar ?\n> >\n> > alignedUpTo and alignedDownTo ? roundedDownTo and roundedUpTo ? Do you\n> > need both in the IPU3 pipeline handler ?\n> \n> I don't and I don't think the 'down' versions are required. Just not\n> assume alignment happens to the next larger integer. Are floor and\n> ceil mis-leading as names in your opinion ?\n\nFloor and ceil have established meanings in mathematical operations, so\nI don't think they would be misleading, but floorTo() would sound weird,\nand would also not convey that we're dealing with alignments.\nalignedFloorTo() or alignedToFloor() also sounds weird.\n\n> Have I forgot my tag in the previous reply?\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> \n> > > > +\t{\n> > > > +\t\treturn {\n> > > > +\t\t\t(width + hAlignment - 1) / hAlignment * hAlignment,\n> > > > +\t\t\t(height + vAlignment - 1) / vAlignment * vAlignment\n> > > > +\t\t};\n> > > > +\t}\n> > > > +\n> > > > +\tSize boundedTo(const Size &bound) const\n> > > > +\t{\n> > > > +\t\treturn {\n> > > > +\t\t\tstd::min(width, bound.width),\n> > > > +\t\t\tstd::min(height, bound.height)\n> > > > +\t\t};\n> > > > +\t}\n> > > > +\n> > > > +\tSize expandedTo(const Size &expand) const\n> > > > +\t{\n> > > > +\t\treturn {\n> > > > +\t\t\tstd::max(width, expand.width),\n> > > > +\t\t\tstd::max(height, expand.height)\n> > > > +\t\t};\n> > > > +\t}\n> > > >  };\n> > > >\n> > > >  bool operator==(const Size &lhs, const Size &rhs);\n> > > > diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n> > > > index 24c44fb43acf..d647c5efbdb1 100644\n> > > > --- a/src/libcamera/geometry.cpp\n> > > > +++ b/src/libcamera/geometry.cpp\n> > > > @@ -122,6 +122,32 @@ const std::string Size::toString() const\n> > > >  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n> > > >  }\n> > > >\n> > > > +/**\n> > > > + * \\fn Size::alignedTo(unsigned int hAlignment, unsigned int vAlignment)\n> > > > + * \\brief Align the size horizontally and vertically\n> > > > + * \\param[in] hAlignment Horizontal alignment\n> > > > + * \\param[in] vAlignment Vertical alignment\n> > > > + * \\return A Size whose width and height are equal to the width and height of\n> > > > + * this size aligned to the next multiple of \\a hAlignment and \\a vAlignment\n> > > > + * respectively\n> > > > + */\n> > > > +\n> > > > +/**\n> > > > + * \\fn Size::boundedTo(const Size &bound)\n> > > > + * \\brief Bound the size to \\a bound\n> > > > + * \\param[in] bound The maximum size\n> > > > + * \\return A Size whose width and height are the minimum of the width and\n> > > > + * height of this size and the \\a bound size\n> > > > + */\n> > > > +\n> > > > +/**\n> > > > + * \\fn Size::expandedTo(const Size &expand)\n> > > > + * \\brief Expand the size to \\a expand\n> > > > + * \\param[in] expand The minimum size\n> > > > + * \\return A Size whose width and height are the maximum of the width and\n> > > > + * height of this size and the \\a expand size\n> > > > + */\n> > > > +\n> > > >  /**\n> > > >   * \\brief Compare sizes for equality\n> > > >   * \\return True if the two sizes are equal, false otherwise\n> > > > diff --git a/test/geometry.cpp b/test/geometry.cpp\n> > > > index 904ad92c9448..5ef7cb7c9014 100644\n> > > > --- a/test/geometry.cpp\n> > > > +++ b/test/geometry.cpp\n> > > > @@ -46,6 +46,28 @@ protected:\n> > > >  \t\t\treturn TestFail;\n> > > >  \t\t}\n> > > >\n> > > > +\t\t/* Test alignedTo(), boundedTo() and expandedTo() */\n> > > > +\t\tif (Size(0, 0).alignedTo(16, 8) != Size(0, 0) ||\n> > > > +\t\t    Size(1, 1).alignedTo(16, 8) != Size(16, 8) ||\n> > > > +\t\t    Size(16, 8).alignedTo(16, 8) != Size(16, 8)) {\n> > > > +\t\t\tcout << \"Size::alignedTo() test failed\" << endl;\n> > > > +\t\t\treturn TestFail;\n> > > > +\t\t}\n> > > > +\n> > > > +\t\tif (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||\n> > > > +\t\t    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||\n> > > > +\t\t    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {\n> > > > +\t\t\tcout << \"Size::boundedTo() test failed\" << endl;\n> > > > +\t\t\treturn TestFail;\n> > > > +\t\t}\n> > > > +\n> > > > +\t\tif (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||\n> > > > +\t\t    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||\n> > > > +\t\t    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {\n> > > > +\t\t\tcout << \"Size::expandedTo() test failed\" << endl;\n> > > > +\t\t\treturn TestFail;\n> > > > +\t\t}\n> > > > +\n> > >\n> > > Looks good and will use it in the IPU3 series.\n> > >\n> > > >  \t\t/* Test Size equality and inequality. */\n> > > >  \t\tif (!compare(Size(100, 100), Size(100, 100), &operator==, \"==\", true))\n> > > >  \t\t\treturn TestFail;\n> >\n> > --\n> > Regards,\n> >\n> > Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 4BB69BD790\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Jul 2020 12:43:22 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BC651613C7;\n\tFri, 10 Jul 2020 14:43:21 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B246611BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jul 2020 14:43:20 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 97BFB2C0;\n\tFri, 10 Jul 2020 14:43:19 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"k79v5uDj\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1594384999;\n\tbh=DMXH/gCcg3rNfGXgJQpLrJ/fm+K+3n4peab7xtjwygQ=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=k79v5uDjkZy7GNROBQweYyNzGLIvAczrjkb+CWKQhQZLIOwiSFSdXIon3ynoOt55m\n\tjnPjBaSo1XDtYqA5HOM1Mv81LAns35yPZFrme5e1ne+MF+XOSHhSmruTn8lDxgQoLt\n\tpt631rLOZmsKE+V3tQV0I89w35au2z00/4q+aax0=","Date":"Fri, 10 Jul 2020 15:43:13 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<20200710124313.GU5964@pendragon.ideasonboard.com>","References":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>\n\t<20200710100516.v32hylqd4z6arf2b@uno.localdomain>\n\t<20200710113054.GI5964@pendragon.ideasonboard.com>\n\t<20200710124321.ypyiylt2z4qrkq4e@uno.localdomain>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200710124321.ypyiylt2z4qrkq4e@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":11338,"web_url":"https://patchwork.libcamera.org/comment/11338/","msgid":"<1e57313b-2898-7a99-4c07-97d99a3c3ad2@ideasonboard.com>","date":"2020-07-10T14:54:11","subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Hi Laurent, Jacopo,\n\nOn 10/07/2020 13:43, Laurent Pinchart wrote:\n> Hi Jacopo,\n> \n> On Fri, Jul 10, 2020 at 02:43:21PM +0200, Jacopo Mondi wrote:\n>> On Fri, Jul 10, 2020 at 02:30:54PM +0300, Laurent Pinchart wrote:\n>>> On Fri, Jul 10, 2020 at 12:05:16PM +0200, Jacopo Mondi wrote:\n>>>> On Fri, Jul 10, 2020 at 11:24:55AM +0300, Laurent Pinchart wrote:\n>>>>> Pipeline handlers commonly have to calculate the minimum or maximum of\n>>>>> multiple sizes, or align a size's width and height. Add helper functions\n>>>>> to the Size class to perform those tasks.\n>>>>>\n\nOhhh I love a good helper ...\n\nPotentially foreseeing some growth in the Rectangle helpers too (see\nrecent threads).\n\n>>>>> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>>>>> ---\n>>>>>  include/libcamera/geometry.h | 25 +++++++++++++++++++++++++\n>>>>>  src/libcamera/geometry.cpp   | 26 ++++++++++++++++++++++++++\n>>>>>  test/geometry.cpp            | 22 ++++++++++++++++++++++\n>>>>>  3 files changed, 73 insertions(+)\n>>>>>\n>>>>> diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n>>>>> index 7d4b8bcfe3d8..c1411290f163 100644\n>>>>> --- a/include/libcamera/geometry.h\n>>>>> +++ b/include/libcamera/geometry.h\n>>>>> @@ -8,6 +8,7 @@\n>>>>>  #ifndef __LIBCAMERA_GEOMETRY_H__\n>>>>>  #define __LIBCAMERA_GEOMETRY_H__\n>>>>>\n>>>>> +#include <algorithm>\n>>>>>  #include <string>\n>>>>>\n>>>>>  namespace libcamera {\n>>>>> @@ -43,6 +44,30 @@ struct Size {\n>>>>>\n>>>>>  \tbool isNull() const { return !width && !height; }\n>>>>>  \tconst std::string toString() const;\n>>>>> +\n>>>>> +\tSize alignedTo(unsigned int hAlignment, unsigned int vAlignment) const\n>>>>\n>>>> Should this take a Size ?\n>>>\n>>> I've thought about it, but it's really two alignments, not a size.\n>>\n>> As soon as I used it, I realized using alignments is more natural.\n>>\n>>>> Also, is aligned always assumed to happen to next largest integer ?\n>>>> Shouldn't this be alignIncrease or similar ?\n>>>\n>>> alignedUpTo and alignedDownTo ? roundedDownTo and roundedUpTo ? Do you\n>>> need both in the IPU3 pipeline handler ?\n>>\n>> I don't and I don't think the 'down' versions are required. Just not\n>> assume alignment happens to the next larger integer. Are floor and\n>> ceil mis-leading as names in your opinion ?\n\nActually I suspect I might need an alignedDown for JPEG streams, as I\nneed to have sizes that are to JPEG requirements, aand and I can't\nnecessarily 'increase' the image size ... so it would have to crop down...\n\nEven without both up and down variants, I'd rather see an explicit\ndirection in the function name, because otherwise it may be ambiguous\nwhich way the alignment occurs.\n\n(ok, so someone can read the function-doc ... but ...)\n\nHowever, these helpers are certainly going to be helpful...\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\n> Floor and ceil have established meanings in mathematical operations, so\n> I don't think they would be misleading, but floorTo() would sound weird,\n> and would also not convey that we're dealing with alignments.\n> alignedFloorTo() or alignedToFloor() also sounds weird.\n> \n>> Have I forgot my tag in the previous reply?\n>> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n>>\n>>>>> +\t{\n>>>>> +\t\treturn {\n>>>>> +\t\t\t(width + hAlignment - 1) / hAlignment * hAlignment,\n>>>>> +\t\t\t(height + vAlignment - 1) / vAlignment * vAlignment\n>>>>> +\t\t};\n>>>>> +\t}\n>>>>> +\n>>>>> +\tSize boundedTo(const Size &bound) const\n>>>>> +\t{\n>>>>> +\t\treturn {\n>>>>> +\t\t\tstd::min(width, bound.width),\n>>>>> +\t\t\tstd::min(height, bound.height)\n>>>>> +\t\t};\n>>>>> +\t}\n>>>>> +\n>>>>> +\tSize expandedTo(const Size &expand) const\n>>>>> +\t{\n>>>>> +\t\treturn {\n>>>>> +\t\t\tstd::max(width, expand.width),\n>>>>> +\t\t\tstd::max(height, expand.height)\n>>>>> +\t\t};\n>>>>> +\t}\n>>>>>  };\n>>>>>\n>>>>>  bool operator==(const Size &lhs, const Size &rhs);\n>>>>> diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp\n>>>>> index 24c44fb43acf..d647c5efbdb1 100644\n>>>>> --- a/src/libcamera/geometry.cpp\n>>>>> +++ b/src/libcamera/geometry.cpp\n>>>>> @@ -122,6 +122,32 @@ const std::string Size::toString() const\n>>>>>  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n>>>>>  }\n>>>>>\n>>>>> +/**\n>>>>> + * \\fn Size::alignedTo(unsigned int hAlignment, unsigned int vAlignment)\n>>>>> + * \\brief Align the size horizontally and vertically\n>>>>> + * \\param[in] hAlignment Horizontal alignment\n>>>>> + * \\param[in] vAlignment Vertical alignment\n>>>>> + * \\return A Size whose width and height are equal to the width and height of\n>>>>> + * this size aligned to the next multiple of \\a hAlignment and \\a vAlignment\n>>>>> + * respectively\n>>>>> + */\n>>>>> +\n>>>>> +/**\n>>>>> + * \\fn Size::boundedTo(const Size &bound)\n>>>>> + * \\brief Bound the size to \\a bound\n>>>>> + * \\param[in] bound The maximum size\n>>>>> + * \\return A Size whose width and height are the minimum of the width and\n>>>>> + * height of this size and the \\a bound size\n>>>>> + */\n>>>>> +\n>>>>> +/**\n>>>>> + * \\fn Size::expandedTo(const Size &expand)\n>>>>> + * \\brief Expand the size to \\a expand\n>>>>> + * \\param[in] expand The minimum size\n>>>>> + * \\return A Size whose width and height are the maximum of the width and\n>>>>> + * height of this size and the \\a expand size\n>>>>> + */\n>>>>> +\n>>>>>  /**\n>>>>>   * \\brief Compare sizes for equality\n>>>>>   * \\return True if the two sizes are equal, false otherwise\n>>>>> diff --git a/test/geometry.cpp b/test/geometry.cpp\n>>>>> index 904ad92c9448..5ef7cb7c9014 100644\n>>>>> --- a/test/geometry.cpp\n>>>>> +++ b/test/geometry.cpp\n>>>>> @@ -46,6 +46,28 @@ protected:\n>>>>>  \t\t\treturn TestFail;\n>>>>>  \t\t}\n>>>>>\n>>>>> +\t\t/* Test alignedTo(), boundedTo() and expandedTo() */\n>>>>> +\t\tif (Size(0, 0).alignedTo(16, 8) != Size(0, 0) ||\n>>>>> +\t\t    Size(1, 1).alignedTo(16, 8) != Size(16, 8) ||\n>>>>> +\t\t    Size(16, 8).alignedTo(16, 8) != Size(16, 8)) {\n>>>>> +\t\t\tcout << \"Size::alignedTo() test failed\" << endl;\n>>>>> +\t\t\treturn TestFail;\n>>>>> +\t\t}\n>>>>> +\n>>>>> +\t\tif (Size(0, 0).boundedTo({ 100, 100 }) != Size(0, 0) ||\n>>>>> +\t\t    Size(200, 50).boundedTo({ 100, 100 }) != Size(100, 50) ||\n>>>>> +\t\t    Size(50, 200).boundedTo({ 100, 100 }) != Size(50, 100)) {\n>>>>> +\t\t\tcout << \"Size::boundedTo() test failed\" << endl;\n>>>>> +\t\t\treturn TestFail;\n>>>>> +\t\t}\n>>>>> +\n>>>>> +\t\tif (Size(0, 0).expandedTo({ 100, 100 }) != Size(100, 100) ||\n>>>>> +\t\t    Size(200, 50).expandedTo({ 100, 100 }) != Size(200, 100) ||\n>>>>> +\t\t    Size(50, 200).expandedTo({ 100, 100 }) != Size(100, 200)) {\n>>>>> +\t\t\tcout << \"Size::expandedTo() test failed\" << endl;\n>>>>> +\t\t\treturn TestFail;\n>>>>> +\t\t}\n>>>>> +\n>>>>\n>>>> Looks good and will use it in the IPU3 series.\n>>>>\n>>>>>  \t\t/* Test Size equality and inequality. */\n>>>>>  \t\tif (!compare(Size(100, 100), Size(100, 100), &operator==, \"==\", true))\n>>>>>  \t\t\treturn TestFail;\n>>>\n>>> --\n>>> Regards,\n>>>\n>>> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id A0E92BD790\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 10 Jul 2020 14:54:17 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2824160491;\n\tFri, 10 Jul 2020 16:54:17 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 646196048F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jul 2020 16:54:15 +0200 (CEST)","from [192.168.0.20]\n\t(cpc89242-aztw30-2-0-cust488.18-1.cable.virginm.net [86.31.129.233])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BB10C2C0;\n\tFri, 10 Jul 2020 16:54:14 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ESBQXVZA\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1594392854;\n\tbh=S9xvrJDbx+s5tnk4VmKs3SCEA588U5rQWk/zn6dka7w=;\n\th=Reply-To:Subject:To:Cc:References:From:Date:In-Reply-To:From;\n\tb=ESBQXVZA2Gxhz+FCget+dxqrZonOjPJRFACnBIvC21kKzB0jfSoRIDCK02tUfmL59\n\tQ56dnU/kSg7vr0jvAzn6zOx3VDSHNuOXrebUARBc200RjxORJRYLEM2dp5li+h1HEC\n\tikbkMgS0r/kpMQSYtTwB9pFixbx52B95SNYDj+MY=","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tJacopo Mondi <jacopo@jmondi.org>","References":"<20200710082455.10953-1-laurent.pinchart@ideasonboard.com>\n\t<20200710100516.v32hylqd4z6arf2b@uno.localdomain>\n\t<20200710113054.GI5964@pendragon.ideasonboard.com>\n\t<20200710124321.ypyiylt2z4qrkq4e@uno.localdomain>\n\t<20200710124313.GU5964@pendragon.ideasonboard.com>","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Autocrypt":"addr=kieran.bingham@ideasonboard.com; keydata=\n\t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\n\tWZw01QYHU/GUV/zHJSFk","Organization":"Ideas on Board","Message-ID":"<1e57313b-2898-7a99-4c07-97d99a3c3ad2@ideasonboard.com>","Date":"Fri, 10 Jul 2020 15:54:11 +0100","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101\n\tThunderbird/68.8.0","MIME-Version":"1.0","In-Reply-To":"<20200710124313.GU5964@pendragon.ideasonboard.com>","Content-Language":"en-GB","Subject":"Re: [libcamera-devel] [PATCH] libcamera: geometry: Add helper\n\tfunctions to the Size class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Reply-To":"kieran.bingham@ideasonboard.com","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]