[v1,2/3] treewide: Use `YamlObject::find()`
diff mbox series

Message ID 20241205163411.1160094-2-pobrn@protonmail.com
State New
Headers show
Series
  • [v1,1/3] libcamera: yaml_parser: Add `YamlObject::find(key)`
Related show

Commit Message

Barnabás Pőcze Dec. 5, 2024, 4:34 p.m. UTC
Replace some uses of `contains()` + `operator[]` with `find()`.
Using `find()` avoids the double lookup, as well as does away with
the need for specifying the key twice.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
---
 src/android/camera_hal_config.cpp          | 19 ++++----
 src/ipa/ipu3/ipu3.cpp                      |  5 +-
 src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------
 src/ipa/rkisp1/rkisp1.cpp                  |  5 +-
 src/ipa/rpi/controller/controller.cpp      |  5 +-
 src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------
 src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--
 src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-
 src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--
 src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---
 src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-
 src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-
 src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----
 src/ipa/simple/soft_simple.cpp             |  5 +-
 14 files changed, 99 insertions(+), 97 deletions(-)

Comments

Laurent Pinchart Dec. 6, 2024, 1:09 a.m. UTC | #1
Hi Barnabás,

Thank you for the patch.

On Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:
> Replace some uses of `contains()` + `operator[]` with `find()`.
> Using `find()` avoids the double lookup, as well as does away with
> the need for specifying the key twice.
> 
> Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
> ---
>  src/android/camera_hal_config.cpp          | 19 ++++----
>  src/ipa/ipu3/ipu3.cpp                      |  5 +-
>  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------
>  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-
>  src/ipa/rpi/controller/controller.cpp      |  5 +-
>  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------
>  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--
>  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-
>  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--
>  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---
>  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-
>  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-
>  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----
>  src/ipa/simple/soft_simple.cpp             |  5 +-
>  14 files changed, 99 insertions(+), 97 deletions(-)
> 
> diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp
> index 7ef451ef..6fde953d 100644
> --- a/src/android/camera_hal_config.cpp
> +++ b/src/android/camera_hal_config.cpp
> @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,
>  		return -EINVAL;
>  
>  	/* Parse property "cameras" */
> -	if (!root->contains("cameras"))
> +	auto *yamlObjectCameras = root->find("cameras");

I generally dislike overusing auto as it makes the code less explicit,
and therefore less readable. There are valid use cases, for instance
spelling out std::map<std::string, std::vector<std::pair<...>>>::iterator
would be inconvenient. Usage of auto in structured bindings is also
useful. In this specifif case, however, writing

	const YamlObject *yamlObjectCameras = root->find("cameras");

isn't much longer, and I think it improves readability.

Same below.

