From patchwork Thu Aug 5 14:21:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 13212 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 1CB5FC3237 for ; Thu, 5 Aug 2021 14:22:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CFA0368822; Thu, 5 Aug 2021 16:22:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ApWBEUIr"; dkim-atps=neutral Received: from mail-wr1-x435.google.com (mail-wr1-x435.google.com [IPv6:2a00:1450:4864:20::435]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 857E16026D for ; Thu, 5 Aug 2021 16:21:59 +0200 (CEST) Received: by mail-wr1-x435.google.com with SMTP id n12so6812773wrr.2 for ; Thu, 05 Aug 2021 07:21:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ncd5E7VqwPo5qncdQR3S7YIkVS5r9s5B2EL/AyaJzTo=; b=ApWBEUIrKy4FSvlKiZylZy8rkGUXApWpL7pNDNn1US0ORGMeisO7Sm+eLw535fILxF jrQepwxFeQt8ll1QKe5z2U6e692CLP7ziIF9Y696pVSwnNjCDnUu3NiPxDy/JEF/x+xs Lxr/bxKZujY9i6XnxqWj5GFWjgGq8D8xKmAH5bFMP4+lMWdVv7KG03Wi5obGRm3qPTMg 19iodFNWeoi5Z2zSO2Vd3yfmFCNJ5QrhNjuA38PdJ/TFwWUdgcdN/uSwV77qi8BRJTvl p0SYmEsrRhrolzEUw9ykZXMmiIyOvHbZBtUJ4fK8JpKQIoa3Z9fKze3o61qgAXydU/es QBPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ncd5E7VqwPo5qncdQR3S7YIkVS5r9s5B2EL/AyaJzTo=; b=buWgbsCAT+vnuvmyFTPSMoi3qK/0Bpt8iKEllKi1GdH0th9lQg67j1tmQX4chN9SqA 1W+/r0vYrYDFnPLY4jn8WlrcZHi0+ayQIRY46R2zZsz1zRA6unv8H80WuK3DFVgKkt7O g2Pa8ZEuzfnouRzVP1ZU0KQp7+Li0ONuG7vdjYFxqzyBND0+MCPfg+hLiGOOVzqWfhyo ngFH0Ny/1EHkv0GEumEBASwS9IoTO4Ej65JbH/o/yg5MocjxjR9TeCggMt1e8BlZGoXh k1u5IesdCTkIoT6RXCdTIB6e80AbBlXTIGxD3U2L0AaFvqWOmGyQvoEGpxGehofc4yOc mIRw== X-Gm-Message-State: AOAM532e4Mnl7efgvyP3/kEn9fmiq1gX3FulK3weZmZy2fxex7iasSGc sMTMn2MBxe5dqAQXOe5k4gg4AcNrU5KFLg== X-Google-Smtp-Source: ABdhPJxpDDhfO5jj5qqSr013rKwN23P1TDgSQlPvDFP1Xdp9jo6RTINb0U70OFJxpt2GA1c+ua78BQ== X-Received: by 2002:adf:f64b:: with SMTP id x11mr5526222wrp.155.1628173318894; Thu, 05 Aug 2021 07:21:58 -0700 (PDT) Received: from pi4-davidp.pitowers.org ([2a00:1098:3142:14:1ce1:9965:4328:89c4]) by smtp.gmail.com with ESMTPSA id k17sm6410004wrw.53.2021.08.05.07.21.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Aug 2021 07:21:58 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Thu, 5 Aug 2021 15:21:52 +0100 Message-Id: <20210805142154.20324-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20210805142154.20324-1-david.plowman@raspberrypi.com> References: <20210805142154.20324-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [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: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Reviewed-by: Naushir Patuck --- 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 + +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 + { + 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); +} + +} /* 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 + +/** + * \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(encoding)]) + "+" + + std::string(transferFunctions[static_cast(transferFunction)]) + "+" + + std::string(ranges[static_cast(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',