[libcamera-devel] [PATCH v2 1/3] libcamera: Add ColorSpace class

David Plowman david.plowman at raspberrypi.com
Mon Sep 27 14:33:25 CEST 2021


This class represents a colour space by defining its YCbCr encoding,
the transfer (gamma) function is uses, and whether the output is full
or limited range.

Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
---
 include/libcamera/color_space.h |  83 +++++++++++++
 include/libcamera/meson.build   |   1 +
 src/libcamera/color_space.cpp   | 207 ++++++++++++++++++++++++++++++++
 src/libcamera/meson.build       |   1 +
 4 files changed, 292 insertions(+)
 create mode 100644 include/libcamera/color_space.h
 create mode 100644 src/libcamera/color_space.cpp

diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h
new file mode 100644
index 00000000..9cd10503
--- /dev/null
+++ b/include/libcamera/color_space.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Raspberry Pi (Trading) Limited
+ *
+ * color_space.h - color space definitions
+ */
+
+#ifndef __LIBCAMERA_COLOR_SPACE_H__
+#define __LIBCAMERA_COLOR_SPACE_H__
+
+#include <string>
+
+namespace libcamera {
+
+class ColorSpace
+{
+public:
+	enum class Encoding : int {
+		UNDEFINED,
+		RAW,
+		REC601,
+		REC709,
+		REC2020,
+		VIDEO,
+	};
+
+	enum class TransferFunction : int {
+		UNDEFINED,
+		IDENTITY,
+		SRGB,
+		REC709,
+	};
+
+	enum class Range : int {
+		UNDEFINED,
+		FULL,
+		LIMITED,
+	};
+
+	constexpr ColorSpace(Encoding e, TransferFunction t, Range r)
+		: encoding(e), transferFunction(t), range(r)
+	{
+	}
+
+	constexpr ColorSpace()
+		: ColorSpace(Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED)
+	{
+	}
+
+	static const ColorSpace UNDEFINED;
+	static const ColorSpace RAW;
+	static const ColorSpace JFIF;
+	static const ColorSpace SMPTE170M;
+	static const ColorSpace REC709;
+	static const ColorSpace REC2020;
+	static const ColorSpace VIDEO;
+
+	Encoding encoding;
+	TransferFunction transferFunction;
+	Range range;
+
+	bool isFullyDefined() const;
+
+	const std::string toString() const;
+};
+
+constexpr ColorSpace ColorSpace::UNDEFINED = { Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED };
+constexpr ColorSpace ColorSpace::RAW = { Encoding::RAW, TransferFunction::IDENTITY, Range::FULL };
+constexpr ColorSpace ColorSpace::JFIF = { Encoding::REC601, TransferFunction::SRGB, Range::FULL };
+constexpr ColorSpace ColorSpace::SMPTE170M = { Encoding::REC601, TransferFunction::REC709, Range::LIMITED };
+constexpr ColorSpace ColorSpace::REC709 = { Encoding::REC709, TransferFunction::REC709, Range::LIMITED };
+constexpr ColorSpace ColorSpace::REC2020 = { Encoding::REC2020, TransferFunction::REC709, Range::LIMITED };
+constexpr ColorSpace ColorSpace::VIDEO = { Encoding::VIDEO, TransferFunction::REC709, Range::LIMITED };
+
+bool operator==(const ColorSpace &lhs, const ColorSpace &rhs);
+static inline bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)
+{
+	return !(lhs == rhs);
+}
+
+} /* namespace libcamera */
+
+#endif /* __LIBCAMERA_COLOR_SPACE_H__ */
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build
index 5b25ef84..7a8a04e5 100644
--- a/include/libcamera/meson.build
+++ b/include/libcamera/meson.build
@@ -3,6 +3,7 @@
 libcamera_public_headers = files([
     'camera.h',
     'camera_manager.h',
+    'color_space.h',
     'compiler.h',
     'controls.h',
     'file_descriptor.h',
diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp
new file mode 100644
index 00000000..d1ccb4cc
--- /dev/null
+++ b/src/libcamera/color_space.cpp
@@ -0,0 +1,207 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Raspberry Pi (Trading) Limited
+ *
+ * color_space.cpp - color spaces.
+ */
+
+#include <sstream>
+
+#include <libcamera/color_space.h>
+
+/**
+ * \file color_space.h
+ * \brief Class and enums to represent colour spaces.
+ */
+
+namespace libcamera {
+
+/**
+ * \class ColorSpace
+ * \brief Class to describe a color space.
+ *
+ * The color space class defines the encodings of the color primaries, the
+ * transfer function associated with the color space, and the range (sometimes
+ * also referred to as the quantisation) of the color space.
+ *
+ * Certain combinations of these fields form well-known standard color spaces,
+ * such as "JFIF" or "REC709", though there is flexibility to leave some or all
+ * of them undefined too.
+ */
+
+/**
+ * \enum ColorSpace::Encoding
+ * \brief The encoding used for the color primaries.
+ *
+ * \var ColorSpace::Encoding::UNDEFINED
+ * \brief The encoding for the colour primaries is not specified.
+ * \var ColorSpace::Encoding::RAW
+ * \brief These are raw colours from the sensor.
+ * \var ColorSpace::Encoding::REC601
+ * \brief REC601 colour primaries.
+ * \var ColorSpace::Encoding::REC709
+ * \brief Rec709 colour primaries.
+ * \var ColorSpace::Encoding::REC2020
+ * \brief REC2020 colour primaries.
+ * \var ColorSpace::Encoding::VIDEO
+ * \brief A place-holder for video streams which will be resolved to one
+ * of REC601, REC709 or REC2020 once the video resolution is known.
+ */
+
+/**
+ * \enum ColorSpace::TransferFunction
+ * \brief The transfer function used for this colour space.
+ *
+ * \var ColorSpace::TransferFunction::UNDEFINED
+ * \brief The transfer function is not specified.
+ * \var ColorSpace::TransferFunction::IDENTITY
+ * \brief This color space uses an identity transfer function.
+ * \var ColorSpace::TransferFunction::SRGB
+ * \brief sRGB transfer function.
+ * \var ColorSpace::TransferFunction::REC709
+ * \brief Rec709 transfer function.
+ */
+
+/**
+ * \enum ColorSpace::Range
+ * \brief The range (sometimes "quantisation") for this color space.
+ *
+ * \var ColorSpace::Range::UNDEFINED
+ * \brief The range is not specified.
+ * \var ColorSpace::Range::FULL
+ * \brief This color space uses full range pixel values.
+ * \var ColorSpace::Range::LIMITED
+ * \brief This color space uses limited range pixel values.
+ */
+
+/**
+ * \fn ColorSpace::ColorSpace(Encoding e, TransferFunction t, Range r)
+ * \brief Construct a ColorSpace from explicit values
+ * \param[in] e The encoding for the color primaries
+ * \param[in] t The transfer function for the color space
+ * \param[in] r The range of the pixel values in this color space
+ */
+
+/**
+ * \fn ColorSpace::ColorSpace()
+ * \brief Construct a color space with undefined encoding, transfer function
+ * and range
+ */
+
+/**
+ * \brief Return true if all the fields of the color space are defined, otherwise false.
+ */
+bool ColorSpace::isFullyDefined() const
+{
+	return encoding != Encoding::UNDEFINED &&
+	       transferFunction != TransferFunction::UNDEFINED &&
+	       range != Range::UNDEFINED;
+}
+
+/**
+ * \brief Assemble and return a readable string representation of the
+ * ColorSpace
+ * \return A string describing the ColorSpace
+ */
+const std::string ColorSpace::toString() const
+{
+	static const char *encodings[] = {
+		"UNDEFINED",
+		"RAW",
+		"REC601",
+		"REC709",
+		"REC2020",
+	};
+	static const char *transferFunctions[] = {
+		"UNDEFINED",
+		"IDENTITY",
+		"SRGB",
+		"REC709",
+	};
+	static const char *ranges[] = {
+		"UNDEFINED",
+		"FULL",
+		"LIMITED",
+	};
+
+	std::stringstream ss;
+	ss << std::string(encodings[static_cast<int>(encoding)]) << "+"
+	   << std::string(transferFunctions[static_cast<int>(transferFunction)]) << "+"
+	   << std::string(ranges[static_cast<int>(range)]);
+
+	return ss.str();
+}
+
+/**
+ * \var ColorSpace::encoding
+ * \brief The encoding of the color primaries
+ */
+
+/**
+ * \var ColorSpace::transferFunction
+ * \brief The transfer function for this color space.
+ */
+
+/**
+ * \var ColorSpace::range
+ * \brief The pixel range used by this color space.
+ */
+
+/**
+ * \var ColorSpace::UNDEFINED
+ * \brief A constant representing a fully undefined color space.
+ */
+
+/**
+ * \var ColorSpace::RAW
+ * \brief A constant representing a raw color space (from a sensor).
+ */
+
+/**
+ * \var ColorSpace::JFIF
+ * \brief A constant representing the JFIF color space usually used for
+ * encoding JPEG images.
+ */
+
+/**
+ * \var ColorSpace::SMPTE170M
+ * \brief A constant representing the SMPTE170M color space (sometimes also
+ * referred to as "full range BT601").
+ */
+
+/**
+ * \var ColorSpace::REC709
+ * \brief A constant representing the REC709 color space.
+ */
+
+/**
+ * \var ColorSpace::REC2020
+ * \brief A constant representing the REC2020 color space.
+ */
+
+/**
+ * \var ColorSpace::VIDEO
+ * \brief A constant that video streams can use to indicate the "default"
+ * color space for a video of this resolution, once that is is known. For
+ * exmample, SD streams would interpret this as SMPTE170M, HD streams as
+ * REC709 and ultra HD as REC2020.
+ */
+
+/**
+ * \brief Compare color spaces for equality
+ * \return True if the two color spaces are identical, false otherwise
+ */
+bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
+{
+	return lhs.encoding == rhs.encoding &&
+	       lhs.transferFunction == rhs.transferFunction &&
+	       lhs.range == rhs.range;
+}
+
+/**
+ * \fn bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)
+ * \brief Compare color spaces for inequality
+ * \return True if the two color spaces are not identical, false otherwise
+ */
+
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index bf82d38b..88dfbf24 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -8,6 +8,7 @@ libcamera_sources = files([
     'camera_manager.cpp',
     'camera_sensor.cpp',
     'camera_sensor_properties.cpp',
+    'color_space.cpp',
     'controls.cpp',
     'control_serializer.cpp',
     'control_validator.cpp',
-- 
2.20.1



More information about the libcamera-devel mailing list