summaryrefslogtreecommitdiff
path: root/test/pixel-format.cpp
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2022-01-24 10:31:06 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-02-03 02:40:07 +0200
commite875503bc4a40e5043fb045942535b865692ff60 (patch)
treec66bc3f0bcb4bf8ca1f04ad788f6861ea4d92d59 /test/pixel-format.cpp
parentb71cd3358f6bb4f8f8efc7974c9d1acd131788bb (diff)
ipa: raspberrypi: Limit the maximum sensor gain used
Limit the gain code to the maximum value reported by the sensor controls when sending to DelayedControls. The AGC algorithm will handle a lower gain used by the sensor, provided it knows the actual gain used. This change ensures that DelayedControls will never report an unclipped gain used. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: David Plowman <david.plowman@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'test/pixel-format.cpp')
0 files changed, 0 insertions, 0 deletions
7 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2022, Google Inc.
 *
 * libcamera YAML parsing helper
 */

#pragma once

#include <iterator>
#include <map>
#include <optional>
#include <string>
#include <vector>

#include <libcamera/base/class.h>

#include <libcamera/geometry.h>

namespace libcamera {

class File;
class YamlParserContext;

class YamlObject
{
private:
	struct Value {
		Value(std::string &&k, std::unique_ptr<YamlObject> &&v)
			: key(std::move(k)), value(std::move(v))
		{
		}
		std::string key;
		std::unique_ptr<YamlObject> value;
	};

	using Container = std::vector<Value>;
	using ListContainer = std::vector<std::unique_ptr<YamlObject>>;

public:
#ifndef __DOXYGEN__
	template<typename Derived>
	class Iterator
	{
	public:
		using difference_type = std::ptrdiff_t;
		using iterator_category = std::forward_iterator_tag;

		Iterator(typename Container::const_iterator it)
			: it_(it)
		{
		}

		Derived &operator++()
		{
			++it_;
			return *static_cast<Derived *>(this);
		}

		Derived operator++(int)
		{
			Derived it = *static_cast<Derived *>(this);
			it_++;
			return it;
		}

		friend bool operator==(const Iterator &a, const Iterator &b)
		{
			return a.it_ == b.it_;
		}

		friend bool operator!=(const Iterator &a, const Iterator &b)
		{
			return a.it_ != b.it_;
		}

	protected:
		Container::const_iterator it_;
	};

	template<typename Iterator>
	class Adapter
	{
	public:
		Adapter(const Container &container)
			: container_(container)
		{
		}

		Iterator begin() const
		{
			return Iterator{ container_.begin() };
		}

		Iterator end() const
		{
			return Iterator{ container_.end() };
		}

	protected:
		const Container &container_;
	};

	class ListIterator : public Iterator<ListIterator>
	{
	public:
		using value_type = const YamlObject &;
		using pointer = const YamlObject *;
		using reference = value_type;

		value_type operator*() const
		{
			return *it_->value.get();
		}

		pointer operator->() const
		{
			return it_->value.get();
		}
	};

	class DictIterator : public Iterator<DictIterator>
	{
	public:
		using value_type = std::pair<const std::string &, const YamlObject &>;
		using pointer = value_type *;
		using reference = value_type &;

		value_type operator*() const
		{
			return { it_->key, *it_->value.get() };
		}
	};

	class DictAdapter : public Adapter<DictIterator>
	{
	public:
		using key_type = std::string;
	};

	class ListAdapter : public Adapter<ListIterator>
	{
	};
#endif /* __DOXYGEN__ */

	YamlObject();
	~YamlObject();

	bool isValue() const
	{
		return type_ == Type::Value;
	}
	bool isList() const
	{
		return type_ == Type::List;
	}
	bool isDictionary() const
	{
		return type_ == Type::Dictionary;
	}

	std::size_t size() const;

#ifndef __DOXYGEN__
	template<typename T,
		 std::enable_if_t<
			 std::is_same_v<bool, T> ||
			 std::is_same_v<double, T> ||
			 std::is_same_v<int8_t, T> ||
			 std::is_same_v<uint8_t, T> ||
			 std::is_same_v<int16_t, T> ||
			 std::is_same_v<uint16_t, T> ||
			 std::is_same_v<int32_t, T> ||
			 std::is_same_v<uint32_t, T> ||
			 std::is_same_v<std::string, T> ||
			 std::is_same_v<Size, T>> * = nullptr>
#else
	template<typename T>
#endif
	std::optional<T> get() const;

	template<typename T, typename U>
	T get(U &&defaultValue) const
	{
		return get<T>().value_or(std::forward<U>(defaultValue));
	}

#ifndef __DOXYGEN__
	template<typename T,
		 std::enable_if_t<
			 std::is_same_v<bool, T> ||
			 std::is_same_v<double, T> ||
			 std::is_same_v<int8_t, T> ||
			 std::is_same_v<uint8_t, T> ||
			 std::is_same_v<int16_t, T> ||
			 std::is_same_v<uint16_t, T> ||
			 std::is_same_v<int32_t, T> ||
			 std::is_same_v<uint32_t, T> ||
			 std::is_same_v<std::string, T> ||
			 std::is_same_v<Size, T>> * = nullptr>
#else
	template<typename T>
#endif
	std::optional<std::vector<T>> getList() const;

	DictAdapter asDict() const { return DictAdapter{ list_ }; }
	ListAdapter asList() const { return ListAdapter{ list_ }; }

	const YamlObject &operator[](std::size_t index) const;

	bool contains(const std::string &key) const;
	const YamlObject &operator[](const std::string &key) const;

private:
	LIBCAMERA_DISABLE_COPY_AND_MOVE(YamlObject)

	friend class YamlParserContext;

	enum class Type {
		Dictionary,
		List,
		Value,
	};

	Type type_;

	std::string value_;
	Container list_;
	std::map<std::string, YamlObject *> dictionary_;
};

class YamlParser final
{
public:
	static std::unique_ptr<YamlObject> parse(File &file);
};

} /* namespace libcamera */