From patchwork Tue May 30 09:20:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 18658 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 0AEA4C328E for ; Tue, 30 May 2023 09:21:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D633B627DC; Tue, 30 May 2023 11:20:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1685438458; bh=nHSP+q/90+O1ZqQyXaOquYKMd+RtlacWXMkMwb0jX+8=; 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=rAKr/RPfbWm4FfyByFdDpGlzCAgrQ9IuJs2Y3gbUdRir0xp2N1vUaxFFXxuzjnbip bKiq6tC7ur633kJrhJttyma7nmEDN+e+gRkKAdDn2/EoADQRltlzbo0X02HRk8YEoM EFCZoeevA+unZyygYldOe0/ElBZd6ATPUq9YRe62p450q8okEBvvwosrK+PwqE6aI+ N7qn96xJFUUEM1X9S3ee+9RerW8E/M7ScN97xA9dUpRzap1nMz850KsA3SznFcaFDZ ve2OWDEMCGDUVR+IwQgkID3l2vWTUxWkE5Ct5VZwsN9bl29T8WZlY5diccRZlbzil/ G5P0CyqO0LOyA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6619660388 for ; Tue, 30 May 2023 11:20:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="nUcVveIl"; dkim-atps=neutral Received: from desky.lan (91-154-35-171.elisa-laajakaista.fi [91.154.35.171]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 8FD177F3; Tue, 30 May 2023 11:20:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1685438435; bh=nHSP+q/90+O1ZqQyXaOquYKMd+RtlacWXMkMwb0jX+8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nUcVveIl7YXYqaWNr7oddErUjvooJCajqbk5dAbt/sZh3nPPIl1ZrnWShRkwVsZjg 5QfCQnLfCleNtBJzd4FIp175CxJ15HsQxkYRwRxth+oMYZXyBJVl9si90OGogs2N2t nUevNWAaOx7Bofp32KNRFxRJcqscLz6oWK5a2K/A= To: libcamera-devel@lists.libcamera.org Date: Tue, 30 May 2023 12:20:13 +0300 Message-Id: <20230530092016.34953-3-tomi.valkeinen@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230530092016.34953-1-tomi.valkeinen@ideasonboard.com> References: <20230530092016.34953-1-tomi.valkeinen@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/5] py: Move ColorSpace and Transform classes to separate files 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" Move ColorSpace and Transform classes to separate files from the main py_main.cpp, for clarity. Signed-off-by: Tomi Valkeinen Reviewed-by: Laurent Pinchart --- src/py/libcamera/meson.build | 2 + src/py/libcamera/py_color_space.cpp | 70 +++++++++++++++++ src/py/libcamera/py_main.cpp | 115 ++-------------------------- src/py/libcamera/py_transform.cpp | 81 ++++++++++++++++++++ 4 files changed, 158 insertions(+), 110 deletions(-) create mode 100644 src/py/libcamera/py_color_space.cpp create mode 100644 src/py/libcamera/py_transform.cpp diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build index af19ffdd..f87b1b4d 100644 --- a/src/py/libcamera/meson.build +++ b/src/py/libcamera/meson.build @@ -14,10 +14,12 @@ pybind11_dep = pybind11_proj.get_variable('pybind11_dep') pycamera_sources = files([ 'py_camera_manager.cpp', + 'py_color_space.cpp', 'py_enums.cpp', 'py_geometry.cpp', 'py_helpers.cpp', 'py_main.cpp', + 'py_transform.cpp', ]) # Generate controls diff --git a/src/py/libcamera/py_color_space.cpp b/src/py/libcamera/py_color_space.cpp new file mode 100644 index 00000000..a8301e3d --- /dev/null +++ b/src/py/libcamera/py_color_space.cpp @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Tomi Valkeinen + * + * Python bindings - Color Space classes + */ + +#include +#include + +#include +#include +#include + +namespace py = pybind11; + +using namespace libcamera; + +void init_py_color_space(py::module &m) +{ + auto pyColorSpace = py::class_(m, "ColorSpace"); + auto pyColorSpacePrimaries = py::enum_(pyColorSpace, "Primaries"); + auto pyColorSpaceTransferFunction = py::enum_(pyColorSpace, "TransferFunction"); + auto pyColorSpaceYcbcrEncoding = py::enum_(pyColorSpace, "YcbcrEncoding"); + auto pyColorSpaceRange = py::enum_(pyColorSpace, "Range"); + + pyColorSpace + .def(py::init([](ColorSpace::Primaries primaries, + ColorSpace::TransferFunction transferFunction, + ColorSpace::YcbcrEncoding ycbcrEncoding, + ColorSpace::Range range) { + return ColorSpace(primaries, transferFunction, ycbcrEncoding, range); + }), py::arg("primaries"), py::arg("transferFunction"), + py::arg("ycbcrEncoding"), py::arg("range")) + .def(py::init([](ColorSpace &other) { return other; })) + .def("__str__", [](ColorSpace &self) { + return ""; + }) + .def_readwrite("primaries", &ColorSpace::primaries) + .def_readwrite("transferFunction", &ColorSpace::transferFunction) + .def_readwrite("ycbcrEncoding", &ColorSpace::ycbcrEncoding) + .def_readwrite("range", &ColorSpace::range) + .def_static("Raw", []() { return ColorSpace::Raw; }) + .def_static("Srgb", []() { return ColorSpace::Srgb; }) + .def_static("Sycc", []() { return ColorSpace::Sycc; }) + .def_static("Smpte170m", []() { return ColorSpace::Smpte170m; }) + .def_static("Rec709", []() { return ColorSpace::Rec709; }) + .def_static("Rec2020", []() { return ColorSpace::Rec2020; }); + + pyColorSpacePrimaries + .value("Raw", ColorSpace::Primaries::Raw) + .value("Smpte170m", ColorSpace::Primaries::Smpte170m) + .value("Rec709", ColorSpace::Primaries::Rec709) + .value("Rec2020", ColorSpace::Primaries::Rec2020); + + pyColorSpaceTransferFunction + .value("Linear", ColorSpace::TransferFunction::Linear) + .value("Srgb", ColorSpace::TransferFunction::Srgb) + .value("Rec709", ColorSpace::TransferFunction::Rec709); + + pyColorSpaceYcbcrEncoding + .value("Null", ColorSpace::YcbcrEncoding::None) + .value("Rec601", ColorSpace::YcbcrEncoding::Rec601) + .value("Rec709", ColorSpace::YcbcrEncoding::Rec709) + .value("Rec2020", ColorSpace::YcbcrEncoding::Rec2020); + + pyColorSpaceRange + .value("Full", ColorSpace::Range::Full) + .value("Limited", ColorSpace::Range::Limited); +} diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index c55495cc..56d0717e 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -40,11 +40,13 @@ LOG_DEFINE_CATEGORY(Python) */ static std::weak_ptr gCameraManager; -void init_py_enums(py::module &m); +void init_py_color_space(py::module &m); void init_py_controls_generated(py::module &m); +void init_py_enums(py::module &m); void init_py_formats_generated(py::module &m); void init_py_geometry(py::module &m); void init_py_properties_generated(py::module &m); +void init_py_transform(py::module &m); PYBIND11_MODULE(_libcamera, m) { @@ -52,6 +54,8 @@ PYBIND11_MODULE(_libcamera, m) init_py_controls_generated(m); init_py_geometry(m); init_py_properties_generated(m); + init_py_color_space(m); + init_py_transform(m); /* Forward declarations */ @@ -79,12 +83,6 @@ PYBIND11_MODULE(_libcamera, m) auto pyFrameMetadata = py::class_(m, "FrameMetadata"); auto pyFrameMetadataStatus = py::enum_(pyFrameMetadata, "Status"); auto pyFrameMetadataPlane = py::class_(pyFrameMetadata, "Plane"); - auto pyTransform = py::class_(m, "Transform"); - auto pyColorSpace = py::class_(m, "ColorSpace"); - auto pyColorSpacePrimaries = py::enum_(pyColorSpace, "Primaries"); - auto pyColorSpaceTransferFunction = py::enum_(pyColorSpace, "TransferFunction"); - auto pyColorSpaceYcbcrEncoding = py::enum_(pyColorSpace, "YcbcrEncoding"); - auto pyColorSpaceRange = py::enum_(pyColorSpace, "Range"); auto pyPixelFormat = py::class_(m, "PixelFormat"); init_py_formats_generated(m); @@ -388,109 +386,6 @@ PYBIND11_MODULE(_libcamera, m) pyFrameMetadataPlane .def_readwrite("bytes_used", &FrameMetadata::Plane::bytesused); - pyTransform - .def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) { - bool ok; - - Transform t = transformFromRotation(rotation, &ok); - if (!ok) - throw std::invalid_argument("Invalid rotation"); - - 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("__str__", [](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; - }); - - pyColorSpace - .def(py::init([](ColorSpace::Primaries primaries, - ColorSpace::TransferFunction transferFunction, - ColorSpace::YcbcrEncoding ycbcrEncoding, - ColorSpace::Range range) { - return ColorSpace(primaries, transferFunction, ycbcrEncoding, range); - }), py::arg("primaries"), py::arg("transferFunction"), - py::arg("ycbcrEncoding"), py::arg("range")) - .def(py::init([](ColorSpace &other) { return other; })) - .def("__str__", [](ColorSpace &self) { - return ""; - }) - .def_readwrite("primaries", &ColorSpace::primaries) - .def_readwrite("transferFunction", &ColorSpace::transferFunction) - .def_readwrite("ycbcrEncoding", &ColorSpace::ycbcrEncoding) - .def_readwrite("range", &ColorSpace::range) - .def_static("Raw", []() { return ColorSpace::Raw; }) - .def_static("Srgb", []() { return ColorSpace::Srgb; }) - .def_static("Sycc", []() { return ColorSpace::Sycc; }) - .def_static("Smpte170m", []() { return ColorSpace::Smpte170m; }) - .def_static("Rec709", []() { return ColorSpace::Rec709; }) - .def_static("Rec2020", []() { return ColorSpace::Rec2020; }); - - pyColorSpacePrimaries - .value("Raw", ColorSpace::Primaries::Raw) - .value("Smpte170m", ColorSpace::Primaries::Smpte170m) - .value("Rec709", ColorSpace::Primaries::Rec709) - .value("Rec2020", ColorSpace::Primaries::Rec2020); - - pyColorSpaceTransferFunction - .value("Linear", ColorSpace::TransferFunction::Linear) - .value("Srgb", ColorSpace::TransferFunction::Srgb) - .value("Rec709", ColorSpace::TransferFunction::Rec709); - - pyColorSpaceYcbcrEncoding - .value("Null", ColorSpace::YcbcrEncoding::None) - .value("Rec601", ColorSpace::YcbcrEncoding::Rec601) - .value("Rec709", ColorSpace::YcbcrEncoding::Rec709) - .value("Rec2020", ColorSpace::YcbcrEncoding::Rec2020); - - pyColorSpaceRange - .value("Full", ColorSpace::Range::Full) - .value("Limited", ColorSpace::Range::Limited); - pyPixelFormat .def(py::init<>()) .def(py::init()) diff --git a/src/py/libcamera/py_transform.cpp b/src/py/libcamera/py_transform.cpp new file mode 100644 index 00000000..08783e29 --- /dev/null +++ b/src/py/libcamera/py_transform.cpp @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2022, Tomi Valkeinen + * + * Python bindings - Transform class + */ + +#include +#include + +#include +#include +#include + +namespace py = pybind11; + +using namespace libcamera; + +void init_py_transform(py::module &m) +{ + auto pyTransform = py::class_(m, "Transform"); + + pyTransform + .def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) { + bool ok; + + Transform t = transformFromRotation(rotation, &ok); + if (!ok) + throw std::invalid_argument("Invalid rotation"); + + 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("__str__", [](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; + }); +}