From patchwork Tue Aug 23 17:43:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17187 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 066FEC0DA4 for ; Tue, 23 Aug 2022 17:43:25 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9D06761FC6; Tue, 23 Aug 2022 19:43:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276604; bh=AIqh8KnQAwpofCVdLbbi6JYWl9cUMSB1QZZKu/dFNTo=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=xQbw+9xpwrxZ9OmWgjcA7CSZGpdyEYEBwHyxbwpazOuWrI/n7LWrUhbb1JI+sV+vc AJ5Q6O3o/nppdLwOZ1iVdETlAN8rWf7wbEAQ3H7b5wGiFVnhG42GiM+qFmX2NwTZ3u ACJjg+jvQIha2P3O375V+iHSODJ3zEvNfi1uhINVSVlNMTCIBWuOOtE6uPjI1mZiR2 cvepVbhtlxi0Hc7tDnAZk9NjW0SVT7gg0A5Mrl+fgQc5xkodPh516frYsykbqx4Zj9 wcCe3wxljJvqL2hUsQXlciaTdnYSouSo9IMDHLuWX6B3dEGPZpHppHxx1IWA7iLX+S a/5CRjmjvV6pg== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 85EE661FA1 for ; Tue, 23 Aug 2022 19:43:21 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="mHbjLnFd"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 147212B3 for ; Tue, 23 Aug 2022 19:43:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276601; bh=AIqh8KnQAwpofCVdLbbi6JYWl9cUMSB1QZZKu/dFNTo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=mHbjLnFdS22MG60nAjudtxylxa8rd4JZmeDqAskWgozbAXu59ESYflUY3gc8x0Pht Fz8YZGk1jQp5C/k+3hwhNNuETgHNOCuUVB3Ddtkm41lw+XeIl4mYvqBxuAFXFXnUeA 73YAQUutbMGk50hble6ycbHWC7egHSvGIHiNzFHs= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:09 +0300 Message-Id: <20220823174314.14881-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/6] utils: Satisfy LegacyInputIterator with StringSplitter::iterator 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The StringSplitter::iterator is used with the utils::split() function to iterate over components of a split string. Add the necessary member types expected by std::iterator_trait in order to satisfy the LegacyInputIterator requirement and make the iterator usable in constructors for various containers. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain Reviewed-by: Paul Elder --- include/libcamera/base/utils.h | 6 ++++++ test/utils.cpp | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h index 889bb4a2270e..ed88b7163770 100644 --- a/include/libcamera/base/utils.h +++ b/include/libcamera/base/utils.h @@ -170,6 +170,12 @@ public: class iterator { public: + using difference_type = std::size_t; + using value_type = std::string; + using pointer = value_type *; + using reference = value_type &; + using iterator_category = std::input_iterator_tag; + iterator(const StringSplitter *ss, std::string::size_type pos); iterator &operator++(); diff --git a/test/utils.cpp b/test/utils.cpp index 129807a63ec6..58b5a59dd17d 100644 --- a/test/utils.cpp +++ b/test/utils.cpp @@ -276,6 +276,14 @@ protected: return TestFail; } + const auto &split = utils::split(path, ":"); + dirs = std::vector{ split.begin(), split.end() }; + + if (dirs != elements) { + cerr << "utils::split() LegacyInputIterator test failed" << endl; + return TestFail; + } + /* utils::join() with conversion function test. */ std::vector sizes = { { 0, 0 }, { 100, 100 } }; s = utils::join(sizes, "/", [](const Size &size) { From patchwork Tue Aug 23 17:43:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17188 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 5FC27C327D for ; Tue, 23 Aug 2022 17:43:26 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BF31561FC8; Tue, 23 Aug 2022 19:43:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276605; bh=Oh0AzzCP/2ZLxH8JAjx6bwvDB0Ud+PZUBvRC08ZUfg8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=VXY6j/JaSnp9XqU7w+gLcdjaj33VYRi8mJt4Ph9U26fqFZ185voFciTOpqKhldZ51 M+I6bySUaZl5dvbLp0E7M9SU7N9KtVvf2qN1DA149iKltIyKFPKjlgCyl6cRgA0PDR YGu3eTItWoieM8KAtk7tIOtaectif0le2tOaQug7mZ2TDsIWXLpFY2YLD555pW6qsH 8DTdIQ3wiaLHyHI71tDDd0U/h7MkOIPxHXYbWdIPapV+sSn9BUR2MVJoBhl1g47Jm0 kV0s6qJt/nU1I1HZrwSUcC8VNL2ctd2aLCrthYSg3qLxzDqc7LsfBeO7O6fsaa+iMP CgcHeEYBjvwfQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 12D4B61FA1 for ; Tue, 23 Aug 2022 19:43:23 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="gqyx01s8"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 931EB2B3 for ; Tue, 23 Aug 2022 19:43:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276602; bh=Oh0AzzCP/2ZLxH8JAjx6bwvDB0Ud+PZUBvRC08ZUfg8=; h=From:To:Subject:Date:In-Reply-To:References:From; b=gqyx01s8VqDUpiFGtFmXdfWDpEFyaoADs22whBILV3euswbFVTrBf+x6YzkkSyk3/ 0gfRm4AxQ0wFKiH9zY45MHxIo4qDNlNCdYTKspN9E0HB+KbdJfY0NQ6iqMlP0vcv7q O1P7ti7dZ0i3DAZluL1LCfbyPMBTyR6j3tn6YvHw= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:10 +0300 Message-Id: <20220823174314.14881-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/6] libcamera: color_space: Reorder members in the same order as the header 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Sort the members of the ColorSpace class in color_space.cpp to match the color_space.h order. No functional change intended. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain Reviewed-by: Paul Elder --- src/libcamera/color_space.cpp | 168 +++++++++++++++++----------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp index f0d6109ac4fb..1b2dd2404452 100644 --- a/src/libcamera/color_space.cpp +++ b/src/libcamera/color_space.cpp @@ -124,6 +124,90 @@ namespace libcamera { * \param[in] r The range of the pixel values in this color space */ +/** + * \brief A constant representing a raw color space (from a sensor) + */ +const ColorSpace ColorSpace::Raw = { + Primaries::Raw, + TransferFunction::Linear, + YcbcrEncoding::None, + Range::Full +}; + +/** + * \brief A constant representing the sRGB color space + * + * This is identical to the sYCC color space except that the Y'CbCr + * range is limited rather than full. + */ +const ColorSpace ColorSpace::Srgb = { + Primaries::Rec709, + TransferFunction::Srgb, + YcbcrEncoding::Rec601, + Range::Limited +}; + +/** + * \brief A constant representing the sYCC color space, typically used for + * encoding JPEG images + */ +const ColorSpace ColorSpace::Sycc = { + Primaries::Rec709, + TransferFunction::Srgb, + YcbcrEncoding::Rec601, + Range::Full +}; + +/** + * \brief A constant representing the SMPTE170M color space + */ +const ColorSpace ColorSpace::Smpte170m = { + Primaries::Smpte170m, + TransferFunction::Rec709, + YcbcrEncoding::Rec601, + Range::Limited +}; + +/** + * \brief A constant representing the Rec.709 color space + */ +const ColorSpace ColorSpace::Rec709 = { + Primaries::Rec709, + TransferFunction::Rec709, + YcbcrEncoding::Rec709, + Range::Limited +}; + +/** + * \brief A constant representing the Rec.2020 color space + */ +const ColorSpace ColorSpace::Rec2020 = { + Primaries::Rec2020, + TransferFunction::Rec709, + YcbcrEncoding::Rec2020, + Range::Limited +}; + +/** + * \var ColorSpace::primaries + * \brief The color primaries of this color space + */ + +/** + * \var ColorSpace::transferFunction + * \brief The transfer function used by this color space + */ + +/** + * \var ColorSpace::ycbcrEncoding + * \brief The Y'CbCr encoding used by this color space + */ + +/** + * \var ColorSpace::range + * \brief The pixel range used with by color space + */ + /** * \brief Assemble and return a readable string representation of the * ColorSpace @@ -219,90 +303,6 @@ std::string ColorSpace::toString(const std::optional &colorSpace) return colorSpace->toString(); } -/** - * \var ColorSpace::primaries - * \brief The color primaries of this color space - */ - -/** - * \var ColorSpace::transferFunction - * \brief The transfer function used by this color space - */ - -/** - * \var ColorSpace::ycbcrEncoding - * \brief The Y'CbCr encoding used by this color space - */ - -/** - * \var ColorSpace::range - * \brief The pixel range used with by color space - */ - -/** - * \brief A constant representing a raw color space (from a sensor) - */ -const ColorSpace ColorSpace::Raw = { - Primaries::Raw, - TransferFunction::Linear, - YcbcrEncoding::None, - Range::Full -}; - -/** - * \brief A constant representing the sRGB color space - * - * This is identical to the sYCC color space except that the Y'CbCr - * range is limited rather than full. - */ -const ColorSpace ColorSpace::Srgb = { - Primaries::Rec709, - TransferFunction::Srgb, - YcbcrEncoding::Rec601, - Range::Limited -}; - -/** - * \brief A constant representing the sYCC color space, typically used for - * encoding JPEG images - */ -const ColorSpace ColorSpace::Sycc = { - Primaries::Rec709, - TransferFunction::Srgb, - YcbcrEncoding::Rec601, - Range::Full -}; - -/** - * \brief A constant representing the SMPTE170M color space - */ -const ColorSpace ColorSpace::Smpte170m = { - Primaries::Smpte170m, - TransferFunction::Rec709, - YcbcrEncoding::Rec601, - Range::Limited -}; - -/** - * \brief A constant representing the Rec.709 color space - */ -const ColorSpace ColorSpace::Rec709 = { - Primaries::Rec709, - TransferFunction::Rec709, - YcbcrEncoding::Rec709, - Range::Limited -}; - -/** - * \brief A constant representing the Rec.2020 color space - */ -const ColorSpace ColorSpace::Rec2020 = { - Primaries::Rec2020, - TransferFunction::Rec709, - YcbcrEncoding::Rec2020, - Range::Limited -}; - /** * \brief Compare color spaces for equality * \return True if the two color spaces are identical, false otherwise From patchwork Tue Aug 23 17:43:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17189 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 BC8CAC0DA4 for ; Tue, 23 Aug 2022 17:43:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 843AE61FCB; Tue, 23 Aug 2022 19:43:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276607; bh=p/iV2Gs577r6vqrB7Pp9gCi++eBBznc7IQqmDvynl+U=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=YVZYY5RbyV6GPNihPMsWFNSacu+43PiSu4C04gVOi3k6pLqLewHTKZzLvbFx7z45J AUw0FHrGi4JkgcTtp+G+65wRAiQ6I75s9jd9x4Fs3OgE7F/78rSTvQ64EzXfxUsKcQ 6Uxs0D9Zfeb93YNW0BHpAm2Ujl22NIxe+N/rilFP4rSD4XT1FXQKEDPz9wBmoRr9V6 CKPVtyBPnCNQuVfeSQ1EzSqw8hVd5B2Sfv7qEJirk/MTFGwnTRxRish4D8IHtB2io0 eSXA0cFSbegYwdTsZVroicEdMI6HgV5DhVdP0GU97s6sqoVW4ai4nzaux/COV6m5vG OWXkivyR1oc0w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9119561FC5 for ; Tue, 23 Aug 2022 19:43:24 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="XP7vT1av"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0F6452B3 for ; Tue, 23 Aug 2022 19:43:23 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276604; bh=p/iV2Gs577r6vqrB7Pp9gCi++eBBznc7IQqmDvynl+U=; h=From:To:Subject:Date:In-Reply-To:References:From; b=XP7vT1avxk1JEcvzUztasZpS51SQEUYkyccPQ2ssKhHn939h4n13zGODbY79i0mRC t4gt3BvWHLweKtLhDYOZ0+IHEJ2D/cYAXa5L18ormVJwpvXZz7uhdaEsxv+2n8qAWg JYghIVZDuhbHBucKLbiRPheR7J6+faGIBpzrt79A= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:11 +0300 Message-Id: <20220823174314.14881-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/6] libcamera: color_space: Add fromString() function 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a ColorSpace:fromString() function to parse a string into a color space. The string can either contain the name of a well-known color space, or four color space components separate by a '/' character. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain --- include/libcamera/color_space.h | 2 + src/libcamera/color_space.cpp | 149 +++++++++++++++++++++++++------- 2 files changed, 121 insertions(+), 30 deletions(-) diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h index 8030a264c66f..f493f72d2db8 100644 --- a/include/libcamera/color_space.h +++ b/include/libcamera/color_space.h @@ -59,6 +59,8 @@ public: std::string toString() const; static std::string toString(const std::optional &colorSpace); + + static std::optional fromString(const std::string &str); }; bool operator==(const ColorSpace &lhs, const ColorSpace &rhs); diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp index 1b2dd2404452..5233626f5ae9 100644 --- a/src/libcamera/color_space.cpp +++ b/src/libcamera/color_space.cpp @@ -12,6 +12,9 @@ #include #include #include +#include + +#include /** * \file color_space.h @@ -208,6 +211,44 @@ const ColorSpace ColorSpace::Rec2020 = { * \brief The pixel range used with by color space */ +namespace { + +const std::array, 6> colorSpaceNames = { { + { ColorSpace::Raw, "RAW" }, + { ColorSpace::Srgb, "sRGB" }, + { ColorSpace::Sycc, "sYCC" }, + { ColorSpace::Smpte170m, "SMPTE170M" }, + { ColorSpace::Rec709, "Rec709" }, + { ColorSpace::Rec2020, "Rec2020" }, +} }; + +const std::map primariesNames = { + { ColorSpace::Primaries::Raw, "RAW" }, + { ColorSpace::Primaries::Smpte170m, "SMPTE170M" }, + { ColorSpace::Primaries::Rec709, "Rec709" }, + { ColorSpace::Primaries::Rec2020, "Rec2020" }, +}; + +const std::map transferNames = { + { ColorSpace::TransferFunction::Linear, "Linear" }, + { ColorSpace::TransferFunction::Srgb, "sRGB" }, + { ColorSpace::TransferFunction::Rec709, "Rec709" }, +}; + +const std::map encodingNames = { + { ColorSpace::YcbcrEncoding::None, "None" }, + { ColorSpace::YcbcrEncoding::Rec601, "Rec601" }, + { ColorSpace::YcbcrEncoding::Rec709, "Rec709" }, + { ColorSpace::YcbcrEncoding::Rec2020, "Rec2020" }, +}; + +const std::map rangeNames = { + { ColorSpace::Range::Full, "Full" }, + { ColorSpace::Range::Limited, "Limited" }, +}; + +} /* namespace */ + /** * \brief Assemble and return a readable string representation of the * ColorSpace @@ -223,14 +264,6 @@ std::string ColorSpace::toString() const { /* Print out a brief name only for standard color spaces. */ - static const std::array, 6> colorSpaceNames = { { - { ColorSpace::Raw, "RAW" }, - { ColorSpace::Srgb, "sRGB" }, - { ColorSpace::Sycc, "sYCC" }, - { ColorSpace::Smpte170m, "SMPTE170M" }, - { ColorSpace::Rec709, "Rec709" }, - { ColorSpace::Rec2020, "Rec2020" }, - } }; auto it = std::find_if(colorSpaceNames.begin(), colorSpaceNames.end(), [this](const auto &item) { return *this == item.first; @@ -240,28 +273,6 @@ std::string ColorSpace::toString() const /* Assemble a name made of the constituent fields. */ - static const std::map primariesNames = { - { Primaries::Raw, "RAW" }, - { Primaries::Smpte170m, "SMPTE170M" }, - { Primaries::Rec709, "Rec709" }, - { Primaries::Rec2020, "Rec2020" }, - }; - static const std::map transferNames = { - { TransferFunction::Linear, "Linear" }, - { TransferFunction::Srgb, "sRGB" }, - { TransferFunction::Rec709, "Rec709" }, - }; - static const std::map encodingNames = { - { YcbcrEncoding::None, "None" }, - { YcbcrEncoding::Rec601, "Rec601" }, - { YcbcrEncoding::Rec709, "Rec709" }, - { YcbcrEncoding::Rec2020, "Rec2020" }, - }; - static const std::map rangeNames = { - { Range::Full, "Full" }, - { Range::Limited, "Limited" }, - }; - auto itPrimaries = primariesNames.find(primaries); std::string primariesName = itPrimaries == primariesNames.end() ? "Invalid" : itPrimaries->second; @@ -303,6 +314,84 @@ std::string ColorSpace::toString(const std::optional &colorSpace) return colorSpace->toString(); } +/** + * \brief Construct a color space from a string + * \param[in] str The string + * + * The string \a str can contain the name of a well-known color space, or be + * made of the four color space components separate by a '/' character. Any + * failure to parse the string, either because it doesn't match the expected + * format, or because the one of the names isn't recognized, will cause this + * function to return std::nullopt. + * + * \return The ColorSpace corresponding to the string, or std::nullopt if the + * string doesn't describe a known color space + */ +std::optional ColorSpace::fromString(const std::string &str) +{ + /* First search for a standard color space name match. */ + auto itColorSpace = std::find_if(colorSpaceNames.begin(), colorSpaceNames.end(), + [&str](const auto &item) { + return str == item.second; + }); + if (itColorSpace != colorSpaceNames.end()) + return itColorSpace->first; + + /* + * If not found, the string must contain the four color space + * components separated by a '/' character. + */ + const auto &split = utils::split(str, "/"); + std::vector components{ split.begin(), split.end() }; + + if (components.size() != 4) + return std::nullopt; + + ColorSpace colorSpace = ColorSpace::Raw; + + /* Color primaries */ + auto itPrimaries = std::find_if(primariesNames.begin(), primariesNames.end(), + [&components](const auto &item) { + return components[0] == item.second; + }); + if (itPrimaries == primariesNames.end()) + return std::nullopt; + + colorSpace.primaries = itPrimaries->first; + + /* Transfer function */ + auto itTransfer = std::find_if(transferNames.begin(), transferNames.end(), + [&components](const auto &item) { + return components[1] == item.second; + }); + if (itTransfer == transferNames.end()) + return std::nullopt; + + colorSpace.transferFunction = itTransfer->first; + + /* YCbCr encoding */ + auto itEncoding = std::find_if(encodingNames.begin(), encodingNames.end(), + [&components](const auto &item) { + return components[2] == item.second; + }); + if (itEncoding == encodingNames.end()) + return std::nullopt; + + colorSpace.ycbcrEncoding = itEncoding->first; + + /* Quantization range */ + auto itRange = std::find_if(rangeNames.begin(), rangeNames.end(), + [&components](const auto &item) { + return components[3] == item.second; + }); + if (itRange == rangeNames.end()) + return std::nullopt; + + colorSpace.range = itRange->first; + + return colorSpace; +} + /** * \brief Compare color spaces for equality * \return True if the two color spaces are identical, false otherwise From patchwork Tue Aug 23 17:43:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17190 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 88EAFC327D for ; Tue, 23 Aug 2022 17:43:28 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1C34A61FCE; Tue, 23 Aug 2022 19:43:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276608; bh=Q8xm+HRrwp36abDQNeAE8x0BCMzSovEjbAzWH2WvBO4=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=aRaD+Vw+9M+3L2fASrmcGr5VMhTHsZmzY0uGpothbbezg4C6LOKMJg0uBxUXCh2h0 JHJcpTF2fQbJ94XmALOfGK5K9YZrjNC1p6YgxXCzlwbm9twDZyUtVcVaXXQUX3PfFr zaz85Rd3offzUsN88Qh7tFa+hmNwrb2uUz+xp+i+7ZtASRekrvfKDlC6V6W74sRRuN RL1wcbWT07AS01eEhqtLy4sNVSwY6f/mxPp1W8HRHNY5kxok/OMxRn4vRII6cKzuMk 9CLh72ILePnoAuo6ZRFCPBDEddkcKyabM5ctMyNBbNhMYhdhwENPqYrQM3w8JyDjva 4lxTdKNy1TGqQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B0B461FC9 for ; Tue, 23 Aug 2022 19:43:26 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="LTX2zNXs"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 9B566484 for ; Tue, 23 Aug 2022 19:43:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276605; bh=Q8xm+HRrwp36abDQNeAE8x0BCMzSovEjbAzWH2WvBO4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=LTX2zNXsP1eUV95xfbmzZq1NAu5QENSJCbS7Jt/HqIHxRM1Oh4m3GGKZL2yeP2Lrs Kj1OVIUm10OeJiLtJrZOsLVu4BmX6l2pvlml1XAHv2lKZLuJcoPApcSejKXTpQIUjH BHCHvQZ+OTdX6+qgS/3rCCW2ctY0h8QOepPURmCw= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:12 +0300 Message-Id: <20220823174314.14881-5-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 4/6] test: Add a ColorSpace test 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add a test for the ColorSpace class that exercises the toString() and fromString() functions. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain Reviewed-by: Paul Elder --- test/color-space.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++ test/meson.build | 1 + 2 files changed, 106 insertions(+) create mode 100644 test/color-space.cpp diff --git a/test/color-space.cpp b/test/color-space.cpp new file mode 100644 index 000000000000..7d45b2179bca --- /dev/null +++ b/test/color-space.cpp @@ -0,0 +1,105 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022, Laurent Pinchart + * + * libcamera ColorSpace test + */ + +#include +#include + +#include + +#include "test.h" + +using namespace libcamera; +using namespace std; + +class ColorSpaceTest : public Test +{ +protected: + int run() + { + if (ColorSpace::toString(std::nullopt) != "Unset") { + std::cerr << "Conversion from nullopt to string failed" << std::endl; + return TestFail; + } + + const std::array, 10> colorSpaces = { { + { ColorSpace::Raw, "RAW" }, + { ColorSpace::Srgb, "sRGB" }, + { ColorSpace::Sycc, "sYCC" }, + { ColorSpace::Smpte170m, "SMPTE170M" }, + { ColorSpace::Rec709, "Rec709" }, + { ColorSpace::Rec2020, "Rec2020" }, + { + ColorSpace{ + ColorSpace::Primaries::Raw, + ColorSpace::TransferFunction::Linear, + ColorSpace::YcbcrEncoding::None, + ColorSpace::Range::Limited + }, + "RAW/Linear/None/Limited" + }, { + ColorSpace{ + ColorSpace::Primaries::Smpte170m, + ColorSpace::TransferFunction::Srgb, + ColorSpace::YcbcrEncoding::Rec601, + ColorSpace::Range::Full + }, + "SMPTE170M/sRGB/Rec601/Full" + }, { + ColorSpace{ + ColorSpace::Primaries::Rec709, + ColorSpace::TransferFunction::Rec709, + ColorSpace::YcbcrEncoding::Rec709, + ColorSpace::Range::Full + }, + "Rec709/Rec709/Rec709/Full" + }, { + ColorSpace{ + ColorSpace::Primaries::Rec2020, + ColorSpace::TransferFunction::Linear, + ColorSpace::YcbcrEncoding::Rec2020, + ColorSpace::Range::Limited + }, + "Rec2020/Linear/Rec2020/Limited" + }, + } }; + + for (const auto &[colorSpace, name] : colorSpaces) { + if (colorSpace.toString() != name) { + std::cerr + << "Conversion from ColorSpace to string failed: " + << "expected " << name + << ", got " << colorSpace.toString() + << std::endl; + return TestFail; + } + + if (ColorSpace::fromString(name) != colorSpace) { + std::cerr + << "Conversion from string " + << name << " to ColorSpace failed" + << std::endl; + return TestFail; + } + } + + if (ColorSpace::fromString("Invalid")) { + std::cerr << "Conversion from invalid name string to color space succeeded" + << std::endl; + return TestFail; + } + + if (ColorSpace::fromString("Rec709/Rec709/Rec710/Limited")) { + std::cerr << "Conversion from invalid component string to color space succeeded" + << std::endl; + return TestFail; + } + + return TestPass; + } +}; + +TEST_REGISTER(ColorSpaceTest) diff --git a/test/meson.build b/test/meson.build index d050bfa14cec..6cc778415dc8 100644 --- a/test/meson.build +++ b/test/meson.build @@ -26,6 +26,7 @@ subdir('v4l2_subdevice') subdir('v4l2_videodevice') public_tests = [ + ['color-space', 'color-space.cpp'], ['geometry', 'geometry.cpp'], ['public-api', 'public-api.cpp'], ['signal', 'signal.cpp'], From patchwork Tue Aug 23 17:43:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17191 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 63407C0DA4 for ; Tue, 23 Aug 2022 17:43:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1A4DC61FD1; Tue, 23 Aug 2022 19:43:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276612; bh=+6ArkC7GrHsJp2uUZyWEqLadtOPYde0OPIZ9tIyl2+E=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Aphodrp7w+srTrscdwLEG5LQPssde7oY8ywsfySbuDtQiaDVXVOiftTtIhWJEOeM2 vbOAOPAgrYlp9sQQxS2Nqa4fWlzTJ1fj0nbcuW8ggYchk2FZYUiDXLvstscvSM9JZU FXU647RhGTccFSLsNNIJs+RZ7ccY79bj2/qJLvVt1eLbV60gMxCv+zT7I5p0BPbVwk rAyAnyK+5u0q4AxaAPsR1yscmA1Um8NBxJl6oFfySnDjG6/UkvKgpLeMbw5+WHV/Ym d3uDSDHNuiEzGH/I7KivGr6628eP2hYnJzJFxZTrTc7or/bBAJrfCt7jPk1uIsjvsx LAIY2iGjFjgtA== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9301761FCC for ; Tue, 23 Aug 2022 19:43:27 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="F87uVHOW"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 20C582B3 for ; Tue, 23 Aug 2022 19:43:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276607; bh=+6ArkC7GrHsJp2uUZyWEqLadtOPYde0OPIZ9tIyl2+E=; h=From:To:Subject:Date:In-Reply-To:References:From; b=F87uVHOWRH1sxJ03eS8F2H+BBrNVZFAR/QkZtIUvTFGmASZ/ar5/vdnpnYWFTxEZY ZMcxN/73lQ43vzCHPG+A+FsuDDUcrRkzB+Y2vI2OLmZA5GhSWiu/vlZ3f4F068K+TC xj8nDe6WvfRXEPKUlN4h/nC348VOXGUq1gFVK/xE= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:13 +0300 Message-Id: <20220823174314.14881-6-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 5/6] libcamera: pipeline: rkisp1: Implement color space support 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Florian Sylvestre --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 38 ++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 03bbe6b467ae..25fbf9f1a0a9 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -416,11 +417,13 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() { const CameraSensor *sensor = data_->sensor_.get(); unsigned int pathCount = data_->selfPath_ ? 2 : 1; - Status status = Valid; + Status status; if (config_.empty()) return Invalid; + status = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace); + if (transform != Transform::Identity) { transform = Transform::Identity; status = Adjusted; @@ -547,21 +550,44 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera if (roles.empty()) return config; + /* + * As the ISP can't output different color spaces for the main and self + * path, pick a sensible default color space based on the role of the + * first stream and use it for all streams. + */ + std::optional colorSpace; + bool mainPathAvailable = true; bool selfPathAvailable = data->selfPath_; + for (const StreamRole role : roles) { bool useMainPath; switch (role) { - case StreamRole::StillCapture: { + case StreamRole::StillCapture: useMainPath = mainPathAvailable; + /* JPEG encoders typically expect sYCC. */ + if (!colorSpace) + colorSpace = ColorSpace::Sycc; break; - } + case StreamRole::Viewfinder: - case StreamRole::VideoRecording: { useMainPath = !selfPathAvailable; + /* + * sYCC is the YCbCr encoding of sRGB, which is commonly + * used by displays. + */ + if (!colorSpace) + colorSpace = ColorSpace::Sycc; break; - } + + case StreamRole::VideoRecording: + useMainPath = !selfPathAvailable; + /* Rec. 709 is a good default for HD video recording. */ + if (!colorSpace) + colorSpace = ColorSpace::Rec709; + break; + default: LOG(RkISP1, Warning) << "Requested stream role not supported: " << role; @@ -580,6 +606,7 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera selfPathAvailable = false; } + cfg.colorSpace = colorSpace; config->addConfiguration(cfg); } @@ -642,6 +669,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret < 0) return ret; + format.colorSpace = config->at(0).colorSpace; ret = isp_->setFormat(2, &format); if (ret < 0) return ret; From patchwork Tue Aug 23 17:43:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 17192 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 03329C327D for ; Tue, 23 Aug 2022 17:43:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9E52B61FCA; Tue, 23 Aug 2022 19:43:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661276612; bh=/SXJKJDO3SeO9tKwX/HD8uXUoE84grewaMGkleZeAqs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=YEJWogwWhMJKCRP9zkoHqIfNbQ+f3wT7G+JzH8l2L+3hKT5vnVb1oHXnm8wj/6Q7i C2chh0no0fOcMcAVCm70EhTgb1vS+lb5S+CCoSTmQRjOdH9YH3GYwLRXQTCrIGt+OP GdaYrlvW8cINWF1OeTkUnsKGXemyGSRiz6zuBqU73KD8SHoiaI6lrEbxHb6W2y3sPR wxmytJk1yEZzaTWm3mNMjUCP+O1kYKh5iTNZHC2GnPM6658os5SFtf/4VTERUN52Hd LWfgfeW29VmN0VYEU6/k4L0SlwXu31InVcQ3VKXAxW8QQuYeoML5OR04yD0386VIpU B3uypyY9o/pwQ== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1C9BC61FCA for ; Tue, 23 Aug 2022 19:43:29 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Vga8QM8q"; dkim-atps=neutral Received: from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 953F1484 for ; Tue, 23 Aug 2022 19:43:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1661276608; bh=/SXJKJDO3SeO9tKwX/HD8uXUoE84grewaMGkleZeAqs=; h=From:To:Subject:Date:In-Reply-To:References:From; b=Vga8QM8qyr8Gx3/0g7/PztOsM4thp8tKk+86hdx4gDdBFYoxs0Z+Y66mfSpl1SwSf Z5kYvuAUA4zFNZyiFVRpwSTu6TXIQp94IhE0ALSoovC4ntvfWIqXNeaOoWiHgXgssC 8dJp9E/MzhIPENRNn9XgUhHzFkHDq3tQBDPadm10= To: libcamera-devel@lists.libcamera.org Date: Tue, 23 Aug 2022 20:43:14 +0300 Message-Id: <20220823174314.14881-7-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> References: <20220823174314.14881-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 6/6] cam: Add color space support 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: , X-Patchwork-Original-From: Laurent Pinchart via libcamera-devel From: Laurent Pinchart Reply-To: Laurent Pinchart Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add support for color space to the StreamKeyValueParser, allowing selection of a color space on the command line. Signed-off-by: Laurent Pinchart Reviewed-by: Umang Jain Reviewed-by: Paul Elder --- src/cam/stream_options.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cam/stream_options.cpp b/src/cam/stream_options.cpp index a68135a9ed88..3a5625f5f267 100644 --- a/src/cam/stream_options.cpp +++ b/src/cam/stream_options.cpp @@ -8,6 +8,8 @@ #include +#include + using namespace libcamera; StreamKeyValueParser::StreamKeyValueParser() @@ -21,6 +23,8 @@ StreamKeyValueParser::StreamKeyValueParser() ArgumentRequired); addOption("pixelformat", OptionString, "Pixel format name", ArgumentRequired); + addOption("colorspace", OptionString, "Color space", + ArgumentRequired); } KeyValueParser::Options StreamKeyValueParser::parse(const char *arguments) @@ -96,6 +100,9 @@ int StreamKeyValueParser::updateConfiguration(CameraConfiguration *config, if (opts.isSet("pixelformat")) cfg.pixelFormat = PixelFormat::fromString(opts["pixelformat"].toString()); + + if (opts.isSet("colorspace")) + cfg.colorSpace = ColorSpace::fromString(opts["colorspace"].toString()); } return 0;