Show a patch.

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

{
    "id": 22090,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/22090/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/22090/",
    "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": "<20241125180310.1254519-10-mzamazal@redhat.com>",
    "date": "2024-11-25T18:03:10",
    "name": "[v2,9/9] libcamera: software_isp: Apply CCM in debayering",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "b5ff0c9fffc2c7c54b4d6ffe572cab5bcdbb508e",
    "submitter": {
        "id": 177,
        "url": "https://patchwork.libcamera.org/api/1.1/people/177/?format=api",
        "name": "Milan Zamazal",
        "email": "mzamazal@redhat.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/22090/mbox/",
    "series": [
        {
            "id": 4820,
            "url": "https://patchwork.libcamera.org/api/1.1/series/4820/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4820",
            "date": "2024-11-25T18:03:01",
            "name": "Software ISP support for CCM",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/4820/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/22090/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/22090/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 CCFD8BD160\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 25 Nov 2024 18:03:49 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 85C3B6604A;\n\tMon, 25 Nov 2024 19:03:49 +0100 (CET)",
            "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 87F3466051\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 25 Nov 2024 19:03:45 +0100 (CET)",
            "from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-581-TMBTDjWsMIOHkId97H8ntg-1;\n\tMon, 25 Nov 2024 13:03:41 -0500",
            "from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.15])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 9F4B819541BE; Mon, 25 Nov 2024 18:03:40 +0000 (UTC)",
            "from nuthatch.redhat.com (unknown [10.45.224.109])\n\tby mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 162FA1956086; Mon, 25 Nov 2024 18:03:38 +0000 (UTC)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"XIyuCu4p\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1732557824;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=/L7ndDN9dpi5bM5dDHzLSiUSsLtx2dVlTb9f6z+ClZE=;\n\tb=XIyuCu4plGsoFcOMGot7H6haMs5DnOtbqsPkXczooXyjcTqPyUQpTA3IaeOFmLEALjjoty\n\tYZQrqvd6QauKybj8yPwt5an5gQZXgWPnulrqWiLkPZouzU9Wl+8jXXGqmbduMGegl5Pb68\n\t/uwidEfJ5Z1gCYxY/ie0kie8q8njUDg=",
        "X-MC-Unique": "TMBTDjWsMIOHkId97H8ntg-1",
        "X-Mimecast-MFC-AGG-ID": "TMBTDjWsMIOHkId97H8ntg",
        "From": "Milan Zamazal <mzamazal@redhat.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\tRobert Mader <robert.mader@collabora.com>",
        "Subject": "[PATCH v2 9/9] libcamera: software_isp: Apply CCM in debayering",
        "Date": "Mon, 25 Nov 2024 19:03:10 +0100",
        "Message-ID": "<20241125180310.1254519-10-mzamazal@redhat.com>",
        "In-Reply-To": "<20241125180310.1254519-1-mzamazal@redhat.com>",
        "References": "<20241125180310.1254519-1-mzamazal@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.15",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "pgnRz8JOY1d-cV4J9xkj6YFmCq76Tb4H995GbQ9hfK8_1732557820",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "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>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "This patch applies color correction matrix (CCM) in debayering if the\nCCM is specified.  Not using CCM must still be supported for performance\nreasons.\n\nThe CCM is applied as follows:\n\n            [r1 r2 r3]\n  [r g b] * [g1 g2 g3]\n            [b1 b2 b3]\n\nThe CCM matrix (the right side of the multiplication) is constant during\nsingle frame processing, while the input pixel (the left side) changes.\nBecause each of the color channels is only 8-bit in software ISP, we can\nmake 9 lookup tables with 256 input values for multiplications of each\nof the r_i, g_i, b_i values.  This way we don't have to multiply each\npixel, we can use table lookups and additions instead.  Gamma (which is\nnon-linear and thus cannot be a part of the 9 lookup tables values) is\napplied on the final values rounded to integers using another lookup\ntable.\n\nWe use int16_t to store the precomputed multiplications.  This seems to\nbe noticeably (>10%) faster than `float' for the price of slightly less\naccuracy and it covers the range of values that sane CCMs produce.  The\nselection and structure of data is performance critical, for example\nusing bytes would add significant (>10%) speedup but would be too short\nto cover the value range.\n\nThe color lookup tables are changed to unions to be able to serve as\nboth simple lookup tables or CCM lookup tables.  This is arguable but it\nkeeps the code easier to understand if nothing else.  It is important to\nmake the unions on the whole lookup tables rather than their values\nbecause the latter might cause a noticeable slowdown on simple lookup\ndue to the sheer fact that the table is not compact.  Using unions makes\nthe initialization of the tables dubious because it is done before the\ndecision about using CCM is made but the initial values are dubious\nanyway.\n\nThe tables are copied (as before), which is not elegant but also not a\nbig problem.  There are patches posted that use shared buffers for\nparameters passing in software ISP (see software ISP TODO #5) and they\ncan be adjusted for the new parameter format.\n\nWith this patch, the reported per-frame slowdown when applying CCM is\nabout 45% on Debix Model A and about 75% on TI AM69 SK.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n .../internal/software_isp/debayer_params.h    | 20 ++++++-\n src/ipa/simple/algorithms/lut.cpp             | 58 ++++++++++++++-----\n src/ipa/simple/algorithms/lut.h               |  1 +\n src/libcamera/software_isp/debayer.cpp        | 53 ++++++++++++++++-\n src/libcamera/software_isp/debayer_cpu.cpp    | 34 ++++++++---\n src/libcamera/software_isp/debayer_cpu.h      |  7 ++-\n src/libcamera/software_isp/software_isp.cpp   |  6 +-\n 7 files changed, 145 insertions(+), 34 deletions(-)",
    "diff": "diff --git a/include/libcamera/internal/software_isp/debayer_params.h b/include/libcamera/internal/software_isp/debayer_params.h\nindex 7d8fdd481..f8731eaee 100644\n--- a/include/libcamera/internal/software_isp/debayer_params.h\n+++ b/include/libcamera/internal/software_isp/debayer_params.h\n@@ -18,11 +18,25 @@ namespace libcamera {\n struct DebayerParams {\n \tstatic constexpr unsigned int kRGBLookupSize = 256;\n \n+\tstruct CcmColumn {\n+\t\tint16_t r;\n+\t\tint16_t g;\n+\t\tint16_t b;\n+\t};\n+\n \tusing ColorLookupTable = std::array<uint8_t, kRGBLookupSize>;\n+\tusing CcmLookupTable = std::array<CcmColumn, kRGBLookupSize>;\n+\tusing GammaLookupTable = std::array<uint8_t, kRGBLookupSize>;\n+\n+\tunion LookupTable {\n+\t\tColorLookupTable simple;\n+\t\tCcmLookupTable ccm;\n+\t};\n \n-\tColorLookupTable red;\n-\tColorLookupTable green;\n-\tColorLookupTable blue;\n+\tLookupTable red;\n+\tLookupTable green;\n+\tLookupTable blue;\n+\tGammaLookupTable gammaLut;\n };\n \n } /* namespace libcamera */\ndiff --git a/src/ipa/simple/algorithms/lut.cpp b/src/ipa/simple/algorithms/lut.cpp\nindex 8fca96b0a..1d9a607b2 100644\n--- a/src/ipa/simple/algorithms/lut.cpp\n+++ b/src/ipa/simple/algorithms/lut.cpp\n@@ -44,6 +44,11 @@ void Lut::updateGammaTable(IPAContext &context)\n \tcontext.activeState.gamma.blackLevel = blackLevel;\n }\n \n+int16_t Lut::ccmValue(unsigned int i, float ccm) const\n+{\n+\treturn std::round(i * ccm);\n+}\n+\n void Lut::prepare(IPAContext &context,\n \t\t  [[maybe_unused]] const uint32_t frame,\n \t\t  [[maybe_unused]] IPAFrameContext &frameContext,\n@@ -55,27 +60,48 @@ void Lut::prepare(IPAContext &context,\n \t * observed, it's not permanently prone to minor fluctuations or\n \t * rounding errors.\n \t */\n-\tif (context.activeState.gamma.blackLevel != context.activeState.blc.level)\n+\tconst bool gammaUpdateNeeded =\n+\t\tcontext.activeState.gamma.blackLevel != context.activeState.blc.level;\n+\tif (gammaUpdateNeeded)\n \t\tupdateGammaTable(context);\n \n \tauto &gains = context.activeState.awb.gains;\n \tauto &gammaTable = context.activeState.gamma.gammaTable;\n \tconst unsigned int gammaTableSize = gammaTable.size();\n-\n-\tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) {\n-\t\tconst double div = static_cast<double>(DebayerParams::kRGBLookupSize) /\n-\t\t\t\t   gammaTableSize;\n-\t\t/* Apply gamma after gain! */\n-\t\tunsigned int idx;\n-\t\tidx = std::min({ static_cast<unsigned int>(i * gains.red / div),\n-\t\t\t\t gammaTableSize - 1 });\n-\t\tparams->red[i] = gammaTable[idx];\n-\t\tidx = std::min({ static_cast<unsigned int>(i * gains.green / div),\n-\t\t\t\t gammaTableSize - 1 });\n-\t\tparams->green[i] = gammaTable[idx];\n-\t\tidx = std::min({ static_cast<unsigned int>(i * gains.blue / div),\n-\t\t\t\t gammaTableSize - 1 });\n-\t\tparams->blue[i] = gammaTable[idx];\n+\tconst double div = static_cast<double>(DebayerParams::kRGBLookupSize) /\n+\t\t\t   gammaTableSize;\n+\n+\tif (!context.activeState.ccm.enabled) {\n+\t\tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) {\n+\t\t\t/* Apply gamma after gain! */\n+\t\t\tunsigned int idx;\n+\t\t\tidx = std::min({ static_cast<unsigned int>(i * gains.red / div),\n+\t\t\t\t\t gammaTableSize - 1 });\n+\t\t\tparams->red.simple[i] = gammaTable[idx];\n+\t\t\tidx = std::min({ static_cast<unsigned int>(i * gains.green / div),\n+\t\t\t\t\t gammaTableSize - 1 });\n+\t\t\tparams->green.simple[i] = gammaTable[idx];\n+\t\t\tidx = std::min({ static_cast<unsigned int>(i * gains.blue / div),\n+\t\t\t\t\t gammaTableSize - 1 });\n+\t\t\tparams->blue.simple[i] = gammaTable[idx];\n+\t\t}\n+\t} else if (context.activeState.ccm.changed || gammaUpdateNeeded) {\n+\t\tauto &ccm = context.activeState.ccm.ccm;\n+\t\tauto &red = params->red.ccm;\n+\t\tauto &green = params->green.ccm;\n+\t\tauto &blue = params->blue.ccm;\n+\t\tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) {\n+\t\t\tred[i].r = ccmValue(i, ccm[0][0]);\n+\t\t\tred[i].g = ccmValue(i, ccm[1][0]);\n+\t\t\tred[i].b = ccmValue(i, ccm[2][0]);\n+\t\t\tgreen[i].r = ccmValue(i, ccm[0][1]);\n+\t\t\tgreen[i].g = ccmValue(i, ccm[1][1]);\n+\t\t\tgreen[i].b = ccmValue(i, ccm[2][1]);\n+\t\t\tblue[i].r = ccmValue(i, ccm[0][2]);\n+\t\t\tblue[i].g = ccmValue(i, ccm[1][2]);\n+\t\t\tblue[i].b = ccmValue(i, ccm[2][2]);\n+\t\t\tparams->gammaLut[i] = gammaTable[i / div];\n+\t\t}\n \t}\n }\n \ndiff --git a/src/ipa/simple/algorithms/lut.h b/src/ipa/simple/algorithms/lut.h\nindex b635987d0..8d50a23fc 100644\n--- a/src/ipa/simple/algorithms/lut.h\n+++ b/src/ipa/simple/algorithms/lut.h\n@@ -27,6 +27,7 @@ public:\n \n private:\n \tvoid updateGammaTable(IPAContext &context);\n+\tint16_t ccmValue(unsigned int i, float ccm) const;\n };\n \n } /* namespace ipa::soft::algorithms */\ndiff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\nindex f0b832619..47f9996bb 100644\n--- a/src/libcamera/software_isp/debayer.cpp\n+++ b/src/libcamera/software_isp/debayer.cpp\n@@ -23,11 +23,56 @@ namespace libcamera {\n  * \\brief Size of a color lookup table\n  */\n \n+/**\n+ * \\struct DebayerParams::CcmColumn\n+ * \\brief Type of a single column of a color correction matrix\n+ */\n+\n+/**\n+ * \\var DebayerParams::CcmColumn::r\n+ * \\brief Red (first) component of a CCM column\n+ */\n+\n+/**\n+ * \\var DebayerParams::CcmColumn::g\n+ * \\brief Green (second) component of a CCM column\n+ */\n+\n+/**\n+ * \\var DebayerParams::CcmColumn::b\n+ * \\brief Blue (third) component of a CCM column\n+ */\n+\n /**\n  * \\typedef DebayerParams::ColorLookupTable\n+ * \\brief Type of the simple lookup tables for red, green, blue values\n+ */\n+\n+/**\n+ * \\typedef DebayerParams::CcmLookupTable\n+ * \\brief Type of the CCM lookup tables for red, green, blue values\n+ */\n+\n+/**\n+ * \\typedef DebayerParams::GammaLookupTable\n+ * \\brief Type of the gamma lookup tables for CCM\n+ */\n+\n+/**\n+ * \\union DebayerParams::LookupTable\n  * \\brief Type of the lookup tables for red, green, blue values\n  */\n \n+/**\n+ * \\var DebayerParams::LookupTable::simple\n+ * \\brief Simple lookup table for red, green, blue values\n+ */\n+\n+/**\n+ * \\var DebayerParams::LookupTable::ccm\n+ * \\brief CCM lookup table for red, green, blue values\n+ */\n+\n /**\n  * \\var DebayerParams::red\n  * \\brief Lookup table for red color, mapping input values to output values\n@@ -43,6 +88,11 @@ namespace libcamera {\n  * \\brief Lookup table for blue color, mapping input values to output values\n  */\n \n+/**\n+ * \\var DebayerParams::gammaLut\n+ * \\brief Gamma lookup table used with color correction matrix\n+ */\n+\n /**\n  * \\class Debayer\n  * \\brief Base debayering class\n@@ -57,10 +107,11 @@ Debayer::~Debayer()\n }\n \n /**\n- * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n+ * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, ccmEnabled)\n  * \\brief Configure the debayer object according to the passed in parameters\n  * \\param[in] inputCfg The input configuration\n  * \\param[in] outputCfgs The output configurations\n+ * \\param[in] ccmEnabled Whether a color correction matrix is applied\n  *\n  * \\return 0 on success, a negative errno on failure\n  */\ndiff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\nindex 92f81baf2..30bd1991c 100644\n--- a/src/libcamera/software_isp/debayer_cpu.cpp\n+++ b/src/libcamera/software_isp/debayer_cpu.cpp\n@@ -11,6 +11,7 @@\n \n #include \"debayer_cpu.h\"\n \n+#include <algorithm>\n #include <stdlib.h>\n #include <sys/ioctl.h>\n #include <time.h>\n@@ -50,8 +51,12 @@ DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats)\n \tenableInputMemcpy_ = true;\n \n \t/* Initialize color lookup tables */\n-\tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++)\n-\t\tred_[i] = green_[i] = blue_[i] = i;\n+\tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) {\n+\t\tred_.simple[i] = green_.simple[i] = blue_.simple[i] = i;\n+\t\tred_.ccm[i].r = red_.ccm[i].g = red_.ccm[i].b = 0;\n+\t\tgreen_.ccm[i].r = green_.ccm[i].g = green_.ccm[i].b = 0;\n+\t\tblue_.ccm[i].r = blue_.ccm[i].g = blue_.ccm[i].b = 0;\n+\t}\n }\n \n DebayerCpu::~DebayerCpu() = default;\n@@ -61,12 +66,24 @@ DebayerCpu::~DebayerCpu() = default;\n \tconst pixel_t *curr = (const pixel_t *)src[1] + xShift_; \\\n \tconst pixel_t *next = (const pixel_t *)src[2] + xShift_;\n \n-#define STORE_PIXEL(b, g, r)        \\\n-\t*dst++ = blue_[b];          \\\n-\t*dst++ = green_[g];         \\\n-\t*dst++ = red_[r];           \\\n-\tif constexpr (addAlphaByte) \\\n-\t\t*dst++ = 255;       \\\n+#define GAMMA(value) \\\n+\t*dst++ = gammaLut_[std::clamp(value, 0, static_cast<int>(gammaLut_.size()) - 1)]\n+\n+#define STORE_PIXEL(b_, g_, r_)                                   \\\n+\tif constexpr (ccmEnabled) {                               \\\n+\t\tDebayerParams::CcmColumn &blue = blue_.ccm[b_];   \\\n+\t\tDebayerParams::CcmColumn &green = green_.ccm[g_]; \\\n+\t\tDebayerParams::CcmColumn &red = red_.ccm[r_];     \\\n+\t\tGAMMA(blue.r + blue.g + blue.b);                  \\\n+\t\tGAMMA(green.r + green.g + green.b);               \\\n+\t\tGAMMA(red.r + red.g + red.b);                     \\\n+\t} else {                                                  \\\n+\t\t*dst++ = blue_.simple[b_];                        \\\n+\t\t*dst++ = green_.simple[g_];                       \\\n+\t\t*dst++ = red_.simple[r_];                         \\\n+\t}                                                         \\\n+\tif constexpr (addAlphaByte)                               \\\n+\t\t*dst++ = 255;                                     \\\n \tx++;\n \n /*\n@@ -764,6 +781,7 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n \tgreen_ = params.green;\n \tred_ = swapRedBlueGains_ ? params.blue : params.red;\n \tblue_ = swapRedBlueGains_ ? params.red : params.blue;\n+\tgammaLut_ = params.gammaLut;\n \n \t/* Copy metadata from the input buffer */\n \tFrameMetadata &metadata = output->_d()->metadata();\ndiff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\nindex b2ec8f1bd..35c51e4fd 100644\n--- a/src/libcamera/software_isp/debayer_cpu.h\n+++ b/src/libcamera/software_isp/debayer_cpu.h\n@@ -137,9 +137,10 @@ private:\n \t/* Max. supported Bayer pattern height is 4, debayering this requires 5 lines */\n \tstatic constexpr unsigned int kMaxLineBuffers = 5;\n \n-\tDebayerParams::ColorLookupTable red_;\n-\tDebayerParams::ColorLookupTable green_;\n-\tDebayerParams::ColorLookupTable blue_;\n+\tDebayerParams::LookupTable red_;\n+\tDebayerParams::LookupTable green_;\n+\tDebayerParams::LookupTable blue_;\n+\tDebayerParams::GammaLookupTable gammaLut_;\n \tdebayerFn debayer0_;\n \tdebayerFn debayer1_;\n \tdebayerFn debayer2_;\ndiff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\nindex 0e1d3a457..08eca192e 100644\n--- a/src/libcamera/software_isp/software_isp.cpp\n+++ b/src/libcamera/software_isp/software_isp.cpp\n@@ -79,9 +79,9 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor)\n \tfor (unsigned int i = 0; i < 256; i++)\n \t\tgammaTable[i] = UINT8_MAX * std::pow(i / 256.0, 0.5);\n \tfor (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++) {\n-\t\tdebayerParams_.red[i] = gammaTable[i];\n-\t\tdebayerParams_.green[i] = gammaTable[i];\n-\t\tdebayerParams_.blue[i] = gammaTable[i];\n+\t\tdebayerParams_.red.simple[i] = gammaTable[i];\n+\t\tdebayerParams_.green.simple[i] = gammaTable[i];\n+\t\tdebayerParams_.blue.simple[i] = gammaTable[i];\n \t}\n \n \tif (!dmaHeap_.isValid()) {\n",
    "prefixes": [
        "v2",
        "9/9"
    ]
}