[{"id":36836,"web_url":"https://patchwork.libcamera.org/comment/36836/","msgid":"<74d0fd95-dfc2-45e3-bebd-61f8702cff14@ideasonboard.com>","date":"2025-11-14T18:08:53","subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2025. 11. 14. 1:54 keltezéssel, Kieran Bingham írta:\n> Extend the new Quantized FixedPoint capabilities with a ScaledFixedPointQTraits\n> which takes an existing Quantized type and scales the conversion by the\n> given Scale template parameter.\n> \n> This can be useful to represent fixed point values which represent\n> a linear range with a different scale to the underlying float\n> or integral type.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> \n> v3:\n> - Rename quantized_type to QuantizedType\n> \n> v4:\n> - Fix copydoc for ScaledFixedPointQTraits::toFloat\n> \n>   src/ipa/libipa/fixedpoint.cpp | 59 +++++++++++++++++++++++++++++++++++\n>   src/ipa/libipa/fixedpoint.h   | 24 ++++++++++++++\n>   2 files changed, 83 insertions(+)\n> \n> diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp\n> index 03053668ed79..97cdd9b3f7aa 100644\n> --- a/src/ipa/libipa/fixedpoint.cpp\n> +++ b/src/ipa/libipa/fixedpoint.cpp\n> @@ -185,6 +185,65 @@ namespace ipa {\n>    * Represents values in the range [0.0, 4095.9375] with a resolution of 1/16.\n>    */\n>   \n> +/**\n> + * \\struct ScaledFixedPointQTraits\n> + * \\brief Wrap a FixedPointQTraits with a linear scaling factor\n> + *\n> + * This trait extends an existing fixed-point quantisation policy\n> + * by applying an additional multiplicative scale between the\n> + * floating-point and quantised domains.\n> + *\n> + * \\tparam Q The base fixed-point traits type\n> + * \\tparam Scale The scale factor applied to the floating-point domain\n> + */\n> +\n> +/**\n> + * \\typedef ScaledFixedPointQTraits::QuantizedType\n> + * \\copydoc FixedPointQTraits::QuantizedType\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::scale\n> + * \\brief The constant scaling factor applied to the floating-point domain\n> + *\n> + * Floating-point inputs are divided by this factor before quantisation,\n> + * and multiplied by it after dequantisation.\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::qmin\n> + * \\copydoc FixedPointQTraits::qmin\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::qmax\n> + * \\copydoc FixedPointQTraits::qmax\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::min\n> + * \\copydoc FixedPointQTraits::min\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::max\n> + * \\copydoc FixedPointQTraits::max\n> + */\n> +\n> +/**\n> + * \\fn ScaledFixedPointQTraits::fromFloat(float v)\n> + * \\copydoc FixedPointQTraits::fromFloat(float v)\n> + *\n> + * The input value \\a v is divided by the scaling factor before conversion.\n> + */\n> +\n> +/**\n> + * \\fn ScaledFixedPointQTraits::toFloat(QuantizedType q)\n> + * \\copydoc FixedPointQTraits::toFloat()\n> + *\n> + * The output value is multiplied by the scaling factor after conversion.\n> + */\n> +\n>   } /* namespace ipa */\n>   \n>   } /* namespace libcamera */\n> diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h\n> index 05dd97e64f40..1e984350111c 100644\n> --- a/src/ipa/libipa/fixedpoint.h\n> +++ b/src/ipa/libipa/fixedpoint.h\n> @@ -113,6 +113,30 @@ using UQ5_8 = Quantized<FixedPointQTraits<5, 8, uint16_t>>;\n>   using Q12_4 = Quantized<FixedPointQTraits<12, 4, int16_t>>;\n>   using UQ12_4 = Quantized<FixedPointQTraits<12, 4, uint16_t>>;\n>   \n> +template<typename Q, int Scale>\n> +struct ScaledFixedPointQTraits {\n\nI believe we could name it just \"ScaledQTraits\" since there is nothing here\nthat inherently depends on `FixedQTraits`\n\n\n> +\tusing QuantizedType = typename Q::QuantizedType;\n> +\n> +\tstatic constexpr float scale = static_cast<float>(Scale);\n\nI would add `static_assert(Scale > 0)`. But otherwise it looks good to me.\nHaving a float as a template parameter is sadly a C++20 feature.\n\nReviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\n\n> +\n> +\t/* Re-expose base limits, adjusted by the scaling factor */\n> +\tstatic constexpr QuantizedType qmin = Q::qmin;\n> +\tstatic constexpr QuantizedType qmax = Q::qmax;\n> +\tstatic constexpr float min = Q::min * scale;\n> +\tstatic constexpr float max = Q::max * scale;\n> +\n> +\tstatic QuantizedType fromFloat(float v)\n> +\t{\n> +\t\tv = std::clamp(v, min, max);\n> +\t\treturn Q::fromFloat(v / scale);\n> +\t}\n> +\n> +\tstatic float toFloat(QuantizedType q)\n> +\t{\n> +\t\treturn Q::toFloat(q) * scale;\n> +\t}\n> +};\n> +\n>   } /* namespace ipa */\n>   \n>   } /* namespace libcamera */","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 D717FC3263\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Nov 2025 18:08:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8AE65609DE;\n\tFri, 14 Nov 2025 19:08: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 13517606E6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Nov 2025 19:08:56 +0100 (CET)","from [192.168.33.35] (185.221.143.100.nat.pool.zt.hu\n\t[185.221.143.100])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 18EC5397;\n\tFri, 14 Nov 2025 19:06:55 +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=\"tvKK51lp\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763143615;\n\tbh=h76LPxWC6baFyovYnzkCAAISf0rI12KZWa7BDYEeytk=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=tvKK51lpIU+MKp7IIDtDwskk8m170UyhpSne8IDm0q9bBK1y92xgByXaqpkPndWis\n\tLuKGoZakSspU7piCtXMYB6zUH7rwaGF1Oufa78TZ7d/LNv0gcXoGbeInppkbdH5M5J\n\t8wxRfTxbwsrsUOz+lVvW7HPNKruwfzHuiXJ2PbAI=","Message-ID":"<74d0fd95-dfc2-45e3-bebd-61f8702cff14@ideasonboard.com>","Date":"Fri, 14 Nov 2025 19:08:53 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-11-kieran.bingham@ideasonboard.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20251114005428.90024-11-kieran.bingham@ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","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>"}},{"id":36840,"web_url":"https://patchwork.libcamera.org/comment/36840/","msgid":"<176314635136.567526.3388338953189504735@ping.linuxembedded.co.uk>","date":"2025-11-14T18:52:31","subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2025-11-14 18:08:53)\n> 2025. 11. 14. 1:54 keltezéssel, Kieran Bingham írta:\n> > Extend the new Quantized FixedPoint capabilities with a ScaledFixedPointQTraits\n> > which takes an existing Quantized type and scales the conversion by the\n> > given Scale template parameter.\n> > \n> > This can be useful to represent fixed point values which represent\n> > a linear range with a different scale to the underlying float\n> > or integral type.\n> > \n> > Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > \n> > ---\n> > \n> > v3:\n> > - Rename quantized_type to QuantizedType\n> > \n> > v4:\n> > - Fix copydoc for ScaledFixedPointQTraits::toFloat\n> > \n> >   src/ipa/libipa/fixedpoint.cpp | 59 +++++++++++++++++++++++++++++++++++\n> >   src/ipa/libipa/fixedpoint.h   | 24 ++++++++++++++\n> >   2 files changed, 83 insertions(+)\n> > \n> > diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp\n> > index 03053668ed79..97cdd9b3f7aa 100644\n> > --- a/src/ipa/libipa/fixedpoint.cpp\n> > +++ b/src/ipa/libipa/fixedpoint.cpp\n> > @@ -185,6 +185,65 @@ namespace ipa {\n> >    * Represents values in the range [0.0, 4095.9375] with a resolution of 1/16.\n> >    */\n> >   \n> > +/**\n> > + * \\struct ScaledFixedPointQTraits\n> > + * \\brief Wrap a FixedPointQTraits with a linear scaling factor\n> > + *\n> > + * This trait extends an existing fixed-point quantisation policy\n> > + * by applying an additional multiplicative scale between the\n> > + * floating-point and quantised domains.\n> > + *\n> > + * \\tparam Q The base fixed-point traits type\n> > + * \\tparam Scale The scale factor applied to the floating-point domain\n> > + */\n> > +\n> > +/**\n> > + * \\typedef ScaledFixedPointQTraits::QuantizedType\n> > + * \\copydoc FixedPointQTraits::QuantizedType\n> > + */\n> > +\n> > +/**\n> > + * \\var ScaledFixedPointQTraits::scale\n> > + * \\brief The constant scaling factor applied to the floating-point domain\n> > + *\n> > + * Floating-point inputs are divided by this factor before quantisation,\n> > + * and multiplied by it after dequantisation.\n> > + */\n> > +\n> > +/**\n> > + * \\var ScaledFixedPointQTraits::qmin\n> > + * \\copydoc FixedPointQTraits::qmin\n> > + */\n> > +\n> > +/**\n> > + * \\var ScaledFixedPointQTraits::qmax\n> > + * \\copydoc FixedPointQTraits::qmax\n> > + */\n> > +\n> > +/**\n> > + * \\var ScaledFixedPointQTraits::min\n> > + * \\copydoc FixedPointQTraits::min\n> > + */\n> > +\n> > +/**\n> > + * \\var ScaledFixedPointQTraits::max\n> > + * \\copydoc FixedPointQTraits::max\n> > + */\n> > +\n> > +/**\n> > + * \\fn ScaledFixedPointQTraits::fromFloat(float v)\n> > + * \\copydoc FixedPointQTraits::fromFloat(float v)\n> > + *\n> > + * The input value \\a v is divided by the scaling factor before conversion.\n> > + */\n> > +\n> > +/**\n> > + * \\fn ScaledFixedPointQTraits::toFloat(QuantizedType q)\n> > + * \\copydoc FixedPointQTraits::toFloat()\n> > + *\n> > + * The output value is multiplied by the scaling factor after conversion.\n> > + */\n> > +\n> >   } /* namespace ipa */\n> >   \n> >   } /* namespace libcamera */\n> > diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h\n> > index 05dd97e64f40..1e984350111c 100644\n> > --- a/src/ipa/libipa/fixedpoint.h\n> > +++ b/src/ipa/libipa/fixedpoint.h\n> > @@ -113,6 +113,30 @@ using UQ5_8 = Quantized<FixedPointQTraits<5, 8, uint16_t>>;\n> >   using Q12_4 = Quantized<FixedPointQTraits<12, 4, int16_t>>;\n> >   using UQ12_4 = Quantized<FixedPointQTraits<12, 4, uint16_t>>;\n> >   \n> > +template<typename Q, int Scale>\n> > +struct ScaledFixedPointQTraits {\n> \n> I believe we could name it just \"ScaledQTraits\" since there is nothing here\n> that inherently depends on `FixedQTraits`\n\nGood point.\n\n> > +     using QuantizedType = typename Q::QuantizedType;\n> > +\n> > +     static constexpr float scale = static_cast<float>(Scale);\n> \n> I would add `static_assert(Scale > 0)`. But otherwise it looks good to me.\n> Having a float as a template parameter is sadly a C++20 feature.\n\nIndeed, I think I started as an int and hit the compile failures.\n\nI wonder when we will move to C++20 then ;-)\n\n> \n> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\nThanks\n\n\n> \n> \n> > +\n> > +     /* Re-expose base limits, adjusted by the scaling factor */\n> > +     static constexpr QuantizedType qmin = Q::qmin;\n> > +     static constexpr QuantizedType qmax = Q::qmax;\n> > +     static constexpr float min = Q::min * scale;\n> > +     static constexpr float max = Q::max * scale;\n> > +\n> > +     static QuantizedType fromFloat(float v)\n> > +     {\n> > +             v = std::clamp(v, min, max);\n> > +             return Q::fromFloat(v / scale);\n> > +     }\n> > +\n> > +     static float toFloat(QuantizedType q)\n> > +     {\n> > +             return Q::toFloat(q) * scale;\n> > +     }\n> > +};\n> > +\n> >   } /* namespace ipa */\n> >   \n> >   } /* namespace libcamera */\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 D9AE0C3241\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Nov 2025 18:52:36 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8B8F2606E6;\n\tFri, 14 Nov 2025 19:52:36 +0100 (CET)","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 873FD606E6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Nov 2025 19:52:34 +0100 (CET)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 88E75161;\n\tFri, 14 Nov 2025 19:50:33 +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=\"FSyLKh9P\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763146233;\n\tbh=Bng3NzZgoMT5XjlexuA4m1/edk+0t+1HcxXzWauHA0I=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=FSyLKh9P5av/EKfPEQ0V5gxwcLmpPIzt2R+jVAF08UX4AurEZMs9SI6mbcaSuFuu7\n\tiJw6PmJXmwez0rHiPXHlsNEmBkgVbIhEw1zcLq/YFiljJL0ILsJgfXu7dsAFaD3OZy\n\tQChtnbzXdraunPzS8mjb2h8/Z0buUXiiYkTUbzh8=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<74d0fd95-dfc2-45e3-bebd-61f8702cff14@ideasonboard.com>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-11-kieran.bingham@ideasonboard.com>\n\t<74d0fd95-dfc2-45e3-bebd-61f8702cff14@ideasonboard.com>","Subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Fri, 14 Nov 2025 18:52:31 +0000","Message-ID":"<176314635136.567526.3388338953189504735@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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>"}},{"id":36876,"web_url":"https://patchwork.libcamera.org/comment/36876/","msgid":"<176346958953.880260.9141645887336151413@isaac-ThinkPad-T16-Gen-2>","date":"2025-11-18T12:39:49","subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","submitter":{"id":215,"url":"https://patchwork.libcamera.org/api/people/215/","name":"Isaac Scott","email":"isaac.scott@ideasonboard.com"},"content":"Hi Kieran,\n\nThank you for the patch!\n\nReviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>\n\nQuoting Kieran Bingham (2025-11-14 00:54:14)\n> Extend the new Quantized FixedPoint capabilities with a ScaledFixedPointQTraits\n> which takes an existing Quantized type and scales the conversion by the\n> given Scale template parameter.\n> \n> This can be useful to represent fixed point values which represent\n> a linear range with a different scale to the underlying float\n> or integral type.\n> \n> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> \n> ---\n> \n> v3:\n> - Rename quantized_type to QuantizedType\n> \n> v4:\n> - Fix copydoc for ScaledFixedPointQTraits::toFloat\n> \n>  src/ipa/libipa/fixedpoint.cpp | 59 +++++++++++++++++++++++++++++++++++\n>  src/ipa/libipa/fixedpoint.h   | 24 ++++++++++++++\n>  2 files changed, 83 insertions(+)\n> \n> diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp\n> index 03053668ed79..97cdd9b3f7aa 100644\n> --- a/src/ipa/libipa/fixedpoint.cpp\n> +++ b/src/ipa/libipa/fixedpoint.cpp\n> @@ -185,6 +185,65 @@ namespace ipa {\n>   * Represents values in the range [0.0, 4095.9375] with a resolution of 1/16.\n>   */\n>  \n> +/**\n> + * \\struct ScaledFixedPointQTraits\n> + * \\brief Wrap a FixedPointQTraits with a linear scaling factor\n> + *\n> + * This trait extends an existing fixed-point quantisation policy\n> + * by applying an additional multiplicative scale between the\n> + * floating-point and quantised domains.\n> + *\n> + * \\tparam Q The base fixed-point traits type\n> + * \\tparam Scale The scale factor applied to the floating-point domain\n> + */\n> +\n> +/**\n> + * \\typedef ScaledFixedPointQTraits::QuantizedType\n> + * \\copydoc FixedPointQTraits::QuantizedType\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::scale\n> + * \\brief The constant scaling factor applied to the floating-point domain\n> + *\n> + * Floating-point inputs are divided by this factor before quantisation,\n> + * and multiplied by it after dequantisation.\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::qmin\n> + * \\copydoc FixedPointQTraits::qmin\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::qmax\n> + * \\copydoc FixedPointQTraits::qmax\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::min\n> + * \\copydoc FixedPointQTraits::min\n> + */\n> +\n> +/**\n> + * \\var ScaledFixedPointQTraits::max\n> + * \\copydoc FixedPointQTraits::max\n> + */\n> +\n> +/**\n> + * \\fn ScaledFixedPointQTraits::fromFloat(float v)\n> + * \\copydoc FixedPointQTraits::fromFloat(float v)\n> + *\n> + * The input value \\a v is divided by the scaling factor before conversion.\n> + */\n> +\n> +/**\n> + * \\fn ScaledFixedPointQTraits::toFloat(QuantizedType q)\n> + * \\copydoc FixedPointQTraits::toFloat()\n> + *\n> + * The output value is multiplied by the scaling factor after conversion.\n> + */\n> +\n>  } /* namespace ipa */\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h\n> index 05dd97e64f40..1e984350111c 100644\n> --- a/src/ipa/libipa/fixedpoint.h\n> +++ b/src/ipa/libipa/fixedpoint.h\n> @@ -113,6 +113,30 @@ using UQ5_8 = Quantized<FixedPointQTraits<5, 8, uint16_t>>;\n>  using Q12_4 = Quantized<FixedPointQTraits<12, 4, int16_t>>;\n>  using UQ12_4 = Quantized<FixedPointQTraits<12, 4, uint16_t>>;\n>  \n> +template<typename Q, int Scale>\n> +struct ScaledFixedPointQTraits {\n> +       using QuantizedType = typename Q::QuantizedType;\n> +\n> +       static constexpr float scale = static_cast<float>(Scale);\n> +\n> +       /* Re-expose base limits, adjusted by the scaling factor */\n> +       static constexpr QuantizedType qmin = Q::qmin;\n> +       static constexpr QuantizedType qmax = Q::qmax;\n> +       static constexpr float min = Q::min * scale;\n> +       static constexpr float max = Q::max * scale;\n> +\n> +       static QuantizedType fromFloat(float v)\n> +       {\n> +               v = std::clamp(v, min, max);\n> +               return Q::fromFloat(v / scale);\n> +       }\n> +\n> +       static float toFloat(QuantizedType q)\n> +       {\n> +               return Q::toFloat(q) * scale;\n> +       }\n> +};\n> +\n>  } /* namespace ipa */\n>  \n>  } /* namespace libcamera */\n> -- \n> 2.51.1\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 79F24BD80A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 18 Nov 2025 12:39:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1AEC860A86;\n\tTue, 18 Nov 2025 13:39:54 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 63D52606D5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 18 Nov 2025 13:39:52 +0100 (CET)","from thinkpad.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id A1381D52;\n\tTue, 18 Nov 2025 13:37:48 +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=\"VKoCVgtv\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1763469468;\n\tbh=AmCqglu5HaQag5XxMhQRwUcNWEfRtRMgLfFatVGM/rs=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=VKoCVgtvDHY87y6pxDhDGtC+uRhEyw9LCC9owi+xNF6ehdT8H/o9cyEzOMe6utScR\n\thOkIbmwh9qrxw47ilYZbC7AinQFkBOBnOELifUNTQMxGn7gxeJhK449VJOjSdqsp28\n\tMaI5MvzLF3kc0jNpLIPRMMHK7WggYRcGplINBdrA=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20251114005428.90024-11-kieran.bingham@ideasonboard.com>","References":"<20251114005428.90024-1-kieran.bingham@ideasonboard.com>\n\t<20251114005428.90024-11-kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v4 10/21] ipa: libipa: fixedpoint: Provide a\n\tScaledFixedPoint type","From":"Isaac Scott <isaac.scott@ideasonboard.com>","Cc":"Kieran Bingham <kieran.bingham@ideasonboard.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>,\n\tlibcamera devel <libcamera-devel@lists.libcamera.org>","Date":"Tue, 18 Nov 2025 12:39:49 +0000","Message-ID":"<176346958953.880260.9141645887336151413@isaac-ThinkPad-T16-Gen-2>","User-Agent":"alot/0.10","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>"}}]