Patch Detail
Show a patch.
GET /api/patches/24824/?format=api
{ "id": 24824, "url": "https://patchwork.libcamera.org/api/patches/24824/?format=api", "web_url": "https://patchwork.libcamera.org/patch/24824/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20251026233048.175689-2-kieran.bingham@ideasonboard.com>", "date": "2025-10-26T23:30:38", "name": "[1/6] libipa: Provide a Quantized type and Quantizer support", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "9f6ba8cadee5c18470ee0299aa5b7a1f00682034", "submitter": { "id": 4, "url": "https://patchwork.libcamera.org/api/people/4/?format=api", "name": "Kieran Bingham", "email": "kieran.bingham@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/24824/mbox/", "series": [ { "id": 5532, "url": "https://patchwork.libcamera.org/api/series/5532/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5532", "date": "2025-10-26T23:30:37", "name": "libipa: Introduce a Quantized type", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5532/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/24824/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/24824/checks/", "tags": {}, "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 D6068BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 26 Oct 2025 23:30:59 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5AEE4606F8;\n\tMon, 27 Oct 2025 00:30:57 +0100 (CET)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EAE8D606E0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Oct 2025 00:30:53 +0100 (CET)", "from charm.hippo-penny.ts.net (unknown [209.38.108.23])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 38CE4E77;\n\tMon, 27 Oct 2025 00:29:06 +0100 (CET)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"gN822ZId\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1761521346;\n\tbh=1FcaQEB87OPnpDmcTCZcyq3suw1t0sx0KOfWaRXpDsw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=gN822ZId2NSBWy5bEOP1F2N8efdTHaLGqDTpOEWZgz8N4Ho8tiyNWocAPGAt7XYK/\n\tCS0NqUlVKFifCNglucxdUQAnlX7PjM6qAnxmRQYJ1kIREiXzq64gRe7iVwFdmZN08t\n\tk+dAte/yEeZng0x3JNpFFIaDL9XzP4wLlZuw+iZg=", "From": "Kieran Bingham <kieran.bingham@ideasonboard.com>", "To": "libcamera devel <libcamera-devel@lists.libcamera.org>", "Cc": "Kieran Bingham <kieran.bingham@ideasonboard.com>", "Subject": "[PATCH 1/6] libipa: Provide a Quantized type and Quantizer support", "Date": "Sun, 26 Oct 2025 23:30:38 +0000", "Message-ID": "<20251026233048.175689-2-kieran.bingham@ideasonboard.com>", "X-Mailer": "git-send-email 2.51.0", "In-Reply-To": "<20251026233048.175689-1-kieran.bingham@ideasonboard.com>", "References": "<20251026233048.175689-1-kieran.bingham@ideasonboard.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "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>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Frequently when handling data in IPA components we must convert and\nstore user interface values which may be floating point values, and\nperform a specific operation or conversion to quantize this to a\nhardware value.\n\nThis value may be to a fixed point type, or more custom code mappings,\nbut in either case it is important to contain both the required hardware\nvalue, with it's effective quantized value.\n\nProvide a new storage type 'Quantized' which can be read publicly but\nmust only be written through a controller class known as a Quantizer.\n\nQuantizers can be customised and specified by the owner of the data\nobject and must implement conversion between floats and the underlying\nhardware type.\n\nSigned-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n---\n src/ipa/libipa/meson.build | 2 +\n src/ipa/libipa/quantized.cpp | 167 +++++++++++++++++++++++++++++++++++\n src/ipa/libipa/quantized.h | 90 +++++++++++++++++++\n 3 files changed, 259 insertions(+)\n create mode 100644 src/ipa/libipa/quantized.cpp\n create mode 100644 src/ipa/libipa/quantized.h", "diff": "diff --git a/src/ipa/libipa/meson.build b/src/ipa/libipa/meson.build\nindex 660be94054fa..804289778f72 100644\n--- a/src/ipa/libipa/meson.build\n+++ b/src/ipa/libipa/meson.build\n@@ -17,6 +17,7 @@ libipa_headers = files([\n 'lux.h',\n 'module.h',\n 'pwl.h',\n+ 'quantized.h',\n ])\n \n libipa_sources = files([\n@@ -36,6 +37,7 @@ libipa_sources = files([\n 'lux.cpp',\n 'module.cpp',\n 'pwl.cpp',\n+ 'quantized.cpp',\n ])\n \n libipa_includes = include_directories('..')\ndiff --git a/src/ipa/libipa/quantized.cpp b/src/ipa/libipa/quantized.cpp\nnew file mode 100644\nindex 000000000000..0078c6f740a9\n--- /dev/null\n+++ b/src/ipa/libipa/quantized.cpp\n@@ -0,0 +1,167 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2025, Ideas On Board.\n+ *\n+ * Helper class to manage conversions between floating point types and quantized\n+ * storage and representation of those values.\n+ */\n+\n+#include \"quantized.h\"\n+\n+/**\n+ * \\file quantized.h\n+ * \\brief Quantized storage and Quantizer representations\n+ */\n+\n+namespace libcamera {\n+\n+namespace ipa {\n+\n+/**\n+ * \\struct Quantized\n+ * \\brief Quantized stores both an internal and quantized representation of a value\n+ * \\tparam T The quantized type (e.g., uint16_t, int16_t).\n+ *\n+ * This struct provides read-only access to both representations of the value.\n+ * It does not perform any conversions or quantization logic itself. This must\n+ * be handled externally by a quantizer that knows the appropriate behaviour.\n+ *\n+ * This type can be used to store values that need to be represented in both\n+ * fixed-point or integer (for hardware interfaces) and floating-point (for user\n+ * facing interfaces)\n+ *\n+ * It is intended to be used in shared context structures where both\n+ * hardware-level and software-level representations of a value are required.\n+ */\n+\n+/**\n+ * \\fn float Quantized::value() const noexcept\n+ * \\brief Get the floating-point representation of the quantized value\n+ *\n+ * This function returns the floating-point form that was either directly assigned\n+ * or computed from the quantized value.\n+ *\n+ * \\return The floating-point value\n+ */\n+\n+/**\n+ * \\fn T Quantized::quantized() const noexcept\n+ * \\brief Get the raw quantized representation of the value\n+ *\n+ * This function returns the internal quantized value (e.g. \\c uint8_t or \\c int16_t),\n+ * which is typically used for hardware-level programming or serialization.\n+ *\n+ * \\return The quantized value of type \\c T\n+ */\n+\n+/**\n+ * \\fn std::string Quantized::toString() const\n+ * \\brief Generate a string representation of the quantized and float values\n+ *\n+ * Produces a human-readable string including both the quantized and floating-point\n+ * values, typically in the format: \"Q:0xXX F:float\".\n+ *\n+ * \\return A formatted string representing the internal state\n+ */\n+\n+/**\n+ * \\fn bool Quantized::operator==(const Quantized<T> &other) const noexcept\n+ * \\brief Compare two quantized values for equality\n+ *\n+ * Two \\c Quantized<T> objects are equal if their quantized values are equal.\n+ *\n+ * \\param other The \\c Quantized<T> to compare with\n+ * \\return \\c true if equal, \\c false otherwise\n+ */\n+\n+/**\n+ * \\fn bool Quantized::operator!=(const Quantized<T> &other) const noexcept\n+ * \\brief Compare two quantized values for inequality\n+ *\n+ * Two \\c Quantized<T> objects are not equal if their quantized values differ.\n+ *\n+ * \\param other The \\c Quantized<T> to compare with\n+ * \\return \\c true if not equal, \\c false otherwise\n+ */\n+\n+/**\n+ * \\var Quantized::quantized_\n+ * \\brief The raw quantized value\n+ *\n+ * This member stores the fixed-point or integer representation of the value, typically\n+ * used for interfacing with hardware or protocols that require compact formats.\n+ *\n+ * It must only be updated or accessed through a Quantizer in conjunction with\n+ * corresponding updates to \\c Quantized::value_.\n+ */\n+\n+/**\n+ * \\var Quantized::value_\n+ * \\brief The floating-point representation of the quantized value\n+ *\n+ * This member holds the floating-point equivalent of the quantized value, usually\n+ * for use in calculations or presentation to higher-level software components.\n+ *\n+ * It must only be updated or accessed through a Quantizer in conjunction with\n+ * corresponding updates to \\c Quantized::quantized_.\n+ */\n+\n+/**\n+ * \\class Quantizer\n+ * \\brief Interface for converting between floating-point and quantized types\n+ * \\tparam T The quantized type (e.g., uint16_t, int16_t).\n+ *\n+ * This abstract class defines the interface for quantizers that handle\n+ * conversions between floating-point values and their quantized representations.\n+ * Specific quantization handlers should implement this interface and provide\n+ * the toFloat and fromFloat methods specifically for their types.\n+ */\n+\n+/**\n+ * \\typedef Quantizer::qType\n+ * \\brief The underlying quantized type used by the quantizer\n+ *\n+ * This alias exposes the quantized type (e.g. \\c uint8_t or \\c int16_t) used internally\n+ * by the \\c Quantizer, which is helpful in template and debug contexts.\n+ */\n+\n+/**\n+ * \\fn Quantizer::fromFloat(T val)\n+ * \\brief Convert a floating-point value to its quantized representation\n+ *\n+ * \\param val The floating-point value\n+ * \\return The quantized equivalent\n+ */\n+\n+/**\n+ * \\fn Quantizer::toFloat(T val)\n+ * \\brief Convert a quantized value to its floating-point representation\n+ *\n+ * \\param val The quantized value\n+ * \\return The floating-point equivalent\n+ */\n+\n+/**\n+ * \\fn Quantizer::set(float val)\n+ * \\brief Set the value of a Quantized<T> using a floating-point input\n+ *\n+ * This function updates both the quantized and floating-point\n+ * representations stored in the Quantized<T>, storing the quantized\n+ * version of the float input.\n+ *\n+ * \\param val The floating-point value to set\n+ */\n+\n+/**\n+ * \\fn Quantizer::set(T val)\n+ * \\brief Set the value of a Quantized<T> using a quantized input\n+ *\n+ * This function updates both the quantized and floating-point\n+ * representations stored in the Quantized<T>.\n+ *\n+ * \\param val The quantized value to set\n+ */\n+\n+} /* namespace ipa */\n+\n+} /* namespace libcamera */\ndiff --git a/src/ipa/libipa/quantized.h b/src/ipa/libipa/quantized.h\nnew file mode 100644\nindex 000000000000..1c1963cf0848\n--- /dev/null\n+++ b/src/ipa/libipa/quantized.h\n@@ -0,0 +1,90 @@\n+/* SPDX-License-Identifier: LGPL-2.1-or-later */\n+/*\n+ * Copyright (C) 2025, Ideas On Board.\n+ *\n+ * Helper class to manage conversions between floating point types and quantized\n+ * storage and representation of those values.\n+ */\n+\n+#pragma once\n+\n+#include <iomanip>\n+#include <sstream>\n+#include <stdint.h>\n+#include <type_traits>\n+\n+namespace libcamera {\n+\n+namespace ipa {\n+\n+template<typename Q>\n+class Quantizer;\n+\n+template<typename T>\n+struct Quantized {\n+\tstatic_assert(std::is_arithmetic_v<T>, \"Quantized: T must be an arithmetic type\");\n+\n+\tfloat value() const noexcept { return value_; }\n+\tT quantized() const noexcept { return quantized_; }\n+\n+\tstd::string toString() const\n+\t{\n+\t\tusing UT = std::make_unsigned_t<T>;\n+\t\tstd::ostringstream oss;\n+\n+\t\toss << \"Q:0x\" << std::hex << std::uppercase << std::setw(sizeof(T) * 2)\n+\t\t << std::setfill('0');\n+\n+\t\tif constexpr (std::is_unsigned_v<T>) {\n+\t\t\toss << static_cast<unsigned>(quantized_);\n+\t\t} else {\n+\t\t\toss << static_cast<unsigned>(static_cast<UT>(quantized_));\n+\t\t}\n+\n+\t\toss << \" F:\" << value_;\n+\n+\t\treturn oss.str();\n+\t}\n+\n+\tbool operator==(const Quantized<T> &other) const noexcept\n+\t{\n+\t\treturn quantized_ == other.quantized_ && value_ == other.value_;\n+\t}\n+\n+\tbool operator!=(const Quantized<T> &other) const noexcept\n+\t{\n+\t\treturn !(*this == other);\n+\t}\n+\n+protected:\n+\tT quantized_{};\n+\tfloat value_{};\n+};\n+\n+template<typename T>\n+class Quantizer : public Quantized<T>\n+{\n+public:\n+\tusing qType = T;\n+\n+\tvirtual ~Quantizer() = default;\n+\n+\tvirtual T fromFloat(float val) const = 0;\n+\tvirtual float toFloat(T val) const = 0;\n+\n+\tvoid set(float val)\n+\t{\n+\t\tthis->quantized_ = fromFloat(val);\n+\t\tthis->value_ = toFloat(this->quantized_);\n+\t}\n+\n+\tvoid set(T val)\n+\t{\n+\t\tthis->quantized_ = val;\n+\t\tthis->value_ = toFloat(val);\n+\t}\n+};\n+\n+} /* namespace ipa */\n+\n+} /* namespace libcamera */\n", "prefixes": [ "1/6" ] }