Patch Detail
Show a patch.
GET /api/patches/24281/?format=api
{ "id": 24281, "url": "https://patchwork.libcamera.org/api/patches/24281/?format=api", "web_url": "https://patchwork.libcamera.org/patch/24281/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/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": "<20250901162606.44139-2-mzamazal@redhat.com>", "date": "2025-09-01T16:25:15", "name": "[v3,1/1] apps: cam: Support PPM output for other RGB formats", "commit_ref": "baea40a8a5dddbad3cf6398aa8ce248e4547c955", "pull_url": null, "state": "accepted", "archived": false, "hash": "d2f92674b411c1dc2b6eae8383af0d016235ca45", "submitter": { "id": 177, "url": "https://patchwork.libcamera.org/api/people/177/?format=api", "name": "Milan Zamazal", "email": "mzamazal@redhat.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/24281/mbox/", "series": [ { "id": 5421, "url": "https://patchwork.libcamera.org/api/series/5421/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5421", "date": "2025-09-01T16:25:14", "name": "PPM output for RGB formats", "version": 3, "mbox": "https://patchwork.libcamera.org/series/5421/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/24281/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/24281/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 D757DBEFBE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 1 Sep 2025 16:26:23 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8A31769338;\n\tMon, 1 Sep 2025 18:26:23 +0200 (CEST)", "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 508FB69324\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 1 Sep 2025 18:26:22 +0200 (CEST)", "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-541-gjAIB4uPM92fjTSeKj9kYw-1;\n\tMon, 01 Sep 2025 12:26:17 -0400", "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.17])\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 B0BED195608D; Mon, 1 Sep 2025 16:26:15 +0000 (UTC)", "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.224.12])\n\tby mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 5EF3C1955EA4; Mon, 1 Sep 2025 16:26:13 +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=\"ZtfN35zz\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1756743981;\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=NAeZx4gJvFN9WlZgAw3qSSo6h26o4W9S34ygZAnEBBI=;\n\tb=ZtfN35zzYyBLecNEZrRk0KZu44N+abLchdONLpQ7x1yqXw8LdvCmrEHrCOi5Rco77zVpK5\n\t/wqmIS7QEN85gWcEddp5uGRtXlW+2nzpTTDnvq83IsYZ/dX+kwzpYPoKmOHHUoQxB0fhmn\n\tfAprtkX0C5wq2GP+N7iCUVZ1Xxaccgw=", "X-MC-Unique": "gjAIB4uPM92fjTSeKj9kYw-1", "X-Mimecast-MFC-AGG-ID": "gjAIB4uPM92fjTSeKj9kYw_1756743976", "From": "Milan Zamazal <mzamazal@redhat.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Milan Zamazal <mzamazal@redhat.com>,\n\t\"Bryan O'Donoghue\" <bryan.odonoghue@linaro.org>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>,\n\tPavel Machek <pavel@ucw.cz>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>", "Subject": "[PATCH v3 1/1] apps: cam: Support PPM output for other RGB formats", "Date": "Mon, 1 Sep 2025 18:25:15 +0200", "Message-ID": "<20250901162606.44139-2-mzamazal@redhat.com>", "In-Reply-To": "<20250901162606.44139-1-mzamazal@redhat.com>", "References": "<20250901162606.44139-1-mzamazal@redhat.com>", "MIME-Version": "1.0", "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17", "X-Mimecast-Spam-Score": "0", "X-Mimecast-MFC-PROC-ID": "lUSoHAESnCulVtppgxHcT1iOTSN2-eWMtriQEMtE3H8_1756743976", "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": "GPU ISP can produce only 32-bit output. Let's add support to the PPM\nwriter for all the common RGB image formats so that we can store GPU ISP\noutput as PPM files. Contingent alpha values are ignored as there is no\nsupport for the alpha channel in PPM.\n\nThere is no obvious performance penalty in my environment compared to\noutput in the raw format.\n\nSigned-off-by: Pavel Machek <pavel@ucw.cz>\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n src/apps/common/ppm_writer.cpp | 48 +++++++++++++++++++++++++++++++---\n 1 file changed, 44 insertions(+), 4 deletions(-)", "diff": "diff --git a/src/apps/common/ppm_writer.cpp b/src/apps/common/ppm_writer.cpp\nindex 368de8bf6..6f0bbbe9e 100644\n--- a/src/apps/common/ppm_writer.cpp\n+++ b/src/apps/common/ppm_writer.cpp\n@@ -10,6 +10,7 @@\n #include <errno.h>\n #include <fstream>\n #include <iostream>\n+#include <vector>\n \n #include <libcamera/formats.h>\n #include <libcamera/pixel_format.h>\n@@ -20,9 +21,34 @@ int PPMWriter::write(const char *filename,\n \t\t const StreamConfiguration &config,\n \t\t const Span<uint8_t> &data)\n {\n-\tif (config.pixelFormat != formats::BGR888) {\n-\t\tstd::cerr << \"Only BGR888 output pixel format is supported (\"\n-\t\t\t << config.pixelFormat << \" requested)\" << std::endl;\n+\tstruct FormatTransformation {\n+\t\tunsigned int rPos;\n+\t\tunsigned int gPos;\n+\t\tunsigned int bPos;\n+\t\tunsigned int bytesPerPixel;\n+\t};\n+\n+\tstatic const std::map<libcamera::PixelFormat, FormatTransformation> transforms = {\n+\t\t{ libcamera::formats::R8, { 0, 0, 0, 1 } },\n+\t\t{ libcamera::formats::RGB888, { 2, 1, 0, 3 } },\n+\t\t{ libcamera::formats::BGR888, { 0, 1, 2, 3 } },\n+\t\t{ libcamera::formats::ARGB8888, { 2, 1, 0, 4 } },\n+\t\t{ libcamera::formats::XRGB8888, { 2, 1, 0, 4 } },\n+\t\t{ libcamera::formats::ABGR8888, { 0, 1, 2, 4 } },\n+\t\t{ libcamera::formats::XBGR8888, { 0, 1, 2, 4 } },\n+\t\t{ libcamera::formats::RGBA8888, { 3, 2, 1, 4 } },\n+\t\t{ libcamera::formats::RGBX8888, { 3, 2, 1, 4 } },\n+\t\t{ libcamera::formats::BGRA8888, { 1, 2, 3, 4 } },\n+\t\t{ libcamera::formats::BGRX8888, { 1, 2, 3, 4 } },\n+\t};\n+\n+\tFormatTransformation transformation;\n+\tif (auto search = transforms.find(config.pixelFormat); search != transforms.end()) {\n+\t\ttransformation = search->second;\n+\t} else {\n+\t\tstd::cerr\n+\t\t\t<< \"Only RGB output pixel formats are supported (\"\n+\t\t\t<< config.pixelFormat << \" requested)\" << std::endl;\n \t\treturn -EINVAL;\n \t}\n \n@@ -42,8 +68,22 @@ int PPMWriter::write(const char *filename,\n \n \tconst unsigned int rowLength = config.size.width * 3;\n \tconst char *row = reinterpret_cast<const char *>(data.data());\n+\tconst bool transform = config.pixelFormat != formats::BGR888;\n+\tstd::vector<char> transformedRow(transform ? rowLength : 0);\n+\n \tfor (unsigned int y = 0; y < config.size.height; y++, row += config.stride) {\n-\t\toutput.write(row, rowLength);\n+\t\tif (transform) {\n+\t\t\tfor (unsigned int x = 0; x < config.size.width; x++) {\n+\t\t\t\ttransformedRow[x * 3] =\n+\t\t\t\t\trow[x * transformation.bytesPerPixel + transformation.rPos];\n+\t\t\t\ttransformedRow[x * 3 + 1] =\n+\t\t\t\t\trow[x * transformation.bytesPerPixel + transformation.gPos];\n+\t\t\t\ttransformedRow[x * 3 + 2] =\n+\t\t\t\t\trow[x * transformation.bytesPerPixel + transformation.bPos];\n+\t\t\t}\n+\t\t}\n+\n+\t\toutput.write(transform ? transformedRow.data() : row, rowLength);\n \t\tif (!output) {\n \t\t\tstd::cerr << \"Failed to write image data at row \" << y << std::endl;\n \t\t\treturn -EIO;\n", "prefixes": [ "v3", "1/1" ] }