[libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class
paul.elder at ideasonboard.com
paul.elder at ideasonboard.com
Thu Sep 23 08:21:10 CEST 2021
Hi David,
Thanks for the patch.
On Thu, Aug 05, 2021 at 03:21:52PM +0100, David Plowman wrote:
> 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 | 94 +++++++++++++++++
> include/libcamera/meson.build | 1 +
> src/libcamera/color_space.cpp | 180 ++++++++++++++++++++++++++++++++
> src/libcamera/meson.build | 1 +
> 4 files changed, 276 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..3d990f99
> --- /dev/null
> +++ b/include/libcamera/color_space.h
> @@ -0,0 +1,94 @@
> +/* 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,
> + };
I suppose we'll just ignore the other values that V4L2 has that we don't
have?
> +
> + 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
> + {
> + return encoding != Encoding::UNDEFINED &&
> + transferFunction != TransferFunction::UNDEFINED &&
> + range != Range::UNDEFINED;
> + }
> +
> + 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 };
> +
> +static inline bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
> +{
> + return lhs.encoding == rhs.encoding &&
> + lhs.transferFunction == rhs.transferFunction &&
> + lhs.range == rhs.range;
> +}
> +
> +static inline bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)
> +{
> + return !(lhs == rhs);
> +}
What's wrong with putting these two functions in the cpp file, and
leaving a funtion prototype in the class definition?
Otherwise, looks good to me.
Paul
> +
> +} /* 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..c40264db
> --- /dev/null
> +++ b/src/libcamera/color_space.cpp
> @@ -0,0 +1,180 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2021, Raspberry Pi (Trading) Limited
> + *
> + * color_space.cpp - color spaces.
> + */
> +
> +#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
> + */
> +
> +/**
> + * \fn ColorSpace::isFullyDefined() const
> + * \brief Return whether all the fields of the color space are defined.
> + */
> +
> +/**
> + * \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",
> + };
> +
> + return std::string(encodings[static_cast<int>(encoding)]) + "+" +
> + std::string(transferFunctions[static_cast<int>(transferFunction)]) + "+" +
> + std::string(ranges[static_cast<int>(range)]);
> +}
> +
> +/**
> + * \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.
> + */
> +
> +} /* namespace libcamera */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 4f085801..e0748840 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