[{"id":26633,"web_url":"https://patchwork.libcamera.org/comment/26633/","msgid":"<20230312151034.GS2545@pendragon.ideasonboard.com>","date":"2023-03-12T15:10:34","subject":"Re: [libcamera-devel] [PATCH v4 13/15] py: Move Color Space and\n\tTransform classes to separate files","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, Mar 09, 2023 at 04:25:59PM +0200, Tomi Valkeinen via libcamera-devel wrote:\n> Move Color Space and Transform classes to separate files from the main\n\ns/Color Space/ColorSpace/\n\n> py_main.cpp, for clarity.\n> \n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  src/py/libcamera/meson.build        |   2 +\n>  src/py/libcamera/py_color_space.cpp |  71 +++++++++++++++++\n>  src/py/libcamera/py_main.cpp        | 115 ++--------------------------\n>  src/py/libcamera/py_transform.cpp   |  81 ++++++++++++++++++++\n>  4 files changed, 159 insertions(+), 110 deletions(-)\n>  create mode 100644 src/py/libcamera/py_color_space.cpp\n>  create mode 100644 src/py/libcamera/py_transform.cpp\n> \n> diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\n> index af19ffdd..f87b1b4d 100644\n> --- a/src/py/libcamera/meson.build\n> +++ b/src/py/libcamera/meson.build\n> @@ -14,10 +14,12 @@ pybind11_dep = pybind11_proj.get_variable('pybind11_dep')\n>  \n>  pycamera_sources = files([\n>      'py_camera_manager.cpp',\n> +    'py_color_space.cpp',\n>      'py_enums.cpp',\n>      'py_geometry.cpp',\n>      'py_helpers.cpp',\n>      'py_main.cpp',\n> +    'py_transform.cpp',\n>  ])\n>  \n>  # Generate controls\n> diff --git a/src/py/libcamera/py_color_space.cpp b/src/py/libcamera/py_color_space.cpp\n> new file mode 100644\n> index 00000000..4bd86320\n> --- /dev/null\n> +++ b/src/py/libcamera/py_color_space.cpp\n> @@ -0,0 +1,71 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> + *\n> + * Python bindings - Color Space classes\n> + */\n> +\n> +#include <libcamera/color_space.h>\n> +#include <libcamera/libcamera.h>\n> +\n> +#include <pybind11/operators.h>\n> +#include <pybind11/smart_holder.h>\n> +#include <pybind11/stl.h>\n> +\n> +namespace py = pybind11;\n> +\n> +using namespace libcamera;\n> +\n> +void init_py_color_space(py::module &m)\n> +{\n> +\tauto pyColorSpace = py::class_<ColorSpace>(m, \"ColorSpace\");\n> +\tauto pyColorSpacePrimaries = py::enum_<ColorSpace::Primaries>(pyColorSpace, \"Primaries\");\n> +\tauto pyColorSpaceTransferFunction = py::enum_<ColorSpace::TransferFunction>(pyColorSpace, \"TransferFunction\");\n> +\tauto pyColorSpaceYcbcrEncoding = py::enum_<ColorSpace::YcbcrEncoding>(pyColorSpace, \"YcbcrEncoding\");\n> +\tauto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, \"Range\");\n> +\n> +\tpyColorSpace\n> +\t\t.def(py::init([](ColorSpace::Primaries primaries,\n> +\t\t\t\t ColorSpace::TransferFunction transferFunction,\n> +\t\t\t\t ColorSpace::YcbcrEncoding ycbcrEncoding,\n> +\t\t\t\t ColorSpace::Range range) {\n> +\t\t\treturn ColorSpace(primaries, transferFunction, ycbcrEncoding, range);\n> +\t\t}), py::arg(\"primaries\"), py::arg(\"transferFunction\"),\n> +\t\t    py::arg(\"ycbcrEncoding\"), py::arg(\"range\"))\n> +\t\t.def(py::init([](ColorSpace &other) { return other; }))\n> +\t\t.def(\"__str__\", [](ColorSpace &self) {\n> +\t\t\treturn \"<libcamera.ColorSpace '\" + self.toString() + \"'>\";\n> +\t\t})\n> +\t\t.def_readwrite(\"primaries\", &ColorSpace::primaries)\n> +\t\t.def_readwrite(\"transferFunction\", &ColorSpace::transferFunction)\n> +\t\t.def_readwrite(\"ycbcrEncoding\", &ColorSpace::ycbcrEncoding)\n> +\t\t.def_readwrite(\"range\", &ColorSpace::range)\n> +\t\t.def_static(\"Raw\", []() { return ColorSpace::Raw; })\n> +\t\t.def_static(\"Srgb\", []() { return ColorSpace::Srgb; })\n> +\t\t.def_static(\"Sycc\", []() { return ColorSpace::Sycc; })\n> +\t\t.def_static(\"Smpte170m\", []() { return ColorSpace::Smpte170m; })\n> +\t\t.def_static(\"Rec709\", []() { return ColorSpace::Rec709; })\n> +\t\t.def_static(\"Rec2020\", []() { return ColorSpace::Rec2020; });\n> +\n> +\tpyColorSpacePrimaries\n> +\t\t.value(\"Raw\", ColorSpace::Primaries::Raw)\n> +\t\t.value(\"Smpte170m\", ColorSpace::Primaries::Smpte170m)\n> +\t\t.value(\"Rec709\", ColorSpace::Primaries::Rec709)\n> +\t\t.value(\"Rec2020\", ColorSpace::Primaries::Rec2020);\n> +\n> +\tpyColorSpaceTransferFunction\n> +\t\t.value(\"Linear\", ColorSpace::TransferFunction::Linear)\n> +\t\t.value(\"Srgb\", ColorSpace::TransferFunction::Srgb)\n> +\t\t.value(\"Rec709\", ColorSpace::TransferFunction::Rec709);\n> +\n> +\tpyColorSpaceYcbcrEncoding\n> +\t\t.value(\"Null\", ColorSpace::YcbcrEncoding::None)\n> +\t\t.value(\"Rec601\", ColorSpace::YcbcrEncoding::Rec601)\n> +\t\t.value(\"Rec709\", ColorSpace::YcbcrEncoding::Rec709)\n> +\t\t.value(\"Rec2020\", ColorSpace::YcbcrEncoding::Rec2020);\n> +\n> +\tpyColorSpaceRange\n> +\t\t.value(\"Full\", ColorSpace::Range::Full)\n> +\t\t.value(\"Limited\", ColorSpace::Range::Limited);\n> +\n> +}\n> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> index 1069fd9c..1585b14a 100644\n> --- a/src/py/libcamera/py_main.cpp\n> +++ b/src/py/libcamera/py_main.cpp\n> @@ -40,11 +40,13 @@ LOG_DEFINE_CATEGORY(Python)\n>   */\n>  static std::weak_ptr<PyCameraManager> gCameraManager;\n>  \n> -void init_py_enums(py::module &m);\n> +void init_py_color_space(py::module &m);\n>  void init_py_controls_generated(py::module &m);\n> +void init_py_enums(py::module &m);\n>  void init_py_formats_generated(py::module &m);\n>  void init_py_geometry(py::module &m);\n>  void init_py_properties_generated(py::module &m);\n> +void init_py_transform(py::module &m);\n>  \n>  PYBIND11_MODULE(_libcamera, m)\n>  {\n> @@ -52,6 +54,8 @@ PYBIND11_MODULE(_libcamera, m)\n>  \tinit_py_controls_generated(m);\n>  \tinit_py_geometry(m);\n>  \tinit_py_properties_generated(m);\n> +\tinit_py_color_space(m);\n> +\tinit_py_transform(m);\n>  \n>  \t/* Forward declarations */\n>  \n> @@ -80,12 +84,6 @@ PYBIND11_MODULE(_libcamera, m)\n>  \tauto pyFrameMetadata = py::class_<FrameMetadata>(m, \"FrameMetadata\");\n>  \tauto pyFrameMetadataStatus = py::enum_<FrameMetadata::Status>(pyFrameMetadata, \"Status\");\n>  \tauto pyFrameMetadataPlane = py::class_<FrameMetadata::Plane>(pyFrameMetadata, \"Plane\");\n> -\tauto pyTransform = py::class_<Transform>(m, \"Transform\");\n> -\tauto pyColorSpace = py::class_<ColorSpace>(m, \"ColorSpace\");\n> -\tauto pyColorSpacePrimaries = py::enum_<ColorSpace::Primaries>(pyColorSpace, \"Primaries\");\n> -\tauto pyColorSpaceTransferFunction = py::enum_<ColorSpace::TransferFunction>(pyColorSpace, \"TransferFunction\");\n> -\tauto pyColorSpaceYcbcrEncoding = py::enum_<ColorSpace::YcbcrEncoding>(pyColorSpace, \"YcbcrEncoding\");\n> -\tauto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, \"Range\");\n>  \tauto pyPixelFormat = py::class_<PixelFormat>(m, \"PixelFormat\");\n>  \n>  \tinit_py_formats_generated(m);\n> @@ -455,109 +453,6 @@ PYBIND11_MODULE(_libcamera, m)\n>  \tpyFrameMetadataPlane\n>  \t\t.def_readwrite(\"bytes_used\", &FrameMetadata::Plane::bytesused);\n>  \n> -\tpyTransform\n> -\t\t.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\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::invalid_argument(\"Invalid rotation\");\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(\"__str__\", [](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> -\n> -\tpyColorSpace\n> -\t\t.def(py::init([](ColorSpace::Primaries primaries,\n> -\t\t\t\t ColorSpace::TransferFunction transferFunction,\n> -\t\t\t\t ColorSpace::YcbcrEncoding ycbcrEncoding,\n> -\t\t\t\t ColorSpace::Range range) {\n> -\t\t\treturn ColorSpace(primaries, transferFunction, ycbcrEncoding, range);\n> -\t\t}), py::arg(\"primaries\"), py::arg(\"transferFunction\"),\n> -\t\t    py::arg(\"ycbcrEncoding\"), py::arg(\"range\"))\n> -\t\t.def(py::init([](ColorSpace &other) { return other; }))\n> -\t\t.def(\"__str__\", [](ColorSpace &self) {\n> -\t\t\treturn \"<libcamera.ColorSpace '\" + self.toString() + \"'>\";\n> -\t\t})\n> -\t\t.def_readwrite(\"primaries\", &ColorSpace::primaries)\n> -\t\t.def_readwrite(\"transferFunction\", &ColorSpace::transferFunction)\n> -\t\t.def_readwrite(\"ycbcrEncoding\", &ColorSpace::ycbcrEncoding)\n> -\t\t.def_readwrite(\"range\", &ColorSpace::range)\n> -\t\t.def_static(\"Raw\", []() { return ColorSpace::Raw; })\n> -\t\t.def_static(\"Srgb\", []() { return ColorSpace::Srgb; })\n> -\t\t.def_static(\"Sycc\", []() { return ColorSpace::Sycc; })\n> -\t\t.def_static(\"Smpte170m\", []() { return ColorSpace::Smpte170m; })\n> -\t\t.def_static(\"Rec709\", []() { return ColorSpace::Rec709; })\n> -\t\t.def_static(\"Rec2020\", []() { return ColorSpace::Rec2020; });\n> -\n> -\tpyColorSpacePrimaries\n> -\t\t.value(\"Raw\", ColorSpace::Primaries::Raw)\n> -\t\t.value(\"Smpte170m\", ColorSpace::Primaries::Smpte170m)\n> -\t\t.value(\"Rec709\", ColorSpace::Primaries::Rec709)\n> -\t\t.value(\"Rec2020\", ColorSpace::Primaries::Rec2020);\n> -\n> -\tpyColorSpaceTransferFunction\n> -\t\t.value(\"Linear\", ColorSpace::TransferFunction::Linear)\n> -\t\t.value(\"Srgb\", ColorSpace::TransferFunction::Srgb)\n> -\t\t.value(\"Rec709\", ColorSpace::TransferFunction::Rec709);\n> -\n> -\tpyColorSpaceYcbcrEncoding\n> -\t\t.value(\"Null\", ColorSpace::YcbcrEncoding::None)\n> -\t\t.value(\"Rec601\", ColorSpace::YcbcrEncoding::Rec601)\n> -\t\t.value(\"Rec709\", ColorSpace::YcbcrEncoding::Rec709)\n> -\t\t.value(\"Rec2020\", ColorSpace::YcbcrEncoding::Rec2020);\n> -\n> -\tpyColorSpaceRange\n> -\t\t.value(\"Full\", ColorSpace::Range::Full)\n> -\t\t.value(\"Limited\", ColorSpace::Range::Limited);\n> -\n>  \tpyPixelFormat\n>  \t\t.def(py::init<>())\n>  \t\t.def(py::init<uint32_t, uint64_t>())\n> diff --git a/src/py/libcamera/py_transform.cpp b/src/py/libcamera/py_transform.cpp\n> new file mode 100644\n> index 00000000..08783e29\n> --- /dev/null\n> +++ b/src/py/libcamera/py_transform.cpp\n> @@ -0,0 +1,81 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> + *\n> + * Python bindings - Transform class\n> + */\n> +\n> +#include <libcamera/transform.h>\n> +#include <libcamera/libcamera.h>\n> +\n> +#include <pybind11/operators.h>\n> +#include <pybind11/smart_holder.h>\n> +#include <pybind11/stl.h>\n> +\n> +namespace py = pybind11;\n> +\n> +using namespace libcamera;\n> +\n> +void init_py_transform(py::module &m)\n> +{\n> +\tauto pyTransform = py::class_<Transform>(m, \"Transform\");\n> +\n> +\tpyTransform\n> +\t\t.def(py::init([](int rotation, bool hflip, bool vflip, bool transpose) {\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::invalid_argument(\"Invalid rotation\");\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(\"__str__\", [](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 51A58BD80A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 12 Mar 2023 15:10:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9D36B62709;\n\tSun, 12 Mar 2023 16:10:35 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CCCA762705\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 12 Mar 2023 16:10:33 +0100 (CET)","from pendragon.ideasonboard.com (85-76-21-162-nat.elisa-mobile.fi\n\t[85.76.21.162])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id CA29B814;\n\tSun, 12 Mar 2023 16:10:32 +0100 (CET)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1678633835;\n\tbh=mI4bmc3irn9AKGc12b6gNCf45/rRISVB9VpFC9nor+U=;\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=J2qFNORbolZmckC4e/NBuZlTHVE4WvwJJOefZ6Uz4+jnTGXIzTGaLpyGSkzbUAJ7O\n\tRaQuvnM5eJYbAerk582x1SEgXhfgu6vLGHsrVEWz75Ex/BnTpMjudJEO4K/CgSID3o\n\tLM6y9c2M26i3ixyfnDFLMKWYPtBGyEVwf34Eq7bCybXuYS1JZ9qDurvjIPdIi2ANEd\n\to3sGl+jaalZJ7g4UyttZ4BPhWyUXuBYpizCZFpyn/BMOEdxOvodGJHbOAo0Bft0i5H\n\tYRZyd80vhzb2k85xHh5Fh+8TBeZJmaiTryBYJZw4DUdffdqjygtgsZ15AnFRkxbkSC\n\tpf4pzbmC+XMWw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1678633833;\n\tbh=mI4bmc3irn9AKGc12b6gNCf45/rRISVB9VpFC9nor+U=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=PKr/yV4kOQIeso1mo+kkw1T3B6NyZnWZmFbFHbyCkRNqBcYeEYJlBpbctcdnrvNtB\n\tGcnM1I6gyZ9MAlPB+lAlJM63Isjmp8zwvL5zXjVyIZmXBWLHYq9PnmClVDPq0YqiiT\n\t7zGXiN6P2h6tjxXrwGRJiJ5p7JkyF2qaXc806Fo8="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"PKr/yV4k\"; dkim-atps=neutral","Date":"Sun, 12 Mar 2023 17:10:34 +0200","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<20230312151034.GS2545@pendragon.ideasonboard.com>","References":"<20230309142601.70556-1-tomi.valkeinen@ideasonboard.com>\n\t<20230309142601.70556-14-tomi.valkeinen@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20230309142601.70556-14-tomi.valkeinen@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 13/15] py: Move Color Space and\n\tTransform classes to separate files","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>"}}]