<div dir="ltr"><div dir="ltr">Hi David,<div><br></div><div>Thank you for your patch.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 5 Aug 2021 at 15:22, David Plowman <<a href="mailto:david.plowman@raspberrypi.com">david.plowman@raspberrypi.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This class represents a colour space by defining its YCbCr encoding,<br>
the transfer (gamma) function is uses, and whether the output is full<br>
or limited range.<br>
<br>
Signed-off-by: David Plowman <<a href="mailto:david.plowman@raspberrypi.com" target="_blank">david.plowman@raspberrypi.com</a>><br>
---<br>
 include/libcamera/color_space.h |  94 +++++++++++++++++<br>
 include/libcamera/meson.build   |   1 +<br>
 src/libcamera/color_space.cpp   | 180 ++++++++++++++++++++++++++++++++<br>
 src/libcamera/meson.build       |   1 +<br>
 4 files changed, 276 insertions(+)<br>
 create mode 100644 include/libcamera/color_space.h<br>
 create mode 100644 src/libcamera/color_space.cpp<br>
<br>
diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h<br>
new file mode 100644<br>
index 00000000..3d990f99<br>
--- /dev/null<br>
+++ b/include/libcamera/color_space.h<br>
@@ -0,0 +1,94 @@<br>
+/* SPDX-License-Identifier: LGPL-2.1-or-later */<br>
+/*<br>
+ * Copyright (C) 2021, Raspberry Pi (Trading) Limited<br>
+ *<br>
+ * color_space.h - color space definitions<br>
+ */<br>
+<br>
+#ifndef __LIBCAMERA_COLOR_SPACE_H__<br>
+#define __LIBCAMERA_COLOR_SPACE_H__<br>
+<br>
+#include <string><br>
+<br>
+namespace libcamera {<br>
+<br>
+class ColorSpace<br>
+{<br>
+public:<br>
+       enum class Encoding : int {<br>
+               UNDEFINED,<br>
+               RAW,<br>
+               REC601,<br>
+               REC709,<br>
+               REC2020,<br>
+               VIDEO,<br>
+       };<br>
+<br>
+       enum class TransferFunction : int {<br>
+               UNDEFINED,<br>
+               IDENTITY,<br>
+               SRGB,<br>
+               REC709,<br>
+       };<br>
+<br>
+       enum class Range : int {<br>
+               UNDEFINED,<br>
+               FULL,<br>
+               LIMITED,<br>
+       };<br>
+<br>
+       constexpr ColorSpace(Encoding e, TransferFunction t, Range r)<br>
+               : encoding(e), transferFunction(t), range(r)<br>
+       {<br>
+       }<br>
+<br>
+       constexpr ColorSpace()<br>
+               : ColorSpace(Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED)<br>
+       {<br>
+       }<br>
+<br>
+       static const ColorSpace UNDEFINED;<br>
+       static const ColorSpace RAW;<br>
+       static const ColorSpace JFIF;<br>
+       static const ColorSpace SMPTE170M;<br>
+       static const ColorSpace REC709;<br>
+       static const ColorSpace REC2020;<br>
+       static const ColorSpace VIDEO;<br>
+<br>
+       Encoding encoding;<br>
+       TransferFunction transferFunction;<br>
+       Range range;<br>
+<br>
+       bool isFullyDefined() const<br>
+       {<br>
+               return encoding != Encoding::UNDEFINED &&<br>
+                      transferFunction != TransferFunction::UNDEFINED &&<br>
+                      range != Range::UNDEFINED;<br>
+       }<br>
+<br>
+       const std::string toString() const;<br>
+};<br>
+<br>
+constexpr ColorSpace ColorSpace::UNDEFINED = { Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED };<br>
+constexpr ColorSpace ColorSpace::RAW = { Encoding::RAW, TransferFunction::IDENTITY, Range::FULL };<br>
+constexpr ColorSpace ColorSpace::JFIF = { Encoding::REC601, TransferFunction::SRGB, Range::FULL };<br>
+constexpr ColorSpace ColorSpace::SMPTE170M = { Encoding::REC601, TransferFunction::REC709, Range::LIMITED };<br>
+constexpr ColorSpace ColorSpace::REC709 = { Encoding::REC709, TransferFunction::REC709, Range::LIMITED };<br>
+constexpr ColorSpace ColorSpace::REC2020 = { Encoding::REC2020, TransferFunction::REC709, Range::LIMITED };<br>
+constexpr ColorSpace ColorSpace::VIDEO = { Encoding::VIDEO, TransferFunction::REC709, Range::LIMITED };<br>
+<br>
+static inline bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)<br>
+{<br>
+       return lhs.encoding == rhs.encoding &&<br>
+              lhs.transferFunction == rhs.transferFunction &&<br>
+              lhs.range == rhs.range;<br>
+}<br>
+<br>
+static inline bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)<br>
+{<br>
+       return !(lhs == rhs);<br>
+}<br>
+<br>
+} /* namespace libcamera */<br>
+<br>
+#endif /* __LIBCAMERA_COLOR_SPACE_H__ */<br>
diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build<br>
index 5b25ef84..7a8a04e5 100644<br>
--- a/include/libcamera/meson.build<br>
+++ b/include/libcamera/meson.build<br>
@@ -3,6 +3,7 @@<br>
 libcamera_public_headers = files([<br>
     'camera.h',<br>
     'camera_manager.h',<br>
+    'color_space.h',<br>
     'compiler.h',<br>
     'controls.h',<br>
     'file_descriptor.h',<br>
diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp<br>
new file mode 100644<br>
index 00000000..c40264db<br>
--- /dev/null<br>
+++ b/src/libcamera/color_space.cpp<br>
@@ -0,0 +1,180 @@<br>
+/* SPDX-License-Identifier: LGPL-2.1-or-later */<br>
+/*<br>
+ * Copyright (C) 2021, Raspberry Pi (Trading) Limited<br>
+ *<br>
+ * color_space.cpp - color spaces.<br>
+ */<br>
+<br>
+#include <libcamera/color_space.h><br>
+<br>
+/**<br>
+ * \file color_space.h<br>
+ * \brief Class and enums to represent colour spaces.<br>
+ */<br>
+<br>
+namespace libcamera {<br>
+<br>
+/**<br>
+ * \class ColorSpace<br>
+ * \brief Class to describe a color space.<br>
+ *<br>
+ * The color space class defines the encodings of the color primaries, the<br>
+ * transfer function associated with the color space, and the range (sometimes<br>
+ * also referred to as the quantisation) of the color space.<br>
+ *<br>
+ * Certain combinations of these fields form well-known standard color spaces,<br>
+ * such as "JFIF" or "REC709", though there is flexibility to leave some or all<br>
+ * of them undefined too.<br>
+ */<br>
+<br>
+/**<br>
+ * \enum ColorSpace::Encoding<br>
+ * \brief The encoding used for the color primaries.<br>
+ *<br>
+ * \var ColorSpace::Encoding::UNDEFINED<br>
+ * \brief The encoding for the colour primaries is not specified.<br>
+ * \var ColorSpace::Encoding::RAW<br>
+ * \brief These are raw colours from the sensor.<br>
+ * \var ColorSpace::Encoding::REC601<br>
+ * \brief REC601 colour primaries.<br>
+ * \var ColorSpace::Encoding::REC709<br>
+ * \brief Rec709 colour primaries.<br>
+ * \var ColorSpace::Encoding::REC2020<br>
+ * \brief REC2020 colour primaries.<br>
+ * \var ColorSpace::Encoding::VIDEO<br>
+ * \brief A place-holder for video streams which will be resolved to one<br>
+ * of REC601, REC709 or REC2020 once the video resolution is known.<br>
+ */<br>
+<br>
+/**<br>
+ * \enum ColorSpace::TransferFunction<br>
+ * \brief The transfer function used for this colour space.<br>
+ *<br>
+ * \var ColorSpace::TransferFunction::UNDEFINED<br>
+ * \brief The transfer function is not specified.<br>
+ * \var ColorSpace::TransferFunction::IDENTITY<br>
+ * \brief This color space uses an identity transfer function.<br>
+ * \var ColorSpace::TransferFunction::SRGB<br>
+ * \brief sRGB transfer function.<br>
+ * \var ColorSpace::TransferFunction::REC709<br>
+ * \brief Rec709 transfer function.<br>
+ */<br>
+<br>
+/**<br>
+ * \enum ColorSpace::Range<br>
+ * \brief The range (sometimes "quantisation") for this color space.<br>
+ *<br>
+ * \var ColorSpace::Range::UNDEFINED<br>
+ * \brief The range is not specified.<br>
+ * \var ColorSpace::Range::FULL<br>
+ * \brief This color space uses full range pixel values.<br>
+ * \var ColorSpace::Range::LIMITED<br>
+ * \brief This color space uses limited range pixel values.<br>
+ */<br>
+<br>
+/**<br>
+ * \fn ColorSpace::ColorSpace(Encoding e, TransferFunction t, Range r)<br>
+ * \brief Construct a ColorSpace from explicit values<br>
+ * \param[in] e The encoding for the color primaries<br>
+ * \param[in] t The transfer function for the color space<br>
+ * \param[in] r The range of the pixel values in this color space<br>
+ */<br>
+<br>
+/**<br>
+ * \fn ColorSpace::ColorSpace()<br>
+ * \brief Construct a color space with undefined encoding, transfer function<br>
+ * and range<br>
+ */<br>
+<br>
+/**<br>
+ * \fn ColorSpace::isFullyDefined() const<br>
+ * \brief Return whether all the fields of the color space are defined.<br>
+ */<br>
+<br>
+/**<br>
+ * \brief Assemble and return a readable string representation of the<br>
+ * ColorSpace<br>
+ * \return A string describing the ColorSpace<br>
+ */<br>
+const std::string ColorSpace::toString() const<br>
+{<br>
+       static const char *encodings[] = {<br>
+               "UNDEFINED",<br>
+               "RAW",<br>
+               "REC601",<br>
+               "REC709",<br>
+               "REC2020",<br>
+       };<br>
+       static const char *transferFunctions[] = {<br>
+               "UNDEFINED",<br>
+               "IDENTITY",<br>
+               "SRGB",<br>
+               "REC709",<br>
+       };<br>
+       static const char *ranges[] = {<br>
+               "UNDEFINED",<br>
+               "FULL",<br>
+               "LIMITED",<br>
+       };<br>
+<br>
+       return std::string(encodings[static_cast<int>(encoding)]) + "+" +<br>
+              std::string(transferFunctions[static_cast<int>(transferFunction)]) + "+" +<br>
+              std::string(ranges[static_cast<int>(range)]);<br>
+}<br></blockquote><div><br></div><div>Perhaps using std::stringstream would be better here?</div><div>Apart from that</div><div><br></div><div>Reviewed-by: Naushir Patuck <<a href="mailto:naush@raspberrypi.com">naush@raspberrypi.com</a>></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+/**<br>
+ * \var ColorSpace::encoding<br>
+ * \brief The encoding of the color primaries<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::transferFunction<br>
+ * \brief The transfer function for this color space.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::range<br>
+ * \brief The pixel range used by this color space.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::UNDEFINED<br>
+ * \brief A constant representing a fully undefined color space.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::RAW<br>
+ * \brief A constant representing a raw color space (from a sensor).<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::JFIF<br>
+ * \brief A constant representing the JFIF color space usually used for<br>
+ * encoding JPEG images.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::SMPTE170M<br>
+ * \brief A constant representing the SMPTE170M color space (sometimes also<br>
+ * referred to as "full range BT601").<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::REC709<br>
+ * \brief A constant representing the REC709 color space.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::REC2020<br>
+ * \brief A constant representing the REC2020 color space.<br>
+ */<br>
+<br>
+/**<br>
+ * \var ColorSpace::VIDEO<br>
+ * \brief A constant that video streams can use to indicate the "default"<br>
+ * color space for a video of this resolution, once that is is known. For<br>
+ * exmample, SD streams would interpret this as SMPTE170M, HD streams as<br>
+ * REC709 and ultra HD as REC2020.<br>
+ */<br>
+<br>
+} /* namespace libcamera */<br>
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build<br>
index 4f085801..e0748840 100644<br>
--- a/src/libcamera/meson.build<br>
+++ b/src/libcamera/meson.build<br>
@@ -8,6 +8,7 @@ libcamera_sources = files([<br>
     'camera_manager.cpp',<br>
     'camera_sensor.cpp',<br>
     'camera_sensor_properties.cpp',<br>
+    'color_space.cpp',<br>
     'controls.cpp',<br>
     'control_serializer.cpp',<br>
     'control_validator.cpp',<br>
-- <br>
2.20.1<br>
<br>
</blockquote></div></div>