[{"id":24774,"web_url":"https://patchwork.libcamera.org/comment/24774/","msgid":"<20220825155207.GF109174@pyrite.rasen.tech>","date":"2022-08-25T15:52:07","subject":"Re: [libcamera-devel] [PATCH v2] libcamera: color_space: Rename\n\tJpeg to Sycc","submitter":{"id":97,"url":"https://patchwork.libcamera.org/api/people/97/","name":"Nicolas Dufresne via libcamera-devel","email":"libcamera-devel@lists.libcamera.org"},"content":"On Tue, Aug 23, 2022 at 02:45:51PM +0300, Laurent Pinchart via libcamera-devel wrote:\n> The JPEG color space is badly name, as the JPEG specification (ITU-T\n> T.81) doesn't define any particular color space:\n> \n>     The interchange format does not specify a complete coded image\n>     representation. Application-dependent information, e.g. colour\n>     space, is outside the scope of this Specification.\n> \n> The JFIF specification (ITU-T T.871) is clearer as it requires ITU-R\n> BT.601 YCbCr encoding and a full quantization range:\n> \n>   The interpretations of Y, CB, and CR are derived from the E'Y, E'Cb,\n>   and E'Cr signals defined in the 625-line specification of Rec. ITU-R\n>   BT.601, but these signals are normalized so as to permit the usage of\n>   the full range of 256 levels of the 8-bit binary encoding of the Y\n>   component.\n> \n> It however doesn't specify color primaries or a transfer function\n> explicitly. It only mentions the latter when describing the conversion\n> from YCbCr to RGB:\n> \n>   The inverse relationship for computing full scale 8-bit per colour\n>   channel gamma pre-corrected RGB values (following Rec. ITU-R BT.601\n>   gamma pre-correction and colour primary specifications) from YCbCr\n>   colours (with 256 levels per component) can be computed as follows:\n>   [...]\n> \n> Given that ITU-R BT.601-5 (1995) didn't specify color primaries or a\n> transfer function, and that the later ITU-R BT.601-7 (2011) version\n> specifies color primaries for the 625-line variant that do not match\n> sRGB, the JPEG color space in libcamera is badly named. This is\n> confirmed by ITU-T T.871:\n> \n>   As this Recommendation | International Standard is based on the prior\n>   informally-circulated JFIF version 1.02 specification that was\n>   produced in 1992, which referenced Rec. ITU-R BT.601 (formerly CCIR\n>   601), it references that specification for definition of the E'Y,\n>   E'Cb, and E'Cr signals that correspond to the YCBCR values specified\n>   herein. However, since the development of the prior JFIF version 1.02\n>   specification, additional industry specifications have been developed,\n>   Rec. ITU-R BT.601 has been updated, and common industry practice has\n>   emerged which often follows the sYCC specification in IEC\n>   61966-2-1/Amd.1. The difference between the use of the colour\n>   interpretation specification in this Recommendation | International\n>   Standard and that of the sYCC specification may be considered\n>   negligible in practice.\n> \n> Rename the color space to sYCC, as its definition matches the sYCC\n> standard, and indicate that it is typically used to encode JPEG images.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Reviewed-by: Umang Jain <umang.jain@ideasonboard.com>\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n> Changes since v1:\n> \n> - Rename more instances of JPEG to sYCC\n> - Reword the references to the V4L2 documentation\n> ---\n>  include/libcamera/color_space.h               |  2 +-\n>  src/libcamera/color_space.cpp                 | 43 +++++++++++--------\n>  .../pipeline/raspberrypi/raspberrypi.cpp      | 10 ++---\n>  src/libcamera/v4l2_device.cpp                 |  4 +-\n>  src/py/libcamera/py_main.cpp                  |  2 +-\n>  5 files changed, 34 insertions(+), 27 deletions(-)\n> \n> diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h\n> index 0d39fbc02220..8030a264c66f 100644\n> --- a/include/libcamera/color_space.h\n> +++ b/include/libcamera/color_space.h\n> @@ -46,8 +46,8 @@ public:\n>  \t}\n>  \n>  \tstatic const ColorSpace Raw;\n> -\tstatic const ColorSpace Jpeg;\n>  \tstatic const ColorSpace Srgb;\n> +\tstatic const ColorSpace Sycc;\n>  \tstatic const ColorSpace Smpte170m;\n>  \tstatic const ColorSpace Rec709;\n>  \tstatic const ColorSpace Rec2020;\n> diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp\n> index caf397607b10..f0d6109ac4fb 100644\n> --- a/src/libcamera/color_space.cpp\n> +++ b/src/libcamera/color_space.cpp\n> @@ -29,21 +29,28 @@ namespace libcamera {\n>   * (sometimes also referred to as the quantisation) of the color space.\n>   *\n>   * Certain combinations of these fields form well-known standard color\n> - * spaces such as \"JPEG\" or \"REC709\".\n> + * spaces such as \"sRGB\" or \"Rec709\".\n>   *\n>   * In the strictest sense a \"color space\" formally only refers to the\n>   * color primaries and white point. Here, however, the ColorSpace class\n>   * adopts the common broader usage that includes the transfer function,\n>   * Y'CbCr encoding method and quantisation.\n>   *\n> - * For more information on the specific color spaces described here, please\n> - * see:\n> + * More information on color spaces is available in the V4L2 documentation, see\n> + * in particular\n>   *\n>   * - <a href=\"https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-details.html#col-srgb\">sRGB</a>\n>   * - <a href=\"https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-details.html#col-jpeg\">JPEG</a>\n>   * - <a href=\"https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-details.html#col-smpte-170m\">SMPTE 170M</a>\n>   * - <a href=\"https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-details.html#col-rec709\">Rec.709</a>\n>   * - <a href=\"https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/colorspaces-details.html#col-bt2020\">Rec.2020</a>\n> + *\n> + * Note that there is no guarantee of a 1:1 mapping between color space names\n> + * and definitions in libcamera and V4L2. A notable difference is that the sYCC\n> + * libcamera color space is called JPEG in V4L2 due to historical reasons.\n> + *\n> + * \\todo Define the color space fully in the libcamera API to avoid referencing\n> + * V4L2\n>   */\n>  \n>  /**\n> @@ -121,8 +128,8 @@ namespace libcamera {\n>   * \\brief Assemble and return a readable string representation of the\n>   * ColorSpace\n>   *\n> - * If the color space matches a standard ColorSpace (such as ColorSpace::Jpeg)\n> - * then the short name of the color space (\"JPEG\") is returned. Otherwise\n> + * If the color space matches a standard ColorSpace (such as ColorSpace::Sycc)\n> + * then the short name of the color space (\"sYCC\") is returned. Otherwise\n>   * the four constituent parts of the ColorSpace are assembled into a longer\n>   * string.\n>   *\n> @@ -134,8 +141,8 @@ std::string ColorSpace::toString() const\n>  \n>  \tstatic const std::array<std::pair<ColorSpace, const char *>, 6> colorSpaceNames = { {\n>  \t\t{ ColorSpace::Raw, \"RAW\" },\n> -\t\t{ ColorSpace::Jpeg, \"JPEG\" },\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> @@ -242,21 +249,10 @@ const ColorSpace ColorSpace::Raw = {\n>  \tRange::Full\n>  };\n>  \n> -/**\n> - * \\brief A constant representing the JPEG color space used for\n> - * encoding JPEG images\n> - */\n> -const ColorSpace ColorSpace::Jpeg = {\n> -\tPrimaries::Rec709,\n> -\tTransferFunction::Srgb,\n> -\tYcbcrEncoding::Rec601,\n> -\tRange::Full\n> -};\n> -\n>  /**\n>   * \\brief A constant representing the sRGB color space\n>   *\n> - * This is identical to the JPEG color space except that the Y'CbCr\n> + * This is identical to the sYCC color space except that the Y'CbCr\n>   * range is limited rather than full.\n>   */\n>  const ColorSpace ColorSpace::Srgb = {\n> @@ -266,6 +262,17 @@ const ColorSpace ColorSpace::Srgb = {\n>  \tRange::Limited\n>  };\n>  \n> +/**\n> + * \\brief A constant representing the sYCC color space, typically used for\n> + * encoding JPEG images\n> + */\n> +const ColorSpace ColorSpace::Sycc = {\n> +\tPrimaries::Rec709,\n> +\tTransferFunction::Srgb,\n> +\tYcbcrEncoding::Rec601,\n> +\tRange::Full\n> +};\n> +\n>  /**\n>   * \\brief A constant representing the SMPTE170M color space\n>   */\n> diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> index e895584d4fbc..b4094898ca6c 100644\n> --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp\n> @@ -593,11 +593,11 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n>  \t\t\tfmts = data->isp_[Isp::Output0].dev()->formats();\n>  \t\t\tpixelFormat = formats::NV12;\n>  \t\t\t/*\n> -\t\t\t * Still image codecs usually expect the JPEG color space.\n> +\t\t\t * Still image codecs usually expect the sYCC color space.\n>  \t\t\t * Even RGB codecs will be fine as the RGB we get with the\n> -\t\t\t * JPEG color space is the same as sRGB.\n> +\t\t\t * sYCC color space is the same as sRGB.\n>  \t\t\t */\n> -\t\t\tcolorSpace = ColorSpace::Jpeg;\n> +\t\t\tcolorSpace = ColorSpace::Sycc;\n>  \t\t\t/* Return the largest sensor resolution. */\n>  \t\t\tsize = sensorSize;\n>  \t\t\tbufferCount = 1;\n> @@ -628,7 +628,7 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,\n>  \t\tcase StreamRole::Viewfinder:\n>  \t\t\tfmts = data->isp_[Isp::Output0].dev()->formats();\n>  \t\t\tpixelFormat = formats::ARGB8888;\n> -\t\t\tcolorSpace = ColorSpace::Jpeg;\n> +\t\t\tcolorSpace = ColorSpace::Sycc;\n>  \t\t\tsize = { 800, 600 };\n>  \t\t\tbufferCount = 4;\n>  \t\t\toutCount++;\n> @@ -835,7 +835,7 @@ int PipelineHandlerRPi::configure(Camera *camera, CameraConfiguration *config)\n>  \t\tformat.size = maxSize;\n>  \t\tformat.fourcc = dev->toV4L2PixelFormat(formats::YUV420);\n>  \t\t/* No one asked for output, so the color space doesn't matter. */\n> -\t\tformat.colorSpace = ColorSpace::Jpeg;\n> +\t\tformat.colorSpace = ColorSpace::Sycc;\n>  \t\tret = dev->setFormat(&format);\n>  \t\tif (ret) {\n>  \t\t\tLOG(RPI, Error)\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index 3fc8438f6579..b22a981ff1a6 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -745,8 +745,8 @@ void V4L2Device::eventAvailable()\n>  \n>  static const std::map<uint32_t, ColorSpace> v4l2ToColorSpace = {\n>  \t{ V4L2_COLORSPACE_RAW, ColorSpace::Raw },\n> -\t{ V4L2_COLORSPACE_JPEG, ColorSpace::Jpeg },\n>  \t{ V4L2_COLORSPACE_SRGB, ColorSpace::Srgb },\n> +\t{ V4L2_COLORSPACE_JPEG, ColorSpace::Sycc },\n>  \t{ V4L2_COLORSPACE_SMPTE170M, ColorSpace::Smpte170m },\n>  \t{ V4L2_COLORSPACE_REC709, ColorSpace::Rec709 },\n>  \t{ V4L2_COLORSPACE_BT2020, ColorSpace::Rec2020 },\n> @@ -771,8 +771,8 @@ static const std::map<uint32_t, ColorSpace::Range> v4l2ToRange = {\n>  \n>  static const std::vector<std::pair<ColorSpace, v4l2_colorspace>> colorSpaceToV4l2 = {\n>  \t{ ColorSpace::Raw, V4L2_COLORSPACE_RAW },\n> -\t{ ColorSpace::Jpeg, V4L2_COLORSPACE_JPEG },\n>  \t{ ColorSpace::Srgb, V4L2_COLORSPACE_SRGB },\n> +\t{ ColorSpace::Sycc, V4L2_COLORSPACE_JPEG },\n>  \t{ ColorSpace::Smpte170m, V4L2_COLORSPACE_SMPTE170M },\n>  \t{ ColorSpace::Rec709, V4L2_COLORSPACE_REC709 },\n>  \t{ ColorSpace::Rec2020, V4L2_COLORSPACE_BT2020 },\n> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> index 7e613a3f2a5a..75947889f7b1 100644\n> --- a/src/py/libcamera/py_main.cpp\n> +++ b/src/py/libcamera/py_main.cpp\n> @@ -463,8 +463,8 @@ PYBIND11_MODULE(_libcamera, m)\n>  \t\t.def_readwrite(\"ycbcrEncoding\", &ColorSpace::ycbcrEncoding)\n>  \t\t.def_readwrite(\"range\", &ColorSpace::range)\n>  \t\t.def_static(\"Raw\", []() { return ColorSpace::Raw; })\n> -\t\t.def_static(\"Jpeg\", []() { return ColorSpace::Jpeg; })\n>  \t\t.def_static(\"Srgb\", []() { return ColorSpace::Srgb; })\n> +\t\t.def_static(\"Sycc\", []() { return ColorSpace::Sycc; })\n>  \t\t.def_static(\"Smpte170m\", []() { return ColorSpace::Smpte170m; })\n>  \t\t.def_static(\"Rec709\", []() { return ColorSpace::Rec709; })\n>  \t\t.def_static(\"Rec2020\", []() { return ColorSpace::Rec2020; });","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 18849C0DA4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 25 Aug 2022 15:52:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C7BEF61FC3;\n\tThu, 25 Aug 2022 17:52:15 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 59BA461FA0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 25 Aug 2022 17:52:14 +0200 (CEST)","from pyrite.rasen.tech (unknown\n\t[IPv6:2604:2d80:ad8a:9000:1bf9:855b:22de:3645])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7B0892B3;\n\tThu, 25 Aug 2022 17:52:13 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1661442735;\n\tbh=etNFHOc/XQwaf8h5BnhXTGzF2ztSqMIDTqe9qwM/4YA=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=onmUxXEKBozUrZOfWNY2kGtcYzaP3U8bBui1xWnVs0rXmRDmT7SonXTz/xdZQIbAF\n\tjyfVLiG5HfFpG5GzyZZVHAaDXwEC9M++7CXvFNcmeJ8kB0xTJep9dAOX0eEvR6Az8b\n\tt+0k4vLO4TQIs+KwtSTisfEtA1ANwbbKFjYpwhyRKbXkWTLBiI+p5c7p+7CDbKFoRX\n\t59aQindjdCoYGr2NAlR1NzdAqu9goaeLsilMkoeYpKvBicGxcbcYKWGK+zjzH7bTwm\n\tyKOTPhX86JX62vDdpaKwDh4OP+hsnOQsFOL9n1x4lPCas0QCFf0Z8IRmn7fJKVGCO+\n\tKGlfTSD1hxpTg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1661442734;\n\tbh=etNFHOc/XQwaf8h5BnhXTGzF2ztSqMIDTqe9qwM/4YA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Zn68iGyfe1ozE9srl6iS31mxUMcmEtm8wNOHeXv4q7DMTfIc1Nn7WuMv/3bDeQlUZ\n\tYMxViFrjIC59V6VrE0VjwyBzoTUXn2PMQYLgjov1eyAG08jk+kvag0HQv7M8S0btlX\n\tQDWb1sVsLkidEaWvExB8O7dzlE8mAtdj9wGKRapU="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Zn68iGyf\"; dkim-atps=neutral","Date":"Thu, 25 Aug 2022 10:52:07 -0500","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20220825155207.GF109174@pyrite.rasen.tech>","References":"<20220823114551.27796-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20220823114551.27796-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2] libcamera: color_space: Rename\n\tJpeg to Sycc","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":"Paul Elder via libcamera-devel <libcamera-devel@lists.libcamera.org>","Reply-To":"paul.elder@ideasonboard.com","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]