From patchwork Sat Jun 4 18:59:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16156 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 4B496C326B for ; Sat, 4 Jun 2022 19:00:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C680E633A6; Sat, 4 Jun 2022 21:00:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369200; bh=c+sScQK4fT7hxRiMXqN58bPZT5GyrKJgbTvVGkrF0lI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=buEGYi0WsOyR3Zbav+TVu88AlJ/8s32iDbalgQkOppOIQ3ywAxOD1Wg/HFyUI+kCG /WAeMTXRDm8yWFoZFb2gLx1B2YwEVXRXT01/RBmA3OQdGq4svjvJOk8Ufbd2poYdDM MAcw9baz22ezetBSCJrARxBxwbTjgvlF4RBZn5L3nhLW2G43w7gveBnSo/VXfH31j6 6JLbK51tB38fszzFu3r3agsIWeGF9/RKN190uqsjr2gplOp5O2BNwzR9mv8HAR421G wtxDAYkj2DxFzZMmIkvv2bYBr0C7Ai4XlCZ7OOdRb11wr6IWfniu3eL0mp+enQsYD9 WUNGKe6cWQT1Q== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5EC9865632 for ; Sat, 4 Jun 2022 20:59:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UiGVzp+M"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 288DD87A; Sat, 4 Jun 2022 20:59:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369198; bh=c+sScQK4fT7hxRiMXqN58bPZT5GyrKJgbTvVGkrF0lI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UiGVzp+MmRfpl4ZMvQlwrJTLVd+YkldgRV5dsMyWdBehtJAg8kB4lv5RUfLQ+Jjl/ 6FxNtvl9t6tBLsjCJXe5syXh8Hberu5oetZuogOInMUj8ssRnDL3jm6KrJyglV2cap t+nLDq+GutD9gIP57R7fInwZkBA/zsld21R6fz8k= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:26 +0300 Message-Id: <20220604185939.29163-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 01/14] libcamera: yaml_object: Turn Type into an enum class X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Turn the Type enum into an enum class to force qualifying 'List' and 'Dictionary' in the YamlObject namespace scope. This will help avoiding ambiguities when adding iterator support. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder --- include/libcamera/internal/yaml_parser.h | 8 +++--- src/libcamera/yaml_parser.cpp | 32 ++++++++++++------------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index 3a4f3052fb65..e002fcf59278 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -28,15 +28,15 @@ public: bool isValue() const { - return type_ == Value; + return type_ == Type::Value; } bool isList() const { - return type_ == List; + return type_ == Type::List; } bool isDictionary() const { - return type_ == Dictionary; + return type_ == Type::Dictionary; } #ifndef __DOXYGEN__ @@ -65,7 +65,7 @@ private: friend class YamlParserContext; - enum Type { + enum class Type { Dictionary, List, Value, diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 92fedaebebfd..4b5ea427bf45 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -47,7 +47,7 @@ void setOk(bool *ok, bool result) */ YamlObject::YamlObject() - : type_(Value) + : type_(Type::Value) { } @@ -99,7 +99,7 @@ bool YamlObject::get(const bool &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != Value) + if (type_ != Type::Value) return defaultValue; if (value_ == "true") { @@ -118,7 +118,7 @@ int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != Value) + if (type_ != Type::Value) return defaultValue; if (value_ == "") @@ -141,7 +141,7 @@ uint32_t YamlObject::get(const uint32_t &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != Value) + if (type_ != Type::Value) return defaultValue; if (value_ == "") @@ -175,7 +175,7 @@ double YamlObject::get(const double &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != Value) + if (type_ != Type::Value) return defaultValue; if (value_ == "") @@ -198,7 +198,7 @@ std::string YamlObject::get(const std::string &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != Value) + if (type_ != Type::Value) return defaultValue; setOk(ok, true); @@ -210,7 +210,7 @@ Size YamlObject::get(const Size &defaultValue, bool *ok) const { setOk(ok, false); - if (type_ != List) + if (type_ != Type::List) return defaultValue; if (list_.size() != 2) @@ -248,7 +248,7 @@ Size YamlObject::get(const Size &defaultValue, bool *ok) const */ std::size_t YamlObject::size() const { - if (type_ != List) + if (type_ != Type::List) return 0; return list_.size(); @@ -266,7 +266,7 @@ std::size_t YamlObject::size() const */ const YamlObject &YamlObject::operator[](std::size_t index) const { - if (type_ != List || index >= size()) + if (type_ != Type::List || index >= size()) return empty; return *list_[index]; @@ -326,7 +326,7 @@ std::vector YamlObject::memberNames() const */ const YamlObject &YamlObject::operator[](const std::string &key) const { - if (type_ != Dictionary || !contains(key)) + if (type_ != Type::Dictionary || !contains(key)) return empty; auto iter = dictionary_.find(key); @@ -510,7 +510,7 @@ int YamlParserContext::parseDictionaryOrList(YamlObject::Type type, const std::function &parseItem) { yaml_event_type_t endEventType = YAML_SEQUENCE_END_EVENT; - if (type == YamlObject::Dictionary) + if (type == YamlObject::Type::Dictionary) endEventType = YAML_MAPPING_END_EVENT; /* @@ -554,22 +554,22 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even switch (event->type) { case YAML_SCALAR_EVENT: - yamlObject.type_ = YamlObject::Value; + yamlObject.type_ = YamlObject::Type::Value; readValue(yamlObject.value_, std::move(event)); return 0; case YAML_SEQUENCE_START_EVENT: { - yamlObject.type_ = YamlObject::List; + yamlObject.type_ = YamlObject::Type::List; auto &list = yamlObject.list_; auto handler = [this, &list](EventPtr evt) { list.emplace_back(new YamlObject()); return parseNextYamlObject(*list.back(), std::move(evt)); }; - return parseDictionaryOrList(YamlObject::List, handler); + return parseDictionaryOrList(YamlObject::Type::List, handler); } case YAML_MAPPING_START_EVENT: { - yamlObject.type_ = YamlObject::Dictionary; + yamlObject.type_ = YamlObject::Type::Dictionary; auto &dictionary = yamlObject.dictionary_; auto handler = [this, &dictionary](EventPtr evtKey) { /* Parse key */ @@ -592,7 +592,7 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even auto elem = dictionary.emplace(key, std::make_unique()); return parseNextYamlObject(*elem.first->second.get(), std::move(evtValue)); }; - return parseDictionaryOrList(YamlObject::Dictionary, handler); + return parseDictionaryOrList(YamlObject::Type::Dictionary, handler); } default: From patchwork Sat Jun 4 18:59:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16157 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 61F8BC3273 for ; Sat, 4 Jun 2022 19:00:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 366A865639; Sat, 4 Jun 2022 21:00:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369201; bh=nhjLA//4m1HvlSUtXkPDjGURRb36QN5w86OMCpUkbyc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Uoo1IiCsDxI2iFbQkz82wu18OvOy/l4dMyAFsIhmBbEOdtsWQzEqm3msiMy/xCvEr lScRHbVJ5VHZmqut1bQ0LltO19fUNz+06ao1hcw4WduzUsOEOwDu1GAnJG7YDtHwm3 BjtYSZ1gQm1mdMhqPRi7CX/rTxCN8mDsL0DqgwT8twomdeEGVJbBqNNIvA1PCEgMGT 0msUKlNSNp8811F09jl5ZdIKEid0XogH5uYzchvrSc3j7J2innVE/gLPDEZmDolmvy R/haNubhkgumGSKCsF5gyTYxU75Ea7Cu1AuWQyAwAJCQ6nJYXvFa+uwMIp4vuK/Fp6 g9Sli870EIlqA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0722765632 for ; Sat, 4 Jun 2022 21:00:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XExsG9DY"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C43EB6D4; Sat, 4 Jun 2022 20:59:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369199; bh=nhjLA//4m1HvlSUtXkPDjGURRb36QN5w86OMCpUkbyc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XExsG9DYSDtI7Vz6AQMeLM6YAjfU1iw/G50KmjNdeOioNNrI/wQrvRRAXrNWq4OD9 GqPWJ3cDeOqO9by31BnVB8tCtN2sKYiPRQWX6KlhH+6jiO/Ti2SYUqcefoUfY2xlly Txo8jIvw6wDXAq6oI8jOHynB0rIRDH8bXf1RIgV0= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:27 +0300 Message-Id: <20220604185939.29163-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 02/14] libcamera: yaml_parser: Extend YamlObject::size() to dictionaries X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Dictionaries have a size too, extend the size() function to support them. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder --- include/libcamera/internal/yaml_parser.h | 3 +- src/libcamera/yaml_parser.cpp | 42 +++++++++++++----------- test/yaml-parser.cpp | 5 +++ 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index e002fcf59278..b4f852b1ce54 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -39,6 +39,8 @@ public: return type_ == Type::Dictionary; } + std::size_t size() const; + #ifndef __DOXYGEN__ template YamlObject::get( * const T &defaultValue, bool *ok) const @@ -235,25 +258,6 @@ Size YamlObject::get(const Size &defaultValue, bool *ok) const #endif /* __DOXYGEN__ */ -/** - * \fn YamlObject::size() - * \brief Retrieve the number of elements in a list YamlObject - * - * This function retrieves the size of the YamlObject, defined as the number of - * child elements it contains. Only YamlObject instances of List type have a - * size, calling this function on other types of instances is invalid and - * results in undefined behaviour. - * - * \return The size of the YamlObject - */ -std::size_t YamlObject::size() const -{ - if (type_ != Type::List) - return 0; - - return list_.size(); -} - /** * \fn YamlObject::operator[](std::size_t index) const * \brief Retrieve the element from list YamlObject by index diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index 5315d99fae5d..c5b4ddbb19e5 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -421,6 +421,11 @@ protected: return TestFail; } + if (dictObj.size() != 3) { + cerr << "Dictionary object parse with wrong size" << std::endl; + return TestFail; + } + auto memeberNames = dictObj.memberNames(); sort(memeberNames.begin(), memeberNames.end()); From patchwork Sat Jun 4 18:59:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16158 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 6B149C3274 for ; Sat, 4 Jun 2022 19:00:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B280165644; Sat, 4 Jun 2022 21:00:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369203; bh=gh83vO2M0GAuJE7wr6hbUrqmm2P+xGfstsTSz+FOkRs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Nq7gSFJgnoMZvi64PxxL+dyP0/2ibYiqYxbRXkkLB/EEGep49ZsTLRy9lDsziGhgB dJGS1FUnkQhD/bOAuO+B+4glhXjVD+vA8vsFMfHTCsj6x5TUy2NDcm6SjUVU3nZRzn uzXlhdun3ZWPTfHA8oz5YAGVauepN/cKj8wfQ5xt8UoOyhNWRUwlnQTRmow71H05Ym 4FhJlQa+IWVufIi1/KncWtPu7nkfj92IVitQrQ05XYHOZr/0Ne+O8OHqMR8IbA7pxt YcaWh9e+86wpi1Qwpf4Tvbn+EwWMYQ9YdBqoysXf69atA2nj7vVTIyUkg2GK3TBn5h IqQrw4MdYIkdw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8C65C6563F for ; Sat, 4 Jun 2022 21:00:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Zi9VxCig"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3A13387A; Sat, 4 Jun 2022 21:00:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369201; bh=gh83vO2M0GAuJE7wr6hbUrqmm2P+xGfstsTSz+FOkRs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Zi9VxCigGJO7MygHot/a12hdle/wZqu6ya6xe1nKg/HMxm0T9x1JbiK1HqpmT3fqn 2/MD94ThNdWa3VyQNJP8zmQrxnIfnnLPyvecjdHCYiaQKaKlm8B1k4jXEsKx61T/Hr PnnSZQG/McaG1uujWT6V+0VUDgc242l9mqYhnlow= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:28 +0300 Message-Id: <20220604185939.29163-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 03/14] libcamera: yaml_parser: Switch from FILE to File X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" THe FILE object isn't very user-friendly as it requires manual close. Replace it with File to provide RAII-style resource management in the YamlParser API. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder --- include/libcamera/internal/yaml_parser.h | 4 +-- src/android/camera_hal_config.cpp | 16 +++++----- src/libcamera/yaml_parser.cpp | 39 +++++++++++++++++------- test/yaml-parser.cpp | 18 +++++------ 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index b4f852b1ce54..be5f0914703f 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -7,7 +7,6 @@ #pragma once -#include #include #include #include @@ -18,6 +17,7 @@ namespace libcamera { +class File; class YamlParserContext; class YamlObject @@ -82,7 +82,7 @@ private: class YamlParser final { public: - static std::unique_ptr parse(std::FILE *fh); + static std::unique_ptr parse(File &file); }; } /* namespace libcamera */ diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp index 8ba8738cc6b6..ac484b8df1bd 100644 --- a/src/android/camera_hal_config.cpp +++ b/src/android/camera_hal_config.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "libcamera/internal/yaml_parser.h" @@ -27,7 +28,7 @@ class CameraHalConfig::Private : public Extensible::Private public: Private(); - int parseConfigFile(FILE *fh, std::map *cameras); + int parseConfigFile(File &file, std::map *cameras); private: int parseCameraConfigData(const std::string &cameraId, const YamlObject &); @@ -41,7 +42,7 @@ CameraHalConfig::Private::Private() { } -int CameraHalConfig::Private::parseConfigFile(FILE *fh, +int CameraHalConfig::Private::parseConfigFile(File &file, std::map *cameras) { /* @@ -65,7 +66,7 @@ int CameraHalConfig::Private::parseConfigFile(FILE *fh, cameras_ = cameras; - std::unique_ptr root = YamlParser::parse(fh); + std::unique_ptr root = YamlParser::parse(file); if (!root) return -EINVAL; @@ -169,9 +170,9 @@ int CameraHalConfig::parseConfigurationFile() return -ENOENT; } - FILE *fh = fopen(filePath.c_str(), "r"); - if (!fh) { - int ret = -errno; + File file(filePath); + if (!file.open(File::OpenModeFlag::ReadOnly)) { + int ret = file.error(); LOG(HALConfig, Error) << "Failed to open configuration file " << filePath << ": " << strerror(-ret); return ret; @@ -179,8 +180,7 @@ int CameraHalConfig::parseConfigurationFile() exists_ = true; - int ret = _d()->parseConfigFile(fh, &cameras_); - fclose(fh); + int ret = _d()->parseConfigFile(file, &cameras_); if (ret) return -EINVAL; diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 5b872dbb0a2d..85f6694f5fde 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -345,7 +346,7 @@ public: YamlParserContext(); ~YamlParserContext(); - int init(std::FILE *fh); + int init(File &file); int parseContent(YamlObject &yamlObject); private: @@ -358,6 +359,9 @@ private: }; using EventPtr = std::unique_ptr; + static int yamlRead(void *data, unsigned char *buffer, size_t size, + size_t *sizeRead); + EventPtr nextEvent(); void readValue(std::string &value, EventPtr event); @@ -399,13 +403,13 @@ YamlParserContext::~YamlParserContext() * \param[in] fh The YAML file to parse * * Prior to parsing the YAML content, the YamlParserContext must be initialized - * with an opened FILE to create an internal parser. The FILE needs to stay - * valid during the process. + * with a file to create an internal parser. The file needs to stay valid until + * parsing completes. * * \return 0 on success or a negative error code otherwise * \retval -EINVAL The parser has failed to initialize */ -int YamlParserContext::init(std::FILE *fh) +int YamlParserContext::init(File &file) { /* yaml_parser_initialize returns 1 when it succeededs */ if (!yaml_parser_initialize(&parser_)) { @@ -413,11 +417,25 @@ int YamlParserContext::init(std::FILE *fh) return -EINVAL; } parserValid_ = true; - yaml_parser_set_input_file(&parser_, fh); + yaml_parser_set_input(&parser_, &YamlParserContext::yamlRead, &file); return 0; } +int YamlParserContext::yamlRead(void *data, unsigned char *buffer, size_t size, + size_t *sizeRead) +{ + File *file = static_cast(data); + + Span buf{ buffer, size }; + ssize_t ret = file->read(buf); + if (ret < 0) + return 0; + + *sizeRead = ret; + return 1; +} + /** * \fn YamlParserContext::nextEvent() * \brief Get the next event @@ -655,21 +673,20 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even */ /** - * \fn YamlParser::parse() * \brief Parse a YAML file as a YamlObject - * \param[in] fh The YAML file to parse + * \param[in] file The YAML file to parse * - * The YamlParser::parse() function takes an open FILE, parses its contents, and + * The YamlParser::parse() function takes a file, parses its contents, and * returns a pointer to a YamlObject corresponding to the root node of the YAML - * document. The caller is responsible for closing the file. + * document. * * \return Pointer to result YamlObject on success or nullptr otherwise */ -std::unique_ptr YamlParser::parse(std::FILE *fh) +std::unique_ptr YamlParser::parse(File &file) { YamlParserContext context; - if (context.init(fh)) + if (context.init(file)) return nullptr; std::unique_ptr root(new YamlObject()); diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index c5b4ddbb19e5..e75f8fe8f642 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "libcamera/internal/yaml_parser.h" #include "test.h" @@ -69,29 +71,27 @@ protected: int run() { /* Test invalid YAML file */ - FILE *fh = fopen(invalidYamlFile_.c_str(), "r"); - if (!fh) { + File file{ invalidYamlFile_ }; + if (!file.open(File::OpenModeFlag::ReadOnly)) { cerr << "Fail to open invalid YAML file" << std::endl; return TestFail; } - std::unique_ptr root = YamlParser::parse(fh); - fclose(fh); - + std::unique_ptr root = YamlParser::parse(file); if (root) { cerr << "Invalid YAML file parse successfully" << std::endl; return TestFail; } /* Test YAML file */ - fh = fopen(testYamlFile_.c_str(), "r"); - if (!fh) { + file.close(); + file.setFileName(testYamlFile_); + if (!file.open(File::OpenModeFlag::ReadOnly)) { cerr << "Fail to open test YAML file" << std::endl; return TestFail; } - root = YamlParser::parse(fh); - fclose(fh); + root = YamlParser::parse(file); if (!root) { cerr << "Fail to parse test YAML file: " << std::endl; From patchwork Sat Jun 4 18:59:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16159 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CFC01C3275 for ; Sat, 4 Jun 2022 19:00:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 600B665640; Sat, 4 Jun 2022 21:00:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369204; bh=2b6Hode8CuVVoCxJIW23UGQNd3KaWgZiy3XrrRBmJ1Y=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=PstcApy2TYb9MGwM5dY3HCBeOA09uy3MdYoFrDo6RQyae3sZSRImcsQ03fMjg2RYV n8MgufFPTdXOQ6p4u1wLHoFTj3xL15DyqXNLlYw7CR7bcdCpc3yLVqiJx+CSur036I WZnurIKtFLi2cmKqUBcnymI5Ijllk7iAMD2ob0yyhD2SgVr6NbP8OXyKlqxcRwXc1o cJIj9pRTzOlRX7lHKySdEWx/A2cwL180jS7WOzIU4MqsndNZ/PARPuYfKCNjADyjuW //XT7BGBLDvFIcv53qp7Nk37fWz/Th0hK6p0jF/KUsWwDXM2XJivznQ5zU/Ou56hba ZpkuOJm8LHiyA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D952A6563A for ; Sat, 4 Jun 2022 21:00:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="UTipqGIM"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A5BDEE0F; Sat, 4 Jun 2022 21:00:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369202; bh=2b6Hode8CuVVoCxJIW23UGQNd3KaWgZiy3XrrRBmJ1Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UTipqGIMxtKUI617NRkjuI1j5EQmyQU+Ac9/6c89CSmcU82JRKGoDfsm7kCph5lx6 j1oOQRF9tA0a3eTYmOn7ZJwKjtqeyDwa3nDHcg+1TB0DesCZjYMt1zJdomIjijLObQ n/AgzRNLUFLv/G93o8YGl5xMUm1yaCU0ys7pxsAI= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:29 +0300 Message-Id: <20220604185939.29163-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 04/14] test: yaml-parser: Use write() instead of fwrite() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" There's no point in wrapping a fd into a FILE to then only call fwrite() and fclose(). Use write() and close() directly. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder --- test/yaml-parser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index e75f8fe8f642..5ff4c3236dbf 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -49,10 +49,11 @@ protected: if (fd == -1) return false; - FILE *fh = fdopen(fd, "w"); - fputs(content.c_str(), fh); + int ret = write(fd, content.c_str(), content.size()); + close(fd); - fclose(fh); + if (ret != static_cast(content.size())) + return false; return true; } From patchwork Sat Jun 4 18:59:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16160 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 23E61C3276 for ; Sat, 4 Jun 2022 19:00:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 42E516563A; Sat, 4 Jun 2022 21:00:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369206; bh=0ujFVweJ22FiMvPjHZ/GcIyK24KVDI3beDTIVi0P+Lc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=f5bLRCbK+SUKd8YZ2KNj3QPVb6sQBnCNTqPRWpoKIm0jHOyF4RJ2qeZCbWQfV/n/W EB0xhu0Ejaqh6hfiPeNxQwBSwVH0iUZoCtKJ9x8ZtG+tgBaOnpb+rMm4fd33eYYXzz vcrq/03H6fIwusmfbxVF5u6VkP0/QYTFwDwrW9Uu5ZrrmQmNilf0qAkit1T7/wf/Sc hHMhhvS4Yw0TypJUi0L4YSmozmRKNX9ddsSZoYg1TlGqir+kVtl5hcNdV+I1A6A68X rQ/tvZy63nitIS54v6yeJjPoFnnLSYYkSWWcX22H+gQVUqAk0xB2SePm3QZztRGQ1e 1HxlUVEErLsZw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id BF5636563F for ; Sat, 4 Jun 2022 21:00:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="o36Z+NYv"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BA586D4; Sat, 4 Jun 2022 21:00:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369204; bh=0ujFVweJ22FiMvPjHZ/GcIyK24KVDI3beDTIVi0P+Lc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o36Z+NYvYRDFe+8bNluaGPWnCUQw77Ec7NhPZVETPXcXbh0ScT4v4EbL6DRNdU7NH HVzltu7WTxsUfJlaGAaltr11ArV6ZNpvGueGlzb9VQI9WbQTCFoYwOrb9TQT7hMjKM iqWUXRZ3PVgFzV8NxAi711KstFpMJbSxdIRuQKeE= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:30 +0300 Message-Id: <20220604185939.29163-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 05/14] test: yaml-parser: Test dictionary items ordering X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The order of items in a YAML dictionary may matter. Update the test to ensure that it is preserved. The test currently fails at the YamlParser doesn't correctly preserve the order, this will be fixed by the next commit. Signed-off-by: Laurent Pinchart --- test/yaml-parser.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index 5ff4c3236dbf..582c9caed836 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -29,8 +29,8 @@ static const string testYaml = " - Mary\n" "dictionary:\n" " a: 1\n" - " b: 2\n" " c: 3\n" + " b: 2\n" "level1:\n" " level2:\n" " - [1, 2]\n" @@ -428,7 +428,6 @@ protected: } auto memeberNames = dictObj.memberNames(); - sort(memeberNames.begin(), memeberNames.end()); if (memeberNames.size() != 3) { cerr << "Dictionary object fail to extra member names" << std::endl; @@ -436,8 +435,8 @@ protected: } if (memeberNames[0] != "a" || - memeberNames[1] != "b" || - memeberNames[2] != "c") { + memeberNames[1] != "c" || + memeberNames[2] != "b") { cerr << "Dictionary object fail to parse member names" << std::endl; return TestFail; } From patchwork Sat Jun 4 18:59:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16161 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 072B0C3277 for ; Sat, 4 Jun 2022 19:00:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BDE0765633; Sat, 4 Jun 2022 21:00:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369207; bh=n/JQvu7qEoXZjoWbSvBdtljGjeBswyT1Z/bFeWPyVN8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=hAZcEzCVEGkC3Hef9Eal/rJOiy/t9zSqHhVjosTIdHzc1KG3Ru8XibUZVbHEhRcgw GZzBulOqYxsC1Jrh9TlO5mWqD7qJfKRcoHQlxR/26PQem0jXfGSVh+w04rtJG9qN/U u4E8gZaNbx+8L35KS+rDZV4BVqJBWggy5B7OwFeywd83ttwVli1L3WK+AoXIH6H5++ sRN6ZoDXnAFo1beehkhbyA1mqWGnivIBeuITjhnzLs+JIdu9bRnRTYQC74cueoHfZn nKZMtAiTzbxp7hWauFv5ooQDi3wztr0zCIgQCls/U9zy6fiiyOpA9dx/5gEBTlzXTT 1PrkhKw64vhvA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7001365643 for ; Sat, 4 Jun 2022 21:00:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="GchkrjYE"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 299BE6D4; Sat, 4 Jun 2022 21:00:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369206; bh=n/JQvu7qEoXZjoWbSvBdtljGjeBswyT1Z/bFeWPyVN8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GchkrjYEhsw+OhVapLcczy+sf7jfhreo9ROOtdnxRSzDpHMJ2Xs45jiDhWiqOLRfr k+WbaQZTCV+ZrsKbTCAXLM6UHC+Bm35R8V5Uzfb06psJ2wA30Q0jE6PHkJbB5Z9q8y T1S+ZQvGz62MJlDFfuJh88PaQsIIKlPYgdNmfJw8= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:31 +0300 Message-Id: <20220604185939.29163-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 06/14] libcamera: yaml_parser: Preserve order of items in dictionary X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" YAML dictionaries are ordered, but the std::map container used to store dictionary items in YamlObject doesn't preserve that order as maps are ordered by key, not by insertion order. As the order of items in the YAML file may be important, preserve it by storing items in list_ unconditionally. Turn the list_ vector from storing YamlObject unique pointers to storing key-value pairs, with the key being absent when the object is a list, not a dictionary. The YamlObject implementation is updated to preserve the existing API, with the only difference being that YamlObject::memberNames() now returns member names in the same order as in the YAML file. Signed-off-by: Laurent Pinchart --- include/libcamera/internal/yaml_parser.h | 13 +++++++-- src/libcamera/yaml_parser.cpp | 37 +++++++++++++++--------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index be5f0914703f..bd1d06d5c488 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -72,11 +72,20 @@ private: Value, }; + struct Value { + Value(std::string &&k, std::unique_ptr &&v) + : key(std::move(k)), value(std::move(v)) + { + } + std::string key; + std::unique_ptr value; + }; + Type type_; std::string value_; - std::vector> list_; - std::map> dictionary_; + std::vector list_; + std::map dictionary_; }; class YamlParser final diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 85f6694f5fde..83813e2a8552 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -90,7 +90,6 @@ std::size_t YamlObject::size() const { switch (type_) { case Type::Dictionary: - return dictionary_.size(); case Type::List: return list_.size(); default: @@ -245,11 +244,11 @@ Size YamlObject::get(const Size &defaultValue, bool *ok) const * that ok == nullptr. */ bool valid; - uint32_t width = list_[0]->get(0, &valid); + uint32_t width = list_[0].value->get(0, &valid); if (!valid) return defaultValue; - uint32_t height = list_[1]->get(0, &valid); + uint32_t height = list_[1].value->get(0, &valid); if (!valid) return defaultValue; @@ -274,7 +273,7 @@ const YamlObject &YamlObject::operator[](std::size_t index) const if (type_ != Type::List || index >= size()) return empty; - return *list_[index]; + return *list_[index].value; } /** @@ -290,7 +289,7 @@ const YamlObject &YamlObject::operator[](std::size_t index) const */ bool YamlObject::contains(const std::string &key) const { - if (dictionary_.find(key) == dictionary_.end()) + if (dictionary_.find(std::ref(key)) == dictionary_.end()) return false; return true; @@ -312,7 +311,7 @@ bool YamlObject::contains(const std::string &key) const std::vector YamlObject::memberNames() const { std::vector memberNames; - for (auto &[key, _] : dictionary_) + for (auto &[key, _] : list_) memberNames.push_back(key); return memberNames; @@ -584,16 +583,16 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even yamlObject.type_ = YamlObject::Type::List; auto &list = yamlObject.list_; auto handler = [this, &list](EventPtr evt) { - list.emplace_back(new YamlObject()); - return parseNextYamlObject(*list.back(), std::move(evt)); + list.emplace_back(std::string{}, std::make_unique()); + return parseNextYamlObject(*list.back().value, std::move(evt)); }; return parseDictionaryOrList(YamlObject::Type::List, handler); } case YAML_MAPPING_START_EVENT: { yamlObject.type_ = YamlObject::Type::Dictionary; - auto &dictionary = yamlObject.dictionary_; - auto handler = [this, &dictionary](EventPtr evtKey) { + auto &list = yamlObject.list_; + auto handler = [this, &list](EventPtr evtKey) { /* Parse key */ if (evtKey->type != YAML_SCALAR_EVENT) { LOG(YamlParser, Error) << "Expect key at line: " @@ -611,10 +610,19 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even if (!evtValue) return -EINVAL; - auto elem = dictionary.emplace(key, std::make_unique()); - return parseNextYamlObject(*elem.first->second.get(), std::move(evtValue)); + auto &elem = list.emplace_back(std::move(key), + std::make_unique()); + return parseNextYamlObject(*elem.value, std::move(evtValue)); }; - return parseDictionaryOrList(YamlObject::Type::Dictionary, handler); + int ret = parseDictionaryOrList(YamlObject::Type::Dictionary, handler); + if (ret) + return ret; + + auto &dictionary = yamlObject.dictionary_; + for (const auto &elem : list) + dictionary.emplace(elem.key, elem.value.get()); + + return 0; } default: @@ -670,6 +678,9 @@ int YamlParserContext::parseNextYamlObject(YamlObject &yamlObject, EventPtr even * The YamlParser::parse() function takes an open FILE, parses its contents, and * returns a pointer to a YamlObject corresponding to the root node of the YAML * document. + * + * The parser preserves the order of items in the YAML file, for both lists and + * dictionaries. */ /** From patchwork Sat Jun 4 18:59:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16162 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 708FABD161 for ; Sat, 4 Jun 2022 19:00:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 3115265643; Sat, 4 Jun 2022 21:00:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369210; bh=sv54BM/pRTcqIkDYh3/i2g58b1KvyQ0LCmSCunIt60M=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=sKMYzAwXR6FzByeEvE1IcqbwqvAKujDFC7lTA0bZafBWvxiYqYQ+FmR4b+4cRIQ9v I1LGvI3U4Py+Rce/gi7f12IjYvxlaPZYCIRtEqIJLWbKL06ckV8ATKNe5scKJx4+N+ sBZqUNG0S+JyjJGLwVPPoHAPCKzuW+DO3rX0a1XukDntt455UseuW2xb7PnOlie1Zf UfaYdT5JHXt8sktf6NIFn61GeEZsMV7qzlnwbSqyuuXq7+dPAVjl0h734ijW/rnatJ +u5yHwPgBUJrevvoG0Jr1Mo6gJ5ghSouu8E16sc7ZfqrOSIHfQlSeAAPaiiqnb3nkY v69jEWTGg472w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D573F65637 for ; Sat, 4 Jun 2022 21:00:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EDy3DXDz"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 09DC36D4; Sat, 4 Jun 2022 21:00:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369208; bh=sv54BM/pRTcqIkDYh3/i2g58b1KvyQ0LCmSCunIt60M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EDy3DXDzdAtEjrLiAghIKEn4TSSUz/juYYCMsBz1CEaKWj4CvBs6e8SpJTkVcU8iz HmSUH4U0msU8kcDcflnxDH6QpxZI6Wk+h3FsyJYdANFIRkAh8DZjaRX8tRyTHNEG+Z kMPi5zEsb83AO2g6qHgrMLOD8vdPjc2yXVfjCw+Q= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:32 +0300 Message-Id: <20220604185939.29163-8-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 07/14] libcamera: yaml_parser: Add iterator API X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Allow using range-based for loops over YamlObject instances by implementing iterators. New YamlObject::DictAdapter and YamlObject::ListAdapter adapter classes are introduced to provide different iterators depending on the object type. Signed-off-by: Laurent Pinchart --- include/libcamera/internal/yaml_parser.h | 131 +++++++++++++++++++++-- src/libcamera/yaml_parser.cpp | 37 +++++++ 2 files changed, 158 insertions(+), 10 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index bd1d06d5c488..e142cde0fb6f 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -22,7 +23,123 @@ class YamlParserContext; class YamlObject { +private: + struct Value { + Value(std::string &&k, std::unique_ptr &&v) + : key(std::move(k)), value(std::move(v)) + { + } + std::string key; + std::unique_ptr value; + }; + + using Container = std::vector; + using ListContainer = std::vector>; + public: +#ifndef __DOXYGEN__ + template + class Iterator + { + public: + using difference_type = std::ptrdiff_t; + using iterator_category = std::bidirectional_iterator_tag; + + Iterator(typename Container::const_iterator it) + : it_(it) + { + } + + Derived &operator++() + { + ++it_; + return *static_cast(this); + } + + Derived operator++(int) + { + Derived it = *static_cast(this); + it_++; + return it; + } + + friend bool operator==(const Iterator &a, const Iterator &b) + { + return a.it_ == b.it_; + } + + friend bool operator!=(const Iterator &a, const Iterator &b) + { + return a.it_ != b.it_; + } + + protected: + Container::const_iterator it_; + }; + + template + class Adapter + { + public: + Adapter(const Container &container) + : container_(container) + { + } + + Iterator begin() const + { + return Iterator{ container_.begin() }; + } + + Iterator end() const + { + return Iterator{ container_.end() }; + } + + protected: + const Container &container_; + }; + + class ListIterator : public Iterator + { + public: + using value_type = const YamlObject &; + using pointer = const YamlObject *; + using reference = value_type; + + value_type operator*() const + { + return *it_->value.get(); + } + + pointer operator->() const + { + return it_->value.get(); + } + }; + + class DictIterator : public Iterator + { + public: + using value_type = std::pair; + using pointer = value_type *; + using reference = value_type &; + + value_type operator*() const + { + return { it_->key, *it_->value.get() }; + } + }; + + class DictAdapter : public Adapter + { + }; + + class ListAdapter : public Adapter + { + }; +#endif /* __DOXYGEN__ */ + YamlObject(); ~YamlObject(); @@ -55,6 +172,9 @@ public: #endif T get(const T &defaultValue, bool *ok = nullptr) const; + DictAdapter asDict() const { return DictAdapter{ list_ }; } + ListAdapter asList() const { return ListAdapter{ list_ }; } + const YamlObject &operator[](std::size_t index) const; bool contains(const std::string &key) const; @@ -72,19 +192,10 @@ private: Value, }; - struct Value { - Value(std::string &&k, std::unique_ptr &&v) - : key(std::move(k)), value(std::move(v)) - { - } - std::string key; - std::unique_ptr value; - }; - Type type_; std::string value_; - std::vector list_; + Container list_; std::map dictionary_; }; diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 83813e2a8552..9cdb370d0f2e 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -258,6 +258,43 @@ Size YamlObject::get(const Size &defaultValue, bool *ok) const #endif /* __DOXYGEN__ */ +/** + * \fn YamlObject::asDict() const + * \brief Wrap a dictionary YamlObject in an adapter that exposes iterators + * + * The YamlObject class doesn't directly implement iterators, as the iterator + * type depends on whether the object is a Dictionary or List. This function + * wraps a YamlObject of Dictionary type into an adapter that exposes + * iterators, as well as begin() and end() functions, allowing usage of + * range-based for loops with YamlObject. + * + * The iterator's value_type is a + * std::pair. + * + * If the YamlObject is not of Dictionary type, the returned adapter operates + * as an empty container. + * + * \return An adapter of unspecified type compatible with range-based for loops + */ + +/** + * \fn YamlObject::asList() const + * \brief Wrap a list YamlObject in an adapter that exposes iterators + * + * The YamlObject class doesn't directly implement iterators, as the iterator + * type depends on whether the object is a Dictionary or List. This function + * wraps a YamlObject of List type into an adapter that exposes iterators, as + * well as begin() and end() functions, allowing usage of range-based for loops + * with YamlObject. + * + * The iterator's value_type is a const YamlObject &. + * + * If the YamlObject is not of List type, the returned adapter operates as an + * empty container. + * + * \return An adapter of unspecified type compatible with range-based for loops + */ + /** * \fn YamlObject::operator[](std::size_t index) const * \brief Retrieve the element from list YamlObject by index From patchwork Sat Jun 4 18:59:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16163 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 21A47C3278 for ; Sat, 4 Jun 2022 19:00:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8AE206563D; Sat, 4 Jun 2022 21:00:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369212; bh=SUZ5vJfie+i32xSq7wD2gVnyYdGkZTsdqJhOzBSQbHQ=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=G2CFfuUnYM/DyDPSU/RIXTUIf+cfOOdsVJuZxs3VzO9OuZ9HEWV9i6Zk0yLZ0zQaX d+PSAM/J5YfRc3yAJrZn2m7oBzsmayqKvdvwGXAvRP4Zir/X7uom3Qz9u38cBODsoI 0tL1WT7PkX5yonazMElXcVvWcLr0emmg3LgC6qNznVGpCaU2+aiGCwSr19iU8g0amF wljQfdB5Qu3kAGChlaaA1eLjPnUn/twVeQ3pYXE+UqFDrY+naSpf0GCdmZ0ozn+36k rEFhFrcNwVqgcU3i5bb2VJMouyzQ4MYhfJvAlP1juU61yhzJdLYiOb9pspqXnPH8K1 26a/9vnKNpqxg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AABFD6563D for ; Sat, 4 Jun 2022 21:00:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="K8kuYlwZ"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 41FF86D4; Sat, 4 Jun 2022 21:00:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369210; bh=SUZ5vJfie+i32xSq7wD2gVnyYdGkZTsdqJhOzBSQbHQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K8kuYlwZ00g7uhuK3xC8+fSFvMs5eHXULdND3npPAHtiLg/uGc9WUuVeDS8y5evYj pKs3xgo2V12cDBiIzEMgwfu9agkAHZJPYhhUJHG8K170ulIDc1JjxKyX2912R+tden 8bmI7UPsn+8J94NGVC5Vo1M+wvUdEx5S6m5PcdQU= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:33 +0300 Message-Id: <20220604185939.29163-9-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 08/14] test: yaml_parser: Extend tests to cover the iterator API X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Test iteration over lists and dictionaries to test the YamlObject iterator API. Signed-off-by: Laurent Pinchart --- test/yaml-parser.cpp | 88 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index 582c9caed836..6dfec49d6be0 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -5,6 +5,7 @@ * yaml-parser.cpp - YAML parser operations tests */ +#include #include #include #include @@ -373,15 +374,39 @@ protected: return TestFail; } - if (listObj.size() > 2) { + static constexpr std::array listValues{ + "James", + "Mary", + }; + + if (listObj.size() != listValues.size()) { cerr << "List object parse with wrong size" << std::endl; return TestFail; } - if (listObj[0].get("") != "James" || - listObj[1].get("") != "Mary") { - cerr << "List object parse as wrong value" << std::endl; - return TestFail; + unsigned int i = 0; + for (auto &elem : listObj.asList()) { + if (i >= listValues.size()) { + std::cerr << "Too many elements in list during iteration" + << std::endl; + return TestFail; + } + + std::string value = listValues[i]; + + if (&elem != &listObj[i]) { + std::cerr << "List element " << i << " has wrong address" + << std::endl; + return TestFail; + } + + if (elem.get("") != value) { + std::cerr << "List element " << i << " has wrong value" + << std::endl; + return TestFail; + } + + i++; } /* Test dictionary object */ @@ -422,18 +447,50 @@ protected: return TestFail; } - if (dictObj.size() != 3) { - cerr << "Dictionary object parse with wrong size" << std::endl; + static constexpr std::array, 3> dictValues{ { + { "a", 1 }, + { "c", 3 }, + { "b", 2 }, + } }; + + if (dictObj.size() != dictValues.size()) { + cerr << "Dictionary object has wrong size" << std::endl; return TestFail; } + i = 0; + for (const auto &[key, elem] : dictObj.asDict()) { + if (i >= dictValues.size()) { + std::cerr << "Too many elements in dictionary during iteration" + << std::endl; + return TestFail; + } + + const std::pair &value = dictValues[i]; + + if (key != value.first) { + std::cerr << "Dictionary key " << i << " has wrong value" + << std::endl; + return TestFail; + } + + if (&elem != &dictObj[key]) { + std::cerr << "Dictionary element " << i << " has wrong address" + << std::endl; + return TestFail; + } + + if (elem.get(0) != value.second) { + std::cerr << "Dictionary element " << i << " has wrong value" + << std::endl; + return TestFail; + } + + i++; + } + auto memeberNames = dictObj.memberNames(); - if (memeberNames.size() != 3) { - cerr << "Dictionary object fail to extra member names" << std::endl; - return TestFail; - } - if (memeberNames[0] != "a" || memeberNames[1] != "c" || memeberNames[2] != "b") { @@ -441,13 +498,6 @@ protected: return TestFail; } - if (dictObj["a"].get(0) != 1 || - dictObj["b"].get(0) != 2 || - dictObj["c"].get(0) != 3) { - cerr << "Dictionary object fail to parse member value" << std::endl; - return TestFail; - } - /* Test leveled objects */ auto &level1Obj = (*root)["level1"]; From patchwork Sat Jun 4 18:59:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16164 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 99255C3279 for ; Sat, 4 Jun 2022 19:00:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1ECAF65646; Sat, 4 Jun 2022 21:00:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369213; bh=Ic3F3Afbq5cwq4A8ifAQhqKg4w3eXeU4Dm+xJoUklrM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=FB0NORvWhjRiUZoCQ9R8TgS+RJwPqkhkMROjEagI8h17cL50HO1eskrDbrhM54/Sp 9zoKulddGCeSwzV2tvENtm+KfoW6X9Bw5foRKtsqs2UApMPjF7vZVr/9YurPN0ANOT inw2C4wgukqrQctFIvgrHpmqkyZeMoWhBVLk5JRCT0QQ9tT2ajAGTi0SXSg/A5Wdy3 ZdFR0+ZQaSrorwyiuU+129bFxZKjw9el+3SmRifxdYvrV2+TLvtBD+LjeXoxfoXsGp NYZamgpLrML4B9PvoW7hZ++cFn2m8WpTF1OC8PFXNspLRb7ORcPCazAFWqvW5vGVHm Hzk75ml6LUWKw== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4D3ED633A6 for ; Sat, 4 Jun 2022 21:00:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CoW4zHeb"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DE32BE0F; Sat, 4 Jun 2022 21:00:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369212; bh=Ic3F3Afbq5cwq4A8ifAQhqKg4w3eXeU4Dm+xJoUklrM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CoW4zHeby2LL1j+tOBPhLCQabDG+zaMfnBKczgXxSguih2ndGMWafq5Pc1JuBPuly OJIESbKLbCKzzZ4Jza+bQouPD/eRB9VExzBbxZPKEwqaXo4dvV9BP+uoIiPBrlKKvS qI7dIxkdJyVFBD9AplI/b2kzp8R3O3vpuGFZcxKA= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:34 +0300 Message-Id: <20220604185939.29163-10-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 09/14] android: Use the YamlObject iterator API X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Replace usage of YamlObject::memberNames() with the more efficient iterator API. Signed-off-by: Laurent Pinchart --- src/android/camera_hal_config.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp index ac484b8df1bd..bacfe4b9c505 100644 --- a/src/android/camera_hal_config.cpp +++ b/src/android/camera_hal_config.cpp @@ -82,10 +82,8 @@ int CameraHalConfig::Private::parseConfigFile(File &file, if (!yamlObjectCameras.isDictionary()) return -EINVAL; - std::vector cameraIds = yamlObjectCameras.memberNames(); - for (const std::string &cameraId : cameraIds) { - if (parseCameraConfigData(cameraId, - yamlObjectCameras[cameraId])) + for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) { + if (parseCameraConfigData(cameraId, configData)) return -EINVAL; } From patchwork Sat Jun 4 18:59:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16165 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id EEEF9C327A for ; Sat, 4 Jun 2022 19:00:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 070626564C; Sat, 4 Jun 2022 21:00:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369216; bh=v1mnG3JXPIC1r12cJ7UCp9XicED3HrFTGWy07p9m4bQ=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=uB0K26aBQZJI+0J1oKYBrrcaTkhLIFFLLenA+kRJxX5+U7tStIfZ7AGmYHkveg4fZ FhugbqeiPHIhhgJyJaOD8uRafEVjr9c7jTTViBAXMsW+QkcoKEiL1MflD++QfHgsc9 M+YftH9SIsQ54ni0VlxfMt57sQuXKSzWduz9+l9wMJnYD+OamNBrUD7S81L1D2bYnt nE71yXQ5qx1Tvv2R4NyBgx3ZeB9ugr3nW9BTGpZ4dj19zWiMWFUPPPgmonJJuWqgY9 ovwYGAlTbKnUqKZqdHPPwHwDA8efzuuwArH10bhwq0/timEq83WBM3ZErQFn+yxYbu Qbn7d/O6+Gl/A== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C154A65639 for ; Sat, 4 Jun 2022 21:00:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JNa1WUlg"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 000BD6D4; Sat, 4 Jun 2022 21:00:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369214; bh=v1mnG3JXPIC1r12cJ7UCp9XicED3HrFTGWy07p9m4bQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JNa1WUlgMeAWiTOJ19lyXn30tpoMc2uEV8vW9ZWOFqPU0+72QU34vYMQcsovTUo3V qmIeoiYAmmvFUMkRWSXBksiVv8WkH/C6BVbZGW2QBEPeTgSV+LJxzDxYCkN9C0u7kO RaOq45sDpQcg/zTXj6OU0ScqSON69X9DCB98bBbs= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:35 +0300 Message-Id: <20220604185939.29163-11-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 10/14] libcamera: yaml_parser: Remove memberNames() function X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Now that YamlObject supports iteration, the memberNames() function isn't useful anymore as it can be implemented using utils::map_keys() if really needed. Drop it. Signed-off-by: Laurent Pinchart --- include/libcamera/internal/yaml_parser.h | 1 - src/libcamera/yaml_parser.cpp | 22 ---------------------- test/yaml-parser.cpp | 9 --------- 3 files changed, 32 deletions(-) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index e142cde0fb6f..d0ddb5f682b2 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -179,7 +179,6 @@ public: bool contains(const std::string &key) const; const YamlObject &operator[](const std::string &key) const; - std::vector memberNames() const; private: LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject) diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 9cdb370d0f2e..97104ac118a8 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -332,28 +332,6 @@ bool YamlObject::contains(const std::string &key) const return true; } -/** - * \fn YamlObject::memberNames() - * \brief Retrieve all member names of the dictionary - * - * This function retrieve member names of a YamlObject. Only YamlObject - * instances of Dictionary type associate elements with names, calling this - * function on other types of instances is invalid and results in undefined - * behaviour. - * - * \todo Replace this function with an iterator-based API - * - * \return A vector of string as the member names - */ -std::vector YamlObject::memberNames() const -{ - std::vector memberNames; - for (auto &[key, _] : list_) - memberNames.push_back(key); - - return memberNames; -} - /** * \fn YamlObject::operator[](const std::string &key) const * \brief Retrieve a member by name from the dictionary diff --git a/test/yaml-parser.cpp b/test/yaml-parser.cpp index 6dfec49d6be0..bd92869a4cb3 100644 --- a/test/yaml-parser.cpp +++ b/test/yaml-parser.cpp @@ -489,15 +489,6 @@ protected: i++; } - auto memeberNames = dictObj.memberNames(); - - if (memeberNames[0] != "a" || - memeberNames[1] != "c" || - memeberNames[2] != "b") { - cerr << "Dictionary object fail to parse member names" << std::endl; - return TestFail; - } - /* Test leveled objects */ auto &level1Obj = (*root)["level1"]; From patchwork Sat Jun 4 18:59:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16166 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 529C1C327B for ; Sat, 4 Jun 2022 19:00:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 95EFD65644; Sat, 4 Jun 2022 21:00:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369218; bh=k57qIkmOr92weRC9ZN8KPGgryCWRstSN6CSSZQy7WIU=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=fbD+bO3qjLrCT9ZtM1mvWaV1gL9BppALVEjUcuiOWqRJ76vrKCH5uxqSG1A6V/2Tq TSoQQSidN9AtBYZfrT1xU5pEVF3XquI/Ek0FncRsQlB/BNGPW57zSQn1zeQe8hCSKI 2WNHHQw86mni9poymC4GYZPtRh+ZcHJ2Nr51u6ZPSe0TnqbLJqVhOaerhJGvHLWzU0 /+i0Vtkm9nabV4M8FZqY1atAERSqH/hOR4AE8L75ExMhuRSCCmFmwDI6hIN5CkwS3F O0ixzvXKqlYlVBR1jpERPB54IUjS/5AmlEndtdelLJVbQgkePfPpKgta26WOffVMD2 /SWDXH5sPD9NA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 391386564F for ; Sat, 4 Jun 2022 21:00:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="f3U9QGRa"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F02B487A; Sat, 4 Jun 2022 21:00:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369216; bh=k57qIkmOr92weRC9ZN8KPGgryCWRstSN6CSSZQy7WIU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f3U9QGRaExL4oD8psOpleuvb5GQsODoJ6ocEFNKWz1NFy2OOCsvXHrHNx3W0HSljY fMi/LFNhxg7WY/wyXY5tOooFjxwFKYjzYTEmS6GtUhSX8mjWr9h0mMdkbykU24OHOi GQ1lJbBE0bDUMJm9EM7heoH7hED5vppgeV4ioF2U= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:36 +0300 Message-Id: <20220604185939.29163-12-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 11/14] libcamera: yaml_parser: Fix range checks for 32-bit integers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The strtol() and strtoul() functions return long integers, which may be larger than 32-bit integers. Add manual range checks. Signed-off-by: Laurent Pinchart --- src/libcamera/yaml_parser.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 97104ac118a8..3fb6fec695ee 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -150,9 +151,11 @@ int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const char *end; errno = 0; - int32_t value = std::strtol(value_.c_str(), &end, 10); + long value = std::strtol(value_.c_str(), &end, 10); - if ('\0' != *end || errno == ERANGE) + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) return defaultValue; setOk(ok, true); @@ -184,9 +187,11 @@ uint32_t YamlObject::get(const uint32_t &defaultValue, bool *ok) const char *end; errno = 0; - uint32_t value = std::strtoul(value_.c_str(), &end, 10); + unsigned long value = std::strtoul(value_.c_str(), &end, 10); - if ('\0' != *end || errno == ERANGE) + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) return defaultValue; setOk(ok, true); From patchwork Sat Jun 4 18:59:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16167 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 7329EC327C for ; Sat, 4 Jun 2022 19:00:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0E2E06563F; Sat, 4 Jun 2022 21:00:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369219; bh=TqHiVr4QGQxzOpjf0XHtdsxLe3op6/BtgX5oVoQx3UM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=lBmfT72x//xbgBDzpesbhnZVgzzX5SnARlpCI9THg8drZxqpLXdi1TZcGjfroXXoa fmKwulcaMtN8LZLYWnlNDbySIeH1KzrBXzUmF3LCIaRs/JzkmqbmSmpMFLag3U9K4z MpkfoUqDsejxVPIRRvni4I2DP0sOv9yO2mlMCchxL8fYvpBYIIrZHdXDnGTKTUto5L f+l2wkACqF4C/18w2aB1KJulrpVlRJpDHFWobNs3nZQ0UWpIG4wT5uCyWWEuY/yEgq AyebuxqBKD4lEhfssk9QcXpGidWvNnTjT1BW8AR/phhHboERzQR9pnTJ/GW5Ysai9l 8GxZz4nFOV6Lg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9A3A165644 for ; Sat, 4 Jun 2022 21:00:17 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EyHhAKPI"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 662F36D4; Sat, 4 Jun 2022 21:00:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369217; bh=TqHiVr4QGQxzOpjf0XHtdsxLe3op6/BtgX5oVoQx3UM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EyHhAKPIqo9QWObfkxWrGc54i9Lxh6zwzRT5YpXEX+vRt1DKSW5Sq6I40xeoUbHsA HlbPSnPFafGT4pFh8r9Ey26NcrOKaY3H21FzQYKXo3osZ+baseo/aVsHV/6eNamF2H ofgtQoJtPvIorATAU/GJwFrjLOPTXkR97fMULsS4= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:37 +0300 Message-Id: <20220604185939.29163-13-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 12/14] libcamera: yaml_parser: Add get() specializations for 16-bit integers X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Extend the YamlObject::get() function template to support 16-bit integers. Signed-off-by: Laurent Pinchart --- include/libcamera/internal/yaml_parser.h | 2 + src/libcamera/yaml_parser.cpp | 61 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/libcamera/internal/yaml_parser.h b/include/libcamera/internal/yaml_parser.h index d0ddb5f682b2..eebfff2c8a8a 100644 --- a/include/libcamera/internal/yaml_parser.h +++ b/include/libcamera/internal/yaml_parser.h @@ -163,6 +163,8 @@ public: typename std::enable_if_t< std::is_same::value || std::is_same::value || + std::is_same::value || + std::is_same::value || std::is_same::value || std::is_same::value || std::is_same::value || diff --git a/src/libcamera/yaml_parser.cpp b/src/libcamera/yaml_parser.cpp index 3fb6fec695ee..3faebe61d338 100644 --- a/src/libcamera/yaml_parser.cpp +++ b/src/libcamera/yaml_parser.cpp @@ -137,6 +137,67 @@ bool YamlObject::get(const bool &defaultValue, bool *ok) const return defaultValue; } +template<> +int16_t YamlObject::get(const int16_t &defaultValue, bool *ok) const +{ + setOk(ok, false); + + if (type_ != Type::Value) + return defaultValue; + + if (value_ == "") + return defaultValue; + + char *end; + + errno = 0; + int16_t value = std::strtol(value_.c_str(), &end, 10); + + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) + return defaultValue; + + setOk(ok, true); + return value; +} + +template<> +uint16_t YamlObject::get(const uint16_t &defaultValue, bool *ok) const +{ + setOk(ok, false); + + if (type_ != Type::Value) + return defaultValue; + + if (value_ == "") + return defaultValue; + + /* + * libyaml parses all scalar values as strings. When a string has + * leading spaces before a minus sign, for example " -10", strtoul + * skips leading spaces, accepts the leading minus sign, and the + * calculated digits are negated as if by unary minus. Rule it out in + * case the user gets a large number when the value is negative. + */ + std::size_t found = value_.find_first_not_of(" \t"); + if (found != std::string::npos && value_[found] == '-') + return defaultValue; + + char *end; + + errno = 0; + uint16_t value = std::strtoul(value_.c_str(), &end, 10); + + if ('\0' != *end || errno == ERANGE || + value < std::numeric_limits::min() || + value > std::numeric_limits::max()) + return defaultValue; + + setOk(ok, true); + return value; +} + template<> int32_t YamlObject::get(const int32_t &defaultValue, bool *ok) const { From patchwork Sat Jun 4 18:59:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16168 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5AAC3C326B for ; Sat, 4 Jun 2022 19:00:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D028B65648; Sat, 4 Jun 2022 21:00:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369221; bh=Glf9pjjGnzIfbfULE+Zq+A8HaL9XSI9VV/ERWec7nYo=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=FxC+Ire+6k32uaEtmJes+s22yFj+zwlreFuqt0lWC1XEV8Wxxar13WiI2WOYv2dRv 8XRAsPLBZVabQPp4OivGZM9lvUE4FIGNrJVsPGipgGs6AYgCQFZK9rK388T3X+Ic60 cw1hCHFjb7RPCk2yQU7U2skZ+kBPGuhzOh1/4UMubrABaphFAZL/OmYNCO4fs2ywgl OnhIA4zo6itslHjimBdE6xQkGEgx2Fg71k0naLCquMUOkrYYKLr06aJ4owj95i62B4 LKxcJJYi8WOnqaWtMUMu60nGoDgCGqPEHKlI2gCFnPadUQqX9N+9VBz2LMFnnBqY93 1RQpsRVRnaMdg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B4CD65648 for ; Sat, 4 Jun 2022 21:00:19 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Of3r0K1S"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D07266D4; Sat, 4 Jun 2022 21:00:17 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369218; bh=Glf9pjjGnzIfbfULE+Zq+A8HaL9XSI9VV/ERWec7nYo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Of3r0K1SMKQ0HlEjC1jvqlL8Mh4WHkDJBHL863BWmuhGirUjs0URD0qth4g/SrOh8 JnKKxoq8CTOP9rUAJsXwudyw2fPEfXTqYPV/YiDTGsaWXijrt35+Oh/ACxhm6lFCa9 14rVLsbg/WU9Y7h/qtt1sIq4JoxZ+I0FZv1+zxYI= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:38 +0300 Message-Id: <20220604185939.29163-14-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 13/14] ipa: raspberrypi: Replace tabs with spaces in tuning data files X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Tuning data files mostly use spaces for indentation, with occasional stray tabs. Use spaces consistently. This allows parsing the tuning files with libyaml, preparing to replace the dependency on boost. Signed-off-by: Laurent Pinchart --- src/ipa/raspberrypi/data/imx219.json | 8 ++++---- src/ipa/raspberrypi/data/imx219_noir.json | 10 +++++----- src/ipa/raspberrypi/data/imx290.json | 18 +++++++++--------- src/ipa/raspberrypi/data/imx477.json | 8 ++++---- src/ipa/raspberrypi/data/imx477_noir.json | 10 +++++----- src/ipa/raspberrypi/data/ov5647.json | 10 +++++----- src/ipa/raspberrypi/data/ov5647_noir.json | 12 ++++++------ src/ipa/raspberrypi/data/se327m12.json | 6 +++--- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/ipa/raspberrypi/data/imx219.json b/src/ipa/raspberrypi/data/imx219.json index de59d9363be4..4e24c5d57da1 100644 --- a/src/ipa/raspberrypi/data/imx219.json +++ b/src/ipa/raspberrypi/data/imx219.json @@ -189,10 +189,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] diff --git a/src/ipa/raspberrypi/data/imx219_noir.json b/src/ipa/raspberrypi/data/imx219_noir.json index 9a3f03ec86f4..1835ec3df63b 100644 --- a/src/ipa/raspberrypi/data/imx219_noir.json +++ b/src/ipa/raspberrypi/data/imx219_noir.json @@ -31,7 +31,7 @@ }, "rpi.awb": { - "bayes": 0 + "bayes": 0 }, "rpi.agc": { @@ -121,10 +121,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] diff --git a/src/ipa/raspberrypi/data/imx290.json b/src/ipa/raspberrypi/data/imx290.json index 20b45c1684c2..1363bab71340 100644 --- a/src/ipa/raspberrypi/data/imx290.json +++ b/src/ipa/raspberrypi/data/imx290.json @@ -29,11 +29,11 @@ }, "rpi.awb": { - "bayes": 0 + "bayes": 0 }, "rpi.agc": { - "speed": 0.2, + "speed": 0.2, "metering_modes": { "matrix": @@ -150,14 +150,14 @@ "rpi.ccm": { "ccms": - [ + [ { - "ct": 3900, "ccm": - [ - 1.54659, -0.17707, -0.36953, -0.51471, 1.72733, -0.21262, 0.06667, -0.92279, 1.85612 - ] - } - ] + "ct": 3900, "ccm": + [ + 1.54659, -0.17707, -0.36953, -0.51471, 1.72733, -0.21262, 0.06667, -0.92279, 1.85612 + ] + } + ] }, "rpi.focus": { diff --git a/src/ipa/raspberrypi/data/imx477.json b/src/ipa/raspberrypi/data/imx477.json index d07febd283ed..0f389661c246 100644 --- a/src/ipa/raspberrypi/data/imx477.json +++ b/src/ipa/raspberrypi/data/imx477.json @@ -189,10 +189,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] diff --git a/src/ipa/raspberrypi/data/imx477_noir.json b/src/ipa/raspberrypi/data/imx477_noir.json index 7d4fc7dab9fd..a379d780d966 100644 --- a/src/ipa/raspberrypi/data/imx477_noir.json +++ b/src/ipa/raspberrypi/data/imx477_noir.json @@ -31,7 +31,7 @@ }, "rpi.awb": { - "bayes": 0 + "bayes": 0 }, "rpi.agc": { @@ -121,10 +121,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] diff --git a/src/ipa/raspberrypi/data/ov5647.json b/src/ipa/raspberrypi/data/ov5647.json index 24bc06fb6114..e65f9385d970 100644 --- a/src/ipa/raspberrypi/data/ov5647.json +++ b/src/ipa/raspberrypi/data/ov5647.json @@ -189,10 +189,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] @@ -203,7 +203,7 @@ [ 0, 0.16, 1000, 0.165, 10000, 0.17 ], - "base_ev": 1.25 + "base_ev": 1.25 }, "rpi.alsc": { diff --git a/src/ipa/raspberrypi/data/ov5647_noir.json b/src/ipa/raspberrypi/data/ov5647_noir.json index 1c628ed13f19..dad73a5e8cd9 100644 --- a/src/ipa/raspberrypi/data/ov5647_noir.json +++ b/src/ipa/raspberrypi/data/ov5647_noir.json @@ -31,7 +31,7 @@ }, "rpi.awb": { - "bayes": 0 + "bayes": 0 }, "rpi.agc": { @@ -121,10 +121,10 @@ ] } ], - "shadows": - [ - { - "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": + "shadows": + [ + { + "bound": "LOWER", "q_lo": 0.0, "q_hi": 0.5, "y_target": [ 0, 0.17, 1000, 0.17 ] @@ -135,7 +135,7 @@ [ 0, 0.16, 1000, 0.165, 10000, 0.17 ], - "base_ev": 1.25 + "base_ev": 1.25 }, "rpi.alsc": { diff --git a/src/ipa/raspberrypi/data/se327m12.json b/src/ipa/raspberrypi/data/se327m12.json index 94af2239f700..5b1ac2ce3bf8 100644 --- a/src/ipa/raspberrypi/data/se327m12.json +++ b/src/ipa/raspberrypi/data/se327m12.json @@ -334,8 +334,8 @@ }, "rpi.sharpen": { - "threshold": 2.0, - "strength": 0.5, - "limit": 0.5 + "threshold": 2.0, + "strength": 0.5, + "limit": 0.5 } } From patchwork Sat Jun 4 18:59:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 16169 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id CD8B5C327D for ; Sat, 4 Jun 2022 19:00:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4F46665651; Sat, 4 Jun 2022 21:00:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1654369222; bh=BXwVDLqZukHi73ClXR+i2KffARet0962NKFFXGZ6VxM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=4baTeuLjfA5Aoj7HVetRYRB91eC9ur/nB6+0NwZTsffzUYfZY41Eu7y+TzimH3tVm OxMzyDznDHN2lCEyLyR9kodrF8kpPRmb8dB9mQ5o7MAIiQ1lCdfTKp8lK19JjecDY4 wpvuS/4hQRkgcgEwzzl/0zMl8wY3T8ZiEUgiW/3mFkaKDFhMu4EgOO9E52XQyEjSwn TGkoo/xuSY8wobhH4UrkvSn78ajbbz5u5uaOtlwH1Cm3VJqye7isoZEVAA0KdoOsfp 3id+qoZZII9LkQv/A4xoUMb7B4hjLhU9C6avTtGVTV6xRcJVRVMFHWIORpc/inzAET pxVIhnzCpa5sA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E65DD65647 for ; Sat, 4 Jun 2022 21:00:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="EPLXiVM5"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (85-76-79-203-nat.elisa-mobile.fi [85.76.79.203]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 781E66D4; Sat, 4 Jun 2022 21:00:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1654369220; bh=BXwVDLqZukHi73ClXR+i2KffARet0962NKFFXGZ6VxM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EPLXiVM55jOUIbRyIu20urU2JkCnkSgy6CpW9L2ItRH488MyMN7zufynoMCarbMkJ yBKDnxwYPEjJ3zzrnXZgFRHzaJZcUvG/oZDFbYOVA02iJ3UQuwcEmNRYaKGrgZ63XT m9xQ4wL4t/IdwkyFUDzPthg4XPP4ZBUabIfBnPbk= To: libcamera-devel@lists.libcamera.org Date: Sat, 4 Jun 2022 21:59:39 +0300 Message-Id: <20220604185939.29163-15-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> References: <20220604185939.29163-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [RFC PATCH v2 14/14] ipa: raspberrypi: Use YamlParser to replace dependency on boost X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The Raspberry Pi IPA module depends on boost only to parse the JSON tuning data files. As libcamera depends on libyaml, use the YamlParser class to parse those files and drop the dependency on boost. Signed-off-by: Laurent Pinchart --- README.rst | 6 -- src/ipa/raspberrypi/controller/algorithm.cpp | 2 +- src/ipa/raspberrypi/controller/algorithm.hpp | 6 +- src/ipa/raspberrypi/controller/controller.cpp | 27 ++++-- src/ipa/raspberrypi/controller/pwl.cpp | 12 ++- src/ipa/raspberrypi/controller/pwl.hpp | 5 +- src/ipa/raspberrypi/controller/rpi/agc.cpp | 94 +++++++++---------- src/ipa/raspberrypi/controller/rpi/agc.hpp | 10 +- src/ipa/raspberrypi/controller/rpi/alsc.cpp | 94 +++++++++---------- src/ipa/raspberrypi/controller/rpi/alsc.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/awb.cpp | 89 +++++++++--------- src/ipa/raspberrypi/controller/rpi/awb.hpp | 8 +- .../controller/rpi/black_level.cpp | 12 +-- .../controller/rpi/black_level.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/ccm.cpp | 28 +++--- src/ipa/raspberrypi/controller/rpi/ccm.hpp | 4 +- .../raspberrypi/controller/rpi/contrast.cpp | 18 ++-- .../raspberrypi/controller/rpi/contrast.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/dpc.cpp | 4 +- src/ipa/raspberrypi/controller/rpi/dpc.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/geq.cpp | 10 +- src/ipa/raspberrypi/controller/rpi/geq.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/lux.cpp | 12 +-- src/ipa/raspberrypi/controller/rpi/lux.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/noise.cpp | 6 +- src/ipa/raspberrypi/controller/rpi/noise.hpp | 2 +- src/ipa/raspberrypi/controller/rpi/sdn.cpp | 6 +- src/ipa/raspberrypi/controller/rpi/sdn.hpp | 2 +- .../raspberrypi/controller/rpi/sharpen.cpp | 8 +- .../raspberrypi/controller/rpi/sharpen.hpp | 2 +- src/ipa/raspberrypi/meson.build | 1 - src/ipa/raspberrypi/raspberrypi.cpp | 1 + 32 files changed, 241 insertions(+), 240 deletions(-) diff --git a/README.rst b/README.rst index f81d6e2e7867..8d9145f58d64 100644 --- a/README.rst +++ b/README.rst @@ -71,12 +71,6 @@ for improved debugging: [optional] information, and libunwind is not needed if both libdw and the glibc backtrace() function are available. -for the Raspberry Pi IPA: [optional] - libboost-dev - - Support for Raspberry Pi can be disabled through the meson - 'pipelines' option to avoid this dependency. - for device hotplug enumeration: [optional] libudev-dev diff --git a/src/ipa/raspberrypi/controller/algorithm.cpp b/src/ipa/raspberrypi/controller/algorithm.cpp index 43ad0a2be222..4fd36fc1be5b 100644 --- a/src/ipa/raspberrypi/controller/algorithm.cpp +++ b/src/ipa/raspberrypi/controller/algorithm.cpp @@ -9,7 +9,7 @@ using namespace RPiController; -void Algorithm::Read([[maybe_unused]] boost::property_tree::ptree const ¶ms) +void Algorithm::Read([[maybe_unused]] const libcamera::YamlObject ¶ms) { } diff --git a/src/ipa/raspberrypi/controller/algorithm.hpp b/src/ipa/raspberrypi/controller/algorithm.hpp index 5123c87bab34..87bfca8d2045 100644 --- a/src/ipa/raspberrypi/controller/algorithm.hpp +++ b/src/ipa/raspberrypi/controller/algorithm.hpp @@ -13,10 +13,10 @@ #include #include +#include "libcamera/internal/yaml_parser.h" + #include "controller.hpp" -#include - namespace RPiController { // This defines the basic interface for all control algorithms. @@ -33,7 +33,7 @@ public: virtual bool IsPaused() const { return paused_; } virtual void Pause() { paused_ = true; } virtual void Resume() { paused_ = false; } - virtual void Read(boost::property_tree::ptree const ¶ms); + virtual void Read(const libcamera::YamlObject ¶ms); virtual void Initialise(); virtual void SwitchMode(CameraMode const &camera_mode, Metadata *metadata); virtual void Prepare(Metadata *image_metadata); diff --git a/src/ipa/raspberrypi/controller/controller.cpp b/src/ipa/raspberrypi/controller/controller.cpp index d3433ad2e7e8..67d650ef0c1b 100644 --- a/src/ipa/raspberrypi/controller/controller.cpp +++ b/src/ipa/raspberrypi/controller/controller.cpp @@ -5,14 +5,16 @@ * controller.cpp - ISP controller */ +#include + +#include #include +#include "libcamera/internal/yaml_parser.h" + #include "algorithm.hpp" #include "controller.hpp" -#include -#include - using namespace RPiController; using namespace libcamera; @@ -32,16 +34,23 @@ Controller::~Controller() {} void Controller::Read(char const *filename) { - boost::property_tree::ptree root; - boost::property_tree::read_json(filename, root); - for (auto const &key_and_value : root) { - Algorithm *algo = CreateAlgorithm(key_and_value.first.c_str()); + File file(filename); + if (!file.open(File::OpenModeFlag::ReadOnly)) { + LOG(RPiController, Warning) + << "Failed to open tuning file '" << filename << "'"; + return; + } + + std::unique_ptr root = YamlParser::parse(file); + + for (auto const &[key, value] : root->asDict()) { + Algorithm *algo = CreateAlgorithm(key.c_str()); if (algo) { - algo->Read(key_and_value.second); + algo->Read(value); algorithms_.push_back(AlgorithmPtr(algo)); } else LOG(RPiController, Warning) - << "No algorithm found for \"" << key_and_value.first << "\""; + << "No algorithm found for \"" << key << "\""; } } diff --git a/src/ipa/raspberrypi/controller/pwl.cpp b/src/ipa/raspberrypi/controller/pwl.cpp index 130c820b559f..9c7bc94dd484 100644 --- a/src/ipa/raspberrypi/controller/pwl.cpp +++ b/src/ipa/raspberrypi/controller/pwl.cpp @@ -12,13 +12,15 @@ using namespace RPiController; -void Pwl::Read(boost::property_tree::ptree const ¶ms) +void Pwl::Read(const libcamera::YamlObject ¶ms) { - for (auto it = params.begin(); it != params.end(); it++) { - double x = it->second.get_value(); - assert(it == params.begin() || x > points_.back().x); + const auto &list = params.asList(); + + for (auto it = list.begin(); it != list.end(); it++) { + double x = it->get(0.0); + assert(it == list.begin() || x > points_.back().x); it++; - double y = it->second.get_value(); + double y = it->get(0.0); points_.push_back(Point(x, y)); } assert(points_.size() >= 2); diff --git a/src/ipa/raspberrypi/controller/pwl.hpp b/src/ipa/raspberrypi/controller/pwl.hpp index 484672f64095..70df4ba0daea 100644 --- a/src/ipa/raspberrypi/controller/pwl.hpp +++ b/src/ipa/raspberrypi/controller/pwl.hpp @@ -6,10 +6,11 @@ */ #pragma once +#include #include #include -#include +#include "libcamera/internal/yaml_parser.h" namespace RPiController { @@ -55,7 +56,7 @@ public: }; Pwl() {} Pwl(std::vector const &points) : points_(points) {} - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); void Append(double x, double y, const double eps = 1e-6); void Prepend(double x, double y, const double eps = 1e-6); Interval Domain() const; diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp index f6a9cb0a2cd8..c82f29600be7 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp @@ -30,13 +30,13 @@ LOG_DEFINE_CATEGORY(RPiAgc) #define PIPELINE_BITS 13 // seems to be a 13-bit pipeline -void AgcMeteringMode::Read(boost::property_tree::ptree const ¶ms) +void AgcMeteringMode::Read(const libcamera::YamlObject ¶ms) { int num = 0; - for (auto &p : params.get_child("weights")) { + for (const auto &p : params["weights"].asList()) { if (num == AGC_STATS_SIZE) throw std::runtime_error("AgcConfig: too many weights"); - weights[num++] = p.second.get_value(); + weights[num++] = p.get(0.0); } if (num != AGC_STATS_SIZE) throw std::runtime_error("AgcConfig: insufficient weights"); @@ -44,39 +44,39 @@ void AgcMeteringMode::Read(boost::property_tree::ptree const ¶ms) static std::string read_metering_modes(std::map &metering_modes, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { std::string first; - for (auto &p : params) { + for (const auto &[key, value] : params.asDict()) { AgcMeteringMode metering_mode; - metering_mode.Read(p.second); - metering_modes[p.first] = std::move(metering_mode); + metering_mode.Read(value); + metering_modes[key] = std::move(metering_mode); if (first.empty()) - first = p.first; + first = key; } return first; } static int read_list(std::vector &list, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { - for (auto &p : params) - list.push_back(p.second.get_value()); + for (const auto &p : params.asList()) + list.push_back(p.get(0.0)); return list.size(); } static int read_list(std::vector &list, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { - for (auto &p : params) - list.push_back(p.second.get_value() * 1us); + for (const auto &p : params.asList()) + list.push_back(p.get(0.0) * 1us); return list.size(); } -void AgcExposureMode::Read(boost::property_tree::ptree const ¶ms) +void AgcExposureMode::Read(const libcamera::YamlObject ¶ms) { - int num_shutters = read_list(shutter, params.get_child("shutter")); - int num_ags = read_list(gain, params.get_child("gain")); + int num_shutters = read_list(shutter, params["shutter"]); + int num_ags = read_list(gain, params["gain"]); if (num_shutters < 2 || num_ags < 2) throw std::runtime_error( "AgcConfig: must have at least two entries in exposure profile"); @@ -87,40 +87,40 @@ void AgcExposureMode::Read(boost::property_tree::ptree const ¶ms) static std::string read_exposure_modes(std::map &exposure_modes, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { std::string first; - for (auto &p : params) { + for (const auto &[key, value] : params.asDict()) { AgcExposureMode exposure_mode; - exposure_mode.Read(p.second); - exposure_modes[p.first] = std::move(exposure_mode); + exposure_mode.Read(value); + exposure_modes[key] = std::move(exposure_mode); if (first.empty()) - first = p.first; + first = key; } return first; } -void AgcConstraint::Read(boost::property_tree::ptree const ¶ms) +void AgcConstraint::Read(const libcamera::YamlObject ¶ms) { - std::string bound_string = params.get("bound", ""); + std::string bound_string = params["bound"].get(""); transform(bound_string.begin(), bound_string.end(), bound_string.begin(), ::toupper); if (bound_string != "UPPER" && bound_string != "LOWER") throw std::runtime_error( "AGC constraint type should be UPPER or LOWER"); bound = bound_string == "UPPER" ? Bound::UPPER : Bound::LOWER; - q_lo = params.get("q_lo"); - q_hi = params.get("q_hi"); - Y_target.Read(params.get_child("y_target")); + q_lo = params["q_lo"].get(0.0); + q_hi = params["q_hi"].get(0.0); + Y_target.Read(params["y_target"]); } static AgcConstraintMode -read_constraint_mode(boost::property_tree::ptree const ¶ms) +read_constraint_mode(const libcamera::YamlObject ¶ms) { AgcConstraintMode mode; - for (auto &p : params) { + for (const auto &p : params.asList()) { AgcConstraint constraint; - constraint.Read(p.second); + constraint.Read(p); mode.push_back(std::move(constraint)); } return mode; @@ -128,36 +128,36 @@ read_constraint_mode(boost::property_tree::ptree const ¶ms) static std::string read_constraint_modes( std::map &constraint_modes, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { std::string first; - for (auto &p : params) { - constraint_modes[p.first] = read_constraint_mode(p.second); + for (const auto &[key, value] : params.asDict()) { + constraint_modes[key] = read_constraint_mode(value); if (first.empty()) - first = p.first; + first = key; } return first; } -void AgcConfig::Read(boost::property_tree::ptree const ¶ms) +void AgcConfig::Read(const libcamera::YamlObject ¶ms) { LOG(RPiAgc, Debug) << "AgcConfig"; default_metering_mode = read_metering_modes( - metering_modes, params.get_child("metering_modes")); + metering_modes, params["metering_modes"]); default_exposure_mode = read_exposure_modes( - exposure_modes, params.get_child("exposure_modes")); + exposure_modes, params["exposure_modes"]); default_constraint_mode = read_constraint_modes( - constraint_modes, params.get_child("constraint_modes")); - Y_target.Read(params.get_child("y_target")); - speed = params.get("speed", 0.2); - startup_frames = params.get("startup_frames", 10); - convergence_frames = params.get("convergence_frames", 6); + constraint_modes, params["constraint_modes"]); + Y_target.Read(params["y_target"]); + speed = params["speed"].get(0.2); + startup_frames = params["startup_frames"].get(10); + convergence_frames = params["convergence_frames"].get(6); fast_reduce_threshold = - params.get("fast_reduce_threshold", 0.4); - base_ev = params.get("base_ev", 1.0); + params["fast_reduce_threshold"].get(0.4); + base_ev = params["base_ev"].get(1.0); // Start with quite a low value as ramping up is easier than ramping down. - default_exposure_time = params.get("default_exposure_time", 1000) * 1us; - default_analogue_gain = params.get("default_analogue_gain", 1.0); + default_exposure_time = params["default_exposure_time"].get(1000) * 1us; + default_analogue_gain = params["default_analogue_gain"].get(1.0); } Agc::ExposureValues::ExposureValues() @@ -186,7 +186,7 @@ char const *Agc::Name() const return NAME; } -void Agc::Read(boost::property_tree::ptree const ¶ms) +void Agc::Read(const libcamera::YamlObject ¶ms) { LOG(RPiAgc, Debug) << "Agc"; config_.Read(params); diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp index c100d3128c90..7794ba744efc 100644 --- a/src/ipa/raspberrypi/controller/rpi/agc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp @@ -26,13 +26,13 @@ namespace RPiController { struct AgcMeteringMode { double weights[AGC_STATS_SIZE]; - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); }; struct AgcExposureMode { std::vector shutter; std::vector gain; - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); }; struct AgcConstraint { @@ -41,13 +41,13 @@ struct AgcConstraint { double q_lo; double q_hi; Pwl Y_target; - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); }; typedef std::vector AgcConstraintMode; struct AgcConfig { - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); std::map metering_modes; std::map exposure_modes; std::map constraint_modes; @@ -72,7 +72,7 @@ class Agc : public AgcAlgorithm public: Agc(Controller *controller); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; // AGC handles "pausing" for itself. bool IsPaused() const override; void Pause() override; diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp index e575c14a92db..b38b037c7713 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp @@ -5,6 +5,7 @@ * alsc.cpp - ALSC (auto lens shading correction) control algorithm */ +#include #include #include @@ -50,12 +51,12 @@ char const *Alsc::Name() const return NAME; } -static void generate_lut(double *lut, boost::property_tree::ptree const ¶ms) +static void generate_lut(double *lut, const libcamera::YamlObject ¶ms) { - double cstrength = params.get("corner_strength", 2.0); + double cstrength = params["corner_strength"].get(2.0); if (cstrength <= 1.0) throw std::runtime_error("Alsc: corner_strength must be > 1.0"); - double asymmetry = params.get("asymmetry", 1.0); + double asymmetry = params["asymmetry"].get(1.0); if (asymmetry < 0) throw std::runtime_error("Alsc: asymmetry must be >= 0"); double f1 = cstrength - 1, f2 = 1 + sqrt(cstrength); @@ -73,50 +74,43 @@ static void generate_lut(double *lut, boost::property_tree::ptree const ¶ms) } } -static void read_lut(double *lut, boost::property_tree::ptree const ¶ms) +static void read_lut(double *lut, const libcamera::YamlObject ¶ms) { + if (params.size() != XY) + throw std::runtime_error( + "Alsc: invalid number of entries in LSC table"); + int num = 0; - const int max_num = XY; - for (auto &p : params) { - if (num == max_num) - throw std::runtime_error( - "Alsc: too many entries in LSC table"); - lut[num++] = p.second.get_value(); - } - if (num < max_num) - throw std::runtime_error("Alsc: too few entries in LSC table"); + for (const auto &p : params.asList()) + lut[num++] = p.get(0.0); } static void read_calibrations(std::vector &calibrations, - boost::property_tree::ptree const ¶ms, + const libcamera::YamlObject ¶ms, std::string const &name) { - if (params.get_child_optional(name)) { + if (params.contains(name)) { double last_ct = 0; - for (auto &p : params.get_child(name)) { - double ct = p.second.get("ct"); + for (const auto &p : params[name].asList()) { + double ct = p["ct"].get(0.0); if (ct <= last_ct) throw std::runtime_error( "Alsc: entries in " + name + " must be in increasing ct order"); AlscCalibration calibration; calibration.ct = last_ct = ct; - boost::property_tree::ptree const &table = - p.second.get_child("table"); + + const libcamera::YamlObject &table = p["table"]; + if (table.size() != XY) + throw std::runtime_error( + "Alsc: incorrect number of values for ct " + + std::to_string(ct) + " in " + + name); + int num = 0; - for (auto it = table.begin(); it != table.end(); it++) { - if (num == XY) - throw std::runtime_error( - "Alsc: too many values for ct " + - std::to_string(ct) + " in " + - name); - calibration.table[num++] = - it->second.get_value(); - } - if (num != XY) - throw std::runtime_error( - "Alsc: too few values for ct " + - std::to_string(ct) + " in " + name); + for (const auto &value : table.asList()) + calibration.table[num++] = value.get(0.0); + calibrations.push_back(calibration); LOG(RPiAlsc, Debug) << "Read " << name << " calibration for ct " << ct; @@ -124,35 +118,35 @@ static void read_calibrations(std::vector &calibrations, } } -void Alsc::Read(boost::property_tree::ptree const ¶ms) +void Alsc::Read(const libcamera::YamlObject ¶ms) { - config_.frame_period = params.get("frame_period", 12); - config_.startup_frames = params.get("startup_frames", 10); - config_.speed = params.get("speed", 0.05); - double sigma = params.get("sigma", 0.01); - config_.sigma_Cr = params.get("sigma_Cr", sigma); - config_.sigma_Cb = params.get("sigma_Cb", sigma); - config_.min_count = params.get("min_count", 10.0); - config_.min_G = params.get("min_G", 50); - config_.omega = params.get("omega", 1.3); - config_.n_iter = params.get("n_iter", X + Y); + config_.frame_period = params["frame_period"].get(12); + config_.startup_frames = params["startup_frames"].get(10); + config_.speed = params["speed"].get(0.05); + double sigma = params["sigma"].get(0.01); + config_.sigma_Cr = params["sigma_Cr"].get(sigma); + config_.sigma_Cb = params["sigma_Cb"].get(sigma); + config_.min_count = params["min_count"].get(10.0); + config_.min_G = params["min_G"].get(50); + config_.omega = params["omega"].get(1.3); + config_.n_iter = params["n_iter"].get(X + Y); config_.luminance_strength = - params.get("luminance_strength", 1.0); + params["luminance_strength"].get(1.0); for (int i = 0; i < XY; i++) config_.luminance_lut[i] = 1.0; - if (params.get_child_optional("corner_strength")) + if (params.contains("corner_strength")) generate_lut(config_.luminance_lut, params); - else if (params.get_child_optional("luminance_lut")) + else if (params.contains("luminance_lut")) read_lut(config_.luminance_lut, - params.get_child("luminance_lut")); + params["luminance_lut"]); else LOG(RPiAlsc, Warning) << "no luminance table - assume unity everywhere"; read_calibrations(config_.calibrations_Cr, params, "calibrations_Cr"); read_calibrations(config_.calibrations_Cb, params, "calibrations_Cb"); - config_.default_ct = params.get("default_ct", 4500.0); - config_.threshold = params.get("threshold", 1e-3); - config_.lambda_bound = params.get("lambda_bound", 0.05); + config_.default_ct = params["default_ct"].get(4500.0); + config_.threshold = params["threshold"].get(1e-3); + config_.lambda_bound = params["lambda_bound"].get(0.05); } static double get_ct(Metadata *metadata, double default_ct); diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp index d1dbe0d1d22d..9d28c1b49a6d 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp @@ -52,7 +52,7 @@ public: char const *Name() const override; void Initialise() override; void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp index d4c934473832..1c40bf878cd3 100644 --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp @@ -5,6 +5,8 @@ * awb.cpp - AWB control algorithm */ +#include + #include #include "../lux_status.h" @@ -24,33 +26,35 @@ LOG_DEFINE_CATEGORY(RPiAwb) // todo - the locking in this algorithm needs some tidying up as has been done // elsewhere (ALSC and AGC). -void AwbMode::Read(boost::property_tree::ptree const ¶ms) +void AwbMode::Read(const libcamera::YamlObject ¶ms) { - ct_lo = params.get("lo"); - ct_hi = params.get("hi"); + ct_lo = params["lo"].get(0.0); + ct_hi = params["hi"].get(0.0); } -void AwbPrior::Read(boost::property_tree::ptree const ¶ms) +void AwbPrior::Read(const libcamera::YamlObject ¶ms) { - lux = params.get("lux"); - prior.Read(params.get_child("prior")); + lux = params["lux"].get(0.0); + prior.Read(params["prior"]); } static void read_ct_curve(Pwl &ct_r, Pwl &ct_b, - boost::property_tree::ptree const ¶ms) + const libcamera::YamlObject ¶ms) { + const auto &list = params.asList(); int num = 0; - for (auto it = params.begin(); it != params.end(); it++) { - double ct = it->second.get_value(); - assert(it == params.begin() || ct != ct_r.Domain().end); - if (++it == params.end()) + + for (auto it = list.begin(); it != list.end(); it++) { + double ct = it->get(0.0); + assert(it == list.begin() || ct != ct_r.Domain().end); + if (++it == list.end()) throw std::runtime_error( "AwbConfig: incomplete CT curve entry"); - ct_r.Append(ct, it->second.get_value()); - if (++it == params.end()) + ct_r.Append(ct, it->get(0.0)); + if (++it == list.end()) throw std::runtime_error( "AwbConfig: incomplete CT curve entry"); - ct_b.Append(ct, it->second.get_value()); + ct_b.Append(ct, it->get(0.0)); num++; } if (num < 2) @@ -58,19 +62,19 @@ static void read_ct_curve(Pwl &ct_r, Pwl &ct_b, "AwbConfig: insufficient points in CT curve"); } -void AwbConfig::Read(boost::property_tree::ptree const ¶ms) +void AwbConfig::Read(const libcamera::YamlObject ¶ms) { - bayes = params.get("bayes", 1); - frame_period = params.get("frame_period", 10); - startup_frames = params.get("startup_frames", 10); - convergence_frames = params.get("convergence_frames", 3); - speed = params.get("speed", 0.05); - if (params.get_child_optional("ct_curve")) - read_ct_curve(ct_r, ct_b, params.get_child("ct_curve")); - if (params.get_child_optional("priors")) { - for (auto &p : params.get_child("priors")) { + bayes = params["bayes"].get(1); + frame_period = params["frame_period"].get(10); + startup_frames = params["startup_frames"].get(10); + convergence_frames = params["convergence_frames"].get(3); + speed = params["speed"].get(0.05); + if (params.contains("ct_curve")) + read_ct_curve(ct_r, ct_b, params["ct_curve"]); + if (params.contains("priors")) { + for (const auto &p : params["priors"].asList()) { AwbPrior prior; - prior.Read(p.second); + prior.Read(p); if (!priors.empty() && prior.lux <= priors.back().lux) throw std::runtime_error( "AwbConfig: Prior must be ordered in increasing lux value"); @@ -80,28 +84,28 @@ void AwbConfig::Read(boost::property_tree::ptree const ¶ms) throw std::runtime_error( "AwbConfig: no AWB priors configured"); } - if (params.get_child_optional("modes")) { - for (auto &p : params.get_child("modes")) { - modes[p.first].Read(p.second); + if (params.contains("modes")) { + for (const auto &[key, value] : params["modes"].asDict()) { + modes[key].Read(value); if (default_mode == nullptr) - default_mode = &modes[p.first]; + default_mode = &modes[key]; } if (default_mode == nullptr) throw std::runtime_error( "AwbConfig: no AWB modes configured"); } - min_pixels = params.get("min_pixels", 16.0); - min_G = params.get("min_G", 32); - min_regions = params.get("min_regions", 10); - delta_limit = params.get("delta_limit", 0.2); - coarse_step = params.get("coarse_step", 0.2); - transverse_pos = params.get("transverse_pos", 0.01); - transverse_neg = params.get("transverse_neg", 0.01); + min_pixels = params["min_pixels"].get(16.0); + min_G = params["min_G"].get(32); + min_regions = params["min_regions"].get(10); + delta_limit = params["delta_limit"].get(0.2); + coarse_step = params["coarse_step"].get(0.2); + transverse_pos = params["transverse_pos"].get(0.01); + transverse_neg = params["transverse_neg"].get(0.01); if (transverse_pos <= 0 || transverse_neg <= 0) throw std::runtime_error( "AwbConfig: transverse_pos/neg must be > 0"); - sensitivity_r = params.get("sensitivity_r", 1.0); - sensitivity_b = params.get("sensitivity_b", 1.0); + sensitivity_r = params["sensitivity_r"].get(1.0); + sensitivity_b = params["sensitivity_b"].get(1.0); if (bayes) { if (ct_r.Empty() || ct_b.Empty() || priors.empty() || default_mode == nullptr) { @@ -110,10 +114,9 @@ void AwbConfig::Read(boost::property_tree::ptree const ¶ms) bayes = false; } } - fast = params.get( - "fast", bayes); // default to fast for Bayesian, otherwise slow - whitepoint_r = params.get("whitepoint_r", 0.0); - whitepoint_b = params.get("whitepoint_b", 0.0); + fast = params[fast].get(bayes); // default to fast for Bayesian, otherwise slow + whitepoint_r = params["whitepoint_r"].get(0.0); + whitepoint_b = params["whitepoint_b"].get(0.0); if (bayes == false) sensitivity_r = sensitivity_b = 1.0; // nor do sensitivities make any sense @@ -144,7 +147,7 @@ char const *Awb::Name() const return NAME; } -void Awb::Read(boost::property_tree::ptree const ¶ms) +void Awb::Read(const libcamera::YamlObject ¶ms) { config_.Read(params); } diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp index ac3dca6f42fc..41334f798e2f 100644 --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp @@ -19,20 +19,20 @@ namespace RPiController { // Control algorithm to perform AWB calculations. struct AwbMode { - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); double ct_lo; // low CT value for search double ct_hi; // high CT value for search }; struct AwbPrior { - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); double lux; // lux level Pwl prior; // maps CT to prior log likelihood for this lux level }; struct AwbConfig { AwbConfig() : default_mode(nullptr) {} - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); // Only repeat the AWB calculation every "this many" frames uint16_t frame_period; // number of initial frames for which speed taken as 1.0 (maximum) @@ -82,7 +82,7 @@ public: ~Awb(); char const *Name() const override; void Initialise() override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; // AWB handles "pausing" for itself. bool IsPaused() const override; void Pause() override; diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.cpp b/src/ipa/raspberrypi/controller/rpi/black_level.cpp index 6b3497f13c19..de3a1e98ca1c 100644 --- a/src/ipa/raspberrypi/controller/rpi/black_level.cpp +++ b/src/ipa/raspberrypi/controller/rpi/black_level.cpp @@ -31,13 +31,13 @@ char const *BlackLevel::Name() const return NAME; } -void BlackLevel::Read(boost::property_tree::ptree const ¶ms) +void BlackLevel::Read(const libcamera::YamlObject ¶ms) { - uint16_t black_level = params.get( - "black_level", 4096); // 64 in 10 bits scaled to 16 bits - black_level_r_ = params.get("black_level_r", black_level); - black_level_g_ = params.get("black_level_g", black_level); - black_level_b_ = params.get("black_level_b", black_level); + // 64 in 10 bits scaled to 16 bits + uint16_t black_level = params["black_level"].get(4096); + black_level_r_ = params["black_level_r"].get(black_level); + black_level_g_ = params["black_level_g"].get(black_level); + black_level_b_ = params["black_level_b"].get(black_level); LOG(RPiBlackLevel, Debug) << " Read black levels red " << black_level_r_ << " green " << black_level_g_ diff --git a/src/ipa/raspberrypi/controller/rpi/black_level.hpp b/src/ipa/raspberrypi/controller/rpi/black_level.hpp index 65ec4d0ed26c..5a63b5faef21 100644 --- a/src/ipa/raspberrypi/controller/rpi/black_level.hpp +++ b/src/ipa/raspberrypi/controller/rpi/black_level.hpp @@ -18,7 +18,7 @@ class BlackLevel : public Algorithm public: BlackLevel(Controller *controller); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; private: diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.cpp b/src/ipa/raspberrypi/controller/rpi/ccm.cpp index 821a4c7c98c5..0e02a524c68d 100644 --- a/src/ipa/raspberrypi/controller/rpi/ccm.cpp +++ b/src/ipa/raspberrypi/controller/rpi/ccm.cpp @@ -37,17 +37,15 @@ Matrix::Matrix(double m0, double m1, double m2, double m3, double m4, double m5, m[0][0] = m0, m[0][1] = m1, m[0][2] = m2, m[1][0] = m3, m[1][1] = m4, m[1][2] = m5, m[2][0] = m6, m[2][1] = m7, m[2][2] = m8; } -void Matrix::Read(boost::property_tree::ptree const ¶ms) +void Matrix::Read(const libcamera::YamlObject ¶ms) { double *ptr = (double *)m; - int n = 0; - for (auto it = params.begin(); it != params.end(); it++) { - if (n++ == 9) - throw std::runtime_error("Ccm: too many values in CCM"); - *ptr++ = it->second.get_value(); - } - if (n < 9) - throw std::runtime_error("Ccm: too few values in CCM"); + + if (params.size() != 9) + throw std::runtime_error("Ccm: wrong number of values in CCM"); + + for (const auto ¶m : params.asList()) + *ptr++ = param.get(0.0); } Ccm::Ccm(Controller *controller) @@ -58,14 +56,14 @@ char const *Ccm::Name() const return NAME; } -void Ccm::Read(boost::property_tree::ptree const ¶ms) +void Ccm::Read(const libcamera::YamlObject ¶ms) { - if (params.get_child_optional("saturation")) - config_.saturation.Read(params.get_child("saturation")); - for (auto &p : params.get_child("ccms")) { + if (params.contains("saturation")) + config_.saturation.Read(params["saturation"]); + for (auto &p : params["ccms"].asList()) { CtCcm ct_ccm; - ct_ccm.ct = p.second.get("ct"); - ct_ccm.ccm.Read(p.second.get_child("ccm")); + ct_ccm.ct = p["ct"].get(0.0); + ct_ccm.ccm.Read(p["ccm"]); if (!config_.ccms.empty() && ct_ccm.ct <= config_.ccms.back().ct) throw std::runtime_error( diff --git a/src/ipa/raspberrypi/controller/rpi/ccm.hpp b/src/ipa/raspberrypi/controller/rpi/ccm.hpp index 330ed51fe398..073f02526850 100644 --- a/src/ipa/raspberrypi/controller/rpi/ccm.hpp +++ b/src/ipa/raspberrypi/controller/rpi/ccm.hpp @@ -20,7 +20,7 @@ struct Matrix { double m6, double m7, double m8); Matrix(); double m[3][3]; - void Read(boost::property_tree::ptree const ¶ms); + void Read(const libcamera::YamlObject ¶ms); }; static inline Matrix operator*(double d, Matrix const &m) { @@ -62,7 +62,7 @@ class Ccm : public CcmAlgorithm public: Ccm(Controller *controller = NULL); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void SetSaturation(double saturation) override; void Initialise() override; void Prepare(Metadata *image_metadata) override; diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.cpp b/src/ipa/raspberrypi/controller/rpi/contrast.cpp index ae55aad56739..534f8b48a59b 100644 --- a/src/ipa/raspberrypi/controller/rpi/contrast.cpp +++ b/src/ipa/raspberrypi/controller/rpi/contrast.cpp @@ -36,21 +36,21 @@ char const *Contrast::Name() const return NAME; } -void Contrast::Read(boost::property_tree::ptree const ¶ms) +void Contrast::Read(const libcamera::YamlObject ¶ms) { // enable adaptive enhancement by default - config_.ce_enable = params.get("ce_enable", 1); + config_.ce_enable = params["ce_enable"].get(1); // the point near the bottom of the histogram to move - config_.lo_histogram = params.get("lo_histogram", 0.01); + config_.lo_histogram = params["lo_histogram"].get(0.01); // where in the range to try and move it to - config_.lo_level = params.get("lo_level", 0.015); + config_.lo_level = params["lo_level"].get(0.015); // but don't move by more than this - config_.lo_max = params.get("lo_max", 500); + config_.lo_max = params["lo_max"].get(500); // equivalent values for the top of the histogram... - config_.hi_histogram = params.get("hi_histogram", 0.95); - config_.hi_level = params.get("hi_level", 0.95); - config_.hi_max = params.get("hi_max", 2000); - config_.gamma_curve.Read(params.get_child("gamma_curve")); + config_.hi_histogram = params["hi_histogram"].get(0.95); + config_.hi_level = params["hi_level"].get(0.95); + config_.hi_max = params["hi_max"].get(2000); + config_.gamma_curve.Read(params["gamma_curve"]); } void Contrast::SetBrightness(double brightness) diff --git a/src/ipa/raspberrypi/controller/rpi/contrast.hpp b/src/ipa/raspberrypi/controller/rpi/contrast.hpp index 85624539a1da..6b1e41724f5b 100644 --- a/src/ipa/raspberrypi/controller/rpi/contrast.hpp +++ b/src/ipa/raspberrypi/controller/rpi/contrast.hpp @@ -32,7 +32,7 @@ class Contrast : public ContrastAlgorithm public: Contrast(Controller *controller = NULL); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void SetBrightness(double brightness) override; void SetContrast(double contrast) override; void Initialise() override; diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.cpp b/src/ipa/raspberrypi/controller/rpi/dpc.cpp index 110f50560e76..ac8aa78921c6 100644 --- a/src/ipa/raspberrypi/controller/rpi/dpc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/dpc.cpp @@ -29,9 +29,9 @@ char const *Dpc::Name() const return NAME; } -void Dpc::Read(boost::property_tree::ptree const ¶ms) +void Dpc::Read(const libcamera::YamlObject ¶ms) { - config_.strength = params.get("strength", 1); + config_.strength = params["strength"].get(1); if (config_.strength < 0 || config_.strength > 2) throw std::runtime_error("Dpc: bad strength value"); } diff --git a/src/ipa/raspberrypi/controller/rpi/dpc.hpp b/src/ipa/raspberrypi/controller/rpi/dpc.hpp index d90285c4eb56..382e20a6f1db 100644 --- a/src/ipa/raspberrypi/controller/rpi/dpc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/dpc.hpp @@ -22,7 +22,7 @@ class Dpc : public Algorithm public: Dpc(Controller *controller); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; private: diff --git a/src/ipa/raspberrypi/controller/rpi/geq.cpp b/src/ipa/raspberrypi/controller/rpi/geq.cpp index 4530cb75792c..cff3bfe01ed6 100644 --- a/src/ipa/raspberrypi/controller/rpi/geq.cpp +++ b/src/ipa/raspberrypi/controller/rpi/geq.cpp @@ -33,14 +33,14 @@ char const *Geq::Name() const return NAME; } -void Geq::Read(boost::property_tree::ptree const ¶ms) +void Geq::Read(const libcamera::YamlObject ¶ms) { - config_.offset = params.get("offset", 0); - config_.slope = params.get("slope", 0.0); + config_.offset = params["offset"].get(0); + config_.slope = params["slope"].get(0.0); if (config_.slope < 0.0 || config_.slope >= 1.0) throw std::runtime_error("Geq: bad slope value"); - if (params.get_child_optional("strength")) - config_.strength.Read(params.get_child("strength")); + if (params.contains("strength")) + config_.strength.Read(params["strength"]); } void Geq::Prepare(Metadata *image_metadata) diff --git a/src/ipa/raspberrypi/controller/rpi/geq.hpp b/src/ipa/raspberrypi/controller/rpi/geq.hpp index 8ba3046b2a2b..84104be40452 100644 --- a/src/ipa/raspberrypi/controller/rpi/geq.hpp +++ b/src/ipa/raspberrypi/controller/rpi/geq.hpp @@ -24,7 +24,7 @@ class Geq : public Algorithm public: Geq(Controller *controller); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; private: diff --git a/src/ipa/raspberrypi/controller/rpi/lux.cpp b/src/ipa/raspberrypi/controller/rpi/lux.cpp index f77e9140ac10..cb93198d08a5 100644 --- a/src/ipa/raspberrypi/controller/rpi/lux.cpp +++ b/src/ipa/raspberrypi/controller/rpi/lux.cpp @@ -36,14 +36,14 @@ char const *Lux::Name() const return NAME; } -void Lux::Read(boost::property_tree::ptree const ¶ms) +void Lux::Read(const libcamera::YamlObject ¶ms) { reference_shutter_speed_ = - params.get("reference_shutter_speed") * 1.0us; - reference_gain_ = params.get("reference_gain"); - reference_aperture_ = params.get("reference_aperture", 1.0); - reference_Y_ = params.get("reference_Y"); - reference_lux_ = params.get("reference_lux"); + params["reference_shutter_speed"].get(0.0) * 1.0us; + reference_gain_ = params["reference_gain"].get(0.0); + reference_aperture_ = params["reference_aperture"].get(1.0); + reference_Y_ = params["reference_Y"].get(0.0); + reference_lux_ = params["reference_lux"].get(0.0); current_aperture_ = reference_aperture_; } diff --git a/src/ipa/raspberrypi/controller/rpi/lux.hpp b/src/ipa/raspberrypi/controller/rpi/lux.hpp index 3ebd35d1e382..7d85199f7def 100644 --- a/src/ipa/raspberrypi/controller/rpi/lux.hpp +++ b/src/ipa/raspberrypi/controller/rpi/lux.hpp @@ -22,7 +22,7 @@ class Lux : public Algorithm public: Lux(Controller *controller); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; void Process(StatisticsPtr &stats, Metadata *image_metadata) override; void SetCurrentAperture(double aperture); diff --git a/src/ipa/raspberrypi/controller/rpi/noise.cpp b/src/ipa/raspberrypi/controller/rpi/noise.cpp index 63cad639f313..66a2a7f3486c 100644 --- a/src/ipa/raspberrypi/controller/rpi/noise.cpp +++ b/src/ipa/raspberrypi/controller/rpi/noise.cpp @@ -39,10 +39,10 @@ void Noise::SwitchMode(CameraMode const &camera_mode, mode_factor_ = std::max(1.0, camera_mode.noise_factor); } -void Noise::Read(boost::property_tree::ptree const ¶ms) +void Noise::Read(const libcamera::YamlObject ¶ms) { - reference_constant_ = params.get("reference_constant"); - reference_slope_ = params.get("reference_slope"); + reference_constant_ = params["reference_constant"].get(0.0); + reference_slope_ = params["reference_slope"].get(0.0); } void Noise::Prepare(Metadata *image_metadata) diff --git a/src/ipa/raspberrypi/controller/rpi/noise.hpp b/src/ipa/raspberrypi/controller/rpi/noise.hpp index 1c9de5c87d08..353e79fa2a8c 100644 --- a/src/ipa/raspberrypi/controller/rpi/noise.hpp +++ b/src/ipa/raspberrypi/controller/rpi/noise.hpp @@ -19,7 +19,7 @@ public: Noise(Controller *controller); char const *Name() const override; void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Prepare(Metadata *image_metadata) override; private: diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.cpp b/src/ipa/raspberrypi/controller/rpi/sdn.cpp index 9384550983e7..619a793cbdfb 100644 --- a/src/ipa/raspberrypi/controller/rpi/sdn.cpp +++ b/src/ipa/raspberrypi/controller/rpi/sdn.cpp @@ -32,10 +32,10 @@ char const *Sdn::Name() const return NAME; } -void Sdn::Read(boost::property_tree::ptree const ¶ms) +void Sdn::Read(const libcamera::YamlObject ¶ms) { - deviation_ = params.get("deviation", 3.2); - strength_ = params.get("strength", 0.75); + deviation_ = params["deviation"].get(3.2); + strength_ = params["strength"].get(0.75); } void Sdn::Initialise() {} diff --git a/src/ipa/raspberrypi/controller/rpi/sdn.hpp b/src/ipa/raspberrypi/controller/rpi/sdn.hpp index 2371ce04163f..e69557908cea 100644 --- a/src/ipa/raspberrypi/controller/rpi/sdn.hpp +++ b/src/ipa/raspberrypi/controller/rpi/sdn.hpp @@ -18,7 +18,7 @@ class Sdn : public DenoiseAlgorithm public: Sdn(Controller *controller = NULL); char const *Name() const override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void Initialise() override; void Prepare(Metadata *image_metadata) override; void SetMode(DenoiseMode mode) override; diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp b/src/ipa/raspberrypi/controller/rpi/sharpen.cpp index 18825a43867b..491f88d06c79 100644 --- a/src/ipa/raspberrypi/controller/rpi/sharpen.cpp +++ b/src/ipa/raspberrypi/controller/rpi/sharpen.cpp @@ -37,11 +37,11 @@ void Sharpen::SwitchMode(CameraMode const &camera_mode, mode_factor_ = std::max(1.0, camera_mode.noise_factor); } -void Sharpen::Read(boost::property_tree::ptree const ¶ms) +void Sharpen::Read(const libcamera::YamlObject ¶ms) { - threshold_ = params.get("threshold", 1.0); - strength_ = params.get("strength", 1.0); - limit_ = params.get("limit", 1.0); + threshold_ = params["threshold"].get(1.0); + strength_ = params["strength"].get(1.0); + limit_ = params["limit"].get(1.0); LOG(RPiSharpen, Debug) << "Read threshold " << threshold_ << " strength " << strength_ diff --git a/src/ipa/raspberrypi/controller/rpi/sharpen.hpp b/src/ipa/raspberrypi/controller/rpi/sharpen.hpp index 13a076a86895..6dfc79afb0ac 100644 --- a/src/ipa/raspberrypi/controller/rpi/sharpen.hpp +++ b/src/ipa/raspberrypi/controller/rpi/sharpen.hpp @@ -19,7 +19,7 @@ public: Sharpen(Controller *controller); char const *Name() const override; void SwitchMode(CameraMode const &camera_mode, Metadata *metadata) override; - void Read(boost::property_tree::ptree const ¶ms) override; + void Read(const libcamera::YamlObject ¶ms) override; void SetStrength(double strength) override; void Prepare(Metadata *image_metadata) override; diff --git a/src/ipa/raspberrypi/meson.build b/src/ipa/raspberrypi/meson.build index 32897e07dad9..517d815bb98c 100644 --- a/src/ipa/raspberrypi/meson.build +++ b/src/ipa/raspberrypi/meson.build @@ -4,7 +4,6 @@ ipa_name = 'ipa_rpi' rpi_ipa_deps = [ libcamera_private, - dependency('boost'), libatomic, ] diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp index 3b126bb5175e..f0f568d12513 100644 --- a/src/ipa/raspberrypi/raspberrypi.cpp +++ b/src/ipa/raspberrypi/raspberrypi.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include