Show a patch.

GET /api/1.1/patches/17189/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 17189,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/17189/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/17189/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220823174314.14881-4-laurent.pinchart@ideasonboard.com>",
    "date": "2022-08-23T17:43:11",
    "name": "[libcamera-devel,3/6] libcamera: color_space: Add fromString() function",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "b81f187a7c02b6d12872699708d43e6648e30d54",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/17189/mbox/",
    "series": [
        {
            "id": 3432,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3432/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3432",
            "date": "2022-08-23T17:43:08",
            "name": "libcamera: Add support for color spaces to rkisp1 pipeline handler",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/3432/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/17189/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/17189/checks/",
    "tags": {},
    "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 BC8CAC0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 23 Aug 2022 17:43:27 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 843AE61FCB;\n\tTue, 23 Aug 2022 19:43:27 +0200 (CEST)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9119561FC5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 23 Aug 2022 19:43:24 +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 0F6452B3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 23 Aug 2022 19:43:23 +0200 (CEST)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1661276607;\n\tbh=p/iV2Gs577r6vqrB7Pp9gCi++eBBznc7IQqmDvynl+U=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=YVZYY5RbyV6GPNihPMsWFNSacu+43PiSu4C04gVOi3k6pLqLewHTKZzLvbFx7z45J\n\tAUw0FHrGi4JkgcTtp+G+65wRAiQ6I75s9jd9x4Fs3OgE7F/78rSTvQ64EzXfxUsKcQ\n\t6Uxs0D9Zfeb93YNW0BHpAm2Ujl22NIxe+N/rilFP4rSD4XT1FXQKEDPz9wBmoRr9V6\n\tCKPVtyBPnCNQuVfeSQ1EzSqw8hVd5B2Sfv7qEJirk/MTFGwnTRxRish4D8IHtB2io0\n\teSXA0cFSbegYwdTsZVroicEdMI6HgV5DhVdP0GU97s6sqoVW4ai4nzaux/COV6m5vG\n\tOWXkivyR1oc0w==",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1661276604;\n\tbh=p/iV2Gs577r6vqrB7Pp9gCi++eBBznc7IQqmDvynl+U=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=XP7vT1avxk1JEcvzUztasZpS51SQEUYkyccPQ2ssKhHn939h4n13zGODbY79i0mRC\n\tt4gt3BvWHLweKtLhDYOZ0+IHEJ2D/cYAXa5L18ormVJwpvXZz7uhdaEsxv+2n8qAWg\n\tJYghIVZDuhbHBucKLbiRPheR7J6+faGIBpzrt79A="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"XP7vT1av\"; dkim-atps=neutral",
        "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",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH 3/6] libcamera: color_space: Add\n\tfromString() function",
        "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>",
        "From": "Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "Add a ColorSpace:fromString() function to parse a string into a color\nspace. The string can either contain the name of a well-known color\nspace, or four color space components separate by a '/' character.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n include/libcamera/color_space.h |   2 +\n src/libcamera/color_space.cpp   | 149 +++++++++++++++++++++++++-------\n 2 files changed, 121 insertions(+), 30 deletions(-)",
    "diff": "diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h\nindex 8030a264c66f..f493f72d2db8 100644\n--- a/include/libcamera/color_space.h\n+++ b/include/libcamera/color_space.h\n@@ -59,6 +59,8 @@ public:\n \n \tstd::string toString() const;\n \tstatic std::string toString(const std::optional<ColorSpace> &colorSpace);\n+\n+\tstatic std::optional<ColorSpace> fromString(const std::string &str);\n };\n \n bool operator==(const ColorSpace &lhs, const ColorSpace &rhs);\ndiff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp\nindex 1b2dd2404452..5233626f5ae9 100644\n--- a/src/libcamera/color_space.cpp\n+++ b/src/libcamera/color_space.cpp\n@@ -12,6 +12,9 @@\n #include <map>\n #include <sstream>\n #include <utility>\n+#include <vector>\n+\n+#include <libcamera/base/utils.h>\n \n /**\n  * \\file color_space.h\n@@ -208,6 +211,44 @@ const ColorSpace ColorSpace::Rec2020 = {\n  * \\brief The pixel range used with by color space\n  */\n \n+namespace {\n+\n+const std::array<std::pair<ColorSpace, const char *>, 6> colorSpaceNames = { {\n+\t{ ColorSpace::Raw, \"RAW\" },\n+\t{ ColorSpace::Srgb, \"sRGB\" },\n+\t{ ColorSpace::Sycc, \"sYCC\" },\n+\t{ ColorSpace::Smpte170m, \"SMPTE170M\" },\n+\t{ ColorSpace::Rec709, \"Rec709\" },\n+\t{ ColorSpace::Rec2020, \"Rec2020\" },\n+} };\n+\n+const std::map<ColorSpace::Primaries, std::string> primariesNames = {\n+\t{ ColorSpace::Primaries::Raw, \"RAW\" },\n+\t{ ColorSpace::Primaries::Smpte170m, \"SMPTE170M\" },\n+\t{ ColorSpace::Primaries::Rec709, \"Rec709\" },\n+\t{ ColorSpace::Primaries::Rec2020, \"Rec2020\" },\n+};\n+\n+const std::map<ColorSpace::TransferFunction, std::string> transferNames = {\n+\t{ ColorSpace::TransferFunction::Linear, \"Linear\" },\n+\t{ ColorSpace::TransferFunction::Srgb, \"sRGB\" },\n+\t{ ColorSpace::TransferFunction::Rec709, \"Rec709\" },\n+};\n+\n+const std::map<ColorSpace::YcbcrEncoding, std::string> encodingNames = {\n+\t{ ColorSpace::YcbcrEncoding::None, \"None\" },\n+\t{ ColorSpace::YcbcrEncoding::Rec601, \"Rec601\" },\n+\t{ ColorSpace::YcbcrEncoding::Rec709, \"Rec709\" },\n+\t{ ColorSpace::YcbcrEncoding::Rec2020, \"Rec2020\" },\n+};\n+\n+const std::map<ColorSpace::Range, std::string> rangeNames = {\n+\t{ ColorSpace::Range::Full, \"Full\" },\n+\t{ ColorSpace::Range::Limited, \"Limited\" },\n+};\n+\n+} /* namespace */\n+\n /**\n  * \\brief Assemble and return a readable string representation of the\n  * ColorSpace\n@@ -223,14 +264,6 @@ std::string ColorSpace::toString() const\n {\n \t/* Print out a brief name only for standard color spaces. */\n \n-\tstatic const std::array<std::pair<ColorSpace, const char *>, 6> colorSpaceNames = { {\n-\t\t{ ColorSpace::Raw, \"RAW\" },\n-\t\t{ ColorSpace::Srgb, \"sRGB\" },\n-\t\t{ ColorSpace::Sycc, \"sYCC\" },\n-\t\t{ ColorSpace::Smpte170m, \"SMPTE170M\" },\n-\t\t{ ColorSpace::Rec709, \"Rec709\" },\n-\t\t{ ColorSpace::Rec2020, \"Rec2020\" },\n-\t} };\n \tauto it = std::find_if(colorSpaceNames.begin(), colorSpaceNames.end(),\n \t\t\t       [this](const auto &item) {\n \t\t\t\t       return *this == item.first;\n@@ -240,28 +273,6 @@ std::string ColorSpace::toString() const\n \n \t/* Assemble a name made of the constituent fields. */\n \n-\tstatic const std::map<Primaries, std::string> primariesNames = {\n-\t\t{ Primaries::Raw, \"RAW\" },\n-\t\t{ Primaries::Smpte170m, \"SMPTE170M\" },\n-\t\t{ Primaries::Rec709, \"Rec709\" },\n-\t\t{ Primaries::Rec2020, \"Rec2020\" },\n-\t};\n-\tstatic const std::map<TransferFunction, std::string> transferNames = {\n-\t\t{ TransferFunction::Linear, \"Linear\" },\n-\t\t{ TransferFunction::Srgb, \"sRGB\" },\n-\t\t{ TransferFunction::Rec709, \"Rec709\" },\n-\t};\n-\tstatic const std::map<YcbcrEncoding, std::string> encodingNames = {\n-\t\t{ YcbcrEncoding::None, \"None\" },\n-\t\t{ YcbcrEncoding::Rec601, \"Rec601\" },\n-\t\t{ YcbcrEncoding::Rec709, \"Rec709\" },\n-\t\t{ YcbcrEncoding::Rec2020, \"Rec2020\" },\n-\t};\n-\tstatic const std::map<Range, std::string> rangeNames = {\n-\t\t{ Range::Full, \"Full\" },\n-\t\t{ Range::Limited, \"Limited\" },\n-\t};\n-\n \tauto itPrimaries = primariesNames.find(primaries);\n \tstd::string primariesName =\n \t\titPrimaries == primariesNames.end() ? \"Invalid\" : itPrimaries->second;\n@@ -303,6 +314,84 @@ std::string ColorSpace::toString(const std::optional<ColorSpace> &colorSpace)\n \treturn colorSpace->toString();\n }\n \n+/**\n+ * \\brief Construct a color space from a string\n+ * \\param[in] str The string\n+ *\n+ * The string \\a str can contain the name of a well-known color space, or be\n+ * made of the four color space components separate by a '/' character. Any\n+ * failure to parse the string, either because it doesn't match the expected\n+ * format, or because the one of the names isn't recognized, will cause this\n+ * function to return std::nullopt.\n+ *\n+ * \\return The ColorSpace corresponding to the string, or std::nullopt if the\n+ * string doesn't describe a known color space\n+ */\n+std::optional<ColorSpace> ColorSpace::fromString(const std::string &str)\n+{\n+\t/* First search for a standard color space name match. */\n+\tauto itColorSpace = std::find_if(colorSpaceNames.begin(), colorSpaceNames.end(),\n+\t\t\t\t\t [&str](const auto &item) {\n+\t\t\t\t\t\t return str == item.second;\n+\t\t\t\t\t });\n+\tif (itColorSpace != colorSpaceNames.end())\n+\t\treturn itColorSpace->first;\n+\n+\t/*\n+\t * If not found, the string must contain the four color space\n+\t * components separated by a '/' character.\n+\t */\n+\tconst auto &split = utils::split(str, \"/\");\n+\tstd::vector<std::string> components{ split.begin(), split.end() };\n+\n+\tif (components.size() != 4)\n+\t\treturn std::nullopt;\n+\n+\tColorSpace colorSpace = ColorSpace::Raw;\n+\n+\t/* Color primaries */\n+\tauto itPrimaries = std::find_if(primariesNames.begin(), primariesNames.end(),\n+\t\t\t\t\t[&components](const auto &item) {\n+\t\t\t\t\t\treturn components[0] == item.second;\n+\t\t\t\t\t});\n+\tif (itPrimaries == primariesNames.end())\n+\t\treturn std::nullopt;\n+\n+\tcolorSpace.primaries = itPrimaries->first;\n+\n+\t/* Transfer function */\n+\tauto itTransfer = std::find_if(transferNames.begin(), transferNames.end(),\n+\t\t\t\t       [&components](const auto &item) {\n+\t\t\t\t\t       return components[1] == item.second;\n+\t\t\t\t       });\n+\tif (itTransfer == transferNames.end())\n+\t\treturn std::nullopt;\n+\n+\tcolorSpace.transferFunction = itTransfer->first;\n+\n+\t/* YCbCr encoding */\n+\tauto itEncoding = std::find_if(encodingNames.begin(), encodingNames.end(),\n+\t\t\t\t       [&components](const auto &item) {\n+\t\t\t\t\t       return components[2] == item.second;\n+\t\t\t\t       });\n+\tif (itEncoding == encodingNames.end())\n+\t\treturn std::nullopt;\n+\n+\tcolorSpace.ycbcrEncoding = itEncoding->first;\n+\n+\t/* Quantization range */\n+\tauto itRange = std::find_if(rangeNames.begin(), rangeNames.end(),\n+\t\t\t\t    [&components](const auto &item) {\n+\t\t\t\t\t    return components[3] == item.second;\n+\t\t\t\t    });\n+\tif (itRange == rangeNames.end())\n+\t\treturn std::nullopt;\n+\n+\tcolorSpace.range = itRange->first;\n+\n+\treturn colorSpace;\n+}\n+\n /**\n  * \\brief Compare color spaces for equality\n  * \\return True if the two color spaces are identical, false otherwise\n",
    "prefixes": [
        "libcamera-devel",
        "3/6"
    ]
}