From patchwork Thu May 5 10:41:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 15792 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 60A4DC326F for ; Thu, 5 May 2022 10:41:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A94866566B; Thu, 5 May 2022 12:41:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1651747295; bh=kKxfsicKBd8oRUdODrs8kZ8BAB5F+y6fI6wvRUvLZxY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=ncYFJtR6VWSK9s6aj2R1sJtsVpuy92aQ220g9u68X/115FBvU2VZ6V1xcJrypiuRS KYl7t28WYfQl5E2XEIW1qaNERvVg19jEkM79XwGN+E8gaXoaYqZNYXCpVvlXTOUMiW wkCrTIb1Guu9Ut+8gbyLkoMhN7XqmcrhUiudH59T+YOlzKYTkHoJbTKtN+blrSLYR3 ScIPbiKpSyuNTG9wTLWgz6D9aAexFcqsxB0lcj4+0OdXYNyMl94oMgNfawj4JVnxZn f1Dii4zVFEoBx4pkZ7jHADMzk5gWwSv1/ii1wifR28oQrJkAwpJ2QS6772+0lhF2st i/t8FGa9U/QnQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 761AA65657 for ; Thu, 5 May 2022 12:41:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="g0xaLdyH"; dkim-atps=neutral Received: from deskari.lan (91-156-85-209.elisa-laajakaista.fi [91.156.85.209]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DD83AA46; Thu, 5 May 2022 12:41:29 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1651747290; bh=kKxfsicKBd8oRUdODrs8kZ8BAB5F+y6fI6wvRUvLZxY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g0xaLdyH75SS15qLVvlVqsR7ZWJjhqm1cq+18TrJrweJqbb9KGqIqn1SrGN4Qkt10 tiS3NeSDGVrul3JZFbFZKXaNHE1PM/Kw/v82t7NMYxf71l/oDMQrxo+152Quc6veY8 isMcL4Ox84KHrAlVwVP0uIF5uhD5eeA+GQGRhnng= To: libcamera-devel@lists.libcamera.org, David Plowman , Kieran Bingham , Laurent Pinchart , Jacopo Mondi Date: Thu, 5 May 2022 13:41:00 +0300 Message-Id: <20220505104104.70841-10-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220505104104.70841-1-tomi.valkeinen@ideasonboard.com> References: <20220505104104.70841-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Tomi Valkeinen via libcamera-devel From: Tomi Valkeinen Reply-To: Tomi Valkeinen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add binding for Transform. C++'s Transform is an enum class, but we expose it as a Python class so that it can be easily manipulated. Original version from David Plowman . Signed-off-by: Tomi Valkeinen --- src/py/libcamera/pymain.cpp | 63 ++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp index db9d90ab..3d2393ab 100644 --- a/src/py/libcamera/pymain.cpp +++ b/src/py/libcamera/pymain.cpp @@ -152,6 +152,7 @@ PYBIND11_MODULE(_libcamera, m) auto pyControlId = py::class_(m, "ControlId"); auto pyRequest = py::class_(m, "Request"); auto pyFrameMetadata = py::class_(m, "FrameMetadata"); + auto pyTransform = py::class_(m, "Transform"); /* Global functions */ m.def("logSetLevel", &logSetLevel); @@ -342,7 +343,8 @@ PYBIND11_MODULE(_libcamera, m) .def("validate", &CameraConfiguration::validate) .def("at", py::overload_cast(&CameraConfiguration::at), py::return_value_policy::reference_internal) .def_property_readonly("size", &CameraConfiguration::size) - .def_property_readonly("empty", &CameraConfiguration::empty); + .def_property_readonly("empty", &CameraConfiguration::empty) + .def_readwrite("transform", &CameraConfiguration::transform); pyStreamConfiguration .def("toString", &StreamConfiguration::toString) @@ -462,4 +464,63 @@ PYBIND11_MODULE(_libcamera, m) transform(self.planes().begin(), self.planes().end(), v.begin(), [](const auto &p) { return p.bytesused; }); return v; }); + + pyTransform + .def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) { + bool ok; + + Transform t = transformFromRotation(rotation, &ok); + if (!ok) + throw std::runtime_error("Unable to create the transform"); + + if (hflip) + t ^= Transform::HFlip; + if (vflip) + t ^= Transform::VFlip; + if (transpose) + t ^= Transform::Transpose; + return t; + }), py::arg("rotation") = 0, py::arg("hflip") = false, + py::arg("vflip") = false, py::arg("transpose") = false) + .def(py::init([](Transform &other) { return other; })) + .def("__repr__", [](Transform &self) { + return ""; + }) + .def_property("hflip", + [](Transform &self) { + return !!(self & Transform::HFlip); + }, + [](Transform &self, bool hflip) { + if (hflip) + self |= Transform::HFlip; + else + self &= ~Transform::HFlip; + }) + .def_property("vflip", + [](Transform &self) { + return !!(self & Transform::VFlip); + }, + [](Transform &self, bool vflip) { + if (vflip) + self |= Transform::VFlip; + else + self &= ~Transform::VFlip; + }) + .def_property("transpose", + [](Transform &self) { + return !!(self & Transform::Transpose); + }, + [](Transform &self, bool transpose) { + if (transpose) + self |= Transform::Transpose; + else + self &= ~Transform::Transpose; + }) + .def("inverse", [](Transform &self) { return -self; }) + .def("invert", [](Transform &self) { + self = -self; + }) + .def("compose", [](Transform &self, Transform &other) { + self = self * other; + }); }