[{"id":22867,"web_url":"https://patchwork.libcamera.org/comment/22867/","msgid":"<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>","date":"2022-05-05T17:59:06","subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nThank you for the patch.\n\nOn Thu, May 05, 2022 at 01:41:00PM +0300, Tomi Valkeinen wrote:\n> Add binding for Transform.\n> \n> C++'s Transform is an enum class, but we expose it as a Python class so\n> that it can be easily manipulated.\n> \n> Original version from David Plowman <david.plowman@raspberrypi.com>.\n> \n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> ---\n>  src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-\n>  1 file changed, 62 insertions(+), 1 deletion(-)\n> \n> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n> index db9d90ab..3d2393ab 100644\n> --- a/src/py/libcamera/pymain.cpp\n> +++ b/src/py/libcamera/pymain.cpp\n> @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)\n>  \tauto pyControlId = py::class_<ControlId>(m, \"ControlId\");\n>  \tauto pyRequest = py::class_<Request>(m, \"Request\");\n>  \tauto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n> +\tauto pyTransform = py::class_<Transform>(m, \"Transform\");\n>  \n>  \t/* Global functions */\n>  \tm.def(\"logSetLevel\", &logSetLevel);\n> @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)\n>  \t\t.def(\"validate\", &CameraConfiguration::validate)\n>  \t\t.def(\"at\", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)\n>  \t\t.def_property_readonly(\"size\", &CameraConfiguration::size)\n> -\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty);\n> +\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty)\n> +\t\t.def_readwrite(\"transform\", &CameraConfiguration::transform);\n>  \n>  \tpyStreamConfiguration\n>  \t\t.def(\"toString\", &StreamConfiguration::toString)\n> @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)\n>  \t\t\ttransform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });\n>  \t\t\treturn v;\n>  \t\t});\n> +\n> +\tpyTransform\n> +\t\t.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\n\nI'm not fond of the constructor, three bool arguments in a row are quite\nerror-prone. I'd rather expose the enum.\n\n> +\t\t\tbool ok;\n> +\n> +\t\t\tTransform t = transformFromRotation(rotation, &ok);\n> +\t\t\tif (!ok)\n> +\t\t\t\tthrow std::runtime_error(\"Unable to create the transform\");\n\n\"Invalid rotation\" would be a better message I think.\n\n> +\n> +\t\t\tif (hflip)\n> +\t\t\t\tt ^= Transform::HFlip;\n> +\t\t\tif (vflip)\n> +\t\t\t\tt ^= Transform::VFlip;\n> +\t\t\tif (transpose)\n> +\t\t\t\tt ^= Transform::Transpose;\n> +\t\t\treturn t;\n> +\t\t}), py::arg(\"rotation\") = 0, py::arg(\"hflip\") = false,\n> +\t\t    py::arg(\"vflip\") = false, py::arg(\"transpose\") = false)\n> +\t\t.def(py::init([](Transform &other) { return other; }))\n> +\t\t.def(\"__repr__\", [](Transform &self) {\n> +\t\t\treturn \"<libcamera.Transform '\" + std::string(transformToString(self)) + \"'>\";\n> +\t\t})\n> +\t\t.def_property(\"hflip\",\n> +\t\t\t      [](Transform &self) {\n> +\t\t\t\t      return !!(self & Transform::HFlip);\n> +\t\t\t      },\n> +\t\t\t      [](Transform &self, bool hflip) {\n> +\t\t\t\t      if (hflip)\n> +\t\t\t\t\t      self |= Transform::HFlip;\n> +\t\t\t\t      else\n> +\t\t\t\t\t      self &= ~Transform::HFlip;\n> +\t\t\t      })\n> +\t\t.def_property(\"vflip\",\n> +\t\t\t      [](Transform &self) {\n> +\t\t\t\t      return !!(self & Transform::VFlip);\n> +\t\t\t      },\n> +\t\t\t      [](Transform &self, bool vflip) {\n> +\t\t\t\t      if (vflip)\n> +\t\t\t\t\t      self |= Transform::VFlip;\n> +\t\t\t\t      else\n> +\t\t\t\t\t      self &= ~Transform::VFlip;\n> +\t\t\t      })\n> +\t\t.def_property(\"transpose\",\n> +\t\t\t      [](Transform &self) {\n> +\t\t\t\t      return !!(self & Transform::Transpose);\n> +\t\t\t      },\n> +\t\t\t      [](Transform &self, bool transpose) {\n> +\t\t\t\t      if (transpose)\n> +\t\t\t\t\t      self |= Transform::Transpose;\n> +\t\t\t\t      else\n> +\t\t\t\t\t      self &= ~Transform::Transpose;\n> +\t\t\t      })\n> +\t\t.def(\"inverse\", [](Transform &self) { return -self; })\n> +\t\t.def(\"invert\", [](Transform &self) {\n> +\t\t\tself = -self;\n> +\t\t})\n> +\t\t.def(\"compose\", [](Transform &self, Transform &other) {\n> +\t\t\tself = self * other;\n> +\t\t});\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 9A334C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  5 May 2022 17:59:13 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E1F0765646;\n\tThu,  5 May 2022 19:59:12 +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 239D7603AB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  5 May 2022 19:59:11 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 55545492;\n\tThu,  5 May 2022 19:59:10 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651773552;\n\tbh=5jJfxL1OOKWQMGQknToooIwZ5HVN/3sXZYJ3luWWzCg=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=UWwfsgy06VZx1ROBfhSFLbBEjERVpDL/5mwoePdOQ0bjqPIdapzyF4NQdpwQGFTYi\n\tC/AGMUMvZytjSDtOiMVXRHueG3n9+T0lEsYHBFA/sMhz+S0lX5i8P+mSTrbWiZFGqv\n\tyDADFrJOY/79srbHpvMnUEUNoSNnxhSOibOKtB2Lg5dbZEx2uUTiiktPLIHK8wW8pX\n\tSGXNsMDHkvWFw8TShJcTrmrEsUqJ1zkGeluSTy/p77SlP01teIme6pYaqLDbqbHEN/\n\tNoigmcR+tvABEQeA5/AvThW3e6V2qnfMMjl1B0PRHgAZ9agiQBMBtvLAzWVxCsSXxA\n\tCmYguxvF1BJhA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1651773550;\n\tbh=5jJfxL1OOKWQMGQknToooIwZ5HVN/3sXZYJ3luWWzCg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=JWZ0lTpsvNux1crd0P1/zGkDxF3i3S0CiSJWDXD7V2FmR8ab9cUydMZERt5fs4YbA\n\tOcLTzV7KHwS40SDHf8gwfD2lGQV5OwbGzqjG2HKPXb27VPfbKGgBlo6pXKr6MDlm1S\n\tRXAUlEIyEJWzwWtrogf918LuUo4SZnazVbKrWIb4="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"JWZ0lTps\"; dkim-atps=neutral","Date":"Thu, 5 May 2022 20:59:06 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>","References":"<20220505104104.70841-1-tomi.valkeinen@ideasonboard.com>\n\t<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22876,"web_url":"https://patchwork.libcamera.org/comment/22876/","msgid":"<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>","date":"2022-05-06T11:25:50","subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 05/05/2022 20:59, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> Thank you for the patch.\n> \n> On Thu, May 05, 2022 at 01:41:00PM +0300, Tomi Valkeinen wrote:\n>> Add binding for Transform.\n>>\n>> C++'s Transform is an enum class, but we expose it as a Python class so\n>> that it can be easily manipulated.\n>>\n>> Original version from David Plowman <david.plowman@raspberrypi.com>.\n>>\n>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n>> ---\n>>   src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-\n>>   1 file changed, 62 insertions(+), 1 deletion(-)\n>>\n>> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n>> index db9d90ab..3d2393ab 100644\n>> --- a/src/py/libcamera/pymain.cpp\n>> +++ b/src/py/libcamera/pymain.cpp\n>> @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)\n>>   \tauto pyControlId = py::class_<ControlId>(m, \"ControlId\");\n>>   \tauto pyRequest = py::class_<Request>(m, \"Request\");\n>>   \tauto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n>> +\tauto pyTransform = py::class_<Transform>(m, \"Transform\");\n>>   \n>>   \t/* Global functions */\n>>   \tm.def(\"logSetLevel\", &logSetLevel);\n>> @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)\n>>   \t\t.def(\"validate\", &CameraConfiguration::validate)\n>>   \t\t.def(\"at\", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)\n>>   \t\t.def_property_readonly(\"size\", &CameraConfiguration::size)\n>> -\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty);\n>> +\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty)\n>> +\t\t.def_readwrite(\"transform\", &CameraConfiguration::transform);\n>>   \n>>   \tpyStreamConfiguration\n>>   \t\t.def(\"toString\", &StreamConfiguration::toString)\n>> @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)\n>>   \t\t\ttransform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });\n>>   \t\t\treturn v;\n>>   \t\t});\n>> +\n>> +\tpyTransform\n>> +\t\t.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\n> \n> I'm not fond of the constructor, three bool arguments in a row are quite\n> error-prone. I'd rather expose the enum.\n\nIt's not that bad with python, e.g.:\n\nTransform(transpose=True, vflip=True)\n\nI think that's more pythonic than or'ing enums.\n\n>> +\t\t\tbool ok;\n>> +\n>> +\t\t\tTransform t = transformFromRotation(rotation, &ok);\n>> +\t\t\tif (!ok)\n>> +\t\t\t\tthrow std::runtime_error(\"Unable to create the transform\");\n> \n> \"Invalid rotation\" would be a better message I think.\n\nAnd std::invalid_argument.\n\n  Tomi","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 CA0A7C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  6 May 2022 11:25:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2100F61655;\n\tFri,  6 May 2022 13:25:55 +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 8DF71604A3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  6 May 2022 13:25:53 +0200 (CEST)","from [192.168.1.111] (91-156-85-209.elisa-laajakaista.fi\n\t[91.156.85.209])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id BD472487;\n\tFri,  6 May 2022 13:25:52 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651836355;\n\tbh=axKJJLel9/5CD04y1JG4LjLxEjjSmEWXn2KcesHtgUM=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=FCn5JsRD4zf2OHy9ekok9VGS07g7Zn1ojp4VeNpLr8nCQ5sVR7eSET+FGlLTTdQOK\n\tnqVUqls2JecQ9UpS5O+PJxKn5Bb4N9bjs1Dhayhbw37xX9PpWI/AgIKP4ocMipbqdB\n\tkn4BbE6MeqJtT0yJkM+lCgUTjKDQBBrIcgnows8YXOxSpLvDc1dHNgKHcP2JytBKVU\n\tpM3Etpu+uWQ6fgBMQElaaazJgfPlM2XsSZh0cBb4nf9UPt9p/kdWTz3ZDoqPugoX5M\n\tMtcdxmnrEluFYkPpuJJeGE+oq9EzGjGfFm8qb8Djdwek6nqntBn75UoY4oF/RIBGhR\n\tJogUEFyI3IpBw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1651836353;\n\tbh=axKJJLel9/5CD04y1JG4LjLxEjjSmEWXn2KcesHtgUM=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=vm6B+Kh4FQ6nyRvE5yeCNAEJa5fLL8wOvGouqWS78JWZ0ruM1ZZxhJE48+i0OYNJP\n\tvX2Vvyhru/tqTBgZRQh5PsYcSqO/84EFSMWVxUJ54hrjxGGk+qWuOAH5BeRHzyWvzv\n\tGuD7i7pgPUBk7ILG/cRwdxQAXgBB0NWpYSdXcjJo="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"vm6B+Kh4\"; dkim-atps=neutral","Message-ID":"<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>","Date":"Fri, 6 May 2022 14:25:50 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.8.0","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220505104104.70841-1-tomi.valkeinen@ideasonboard.com>\n\t<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>\n\t<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>","In-Reply-To":"<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","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>","From":"Tomi Valkeinen via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22888,"web_url":"https://patchwork.libcamera.org/comment/22888/","msgid":"<YnU9qxdKISEU37Jb@pendragon.ideasonboard.com>","date":"2022-05-06T15:24:27","subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nOn Fri, May 06, 2022 at 02:25:50PM +0300, Tomi Valkeinen wrote:\n> On 05/05/2022 20:59, Laurent Pinchart wrote:\n> > On Thu, May 05, 2022 at 01:41:00PM +0300, Tomi Valkeinen wrote:\n> >> Add binding for Transform.\n> >>\n> >> C++'s Transform is an enum class, but we expose it as a Python class so\n> >> that it can be easily manipulated.\n> >>\n> >> Original version from David Plowman <david.plowman@raspberrypi.com>.\n> >>\n> >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> >> ---\n> >>   src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-\n> >>   1 file changed, 62 insertions(+), 1 deletion(-)\n> >>\n> >> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n> >> index db9d90ab..3d2393ab 100644\n> >> --- a/src/py/libcamera/pymain.cpp\n> >> +++ b/src/py/libcamera/pymain.cpp\n> >> @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)\n> >>   \tauto pyControlId = py::class_<ControlId>(m, \"ControlId\");\n> >>   \tauto pyRequest = py::class_<Request>(m, \"Request\");\n> >>   \tauto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n> >> +\tauto pyTransform = py::class_<Transform>(m, \"Transform\");\n> >>   \n> >>   \t/* Global functions */\n> >>   \tm.def(\"logSetLevel\", &logSetLevel);\n> >> @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)\n> >>   \t\t.def(\"validate\", &CameraConfiguration::validate)\n> >>   \t\t.def(\"at\", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)\n> >>   \t\t.def_property_readonly(\"size\", &CameraConfiguration::size)\n> >> -\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty);\n> >> +\t\t.def_property_readonly(\"empty\", &CameraConfiguration::empty)\n> >> +\t\t.def_readwrite(\"transform\", &CameraConfiguration::transform);\n> >>   \n> >>   \tpyStreamConfiguration\n> >>   \t\t.def(\"toString\", &StreamConfiguration::toString)\n> >> @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)\n> >>   \t\t\ttransform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });\n> >>   \t\t\treturn v;\n> >>   \t\t});\n> >> +\n> >> +\tpyTransform\n> >> +\t\t.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\n> > \n> > I'm not fond of the constructor, three bool arguments in a row are quite\n> > error-prone. I'd rather expose the enum.\n> \n> It's not that bad with python, e.g.:\n> \n> Transform(transpose=True, vflip=True)\n> \n> I think that's more pythonic than or'ing enums.\n\nOne could also write\n\n    Transform(0, true, false, true)\n\nwhich isn't nice. We can address that out later if needed, either\nmerging this patch already or postponing it. David, do you have any\nopinion ?\n\n> >> +\t\t\tbool ok;\n> >> +\n> >> +\t\t\tTransform t = transformFromRotation(rotation, &ok);\n> >> +\t\t\tif (!ok)\n> >> +\t\t\t\tthrow std::runtime_error(\"Unable to create the transform\");\n> > \n> > \"Invalid rotation\" would be a better message I think.\n> \n> And std::invalid_argument.\n\nGood point.","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 222BEC0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  6 May 2022 15:24:35 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8AA5161655;\n\tFri,  6 May 2022 17:24:34 +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 C4833604A3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  6 May 2022 17:24:32 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E7B2E492;\n\tFri,  6 May 2022 17:24:31 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651850674;\n\tbh=fsK5H4kRS7quvV5O5LTcLftl7GKZQvvlOR+AXDpQlXY=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=rqLSk7hHlGR5vlarcExIyIe9IloLY9BGlHvS+1qKeMjM7gQGTqI5FrgOSrBZZlgLe\n\tbbusF2SPieYNjyL6egawDFx3kimEvZqLfOwORntrAvn77hnmXYHIfmiIR8Ipzv/4cI\n\tsJHTEg1Ea/bNGQoOCGHiDo83DaUbZ4SWFJaalGiObkCDvQDFKbgFijPU9NVuhDrY79\n\tv6L1G+6iyPta9L5ySy8o4GC/TsHZ9nTkmg9H4gN8UcOwxR6FFsIX3mkwIaah+wFhXu\n\tOOd76pZ0bw+/IWebI/0r1OsDWluU9PbLhBAXvIAoxYZvFSE/46oCcP9yKrE7rJkMOr\n\tvikIqi6JX/UuA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1651850672;\n\tbh=fsK5H4kRS7quvV5O5LTcLftl7GKZQvvlOR+AXDpQlXY=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=mldUYy3v+Snw3o1bKy7WXyg+8sd9QK4WUPYwlqbtFdzb+CA4KRIN5SSlr2b4tXtKu\n\tIwoG764tTZXcuzQxqwLPO/4fHXBta9rJumM0uTa5r959W+ebwKF8YS9aMU2Hd074uw\n\tFiCp+E2FAHqJq3EbccQLqL01eyX1boIY300KVW+A="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"mldUYy3v\"; dkim-atps=neutral","Date":"Fri, 6 May 2022 18:24:27 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YnU9qxdKISEU37Jb@pendragon.ideasonboard.com>","References":"<20220505104104.70841-1-tomi.valkeinen@ideasonboard.com>\n\t<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>\n\t<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>\n\t<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22891,"web_url":"https://patchwork.libcamera.org/comment/22891/","msgid":"<CAHW6GY+v3TZe0CdL4M8cookS-9CiP-HMOhoBCpk+JAGTZ3qyag@mail.gmail.com>","date":"2022-05-06T15:40:01","subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi Laurent, Tomi\n\nOn Fri, 6 May 2022 at 16:24, Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> Hi Tomi,\n>\n> On Fri, May 06, 2022 at 02:25:50PM +0300, Tomi Valkeinen wrote:\n> > On 05/05/2022 20:59, Laurent Pinchart wrote:\n> > > On Thu, May 05, 2022 at 01:41:00PM +0300, Tomi Valkeinen wrote:\n> > >> Add binding for Transform.\n> > >>\n> > >> C++'s Transform is an enum class, but we expose it as a Python class so\n> > >> that it can be easily manipulated.\n> > >>\n> > >> Original version from David Plowman <david.plowman@raspberrypi.com>.\n> > >>\n> > >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > >> ---\n> > >>   src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-\n> > >>   1 file changed, 62 insertions(+), 1 deletion(-)\n> > >>\n> > >> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n> > >> index db9d90ab..3d2393ab 100644\n> > >> --- a/src/py/libcamera/pymain.cpp\n> > >> +++ b/src/py/libcamera/pymain.cpp\n> > >> @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)\n> > >>    auto pyControlId = py::class_<ControlId>(m, \"ControlId\");\n> > >>    auto pyRequest = py::class_<Request>(m, \"Request\");\n> > >>    auto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n> > >> +  auto pyTransform = py::class_<Transform>(m, \"Transform\");\n> > >>\n> > >>    /* Global functions */\n> > >>    m.def(\"logSetLevel\", &logSetLevel);\n> > >> @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)\n> > >>            .def(\"validate\", &CameraConfiguration::validate)\n> > >>            .def(\"at\", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)\n> > >>            .def_property_readonly(\"size\", &CameraConfiguration::size)\n> > >> -          .def_property_readonly(\"empty\", &CameraConfiguration::empty);\n> > >> +          .def_property_readonly(\"empty\", &CameraConfiguration::empty)\n> > >> +          .def_readwrite(\"transform\", &CameraConfiguration::transform);\n> > >>\n> > >>    pyStreamConfiguration\n> > >>            .def(\"toString\", &StreamConfiguration::toString)\n> > >> @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)\n> > >>                    transform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });\n> > >>                    return v;\n> > >>            });\n> > >> +\n> > >> +  pyTransform\n> > >> +          .def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\n> > >\n> > > I'm not fond of the constructor, three bool arguments in a row are quite\n> > > error-prone. I'd rather expose the enum.\n> >\n> > It's not that bad with python, e.g.:\n> >\n> > Transform(transpose=True, vflip=True)\n> >\n> > I think that's more pythonic than or'ing enums.\n>\n> One could also write\n>\n>     Transform(0, true, false, true)\n>\n> which isn't nice. We can address that out later if needed, either\n> merging this patch already or postponing it. David, do you have any\n> opinion ?\n\nYes, what Tomi put is exactly how I am expecting to use it. I don't\nfeel terribly strongly, but it did seem both handy and Python-ish. You\ncan do\n\nt = Transform(180)\n\nt = Transform(hflip=True, vflip=True)\n\nt = Transform()\nt.hflip = t.vflip =1\n\nI agree that it can be misused by the determined, but I definitely\nwent for convenience...\n\nDavid\n\n>\n> > >> +                  bool ok;\n> > >> +\n> > >> +                  Transform t = transformFromRotation(rotation, &ok);\n> > >> +                  if (!ok)\n> > >> +                          throw std::runtime_error(\"Unable to create the transform\");\n> > >\n> > > \"Invalid rotation\" would be a better message I think.\n> >\n> > And std::invalid_argument.\n>\n> Good point.\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 07373C3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  6 May 2022 15:40:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5871765646;\n\tFri,  6 May 2022 17:40:14 +0200 (CEST)","from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com\n\t[IPv6:2a00:1450:4864:20::42f])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 258C9604A3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  6 May 2022 17:40:13 +0200 (CEST)","by mail-wr1-x42f.google.com with SMTP id c11so10536308wrn.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 06 May 2022 08:40:13 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651851614;\n\tbh=iUxlGz2BrphQMl5qEJwiHgr+pktgnPWCn714Ahu0WT4=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=kb5Cn1F80+wEEokEZw1x/NMdvTucBIBocoobi4vmKMAnvjtNQUvwvQH4eDD4aB1Uy\n\tYcsg7b35lk2M4p99s1fE3CUqMgJHeuudFYWESWoQitS0oIRYvKg8+nNL8Ld3qo/+sI\n\td15XDvubStXlv2RN5CwFvP5ZwmiFoSj95BTYyJ0qamaBOlQ6aMlIQlwPV2BFHFusDY\n\tGGbskbNGiGE3KUNcKUCduo+oAB9qaJDsOYG03rZ2yXehYpL1SSz8w58Sxt1brMD6jb\n\tAwYwOGQQgItl2bLanCOutnc7oIyexYARabJep/7RA1i6QSFqDHtJ6i5BRtOxFjthHS\n\t9pLpncNCOtPTw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=Bauc9BtWAc438HHCVMpwKzbrK09mupCJ6yGXhzOlo1E=;\n\tb=dcEOzsWWSckGnvS+rVsOhoSNfvYMne/0CizADw4C9xIHJ2LiOTITM8DgD6zH+hUY5e\n\t75MFLFpDtjpm8wZ0TlbS6yXlwfugei96vuSRd33QaW31S2ceig2Y7A64G987GZ0Qk9sn\n\ttbwz0RpIVgP4o+8MrfPDF3NWCISDvYhjQnR4vNfEyMZhKjIWCl8inbKIhN6BDG9DCPKa\n\tOsLV6OKqokdiqhU5rpptCq0csI5ZYi2SLM0Rxs920H+faVa80xxTlUlJv3wEAgBmOIth\n\t//s7z+TRROeM2MUzjEO3Y7oKFPKtrezpPb9UrCqpQ5w/84G5Gu01wtMknD+Eh51CySuv\n\t/aOw=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"dcEOzsWW\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=Bauc9BtWAc438HHCVMpwKzbrK09mupCJ6yGXhzOlo1E=;\n\tb=IIt5fzWqvGgE91bAvYj3APystyZ2ZHrtzGvzKKUiAM+KoxTXVTotJsRPlyD4DX7WGW\n\t6VmMBoNGUPXRsPwy+CBcg5PXYZ3J9G4IICgCF6uFjIzzFD/InV3PJw3BaqkZfkVP66n8\n\tR6wUYYmglBMSMSvCWHRM3TVX95LNxbYMEyhsoRXLZbPFWETlDoWH8+AvvZvmBnFux5uz\n\tEANbuSJYg5ATByr4z43wRvgC6d5hnTtinieFtU3r8NOgBHZCxgXlbIZXLdxOv3+kyKkd\n\tGc/HSa5lTdfi8ARNyvs80sWga4zopErPdCJI5cVStqxjlT5R5t0KeVhxfqMEzj4D5bqt\n\t94VA==","X-Gm-Message-State":"AOAM5321QrLjWFbRD6CKeBhWFHjMUev2tnHroyircaIJkUtHHV0BRLr/\n\tcRBuO17w45BRxwfp0h4L6CPGlD4SSULSFIuc24J8yw==","X-Google-Smtp-Source":"ABdhPJyVEy2284oXCH8L7i2BJZiIOcf4+DarCqy+AAImDcSu9zXipnlxg80smRm03VnJDF62FWmUdjdb4SYBdpdYxeg=","X-Received":"by 2002:adf:f710:0:b0:20a:e189:9983 with SMTP id\n\tr16-20020adff710000000b0020ae1899983mr3103147wrp.24.1651851612726;\n\tFri, 06 May 2022 08:40:12 -0700 (PDT)","MIME-Version":"1.0","References":"<20220505104104.70841-1-tomi.valkeinen@ideasonboard.com>\n\t<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>\n\t<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>\n\t<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>\n\t<YnU9qxdKISEU37Jb@pendragon.ideasonboard.com>","In-Reply-To":"<YnU9qxdKISEU37Jb@pendragon.ideasonboard.com>","Date":"Fri, 6 May 2022 16:40:01 +0100","Message-ID":"<CAHW6GY+v3TZe0CdL4M8cookS-9CiP-HMOhoBCpk+JAGTZ3qyag@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","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>","From":"David Plowman via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"David Plowman <david.plowman@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":22892,"web_url":"https://patchwork.libcamera.org/comment/22892/","msgid":"<YnVC2J4m8bZ1+S0Q@pendragon.ideasonboard.com>","date":"2022-05-06T15:46:32","subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Fri, May 06, 2022 at 04:40:01PM +0100, David Plowman wrote:\n> On Fri, 6 May 2022 at 16:24, Laurent Pinchart wrote:\n> > On Fri, May 06, 2022 at 02:25:50PM +0300, Tomi Valkeinen wrote:\n> > > On 05/05/2022 20:59, Laurent Pinchart wrote:\n> > > > On Thu, May 05, 2022 at 01:41:00PM +0300, Tomi Valkeinen wrote:\n> > > >> Add binding for Transform.\n> > > >>\n> > > >> C++'s Transform is an enum class, but we expose it as a Python class so\n> > > >> that it can be easily manipulated.\n> > > >>\n> > > >> Original version from David Plowman <david.plowman@raspberrypi.com>.\n> > > >>\n> > > >> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > > >> ---\n> > > >>   src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++-\n> > > >>   1 file changed, 62 insertions(+), 1 deletion(-)\n> > > >>\n> > > >> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n> > > >> index db9d90ab..3d2393ab 100644\n> > > >> --- a/src/py/libcamera/pymain.cpp\n> > > >> +++ b/src/py/libcamera/pymain.cpp\n> > > >> @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m)\n> > > >>    auto pyControlId = py::class_<ControlId>(m, \"ControlId\");\n> > > >>    auto pyRequest = py::class_<Request>(m, \"Request\");\n> > > >>    auto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n> > > >> +  auto pyTransform = py::class_<Transform>(m, \"Transform\");\n> > > >>\n> > > >>    /* Global functions */\n> > > >>    m.def(\"logSetLevel\", &logSetLevel);\n> > > >> @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m)\n> > > >>            .def(\"validate\", &CameraConfiguration::validate)\n> > > >>            .def(\"at\", py::overload_cast<unsigned int>(&CameraConfiguration::at), py::return_value_policy::reference_internal)\n> > > >>            .def_property_readonly(\"size\", &CameraConfiguration::size)\n> > > >> -          .def_property_readonly(\"empty\", &CameraConfiguration::empty);\n> > > >> +          .def_property_readonly(\"empty\", &CameraConfiguration::empty)\n> > > >> +          .def_readwrite(\"transform\", &CameraConfiguration::transform);\n> > > >>\n> > > >>    pyStreamConfiguration\n> > > >>            .def(\"toString\", &StreamConfiguration::toString)\n> > > >> @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m)\n> > > >>                    transform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; });\n> > > >>                    return v;\n> > > >>            });\n> > > >> +\n> > > >> +  pyTransform\n> > > >> +          .def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\n> > > >\n> > > > I'm not fond of the constructor, three bool arguments in a row are quite\n> > > > error-prone. I'd rather expose the enum.\n> > >\n> > > It's not that bad with python, e.g.:\n> > >\n> > > Transform(transpose=True, vflip=True)\n> > >\n> > > I think that's more pythonic than or'ing enums.\n> >\n> > One could also write\n> >\n> >     Transform(0, true, false, true)\n> >\n> > which isn't nice. We can address that out later if needed, either\n> > merging this patch already or postponing it. David, do you have any\n> > opinion ?\n> \n> Yes, what Tomi put is exactly how I am expecting to use it. I don't\n> feel terribly strongly, but it did seem both handy and Python-ish. You\n> can do\n> \n> t = Transform(180)\n> \n> t = Transform(hflip=True, vflip=True)\n> \n> t = Transform()\n> t.hflip = t.vflip =1\n> \n> I agree that it can be misused by the determined, but I definitely\n> went for convenience...\n\nTime to document the Python bindings then ? :-)\n\n> > > >> +                  bool ok;\n> > > >> +\n> > > >> +                  Transform t = transformFromRotation(rotation, &ok);\n> > > >> +                  if (!ok)\n> > > >> +                          throw std::runtime_error(\"Unable to create the transform\");\n> > > >\n> > > > \"Invalid rotation\" would be a better message I think.\n> > >\n> > > And std::invalid_argument.\n> >\n> > Good point.","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 044D1C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  6 May 2022 15:46:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 44BC265646;\n\tFri,  6 May 2022 17:46:39 +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 4E291604A3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  6 May 2022 17:46:37 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8C2BF3E4;\n\tFri,  6 May 2022 17:46:36 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1651851999;\n\tbh=I85IA4IkxkovKQS32QtOUhAps1+CJgFzeNl8HRxnfKM=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=uwSivWmzKwJw06qFEZ40ecetyDcauQ2I3o/QFEDtPE3/oko02ao5K9fiIggUzrFZf\n\t1elYvOCF/j/D6iEnEzW+gAeIp96NkichHJXAZjMYRl3oAauecLrKYygE8VLZCtKznn\n\tvWL83xsFHRegT/o8cx0tej6GyAVv0iwH7mWv8MactTnZTaEm8Ed6XI7Xt0R5w//l6G\n\teEyI7oyuvFqgvRIX8AYCvHNAH5vHvZmNnfV3EVk1vH/XNR5t7gpWK6RtKO5iVScPia\n\tKfSOa7ULyQXIBpdlSy/KC4MqsHN0ZxeXL34ZOJaTth9YvQcOg9usweS3QudAGL5WrG\n\tJIxXC7JjVlx+w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1651851996;\n\tbh=I85IA4IkxkovKQS32QtOUhAps1+CJgFzeNl8HRxnfKM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=oEoAI6IldpPImQz1MrIaYksSU8zxujz9OwXGurZ2Wwc99zytP6MVTlZjzlx4cHjY8\n\ts0wWEUlD7xR0ylCUtcDqTDdIs0kqmPlD8KRMvi7wRqcrlohjGouGPsmzrmM5jKOYL1\n\tJx56smvBatIVKaE2ZU2rVm7+HtZjcNePmIVzMsOw="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"oEoAI6Il\"; dkim-atps=neutral","Date":"Fri, 6 May 2022 18:46:32 +0300","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<YnVC2J4m8bZ1+S0Q@pendragon.ideasonboard.com>","References":"<20220505104104.70841-1-tomi.valkeinen@ideasonboard.com>\n\t<20220505104104.70841-10-tomi.valkeinen@ideasonboard.com>\n\t<YnQQalqnnxDeGXIv@pendragon.ideasonboard.com>\n\t<b8723ba3-fdb4-09b9-1204-ef13cc718a9b@ideasonboard.com>\n\t<YnU9qxdKISEU37Jb@pendragon.ideasonboard.com>\n\t<CAHW6GY+v3TZe0CdL4M8cookS-9CiP-HMOhoBCpk+JAGTZ3qyag@mail.gmail.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<CAHW6GY+v3TZe0CdL4M8cookS-9CiP-HMOhoBCpk+JAGTZ3qyag@mail.gmail.com>","Subject":"Re: [libcamera-devel] [PATCH v7 09/13] py: add Transform","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]