[{"id":18576,"web_url":"https://patchwork.libcamera.org/comment/18576/","msgid":"<CAEmqJProA4=m6+hU4E7TB67Xj6v0UaHg575xymo_MC9r4G9FKA@mail.gmail.com>","date":"2021-08-05T14:47:56","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi David,\n\nThank you for your patch.\n\nOn Thu, 5 Aug 2021 at 15:22, David Plowman <david.plowman@raspberrypi.com>\nwrote:\n\n> This class represents a colour space by defining its YCbCr encoding,\n> the transfer (gamma) function is uses, and whether the output is full\n> or limited range.\n>\n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  include/libcamera/color_space.h |  94 +++++++++++++++++\n>  include/libcamera/meson.build   |   1 +\n>  src/libcamera/color_space.cpp   | 180 ++++++++++++++++++++++++++++++++\n>  src/libcamera/meson.build       |   1 +\n>  4 files changed, 276 insertions(+)\n>  create mode 100644 include/libcamera/color_space.h\n>  create mode 100644 src/libcamera/color_space.cpp\n>\n> diff --git a/include/libcamera/color_space.h\n> b/include/libcamera/color_space.h\n> new file mode 100644\n> index 00000000..3d990f99\n> --- /dev/null\n> +++ b/include/libcamera/color_space.h\n> @@ -0,0 +1,94 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> + *\n> + * color_space.h - color space definitions\n> + */\n> +\n> +#ifndef __LIBCAMERA_COLOR_SPACE_H__\n> +#define __LIBCAMERA_COLOR_SPACE_H__\n> +\n> +#include <string>\n> +\n> +namespace libcamera {\n> +\n> +class ColorSpace\n> +{\n> +public:\n> +       enum class Encoding : int {\n> +               UNDEFINED,\n> +               RAW,\n> +               REC601,\n> +               REC709,\n> +               REC2020,\n> +               VIDEO,\n> +       };\n> +\n> +       enum class TransferFunction : int {\n> +               UNDEFINED,\n> +               IDENTITY,\n> +               SRGB,\n> +               REC709,\n> +       };\n> +\n> +       enum class Range : int {\n> +               UNDEFINED,\n> +               FULL,\n> +               LIMITED,\n> +       };\n> +\n> +       constexpr ColorSpace(Encoding e, TransferFunction t, Range r)\n> +               : encoding(e), transferFunction(t), range(r)\n> +       {\n> +       }\n> +\n> +       constexpr ColorSpace()\n> +               : ColorSpace(Encoding::UNDEFINED,\n> TransferFunction::UNDEFINED, Range::UNDEFINED)\n> +       {\n> +       }\n> +\n> +       static const ColorSpace UNDEFINED;\n> +       static const ColorSpace RAW;\n> +       static const ColorSpace JFIF;\n> +       static const ColorSpace SMPTE170M;\n> +       static const ColorSpace REC709;\n> +       static const ColorSpace REC2020;\n> +       static const ColorSpace VIDEO;\n> +\n> +       Encoding encoding;\n> +       TransferFunction transferFunction;\n> +       Range range;\n> +\n> +       bool isFullyDefined() const\n> +       {\n> +               return encoding != Encoding::UNDEFINED &&\n> +                      transferFunction != TransferFunction::UNDEFINED &&\n> +                      range != Range::UNDEFINED;\n> +       }\n> +\n> +       const std::string toString() const;\n> +};\n> +\n> +constexpr ColorSpace ColorSpace::UNDEFINED = { Encoding::UNDEFINED,\n> TransferFunction::UNDEFINED, Range::UNDEFINED };\n> +constexpr ColorSpace ColorSpace::RAW = { Encoding::RAW,\n> TransferFunction::IDENTITY, Range::FULL };\n> +constexpr ColorSpace ColorSpace::JFIF = { Encoding::REC601,\n> TransferFunction::SRGB, Range::FULL };\n> +constexpr ColorSpace ColorSpace::SMPTE170M = { Encoding::REC601,\n> TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::REC709 = { Encoding::REC709,\n> TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::REC2020 = { Encoding::REC2020,\n> TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::VIDEO = { Encoding::VIDEO,\n> TransferFunction::REC709, Range::LIMITED };\n> +\n> +static inline bool operator==(const ColorSpace &lhs, const ColorSpace\n> &rhs)\n> +{\n> +       return lhs.encoding == rhs.encoding &&\n> +              lhs.transferFunction == rhs.transferFunction &&\n> +              lhs.range == rhs.range;\n> +}\n> +\n> +static inline bool operator!=(const ColorSpace &lhs, const ColorSpace\n> &rhs)\n> +{\n> +       return !(lhs == rhs);\n> +}\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_COLOR_SPACE_H__ */\n> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> index 5b25ef84..7a8a04e5 100644\n> --- a/include/libcamera/meson.build\n> +++ b/include/libcamera/meson.build\n> @@ -3,6 +3,7 @@\n>  libcamera_public_headers = files([\n>      'camera.h',\n>      'camera_manager.h',\n> +    'color_space.h',\n>      'compiler.h',\n>      'controls.h',\n>      'file_descriptor.h',\n> diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp\n> new file mode 100644\n> index 00000000..c40264db\n> --- /dev/null\n> +++ b/src/libcamera/color_space.cpp\n> @@ -0,0 +1,180 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> + *\n> + * color_space.cpp - color spaces.\n> + */\n> +\n> +#include <libcamera/color_space.h>\n> +\n> +/**\n> + * \\file color_space.h\n> + * \\brief Class and enums to represent colour spaces.\n> + */\n> +\n> +namespace libcamera {\n> +\n> +/**\n> + * \\class ColorSpace\n> + * \\brief Class to describe a color space.\n> + *\n> + * The color space class defines the encodings of the color primaries, the\n> + * transfer function associated with the color space, and the range\n> (sometimes\n> + * also referred to as the quantisation) of the color space.\n> + *\n> + * Certain combinations of these fields form well-known standard color\n> spaces,\n> + * such as \"JFIF\" or \"REC709\", though there is flexibility to leave some\n> or all\n> + * of them undefined too.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::Encoding\n> + * \\brief The encoding used for the color primaries.\n> + *\n> + * \\var ColorSpace::Encoding::UNDEFINED\n> + * \\brief The encoding for the colour primaries is not specified.\n> + * \\var ColorSpace::Encoding::RAW\n> + * \\brief These are raw colours from the sensor.\n> + * \\var ColorSpace::Encoding::REC601\n> + * \\brief REC601 colour primaries.\n> + * \\var ColorSpace::Encoding::REC709\n> + * \\brief Rec709 colour primaries.\n> + * \\var ColorSpace::Encoding::REC2020\n> + * \\brief REC2020 colour primaries.\n> + * \\var ColorSpace::Encoding::VIDEO\n> + * \\brief A place-holder for video streams which will be resolved to one\n> + * of REC601, REC709 or REC2020 once the video resolution is known.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::TransferFunction\n> + * \\brief The transfer function used for this colour space.\n> + *\n> + * \\var ColorSpace::TransferFunction::UNDEFINED\n> + * \\brief The transfer function is not specified.\n> + * \\var ColorSpace::TransferFunction::IDENTITY\n> + * \\brief This color space uses an identity transfer function.\n> + * \\var ColorSpace::TransferFunction::SRGB\n> + * \\brief sRGB transfer function.\n> + * \\var ColorSpace::TransferFunction::REC709\n> + * \\brief Rec709 transfer function.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::Range\n> + * \\brief The range (sometimes \"quantisation\") for this color space.\n> + *\n> + * \\var ColorSpace::Range::UNDEFINED\n> + * \\brief The range is not specified.\n> + * \\var ColorSpace::Range::FULL\n> + * \\brief This color space uses full range pixel values.\n> + * \\var ColorSpace::Range::LIMITED\n> + * \\brief This color space uses limited range pixel values.\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::ColorSpace(Encoding e, TransferFunction t, Range r)\n> + * \\brief Construct a ColorSpace from explicit values\n> + * \\param[in] e The encoding for the color primaries\n> + * \\param[in] t The transfer function for the color space\n> + * \\param[in] r The range of the pixel values in this color space\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::ColorSpace()\n> + * \\brief Construct a color space with undefined encoding, transfer\n> function\n> + * and range\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::isFullyDefined() const\n> + * \\brief Return whether all the fields of the color space are defined.\n> + */\n> +\n> +/**\n> + * \\brief Assemble and return a readable string representation of the\n> + * ColorSpace\n> + * \\return A string describing the ColorSpace\n> + */\n> +const std::string ColorSpace::toString() const\n> +{\n> +       static const char *encodings[] = {\n> +               \"UNDEFINED\",\n> +               \"RAW\",\n> +               \"REC601\",\n> +               \"REC709\",\n> +               \"REC2020\",\n> +       };\n> +       static const char *transferFunctions[] = {\n> +               \"UNDEFINED\",\n> +               \"IDENTITY\",\n> +               \"SRGB\",\n> +               \"REC709\",\n> +       };\n> +       static const char *ranges[] = {\n> +               \"UNDEFINED\",\n> +               \"FULL\",\n> +               \"LIMITED\",\n> +       };\n> +\n> +       return std::string(encodings[static_cast<int>(encoding)]) + \"+\" +\n> +\n> std::string(transferFunctions[static_cast<int>(transferFunction)]) + \"+\" +\n> +              std::string(ranges[static_cast<int>(range)]);\n> +}\n>\n\nPerhaps using std::stringstream would be better here?\nApart from that\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\n> +\n> +/**\n> + * \\var ColorSpace::encoding\n> + * \\brief The encoding of the color primaries\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::transferFunction\n> + * \\brief The transfer function for this color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::range\n> + * \\brief The pixel range used by this color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::UNDEFINED\n> + * \\brief A constant representing a fully undefined color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::RAW\n> + * \\brief A constant representing a raw color space (from a sensor).\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::JFIF\n> + * \\brief A constant representing the JFIF color space usually used for\n> + * encoding JPEG images.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::SMPTE170M\n> + * \\brief A constant representing the SMPTE170M color space (sometimes\n> also\n> + * referred to as \"full range BT601\").\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::REC709\n> + * \\brief A constant representing the REC709 color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::REC2020\n> + * \\brief A constant representing the REC2020 color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::VIDEO\n> + * \\brief A constant that video streams can use to indicate the \"default\"\n> + * color space for a video of this resolution, once that is is known. For\n> + * exmample, SD streams would interpret this as SMPTE170M, HD streams as\n> + * REC709 and ultra HD as REC2020.\n> + */\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 4f085801..e0748840 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -8,6 +8,7 @@ libcamera_sources = files([\n>      'camera_manager.cpp',\n>      'camera_sensor.cpp',\n>      'camera_sensor_properties.cpp',\n> +    'color_space.cpp',\n>      'controls.cpp',\n>      'control_serializer.cpp',\n>      'control_validator.cpp',\n> --\n> 2.20.1\n>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E91E8C3235\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  5 Aug 2021 14:48:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 77E2F687CF;\n\tThu,  5 Aug 2021 16:48:14 +0200 (CEST)","from mail-lf1-x136.google.com (mail-lf1-x136.google.com\n\t[IPv6:2a00:1450:4864:20::136])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 573726026D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  5 Aug 2021 16:48:13 +0200 (CEST)","by mail-lf1-x136.google.com with SMTP id y34so11587168lfa.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 05 Aug 2021 07:48:13 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"PP8mCoth\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=ebaDg0WhIc4dChGA1ZJ7f8r2C2MIPAAv9PTCJma8efg=;\n\tb=PP8mCothn3/NTivW6ctLWA9R6jFj7TAIGyl8EDbSGeURAfpkY/Rgi+ejvKS/fmTOEq\n\tRWMe6oBlJ3hh8SJ7ykpx2hSdrO5JB+KvByQWNQizFnqkaveKRTrUON8zuR33YGyxHTEh\n\ttCvDrtNOgud5muTBf2JPl+4Eu3SmdqvZfiU5OxB/J1i+tRx8W6Iw+USEHytGOe5LXEul\n\tOd58D23/LM9TooFxB1MKVPHCAfbtAZyYwwqT+CxHz4ezwvt0QYhVlN3DNeGIVptxW88m\n\tsr5S9G6qqRUmrL8fM6Kly5Xeb8ZM7LB1yMZjowuraZeQYc1i3H514Z/GYFNXKNFeiZI+\n\tsDdA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=ebaDg0WhIc4dChGA1ZJ7f8r2C2MIPAAv9PTCJma8efg=;\n\tb=r/T7apYv9xEy08YEQ+kivKP5kUmH24RhVVhDqCWQ/715tL1siyP91OSaEudQxzAebI\n\tFLjtIngicDApCpS/f8vHq7NhiEBYnzlViiiayk0SwiJhDJGJvrD1B/SiyLz/VzYgsMTh\n\t+9It+84wUIpVHvJ+Wu9Y2mCGJXVR5sLFl86RmdaUnRsqIQwhYuJgxsrrcLVBKL+b0d5g\n\ta+e1yNVfasekf1E0lrzJriDkMjvqA9ROqzgRyPu2e+zQUeBhzpzQfPLWYMAAM/1dM6VS\n\tmby2O6p6G4ddp9V1Yn4A81aV/aOUzsrvEBtrUPSZl2RsTYU2cs3/HuRETze+6A2Mz3Cd\n\tirMA==","X-Gm-Message-State":"AOAM531SXl59qw4PdZwtRlxosmHXInbTnF5EDm1jDX7WPOZYdiXm8Fxt\n\tqC72PV6XsEXycyrmGF0ccNSRmvsRmVBJvAXQl3BTRA==","X-Google-Smtp-Source":"ABdhPJwEA8ckzqo3irtHz4cOtfV5+zWGG0DMQW4KwNUHJgyHLIaGlSS84HGLDcKaWOH6XDOAIGe84vfa0bDELuxOQ98=","X-Received":"by 2002:a05:6512:22d3:: with SMTP id\n\tg19mr3783615lfu.171.1628174892515; \n\tThu, 05 Aug 2021 07:48:12 -0700 (PDT)","MIME-Version":"1.0","References":"<20210805142154.20324-1-david.plowman@raspberrypi.com>\n\t<20210805142154.20324-2-david.plowman@raspberrypi.com>","In-Reply-To":"<20210805142154.20324-2-david.plowman@raspberrypi.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Thu, 5 Aug 2021 15:47:56 +0100","Message-ID":"<CAEmqJProA4=m6+hU4E7TB67Xj6v0UaHg575xymo_MC9r4G9FKA@mail.gmail.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Content-Type":"multipart/alternative; boundary=\"00000000000019d4bf05c8d102bd\"","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":19800,"web_url":"https://patchwork.libcamera.org/comment/19800/","msgid":"<20210923062110.GM4382@pyrite.rasen.tech>","date":"2021-09-23T06:21:10","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Hi David,\n\nThanks for the patch.\n\nOn Thu, Aug 05, 2021 at 03:21:52PM +0100, David Plowman wrote:\n> This class represents a colour space by defining its YCbCr encoding,\n> the transfer (gamma) function is uses, and whether the output is full\n> or limited range.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  include/libcamera/color_space.h |  94 +++++++++++++++++\n>  include/libcamera/meson.build   |   1 +\n>  src/libcamera/color_space.cpp   | 180 ++++++++++++++++++++++++++++++++\n>  src/libcamera/meson.build       |   1 +\n>  4 files changed, 276 insertions(+)\n>  create mode 100644 include/libcamera/color_space.h\n>  create mode 100644 src/libcamera/color_space.cpp\n> \n> diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h\n> new file mode 100644\n> index 00000000..3d990f99\n> --- /dev/null\n> +++ b/include/libcamera/color_space.h\n> @@ -0,0 +1,94 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> + *\n> + * color_space.h - color space definitions\n> + */\n> +\n> +#ifndef __LIBCAMERA_COLOR_SPACE_H__\n> +#define __LIBCAMERA_COLOR_SPACE_H__\n> +\n> +#include <string>\n> +\n> +namespace libcamera {\n> +\n> +class ColorSpace\n> +{\n> +public:\n> +\tenum class Encoding : int {\n> +\t\tUNDEFINED,\n> +\t\tRAW,\n> +\t\tREC601,\n> +\t\tREC709,\n> +\t\tREC2020,\n> +\t\tVIDEO,\n> +\t};\n> +\n> +\tenum class TransferFunction : int {\n> +\t\tUNDEFINED,\n> +\t\tIDENTITY,\n> +\t\tSRGB,\n> +\t\tREC709,\n> +\t};\n> +\n> +\tenum class Range : int {\n> +\t\tUNDEFINED,\n> +\t\tFULL,\n> +\t\tLIMITED,\n> +\t};\n\nI suppose we'll just ignore the other values that V4L2 has that we don't\nhave?\n\n> +\n> +\tconstexpr ColorSpace(Encoding e, TransferFunction t, Range r)\n> +\t\t: encoding(e), transferFunction(t), range(r)\n> +\t{\n> +\t}\n> +\n> +\tconstexpr ColorSpace()\n> +\t\t: ColorSpace(Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED)\n> +\t{\n> +\t}\n> +\n> +\tstatic const ColorSpace UNDEFINED;\n> +\tstatic const ColorSpace RAW;\n> +\tstatic const ColorSpace JFIF;\n> +\tstatic const ColorSpace SMPTE170M;\n> +\tstatic const ColorSpace REC709;\n> +\tstatic const ColorSpace REC2020;\n> +\tstatic const ColorSpace VIDEO;\n> +\n> +\tEncoding encoding;\n> +\tTransferFunction transferFunction;\n> +\tRange range;\n> +\n> +\tbool isFullyDefined() const\n> +\t{\n> +\t\treturn encoding != Encoding::UNDEFINED &&\n> +\t\t       transferFunction != TransferFunction::UNDEFINED &&\n> +\t\t       range != Range::UNDEFINED;\n> +\t}\n> +\n> +\tconst std::string toString() const;\n> +};\n> +\n> +constexpr ColorSpace ColorSpace::UNDEFINED = { Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED };\n> +constexpr ColorSpace ColorSpace::RAW = { Encoding::RAW, TransferFunction::IDENTITY, Range::FULL };\n> +constexpr ColorSpace ColorSpace::JFIF = { Encoding::REC601, TransferFunction::SRGB, Range::FULL };\n> +constexpr ColorSpace ColorSpace::SMPTE170M = { Encoding::REC601, TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::REC709 = { Encoding::REC709, TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::REC2020 = { Encoding::REC2020, TransferFunction::REC709, Range::LIMITED };\n> +constexpr ColorSpace ColorSpace::VIDEO = { Encoding::VIDEO, TransferFunction::REC709, Range::LIMITED };\n> +\n> +static inline bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)\n> +{\n> +\treturn lhs.encoding == rhs.encoding &&\n> +\t       lhs.transferFunction == rhs.transferFunction &&\n> +\t       lhs.range == rhs.range;\n> +}\n> +\n> +static inline bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)\n> +{\n> +\treturn !(lhs == rhs);\n> +}\n\nWhat's wrong with putting these two functions in the cpp file, and\nleaving a funtion prototype in the class definition?\n\nOtherwise, looks good to me.\n\n\nPaul\n\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_COLOR_SPACE_H__ */\n> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> index 5b25ef84..7a8a04e5 100644\n> --- a/include/libcamera/meson.build\n> +++ b/include/libcamera/meson.build\n> @@ -3,6 +3,7 @@\n>  libcamera_public_headers = files([\n>      'camera.h',\n>      'camera_manager.h',\n> +    'color_space.h',\n>      'compiler.h',\n>      'controls.h',\n>      'file_descriptor.h',\n> diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp\n> new file mode 100644\n> index 00000000..c40264db\n> --- /dev/null\n> +++ b/src/libcamera/color_space.cpp\n> @@ -0,0 +1,180 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> + *\n> + * color_space.cpp - color spaces.\n> + */\n> +\n> +#include <libcamera/color_space.h>\n> +\n> +/**\n> + * \\file color_space.h\n> + * \\brief Class and enums to represent colour spaces.\n> + */\n> +\n> +namespace libcamera {\n> +\n> +/**\n> + * \\class ColorSpace\n> + * \\brief Class to describe a color space.\n> + *\n> + * The color space class defines the encodings of the color primaries, the\n> + * transfer function associated with the color space, and the range (sometimes\n> + * also referred to as the quantisation) of the color space.\n> + *\n> + * Certain combinations of these fields form well-known standard color spaces,\n> + * such as \"JFIF\" or \"REC709\", though there is flexibility to leave some or all\n> + * of them undefined too.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::Encoding\n> + * \\brief The encoding used for the color primaries.\n> + *\n> + * \\var ColorSpace::Encoding::UNDEFINED\n> + * \\brief The encoding for the colour primaries is not specified.\n> + * \\var ColorSpace::Encoding::RAW\n> + * \\brief These are raw colours from the sensor.\n> + * \\var ColorSpace::Encoding::REC601\n> + * \\brief REC601 colour primaries.\n> + * \\var ColorSpace::Encoding::REC709\n> + * \\brief Rec709 colour primaries.\n> + * \\var ColorSpace::Encoding::REC2020\n> + * \\brief REC2020 colour primaries.\n> + * \\var ColorSpace::Encoding::VIDEO\n> + * \\brief A place-holder for video streams which will be resolved to one\n> + * of REC601, REC709 or REC2020 once the video resolution is known.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::TransferFunction\n> + * \\brief The transfer function used for this colour space.\n> + *\n> + * \\var ColorSpace::TransferFunction::UNDEFINED\n> + * \\brief The transfer function is not specified.\n> + * \\var ColorSpace::TransferFunction::IDENTITY\n> + * \\brief This color space uses an identity transfer function.\n> + * \\var ColorSpace::TransferFunction::SRGB\n> + * \\brief sRGB transfer function.\n> + * \\var ColorSpace::TransferFunction::REC709\n> + * \\brief Rec709 transfer function.\n> + */\n> +\n> +/**\n> + * \\enum ColorSpace::Range\n> + * \\brief The range (sometimes \"quantisation\") for this color space.\n> + *\n> + * \\var ColorSpace::Range::UNDEFINED\n> + * \\brief The range is not specified.\n> + * \\var ColorSpace::Range::FULL\n> + * \\brief This color space uses full range pixel values.\n> + * \\var ColorSpace::Range::LIMITED\n> + * \\brief This color space uses limited range pixel values.\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::ColorSpace(Encoding e, TransferFunction t, Range r)\n> + * \\brief Construct a ColorSpace from explicit values\n> + * \\param[in] e The encoding for the color primaries\n> + * \\param[in] t The transfer function for the color space\n> + * \\param[in] r The range of the pixel values in this color space\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::ColorSpace()\n> + * \\brief Construct a color space with undefined encoding, transfer function\n> + * and range\n> + */\n> +\n> +/**\n> + * \\fn ColorSpace::isFullyDefined() const\n> + * \\brief Return whether all the fields of the color space are defined.\n> + */\n> +\n> +/**\n> + * \\brief Assemble and return a readable string representation of the\n> + * ColorSpace\n> + * \\return A string describing the ColorSpace\n> + */\n> +const std::string ColorSpace::toString() const\n> +{\n> +\tstatic const char *encodings[] = {\n> +\t\t\"UNDEFINED\",\n> +\t\t\"RAW\",\n> +\t\t\"REC601\",\n> +\t\t\"REC709\",\n> +\t\t\"REC2020\",\n> +\t};\n> +\tstatic const char *transferFunctions[] = {\n> +\t\t\"UNDEFINED\",\n> +\t\t\"IDENTITY\",\n> +\t\t\"SRGB\",\n> +\t\t\"REC709\",\n> +\t};\n> +\tstatic const char *ranges[] = {\n> +\t\t\"UNDEFINED\",\n> +\t\t\"FULL\",\n> +\t\t\"LIMITED\",\n> +\t};\n> +\n> +\treturn std::string(encodings[static_cast<int>(encoding)]) + \"+\" +\n> +\t       std::string(transferFunctions[static_cast<int>(transferFunction)]) + \"+\" +\n> +\t       std::string(ranges[static_cast<int>(range)]);\n> +}\n> +\n> +/**\n> + * \\var ColorSpace::encoding\n> + * \\brief The encoding of the color primaries\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::transferFunction\n> + * \\brief The transfer function for this color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::range\n> + * \\brief The pixel range used by this color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::UNDEFINED\n> + * \\brief A constant representing a fully undefined color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::RAW\n> + * \\brief A constant representing a raw color space (from a sensor).\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::JFIF\n> + * \\brief A constant representing the JFIF color space usually used for\n> + * encoding JPEG images.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::SMPTE170M\n> + * \\brief A constant representing the SMPTE170M color space (sometimes also\n> + * referred to as \"full range BT601\").\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::REC709\n> + * \\brief A constant representing the REC709 color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::REC2020\n> + * \\brief A constant representing the REC2020 color space.\n> + */\n> +\n> +/**\n> + * \\var ColorSpace::VIDEO\n> + * \\brief A constant that video streams can use to indicate the \"default\"\n> + * color space for a video of this resolution, once that is is known. For\n> + * exmample, SD streams would interpret this as SMPTE170M, HD streams as\n> + * REC709 and ultra HD as REC2020.\n> + */\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index 4f085801..e0748840 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -8,6 +8,7 @@ libcamera_sources = files([\n>      'camera_manager.cpp',\n>      'camera_sensor.cpp',\n>      'camera_sensor_properties.cpp',\n> +    'color_space.cpp',\n>      'controls.cpp',\n>      'control_serializer.cpp',\n>      'control_validator.cpp',\n> -- \n> 2.20.1\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 54F68BF01C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Sep 2021 06:21:21 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 29F5669186;\n\tThu, 23 Sep 2021 08:21:20 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EDBBB60245\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Sep 2021 08:21:17 +0200 (CEST)","from pyrite.rasen.tech (unknown\n\t[IPv6:2400:4051:61:600:2c71:1b79:d06d:5032])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 8965445E;\n\tThu, 23 Sep 2021 08:21:16 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"bhhpSz/m\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1632378077;\n\tbh=26fdpZBt5WlzcQos5eUzeRDUaJXhoQu/gNIJ0A7wSLA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bhhpSz/mSDUKa/833UWxTC2Q00fER3e1ze8bFOAoLzLC6BmSeyR+vQJJd1tTUljb5\n\tBvwLdMxe8w0v7AnF+ZGvViMVntigCJkOuqoXQXqHmiwBP4d/X/21FAJW9axzJjWP59\n\tphxLvTDpxF1wFmYmz28FgdmBpA/5szI2aVZsKJ1s=","Date":"Thu, 23 Sep 2021 15:21:10 +0900","From":"paul.elder@ideasonboard.com","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<20210923062110.GM4382@pyrite.rasen.tech>","References":"<20210805142154.20324-1-david.plowman@raspberrypi.com>\n\t<20210805142154.20324-2-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20210805142154.20324-2-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":20070,"web_url":"https://patchwork.libcamera.org/comment/20070/","msgid":"<YVxIySG1OFDKiU7J@pendragon.ideasonboard.com>","date":"2021-10-05T12:44:57","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Paul,\n\nOn Thu, Sep 23, 2021 at 03:21:10PM +0900, paul.elder@ideasonboard.com wrote:\n> On Thu, Aug 05, 2021 at 03:21:52PM +0100, David Plowman wrote:\n> > This class represents a colour space by defining its YCbCr encoding,\n> > the transfer (gamma) function is uses, and whether the output is full\n> > or limited range.\n> > \n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n> >  include/libcamera/color_space.h |  94 +++++++++++++++++\n> >  include/libcamera/meson.build   |   1 +\n> >  src/libcamera/color_space.cpp   | 180 ++++++++++++++++++++++++++++++++\n> >  src/libcamera/meson.build       |   1 +\n> >  4 files changed, 276 insertions(+)\n> >  create mode 100644 include/libcamera/color_space.h\n> >  create mode 100644 src/libcamera/color_space.cpp\n> > \n> > diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h\n> > new file mode 100644\n> > index 00000000..3d990f99\n> > --- /dev/null\n> > +++ b/include/libcamera/color_space.h\n> > @@ -0,0 +1,94 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> > + *\n> > + * color_space.h - color space definitions\n> > + */\n> > +\n> > +#ifndef __LIBCAMERA_COLOR_SPACE_H__\n> > +#define __LIBCAMERA_COLOR_SPACE_H__\n> > +\n> > +#include <string>\n> > +\n> > +namespace libcamera {\n> > +\n> > +class ColorSpace\n> > +{\n> > +public:\n> > +\tenum class Encoding : int {\n> > +\t\tUNDEFINED,\n> > +\t\tRAW,\n> > +\t\tREC601,\n> > +\t\tREC709,\n> > +\t\tREC2020,\n> > +\t\tVIDEO,\n> > +\t};\n> > +\n> > +\tenum class TransferFunction : int {\n> > +\t\tUNDEFINED,\n> > +\t\tIDENTITY,\n> > +\t\tSRGB,\n> > +\t\tREC709,\n> > +\t};\n> > +\n> > +\tenum class Range : int {\n> > +\t\tUNDEFINED,\n> > +\t\tFULL,\n> > +\t\tLIMITED,\n> > +\t};\n> \n> I suppose we'll just ignore the other values that V4L2 has that we don't\n> have?\n> \n> > +\n> > +\tconstexpr ColorSpace(Encoding e, TransferFunction t, Range r)\n> > +\t\t: encoding(e), transferFunction(t), range(r)\n> > +\t{\n> > +\t}\n> > +\n> > +\tconstexpr ColorSpace()\n> > +\t\t: ColorSpace(Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED)\n> > +\t{\n> > +\t}\n> > +\n> > +\tstatic const ColorSpace UNDEFINED;\n> > +\tstatic const ColorSpace RAW;\n> > +\tstatic const ColorSpace JFIF;\n> > +\tstatic const ColorSpace SMPTE170M;\n> > +\tstatic const ColorSpace REC709;\n> > +\tstatic const ColorSpace REC2020;\n> > +\tstatic const ColorSpace VIDEO;\n> > +\n> > +\tEncoding encoding;\n> > +\tTransferFunction transferFunction;\n> > +\tRange range;\n> > +\n> > +\tbool isFullyDefined() const\n> > +\t{\n> > +\t\treturn encoding != Encoding::UNDEFINED &&\n> > +\t\t       transferFunction != TransferFunction::UNDEFINED &&\n> > +\t\t       range != Range::UNDEFINED;\n> > +\t}\n> > +\n> > +\tconst std::string toString() const;\n> > +};\n> > +\n> > +constexpr ColorSpace ColorSpace::UNDEFINED = { Encoding::UNDEFINED, TransferFunction::UNDEFINED, Range::UNDEFINED };\n> > +constexpr ColorSpace ColorSpace::RAW = { Encoding::RAW, TransferFunction::IDENTITY, Range::FULL };\n> > +constexpr ColorSpace ColorSpace::JFIF = { Encoding::REC601, TransferFunction::SRGB, Range::FULL };\n> > +constexpr ColorSpace ColorSpace::SMPTE170M = { Encoding::REC601, TransferFunction::REC709, Range::LIMITED };\n> > +constexpr ColorSpace ColorSpace::REC709 = { Encoding::REC709, TransferFunction::REC709, Range::LIMITED };\n> > +constexpr ColorSpace ColorSpace::REC2020 = { Encoding::REC2020, TransferFunction::REC709, Range::LIMITED };\n> > +constexpr ColorSpace ColorSpace::VIDEO = { Encoding::VIDEO, TransferFunction::REC709, Range::LIMITED };\n> > +\n> > +static inline bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)\n> > +{\n> > +\treturn lhs.encoding == rhs.encoding &&\n> > +\t       lhs.transferFunction == rhs.transferFunction &&\n> > +\t       lhs.range == rhs.range;\n> > +}\n> > +\n> > +static inline bool operator!=(const ColorSpace &lhs, const ColorSpace &rhs)\n> > +{\n> > +\treturn !(lhs == rhs);\n> > +}\n> \n> What's wrong with putting these two functions in the cpp file, and\n> leaving a funtion prototype in the class definition?\n\nIt's a matter of inlining. For operator!=(), for instance, there should\nbe very little (or no ?) drawback to inlining it, it won't increase code\nsize, the compiler will be able to optimize it, and there should be no\nbackward compatibility concerns as I don't see how the function\ndefinition could change.\n\n(On a side note, I wish we could use the C++20 spaceship <=>)\n\n> Otherwise, looks good to me.\n> \n> > +\n> > +} /* namespace libcamera */\n> > +\n> > +#endif /* __LIBCAMERA_COLOR_SPACE_H__ */\n> > diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> > index 5b25ef84..7a8a04e5 100644\n> > --- a/include/libcamera/meson.build\n> > +++ b/include/libcamera/meson.build\n> > @@ -3,6 +3,7 @@\n> >  libcamera_public_headers = files([\n> >      'camera.h',\n> >      'camera_manager.h',\n> > +    'color_space.h',\n> >      'compiler.h',\n> >      'controls.h',\n> >      'file_descriptor.h',\n> > diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp\n> > new file mode 100644\n> > index 00000000..c40264db\n> > --- /dev/null\n> > +++ b/src/libcamera/color_space.cpp\n> > @@ -0,0 +1,180 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2021, Raspberry Pi (Trading) Limited\n> > + *\n> > + * color_space.cpp - color spaces.\n> > + */\n> > +\n> > +#include <libcamera/color_space.h>\n> > +\n> > +/**\n> > + * \\file color_space.h\n> > + * \\brief Class and enums to represent colour spaces.\n> > + */\n> > +\n> > +namespace libcamera {\n> > +\n> > +/**\n> > + * \\class ColorSpace\n> > + * \\brief Class to describe a color space.\n> > + *\n> > + * The color space class defines the encodings of the color primaries, the\n> > + * transfer function associated with the color space, and the range (sometimes\n> > + * also referred to as the quantisation) of the color space.\n> > + *\n> > + * Certain combinations of these fields form well-known standard color spaces,\n> > + * such as \"JFIF\" or \"REC709\", though there is flexibility to leave some or all\n> > + * of them undefined too.\n> > + */\n> > +\n> > +/**\n> > + * \\enum ColorSpace::Encoding\n> > + * \\brief The encoding used for the color primaries.\n> > + *\n> > + * \\var ColorSpace::Encoding::UNDEFINED\n> > + * \\brief The encoding for the colour primaries is not specified.\n> > + * \\var ColorSpace::Encoding::RAW\n> > + * \\brief These are raw colours from the sensor.\n> > + * \\var ColorSpace::Encoding::REC601\n> > + * \\brief REC601 colour primaries.\n> > + * \\var ColorSpace::Encoding::REC709\n> > + * \\brief Rec709 colour primaries.\n> > + * \\var ColorSpace::Encoding::REC2020\n> > + * \\brief REC2020 colour primaries.\n> > + * \\var ColorSpace::Encoding::VIDEO\n> > + * \\brief A place-holder for video streams which will be resolved to one\n> > + * of REC601, REC709 or REC2020 once the video resolution is known.\n> > + */\n> > +\n> > +/**\n> > + * \\enum ColorSpace::TransferFunction\n> > + * \\brief The transfer function used for this colour space.\n> > + *\n> > + * \\var ColorSpace::TransferFunction::UNDEFINED\n> > + * \\brief The transfer function is not specified.\n> > + * \\var ColorSpace::TransferFunction::IDENTITY\n> > + * \\brief This color space uses an identity transfer function.\n> > + * \\var ColorSpace::TransferFunction::SRGB\n> > + * \\brief sRGB transfer function.\n> > + * \\var ColorSpace::TransferFunction::REC709\n> > + * \\brief Rec709 transfer function.\n> > + */\n> > +\n> > +/**\n> > + * \\enum ColorSpace::Range\n> > + * \\brief The range (sometimes \"quantisation\") for this color space.\n> > + *\n> > + * \\var ColorSpace::Range::UNDEFINED\n> > + * \\brief The range is not specified.\n> > + * \\var ColorSpace::Range::FULL\n> > + * \\brief This color space uses full range pixel values.\n> > + * \\var ColorSpace::Range::LIMITED\n> > + * \\brief This color space uses limited range pixel values.\n> > + */\n> > +\n> > +/**\n> > + * \\fn ColorSpace::ColorSpace(Encoding e, TransferFunction t, Range r)\n> > + * \\brief Construct a ColorSpace from explicit values\n> > + * \\param[in] e The encoding for the color primaries\n> > + * \\param[in] t The transfer function for the color space\n> > + * \\param[in] r The range of the pixel values in this color space\n> > + */\n> > +\n> > +/**\n> > + * \\fn ColorSpace::ColorSpace()\n> > + * \\brief Construct a color space with undefined encoding, transfer function\n> > + * and range\n> > + */\n> > +\n> > +/**\n> > + * \\fn ColorSpace::isFullyDefined() const\n> > + * \\brief Return whether all the fields of the color space are defined.\n> > + */\n> > +\n> > +/**\n> > + * \\brief Assemble and return a readable string representation of the\n> > + * ColorSpace\n> > + * \\return A string describing the ColorSpace\n> > + */\n> > +const std::string ColorSpace::toString() const\n> > +{\n> > +\tstatic const char *encodings[] = {\n> > +\t\t\"UNDEFINED\",\n> > +\t\t\"RAW\",\n> > +\t\t\"REC601\",\n> > +\t\t\"REC709\",\n> > +\t\t\"REC2020\",\n> > +\t};\n> > +\tstatic const char *transferFunctions[] = {\n> > +\t\t\"UNDEFINED\",\n> > +\t\t\"IDENTITY\",\n> > +\t\t\"SRGB\",\n> > +\t\t\"REC709\",\n> > +\t};\n> > +\tstatic const char *ranges[] = {\n> > +\t\t\"UNDEFINED\",\n> > +\t\t\"FULL\",\n> > +\t\t\"LIMITED\",\n> > +\t};\n> > +\n> > +\treturn std::string(encodings[static_cast<int>(encoding)]) + \"+\" +\n> > +\t       std::string(transferFunctions[static_cast<int>(transferFunction)]) + \"+\" +\n> > +\t       std::string(ranges[static_cast<int>(range)]);\n> > +}\n> > +\n> > +/**\n> > + * \\var ColorSpace::encoding\n> > + * \\brief The encoding of the color primaries\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::transferFunction\n> > + * \\brief The transfer function for this color space.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::range\n> > + * \\brief The pixel range used by this color space.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::UNDEFINED\n> > + * \\brief A constant representing a fully undefined color space.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::RAW\n> > + * \\brief A constant representing a raw color space (from a sensor).\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::JFIF\n> > + * \\brief A constant representing the JFIF color space usually used for\n> > + * encoding JPEG images.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::SMPTE170M\n> > + * \\brief A constant representing the SMPTE170M color space (sometimes also\n> > + * referred to as \"full range BT601\").\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::REC709\n> > + * \\brief A constant representing the REC709 color space.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::REC2020\n> > + * \\brief A constant representing the REC2020 color space.\n> > + */\n> > +\n> > +/**\n> > + * \\var ColorSpace::VIDEO\n> > + * \\brief A constant that video streams can use to indicate the \"default\"\n> > + * color space for a video of this resolution, once that is is known. For\n> > + * exmample, SD streams would interpret this as SMPTE170M, HD streams as\n> > + * REC709 and ultra HD as REC2020.\n> > + */\n> > +\n> > +} /* namespace libcamera */\n> > diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> > index 4f085801..e0748840 100644\n> > --- a/src/libcamera/meson.build\n> > +++ b/src/libcamera/meson.build\n> > @@ -8,6 +8,7 @@ libcamera_sources = files([\n> >      'camera_manager.cpp',\n> >      'camera_sensor.cpp',\n> >      'camera_sensor_properties.cpp',\n> > +    'color_space.cpp',\n> >      'controls.cpp',\n> >      'control_serializer.cpp',\n> >      'control_validator.cpp',","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 135EAC3243\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  5 Oct 2021 12:45:07 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 80ADB691B7;\n\tTue,  5 Oct 2021 14:45:06 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B475684C6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  5 Oct 2021 14:45:05 +0200 (CEST)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id AE72525B;\n\tTue,  5 Oct 2021 14:45:04 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Lqp9wAt7\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1633437904;\n\tbh=o35+i+wX9TtanS5FaMdvToNe0CCM7onO9EAhSLk8UQ8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Lqp9wAt7hSEvG/ngRxoyUvjll02b177zvNRDPCgCCHjECbge6rdLc3dvJAkg8ubYX\n\t6UKKcLMAfduzzeXTjBVo8Mh/tdmTDN+CNc3evrnUsHfCkX8tUuuShSu4JDWLKJ7TAc\n\tGByb0nbCd99Wk8fggcj04Ba/OrU0FAd1Y2mE+Vg8=","Date":"Tue, 5 Oct 2021 15:44:57 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"paul.elder@ideasonboard.com","Message-ID":"<YVxIySG1OFDKiU7J@pendragon.ideasonboard.com>","References":"<20210805142154.20324-1-david.plowman@raspberrypi.com>\n\t<20210805142154.20324-2-david.plowman@raspberrypi.com>\n\t<20210923062110.GM4382@pyrite.rasen.tech>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20210923062110.GM4382@pyrite.rasen.tech>","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: Add ColorSpace class","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]