[{"id":11350,"web_url":"https://patchwork.libcamera.org/comment/11350/","msgid":"<20200713064728.GD1498036@oden.dyn.berto.se>","date":"2020-07-13T06:47:28","subject":"Re: [libcamera-devel] [PATCH v2] libcamera: geometry: Add helper\n\tfunctions to the Size class","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your work.\n\nOn 2020-07-12 18:05:37 +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> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n> Changes since v1:\n> \n> - Rename aligneTo() to alignedUpTo()\n> - Add alignDownTo()\n> ---\n>  include/libcamera/geometry.h | 33 +++++++++++++++++++++++++++++++++\n>  src/libcamera/geometry.cpp   | 36 ++++++++++++++++++++++++++++++++++++\n>  test/geometry.cpp            | 29 +++++++++++++++++++++++++++++\n>  3 files changed, 98 insertions(+)\n> \n> diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h\n> index 7d4b8bcfe3d8..d217cfd50c86 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,38 @@ struct Size {\n>  \n>  \tbool isNull() const { return !width && !height; }\n>  \tconst std::string toString() const;\n> +\n> +\tSize alignedDownTo(unsigned int hAlignment, unsigned int vAlignment) const\n> +\t{\n> +\t\treturn {\n> +\t\t\twidth / hAlignment * hAlignment,\n> +\t\t\theight / vAlignment * vAlignment\n> +\t\t};\n> +\t}\n> +\n> +\tSize alignedUpTo(unsigned int hAlignment, unsigned int vAlignment) const\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..4594f9ff435f 100644\n> --- a/src/libcamera/geometry.cpp\n> +++ b/src/libcamera/geometry.cpp\n> @@ -122,6 +122,42 @@ const std::string Size::toString() const\n>  \treturn std::to_string(width) + \"x\" + std::to_string(height);\n>  }\n>  \n> +/**\n> + * \\fn Size::alignedDownTo(unsigned int hAlignment, unsigned int vAlignment)\n> + * \\brief Align the size down 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 rounded down to the nearest multiple of \\a hAlignment and\n> + * \\a vAlignment respectively\n> + */\n> +\n> +/**\n> + * \\fn Size::alignedUpTo(unsigned int hAlignment, unsigned int vAlignment)\n> + * \\brief Align the size up 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 rounded up to the nearest multiple of \\a hAlignment and\n> + * \\a vAlignment 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..fd0132c03b02 100644\n> --- a/test/geometry.cpp\n> +++ b/test/geometry.cpp\n> @@ -46,6 +46,35 @@ protected:\n>  \t\t\treturn TestFail;\n>  \t\t}\n>  \n> +\t\t/* Test alignedDownTo(), alignedUpTo(), boundedTo() and expandedTo() */\n> +\t\tif (Size(0, 0).alignedDownTo(16, 8) != Size(0, 0) ||\n> +\t\t    Size(1, 1).alignedDownTo(16, 8) != Size(0, 0) ||\n> +\t\t    Size(16, 8).alignedDownTo(16, 8) != Size(16, 8)) {\n> +\t\t\tcout << \"Size::alignedDownTo() test failed\" << endl;\n> +\t\t\treturn TestFail;\n> +\t\t}\n> +\n> +\t\tif (Size(0, 0).alignedUpTo(16, 8) != Size(0, 0) ||\n> +\t\t    Size(1, 1).alignedUpTo(16, 8) != Size(16, 8) ||\n> +\t\t    Size(16, 8).alignedUpTo(16, 8) != Size(16, 8)) {\n> +\t\t\tcout << \"Size::alignedUpTo() 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>  \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 37307BD792\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Jul 2020 06:47:33 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 739E1605AC;\n\tMon, 13 Jul 2020 08:47:32 +0200 (CEST)","from mail-lj1-x241.google.com (mail-lj1-x241.google.com\n\t[IPv6:2a00:1450:4864:20::241])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D14156055B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Jul 2020 08:47:30 +0200 (CEST)","by mail-lj1-x241.google.com with SMTP id x9so5605962ljc.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 12 Jul 2020 23:47:30 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tv24sm4440925lfo.4.2020.07.12.23.47.28\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 12 Jul 2020 23:47:29 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"YDLY+UmC\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=FJy6op7LejLJeX0U6/giJXSE6QJ24PXuHqvXNWhG8o4=;\n\tb=YDLY+UmCVAXonprX5VMIdLovh5b7EAYmru9Nr3NIwDP9IC2KMqlfAVijz2AAwd7SPp\n\t693w0AYj/OysV5fG0ZlNLtGsQHkDhYMtCGa46XijEZ21ji9+SSBClsjV7x4uzy5Yw2bb\n\tbOGRUK2rdxOkpi0o7XA+0PPnLTVhxGCv2gPn4g0VCxn0/MT8JfR8n+hkgiNdIJRc8ELz\n\tgYBNY9Oo7fSpGuulyiA/e1m+St5NckUqtZcBxqN1VOEJ8Bs+LfpKJfLS47IumLUUFEdl\n\tu9/6/rK4TQ7ba4JZTTzzEso/YDXpPVOQxTNhT8a7aQ35I8epvvBxhn0rtTPXeVlbyDjS\n\tyI9Q==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=FJy6op7LejLJeX0U6/giJXSE6QJ24PXuHqvXNWhG8o4=;\n\tb=H6g8GGf7m5X/FRtXTewSNkly+OBfLm8q/nTUn5o4x389V9CgJTh1BbRhakcbajKafY\n\tQKD2fnZ0ZCD1ghZTrmTQom7RzLlqdbYgya0vLURtD1XuZvtcJNWzMfKGlcgSmuc1kz1D\n\t10BLM8IxmcyFKhSYWA4mdVPCUkEVbNoTxKtjd7LC7gGPXdYRi8vkkOvZv+ortRe8gX//\n\tsUlRUXvjBnVz/GykzA13G0346PKwhhrinn0oaSEIssEQOAJbG+mUlV1nSNs4Azn8aj1j\n\tJkCIa0t26q5Fg7xBELIy+yMsuK999pmeHHaDP5K7NRvgK+yWJuguU8t/0LNiOClwgV2B\n\tGX9w==","X-Gm-Message-State":"AOAM532fP6/MyuYBkf2GC0uWHmxM4KxyYw0S+v1heRF3+Z0d97Iq7LaA\n\tplqh3ThhTKIEQWCamoEs2+y3LQ==","X-Google-Smtp-Source":"ABdhPJzKWwacRWwVATGACyfHaMW8wxX4438gkyVVojRwfybxZWZN1mjVKOakDyF9h3v+IpldmgUhqg==","X-Received":"by 2002:a05:651c:512:: with SMTP id\n\to18mr51503368ljp.226.1594622849900; \n\tSun, 12 Jul 2020 23:47:29 -0700 (PDT)","Date":"Mon, 13 Jul 2020 08:47:28 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20200713064728.GD1498036@oden.dyn.berto.se>","References":"<20200712150537.22946-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20200712150537.22946-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2] 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=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]