[{"id":39684,"web_url":"https://patchwork.libcamera.org/comment/39684/","msgid":"<178395426958.3603632.11518373547679826535@localhost>","date":"2026-07-13T14:51:09","subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"content":"Hi Jacopo,\n\nQuoting Jacopo Mondi (2026-07-08 17:51:06)\n> The LscPolynomial::sampleForCrop() function is designed to receive a\n> list of segment sizes and translates it to a list of grid vertexes\n> internally with the sizesListToPositions() function.\n> \n> As the sizesListToPositions() implementation is RkISP1-specific, move it\n> back to the RkISP1 IPA and change the prototype of the sampleForCrop()\n> function to accept a vector of grid vertexes instead of a span of\n> segment sizes.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n\nLooks good to me.\n\nReviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\nBest regards,\nStefan\n\n> ---\n>  src/ipa/libipa/lsc_base.cpp       |  6 +++---\n>  src/ipa/libipa/lsc_base.h         |  3 +--\n>  src/ipa/libipa/lsc_polynomial.cpp | 38 ++++----------------------------------\n>  src/ipa/libipa/lsc_polynomial.h   |  4 +---\n>  src/ipa/libipa/lsc_table.h        |  4 ++--\n>  src/ipa/rkisp1/algorithms/lsc.cpp | 32 +++++++++++++++++++++++++++++++-\n>  src/ipa/rkisp1/algorithms/lsc.h   |  3 +++\n>  7 files changed, 45 insertions(+), 45 deletions(-)\n> \n> diff --git a/src/ipa/libipa/lsc_base.cpp b/src/ipa/libipa/lsc_base.cpp\n> index 678ba8a9a808..cc691e17a694 100644\n> --- a/src/ipa/libipa/lsc_base.cpp\n> +++ b/src/ipa/libipa/lsc_base.cpp\n> @@ -88,8 +88,8 @@ void Interpolator<lsc::Components>::\n>   * \\fn LscImplementation::sampleForCrop\n>   * \\brief Re-sample the LSC components for \\a cropRectangle\n>   * \\param[in] cropRectangle The sensor analogue crop rectangle\n> - * \\param[in] xSizes List of horizontal positions of the LSC grid nodes\n> - * \\param[in] ySizes List of vertical positions of the LSC grid nodes\n> + * \\param[in] xPos List of horizontal positions of the LSC grid nodes\n> + * \\param[in] yPos List of vertical positions of the LSC grid nodes\n>   *\n>   * LSC tables have to be re-sampled every time a new sensor configuration is\n>   * used, as each streaming session might use a different sensor crop rectangle\n> @@ -98,7 +98,7 @@ void Interpolator<lsc::Components>::\n>   * \\a cropRectangle represents the size of the frame on which the LSC tables\n>   * have to be re-sampled on.\n>   *\n> - * \\a xSizes and \\a ySizes represent the position of the grid nodes vertexes in\n> + * \\a xPos and \\a yPos represent the position of the grid nodes vertexes in\n>   * the [0, 1] interval. In example an equally spaced grid of 16 nodes will have\n>   * each segment of size 0.0625 and the list of nodes position will be\n>   * [0, 0.0625, 0.125, 0.1875, ... , 1]. It is expected that the first position\n> diff --git a/src/ipa/libipa/lsc_base.h b/src/ipa/libipa/lsc_base.h\n> index 51cc35888209..8d1843a5d4fd 100644\n> --- a/src/ipa/libipa/lsc_base.h\n> +++ b/src/ipa/libipa/lsc_base.h\n> @@ -65,8 +65,7 @@ public:\n>  \n>         virtual lsc::ComponentsMap\n>         sampleForCrop(const Rectangle &cropRectangle,\n> -                     Span<const double> xSizes,\n> -                     Span<const double> ySizes) = 0;\n> +                     std::vector<double> xPos, std::vector<double> yPos);\n>  };\n>  \n>  } /* namespace ipa */\n> diff --git a/src/ipa/libipa/lsc_polynomial.cpp b/src/ipa/libipa/lsc_polynomial.cpp\n> index f095a5a92024..682e2f14fe09 100644\n> --- a/src/ipa/libipa/lsc_polynomial.cpp\n> +++ b/src/ipa/libipa/lsc_polynomial.cpp\n> @@ -184,8 +184,8 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n>  /**\n>   * \\brief Re-sample the LSC components for \\a cropRectangle\n>   * \\param[in] cropRectangle The sensor analogue crop rectangle\n> - * \\param[in] xSizes List of horizontal positions of the LSc grid nodes\n> - * \\param[in] ySizes List of vertical positions of the LSC grid nodes\n> + * \\param[in] xPos List of horizontal positions of the LSC grid nodes\n> + * \\param[in] yPos List of vertical positions of the LSC grid nodes\n>   *\n>   * LSC tables have to be re-sampled every time a new sensor configuration is\n>   * used, as each streaming session might use a different sensor crop rectangle.\n> @@ -197,7 +197,7 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n>   * \\a cropRectangle represents the size of the frame on which the LSC tables\n>   * have to be re-sampled on.\n>   *\n> - * \\a xSizes and \\a ySizes represent the position of the grid nodes vertexes in\n> + * \\a xPos and \\a yPos represent the position of the grid nodes vertexes in\n>   * the [0, 1] interval. In example an equally spaced grid of 16 nodes will have\n>   * each segment of size 0.0625 and the list of nodes position will be\n>   * [0, 0.0625, 0.125, 0.1875, ... , 1]. It is expected that the first position\n> @@ -205,11 +205,8 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n>   */\n>  lsc::ComponentsMap\n>  LscPolynomial::sampleForCrop(const Rectangle &cropRectangle,\n> -                            Span<const double> xSizes,\n> -                            Span<const double> ySizes)\n> +                            std::vector<double> xPos, std::vector<double> yPos)\n>  {\n> -       std::vector<double> xPos = sizesListToPositions(xSizes);\n> -       std::vector<double> yPos = sizesListToPositions(ySizes);\n>  \n>         lsc::ComponentsMap components;\n>  \n> @@ -259,33 +256,6 @@ LscPolynomial::samplePolynomial(const lsc::Polynomial &poly,\n>         return samples;\n>  }\n>  \n> -/*\n> - * The rkisp1 LSC grid spacing is defined by the cell sizes on the top-left\n> - * quadrant of the grid. This is then mirrored in hardware to the other\n> - * quadrants. See parseSizes() for further details. For easier handling, this\n> - * function converts the cell sizes of half the grid to a list of position of\n> - * the whole grid (on one axis). Example:\n> - *\n> - * input:   | 0.2 | 0.3 |\n> - * output: 0.0   0.2   0.5   0.8   1.0\n> - */\n> -std::vector<double>\n> -LscPolynomial::sizesListToPositions(Span<const double> sizes)\n> -{\n> -       const int half = sizes.size();\n> -       std::vector<double> positions(half * 2 + 1);\n> -       double x = 0.0;\n> -\n> -       positions[half] = 0.5;\n> -       for (int i = 1; i <= half; i++) {\n> -               x += sizes[half - i];\n> -               positions[half - i] = 0.5 - x;\n> -               positions[half + i] = 0.5 + x;\n> -       }\n> -\n> -       return positions;\n> -}\n> -\n>  } /* namespace ipa */\n>  \n>  #ifndef __DOXYGEN__\n> diff --git a/src/ipa/libipa/lsc_polynomial.h b/src/ipa/libipa/lsc_polynomial.h\n> index 17c2c34499f0..d2276ecc6f6b 100644\n> --- a/src/ipa/libipa/lsc_polynomial.h\n> +++ b/src/ipa/libipa/lsc_polynomial.h\n> @@ -71,11 +71,9 @@ public:\n>  \n>         lsc::ComponentsMap\n>         sampleForCrop(const Rectangle &cropRectangle,\n> -                     Span<const double> xSizes,\n> -                     Span<const double> ySizes) override;\n> +                     std::vector<double> xPos, std::vector<double> yPos) override;\n>  \n>  private:\n> -       std::vector<double> sizesListToPositions(Span<const double> sizes);\n>         std::vector<uint16_t> samplePolynomial(const lsc::Polynomial &poly,\n>                                                Span<const double> xPositions,\n>                                                Span<const double> yPositions,\n> diff --git a/src/ipa/libipa/lsc_table.h b/src/ipa/libipa/lsc_table.h\n> index 0983b78c3f6b..67c7464ea5b6 100644\n> --- a/src/ipa/libipa/lsc_table.h\n> +++ b/src/ipa/libipa/lsc_table.h\n> @@ -30,8 +30,8 @@ public:\n>  \n>         lsc::ComponentsMap\n>         sampleForCrop([[maybe_unused]] const Rectangle &cropRectangle,\n> -                     [[maybe_unused]] Span<const double> xSizes,\n> -                     [[maybe_unused]] Span<const double> ySizes) override\n> +                     [[maybe_unused]] std::vector<double> xPos,\n> +                     [[maybe_unused]] std::vector<double> yPos) override\n>         {\n>                 LOG(LscTable, Warning)\n>                         << \"Tabular LSC data doesn't support resampling\";\n> diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\n> index e03bf361c4b9..7010c97db22e 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.cpp\n> +++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n> @@ -70,6 +70,9 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,\n>         if (xSize_.empty() || ySize_.empty())\n>                 return -EINVAL;\n>  \n> +       xPos_ = sizesListToPositions(xSize_);\n> +       yPos_ = sizesListToPositions(ySize_);\n> +\n>         /* Get all defined sets to apply. */\n>         const ValueNode &sets = tuningData[\"sets\"];\n>         if (!sets.isList()) {\n> @@ -138,6 +141,33 @@ std::vector<double> LensShadingCorrection::parseSizes(const ValueNode &tuningDat\n>         return sizes;\n>  }\n>  \n> +/*\n> + * The rkisp1 LSC grid spacing is defined by the cell sizes on the top-left\n> + * quadrant of the grid. This is then mirrored in hardware to the other\n> + * quadrants. See parseSizes() for further details. For easier handling, this\n> + * function converts the cell sizes of half the grid to a list of position of\n> + * the whole grid (on one axis). Example:\n> + *\n> + * input:   | 0.2 | 0.3 |\n> + * output: 0.0   0.2   0.5   0.8   1.0\n> + */\n> +std::vector<double>\n> +LensShadingCorrection::sizesListToPositions(Span<const double> sizes)\n> +{\n> +       const int half = sizes.size();\n> +       std::vector<double> positions(half * 2 + 1);\n> +       double x = 0.0;\n> +\n> +       positions[half] = 0.5;\n> +       for (int i = 1; i <= half; i++) {\n> +               x += sizes[half - i];\n> +               positions[half - i] = 0.5 - x;\n> +               positions[half + i] = 0.5 + x;\n> +       }\n> +\n> +       return positions;\n> +}\n> +\n>  /**\n>   * \\copydoc libcamera::ipa::Algorithm::configure\n>   */\n> @@ -171,7 +201,7 @@ int LensShadingCorrection::configure(IPAContext &context,\n>  \n>         LOG(RkISP1Lsc, Debug) << \"Sample LSC data for \" << configInfo.analogCrop;\n>         lsc::ComponentsMap shadingData = algo_->sampleForCrop(configInfo.analogCrop,\n> -                                                             xSize_, ySize_);\n> +                                                             xPos_, yPos_);\n>         sets_.setData(std::move(shadingData));\n>  \n>         context.activeState.lsc.enabled = true;\n> diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h\n> index ee037353bbe4..06aa7a5f133c 100644\n> --- a/src/ipa/rkisp1/algorithms/lsc.h\n> +++ b/src/ipa/rkisp1/algorithms/lsc.h\n> @@ -41,9 +41,12 @@ private:\n>         void copyTable(rkisp1_cif_isp_lsc_config &config, const lsc::Components &set0);\n>         std::vector<double> parseSizes(const ValueNode &tuningData,\n>                                        const char *prop);\n> +       std::vector<double> sizesListToPositions(Span<const double> sizes);\n>  \n>         std::vector<double> xSize_;\n>         std::vector<double> ySize_;\n> +       std::vector<double> xPos_;\n> +       std::vector<double> yPos_;\n>         uint16_t xGrad_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n>         uint16_t yGrad_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n>         uint16_t xSizes_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n> \n> -- \n> 2.54.0\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 C8EA0C32CE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 13 Jul 2026 14:51:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C68FD66125;\n\tMon, 13 Jul 2026 16:51:14 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 72E366604D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 13 Jul 2026 16:51:12 +0200 (CEST)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:6c1f:355d:1c19:aba6])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D08001049;\n\tMon, 13 Jul 2026 16:50:18 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"uyczNv45\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1783954218;\n\tbh=509K7PPPB0TgRFk/L0HBN/mpgd2drJlHlOOSAPIARls=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=uyczNv45V1Clr2cqOGeTPaSB/9ITwwvnoiQfozdKcCSuTBYsou+pZrq1WSW5O6Oed\n\t1gYTFdc+BmIe0Q3X+fm+Vbir6g0ka9sa8pgQwk0Nwxnh9XF1pr0BWHZqr2i+UKKkLS\n\tdAyUWcL67nwcp1AD4ec/veymd0jqW957SscRPd7Y=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260708-libipa-algorithms-v5-24-0759d0359f52@ideasonboard.com>","References":"<20260708-libipa-algorithms-v5-0-0759d0359f52@ideasonboard.com>\n\t<20260708-libipa-algorithms-v5-24-0759d0359f52@ideasonboard.com>","Subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","From":"Stefan Klug <stefan.klug@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 13 Jul 2026 16:51:09 +0200","Message-ID":"<178395426958.3603632.11518373547679826535@localhost>","User-Agent":"alot/0.12.dev43+g2cacc0d03","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":39700,"web_url":"https://patchwork.libcamera.org/comment/39700/","msgid":"<178404922669.3931061.18413397520993879260@ping.linuxembedded.co.uk>","date":"2026-07-14T17:13:46","subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Stefan Klug (2026-07-13 15:51:09)\n> Hi Jacopo,\n> \n> Quoting Jacopo Mondi (2026-07-08 17:51:06)\n> > The LscPolynomial::sampleForCrop() function is designed to receive a\n> > list of segment sizes and translates it to a list of grid vertexes\n> > internally with the sizesListToPositions() function.\n> > \n> > As the sizesListToPositions() implementation is RkISP1-specific, move it\n> > back to the RkISP1 IPA and change the prototype of the sampleForCrop()\n> > function to accept a vector of grid vertexes instead of a span of\n> > segment sizes.\n> > \n> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> \n> Looks good to me.\n> \n> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> \n> Best regards,\n> Stefan\n> \n> > ---\n> >  src/ipa/libipa/lsc_base.cpp       |  6 +++---\n> >  src/ipa/libipa/lsc_base.h         |  3 +--\n> >  src/ipa/libipa/lsc_polynomial.cpp | 38 ++++----------------------------------\n> >  src/ipa/libipa/lsc_polynomial.h   |  4 +---\n> >  src/ipa/libipa/lsc_table.h        |  4 ++--\n> >  src/ipa/rkisp1/algorithms/lsc.cpp | 32 +++++++++++++++++++++++++++++++-\n> >  src/ipa/rkisp1/algorithms/lsc.h   |  3 +++\n> >  7 files changed, 45 insertions(+), 45 deletions(-)\n> > \n> > diff --git a/src/ipa/libipa/lsc_base.cpp b/src/ipa/libipa/lsc_base.cpp\n> > index 678ba8a9a808..cc691e17a694 100644\n> > --- a/src/ipa/libipa/lsc_base.cpp\n> > +++ b/src/ipa/libipa/lsc_base.cpp\n> > @@ -88,8 +88,8 @@ void Interpolator<lsc::Components>::\n> >   * \\fn LscImplementation::sampleForCrop\n> >   * \\brief Re-sample the LSC components for \\a cropRectangle\n> >   * \\param[in] cropRectangle The sensor analogue crop rectangle\n> > - * \\param[in] xSizes List of horizontal positions of the LSC grid nodes\n> > - * \\param[in] ySizes List of vertical positions of the LSC grid nodes\n> > + * \\param[in] xPos List of horizontal positions of the LSC grid nodes\n> > + * \\param[in] yPos List of vertical positions of the LSC grid nodes\n> >   *\n> >   * LSC tables have to be re-sampled every time a new sensor configuration is\n> >   * used, as each streaming session might use a different sensor crop rectangle\n> > @@ -98,7 +98,7 @@ void Interpolator<lsc::Components>::\n> >   * \\a cropRectangle represents the size of the frame on which the LSC tables\n> >   * have to be re-sampled on.\n> >   *\n> > - * \\a xSizes and \\a ySizes represent the position of the grid nodes vertexes in\n> > + * \\a xPos and \\a yPos represent the position of the grid nodes vertexes in\n> >   * the [0, 1] interval. In example an equally spaced grid of 16 nodes will have\n> >   * each segment of size 0.0625 and the list of nodes position will be\n> >   * [0, 0.0625, 0.125, 0.1875, ... , 1]. It is expected that the first position\n> > diff --git a/src/ipa/libipa/lsc_base.h b/src/ipa/libipa/lsc_base.h\n> > index 51cc35888209..8d1843a5d4fd 100644\n> > --- a/src/ipa/libipa/lsc_base.h\n> > +++ b/src/ipa/libipa/lsc_base.h\n> > @@ -65,8 +65,7 @@ public:\n> >  \n> >         virtual lsc::ComponentsMap\n> >         sampleForCrop(const Rectangle &cropRectangle,\n> > -                     Span<const double> xSizes,\n> > -                     Span<const double> ySizes) = 0;\n> > +                     std::vector<double> xPos, std::vector<double> yPos);\n> >  };\n> >  \n> >  } /* namespace ipa */\n> > diff --git a/src/ipa/libipa/lsc_polynomial.cpp b/src/ipa/libipa/lsc_polynomial.cpp\n> > index f095a5a92024..682e2f14fe09 100644\n> > --- a/src/ipa/libipa/lsc_polynomial.cpp\n> > +++ b/src/ipa/libipa/lsc_polynomial.cpp\n> > @@ -184,8 +184,8 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n> >  /**\n> >   * \\brief Re-sample the LSC components for \\a cropRectangle\n> >   * \\param[in] cropRectangle The sensor analogue crop rectangle\n> > - * \\param[in] xSizes List of horizontal positions of the LSc grid nodes\n> > - * \\param[in] ySizes List of vertical positions of the LSC grid nodes\n> > + * \\param[in] xPos List of horizontal positions of the LSC grid nodes\n> > + * \\param[in] yPos List of vertical positions of the LSC grid nodes\n> >   *\n> >   * LSC tables have to be re-sampled every time a new sensor configuration is\n> >   * used, as each streaming session might use a different sensor crop rectangle.\n> > @@ -197,7 +197,7 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n> >   * \\a cropRectangle represents the size of the frame on which the LSC tables\n> >   * have to be re-sampled on.\n> >   *\n> > - * \\a xSizes and \\a ySizes represent the position of the grid nodes vertexes in\n> > + * \\a xPos and \\a yPos represent the position of the grid nodes vertexes in\n> >   * the [0, 1] interval. In example an equally spaced grid of 16 nodes will have\n> >   * each segment of size 0.0625 and the list of nodes position will be\n> >   * [0, 0.0625, 0.125, 0.1875, ... , 1]. It is expected that the first position\n> > @@ -205,11 +205,8 @@ int LscPolynomial::parseLscData(const ValueNode &sets)\n> >   */\n> >  lsc::ComponentsMap\n> >  LscPolynomial::sampleForCrop(const Rectangle &cropRectangle,\n> > -                            Span<const double> xSizes,\n> > -                            Span<const double> ySizes)\n> > +                            std::vector<double> xPos, std::vector<double> yPos)\n> >  {\n> > -       std::vector<double> xPos = sizesListToPositions(xSizes);\n> > -       std::vector<double> yPos = sizesListToPositions(ySizes);\n> >  \n> >         lsc::ComponentsMap components;\n> >  \n> > @@ -259,33 +256,6 @@ LscPolynomial::samplePolynomial(const lsc::Polynomial &poly,\n> >         return samples;\n> >  }\n> >  \n> > -/*\n> > - * The rkisp1 LSC grid spacing is defined by the cell sizes on the top-left\n> > - * quadrant of the grid. This is then mirrored in hardware to the other\n> > - * quadrants. See parseSizes() for further details. For easier handling, this\n> > - * function converts the cell sizes of half the grid to a list of position of\n> > - * the whole grid (on one axis). Example:\n> > - *\n> > - * input:   | 0.2 | 0.3 |\n> > - * output: 0.0   0.2   0.5   0.8   1.0\n> > - */\n> > -std::vector<double>\n> > -LscPolynomial::sizesListToPositions(Span<const double> sizes)\n> > -{\n> > -       const int half = sizes.size();\n> > -       std::vector<double> positions(half * 2 + 1);\n> > -       double x = 0.0;\n> > -\n> > -       positions[half] = 0.5;\n> > -       for (int i = 1; i <= half; i++) {\n> > -               x += sizes[half - i];\n> > -               positions[half - i] = 0.5 - x;\n> > -               positions[half + i] = 0.5 + x;\n> > -       }\n> > -\n> > -       return positions;\n> > -}\n> > -\n> >  } /* namespace ipa */\n> >  \n> >  #ifndef __DOXYGEN__\n> > diff --git a/src/ipa/libipa/lsc_polynomial.h b/src/ipa/libipa/lsc_polynomial.h\n> > index 17c2c34499f0..d2276ecc6f6b 100644\n> > --- a/src/ipa/libipa/lsc_polynomial.h\n> > +++ b/src/ipa/libipa/lsc_polynomial.h\n> > @@ -71,11 +71,9 @@ public:\n> >  \n> >         lsc::ComponentsMap\n> >         sampleForCrop(const Rectangle &cropRectangle,\n> > -                     Span<const double> xSizes,\n> > -                     Span<const double> ySizes) override;\n> > +                     std::vector<double> xPos, std::vector<double> yPos) override;\n> >  \n> >  private:\n> > -       std::vector<double> sizesListToPositions(Span<const double> sizes);\n> >         std::vector<uint16_t> samplePolynomial(const lsc::Polynomial &poly,\n> >                                                Span<const double> xPositions,\n> >                                                Span<const double> yPositions,\n> > diff --git a/src/ipa/libipa/lsc_table.h b/src/ipa/libipa/lsc_table.h\n> > index 0983b78c3f6b..67c7464ea5b6 100644\n> > --- a/src/ipa/libipa/lsc_table.h\n> > +++ b/src/ipa/libipa/lsc_table.h\n> > @@ -30,8 +30,8 @@ public:\n> >  \n> >         lsc::ComponentsMap\n> >         sampleForCrop([[maybe_unused]] const Rectangle &cropRectangle,\n> > -                     [[maybe_unused]] Span<const double> xSizes,\n> > -                     [[maybe_unused]] Span<const double> ySizes) override\n> > +                     [[maybe_unused]] std::vector<double> xPos,\n> > +                     [[maybe_unused]] std::vector<double> yPos) override\n> >         {\n> >                 LOG(LscTable, Warning)\n> >                         << \"Tabular LSC data doesn't support resampling\";\n> > diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp\n> > index e03bf361c4b9..7010c97db22e 100644\n> > --- a/src/ipa/rkisp1/algorithms/lsc.cpp\n> > +++ b/src/ipa/rkisp1/algorithms/lsc.cpp\n> > @@ -70,6 +70,9 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,\n> >         if (xSize_.empty() || ySize_.empty())\n> >                 return -EINVAL;\n> >  \n> > +       xPos_ = sizesListToPositions(xSize_);\n> > +       yPos_ = sizesListToPositions(ySize_);\n> > +\n> >         /* Get all defined sets to apply. */\n> >         const ValueNode &sets = tuningData[\"sets\"];\n> >         if (!sets.isList()) {\n> > @@ -138,6 +141,33 @@ std::vector<double> LensShadingCorrection::parseSizes(const ValueNode &tuningDat\n> >         return sizes;\n> >  }\n> >  \n> > +/*\n> > + * The rkisp1 LSC grid spacing is defined by the cell sizes on the top-left\n> > + * quadrant of the grid. This is then mirrored in hardware to the other\n> > + * quadrants. See parseSizes() for further details. For easier handling, this\n> > + * function converts the cell sizes of half the grid to a list of position of\n> > + * the whole grid (on one axis). Example:\n> > + *\n> > + * input:   | 0.2 | 0.3 |\n> > + * output: 0.0   0.2   0.5   0.8   1.0\n> > + */\n> > +std::vector<double>\n> > +LensShadingCorrection::sizesListToPositions(Span<const double> sizes)\n> > +{\n> > +       const int half = sizes.size();\n> > +       std::vector<double> positions(half * 2 + 1);\n> > +       double x = 0.0;\n> > +\n> > +       positions[half] = 0.5;\n> > +       for (int i = 1; i <= half; i++) {\n> > +               x += sizes[half - i];\n> > +               positions[half - i] = 0.5 - x;\n> > +               positions[half + i] = 0.5 + x;\n> > +       }\n> > +\n> > +       return positions;\n> > +}\n> > +\n> >  /**\n> >   * \\copydoc libcamera::ipa::Algorithm::configure\n> >   */\n> > @@ -171,7 +201,7 @@ int LensShadingCorrection::configure(IPAContext &context,\n> >  \n> >         LOG(RkISP1Lsc, Debug) << \"Sample LSC data for \" << configInfo.analogCrop;\n> >         lsc::ComponentsMap shadingData = algo_->sampleForCrop(configInfo.analogCrop,\n> > -                                                             xSize_, ySize_);\n> > +                                                             xPos_, yPos_);\n> >         sets_.setData(std::move(shadingData));\n> >  \n> >         context.activeState.lsc.enabled = true;\n> > diff --git a/src/ipa/rkisp1/algorithms/lsc.h b/src/ipa/rkisp1/algorithms/lsc.h\n> > index ee037353bbe4..06aa7a5f133c 100644\n> > --- a/src/ipa/rkisp1/algorithms/lsc.h\n> > +++ b/src/ipa/rkisp1/algorithms/lsc.h\n> > @@ -41,9 +41,12 @@ private:\n> >         void copyTable(rkisp1_cif_isp_lsc_config &config, const lsc::Components &set0);\n> >         std::vector<double> parseSizes(const ValueNode &tuningData,\n> >                                        const char *prop);\n> > +       std::vector<double> sizesListToPositions(Span<const double> sizes);\n> >  \n> >         std::vector<double> xSize_;\n> >         std::vector<double> ySize_;\n> > +       std::vector<double> xPos_;\n> > +       std::vector<double> yPos_;\n> >         uint16_t xGrad_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n> >         uint16_t yGrad_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n> >         uint16_t xSizes_[RKISP1_CIF_ISP_LSC_SECTORS_TBL_SIZE];\n> > \n> > -- \n> > 2.54.0\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 96730BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 14 Jul 2026 17:13:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 500F966144;\n\tTue, 14 Jul 2026 19:13:50 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2091C66137\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 14 Jul 2026 19:13:49 +0200 (CEST)","from monstersaurus.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 C1AA9558;\n\tTue, 14 Jul 2026 19:12:54 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"jHpXFrz1\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1784049174;\n\tbh=OQH/KJx52fXhXTv9XyZSivE1M1W/bIowMi5tsyekaSE=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=jHpXFrz1IKVWiU3BgTo5020c6KZGFLlTdd2gzrbfUt9JgFRwkCHKkwN0NTPBLHdaD\n\t7b2X4Cgg+C11tNWwp9uixyaYsVm31iMOC3OqctsWnS96087/FarSl6NNp1krfhoPir\n\t48fhSI5NEibKc8+BrpMbyPmuSKbdYkeahR6nD/I4=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<178395426958.3603632.11518373547679826535@localhost>","References":"<20260708-libipa-algorithms-v5-0-0759d0359f52@ideasonboard.com>\n\t<20260708-libipa-algorithms-v5-24-0759d0359f52@ideasonboard.com>\n\t<178395426958.3603632.11518373547679826535@localhost>","Subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tStefan Klug <stefan.klug@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Tue, 14 Jul 2026 18:13:46 +0100","Message-ID":"<178404922669.3931061.18413397520993879260@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":39889,"web_url":"https://patchwork.libcamera.org/comment/39889/","msgid":"<e34f9d08-5357-4493-be96-d3bfdca63580@ideasonboard.com>","date":"2026-07-28T07:47:32","subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 07. 08. 17:51 keltezéssel, Jacopo Mondi írta:\n> The LscPolynomial::sampleForCrop() function is designed to receive a\n> list of segment sizes and translates it to a list of grid vertexes\n> internally with the sizesListToPositions() function.\n> \n> As the sizesListToPositions() implementation is RkISP1-specific, move it\n> back to the RkISP1 IPA and change the prototype of the sampleForCrop()\n> function to accept a vector of grid vertexes instead of a span of\n> segment sizes.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> ---\n>   src/ipa/libipa/lsc_base.cpp       |  6 +++---\n>   src/ipa/libipa/lsc_base.h         |  3 +--\n>   src/ipa/libipa/lsc_polynomial.cpp | 38 ++++----------------------------------\n>   src/ipa/libipa/lsc_polynomial.h   |  4 +---\n>   src/ipa/libipa/lsc_table.h        |  4 ++--\n>   src/ipa/rkisp1/algorithms/lsc.cpp | 32 +++++++++++++++++++++++++++++++-\n>   src/ipa/rkisp1/algorithms/lsc.h   |  3 +++\n>   7 files changed, 45 insertions(+), 45 deletions(-)\n> \n> [...]\n> diff --git a/src/ipa/libipa/lsc_base.h b/src/ipa/libipa/lsc_base.h\n> index 51cc35888209..8d1843a5d4fd 100644\n> --- a/src/ipa/libipa/lsc_base.h\n> +++ b/src/ipa/libipa/lsc_base.h\n> @@ -65,8 +65,7 @@ public:\n>   \n>   \tvirtual lsc::ComponentsMap\n>   \tsampleForCrop(const Rectangle &cropRectangle,\n> -\t\t      Span<const double> xSizes,\n> -\t\t      Span<const double> ySizes) = 0;\n> +\t\t      std::vector<double> xPos, std::vector<double> yPos);\n\nWhat's the reason for switching to a vector? As far as I can see `Span<const double>`\nshould work just fine.\n\n\n>   };\n>   \n>   } /* namespace ipa */\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 9EE68C32CE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 28 Jul 2026 07:47:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3FF6467F95;\n\tTue, 28 Jul 2026 09:47:38 +0200 (CEST)","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 F03EA67F85\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 28 Jul 2026 09:47:35 +0200 (CEST)","from [192.168.33.47] (185.182.215.156.nat.pool.zt.hu\n\t[185.182.215.156])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 625DC558;\n\tTue, 28 Jul 2026 09:46:31 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"ozpRMhyY\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1785224791;\n\tbh=Xg2ICuaw1qJWgdO6lbitwg1OtBQvrGZlNlwVnQgfDnE=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=ozpRMhyYww80jilJZN+ue5kbGIMHWXn3iP4Rbt6mRfzzCeeTIzBGRagudpxO7D6Xc\n\tylUEUqr6/sxK184a6uZ5s3/1kwzJ7q2Pw39SMdPi6u5vyzMxbvfIHmB8uNBmdKbyJG\n\tCNEcpLR/ufn0Dqy38NhlPV6M6Jl3tUnKu7TVyKrw=","Message-ID":"<e34f9d08-5357-4493-be96-d3bfdca63580@ideasonboard.com>","Date":"Tue, 28 Jul 2026 09:47:32 +0200","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v5 24/36] ipa: libipa: lsc: Move sizesListToPositions()\n\tback to rkisp1","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tStefan Klug <stefan.klug@ideasonboard.com>","References":"<20260708-libipa-algorithms-v5-0-0759d0359f52@ideasonboard.com>\n\t<20260708-libipa-algorithms-v5-24-0759d0359f52@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":"<20260708-libipa-algorithms-v5-24-0759d0359f52@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>"}}]