[{"id":24200,"web_url":"https://patchwork.libcamera.org/comment/24200/","msgid":"<YuGsdlJBRkzpZFlv@pendragon.ideasonboard.com>","date":"2022-07-27T21:21:58","subject":"Re: [libcamera-devel] [PATCH v7.1 13/14] ipa: raspberrypi: Use\n\tYamlParser to replace dependency on boost","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"The subject line should have read\n\n\"[PATCH v7.1 08/14] ipa: raspberrypi: Use YamlParser to replace dependency on boost\"\n\nSorry about that.\n\nOn Wed, Jul 27, 2022 at 08:43:52PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> The Raspberry Pi IPA module depends on boost only to parse the JSON\n> tuning data files. As libcamera depends on libyaml, use the YamlParser\n> class to parse those files and drop the dependency on boost.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Tested-by: Naushir Patuck <naush@raspberrypi.com>\n> ---\n> Changes since v7:\n> \n> - Guard against invalid number of entries or invalid entries in\n>   Pwl::read()\n> - Don't use default value for reference_Y and reference_lux in lux.cpp\n> \n> Changes since v6:\n> \n> - Propagate tuning data read errors\n> ---\n>  README.rst                                    |   6 -\n>  src/ipa/raspberrypi/controller/algorithm.cpp  |   2 +-\n>  src/ipa/raspberrypi/controller/algorithm.h    |   6 +-\n>  src/ipa/raspberrypi/controller/controller.cpp |  27 ++--\n>  src/ipa/raspberrypi/controller/pwl.cpp        |  27 ++--\n>  src/ipa/raspberrypi/controller/pwl.h          |   4 +-\n>  src/ipa/raspberrypi/controller/rpi/agc.cpp    | 136 ++++++++++--------\n>  src/ipa/raspberrypi/controller/rpi/agc.h      |  10 +-\n>  src/ipa/raspberrypi/controller/rpi/alsc.cpp   | 105 +++++++-------\n>  src/ipa/raspberrypi/controller/rpi/alsc.h     |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/awb.cpp    | 134 ++++++++++-------\n>  src/ipa/raspberrypi/controller/rpi/awb.h      |   8 +-\n>  .../controller/rpi/black_level.cpp            |  12 +-\n>  .../raspberrypi/controller/rpi/black_level.h  |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/ccm.cpp    |  47 +++---\n>  src/ipa/raspberrypi/controller/rpi/ccm.h      |   4 +-\n>  .../raspberrypi/controller/rpi/contrast.cpp   |  28 ++--\n>  src/ipa/raspberrypi/controller/rpi/contrast.h |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/dpc.cpp    |   7 +-\n>  src/ipa/raspberrypi/controller/rpi/dpc.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/geq.cpp    |  10 +-\n>  src/ipa/raspberrypi/controller/rpi/geq.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/lux.cpp    |  30 +++-\n>  src/ipa/raspberrypi/controller/rpi/lux.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/noise.cpp  |  14 +-\n>  src/ipa/raspberrypi/controller/rpi/noise.h    |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/sdn.cpp    |   6 +-\n>  src/ipa/raspberrypi/controller/rpi/sdn.h      |   2 +-\n>  .../raspberrypi/controller/rpi/sharpen.cpp    |   8 +-\n>  src/ipa/raspberrypi/controller/rpi/sharpen.h  |   2 +-\n>  src/ipa/raspberrypi/meson.build               |   1 -\n>  src/ipa/raspberrypi/raspberrypi.cpp           |   1 +\n>  32 files changed, 374 insertions(+), 277 deletions(-)\n\n[snip]","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 9D521BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 27 Jul 2022 21:22:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 024F863311;\n\tWed, 27 Jul 2022 23:22:02 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D941463309\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Jul 2022 23:22:00 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5A7EF56D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Jul 2022 23:22:00 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658956922;\n\tbh=HLopR+PWvDHJacocPhqGi+zJuk68FCZCphNJlxM6/FI=;\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:\n\tFrom;\n\tb=eAggk22WY3cfiPjkvemJ+QSbNhpFBP7orpYRfd/MRhHrYCqrnOnL0Mx/ZFght0Mt6\n\t0B47G8lfpqt4KpBG1Uq/Q8CqHJ9j6Oa11MGq6/eWtcEYjuBkecY5mjOaYMPqESl/0/\n\tMmrep0N7MbU0B15dx7Z1i6OXtCRtZGmZl/Y1Cnk+j1obXFoMAMcBaNdTpMu9bxIR85\n\toa2GxIrzgCZ6AHDAxXClVCLN6Yd63nmF1tY6+AVnS/m5wE/MHdVgY9POzB9Sa+cAYc\n\tcE+OCDIAopyld3k6LgeuxH6rEgGZ//51ufCIfdXTnwRMZMEzTYcsEv+/e4SZh+naVf\n\tKCP+vtohwf7Ww==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1658956920;\n\tbh=HLopR+PWvDHJacocPhqGi+zJuk68FCZCphNJlxM6/FI=;\n\th=Date:From:To:Subject:References:In-Reply-To:From;\n\tb=rTm93XVVc/fIeI0OOsT26V3S2xPdjAFenG7nOrb5d3FgYYXIRefDaabfGS5NUThU4\n\tfavzG8x06w/qGyMsQkqIBMQYxQTsBXtcGWSZUunLSuc0FJvi+PrPfyGgj6+jkC0iY6\n\trjuGjkQRcAuZwNtf62QlL9GcwnCm6ldqEIkqFVSE="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"rTm93XVV\"; dkim-atps=neutral","Date":"Thu, 28 Jul 2022 00:21:58 +0300","To":"libcamera-devel@lists.libcamera.org","Message-ID":"<YuGsdlJBRkzpZFlv@pendragon.ideasonboard.com>","References":"<20220727023816.30008-9-laurent.pinchart@ideasonboard.com>\n\t<20220727174352.21332-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220727174352.21332-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v7.1 13/14] ipa: raspberrypi: Use\n\tYamlParser to replace dependency on boost","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":24207,"web_url":"https://patchwork.libcamera.org/comment/24207/","msgid":"<CAEmqJPrHp_C=USVj1xVC89gOC8_s_LwaRNp55UgLZhUAKstrcQ@mail.gmail.com>","date":"2022-07-28T07:08:07","subject":"Re: [libcamera-devel] [PATCH v7.1 13/14] ipa: raspberrypi: Use\n\tYamlParser to replace dependency on boost","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Laurent,\n\nThank you for the update.\n\nOn Wed, 27 Jul 2022 at 18:43, Laurent Pinchart <\nlaurent.pinchart@ideasonboard.com> wrote:\n\n> The Raspberry Pi IPA module depends on boost only to parse the JSON\n> tuning data files. As libcamera depends on libyaml, use the YamlParser\n> class to parse those files and drop the dependency on boost.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Tested-by: Naushir Patuck <naush@raspberrypi.com>\n>\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n> ---\n> Changes since v7:\n>\n> - Guard against invalid number of entries or invalid entries in\n>   Pwl::read()\n> - Don't use default value for reference_Y and reference_lux in lux.cpp\n>\n> Changes since v6:\n>\n> - Propagate tuning data read errors\n> ---\n>  README.rst                                    |   6 -\n>  src/ipa/raspberrypi/controller/algorithm.cpp  |   2 +-\n>  src/ipa/raspberrypi/controller/algorithm.h    |   6 +-\n>  src/ipa/raspberrypi/controller/controller.cpp |  27 ++--\n>  src/ipa/raspberrypi/controller/pwl.cpp        |  27 ++--\n>  src/ipa/raspberrypi/controller/pwl.h          |   4 +-\n>  src/ipa/raspberrypi/controller/rpi/agc.cpp    | 136 ++++++++++--------\n>  src/ipa/raspberrypi/controller/rpi/agc.h      |  10 +-\n>  src/ipa/raspberrypi/controller/rpi/alsc.cpp   | 105 +++++++-------\n>  src/ipa/raspberrypi/controller/rpi/alsc.h     |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/awb.cpp    | 134 ++++++++++-------\n>  src/ipa/raspberrypi/controller/rpi/awb.h      |   8 +-\n>  .../controller/rpi/black_level.cpp            |  12 +-\n>  .../raspberrypi/controller/rpi/black_level.h  |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/ccm.cpp    |  47 +++---\n>  src/ipa/raspberrypi/controller/rpi/ccm.h      |   4 +-\n>  .../raspberrypi/controller/rpi/contrast.cpp   |  28 ++--\n>  src/ipa/raspberrypi/controller/rpi/contrast.h |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/dpc.cpp    |   7 +-\n>  src/ipa/raspberrypi/controller/rpi/dpc.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/geq.cpp    |  10 +-\n>  src/ipa/raspberrypi/controller/rpi/geq.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/lux.cpp    |  30 +++-\n>  src/ipa/raspberrypi/controller/rpi/lux.h      |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/noise.cpp  |  14 +-\n>  src/ipa/raspberrypi/controller/rpi/noise.h    |   2 +-\n>  src/ipa/raspberrypi/controller/rpi/sdn.cpp    |   6 +-\n>  src/ipa/raspberrypi/controller/rpi/sdn.h      |   2 +-\n>  .../raspberrypi/controller/rpi/sharpen.cpp    |   8 +-\n>  src/ipa/raspberrypi/controller/rpi/sharpen.h  |   2 +-\n>  src/ipa/raspberrypi/meson.build               |   1 -\n>  src/ipa/raspberrypi/raspberrypi.cpp           |   1 +\n>  32 files changed, 374 insertions(+), 277 deletions(-)\n>\n> diff --git a/README.rst b/README.rst\n> index b9e72d81b90c..3d4e48ddc8f6 100644\n> --- a/README.rst\n> +++ b/README.rst\n> @@ -71,12 +71,6 @@ for improved debugging: [optional]\n>          information, and libunwind is not needed if both libdw and the\n> glibc\n>          backtrace() function are available.\n>\n> -for the Raspberry Pi IPA: [optional]\n> -        libboost-dev\n> -\n> -        Support for Raspberry Pi can be disabled through the meson\n> -         'pipelines' option to avoid this dependency.\n> -\n>  for device hotplug enumeration: [optional]\n>          libudev-dev\n>\n> diff --git a/src/ipa/raspberrypi/controller/algorithm.cpp\n> b/src/ipa/raspberrypi/controller/algorithm.cpp\n> index d73cb36fe2d6..6d91ee292bd1 100644\n> --- a/src/ipa/raspberrypi/controller/algorithm.cpp\n> +++ b/src/ipa/raspberrypi/controller/algorithm.cpp\n> @@ -9,7 +9,7 @@\n>\n>  using namespace RPiController;\n>\n> -int Algorithm::read([[maybe_unused]] boost::property_tree::ptree const\n> &params)\n> +int Algorithm::read([[maybe_unused]] const libcamera::YamlObject &params)\n>  {\n>         return 0;\n>  }\n> diff --git a/src/ipa/raspberrypi/controller/algorithm.h\n> b/src/ipa/raspberrypi/controller/algorithm.h\n> index 0c5566fda874..cbbb13ba07a3 100644\n> --- a/src/ipa/raspberrypi/controller/algorithm.h\n> +++ b/src/ipa/raspberrypi/controller/algorithm.h\n> @@ -15,10 +15,10 @@\n>  #include <memory>\n>  #include <map>\n>\n> +#include \"libcamera/internal/yaml_parser.h\"\n> +\n>  #include \"controller.h\"\n>\n> -#include <boost/property_tree/ptree.hpp>\n> -\n>  namespace RPiController {\n>\n>  /* This defines the basic interface for all control algorithms. */\n> @@ -35,7 +35,7 @@ public:\n>         virtual bool isPaused() const { return paused_; }\n>         virtual void pause() { paused_ = true; }\n>         virtual void resume() { paused_ = false; }\n> -       virtual int read(boost::property_tree::ptree const &params);\n> +       virtual int read(const libcamera::YamlObject &params);\n>         virtual void initialise();\n>         virtual void switchMode(CameraMode const &cameraMode, Metadata\n> *metadata);\n>         virtual void prepare(Metadata *imageMetadata);\n> diff --git a/src/ipa/raspberrypi/controller/controller.cpp\n> b/src/ipa/raspberrypi/controller/controller.cpp\n> index d91ac90704cb..bceb62540dbd 100644\n> --- a/src/ipa/raspberrypi/controller/controller.cpp\n> +++ b/src/ipa/raspberrypi/controller/controller.cpp\n> @@ -5,14 +5,16 @@\n>   * controller.cpp - ISP controller\n>   */\n>\n> +#include <assert.h>\n> +\n> +#include <libcamera/base/file.h>\n>  #include <libcamera/base/log.h>\n>\n> +#include \"libcamera/internal/yaml_parser.h\"\n> +\n>  #include \"algorithm.h\"\n>  #include \"controller.h\"\n>\n> -#include <boost/property_tree/json_parser.hpp>\n> -#include <boost/property_tree/ptree.hpp>\n> -\n>  using namespace RPiController;\n>  using namespace libcamera;\n>\n> @@ -34,18 +36,25 @@ Controller::~Controller() {}\n>\n>  int Controller::read(char const *filename)\n>  {\n> -       boost::property_tree::ptree root;\n> -       boost::property_tree::read_json(filename, root);\n> -       for (auto const &keyAndValue : root) {\n> -               Algorithm *algo =\n> createAlgorithm(keyAndValue.first.c_str());\n> +       File file(filename);\n> +       if (!file.open(File::OpenModeFlag::ReadOnly)) {\n> +               LOG(RPiController, Warning)\n> +                       << \"Failed to open tuning file '\" << filename <<\n> \"'\";\n> +               return -EINVAL;\n> +       }\n> +\n> +       std::unique_ptr<YamlObject> root = YamlParser::parse(file);\n> +\n> +       for (auto const &[key, value] : root->asDict()) {\n> +               Algorithm *algo = createAlgorithm(key.c_str());\n>                 if (algo) {\n> -                       int ret = algo->read(keyAndValue.second);\n> +                       int ret = algo->read(value);\n>                         if (ret)\n>                                 return ret;\n>                         algorithms_.push_back(AlgorithmPtr(algo));\n>                 } else\n>                         LOG(RPiController, Warning)\n> -                               << \"No algorithm found for \\\"\" <<\n> keyAndValue.first << \"\\\"\";\n> +                               << \"No algorithm found for \\\"\" << key <<\n> \"\\\"\";\n>         }\n>\n>         return 0;\n> diff --git a/src/ipa/raspberrypi/controller/pwl.cpp\n> b/src/ipa/raspberrypi/controller/pwl.cpp\n> index fde0b298c6ce..c59f5fa131e3 100644\n> --- a/src/ipa/raspberrypi/controller/pwl.cpp\n> +++ b/src/ipa/raspberrypi/controller/pwl.cpp\n> @@ -12,16 +12,27 @@\n>\n>  using namespace RPiController;\n>\n> -int Pwl::read(boost::property_tree::ptree const &params)\n> +int Pwl::read(const libcamera::YamlObject &params)\n>  {\n> -       for (auto it = params.begin(); it != params.end(); it++) {\n> -               double x = it->second.get_value<double>();\n> -               assert(it == params.begin() || x > points_.back().x);\n> -               it++;\n> -               double y = it->second.get_value<double>();\n> -               points_.push_back(Point(x, y));\n> +       if (!params.size() || params.size() % 2)\n> +               return -EINVAL;\n> +\n> +       const auto &list = params.asList();\n> +\n> +       for (auto it = list.begin(); it != list.end(); it++) {\n> +               auto x = it->get<double>();\n> +               if (!x)\n> +                       return -EINVAL;\n> +               if (it != list.begin() && *x <= points_.back().x)\n> +                       return -EINVAL;\n> +\n> +               auto y = (++it)->get<double>();\n> +               if (!y)\n> +                       return -EINVAL;\n> +\n> +               points_.push_back(Point(*x, *y));\n>         }\n> -       assert(points_.size() >= 2);\n> +\n>         return 0;\n>  }\n>\n> diff --git a/src/ipa/raspberrypi/controller/pwl.h\n> b/src/ipa/raspberrypi/controller/pwl.h\n> index ef1cc2ed113a..546482cd04d7 100644\n> --- a/src/ipa/raspberrypi/controller/pwl.h\n> +++ b/src/ipa/raspberrypi/controller/pwl.h\n> @@ -9,7 +9,7 @@\n>  #include <math.h>\n>  #include <vector>\n>\n> -#include <boost/property_tree/ptree.hpp>\n> +#include \"libcamera/internal/yaml_parser.h\"\n>\n>  namespace RPiController {\n>\n> @@ -57,7 +57,7 @@ public:\n>         };\n>         Pwl() {}\n>         Pwl(std::vector<Point> const &points) : points_(points) {}\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>         void append(double x, double y, const double eps = 1e-6);\n>         void prepend(double x, double y, const double eps = 1e-6);\n>         Interval domain() const;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> index 7fd5d18b9a22..5037f9008117 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> @@ -31,67 +31,76 @@ LOG_DEFINE_CATEGORY(RPiAgc)\n>\n>  static constexpr unsigned int PipelineBits = 13; /* seems to be a 13-bit\n> pipeline */\n>\n> -int AgcMeteringMode::read(boost::property_tree::ptree const &params)\n> +int AgcMeteringMode::read(const libcamera::YamlObject &params)\n>  {\n> -       int num = 0;\n> -\n> -       for (auto &p : params.get_child(\"weights\")) {\n> -               if (num == AgcStatsSize) {\n> -                       LOG(RPiAgc, Error) << \"AgcMeteringMode: too many\n> weights\";\n> -                       return -EINVAL;\n> -               }\n> -               weights[num++] = p.second.get_value<double>();\n> -       }\n> -\n> -       if (num != AgcStatsSize) {\n> -               LOG(RPiAgc, Error) << \"AgcMeteringMode: insufficient\n> weights\";\n> +       const YamlObject &yamlWeights = params[\"weights\"];\n> +       if (yamlWeights.size() != AgcStatsSize) {\n> +               LOG(RPiAgc, Error) << \"AgcMeteringMode: Incorrect number\n> of weights\";\n>                 return -EINVAL;\n>         }\n>\n> +       unsigned int num = 0;\n> +       for (const auto &p : yamlWeights.asList()) {\n> +               auto value = p.get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               weights[num++] = *value;\n> +       }\n> +\n>         return 0;\n>  }\n>\n>  static std::tuple<int, std::string>\n> -readMeteringModes(std::map<std::string, AgcMeteringMode> &meteringModes,\n> -                 boost::property_tree::ptree const &params)\n> +readMeteringModes(std::map<std::string, AgcMeteringMode> &metering_modes,\n> +                 const libcamera::YamlObject &params)\n>  {\n>         std::string first;\n>         int ret;\n>\n> -       for (auto &p : params) {\n> +       for (const auto &[key, value] : params.asDict()) {\n>                 AgcMeteringMode meteringMode;\n> -               ret = meteringMode.read(p.second);\n> +               ret = meteringMode.read(value);\n>                 if (ret)\n>                         return { ret, {} };\n>\n> -               meteringModes[p.first] = std::move(meteringMode);\n> +               metering_modes[key] = std::move(meteringMode);\n>                 if (first.empty())\n> -                       first = p.first;\n> +                       first = key;\n>         }\n>\n>         return { 0, first };\n>  }\n>\n>  static int readList(std::vector<double> &list,\n> -                   boost::property_tree::ptree const &params)\n> +                   const libcamera::YamlObject &params)\n>  {\n> -       for (auto &p : params)\n> -               list.push_back(p.second.get_value<double>());\n> +       for (const auto &p : params.asList()) {\n> +               auto value = p.get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               list.push_back(*value);\n> +       }\n> +\n>         return list.size();\n>  }\n>\n>  static int readList(std::vector<Duration> &list,\n> -                   boost::property_tree::ptree const &params)\n> +                   const libcamera::YamlObject &params)\n>  {\n> -       for (auto &p : params)\n> -               list.push_back(p.second.get_value<double>() * 1us);\n> +       for (const auto &p : params.asList()) {\n> +               auto value = p.get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               list.push_back(*value * 1us);\n> +       }\n> +\n>         return list.size();\n>  }\n>\n> -int AgcExposureMode::read(boost::property_tree::ptree const &params)\n> +int AgcExposureMode::read(const libcamera::YamlObject &params)\n>  {\n> -       int numShutters = readList(shutter, params.get_child(\"shutter\"));\n> -       int numAgs = readList(gain, params.get_child(\"gain\"));\n> +       int numShutters = readList(shutter, params[\"shutter\"]);\n> +       int numAgs = readList(gain, params[\"gain\"]);\n>\n>         if (numShutters < 2 || numAgs < 2) {\n>                 LOG(RPiAgc, Error)\n> @@ -110,28 +119,28 @@ int\n> AgcExposureMode::read(boost::property_tree::ptree const &params)\n>\n>  static std::tuple<int, std::string>\n>  readExposureModes(std::map<std::string, AgcExposureMode> &exposureModes,\n> -                 boost::property_tree::ptree const &params)\n> +                 const libcamera::YamlObject &params)\n>  {\n>         std::string first;\n>         int ret;\n>\n> -       for (auto &p : params) {\n> +       for (const auto &[key, value] : params.asDict()) {\n>                 AgcExposureMode exposureMode;\n> -               ret = exposureMode.read(p.second);\n> +               ret = exposureMode.read(value);\n>                 if (ret)\n>                         return { ret, {} };\n>\n> -               exposureModes[p.first] = std::move(exposureMode);\n> +               exposureModes[key] = std::move(exposureMode);\n>                 if (first.empty())\n> -                       first = p.first;\n> +                       first = key;\n>         }\n>\n>         return { 0, first };\n>  }\n>\n> -int AgcConstraint::read(boost::property_tree::ptree const &params)\n> +int AgcConstraint::read(const libcamera::YamlObject &params)\n>  {\n> -       std::string boundString = params.get<std::string>(\"bound\", \"\");\n> +       std::string boundString = params[\"bound\"].get<std::string>(\"\");\n>         transform(boundString.begin(), boundString.end(),\n>                   boundString.begin(), ::toupper);\n>         if (boundString != \"UPPER\" && boundString != \"LOWER\") {\n> @@ -139,20 +148,29 @@ int AgcConstraint::read(boost::property_tree::ptree\n> const &params)\n>                 return -EINVAL;\n>         }\n>         bound = boundString == \"UPPER\" ? Bound::UPPER : Bound::LOWER;\n> -       qLo = params.get<double>(\"q_lo\");\n> -       qHi = params.get<double>(\"q_hi\");\n> -       return yTarget.read(params.get_child(\"y_target\"));\n> +\n> +       auto value = params[\"q_lo\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       qLo = *value;\n> +\n> +       value = params[\"q_hi\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       qHi = *value;\n> +\n> +       return yTarget.read(params[\"y_target\"]);\n>  }\n>\n>  static std::tuple<int, AgcConstraintMode>\n> -readConstraintMode(boost::property_tree::ptree const &params)\n> +readConstraintMode(const libcamera::YamlObject &params)\n>  {\n>         AgcConstraintMode mode;\n>         int ret;\n>\n> -       for (auto &p : params) {\n> +       for (const auto &p : params.asList()) {\n>                 AgcConstraint constraint;\n> -               ret = constraint.read(p.second);\n> +               ret = constraint.read(p);\n>                 if (ret)\n>                         return { ret, {} };\n>\n> @@ -164,53 +182,55 @@ readConstraintMode(boost::property_tree::ptree const\n> &params)\n>\n>  static std::tuple<int, std::string>\n>  readConstraintModes(std::map<std::string, AgcConstraintMode>\n> &constraintModes,\n> -                   boost::property_tree::ptree const &params)\n> +                   const libcamera::YamlObject &params)\n>  {\n>         std::string first;\n>         int ret;\n>\n> -       for (auto &p : params) {\n> -               std::tie(ret, constraintModes[p.first]) =\n> readConstraintMode(p.second);\n> +       for (const auto &[key, value] : params.asDict()) {\n> +               std::tie(ret, constraintModes[key]) =\n> readConstraintMode(value);\n>                 if (ret)\n>                         return { ret, {} };\n>\n>                 if (first.empty())\n> -                       first = p.first;\n> +                       first = key;\n>         }\n>\n>         return { 0, first };\n>  }\n>\n> -int AgcConfig::read(boost::property_tree::ptree const &params)\n> +int AgcConfig::read(const libcamera::YamlObject &params)\n>  {\n>         LOG(RPiAgc, Debug) << \"AgcConfig\";\n>         int ret;\n>\n>         std::tie(ret, defaultMeteringMode) =\n> -               readMeteringModes(meteringModes,\n> params.get_child(\"metering_modes\"));\n> +               readMeteringModes(meteringModes, params[\"metering_modes\"]);\n>         if (ret)\n>                 return ret;\n>         std::tie(ret, defaultExposureMode) =\n> -               readExposureModes(exposureModes,\n> params.get_child(\"exposure_modes\"));\n> +               readExposureModes(exposureModes, params[\"exposure_modes\"]);\n>         if (ret)\n>                 return ret;\n>         std::tie(ret, defaultConstraintMode) =\n> -               readConstraintModes(constraintModes,\n> params.get_child(\"constraint_modes\"));\n> +               readConstraintModes(constraintModes,\n> params[\"constraint_modes\"]);\n>         if (ret)\n>                 return ret;\n>\n> -       ret = yTarget.read(params.get_child(\"y_target\"));\n> +       ret = yTarget.read(params[\"y_target\"]);\n>         if (ret)\n>                 return ret;\n>\n> -       speed = params.get<double>(\"speed\", 0.2);\n> -       startupFrames = params.get<uint16_t>(\"startup_frames\", 10);\n> -       convergenceFrames = params.get<unsigned int>(\"convergence_frames\",\n> 6);\n> -       fastReduceThreshold = params.get<double>(\"fast_reduce_threshold\",\n> 0.4);\n> -       baseEv = params.get<double>(\"base_ev\", 1.0);\n> +       speed = params[\"speed\"].get<double>(0.2);\n> +       startupFrames = params[\"startup_frames\"].get<uint16_t>(10);\n> +       convergenceFrames = params[\"convergence_frames\"].get<unsigned\n> int>(6);\n> +       fastReduceThreshold =\n> params[\"fast_reduce_threshold\"].get<double>(0.4);\n> +       baseEv = params[\"base_ev\"].get<double>(1.0);\n> +\n>         /* Start with quite a low value as ramping up is easier than\n> ramping down. */\n> -       defaultExposureTime = params.get<double>(\"default_exposure_time\",\n> 1000) * 1us;\n> -       defaultAnalogueGain = params.get<double>(\"default_analogueGain\",\n> 1.0);\n> +       defaultExposureTime =\n> params[\"default_exposure_time\"].get<double>(1000) * 1us;\n> +       defaultAnalogueGain =\n> params[\"default_analogue_gain\"].get<double>(1.0);\n> +\n>         return 0;\n>  }\n>\n> @@ -242,7 +262,7 @@ char const *Agc::name() const\n>         return NAME;\n>  }\n>\n> -int Agc::read(boost::property_tree::ptree const &params)\n> +int Agc::read(const libcamera::YamlObject &params)\n>  {\n>         LOG(RPiAgc, Debug) << \"Agc\";\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/agc.h\n> b/src/ipa/raspberrypi/controller/rpi/agc.h\n> index 1351b0ee079c..6d6b0e5ad857 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/agc.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/agc.h\n> @@ -28,13 +28,13 @@ namespace RPiController {\n>\n>  struct AgcMeteringMode {\n>         double weights[AgcStatsSize];\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>  };\n>\n>  struct AgcExposureMode {\n>         std::vector<libcamera::utils::Duration> shutter;\n>         std::vector<double> gain;\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>  };\n>\n>  struct AgcConstraint {\n> @@ -43,13 +43,13 @@ struct AgcConstraint {\n>         double qLo;\n>         double qHi;\n>         Pwl yTarget;\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>  };\n>\n>  typedef std::vector<AgcConstraint> AgcConstraintMode;\n>\n>  struct AgcConfig {\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>         std::map<std::string, AgcMeteringMode> meteringModes;\n>         std::map<std::string, AgcExposureMode> exposureModes;\n>         std::map<std::string, AgcConstraintMode> constraintModes;\n> @@ -74,7 +74,7 @@ class Agc : public AgcAlgorithm\n>  public:\n>         Agc(Controller *controller);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         /* AGC handles \"pausing\" for itself. */\n>         bool isPaused() const override;\n>         void pause() override;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> index 49aaf6b74603..a4afaf841c41 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n> @@ -5,6 +5,7 @@\n>   * alsc.cpp - ALSC (auto lens shading correction) control algorithm\n>   */\n>\n> +#include <functional>\n>  #include <math.h>\n>  #include <numeric>\n>\n> @@ -50,15 +51,15 @@ char const *Alsc::name() const\n>         return NAME;\n>  }\n>\n> -static int generateLut(double *lut, boost::property_tree::ptree const\n> &params)\n> +static int generateLut(double *lut, const libcamera::YamlObject &params)\n>  {\n> -       double cstrength = params.get<double>(\"corner_strength\", 2.0);\n> +       double cstrength = params[\"corner_strength\"].get<double>(2.0);\n>         if (cstrength <= 1.0) {\n>                 LOG(RPiAlsc, Error) << \"corner_strength must be > 1.0\";\n>                 return -EINVAL;\n>         }\n>\n> -       double asymmetry = params.get<double>(\"asymmetry\", 1.0);\n> +       double asymmetry = params[\"asymmetry\"].get<double>(1.0);\n>         if (asymmetry < 0) {\n>                 LOG(RPiAlsc, Error) << \"asymmetry must be >= 0\";\n>                 return -EINVAL;\n> @@ -80,34 +81,35 @@ static int generateLut(double *lut,\n> boost::property_tree::ptree const &params)\n>         return 0;\n>  }\n>\n> -static int readLut(double *lut, boost::property_tree::ptree const &params)\n> +static int readLut(double *lut, const libcamera::YamlObject &params)\n>  {\n> -       int num = 0;\n> -       const int maxNum = XY;\n> +       if (params.size() != XY) {\n> +               LOG(RPiAlsc, Error) << \"Invalid number of entries in LSC\n> table\";\n> +               return -EINVAL;\n> +       }\n>\n> -       for (auto &p : params) {\n> -               if (num == maxNum) {\n> -                       LOG(RPiAlsc, Error) << \"Too many entries in LSC\n> table\";\n> +       int num = 0;\n> +       for (const auto &p : params.asList()) {\n> +               auto value = p.get<double>();\n> +               if (!value)\n>                         return -EINVAL;\n> -               }\n> -               lut[num++] = p.second.get_value<double>();\n> +               lut[num++] = *value;\n>         }\n>\n> -       if (num < maxNum) {\n> -               LOG(RPiAlsc, Error) << \"Too few entries in LSC table\";\n> -               return -EINVAL;\n> -       }\n>         return 0;\n>  }\n>\n>  static int readCalibrations(std::vector<AlscCalibration> &calibrations,\n> -                           boost::property_tree::ptree const &params,\n> +                           const libcamera::YamlObject &params,\n>                             std::string const &name)\n>  {\n> -       if (params.get_child_optional(name)) {\n> +       if (params.contains(name)) {\n>                 double lastCt = 0;\n> -               for (auto &p : params.get_child(name)) {\n> -                       double ct = p.second.get<double>(\"ct\");\n> +               for (const auto &p : params[name].asList()) {\n> +                       auto value = p[\"ct\"].get<double>();\n> +                       if (!value)\n> +                               return -EINVAL;\n> +                       double ct = *value;\n>                         if (ct <= lastCt) {\n>                                 LOG(RPiAlsc, Error)\n>                                         << \"Entries in \" << name << \" must\n> be in increasing ct order\";\n> @@ -115,23 +117,23 @@ static int\n> readCalibrations(std::vector<AlscCalibration> &calibrations,\n>                         }\n>                         AlscCalibration calibration;\n>                         calibration.ct = lastCt = ct;\n> -                       boost::property_tree::ptree const &table =\n> -                               p.second.get_child(\"table\");\n> +\n> +                       const libcamera::YamlObject &table = p[\"table\"];\n> +                       if (table.size() != XY) {\n> +                               LOG(RPiAlsc, Error)\n> +                                       << \"Incorrect number of values for\n> ct \"\n> +                                       << ct << \" in \" << name;\n> +                               return -EINVAL;\n> +                       }\n> +\n>                         int num = 0;\n> -                       for (auto it = table.begin(); it != table.end();\n> it++) {\n> -                               if (num == XY) {\n> -                                       LOG(RPiAlsc, Error)\n> -                                               << \"Too many values for ct\n> \" << ct << \" in \" << name;\n> +                       for (const auto &elem : table.asList()) {\n> +                               value = elem.get<double>();\n> +                               if (!value)\n>                                         return -EINVAL;\n> -                               }\n> -                               calibration.table[num++] =\n> -                                       it->second.get_value<double>();\n> -                       }\n> -                       if (num != XY) {\n> -                               LOG(RPiAlsc, Error)\n> -                                       << \"Too few values for ct \" << ct\n> << \" in \" << name;\n> -                               return -EINVAL;\n> +                               calibration.table[num++] = *value;\n>                         }\n> +\n>                         calibrations.push_back(calibration);\n>                         LOG(RPiAlsc, Debug)\n>                                 << \"Read \" << name << \" calibration for ct\n> \" << ct;\n> @@ -140,30 +142,29 @@ static int\n> readCalibrations(std::vector<AlscCalibration> &calibrations,\n>         return 0;\n>  }\n>\n> -int Alsc::read(boost::property_tree::ptree const &params)\n> +int Alsc::read(const libcamera::YamlObject &params)\n>  {\n> -       config_.framePeriod = params.get<uint16_t>(\"frame_period\", 12);\n> -       config_.startupFrames = params.get<uint16_t>(\"startup_frames\", 10);\n> -       config_.speed = params.get<double>(\"speed\", 0.05);\n> -       double sigma = params.get<double>(\"sigma\", 0.01);\n> -       config_.sigmaCr = params.get<double>(\"sigma_Cr\", sigma);\n> -       config_.sigmaCb = params.get<double>(\"sigma_Cb\", sigma);\n> -       config_.minCount = params.get<double>(\"min_count\", 10.0);\n> -       config_.minG = params.get<uint16_t>(\"min_G\", 50);\n> -       config_.omega = params.get<double>(\"omega\", 1.3);\n> -       config_.nIter = params.get<uint32_t>(\"n_iter\", X + Y);\n> +       config_.framePeriod = params[\"frame_period\"].get<uint16_t>(12);\n> +       config_.startupFrames = params[\"startup_frames\"].get<uint16_t>(10);\n> +       config_.speed = params[\"speed\"].get<double>(0.05);\n> +       double sigma = params[\"sigma\"].get<double>(0.01);\n> +       config_.sigmaCr = params[\"sigma_Cr\"].get<double>(sigma);\n> +       config_.sigmaCb = params[\"sigma_Cb\"].get<double>(sigma);\n> +       config_.minCount = params[\"min_count\"].get<double>(10.0);\n> +       config_.minG = params[\"min_G\"].get<uint16_t>(50);\n> +       config_.omega = params[\"omega\"].get<double>(1.3);\n> +       config_.nIter = params[\"n_iter\"].get<uint32_t>(X + Y);\n>         config_.luminanceStrength =\n> -               params.get<double>(\"luminance_strength\", 1.0);\n> +               params[\"luminance_strength\"].get<double>(1.0);\n>         for (int i = 0; i < XY; i++)\n>                 config_.luminanceLut[i] = 1.0;\n>\n>         int ret = 0;\n>\n> -       if (params.get_child_optional(\"corner_strength\"))\n> +       if (params.contains(\"corner_strength\"))\n>                 ret = generateLut(config_.luminanceLut, params);\n> -       else if (params.get_child_optional(\"luminance_lut\"))\n> -               ret = readLut(config_.luminanceLut,\n> -                             params.get_child(\"luminance_lut\"));\n> +       else if (params.contains(\"luminance_lut\"))\n> +               ret = readLut(config_.luminanceLut,\n> params[\"luminance_lut\"]);\n>         else\n>                 LOG(RPiAlsc, Warning)\n>                         << \"no luminance table - assume unity everywhere\";\n> @@ -177,9 +178,9 @@ int Alsc::read(boost::property_tree::ptree const\n> &params)\n>         if (ret)\n>                 return ret;\n>\n> -       config_.defaultCt = params.get<double>(\"default_ct\", 4500.0);\n> -       config_.threshold = params.get<double>(\"threshold\", 1e-3);\n> -       config_.lambdaBound = params.get<double>(\"lambda_bound\", 0.05);\n> +       config_.defaultCt = params[\"default_ct\"].get<double>(4500.0);\n> +       config_.threshold = params[\"threshold\"].get<double>(1e-3);\n> +       config_.lambdaBound = params[\"lambda_bound\"].get<double>(0.05);\n>\n>         return 0;\n>  }\n> diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.h\n> b/src/ipa/raspberrypi/controller/rpi/alsc.h\n> index 773fd338ea8e..a858ef5a6551 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/alsc.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/alsc.h\n> @@ -52,7 +52,7 @@ public:\n>         char const *name() const override;\n>         void initialise() override;\n>         void switchMode(CameraMode const &cameraMode, Metadata *metadata)\n> override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>         void process(StatisticsPtr &stats, Metadata *imageMetadata)\n> override;\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> index d8c9665445f9..a16e04a07ff8 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> @@ -5,6 +5,8 @@\n>   * awb.cpp - AWB control algorithm\n>   */\n>\n> +#include <assert.h>\n> +\n>  #include <libcamera/base/log.h>\n>\n>  #include \"../lux_status.h\"\n> @@ -26,62 +28,87 @@ static constexpr unsigned int AwbStatsSizeY =\n> DEFAULT_AWB_REGIONS_Y;\n>   * elsewhere (ALSC and AGC).\n>   */\n>\n> -int AwbMode::read(boost::property_tree::ptree const &params)\n> +int AwbMode::read(const libcamera::YamlObject &params)\n>  {\n> -       ctLo = params.get<double>(\"lo\");\n> -       ctHi = params.get<double>(\"hi\");\n> +       auto value = params[\"lo\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       ctLo = *value;\n> +\n> +       value = params[\"hi\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       ctHi = *value;\n> +\n>         return 0;\n>  }\n>\n> -int AwbPrior::read(boost::property_tree::ptree const &params)\n> +int AwbPrior::read(const libcamera::YamlObject &params)\n>  {\n> -       lux = params.get<double>(\"lux\");\n> -       return prior.read(params.get_child(\"prior\"));\n> +       auto value = params[\"lux\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       lux = *value;\n> +\n> +       return prior.read(params[\"prior\"]);\n>  }\n>\n> -static int readCtCurve(Pwl &ctR, Pwl &ctB,\n> -                      boost::property_tree::ptree const &params)\n> +static int readCtCurve(Pwl &ctR, Pwl &ctB, const libcamera::YamlObject\n> &params)\n>  {\n> -       int num = 0;\n> -       for (auto it = params.begin(); it != params.end(); it++) {\n> -               double ct = it->second.get_value<double>();\n> -               assert(it == params.begin() || ct != ctR.domain().end);\n> -               if (++it == params.end()) {\n> -                       LOG(RPiAwb, Error) << \"AwbConfig: incomplete CT\n> curve entry\";\n> -                       return -EINVAL;\n> -               }\n> -               ctR.append(ct, it->second.get_value<double>());\n> -               if (++it == params.end()) {\n> -                       LOG(RPiAwb, Error) << \"AwbConfig: incomplete CT\n> curve entry\";\n> -                       return -EINVAL;\n> -               }\n> -               ctB.append(ct, it->second.get_value<double>());\n> -               num++;\n> +       if (params.size() % 3) {\n> +               LOG(RPiAwb, Error) << \"AwbConfig: incomplete CT curve\n> entry\";\n> +               return -EINVAL;\n>         }\n> -       if (num < 2) {\n> +\n> +       if (params.size() < 6) {\n>                 LOG(RPiAwb, Error) << \"AwbConfig: insufficient points in\n> CT curve\";\n>                 return -EINVAL;\n>         }\n> +\n> +       const auto &list = params.asList();\n> +\n> +       for (auto it = list.begin(); it != list.end(); it++) {\n> +               auto value = it->get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               double ct = *value;\n> +\n> +               assert(it == list.begin() || ct != ctR.domain().end);\n> +\n> +               value = (++it)->get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               ctR.append(ct, *value);\n> +\n> +               value = (++it)->get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               ctB.append(ct, *value);\n> +       }\n> +\n>         return 0;\n>  }\n>\n> -int AwbConfig::read(boost::property_tree::ptree const &params)\n> +int AwbConfig::read(const libcamera::YamlObject &params)\n>  {\n>         int ret;\n> -       bayes = params.get<int>(\"bayes\", 1);\n> -       framePeriod = params.get<uint16_t>(\"framePeriod\", 10);\n> -       startupFrames = params.get<uint16_t>(\"startupFrames\", 10);\n> -       convergenceFrames = params.get<unsigned int>(\"convergence_frames\",\n> 3);\n> -       speed = params.get<double>(\"speed\", 0.05);\n> -       if (params.get_child_optional(\"ct_curve\")) {\n> -               ret = readCtCurve(ctR, ctB, params.get_child(\"ct_curve\"));\n> +\n> +       bayes = params[\"bayes\"].get<int>(1);\n> +       framePeriod = params[\"frame_period\"].get<uint16_t>(10);\n> +       startupFrames = params[\"startup_frames\"].get<uint16_t>(10);\n> +       convergenceFrames = params[\"convergence_frames\"].get<unsigned\n> int>(3);\n> +       speed = params[\"speed\"].get<double>(0.05);\n> +\n> +       if (params.contains(\"ct_curve\")) {\n> +               ret = readCtCurve(ctR, ctB, params[\"ct_curve\"]);\n>                 if (ret)\n>                         return ret;\n>         }\n> -       if (params.get_child_optional(\"priors\")) {\n> -               for (auto &p : params.get_child(\"priors\")) {\n> +\n> +       if (params.contains(\"priors\")) {\n> +               for (const auto &p : params[\"priors\"].asList()) {\n>                         AwbPrior prior;\n> -                       ret = prior.read(p.second);\n> +                       ret = prior.read(p);\n>                         if (ret)\n>                                 return ret;\n>                         if (!priors.empty() && prior.lux <=\n> priors.back().lux) {\n> @@ -95,32 +122,35 @@ int AwbConfig::read(boost::property_tree::ptree const\n> &params)\n>                         return ret;\n>                 }\n>         }\n> -       if (params.get_child_optional(\"modes\")) {\n> -               for (auto &p : params.get_child(\"modes\")) {\n> -                       ret = modes[p.first].read(p.second);\n> +       if (params.contains(\"modes\")) {\n> +               for (const auto &[key, value] : params[\"modes\"].asDict()) {\n> +                       ret = modes[key].read(value);\n>                         if (ret)\n>                                 return ret;\n>                         if (defaultMode == nullptr)\n> -                               defaultMode = &modes[p.first];\n> +                               defaultMode = &modes[key];\n>                 }\n>                 if (defaultMode == nullptr) {\n>                         LOG(RPiAwb, Error) << \"AwbConfig: no AWB modes\n> configured\";\n>                         return -EINVAL;\n>                 }\n>         }\n> -       minPixels = params.get<double>(\"min_pixels\", 16.0);\n> -       minG = params.get<uint16_t>(\"min_G\", 32);\n> -       minRegions = params.get<uint32_t>(\"min_regions\", 10);\n> -       deltaLimit = params.get<double>(\"delta_limit\", 0.2);\n> -       coarseStep = params.get<double>(\"coarse_step\", 0.2);\n> -       transversePos = params.get<double>(\"transverse_pos\", 0.01);\n> -       transverseNeg = params.get<double>(\"transverse_neg\", 0.01);\n> +\n> +       minPixels = params[\"min_pixels\"].get<double>(16.0);\n> +       minG = params[\"min_G\"].get<uint16_t>(32);\n> +       minRegions = params[\"min_regions\"].get<uint32_t>(10);\n> +       deltaLimit = params[\"delta_limit\"].get<double>(0.2);\n> +       coarseStep = params[\"coarse_step\"].get<double>(0.2);\n> +       transversePos = params[\"transverse_pos\"].get<double>(0.01);\n> +       transverseNeg = params[\"transverse_neg\"].get<double>(0.01);\n>         if (transversePos <= 0 || transverseNeg <= 0) {\n>                 LOG(RPiAwb, Error) << \"AwbConfig: transverse_pos/neg must\n> be > 0\";\n>                 return -EINVAL;\n>         }\n> -       sensitivityR = params.get<double>(\"sensitivity_r\", 1.0);\n> -       sensitivityB = params.get<double>(\"sensitivity_b\", 1.0);\n> +\n> +       sensitivityR = params[\"sensitivity_r\"].get<double>(1.0);\n> +       sensitivityB = params[\"sensitivity_b\"].get<double>(1.0);\n> +\n>         if (bayes) {\n>                 if (ctR.empty() || ctB.empty() || priors.empty() ||\n>                     defaultMode == nullptr) {\n> @@ -129,9 +159,9 @@ int AwbConfig::read(boost::property_tree::ptree const\n> &params)\n>                         bayes = false;\n>                 }\n>         }\n> -       fast = params.get<int>(\"fast\", bayes); /* default to fast for\n> Bayesian, otherwise slow */\n> -       whitepointR = params.get<double>(\"whitepoint_r\", 0.0);\n> -       whitepointB = params.get<double>(\"whitepoint_b\", 0.0);\n> +       fast = params[fast].get<int>(bayes); /* default to fast for\n> Bayesian, otherwise slow */\n> +       whitepointR = params[\"whitepoint_r\"].get<double>(0.0);\n> +       whitepointB = params[\"whitepoint_b\"].get<double>(0.0);\n>         if (bayes == false)\n>                 sensitivityR = sensitivityB = 1.0; /* nor do sensitivities\n> make any sense */\n>         return 0;\n> @@ -162,7 +192,7 @@ char const *Awb::name() const\n>         return NAME;\n>  }\n>\n> -int Awb::read(boost::property_tree::ptree const &params)\n> +int Awb::read(const libcamera::YamlObject &params)\n>  {\n>         return config_.read(params);\n>  }\n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.h\n> b/src/ipa/raspberrypi/controller/rpi/awb.h\n> index 9c5cf4eaaaaf..cb4cfd1be2e8 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.h\n> @@ -19,20 +19,20 @@ namespace RPiController {\n>  /* Control algorithm to perform AWB calculations. */\n>\n>  struct AwbMode {\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>         double ctLo; /* low CT value for search */\n>         double ctHi; /* high CT value for search */\n>  };\n>\n>  struct AwbPrior {\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>         double lux; /* lux level */\n>         Pwl prior; /* maps CT to prior log likelihood for this lux level */\n>  };\n>\n>  struct AwbConfig {\n>         AwbConfig() : defaultMode(nullptr) {}\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>         /* Only repeat the AWB calculation every \"this many\" frames */\n>         uint16_t framePeriod;\n>         /* number of initial frames for which speed taken as 1.0 (maximum)\n> */\n> @@ -90,7 +90,7 @@ public:\n>         ~Awb();\n>         char const *name() const override;\n>         void initialise() override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         /* AWB handles \"pausing\" for itself. */\n>         bool isPaused() const override;\n>         void pause() override;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.cpp\n> b/src/ipa/raspberrypi/controller/rpi/black_level.cpp\n> index 749fcd7cdf8c..85baec3fcbdd 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/black_level.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/black_level.cpp\n> @@ -31,13 +31,13 @@ char const *BlackLevel::name() const\n>         return NAME;\n>  }\n>\n> -int BlackLevel::read(boost::property_tree::ptree const &params)\n> +int BlackLevel::read(const libcamera::YamlObject &params)\n>  {\n> -       uint16_t blackLevel = params.get<uint16_t>(\n> -               \"black_level\", 4096); /* 64 in 10 bits scaled to 16 bits */\n> -       blackLevelR_ = params.get<uint16_t>(\"black_level_r\", blackLevel);\n> -       blackLevelG_ = params.get<uint16_t>(\"black_level_g\", blackLevel);\n> -       blackLevelB_ = params.get<uint16_t>(\"black_level_b\", blackLevel);\n> +       /* 64 in 10 bits scaled to 16 bits */\n> +       uint16_t blackLevel = params[\"black_level\"].get<uint16_t>(4096);\n> +       blackLevelR_ = params[\"black_level_r\"].get<uint16_t>(blackLevel);\n> +       blackLevelG_ = params[\"black_level_g\"].get<uint16_t>(blackLevel);\n> +       blackLevelB_ = params[\"black_level_b\"].get<uint16_t>(blackLevel);\n>         LOG(RPiBlackLevel, Debug)\n>                 << \" Read black levels red \" << blackLevelR_\n>                 << \" green \" << blackLevelG_\n> diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.h\n> b/src/ipa/raspberrypi/controller/rpi/black_level.h\n> index 6ec8c4f9ba8f..2403f7f77625 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/black_level.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/black_level.h\n> @@ -18,7 +18,7 @@ class BlackLevel : public Algorithm\n>  public:\n>         BlackLevel(Controller *controller);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>\n>  private:\n> diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.cpp\n> b/src/ipa/raspberrypi/controller/rpi/ccm.cpp\n> index 9588e94adeb1..2e2e66647e86 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/ccm.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/ccm.cpp\n> @@ -39,21 +39,22 @@ Matrix::Matrix(double m0, double m1, double m2, double\n> m3, double m4, double m5,\n>         m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] =\n> m4,\n>         m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8;\n>  }\n> -int Matrix::read(boost::property_tree::ptree const &params)\n> +int Matrix::read(const libcamera::YamlObject &params)\n>  {\n>         double *ptr = (double *)m;\n> -       int n = 0;\n> -       for (auto it = params.begin(); it != params.end(); it++) {\n> -               if (n++ == 9) {\n> -                       LOG(RPiCcm, Error) << \"Too many values in CCM\";\n> -                       return -EINVAL;\n> -               }\n> -               *ptr++ = it->second.get_value<double>();\n> -       }\n> -       if (n < 9) {\n> -               LOG(RPiCcm, Error) << \"Too few values in CCM\";\n> +\n> +       if (params.size() != 9) {\n> +               LOG(RPiCcm, Error) << \"Wrong number of values in CCM\";\n>                 return -EINVAL;\n>         }\n> +\n> +       for (const auto &param : params.asList()) {\n> +               auto value = param.get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +               *ptr++ = *value;\n> +       }\n> +\n>         return 0;\n>  }\n>\n> @@ -65,27 +66,33 @@ char const *Ccm::name() const\n>         return NAME;\n>  }\n>\n> -int Ccm::read(boost::property_tree::ptree const &params)\n> +int Ccm::read(const libcamera::YamlObject &params)\n>  {\n>         int ret;\n>\n> -       if (params.get_child_optional(\"saturation\")) {\n> -               ret =\n> config_.saturation.read(params.get_child(\"saturation\"));\n> +       if (params.contains(\"saturation\")) {\n> +               ret = config_.saturation.read(params[\"saturation\"]);\n>                 if (ret)\n>                         return ret;\n>         }\n>\n> -       for (auto &p : params.get_child(\"ccms\")) {\n> +       for (auto &p : params[\"ccms\"].asList()) {\n> +               auto value = p[\"ct\"].get<double>();\n> +               if (!value)\n> +                       return -EINVAL;\n> +\n>                 CtCcm ctCcm;\n> -               ctCcm.ct = p.second.get<double>(\"ct\");\n> -               ret = ctCcm.ccm.read(p.second.get_child(\"ccm\"));\n> +               ctCcm.ct = *value;\n> +               ret = ctCcm.ccm.read(p[\"ccm\"]);\n>                 if (ret)\n>                         return ret;\n> -               if (!config_.ccms.empty() &&\n> -                   ctCcm.ct <= config_.ccms.back().ct) {\n> -                       LOG(RPiCcm, Error) << \"CCM not in increasing\n> colour temperature order\";\n> +\n> +               if (!config_.ccms.empty() && ctCcm.ct <=\n> config_.ccms.back().ct) {\n> +                       LOG(RPiCcm, Error)\n> +                               << \"CCM not in increasing colour\n> temperature order\";\n>                         return -EINVAL;\n>                 }\n> +\n>                 config_.ccms.push_back(std::move(ctCcm));\n>         }\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.h\n> b/src/ipa/raspberrypi/controller/rpi/ccm.h\n> index 6b65c7aea8a6..286d0b33e72f 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/ccm.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/ccm.h\n> @@ -20,7 +20,7 @@ struct Matrix {\n>                double m6, double m7, double m8);\n>         Matrix();\n>         double m[3][3];\n> -       int read(boost::property_tree::ptree const &params);\n> +       int read(const libcamera::YamlObject &params);\n>  };\n>  static inline Matrix operator*(double d, Matrix const &m)\n>  {\n> @@ -62,7 +62,7 @@ class Ccm : public CcmAlgorithm\n>  public:\n>         Ccm(Controller *controller = NULL);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void setSaturation(double saturation) override;\n>         void initialise() override;\n>         void prepare(Metadata *imageMetadata) override;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.cpp\n> b/src/ipa/raspberrypi/controller/rpi/contrast.cpp\n> index d76dc43b837f..5b37edcbd46a 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/contrast.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/contrast.cpp\n> @@ -38,21 +38,21 @@ char const *Contrast::name() const\n>         return NAME;\n>  }\n>\n> -int Contrast::read(boost::property_tree::ptree const &params)\n> +int Contrast::read(const libcamera::YamlObject &params)\n>  {\n> -       /* enable adaptive enhancement by default */\n> -       config_.ceEnable = params.get<int>(\"ce_enable\", 1);\n> -       /* the point near the bottom of the histogram to move */\n> -       config_.loHistogram = params.get<double>(\"lo_histogram\", 0.01);\n> -       /* where in the range to try and move it to */\n> -       config_.loLevel = params.get<double>(\"lo_level\", 0.015);\n> -       /* but don't move by more than this */\n> -       config_.loMax = params.get<double>(\"lo_max\", 500);\n> -       /* equivalent values for the top of the histogram... */\n> -       config_.hiHistogram = params.get<double>(\"hi_histogram\", 0.95);\n> -       config_.hiLevel = params.get<double>(\"hi_level\", 0.95);\n> -       config_.hiMax = params.get<double>(\"hi_max\", 2000);\n> -       return config_.gammaCurve.read(params.get_child(\"gamma_curve\"));\n> +       // enable adaptive enhancement by default\n> +       config_.ceEnable = params[\"ce_enable\"].get<int>(1);\n> +       // the point near the bottom of the histogram to move\n> +       config_.loHistogram = params[\"lo_histogram\"].get<double>(0.01);\n> +       // where in the range to try and move it to\n> +       config_.loLevel = params[\"lo_level\"].get<double>(0.015);\n> +       // but don't move by more than this\n> +       config_.loMax = params[\"lo_max\"].get<double>(500);\n> +       // equivalent values for the top of the histogram...\n> +       config_.hiHistogram = params[\"hi_histogram\"].get<double>(0.95);\n> +       config_.hiLevel = params[\"hi_level\"].get<double>(0.95);\n> +       config_.hiMax = params[\"hi_max\"].get<double>(2000);\n> +       return config_.gammaCurve.read(params[\"gamma_curve\"]);\n>  }\n>\n>  void Contrast::setBrightness(double brightness)\n> diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.h\n> b/src/ipa/raspberrypi/controller/rpi/contrast.h\n> index 5c3d2f56b310..c68adbc9e463 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/contrast.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/contrast.h\n> @@ -34,7 +34,7 @@ class Contrast : public ContrastAlgorithm\n>  public:\n>         Contrast(Controller *controller = NULL);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void setBrightness(double brightness) override;\n>         void setContrast(double contrast) override;\n>         void initialise() override;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.cpp\n> b/src/ipa/raspberrypi/controller/rpi/dpc.cpp\n> index def39bb7416a..be3871dffe28 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/dpc.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/dpc.cpp\n> @@ -31,13 +31,14 @@ char const *Dpc::name() const\n>         return NAME;\n>  }\n>\n> -int Dpc::read(boost::property_tree::ptree const &params)\n> +int Dpc::read(const libcamera::YamlObject &params)\n>  {\n> -       config_.strength = params.get<int>(\"strength\", 1);\n> +       config_.strength = params[\"strength\"].get<int>(1);\n>         if (config_.strength < 0 || config_.strength > 2) {\n> -               LOG(RPiDpc, Error) << \"bad strength value\";\n> +               LOG(RPiDpc, Error) << \"Bad strength value\";\n>                 return -EINVAL;\n>         }\n> +\n>         return 0;\n>  }\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.h\n> b/src/ipa/raspberrypi/controller/rpi/dpc.h\n> index 2bb6cef565a7..84a05604394d 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/dpc.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/dpc.h\n> @@ -22,7 +22,7 @@ class Dpc : public Algorithm\n>  public:\n>         Dpc(Controller *controller);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>\n>  private:\n> diff --git a/src/ipa/raspberrypi/controller/rpi/geq.cpp\n> b/src/ipa/raspberrypi/controller/rpi/geq.cpp\n> index 106f0a40dfc1..510870e9edbf 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/geq.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/geq.cpp\n> @@ -35,17 +35,17 @@ char const *Geq::name() const\n>         return NAME;\n>  }\n>\n> -int Geq::read(boost::property_tree::ptree const &params)\n> +int Geq::read(const libcamera::YamlObject &params)\n>  {\n> -       config_.offset = params.get<uint16_t>(\"offset\", 0);\n> -       config_.slope = params.get<double>(\"slope\", 0.0);\n> +       config_.offset = params[\"offset\"].get<uint16_t>(0);\n> +       config_.slope = params[\"slope\"].get<double>(0.0);\n>         if (config_.slope < 0.0 || config_.slope >= 1.0) {\n>                 LOG(RPiGeq, Error) << \"Bad slope value\";\n>                 return -EINVAL;\n>         }\n>\n> -       if (params.get_child_optional(\"strength\")) {\n> -               int ret =\n> config_.strength.read(params.get_child(\"strength\"));\n> +       if (params.contains(\"strength\")) {\n> +               int ret = config_.strength.read(params[\"strength\"]);\n>                 if (ret)\n>                         return ret;\n>         }\n> diff --git a/src/ipa/raspberrypi/controller/rpi/geq.h\n> b/src/ipa/raspberrypi/controller/rpi/geq.h\n> index 677a0510c6ac..ee3a52ff50f5 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/geq.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/geq.h\n> @@ -24,7 +24,7 @@ class Geq : public Algorithm\n>  public:\n>         Geq(Controller *controller);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>\n>  private:\n> diff --git a/src/ipa/raspberrypi/controller/rpi/lux.cpp\n> b/src/ipa/raspberrypi/controller/rpi/lux.cpp\n> index ca1e827191fd..9759186afacf 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/lux.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/lux.cpp\n> @@ -38,14 +38,30 @@ char const *Lux::name() const\n>         return NAME;\n>  }\n>\n> -int Lux::read(boost::property_tree::ptree const &params)\n> +int Lux::read(const libcamera::YamlObject &params)\n>  {\n> -       referenceShutterSpeed_ =\n> -               params.get<double>(\"reference_shutter_speed\") * 1.0us;\n> -       referenceGain_ = params.get<double>(\"reference_gain\");\n> -       referenceAperture_ = params.get<double>(\"reference_aperture\", 1.0);\n> -       referenceY_ = params.get<double>(\"reference_Y\");\n> -       referenceLux_ = params.get<double>(\"reference_lux\");\n> +       auto value = params[\"reference_shutter_speed\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceShutterSpeed_ = *value * 1.0us;\n> +\n> +       value = params[\"reference_gain\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceGain_ = *value;\n> +\n> +       referenceAperture_ = params[\"reference_aperture\"].get<double>(1.0);\n> +\n> +       value = params[\"reference_Y\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceY_ = *value;\n> +\n> +       value = params[\"reference_lux\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceLux_ = *value;\n> +\n>         currentAperture_ = referenceAperture_;\n>         return 0;\n>  }\n> diff --git a/src/ipa/raspberrypi/controller/rpi/lux.h\n> b/src/ipa/raspberrypi/controller/rpi/lux.h\n> index 6416dfb52553..89411a5432b4 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/lux.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/lux.h\n> @@ -22,7 +22,7 @@ class Lux : public Algorithm\n>  public:\n>         Lux(Controller *controller);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>         void process(StatisticsPtr &stats, Metadata *imageMetadata)\n> override;\n>         void setCurrentAperture(double aperture);\n> diff --git a/src/ipa/raspberrypi/controller/rpi/noise.cpp\n> b/src/ipa/raspberrypi/controller/rpi/noise.cpp\n> index 74fa99bafe48..bcd8b9edaebe 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/noise.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/noise.cpp\n> @@ -41,10 +41,18 @@ void Noise::switchMode(CameraMode const &cameraMode,\n>         modeFactor_ = std::max(1.0, cameraMode.noiseFactor);\n>  }\n>\n> -int Noise::read(boost::property_tree::ptree const &params)\n> +int Noise::read(const libcamera::YamlObject &params)\n>  {\n> -       referenceConstant_ = params.get<double>(\"reference_constant\");\n> -       referenceSlope_ = params.get<double>(\"reference_slope\");\n> +       auto value = params[\"reference_constant\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceConstant_ = *value;\n> +\n> +       value = params[\"reference_slope\"].get<double>();\n> +       if (!value)\n> +               return -EINVAL;\n> +       referenceSlope_ = *value;\n> +\n>         return 0;\n>  }\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/noise.h\n> b/src/ipa/raspberrypi/controller/rpi/noise.h\n> index b33a5fc75ec7..74c31e640c3f 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/noise.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/noise.h\n> @@ -19,7 +19,7 @@ public:\n>         Noise(Controller *controller);\n>         char const *name() const override;\n>         void switchMode(CameraMode const &cameraMode, Metadata *metadata)\n> override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void prepare(Metadata *imageMetadata) override;\n>\n>  private:\n> diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.cpp\n> b/src/ipa/raspberrypi/controller/rpi/sdn.cpp\n> index 03d9f119a338..b6b662518f2c 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/sdn.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/sdn.cpp\n> @@ -34,10 +34,10 @@ char const *Sdn::name() const\n>         return NAME;\n>  }\n>\n> -int Sdn::read(boost::property_tree::ptree const &params)\n> +int Sdn::read(const libcamera::YamlObject &params)\n>  {\n> -       deviation_ = params.get<double>(\"deviation\", 3.2);\n> -       strength_ = params.get<double>(\"strength\", 0.75);\n> +       deviation_ = params[\"deviation\"].get<double>(3.2);\n> +       strength_ = params[\"strength\"].get<double>(0.75);\n>         return 0;\n>  }\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.h\n> b/src/ipa/raspberrypi/controller/rpi/sdn.h\n> index 4287ef08a79f..9dd73c388edb 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/sdn.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/sdn.h\n> @@ -18,7 +18,7 @@ class Sdn : public DenoiseAlgorithm\n>  public:\n>         Sdn(Controller *controller = NULL);\n>         char const *name() const override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void initialise() override;\n>         void prepare(Metadata *imageMetadata) override;\n>         void setMode(DenoiseMode mode) override;\n> diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp\n> b/src/ipa/raspberrypi/controller/rpi/sharpen.cpp\n> index 9c4cffa4128c..4f6f020a417b 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/sharpen.cpp\n> @@ -37,11 +37,11 @@ void Sharpen::switchMode(CameraMode const &cameraMode,\n>         modeFactor_ = std::max(1.0, cameraMode.noiseFactor);\n>  }\n>\n> -int Sharpen::read(boost::property_tree::ptree const &params)\n> +int Sharpen::read(const libcamera::YamlObject &params)\n>  {\n> -       threshold_ = params.get<double>(\"threshold\", 1.0);\n> -       strength_ = params.get<double>(\"strength\", 1.0);\n> -       limit_ = params.get<double>(\"limit\", 1.0);\n> +       threshold_ = params[\"threshold\"].get<double>(1.0);\n> +       strength_ = params[\"strength\"].get<double>(1.0);\n> +       limit_ = params[\"limit\"].get<double>(1.0);\n>         LOG(RPiSharpen, Debug)\n>                 << \"Read threshold \" << threshold_\n>                 << \" strength \" << strength_\n> diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.h\n> b/src/ipa/raspberrypi/controller/rpi/sharpen.h\n> index 0cd8b92f2224..8bb7631e916b 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/sharpen.h\n> +++ b/src/ipa/raspberrypi/controller/rpi/sharpen.h\n> @@ -19,7 +19,7 @@ public:\n>         Sharpen(Controller *controller);\n>         char const *name() const override;\n>         void switchMode(CameraMode const &cameraMode, Metadata *metadata)\n> override;\n> -       int read(boost::property_tree::ptree const &params) override;\n> +       int read(const libcamera::YamlObject &params) override;\n>         void setStrength(double strength) override;\n>         void prepare(Metadata *imageMetadata) override;\n>\n> diff --git a/src/ipa/raspberrypi/meson.build\n> b/src/ipa/raspberrypi/meson.build\n> index 32897e07dad9..517d815bb98c 100644\n> --- a/src/ipa/raspberrypi/meson.build\n> +++ b/src/ipa/raspberrypi/meson.build\n> @@ -4,7 +4,6 @@ ipa_name = 'ipa_rpi'\n>\n>  rpi_ipa_deps = [\n>      libcamera_private,\n> -    dependency('boost'),\n>      libatomic,\n>  ]\n>\n> diff --git a/src/ipa/raspberrypi/raspberrypi.cpp\n> b/src/ipa/raspberrypi/raspberrypi.cpp\n> index b9e9b814e886..6befdd71433d 100644\n> --- a/src/ipa/raspberrypi/raspberrypi.cpp\n> +++ b/src/ipa/raspberrypi/raspberrypi.cpp\n> @@ -7,6 +7,7 @@\n>\n>  #include <algorithm>\n>  #include <array>\n> +#include <cstring>\n>  #include <fcntl.h>\n>  #include <math.h>\n>  #include <stdint.h>\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\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 676B4C3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 28 Jul 2022 07:08:28 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9A8AB63311;\n\tThu, 28 Jul 2022 09:08:27 +0200 (CEST)","from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com\n\t[IPv6:2a00:1450:4864:20::12a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3C508603EB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 28 Jul 2022 09:08:25 +0200 (CEST)","by mail-lf1-x12a.google.com with SMTP id p11so1551728lfu.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 28 Jul 2022 00:08:25 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1658992107;\n\tbh=VIG1qMRwcMl8etKNEphtGufgAbU2ei4Jfl5xFIrVu/k=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=fnZJ+eycOttJoI3Upr9Hm9fH9GMaxSC1S+WFRmrqjmpC0jVguEzNQT+0+0TcWYQV8\n\tPyDfW/ut7KJkclws8UFArdpvbyp3u8d6oXFMIEjLN9JYvcXOm9yx69HpP/9o7ZlTNA\n\tQMqQ8Oanp3zc7umKQ36TtKHdH2epSQ1210Ovkm6cAFwnWfWUObOu1sgj826Iaz/Tcb\n\t3+EOd/2DE20QFBA9JzjM8IkjcvpgTpZ5zSfxx6DO+mv+yfkkV2W8My3Suu0Ns7woZ0\n\t7KGVmdHO029cvG5om/IwLT8Vt2MM4TZX1vkf6uEdlwtJVaJ/4DgXj3GeYB4tLFwEVl\n\tpEafMhwgUnTOg==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=M4n6yzPlqdgYYX9QcdNFy75vFVtdRXZzt2hnFOPSXCU=;\n\tb=GPACGLtfMv2ViamW8d6usmAWEmI6p8A6aKT/dNf9aiL+hbBk4VrKncAYkwbujPnqee\n\t64zbvXB4Nk2hut2bSCboEgGxixRqHvbtAWDq4FLGwmm3aQKmMwBbETxwoW8wltHcpaLk\n\tG6jNEowTtqZNRkTXTZgOuW3FCmxfVedLqbrf7iaM7gTrrNwjxiUxhmpwizlEkB+vQbEn\n\tFqjtFDHGn56CBYAvdOsBK8Z2KbqpQtye5P7xj8eGEAKYBhEmUZYGFmJzGpNYOboY3RcH\n\tGGSg7zgpEehgiYRtv4+yiJ4Gd7a4hBWW5yp3sHkigxAEC9qbGmdPR25cbq18GuPo0Yrk\n\tBozA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"GPACGLtf\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=M4n6yzPlqdgYYX9QcdNFy75vFVtdRXZzt2hnFOPSXCU=;\n\tb=St+bRX147EKLoqp5abgVbxEyEFyxforoBD7ZBcSfbnOGMrXAGxHrQAnN0akiIGiDUw\n\tdcC/L8rufhyvIggqY04POXgiSgtj4Qf10ezX1EoUNT8nkTeyv46kno2X/3Li9plp2/m4\n\tG4/t9EEWdVAcXw78rpizkqwYNJJGKn1pdfEEduKFiaeGQM1yR33cEynGF0KiWMFZ86zv\n\tFz9ZMiZDI06Fzu6DJAP592dkL3GOpvAIBXL226BkO1/oAVFDSZX/yxwFPynvz4YEaK6O\n\tnk9GHm0+AtUbfI1DWJ5px029T66F5TMaytz35J86mEfQV6zgBKjeks8AHCAipv4NFeS/\n\t9Hzg==","X-Gm-Message-State":"AJIora89HIvCDlEaWRCyUPpmh5ipDOmurZ40YmbcUDI7CnlkUYbt2mp1\n\tsEliJqU3+CeuQ/MjfIg0DGZvN08qj7NH/puwhVx68AEID10=","X-Google-Smtp-Source":"AGRyM1tinP/I4nrd1SjvPuM8lNDl5ltSrI86zwWe01XuixBwQAO/mQK6eb65UY41MpPg+HbeeLHTd13D+ajpk9uDKy0=","X-Received":"by 2002:a05:6512:baa:b0:48a:b09e:f299 with SMTP id\n\tb42-20020a0565120baa00b0048ab09ef299mr3395128lfv.38.1658992104057;\n\tThu, 28 Jul 2022 00:08:24 -0700 (PDT)","MIME-Version":"1.0","References":"<20220727023816.30008-9-laurent.pinchart@ideasonboard.com>\n\t<20220727174352.21332-1-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20220727174352.21332-1-laurent.pinchart@ideasonboard.com>","Date":"Thu, 28 Jul 2022 08:08:07 +0100","Message-ID":"<CAEmqJPrHp_C=USVj1xVC89gOC8_s_LwaRNp55UgLZhUAKstrcQ@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"multipart/alternative; boundary=\"0000000000000c484605e4d8336f\"","Subject":"Re: [libcamera-devel] [PATCH v7.1 13/14] ipa: raspberrypi: Use\n\tYamlParser to replace dependency on boost","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":"Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]