> +	if (!yamlObjectCameras)
>  		return -EINVAL;
>  
> -	const YamlObject &yamlObjectCameras = (*root)["cameras"];
> -
> -	if (!yamlObjectCameras.isDictionary())
> +	if (!yamlObjectCameras->isDictionary())
>  		return -EINVAL;
>  
> -	for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {
> +	for (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {
>  		if (parseCameraConfigData(cameraId, configData))
>  			return -EINVAL;
>  	}
> @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,
>  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
>  					    CameraConfigData &cameraConfigData)
>  {
> -	if (!cameraObject.contains("location"))
> +	auto *loc = cameraObject.find("location");
> +	if (!loc)
>  		return -EINVAL;
>  
> -	std::string location = cameraObject["location"].get<std::string>("");
> +	std::string location = loc->get<std::string>("");
>  
>  	if (location == "front")
>  		cameraConfigData.facing = CAMERA_FACING_FRONT;
> @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
>  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,
>  					    CameraConfigData &cameraConfigData)
>  {
> -	if (!cameraObject.contains("rotation"))
> +	auto *rot = cameraObject.find("rotation");
> +	if (!rot)
>  		return -EINVAL;
>  
> -	int32_t rotation = cameraObject["rotation"].get<int32_t>(-1);
> +	int32_t rotation = rot->get<int32_t>(-1);
>  
>  	if (rotation < 0 || rotation >= 360) {
>  		LOG(HALConfig, Error)
> diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> index 44c98cbf..88b1bb81 100644
> --- a/src/ipa/ipu3/ipu3.cpp
> +++ b/src/ipa/ipu3/ipu3.cpp
> @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,
>  		return -EINVAL;
>  	}
>  
> -	if (!data->contains("algorithms")) {
> +	auto *algos = data->find("algorithms");
> +	if (!algos) {
>  		LOG(IPAIPU3, Error)
>  			<< "Tuning file doesn't contain any algorithm";
>  		return -EINVAL;
>  	}
>  
> -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> +	int ret = createAlgorithms(context_, *algos);
>  	if (ret)
>  		return ret;
>  
> diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
> index 78946281..8946c1a7 100644
> --- a/src/ipa/rkisp1/algorithms/dpcc.cpp
> +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
> @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
>  		/* PG Method */
>  		const YamlObject &pgObject = set["pg-factor"];
>  
> -		if (pgObject.contains("green")) {
> +		if (auto *green = pgObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
>  
> -			value = pgObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
>  		}
>  
> -		if (pgObject.contains("red-blue")) {
> +		if (auto *redBlue = pgObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
>  
> -			value = pgObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
>  		}
>  
>  		/* RO Method */
>  		const YamlObject &roObject = set["ro-limits"];
>  
> -		if (roObject.contains("green")) {
> +		if (auto *green = roObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
>  
> -			value = roObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			config_.ro_limits |=
>  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
>  		}
>  
> -		if (roObject.contains("red-blue")) {
> +		if (auto *redBlue = roObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
>  
> -			value = roObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			config_.ro_limits |=
>  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
>  		}
> @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
>  		const YamlObject &rgObject = set["rg-factor"];
>  		method.rg_fac = 0;
>  
> -		if (rgObject.contains("green")) {
> +		if (auto *green = rgObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
>  
> -			value = rgObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
>  		}
>  
> -		if (rgObject.contains("red-blue")) {
> +		if (auto *redBlue = rgObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
>  
> -			value = rgObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
>  		}
>  
>  		/* RND Method */
>  		const YamlObject &rndOffsetsObject = set["rnd-offsets"];
>  
> -		if (rndOffsetsObject.contains("green")) {
> +		if (auto *green = rndOffsetsObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
>  
> -			value = rndOffsetsObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			config_.rnd_offs |=
>  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
>  		}
>  
> -		if (rndOffsetsObject.contains("red-blue")) {
> +		if (auto *redBlue = rndOffsetsObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
>  
> -			value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			config_.rnd_offs |=
>  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
>  		}
> @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
>  		const YamlObject &rndThresholdObject = set["rnd-threshold"];
>  		method.rnd_thresh = 0;
>  
> -		if (rndThresholdObject.contains("green")) {
> +		if (auto *green = rndThresholdObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
>  
> -			value = rndThresholdObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			method.rnd_thresh |=
>  				RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
>  		}
>  
> -		if (rndThresholdObject.contains("red-blue")) {
> +		if (auto *redBlue = rndThresholdObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
>  
> -			value = rndThresholdObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			method.rnd_thresh |=
>  				RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
>  		}
> @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
>  		const YamlObject &lcThresholdObject = set["line-threshold"];
>  		method.line_thresh = 0;
>  
> -		if (lcThresholdObject.contains("green")) {
> +		if (auto *green = lcThresholdObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
>  
> -			value = lcThresholdObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			method.line_thresh |=
>  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
>  		}
>  
> -		if (lcThresholdObject.contains("red-blue")) {
> +		if (auto *redBlue = lcThresholdObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
>  
> -			value = lcThresholdObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			method.line_thresh |=
>  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
>  		}
> @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
>  		const YamlObject &lcTMadFactorObject = set["line-mad-factor"];
>  		method.line_mad_fac = 0;
>  
> -		if (lcTMadFactorObject.contains("green")) {
> +		if (auto *green = lcTMadFactorObject.find("green")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
>  
> -			value = lcTMadFactorObject["green"].get<uint16_t>(0);
> +			value = green->get<uint16_t>(0);
>  			method.line_mad_fac |=
>  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
>  		}
>  
> -		if (lcTMadFactorObject.contains("red-blue")) {
> +		if (auto *redBlue = lcTMadFactorObject.find("red-blue")) {
>  			method.method |=
>  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
>  
> -			value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
> +			value = redBlue->get<uint16_t>(0);
>  			method.line_mad_fac |=
>  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
>  		}
> diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> index 2ffdd99b..202b53b7 100644
> --- a/src/ipa/rkisp1/rkisp1.cpp
> +++ b/src/ipa/rkisp1/rkisp1.cpp
> @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
>  		return -EINVAL;
>  	}
>  
> -	if (!data->contains("algorithms")) {
> +	auto *algos = data->find("algorithms");
> +	if (!algos) {
>  		LOG(IPARkISP1, Error)
>  			<< "Tuning file doesn't contain any algorithm";
>  		return -EINVAL;
>  	}
>  
> -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> +	int ret = createAlgorithms(context_, *algos);
>  	if (ret)
>  		return ret;
>  
> diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp
> index e0131018..fbf31f23 100644
> --- a/src/ipa/rpi/controller/controller.cpp
> +++ b/src/ipa/rpi/controller/controller.cpp
> @@ -109,14 +109,15 @@ int Controller::read(char const *filename)
>  				return ret;
>  		}
>  	} else if (version < 3.0) {
> -		if (!root->contains("algorithms")) {
> +		auto *algos = root->find("algorithms");
> +		if (!algos) {
>  			LOG(RPiController, Error)
>  				<< "Tuning file " << filename
>  				<< " does not have an \"algorithms\" list!";
>  			return -EINVAL;
>  		}
>  
> -		for (auto const &rootAlgo : (*root)["algorithms"].asList())
> +		for (auto const &rootAlgo : algos->asList())
>  			for (auto const &[key, value] : rootAlgo.asDict()) {
>  				int ret = createAlgorithm(key, value);
>  				if (ret)
> diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp
> index 2157eb94..c29bbaeb 100644
> --- a/src/ipa/rpi/controller/rpi/af.cpp
> +++ b/src/ipa/rpi/controller/rpi/af.cpp
> @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)
>  
>  int Af::CfgParams::read(const libcamera::YamlObject &params)
>  {
> -	if (params.contains("ranges")) {
> -		auto &rr = params["ranges"];
> -
> -		if (rr.contains("normal"))
> -			ranges[AfRangeNormal].read(rr["normal"]);
> +	if (auto *rs = params.find("ranges")) {

I would have kept the same variable name (rr) but that doesn't matter
much.

> +		if (auto *normal = rs->find("normal"))
> +			ranges[AfRangeNormal].read(*normal);
>  		else
>  			LOG(RPiAf, Warning) << "Missing range \"normal\"";
>  
>  		ranges[AfRangeMacro] = ranges[AfRangeNormal];
> -		if (rr.contains("macro"))
> -			ranges[AfRangeMacro].read(rr["macro"]);
> +		if (auto *macro = rs->find("macro"))
> +			ranges[AfRangeMacro].read(*macro);
>  
>  		ranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,
>  							ranges[AfRangeMacro].focusMin);
>  		ranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,
>  							ranges[AfRangeMacro].focusMax);
>  		ranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;
> -		if (rr.contains("full"))
> -			ranges[AfRangeFull].read(rr["full"]);
> +		if (auto *full = rs->find("full"))
> +			ranges[AfRangeFull].read(*full);
>  	} else
>  		LOG(RPiAf, Warning) << "No ranges defined";
>  
> -	if (params.contains("speeds")) {
> -		auto &ss = params["speeds"];
> -
> -		if (ss.contains("normal"))
> -			speeds[AfSpeedNormal].read(ss["normal"]);
> +	if (auto *ss = params.find("speeds")) {
> +		if (auto *normal = ss->find("normal"))
> +			speeds[AfSpeedNormal].read(*normal);
>  		else
>  			LOG(RPiAf, Warning) << "Missing speed \"normal\"";
>  
>  		speeds[AfSpeedFast] = speeds[AfSpeedNormal];
> -		if (ss.contains("fast"))
> -			speeds[AfSpeedFast].read(ss["fast"]);
> +		if (auto *fast = ss->find("fast"))
> +			speeds[AfSpeedFast].read(*fast);
>  	} else
>  		LOG(RPiAf, Warning) << "No speeds defined";
>  
> @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)
>  	readNumber<uint32_t>(confClip, params, "conf_clip");
>  	readNumber<uint32_t>(skipFrames, params, "skip_frames");
>  
> -	if (params.contains("map"))
> -		map = params["map"].get<ipa::Pwl>(ipa::Pwl{});
> +	if (auto *m = params.find("map"))
> +		map = m->get<ipa::Pwl>(ipa::Pwl{});
>  	else
>  		LOG(RPiAf, Warning) << "No map defined";
>  
> diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
> index c48fdf15..5d924ebf 100644
> --- a/src/ipa/rpi/controller/rpi/agc.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc.cpp
> @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)
>  	 * When there is only a single channel we can read the old style syntax.
>  	 * Otherwise we expect a "channels" keyword followed by a list of configurations.
>  	 */
> -	if (!params.contains("channels")) {
> +	auto *channels = params.find("channels");
> +	if (!channels) {
>  		LOG(RPiAgc, Debug) << "Single channel only";
>  		channelTotalExposures_.resize(1, 0s);
>  		channelData_.emplace_back();
>  		return channelData_.back().channel.read(params, getHardwareConfig());
>  	}
>  
> -	const auto &channels = params["channels"].asList();
> -	for (auto ch = channels.begin(); ch != channels.end(); ch++) {
> +	for (const auto &ch : channels->asList()) {
>  		LOG(RPiAgc, Debug) << "Read AGC channel";
>  		channelData_.emplace_back();
> -		int ret = channelData_.back().channel.read(*ch, getHardwareConfig());
> +		int ret = channelData_.back().channel.read(ch, getHardwareConfig());
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> index 79c45973..50b9efd2 100644
> --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
> +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)
>  	if (ret)
>  		return ret;
>  
> -	if (params.contains("channel_constraints")) {
> -		ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
> +	if (auto *cc = params.find("channel_constraints")) {
> +		ret = readChannelConstraints(channelConstraints, *cc);
>  		if (ret)
>  			return ret;
>  	}
> diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
> index 21edb819..5a1a702b 100644
> --- a/src/ipa/rpi/controller/rpi/alsc.cpp
> +++ b/src/ipa/rpi/controller/rpi/alsc.cpp
> @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,
>  			    const libcamera::YamlObject &params,
>  			    std::string const &name, const Size &size)
>  {
> -	if (params.contains(name)) {
> +	if (auto *param = params.find(name)) {
>  		double lastCt = 0;
> -		for (const auto &p : params[name].asList()) {
> +		for (const auto &p : param->asList()) {
>  			auto value = p["ct"].get<double>();
>  			if (!value)
>  				return -EINVAL;
> @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)
>  	config_.luminanceLut.resize(config_.tableSize, 1.0);
>  	int ret = 0;
>  
> -	if (params.contains("corner_strength"))
> +	if (params.find("corner_strength"))
>  		ret = generateLut(config_.luminanceLut, params);
> -	else if (params.contains("luminance_lut"))
> -		ret = readLut(config_.luminanceLut, params["luminance_lut"]);
> +	else if (auto *ll = params.find("luminance_lut"))
> +		ret = readLut(config_.luminanceLut, *ll);
>  	else
>  		LOG(RPiAlsc, Warning)
>  			<< "no luminance table - assume unity everywhere";
> diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
> index c277a176..2e6e295c 100644
> --- a/src/ipa/rpi/controller/rpi/awb.cpp
> +++ b/src/ipa/rpi/controller/rpi/awb.cpp
> @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
>  	convergenceFrames = params["convergence_frames"].get<unsigned int>(3);
>  	speed = params["speed"].get<double>(0.05);
>  
> -	if (params.contains("ct_curve")) {
> -		ret = readCtCurve(ctR, ctB, params["ct_curve"]);
> +	if (auto *ct_curve = params.find("ct_curve")) {
> +		ret = readCtCurve(ctR, ctB, *ct_curve);
>  		if (ret)
>  			return ret;
>  		/* We will want the inverse functions of these too. */
> @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
>  		ctBInverse = ctB.inverse().first;
>  	}
>  
> -	if (params.contains("priors")) {
> -		for (const auto &p : params["priors"].asList()) {
> +	if (auto *ps = params.find("priors")) {
> +		for (const auto &p : ps->asList()) {
>  			AwbPrior prior;
>  			ret = prior.read(p);
>  			if (ret)
> @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
>  			return -EINVAL;
>  		}
>  	}
> -	if (params.contains("modes")) {
> -		for (const auto &[key, value] : params["modes"].asDict()) {
> +	if (auto *ms = params.find("modes")) {
> +		for (const auto &[key, value] : ms->asDict()) {
>  			ret = modes[key].read(value);
>  			if (ret)
>  				return ret;
> diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
> index 8607f152..5616e5f4 100644
> --- a/src/ipa/rpi/controller/rpi/ccm.cpp
> +++ b/src/ipa/rpi/controller/rpi/ccm.cpp
> @@ -41,8 +41,8 @@ char const *Ccm::name() const
>  
>  int Ccm::read(const libcamera::YamlObject &params)
>  {
> -	if (params.contains("saturation")) {
> -		config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
> +	if (auto *s = params.find("saturation")) {
> +		config_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});
>  		if (config_.saturation.empty())
>  			return -EINVAL;
>  	}
> diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp
> index 40e7191b..6935f726 100644
> --- a/src/ipa/rpi/controller/rpi/geq.cpp
> +++ b/src/ipa/rpi/controller/rpi/geq.cpp
> @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)
>  		return -EINVAL;
>  	}
>  
> -	if (params.contains("strength")) {
> -		config_.strength = params["strength"].get<ipa::Pwl>(ipa::Pwl{});
> +	if (auto *strength = params.find("strength")) {
> +		config_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});
>  		if (config_.strength.empty())
>  			return -EINVAL;
>  	}
> diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp
> index f3da8291..20b1ff4b 100644
> --- a/src/ipa/rpi/controller/rpi/hdr.cpp
> +++ b/src/ipa/rpi/controller/rpi/hdr.cpp
> @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
>  {
>  	name = modeName;
>  
> -	if (!params.contains("cadence"))
> +	auto *c = params.find("cadence");
> +	if (!c)
>  		LOG(RPiHdr, Fatal) << "No cadence for HDR mode " << name;
> -	cadence = params["cadence"].getList<unsigned int>().value();
> +	cadence = c->getList<unsigned int>().value();
>  	if (cadence.empty())
>  		LOG(RPiHdr, Fatal) << "Empty cadence in HDR mode " << name;
>  
> @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
>  		channelMap[v.get<unsigned int>().value()] = k;
>  
>  	/* Lens shading related parameters. */
> -	if (params.contains("spatial_gain_curve")) {
> -		spatialGainCurve = params["spatial_gain_curve"].get<ipa::Pwl>(ipa::Pwl{});
> -	} else if (params.contains("spatial_gain")) {
> -		double spatialGain = params["spatial_gain"].get<double>(2.0);
> +	if (auto *sgc = params.find("spatial_gain_curve")) {
> +		spatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});
> +	} else if (auto *sg = params.find("spatial_gain")) {
> +		double spatialGain = sg->get<double>(2.0);
>  		spatialGainCurve.append(0.0, spatialGain);
>  		spatialGainCurve.append(0.01, spatialGain);
>  		spatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */
> @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
>  	if (tonemapEnable)
>  		tonemap = params["tonemap"].get<ipa::Pwl>(ipa::Pwl{});
>  	speed = params["speed"].get<double>(1.0);
> -	if (params.contains("hi_quantile_targets")) {
> -		hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
> +	if (auto *hqt = params.find("hi_quantile_targets")) {
> +		hiQuantileTargets = hqt->getList<double>().value();
>  		if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
>  			LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
>  	} else
>  		hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
>  	hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
> -	if (params.contains("quantile_targets")) {
> -		quantileTargets = params["quantile_targets"].getList<double>().value();
> +	if (auto *qt = params.find("quantile_targets")) {
> +		quantileTargets = qt->getList<double>().value();
>  		if (quantileTargets.empty() || quantileTargets.size() % 2)
>  			LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
>  	} else
>  		quantileTargets = { 0.2, 0.03, 1.0, 0.15 };
>  	powerMin = params["power_min"].get<double>(0.65);
>  	powerMax = params["power_max"].get<double>(1.0);
> -	if (params.contains("contrast_adjustments")) {
> -		contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
> -	} else
> +	if (auto *ca = params.find("contrast_adjustments"))
> +		contrastAdjustments = ca->getList<double>().value();
> +	else
>  		contrastAdjustments = { 0.5, 0.75 };
>  
>  	/* Read any stitch parameters. */
> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
> index e1b6d3af..ca3fe487 100644
> --- a/src/ipa/simple/soft_simple.cpp
> +++ b/src/ipa/simple/soft_simple.cpp
> @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,
>  	unsigned int version = (*data)["version"].get<uint32_t>(0);
>  	LOG(IPASoft, Debug) << "Tuning file version " << version;
>  
> -	if (!data->contains("algorithms")) {
> +	auto *algos = data->find("algorithms");
> +	if (!algos) {
>  		LOG(IPASoft, Error) << "Tuning file doesn't contain algorithms";
>  		return -EINVAL;
>  	}
>  
> -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> +	int ret = createAlgorithms(context_, *algos);
>  	if (ret)
>  		return ret;
>
Barnabás Pőcze Dec. 9, 2024, 5:56 p.m. UTC | #2
Hi


2024. december 6., péntek 2:09 keltezéssel, Laurent Pinchart <laurent.pinchart@ideasonboard.com> írta:

> Hi Barnabás,
> 
> Thank you for the patch.
> 
> On Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:
> > Replace some uses of `contains()` + `operator[]` with `find()`.
> > Using `find()` avoids the double lookup, as well as does away with
> > the need for specifying the key twice.
> >
> > Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
> > ---
> >  src/android/camera_hal_config.cpp          | 19 ++++----
> >  src/ipa/ipu3/ipu3.cpp                      |  5 +-
> >  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------
> >  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-
> >  src/ipa/rpi/controller/controller.cpp      |  5 +-
> >  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------
> >  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--
> >  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-
> >  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--
> >  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---
> >  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-
> >  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-
> >  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----
> >  src/ipa/simple/soft_simple.cpp             |  5 +-
> >  14 files changed, 99 insertions(+), 97 deletions(-)
> >
> > diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp
> > index 7ef451ef..6fde953d 100644
> > --- a/src/android/camera_hal_config.cpp
> > +++ b/src/android/camera_hal_config.cpp
> > @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,
> >  		return -EINVAL;
> >
> >  	/* Parse property "cameras" */
> > -	if (!root->contains("cameras"))
> > +	auto *yamlObjectCameras = root->find("cameras");
> 
> I generally dislike overusing auto as it makes the code less explicit,
> and therefore less readable. There are valid use cases, for instance
> spelling out std::map<std::string, std::vector<std::pair<...>>>::iterator
> would be inconvenient. Usage of auto in structured bindings is also
> useful. In this specifif case, however, writing
> 
> 	const YamlObject *yamlObjectCameras = root->find("cameras");
> 
> isn't much longer, and I think it improves readability.
> 
> Same below.

So you would specify the explicit type everywhere this change touches?
Even in the controlling expression of `if` statements?


Regards,
Barnabás Pőcze

> 
> > +	if (!yamlObjectCameras)
> >  		return -EINVAL;
> >
> > -	const YamlObject &yamlObjectCameras = (*root)["cameras"];
> > -
> > -	if (!yamlObjectCameras.isDictionary())
> > +	if (!yamlObjectCameras->isDictionary())
> >  		return -EINVAL;
> >
> > -	for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {
> > +	for (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {
> >  		if (parseCameraConfigData(cameraId, configData))
> >  			return -EINVAL;
> >  	}
> > @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,
> >  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
> >  					    CameraConfigData &cameraConfigData)
> >  {
> > -	if (!cameraObject.contains("location"))
> > +	auto *loc = cameraObject.find("location");
> > +	if (!loc)
> >  		return -EINVAL;
> >
> > -	std::string location = cameraObject["location"].get<std::string>("");
> > +	std::string location = loc->get<std::string>("");
> >
> >  	if (location == "front")
> >  		cameraConfigData.facing = CAMERA_FACING_FRONT;
> > @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
> >  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,
> >  					    CameraConfigData &cameraConfigData)
> >  {
> > -	if (!cameraObject.contains("rotation"))
> > +	auto *rot = cameraObject.find("rotation");
> > +	if (!rot)
> >  		return -EINVAL;
> >
> > -	int32_t rotation = cameraObject["rotation"].get<int32_t>(-1);
> > +	int32_t rotation = rot->get<int32_t>(-1);
> >
> >  	if (rotation < 0 || rotation >= 360) {
> >  		LOG(HALConfig, Error)
> > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> > index 44c98cbf..88b1bb81 100644
> > --- a/src/ipa/ipu3/ipu3.cpp
> > +++ b/src/ipa/ipu3/ipu3.cpp
> > @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,
> >  		return -EINVAL;
> >  	}
> >
> > -	if (!data->contains("algorithms")) {
> > +	auto *algos = data->find("algorithms");
> > +	if (!algos) {
> >  		LOG(IPAIPU3, Error)
> >  			<< "Tuning file doesn't contain any algorithm";
> >  		return -EINVAL;
> >  	}
> >
> > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > +	int ret = createAlgorithms(context_, *algos);
> >  	if (ret)
> >  		return ret;
> >
> > diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
> > index 78946281..8946c1a7 100644
> > --- a/src/ipa/rkisp1/algorithms/dpcc.cpp
> > +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
> > @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> >  		/* PG Method */
> >  		const YamlObject &pgObject = set["pg-factor"];
> >
> > -		if (pgObject.contains("green")) {
> > +		if (auto *green = pgObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
> >
> > -			value = pgObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
> >  		}
> >
> > -		if (pgObject.contains("red-blue")) {
> > +		if (auto *redBlue = pgObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
> >
> > -			value = pgObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
> >  		}
> >
> >  		/* RO Method */
> >  		const YamlObject &roObject = set["ro-limits"];
> >
> > -		if (roObject.contains("green")) {
> > +		if (auto *green = roObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
> >
> > -			value = roObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			config_.ro_limits |=
> >  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
> >  		}
> >
> > -		if (roObject.contains("red-blue")) {
> > +		if (auto *redBlue = roObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
> >
> > -			value = roObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			config_.ro_limits |=
> >  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
> >  		}
> > @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> >  		const YamlObject &rgObject = set["rg-factor"];
> >  		method.rg_fac = 0;
> >
> > -		if (rgObject.contains("green")) {
> > +		if (auto *green = rgObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
> >
> > -			value = rgObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
> >  		}
> >
> > -		if (rgObject.contains("red-blue")) {
> > +		if (auto *redBlue = rgObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
> >
> > -			value = rgObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
> >  		}
> >
> >  		/* RND Method */
> >  		const YamlObject &rndOffsetsObject = set["rnd-offsets"];
> >
> > -		if (rndOffsetsObject.contains("green")) {
> > +		if (auto *green = rndOffsetsObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
> >
> > -			value = rndOffsetsObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			config_.rnd_offs |=
> >  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
> >  		}
> >
> > -		if (rndOffsetsObject.contains("red-blue")) {
> > +		if (auto *redBlue = rndOffsetsObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
> >
> > -			value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			config_.rnd_offs |=
> >  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
> >  		}
> > @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> >  		const YamlObject &rndThresholdObject = set["rnd-threshold"];
> >  		method.rnd_thresh = 0;
> >
> > -		if (rndThresholdObject.contains("green")) {
> > +		if (auto *green = rndThresholdObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
> >
> > -			value = rndThresholdObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			method.rnd_thresh |=
> >  				RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
> >  		}
> >
> > -		if (rndThresholdObject.contains("red-blue")) {
> > +		if (auto *redBlue = rndThresholdObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
> >
> > -			value = rndThresholdObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			method.rnd_thresh |=
> >  				RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
> >  		}
> > @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> >  		const YamlObject &lcThresholdObject = set["line-threshold"];
> >  		method.line_thresh = 0;
> >
> > -		if (lcThresholdObject.contains("green")) {
> > +		if (auto *green = lcThresholdObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
> >
> > -			value = lcThresholdObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			method.line_thresh |=
> >  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
> >  		}
> >
> > -		if (lcThresholdObject.contains("red-blue")) {
> > +		if (auto *redBlue = lcThresholdObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
> >
> > -			value = lcThresholdObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			method.line_thresh |=
> >  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
> >  		}
> > @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> >  		const YamlObject &lcTMadFactorObject = set["line-mad-factor"];
> >  		method.line_mad_fac = 0;
> >
> > -		if (lcTMadFactorObject.contains("green")) {
> > +		if (auto *green = lcTMadFactorObject.find("green")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
> >
> > -			value = lcTMadFactorObject["green"].get<uint16_t>(0);
> > +			value = green->get<uint16_t>(0);
> >  			method.line_mad_fac |=
> >  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
> >  		}
> >
> > -		if (lcTMadFactorObject.contains("red-blue")) {
> > +		if (auto *redBlue = lcTMadFactorObject.find("red-blue")) {
> >  			method.method |=
> >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
> >
> > -			value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
> > +			value = redBlue->get<uint16_t>(0);
> >  			method.line_mad_fac |=
> >  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
> >  		}
> > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> > index 2ffdd99b..202b53b7 100644
> > --- a/src/ipa/rkisp1/rkisp1.cpp
> > +++ b/src/ipa/rkisp1/rkisp1.cpp
> > @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
> >  		return -EINVAL;
> >  	}
> >
> > -	if (!data->contains("algorithms")) {
> > +	auto *algos = data->find("algorithms");
> > +	if (!algos) {
> >  		LOG(IPARkISP1, Error)
> >  			<< "Tuning file doesn't contain any algorithm";
> >  		return -EINVAL;
> >  	}
> >
> > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > +	int ret = createAlgorithms(context_, *algos);
> >  	if (ret)
> >  		return ret;
> >
> > diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp
> > index e0131018..fbf31f23 100644
> > --- a/src/ipa/rpi/controller/controller.cpp
> > +++ b/src/ipa/rpi/controller/controller.cpp
> > @@ -109,14 +109,15 @@ int Controller::read(char const *filename)
> >  				return ret;
> >  		}
> >  	} else if (version < 3.0) {
> > -		if (!root->contains("algorithms")) {
> > +		auto *algos = root->find("algorithms");
> > +		if (!algos) {
> >  			LOG(RPiController, Error)
> >  				<< "Tuning file " << filename
> >  				<< " does not have an \"algorithms\" list!";
> >  			return -EINVAL;
> >  		}
> >
> > -		for (auto const &rootAlgo : (*root)["algorithms"].asList())
> > +		for (auto const &rootAlgo : algos->asList())
> >  			for (auto const &[key, value] : rootAlgo.asDict()) {
> >  				int ret = createAlgorithm(key, value);
> >  				if (ret)
> > diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp
> > index 2157eb94..c29bbaeb 100644
> > --- a/src/ipa/rpi/controller/rpi/af.cpp
> > +++ b/src/ipa/rpi/controller/rpi/af.cpp
> > @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)
> >
> >  int Af::CfgParams::read(const libcamera::YamlObject &params)
> >  {
> > -	if (params.contains("ranges")) {
> > -		auto &rr = params["ranges"];
> > -
> > -		if (rr.contains("normal"))
> > -			ranges[AfRangeNormal].read(rr["normal"]);
> > +	if (auto *rs = params.find("ranges")) {
> 
> I would have kept the same variable name (rr) but that doesn't matter
> much.
> 
> > +		if (auto *normal = rs->find("normal"))
> > +			ranges[AfRangeNormal].read(*normal);
> >  		else
> >  			LOG(RPiAf, Warning) << "Missing range \"normal\"";
> >
> >  		ranges[AfRangeMacro] = ranges[AfRangeNormal];
> > -		if (rr.contains("macro"))
> > -			ranges[AfRangeMacro].read(rr["macro"]);
> > +		if (auto *macro = rs->find("macro"))
> > +			ranges[AfRangeMacro].read(*macro);
> >
> >  		ranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,
> >  							ranges[AfRangeMacro].focusMin);
> >  		ranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,
> >  							ranges[AfRangeMacro].focusMax);
> >  		ranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;
> > -		if (rr.contains("full"))
> > -			ranges[AfRangeFull].read(rr["full"]);
> > +		if (auto *full = rs->find("full"))
> > +			ranges[AfRangeFull].read(*full);
> >  	} else
> >  		LOG(RPiAf, Warning) << "No ranges defined";
> >
> > -	if (params.contains("speeds")) {
> > -		auto &ss = params["speeds"];
> > -
> > -		if (ss.contains("normal"))
> > -			speeds[AfSpeedNormal].read(ss["normal"]);
> > +	if (auto *ss = params.find("speeds")) {
> > +		if (auto *normal = ss->find("normal"))
> > +			speeds[AfSpeedNormal].read(*normal);
> >  		else
> >  			LOG(RPiAf, Warning) << "Missing speed \"normal\"";
> >
> >  		speeds[AfSpeedFast] = speeds[AfSpeedNormal];
> > -		if (ss.contains("fast"))
> > -			speeds[AfSpeedFast].read(ss["fast"]);
> > +		if (auto *fast = ss->find("fast"))
> > +			speeds[AfSpeedFast].read(*fast);
> >  	} else
> >  		LOG(RPiAf, Warning) << "No speeds defined";
> >
> > @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)
> >  	readNumber<uint32_t>(confClip, params, "conf_clip");
> >  	readNumber<uint32_t>(skipFrames, params, "skip_frames");
> >
> > -	if (params.contains("map"))
> > -		map = params["map"].get<ipa::Pwl>(ipa::Pwl{});
> > +	if (auto *m = params.find("map"))
> > +		map = m->get<ipa::Pwl>(ipa::Pwl{});
> >  	else
> >  		LOG(RPiAf, Warning) << "No map defined";
> >
> > diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
> > index c48fdf15..5d924ebf 100644
> > --- a/src/ipa/rpi/controller/rpi/agc.cpp
> > +++ b/src/ipa/rpi/controller/rpi/agc.cpp
> > @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)
> >  	 * When there is only a single channel we can read the old style syntax.
> >  	 * Otherwise we expect a "channels" keyword followed by a list of configurations.
> >  	 */
> > -	if (!params.contains("channels")) {
> > +	auto *channels = params.find("channels");
> > +	if (!channels) {
> >  		LOG(RPiAgc, Debug) << "Single channel only";
> >  		channelTotalExposures_.resize(1, 0s);
> >  		channelData_.emplace_back();
> >  		return channelData_.back().channel.read(params, getHardwareConfig());
> >  	}
> >
> > -	const auto &channels = params["channels"].asList();
> > -	for (auto ch = channels.begin(); ch != channels.end(); ch++) {
> > +	for (const auto &ch : channels->asList()) {
> >  		LOG(RPiAgc, Debug) << "Read AGC channel";
> >  		channelData_.emplace_back();
> > -		int ret = channelData_.back().channel.read(*ch, getHardwareConfig());
> > +		int ret = channelData_.back().channel.read(ch, getHardwareConfig());
> >  		if (ret)
> >  			return ret;
> >  	}
> > diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > index 79c45973..50b9efd2 100644
> > --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)
> >  	if (ret)
> >  		return ret;
> >
> > -	if (params.contains("channel_constraints")) {
> > -		ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
> > +	if (auto *cc = params.find("channel_constraints")) {
> > +		ret = readChannelConstraints(channelConstraints, *cc);
> >  		if (ret)
> >  			return ret;
> >  	}
> > diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
> > index 21edb819..5a1a702b 100644
> > --- a/src/ipa/rpi/controller/rpi/alsc.cpp
> > +++ b/src/ipa/rpi/controller/rpi/alsc.cpp
> > @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,
> >  			    const libcamera::YamlObject &params,
> >  			    std::string const &name, const Size &size)
> >  {
> > -	if (params.contains(name)) {
> > +	if (auto *param = params.find(name)) {
> >  		double lastCt = 0;
> > -		for (const auto &p : params[name].asList()) {
> > +		for (const auto &p : param->asList()) {
> >  			auto value = p["ct"].get<double>();
> >  			if (!value)
> >  				return -EINVAL;
> > @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)
> >  	config_.luminanceLut.resize(config_.tableSize, 1.0);
> >  	int ret = 0;
> >
> > -	if (params.contains("corner_strength"))
> > +	if (params.find("corner_strength"))
> >  		ret = generateLut(config_.luminanceLut, params);
> > -	else if (params.contains("luminance_lut"))
> > -		ret = readLut(config_.luminanceLut, params["luminance_lut"]);
> > +	else if (auto *ll = params.find("luminance_lut"))
> > +		ret = readLut(config_.luminanceLut, *ll);
> >  	else
> >  		LOG(RPiAlsc, Warning)
> >  			<< "no luminance table - assume unity everywhere";
> > diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
> > index c277a176..2e6e295c 100644
> > --- a/src/ipa/rpi/controller/rpi/awb.cpp
> > +++ b/src/ipa/rpi/controller/rpi/awb.cpp
> > @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> >  	convergenceFrames = params["convergence_frames"].get<unsigned int>(3);
> >  	speed = params["speed"].get<double>(0.05);
> >
> > -	if (params.contains("ct_curve")) {
> > -		ret = readCtCurve(ctR, ctB, params["ct_curve"]);
> > +	if (auto *ct_curve = params.find("ct_curve")) {
> > +		ret = readCtCurve(ctR, ctB, *ct_curve);
> >  		if (ret)
> >  			return ret;
> >  		/* We will want the inverse functions of these too. */
> > @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> >  		ctBInverse = ctB.inverse().first;
> >  	}
> >
> > -	if (params.contains("priors")) {
> > -		for (const auto &p : params["priors"].asList()) {
> > +	if (auto *ps = params.find("priors")) {
> > +		for (const auto &p : ps->asList()) {
> >  			AwbPrior prior;
> >  			ret = prior.read(p);
> >  			if (ret)
> > @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> >  			return -EINVAL;
> >  		}
> >  	}
> > -	if (params.contains("modes")) {
> > -		for (const auto &[key, value] : params["modes"].asDict()) {
> > +	if (auto *ms = params.find("modes")) {
> > +		for (const auto &[key, value] : ms->asDict()) {
> >  			ret = modes[key].read(value);
> >  			if (ret)
> >  				return ret;
> > diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
> > index 8607f152..5616e5f4 100644
> > --- a/src/ipa/rpi/controller/rpi/ccm.cpp
> > +++ b/src/ipa/rpi/controller/rpi/ccm.cpp
> > @@ -41,8 +41,8 @@ char const *Ccm::name() const
> >
> >  int Ccm::read(const libcamera::YamlObject &params)
> >  {
> > -	if (params.contains("saturation")) {
> > -		config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
> > +	if (auto *s = params.find("saturation")) {
> > +		config_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});
> >  		if (config_.saturation.empty())
> >  			return -EINVAL;
> >  	}
> > diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp
> > index 40e7191b..6935f726 100644
> > --- a/src/ipa/rpi/controller/rpi/geq.cpp
> > +++ b/src/ipa/rpi/controller/rpi/geq.cpp
> > @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)
> >  		return -EINVAL;
> >  	}
> >
> > -	if (params.contains("strength")) {
> > -		config_.strength = params["strength"].get<ipa::Pwl>(ipa::Pwl{});
> > +	if (auto *strength = params.find("strength")) {
> > +		config_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});
> >  		if (config_.strength.empty())
> >  			return -EINVAL;
> >  	}
> > diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp
> > index f3da8291..20b1ff4b 100644
> > --- a/src/ipa/rpi/controller/rpi/hdr.cpp
> > +++ b/src/ipa/rpi/controller/rpi/hdr.cpp
> > @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> >  {
> >  	name = modeName;
> >
> > -	if (!params.contains("cadence"))
> > +	auto *c = params.find("cadence");
> > +	if (!c)
> >  		LOG(RPiHdr, Fatal) << "No cadence for HDR mode " << name;
> > -	cadence = params["cadence"].getList<unsigned int>().value();
> > +	cadence = c->getList<unsigned int>().value();
> >  	if (cadence.empty())
> >  		LOG(RPiHdr, Fatal) << "Empty cadence in HDR mode " << name;
> >
> > @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> >  		channelMap[v.get<unsigned int>().value()] = k;
> >
> >  	/* Lens shading related parameters. */
> > -	if (params.contains("spatial_gain_curve")) {
> > -		spatialGainCurve = params["spatial_gain_curve"].get<ipa::Pwl>(ipa::Pwl{});
> > -	} else if (params.contains("spatial_gain")) {
> > -		double spatialGain = params["spatial_gain"].get<double>(2.0);
> > +	if (auto *sgc = params.find("spatial_gain_curve")) {
> > +		spatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});
> > +	} else if (auto *sg = params.find("spatial_gain")) {
> > +		double spatialGain = sg->get<double>(2.0);
> >  		spatialGainCurve.append(0.0, spatialGain);
> >  		spatialGainCurve.append(0.01, spatialGain);
> >  		spatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */
> > @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> >  	if (tonemapEnable)
> >  		tonemap = params["tonemap"].get<ipa::Pwl>(ipa::Pwl{});
> >  	speed = params["speed"].get<double>(1.0);
> > -	if (params.contains("hi_quantile_targets")) {
> > -		hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
> > +	if (auto *hqt = params.find("hi_quantile_targets")) {
> > +		hiQuantileTargets = hqt->getList<double>().value();
> >  		if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
> >  			LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
> >  	} else
> >  		hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
> >  	hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
> > -	if (params.contains("quantile_targets")) {
> > -		quantileTargets = params["quantile_targets"].getList<double>().value();
> > +	if (auto *qt = params.find("quantile_targets")) {
> > +		quantileTargets = qt->getList<double>().value();
> >  		if (quantileTargets.empty() || quantileTargets.size() % 2)
> >  			LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
> >  	} else
> >  		quantileTargets = { 0.2, 0.03, 1.0, 0.15 };
> >  	powerMin = params["power_min"].get<double>(0.65);
> >  	powerMax = params["power_max"].get<double>(1.0);
> > -	if (params.contains("contrast_adjustments")) {
> > -		contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
> > -	} else
> > +	if (auto *ca = params.find("contrast_adjustments"))
> > +		contrastAdjustments = ca->getList<double>().value();
> > +	else
> >  		contrastAdjustments = { 0.5, 0.75 };
> >
> >  	/* Read any stitch parameters. */
> > diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
> > index e1b6d3af..ca3fe487 100644
> > --- a/src/ipa/simple/soft_simple.cpp
> > +++ b/src/ipa/simple/soft_simple.cpp
> > @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,
> >  	unsigned int version = (*data)["version"].get<uint32_t>(0);
> >  	LOG(IPASoft, Debug) << "Tuning file version " << version;
> >
> > -	if (!data->contains("algorithms")) {
> > +	auto *algos = data->find("algorithms");
> > +	if (!algos) {
> >  		LOG(IPASoft, Error) << "Tuning file doesn't contain algorithms";
> >  		return -EINVAL;
> >  	}
> >
> > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > +	int ret = createAlgorithms(context_, *algos);
> >  	if (ret)
> >  		return ret;
> >
> 
> --
> Regards,
> 
> Laurent Pinchart
>
Laurent Pinchart Dec. 9, 2024, 9:21 p.m. UTC | #3
On Mon, Dec 09, 2024 at 05:56:57PM +0000, Barnabás Pőcze wrote:
> 2024. december 6., péntek 2:09 keltezéssel, Laurent Pinchart írta:
> > On Thu, Dec 05, 2024 at 04:34:19PM +0000, Barnabás Pőcze wrote:
> > > Replace some uses of `contains()` + `operator[]` with `find()`.
> > > Using `find()` avoids the double lookup, as well as does away with
> > > the need for specifying the key twice.
> > >
> > > Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
> > > ---
> > >  src/android/camera_hal_config.cpp          | 19 ++++----
> > >  src/ipa/ipu3/ipu3.cpp                      |  5 +-
> > >  src/ipa/rkisp1/algorithms/dpcc.cpp         | 56 +++++++++++-----------
> > >  src/ipa/rkisp1/rkisp1.cpp                  |  5 +-
> > >  src/ipa/rpi/controller/controller.cpp      |  5 +-
> > >  src/ipa/rpi/controller/rpi/af.cpp          | 32 ++++++-------
> > >  src/ipa/rpi/controller/rpi/agc.cpp         |  8 ++--
> > >  src/ipa/rpi/controller/rpi/agc_channel.cpp |  4 +-
> > >  src/ipa/rpi/controller/rpi/alsc.cpp        | 10 ++--
> > >  src/ipa/rpi/controller/rpi/awb.cpp         | 12 ++---
> > >  src/ipa/rpi/controller/rpi/ccm.cpp         |  4 +-
> > >  src/ipa/rpi/controller/rpi/geq.cpp         |  4 +-
> > >  src/ipa/rpi/controller/rpi/hdr.cpp         | 27 ++++++-----
> > >  src/ipa/simple/soft_simple.cpp             |  5 +-
> > >  14 files changed, 99 insertions(+), 97 deletions(-)
> > >
> > > diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp
> > > index 7ef451ef..6fde953d 100644
> > > --- a/src/android/camera_hal_config.cpp
> > > +++ b/src/android/camera_hal_config.cpp
> > > @@ -73,15 +73,14 @@ int CameraHalConfig::Private::parseConfigFile(File &file,
> > >  		return -EINVAL;
> > >
> > >  	/* Parse property "cameras" */
> > > -	if (!root->contains("cameras"))
> > > +	auto *yamlObjectCameras = root->find("cameras");
> > 
> > I generally dislike overusing auto as it makes the code less explicit,
> > and therefore less readable. There are valid use cases, for instance
> > spelling out std::map<std::string, std::vector<std::pair<...>>>::iterator
> > would be inconvenient. Usage of auto in structured bindings is also
> > useful. In this specifif case, however, writing
> > 
> > 	const YamlObject *yamlObjectCameras = root->find("cameras");
> > 
> > isn't much longer, and I think it improves readability.
> > 
> > Same below.
> 
> So you would specify the explicit type everywhere this change touches?
> Even in the controlling expression of `if` statements?

Not necessarily everywhere. For me it's a matter of readability. If find
that usage of auto hinders readability, as it's often unclear when
reading the code what type a variable takes. For long types, especially
with nested qualifiers, writing out the full type would be less readable
than 'auto'. Especially in contexts where the type of the variable is
evident, using 'auto' is fine.

As readability is a subjective concept, I don't think we can set a clear
rule. I won't nitpick too much and I'll let you decide where to draw the
line. Ideally I'd like some sort of consistency through the code base
though.

> > > +	if (!yamlObjectCameras)
> > >  		return -EINVAL;
> > >
> > > -	const YamlObject &yamlObjectCameras = (*root)["cameras"];
> > > -
> > > -	if (!yamlObjectCameras.isDictionary())
> > > +	if (!yamlObjectCameras->isDictionary())
> > >  		return -EINVAL;
> > >
> > > -	for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {
> > > +	for (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {
> > >  		if (parseCameraConfigData(cameraId, configData))
> > >  			return -EINVAL;
> > >  	}
> > > @@ -112,10 +111,11 @@ int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,
> > >  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
> > >  					    CameraConfigData &cameraConfigData)
> > >  {
> > > -	if (!cameraObject.contains("location"))
> > > +	auto *loc = cameraObject.find("location");
> > > +	if (!loc)
> > >  		return -EINVAL;
> > >
> > > -	std::string location = cameraObject["location"].get<std::string>("");
> > > +	std::string location = loc->get<std::string>("");
> > >
> > >  	if (location == "front")
> > >  		cameraConfigData.facing = CAMERA_FACING_FRONT;
> > > @@ -130,10 +130,11 @@ int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
> > >  int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,
> > >  					    CameraConfigData &cameraConfigData)
> > >  {
> > > -	if (!cameraObject.contains("rotation"))
> > > +	auto *rot = cameraObject.find("rotation");
> > > +	if (!rot)
> > >  		return -EINVAL;
> > >
> > > -	int32_t rotation = cameraObject["rotation"].get<int32_t>(-1);
> > > +	int32_t rotation = rot->get<int32_t>(-1);
> > >
> > >  	if (rotation < 0 || rotation >= 360) {
> > >  		LOG(HALConfig, Error)
> > > diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
> > > index 44c98cbf..88b1bb81 100644
> > > --- a/src/ipa/ipu3/ipu3.cpp
> > > +++ b/src/ipa/ipu3/ipu3.cpp
> > > @@ -335,13 +335,14 @@ int IPAIPU3::init(const IPASettings &settings,
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	if (!data->contains("algorithms")) {
> > > +	auto *algos = data->find("algorithms");
> > > +	if (!algos) {
> > >  		LOG(IPAIPU3, Error)
> > >  			<< "Tuning file doesn't contain any algorithm";
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > > +	int ret = createAlgorithms(context_, *algos);
> > >  	if (ret)
> > >  		return ret;
> > >
> > > diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
> > > index 78946281..8946c1a7 100644
> > > --- a/src/ipa/rkisp1/algorithms/dpcc.cpp
> > > +++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
> > > @@ -80,39 +80,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> > >  		/* PG Method */
> > >  		const YamlObject &pgObject = set["pg-factor"];
> > >
> > > -		if (pgObject.contains("green")) {
> > > +		if (auto *green = pgObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
> > >
> > > -			value = pgObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
> > >  		}
> > >
> > > -		if (pgObject.contains("red-blue")) {
> > > +		if (auto *redBlue = pgObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
> > >
> > > -			value = pgObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
> > >  		}
> > >
> > >  		/* RO Method */
> > >  		const YamlObject &roObject = set["ro-limits"];
> > >
> > > -		if (roObject.contains("green")) {
> > > +		if (auto *green = roObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
> > >
> > > -			value = roObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			config_.ro_limits |=
> > >  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
> > >  		}
> > >
> > > -		if (roObject.contains("red-blue")) {
> > > +		if (auto *redBlue = roObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
> > >
> > > -			value = roObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			config_.ro_limits |=
> > >  				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
> > >  		}
> > > @@ -121,39 +121,39 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> > >  		const YamlObject &rgObject = set["rg-factor"];
> > >  		method.rg_fac = 0;
> > >
> > > -		if (rgObject.contains("green")) {
> > > +		if (auto *green = rgObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
> > >
> > > -			value = rgObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
> > >  		}
> > >
> > > -		if (rgObject.contains("red-blue")) {
> > > +		if (auto *redBlue = rgObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
> > >
> > > -			value = rgObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
> > >  		}
> > >
> > >  		/* RND Method */
> > >  		const YamlObject &rndOffsetsObject = set["rnd-offsets"];
> > >
> > > -		if (rndOffsetsObject.contains("green")) {
> > > +		if (auto *green = rndOffsetsObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
> > >
> > > -			value = rndOffsetsObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			config_.rnd_offs |=
> > >  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
> > >  		}
> > >
> > > -		if (rndOffsetsObject.contains("red-blue")) {
> > > +		if (auto *redBlue = rndOffsetsObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
> > >
> > > -			value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			config_.rnd_offs |=
> > >  				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
> > >  		}
> > > @@ -161,20 +161,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> > >  		const YamlObject &rndThresholdObject = set["rnd-threshold"];
> > >  		method.rnd_thresh = 0;
> > >
> > > -		if (rndThresholdObject.contains("green")) {
> > > +		if (auto *green = rndThresholdObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
> > >
> > > -			value = rndThresholdObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			method.rnd_thresh |=
> > >  				RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
> > >  		}
> > >
> > > -		if (rndThresholdObject.contains("red-blue")) {
> > > +		if (auto *redBlue = rndThresholdObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
> > >
> > > -			value = rndThresholdObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			method.rnd_thresh |=
> > >  				RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
> > >  		}
> > > @@ -183,20 +183,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> > >  		const YamlObject &lcThresholdObject = set["line-threshold"];
> > >  		method.line_thresh = 0;
> > >
> > > -		if (lcThresholdObject.contains("green")) {
> > > +		if (auto *green = lcThresholdObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
> > >
> > > -			value = lcThresholdObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			method.line_thresh |=
> > >  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
> > >  		}
> > >
> > > -		if (lcThresholdObject.contains("red-blue")) {
> > > +		if (auto *redBlue = lcThresholdObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
> > >
> > > -			value = lcThresholdObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			method.line_thresh |=
> > >  				RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
> > >  		}
> > > @@ -204,20 +204,20 @@ int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
> > >  		const YamlObject &lcTMadFactorObject = set["line-mad-factor"];
> > >  		method.line_mad_fac = 0;
> > >
> > > -		if (lcTMadFactorObject.contains("green")) {
> > > +		if (auto *green = lcTMadFactorObject.find("green")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
> > >
> > > -			value = lcTMadFactorObject["green"].get<uint16_t>(0);
> > > +			value = green->get<uint16_t>(0);
> > >  			method.line_mad_fac |=
> > >  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
> > >  		}
> > >
> > > -		if (lcTMadFactorObject.contains("red-blue")) {
> > > +		if (auto *redBlue = lcTMadFactorObject.find("red-blue")) {
> > >  			method.method |=
> > >  				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
> > >
> > > -			value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
> > > +			value = redBlue->get<uint16_t>(0);
> > >  			method.line_mad_fac |=
> > >  				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
> > >  		}
> > > diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
> > > index 2ffdd99b..202b53b7 100644
> > > --- a/src/ipa/rkisp1/rkisp1.cpp
> > > +++ b/src/ipa/rkisp1/rkisp1.cpp
> > > @@ -193,13 +193,14 @@ int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	if (!data->contains("algorithms")) {
> > > +	auto *algos = data->find("algorithms");
> > > +	if (!algos) {
> > >  		LOG(IPARkISP1, Error)
> > >  			<< "Tuning file doesn't contain any algorithm";
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > > +	int ret = createAlgorithms(context_, *algos);
> > >  	if (ret)
> > >  		return ret;
> > >
> > > diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp
> > > index e0131018..fbf31f23 100644
> > > --- a/src/ipa/rpi/controller/controller.cpp
> > > +++ b/src/ipa/rpi/controller/controller.cpp
> > > @@ -109,14 +109,15 @@ int Controller::read(char const *filename)
> > >  				return ret;
> > >  		}
> > >  	} else if (version < 3.0) {
> > > -		if (!root->contains("algorithms")) {
> > > +		auto *algos = root->find("algorithms");
> > > +		if (!algos) {
> > >  			LOG(RPiController, Error)
> > >  				<< "Tuning file " << filename
> > >  				<< " does not have an \"algorithms\" list!";
> > >  			return -EINVAL;
> > >  		}
> > >
> > > -		for (auto const &rootAlgo : (*root)["algorithms"].asList())
> > > +		for (auto const &rootAlgo : algos->asList())
> > >  			for (auto const &[key, value] : rootAlgo.asDict()) {
> > >  				int ret = createAlgorithm(key, value);
> > >  				if (ret)
> > > diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp
> > > index 2157eb94..c29bbaeb 100644
> > > --- a/src/ipa/rpi/controller/rpi/af.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/af.cpp
> > > @@ -97,39 +97,35 @@ void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)
> > >
> > >  int Af::CfgParams::read(const libcamera::YamlObject &params)
> > >  {
> > > -	if (params.contains("ranges")) {
> > > -		auto &rr = params["ranges"];
> > > -
> > > -		if (rr.contains("normal"))
> > > -			ranges[AfRangeNormal].read(rr["normal"]);
> > > +	if (auto *rs = params.find("ranges")) {
> > 
> > I would have kept the same variable name (rr) but that doesn't matter
> > much.
> > 
> > > +		if (auto *normal = rs->find("normal"))
> > > +			ranges[AfRangeNormal].read(*normal);
> > >  		else
> > >  			LOG(RPiAf, Warning) << "Missing range \"normal\"";
> > >
> > >  		ranges[AfRangeMacro] = ranges[AfRangeNormal];
> > > -		if (rr.contains("macro"))
> > > -			ranges[AfRangeMacro].read(rr["macro"]);
> > > +		if (auto *macro = rs->find("macro"))
> > > +			ranges[AfRangeMacro].read(*macro);
> > >
> > >  		ranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,
> > >  							ranges[AfRangeMacro].focusMin);
> > >  		ranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,
> > >  							ranges[AfRangeMacro].focusMax);
> > >  		ranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;
> > > -		if (rr.contains("full"))
> > > -			ranges[AfRangeFull].read(rr["full"]);
> > > +		if (auto *full = rs->find("full"))
> > > +			ranges[AfRangeFull].read(*full);
> > >  	} else
> > >  		LOG(RPiAf, Warning) << "No ranges defined";
> > >
> > > -	if (params.contains("speeds")) {
> > > -		auto &ss = params["speeds"];
> > > -
> > > -		if (ss.contains("normal"))
> > > -			speeds[AfSpeedNormal].read(ss["normal"]);
> > > +	if (auto *ss = params.find("speeds")) {
> > > +		if (auto *normal = ss->find("normal"))
> > > +			speeds[AfSpeedNormal].read(*normal);
> > >  		else
> > >  			LOG(RPiAf, Warning) << "Missing speed \"normal\"";
> > >
> > >  		speeds[AfSpeedFast] = speeds[AfSpeedNormal];
> > > -		if (ss.contains("fast"))
> > > -			speeds[AfSpeedFast].read(ss["fast"]);
> > > +		if (auto *fast = ss->find("fast"))
> > > +			speeds[AfSpeedFast].read(*fast);
> > >  	} else
> > >  		LOG(RPiAf, Warning) << "No speeds defined";
> > >
> > > @@ -138,8 +134,8 @@ int Af::CfgParams::read(const libcamera::YamlObject &params)
> > >  	readNumber<uint32_t>(confClip, params, "conf_clip");
> > >  	readNumber<uint32_t>(skipFrames, params, "skip_frames");
> > >
> > > -	if (params.contains("map"))
> > > -		map = params["map"].get<ipa::Pwl>(ipa::Pwl{});
> > > +	if (auto *m = params.find("map"))
> > > +		map = m->get<ipa::Pwl>(ipa::Pwl{});
> > >  	else
> > >  		LOG(RPiAf, Warning) << "No map defined";
> > >
> > > diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
> > > index c48fdf15..5d924ebf 100644
> > > --- a/src/ipa/rpi/controller/rpi/agc.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/agc.cpp
> > > @@ -37,18 +37,18 @@ int Agc::read(const libcamera::YamlObject &params)
> > >  	 * When there is only a single channel we can read the old style syntax.
> > >  	 * Otherwise we expect a "channels" keyword followed by a list of configurations.
> > >  	 */
> > > -	if (!params.contains("channels")) {
> > > +	auto *channels = params.find("channels");
> > > +	if (!channels) {
> > >  		LOG(RPiAgc, Debug) << "Single channel only";
> > >  		channelTotalExposures_.resize(1, 0s);
> > >  		channelData_.emplace_back();
> > >  		return channelData_.back().channel.read(params, getHardwareConfig());
> > >  	}
> > >
> > > -	const auto &channels = params["channels"].asList();
> > > -	for (auto ch = channels.begin(); ch != channels.end(); ch++) {
> > > +	for (const auto &ch : channels->asList()) {
> > >  		LOG(RPiAgc, Debug) << "Read AGC channel";
> > >  		channelData_.emplace_back();
> > > -		int ret = channelData_.back().channel.read(*ch, getHardwareConfig());
> > > +		int ret = channelData_.back().channel.read(ch, getHardwareConfig());
> > >  		if (ret)
> > >  			return ret;
> > >  	}
> > > diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > > index 79c45973..50b9efd2 100644
> > > --- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
> > > @@ -235,8 +235,8 @@ int AgcConfig::read(const libcamera::YamlObject &params)
> > >  	if (ret)
> > >  		return ret;
> > >
> > > -	if (params.contains("channel_constraints")) {
> > > -		ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
> > > +	if (auto *cc = params.find("channel_constraints")) {
> > > +		ret = readChannelConstraints(channelConstraints, *cc);
> > >  		if (ret)
> > >  			return ret;
> > >  	}
> > > diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
> > > index 21edb819..5a1a702b 100644
> > > --- a/src/ipa/rpi/controller/rpi/alsc.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/alsc.cpp
> > > @@ -104,9 +104,9 @@ static int readCalibrations(std::vector<AlscCalibration> &calibrations,
> > >  			    const libcamera::YamlObject &params,
> > >  			    std::string const &name, const Size &size)
> > >  {
> > > -	if (params.contains(name)) {
> > > +	if (auto *param = params.find(name)) {
> > >  		double lastCt = 0;
> > > -		for (const auto &p : params[name].asList()) {
> > > +		for (const auto &p : param->asList()) {
> > >  			auto value = p["ct"].get<double>();
> > >  			if (!value)
> > >  				return -EINVAL;
> > > @@ -163,10 +163,10 @@ int Alsc::read(const libcamera::YamlObject &params)
> > >  	config_.luminanceLut.resize(config_.tableSize, 1.0);
> > >  	int ret = 0;
> > >
> > > -	if (params.contains("corner_strength"))
> > > +	if (params.find("corner_strength"))
> > >  		ret = generateLut(config_.luminanceLut, params);
> > > -	else if (params.contains("luminance_lut"))
> > > -		ret = readLut(config_.luminanceLut, params["luminance_lut"]);
> > > +	else if (auto *ll = params.find("luminance_lut"))
> > > +		ret = readLut(config_.luminanceLut, *ll);
> > >  	else
> > >  		LOG(RPiAlsc, Warning)
> > >  			<< "no luminance table - assume unity everywhere";
> > > diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
> > > index c277a176..2e6e295c 100644
> > > --- a/src/ipa/rpi/controller/rpi/awb.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/awb.cpp
> > > @@ -102,8 +102,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> > >  	convergenceFrames = params["convergence_frames"].get<unsigned int>(3);
> > >  	speed = params["speed"].get<double>(0.05);
> > >
> > > -	if (params.contains("ct_curve")) {
> > > -		ret = readCtCurve(ctR, ctB, params["ct_curve"]);
> > > +	if (auto *ct_curve = params.find("ct_curve")) {
> > > +		ret = readCtCurve(ctR, ctB, *ct_curve);
> > >  		if (ret)
> > >  			return ret;
> > >  		/* We will want the inverse functions of these too. */
> > > @@ -111,8 +111,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> > >  		ctBInverse = ctB.inverse().first;
> > >  	}
> > >
> > > -	if (params.contains("priors")) {
> > > -		for (const auto &p : params["priors"].asList()) {
> > > +	if (auto *ps = params.find("priors")) {
> > > +		for (const auto &p : ps->asList()) {
> > >  			AwbPrior prior;
> > >  			ret = prior.read(p);
> > >  			if (ret)
> > > @@ -128,8 +128,8 @@ int AwbConfig::read(const libcamera::YamlObject &params)
> > >  			return -EINVAL;
> > >  		}
> > >  	}
> > > -	if (params.contains("modes")) {
> > > -		for (const auto &[key, value] : params["modes"].asDict()) {
> > > +	if (auto *ms = params.find("modes")) {
> > > +		for (const auto &[key, value] : ms->asDict()) {
> > >  			ret = modes[key].read(value);
> > >  			if (ret)
> > >  				return ret;
> > > diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
> > > index 8607f152..5616e5f4 100644
> > > --- a/src/ipa/rpi/controller/rpi/ccm.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/ccm.cpp
> > > @@ -41,8 +41,8 @@ char const *Ccm::name() const
> > >
> > >  int Ccm::read(const libcamera::YamlObject &params)
> > >  {
> > > -	if (params.contains("saturation")) {
> > > -		config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
> > > +	if (auto *s = params.find("saturation")) {
> > > +		config_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});
> > >  		if (config_.saturation.empty())
> > >  			return -EINVAL;
> > >  	}
> > > diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp
> > > index 40e7191b..6935f726 100644
> > > --- a/src/ipa/rpi/controller/rpi/geq.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/geq.cpp
> > > @@ -43,8 +43,8 @@ int Geq::read(const libcamera::YamlObject &params)
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	if (params.contains("strength")) {
> > > -		config_.strength = params["strength"].get<ipa::Pwl>(ipa::Pwl{});
> > > +	if (auto *strength = params.find("strength")) {
> > > +		config_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});
> > >  		if (config_.strength.empty())
> > >  			return -EINVAL;
> > >  	}
> > > diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp
> > > index f3da8291..20b1ff4b 100644
> > > --- a/src/ipa/rpi/controller/rpi/hdr.cpp
> > > +++ b/src/ipa/rpi/controller/rpi/hdr.cpp
> > > @@ -27,9 +27,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> > >  {
> > >  	name = modeName;
> > >
> > > -	if (!params.contains("cadence"))
> > > +	auto *c = params.find("cadence");
> > > +	if (!c)
> > >  		LOG(RPiHdr, Fatal) << "No cadence for HDR mode " << name;
> > > -	cadence = params["cadence"].getList<unsigned int>().value();
> > > +	cadence = c->getList<unsigned int>().value();
> > >  	if (cadence.empty())
> > >  		LOG(RPiHdr, Fatal) << "Empty cadence in HDR mode " << name;
> > >
> > > @@ -41,10 +42,10 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> > >  		channelMap[v.get<unsigned int>().value()] = k;
> > >
> > >  	/* Lens shading related parameters. */
> > > -	if (params.contains("spatial_gain_curve")) {
> > > -		spatialGainCurve = params["spatial_gain_curve"].get<ipa::Pwl>(ipa::Pwl{});
> > > -	} else if (params.contains("spatial_gain")) {
> > > -		double spatialGain = params["spatial_gain"].get<double>(2.0);
> > > +	if (auto *sgc = params.find("spatial_gain_curve")) {
> > > +		spatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});
> > > +	} else if (auto *sg = params.find("spatial_gain")) {
> > > +		double spatialGain = sg->get<double>(2.0);
> > >  		spatialGainCurve.append(0.0, spatialGain);
> > >  		spatialGainCurve.append(0.01, spatialGain);
> > >  		spatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */
> > > @@ -68,24 +69,24 @@ void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
> > >  	if (tonemapEnable)
> > >  		tonemap = params["tonemap"].get<ipa::Pwl>(ipa::Pwl{});
> > >  	speed = params["speed"].get<double>(1.0);
> > > -	if (params.contains("hi_quantile_targets")) {
> > > -		hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
> > > +	if (auto *hqt = params.find("hi_quantile_targets")) {
> > > +		hiQuantileTargets = hqt->getList<double>().value();
> > >  		if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
> > >  			LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
> > >  	} else
> > >  		hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
> > >  	hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
> > > -	if (params.contains("quantile_targets")) {
> > > -		quantileTargets = params["quantile_targets"].getList<double>().value();
> > > +	if (auto *qt = params.find("quantile_targets")) {
> > > +		quantileTargets = qt->getList<double>().value();
> > >  		if (quantileTargets.empty() || quantileTargets.size() % 2)
> > >  			LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
> > >  	} else
> > >  		quantileTargets = { 0.2, 0.03, 1.0, 0.15 };
> > >  	powerMin = params["power_min"].get<double>(0.65);
> > >  	powerMax = params["power_max"].get<double>(1.0);
> > > -	if (params.contains("contrast_adjustments")) {
> > > -		contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
> > > -	} else
> > > +	if (auto *ca = params.find("contrast_adjustments"))
> > > +		contrastAdjustments = ca->getList<double>().value();
> > > +	else
> > >  		contrastAdjustments = { 0.5, 0.75 };
> > >
> > >  	/* Read any stitch parameters. */
> > > diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
> > > index e1b6d3af..ca3fe487 100644
> > > --- a/src/ipa/simple/soft_simple.cpp
> > > +++ b/src/ipa/simple/soft_simple.cpp
> > > @@ -114,12 +114,13 @@ int IPASoftSimple::init(const IPASettings &settings,
> > >  	unsigned int version = (*data)["version"].get<uint32_t>(0);
> > >  	LOG(IPASoft, Debug) << "Tuning file version " << version;
> > >
> > > -	if (!data->contains("algorithms")) {
> > > +	auto *algos = data->find("algorithms");
> > > +	if (!algos) {
> > >  		LOG(IPASoft, Error) << "Tuning file doesn't contain algorithms";
> > >  		return -EINVAL;
> > >  	}
> > >
> > > -	int ret = createAlgorithms(context_, (*data)["algorithms"]);
> > > +	int ret = createAlgorithms(context_, *algos);
> > >  	if (ret)
> > >  		return ret;
> > >

Patch
diff mbox series

diff --git a/src/android/camera_hal_config.cpp b/src/android/camera_hal_config.cpp
index 7ef451ef..6fde953d 100644
--- a/src/android/camera_hal_config.cpp
+++ b/src/android/camera_hal_config.cpp
@@ -73,15 +73,14 @@  int CameraHalConfig::Private::parseConfigFile(File &file,
 		return -EINVAL;
 
 	/* Parse property "cameras" */
-	if (!root->contains("cameras"))
+	auto *yamlObjectCameras = root->find("cameras");
+	if (!yamlObjectCameras)
 		return -EINVAL;
 
-	const YamlObject &yamlObjectCameras = (*root)["cameras"];
-
-	if (!yamlObjectCameras.isDictionary())
+	if (!yamlObjectCameras->isDictionary())
 		return -EINVAL;
 
-	for (const auto &[cameraId, configData] : yamlObjectCameras.asDict()) {
+	for (const auto &[cameraId, configData] : yamlObjectCameras->asDict()) {
 		if (parseCameraConfigData(cameraId, configData))
 			return -EINVAL;
 	}
@@ -112,10 +111,11 @@  int CameraHalConfig::Private::parseCameraConfigData(const std::string &cameraId,
 int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
 					    CameraConfigData &cameraConfigData)
 {
-	if (!cameraObject.contains("location"))
+	auto *loc = cameraObject.find("location");
+	if (!loc)
 		return -EINVAL;
 
-	std::string location = cameraObject["location"].get<std::string>("");
+	std::string location = loc->get<std::string>("");
 
 	if (location == "front")
 		cameraConfigData.facing = CAMERA_FACING_FRONT;
@@ -130,10 +130,11 @@  int CameraHalConfig::Private::parseLocation(const YamlObject &cameraObject,
 int CameraHalConfig::Private::parseRotation(const YamlObject &cameraObject,
 					    CameraConfigData &cameraConfigData)
 {
-	if (!cameraObject.contains("rotation"))
+	auto *rot = cameraObject.find("rotation");
+	if (!rot)
 		return -EINVAL;
 
-	int32_t rotation = cameraObject["rotation"].get<int32_t>(-1);
+	int32_t rotation = rot->get<int32_t>(-1);
 
 	if (rotation < 0 || rotation >= 360) {
 		LOG(HALConfig, Error)
diff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp
index 44c98cbf..88b1bb81 100644
--- a/src/ipa/ipu3/ipu3.cpp
+++ b/src/ipa/ipu3/ipu3.cpp
@@ -335,13 +335,14 @@  int IPAIPU3::init(const IPASettings &settings,
 		return -EINVAL;
 	}
 
-	if (!data->contains("algorithms")) {
+	auto *algos = data->find("algorithms");
+	if (!algos) {
 		LOG(IPAIPU3, Error)
 			<< "Tuning file doesn't contain any algorithm";
 		return -EINVAL;
 	}
 
-	int ret = createAlgorithms(context_, (*data)["algorithms"]);
+	int ret = createAlgorithms(context_, *algos);
 	if (ret)
 		return ret;
 
diff --git a/src/ipa/rkisp1/algorithms/dpcc.cpp b/src/ipa/rkisp1/algorithms/dpcc.cpp
index 78946281..8946c1a7 100644
--- a/src/ipa/rkisp1/algorithms/dpcc.cpp
+++ b/src/ipa/rkisp1/algorithms/dpcc.cpp
@@ -80,39 +80,39 @@  int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
 		/* PG Method */
 		const YamlObject &pgObject = set["pg-factor"];
 
-		if (pgObject.contains("green")) {
+		if (auto *green = pgObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_GREEN_ENABLE;
 
-			value = pgObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_G(value);
 		}
 
-		if (pgObject.contains("red-blue")) {
+		if (auto *redBlue = pgObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_PG_RED_BLUE_ENABLE;
 
-			value = pgObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			method.pg_fac |= RKISP1_CIF_ISP_DPCC_PG_FAC_RB(value);
 		}
 
 		/* RO Method */
 		const YamlObject &roObject = set["ro-limits"];
 
-		if (roObject.contains("green")) {
+		if (auto *green = roObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_GREEN_ENABLE;
 
-			value = roObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			config_.ro_limits |=
 				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_G(i, value);
 		}
 
-		if (roObject.contains("red-blue")) {
+		if (auto *redBlue = roObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RO_RED_BLUE_ENABLE;
 
-			value = roObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			config_.ro_limits |=
 				RKISP1_CIF_ISP_DPCC_RO_LIMITS_n_RB(i, value);
 		}
@@ -121,39 +121,39 @@  int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
 		const YamlObject &rgObject = set["rg-factor"];
 		method.rg_fac = 0;
 
-		if (rgObject.contains("green")) {
+		if (auto *green = rgObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_GREEN_ENABLE;
 
-			value = rgObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_G(value);
 		}
 
-		if (rgObject.contains("red-blue")) {
+		if (auto *redBlue = rgObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RG_RED_BLUE_ENABLE;
 
-			value = rgObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			method.rg_fac |= RKISP1_CIF_ISP_DPCC_RG_FAC_RB(value);
 		}
 
 		/* RND Method */
 		const YamlObject &rndOffsetsObject = set["rnd-offsets"];
 
-		if (rndOffsetsObject.contains("green")) {
+		if (auto *green = rndOffsetsObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
 
-			value = rndOffsetsObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			config_.rnd_offs |=
 				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_G(i, value);
 		}
 
-		if (rndOffsetsObject.contains("red-blue")) {
+		if (auto *redBlue = rndOffsetsObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
 
-			value = rndOffsetsObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			config_.rnd_offs |=
 				RKISP1_CIF_ISP_DPCC_RND_OFFS_n_RB(i, value);
 		}
@@ -161,20 +161,20 @@  int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
 		const YamlObject &rndThresholdObject = set["rnd-threshold"];
 		method.rnd_thresh = 0;
 
-		if (rndThresholdObject.contains("green")) {
+		if (auto *green = rndThresholdObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_GREEN_ENABLE;
 
-			value = rndThresholdObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			method.rnd_thresh |=
 				RKISP1_CIF_ISP_DPCC_RND_THRESH_G(value);
 		}
 
-		if (rndThresholdObject.contains("red-blue")) {
+		if (auto *redBlue = rndThresholdObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_RND_RED_BLUE_ENABLE;
 
-			value = rndThresholdObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			method.rnd_thresh |=
 				RKISP1_CIF_ISP_DPCC_RND_THRESH_RB(value);
 		}
@@ -183,20 +183,20 @@  int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
 		const YamlObject &lcThresholdObject = set["line-threshold"];
 		method.line_thresh = 0;
 
-		if (lcThresholdObject.contains("green")) {
+		if (auto *green = lcThresholdObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
 
-			value = lcThresholdObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			method.line_thresh |=
 				RKISP1_CIF_ISP_DPCC_LINE_THRESH_G(value);
 		}
 
-		if (lcThresholdObject.contains("red-blue")) {
+		if (auto *redBlue = lcThresholdObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
 
-			value = lcThresholdObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			method.line_thresh |=
 				RKISP1_CIF_ISP_DPCC_LINE_THRESH_RB(value);
 		}
@@ -204,20 +204,20 @@  int DefectPixelClusterCorrection::init([[maybe_unused]] IPAContext &context,
 		const YamlObject &lcTMadFactorObject = set["line-mad-factor"];
 		method.line_mad_fac = 0;
 
-		if (lcTMadFactorObject.contains("green")) {
+		if (auto *green = lcTMadFactorObject.find("green")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_GREEN_ENABLE;
 
-			value = lcTMadFactorObject["green"].get<uint16_t>(0);
+			value = green->get<uint16_t>(0);
 			method.line_mad_fac |=
 				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_G(value);
 		}
 
-		if (lcTMadFactorObject.contains("red-blue")) {
+		if (auto *redBlue = lcTMadFactorObject.find("red-blue")) {
 			method.method |=
 				RKISP1_CIF_ISP_DPCC_METHODS_SET_LC_RED_BLUE_ENABLE;
 
-			value = lcTMadFactorObject["red-blue"].get<uint16_t>(0);
+			value = redBlue->get<uint16_t>(0);
 			method.line_mad_fac |=
 				RKISP1_CIF_ISP_DPCC_LINE_MAD_FAC_RB(value);
 		}
diff --git a/src/ipa/rkisp1/rkisp1.cpp b/src/ipa/rkisp1/rkisp1.cpp
index 2ffdd99b..202b53b7 100644
--- a/src/ipa/rkisp1/rkisp1.cpp
+++ b/src/ipa/rkisp1/rkisp1.cpp
@@ -193,13 +193,14 @@  int IPARkISP1::init(const IPASettings &settings, unsigned int hwRevision,
 		return -EINVAL;
 	}
 
-	if (!data->contains("algorithms")) {
+	auto *algos = data->find("algorithms");
+	if (!algos) {
 		LOG(IPARkISP1, Error)
 			<< "Tuning file doesn't contain any algorithm";
 		return -EINVAL;
 	}
 
-	int ret = createAlgorithms(context_, (*data)["algorithms"]);
+	int ret = createAlgorithms(context_, *algos);
 	if (ret)
 		return ret;
 
diff --git a/src/ipa/rpi/controller/controller.cpp b/src/ipa/rpi/controller/controller.cpp
index e0131018..fbf31f23 100644
--- a/src/ipa/rpi/controller/controller.cpp
+++ b/src/ipa/rpi/controller/controller.cpp
@@ -109,14 +109,15 @@  int Controller::read(char const *filename)
 				return ret;
 		}
 	} else if (version < 3.0) {
-		if (!root->contains("algorithms")) {
+		auto *algos = root->find("algorithms");
+		if (!algos) {
 			LOG(RPiController, Error)
 				<< "Tuning file " << filename
 				<< " does not have an \"algorithms\" list!";
 			return -EINVAL;
 		}
 
-		for (auto const &rootAlgo : (*root)["algorithms"].asList())
+		for (auto const &rootAlgo : algos->asList())
 			for (auto const &[key, value] : rootAlgo.asDict()) {
 				int ret = createAlgorithm(key, value);
 				if (ret)
diff --git a/src/ipa/rpi/controller/rpi/af.cpp b/src/ipa/rpi/controller/rpi/af.cpp
index 2157eb94..c29bbaeb 100644
--- a/src/ipa/rpi/controller/rpi/af.cpp
+++ b/src/ipa/rpi/controller/rpi/af.cpp
@@ -97,39 +97,35 @@  void Af::SpeedDependentParams::read(const libcamera::YamlObject &params)
 
 int Af::CfgParams::read(const libcamera::YamlObject &params)
 {
-	if (params.contains("ranges")) {
-		auto &rr = params["ranges"];
-
-		if (rr.contains("normal"))
-			ranges[AfRangeNormal].read(rr["normal"]);
+	if (auto *rs = params.find("ranges")) {
+		if (auto *normal = rs->find("normal"))
+			ranges[AfRangeNormal].read(*normal);
 		else
 			LOG(RPiAf, Warning) << "Missing range \"normal\"";
 
 		ranges[AfRangeMacro] = ranges[AfRangeNormal];
-		if (rr.contains("macro"))
-			ranges[AfRangeMacro].read(rr["macro"]);
+		if (auto *macro = rs->find("macro"))
+			ranges[AfRangeMacro].read(*macro);
 
 		ranges[AfRangeFull].focusMin = std::min(ranges[AfRangeNormal].focusMin,
 							ranges[AfRangeMacro].focusMin);
 		ranges[AfRangeFull].focusMax = std::max(ranges[AfRangeNormal].focusMax,
 							ranges[AfRangeMacro].focusMax);
 		ranges[AfRangeFull].focusDefault = ranges[AfRangeNormal].focusDefault;
-		if (rr.contains("full"))
-			ranges[AfRangeFull].read(rr["full"]);
+		if (auto *full = rs->find("full"))
+			ranges[AfRangeFull].read(*full);
 	} else
 		LOG(RPiAf, Warning) << "No ranges defined";
 
-	if (params.contains("speeds")) {
-		auto &ss = params["speeds"];
-
-		if (ss.contains("normal"))
-			speeds[AfSpeedNormal].read(ss["normal"]);
+	if (auto *ss = params.find("speeds")) {
+		if (auto *normal = ss->find("normal"))
+			speeds[AfSpeedNormal].read(*normal);
 		else
 			LOG(RPiAf, Warning) << "Missing speed \"normal\"";
 
 		speeds[AfSpeedFast] = speeds[AfSpeedNormal];
-		if (ss.contains("fast"))
-			speeds[AfSpeedFast].read(ss["fast"]);
+		if (auto *fast = ss->find("fast"))
+			speeds[AfSpeedFast].read(*fast);
 	} else
 		LOG(RPiAf, Warning) << "No speeds defined";
 
@@ -138,8 +134,8 @@  int Af::CfgParams::read(const libcamera::YamlObject &params)
 	readNumber<uint32_t>(confClip, params, "conf_clip");
 	readNumber<uint32_t>(skipFrames, params, "skip_frames");
 
-	if (params.contains("map"))
-		map = params["map"].get<ipa::Pwl>(ipa::Pwl{});
+	if (auto *m = params.find("map"))
+		map = m->get<ipa::Pwl>(ipa::Pwl{});
 	else
 		LOG(RPiAf, Warning) << "No map defined";
 
diff --git a/src/ipa/rpi/controller/rpi/agc.cpp b/src/ipa/rpi/controller/rpi/agc.cpp
index c48fdf15..5d924ebf 100644
--- a/src/ipa/rpi/controller/rpi/agc.cpp
+++ b/src/ipa/rpi/controller/rpi/agc.cpp
@@ -37,18 +37,18 @@  int Agc::read(const libcamera::YamlObject &params)
 	 * When there is only a single channel we can read the old style syntax.
 	 * Otherwise we expect a "channels" keyword followed by a list of configurations.
 	 */
-	if (!params.contains("channels")) {
+	auto *channels = params.find("channels");
+	if (!channels) {
 		LOG(RPiAgc, Debug) << "Single channel only";
 		channelTotalExposures_.resize(1, 0s);
 		channelData_.emplace_back();
 		return channelData_.back().channel.read(params, getHardwareConfig());
 	}
 
-	const auto &channels = params["channels"].asList();
-	for (auto ch = channels.begin(); ch != channels.end(); ch++) {
+	for (const auto &ch : channels->asList()) {
 		LOG(RPiAgc, Debug) << "Read AGC channel";
 		channelData_.emplace_back();
-		int ret = channelData_.back().channel.read(*ch, getHardwareConfig());
+		int ret = channelData_.back().channel.read(ch, getHardwareConfig());
 		if (ret)
 			return ret;
 	}
diff --git a/src/ipa/rpi/controller/rpi/agc_channel.cpp b/src/ipa/rpi/controller/rpi/agc_channel.cpp
index 79c45973..50b9efd2 100644
--- a/src/ipa/rpi/controller/rpi/agc_channel.cpp
+++ b/src/ipa/rpi/controller/rpi/agc_channel.cpp
@@ -235,8 +235,8 @@  int AgcConfig::read(const libcamera::YamlObject &params)
 	if (ret)
 		return ret;
 
-	if (params.contains("channel_constraints")) {
-		ret = readChannelConstraints(channelConstraints, params["channel_constraints"]);
+	if (auto *cc = params.find("channel_constraints")) {
+		ret = readChannelConstraints(channelConstraints, *cc);
 		if (ret)
 			return ret;
 	}
diff --git a/src/ipa/rpi/controller/rpi/alsc.cpp b/src/ipa/rpi/controller/rpi/alsc.cpp
index 21edb819..5a1a702b 100644
--- a/src/ipa/rpi/controller/rpi/alsc.cpp
+++ b/src/ipa/rpi/controller/rpi/alsc.cpp
@@ -104,9 +104,9 @@  static int readCalibrations(std::vector<AlscCalibration> &calibrations,
 			    const libcamera::YamlObject &params,
 			    std::string const &name, const Size &size)
 {
-	if (params.contains(name)) {
+	if (auto *param = params.find(name)) {
 		double lastCt = 0;
-		for (const auto &p : params[name].asList()) {
+		for (const auto &p : param->asList()) {
 			auto value = p["ct"].get<double>();
 			if (!value)
 				return -EINVAL;
@@ -163,10 +163,10 @@  int Alsc::read(const libcamera::YamlObject &params)
 	config_.luminanceLut.resize(config_.tableSize, 1.0);
 	int ret = 0;
 
-	if (params.contains("corner_strength"))
+	if (params.find("corner_strength"))
 		ret = generateLut(config_.luminanceLut, params);
-	else if (params.contains("luminance_lut"))
-		ret = readLut(config_.luminanceLut, params["luminance_lut"]);
+	else if (auto *ll = params.find("luminance_lut"))
+		ret = readLut(config_.luminanceLut, *ll);
 	else
 		LOG(RPiAlsc, Warning)
 			<< "no luminance table - assume unity everywhere";
diff --git a/src/ipa/rpi/controller/rpi/awb.cpp b/src/ipa/rpi/controller/rpi/awb.cpp
index c277a176..2e6e295c 100644
--- a/src/ipa/rpi/controller/rpi/awb.cpp
+++ b/src/ipa/rpi/controller/rpi/awb.cpp
@@ -102,8 +102,8 @@  int AwbConfig::read(const libcamera::YamlObject &params)
 	convergenceFrames = params["convergence_frames"].get<unsigned int>(3);
 	speed = params["speed"].get<double>(0.05);
 
-	if (params.contains("ct_curve")) {
-		ret = readCtCurve(ctR, ctB, params["ct_curve"]);
+	if (auto *ct_curve = params.find("ct_curve")) {
+		ret = readCtCurve(ctR, ctB, *ct_curve);
 		if (ret)
 			return ret;
 		/* We will want the inverse functions of these too. */
@@ -111,8 +111,8 @@  int AwbConfig::read(const libcamera::YamlObject &params)
 		ctBInverse = ctB.inverse().first;
 	}
 
-	if (params.contains("priors")) {
-		for (const auto &p : params["priors"].asList()) {
+	if (auto *ps = params.find("priors")) {
+		for (const auto &p : ps->asList()) {
 			AwbPrior prior;
 			ret = prior.read(p);
 			if (ret)
@@ -128,8 +128,8 @@  int AwbConfig::read(const libcamera::YamlObject &params)
 			return -EINVAL;
 		}
 	}
-	if (params.contains("modes")) {
-		for (const auto &[key, value] : params["modes"].asDict()) {
+	if (auto *ms = params.find("modes")) {
+		for (const auto &[key, value] : ms->asDict()) {
 			ret = modes[key].read(value);
 			if (ret)
 				return ret;
diff --git a/src/ipa/rpi/controller/rpi/ccm.cpp b/src/ipa/rpi/controller/rpi/ccm.cpp
index 8607f152..5616e5f4 100644
--- a/src/ipa/rpi/controller/rpi/ccm.cpp
+++ b/src/ipa/rpi/controller/rpi/ccm.cpp
@@ -41,8 +41,8 @@  char const *Ccm::name() const
 
 int Ccm::read(const libcamera::YamlObject &params)
 {
-	if (params.contains("saturation")) {
-		config_.saturation = params["saturation"].get<ipa::Pwl>(ipa::Pwl{});
+	if (auto *s = params.find("saturation")) {
+		config_.saturation = s->get<ipa::Pwl>(ipa::Pwl{});
 		if (config_.saturation.empty())
 			return -EINVAL;
 	}
diff --git a/src/ipa/rpi/controller/rpi/geq.cpp b/src/ipa/rpi/controller/rpi/geq.cpp
index 40e7191b..6935f726 100644
--- a/src/ipa/rpi/controller/rpi/geq.cpp
+++ b/src/ipa/rpi/controller/rpi/geq.cpp
@@ -43,8 +43,8 @@  int Geq::read(const libcamera::YamlObject &params)
 		return -EINVAL;
 	}
 
-	if (params.contains("strength")) {
-		config_.strength = params["strength"].get<ipa::Pwl>(ipa::Pwl{});
+	if (auto *strength = params.find("strength")) {
+		config_.strength = strength->get<ipa::Pwl>(ipa::Pwl{});
 		if (config_.strength.empty())
 			return -EINVAL;
 	}
diff --git a/src/ipa/rpi/controller/rpi/hdr.cpp b/src/ipa/rpi/controller/rpi/hdr.cpp
index f3da8291..20b1ff4b 100644
--- a/src/ipa/rpi/controller/rpi/hdr.cpp
+++ b/src/ipa/rpi/controller/rpi/hdr.cpp
@@ -27,9 +27,10 @@  void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
 {
 	name = modeName;
 
-	if (!params.contains("cadence"))
+	auto *c = params.find("cadence");
+	if (!c)
 		LOG(RPiHdr, Fatal) << "No cadence for HDR mode " << name;
-	cadence = params["cadence"].getList<unsigned int>().value();
+	cadence = c->getList<unsigned int>().value();
 	if (cadence.empty())
 		LOG(RPiHdr, Fatal) << "Empty cadence in HDR mode " << name;
 
@@ -41,10 +42,10 @@  void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
 		channelMap[v.get<unsigned int>().value()] = k;
 
 	/* Lens shading related parameters. */
-	if (params.contains("spatial_gain_curve")) {
-		spatialGainCurve = params["spatial_gain_curve"].get<ipa::Pwl>(ipa::Pwl{});
-	} else if (params.contains("spatial_gain")) {
-		double spatialGain = params["spatial_gain"].get<double>(2.0);
+	if (auto *sgc = params.find("spatial_gain_curve")) {
+		spatialGainCurve = sgc->get<ipa::Pwl>(ipa::Pwl{});
+	} else if (auto *sg = params.find("spatial_gain")) {
+		double spatialGain = sg->get<double>(2.0);
 		spatialGainCurve.append(0.0, spatialGain);
 		spatialGainCurve.append(0.01, spatialGain);
 		spatialGainCurve.append(0.06, 1.0); /* maybe make this programmable? */
@@ -68,24 +69,24 @@  void HdrConfig::read(const libcamera::YamlObject &params, const std::string &mod
 	if (tonemapEnable)
 		tonemap = params["tonemap"].get<ipa::Pwl>(ipa::Pwl{});
 	speed = params["speed"].get<double>(1.0);
-	if (params.contains("hi_quantile_targets")) {
-		hiQuantileTargets = params["hi_quantile_targets"].getList<double>().value();
+	if (auto *hqt = params.find("hi_quantile_targets")) {
+		hiQuantileTargets = hqt->getList<double>().value();
 		if (hiQuantileTargets.empty() || hiQuantileTargets.size() % 2)
 			LOG(RPiHdr, Fatal) << "hi_quantile_targets much be even and non-empty";
 	} else
 		hiQuantileTargets = { 0.95, 0.65, 0.5, 0.28, 0.3, 0.25 };
 	hiQuantileMaxGain = params["hi_quantile_max_gain"].get<double>(1.6);
-	if (params.contains("quantile_targets")) {
-		quantileTargets = params["quantile_targets"].getList<double>().value();
+	if (auto *qt = params.find("quantile_targets")) {
+		quantileTargets = qt->getList<double>().value();
 		if (quantileTargets.empty() || quantileTargets.size() % 2)
 			LOG(RPiHdr, Fatal) << "quantile_targets much be even and non-empty";
 	} else
 		quantileTargets = { 0.2, 0.03, 1.0, 0.15 };
 	powerMin = params["power_min"].get<double>(0.65);
 	powerMax = params["power_max"].get<double>(1.0);
-	if (params.contains("contrast_adjustments")) {
-		contrastAdjustments = params["contrast_adjustments"].getList<double>().value();
-	} else
+	if (auto *ca = params.find("contrast_adjustments"))
+		contrastAdjustments = ca->getList<double>().value();
+	else
 		contrastAdjustments = { 0.5, 0.75 };
 
 	/* Read any stitch parameters. */
diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp
index e1b6d3af..ca3fe487 100644
--- a/src/ipa/simple/soft_simple.cpp
+++ b/src/ipa/simple/soft_simple.cpp
@@ -114,12 +114,13 @@  int IPASoftSimple::init(const IPASettings &settings,
 	unsigned int version = (*data)["version"].get<uint32_t>(0);
 	LOG(IPASoft, Debug) << "Tuning file version " << version;
 
-	if (!data->contains("algorithms")) {
+	auto *algos = data->find("algorithms");
+	if (!algos) {
 		LOG(IPASoft, Error) << "Tuning file doesn't contain algorithms";
 		return -EINVAL;
 	}
 
-	int ret = createAlgorithms(context_, (*data)["algorithms"]);
+	int ret = createAlgorithms(context_, *algos);
 	if (ret)
 		return ret;