[{"id":33174,"web_url":"https://patchwork.libcamera.org/comment/33174/","msgid":"<20250125210446.GH1805@pendragon.ideasonboard.com>","date":"2025-01-25T21:04:46","subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Milan,\n\nThank you for the patch.\n\nOn Fri, Jan 24, 2025 at 10:58:04PM +0100, Milan Zamazal wrote:\n> `cam' application can be requested to write its output as a PPM file.\n> However, this is supported only for certain formats (only BGR888\n> currently).  If the output format cannot be written, `cam' reports an\n> error and doesn't write anything.\n> \n> This is all right with a single stream input but impractical with\n> multiple streams of different output formats (e.g. a processed stream +\n> a raw stream) where some of them can be written in the supported format\n> while the other not.  In such a case, it's better to write the supported\n> formats as PPM files and the unsupported formats as raw files, with the\n> corresponding warning on stderr.  `.raw' extension is added to the file\n> name in such a case to make clear it's not a PPM file.\n> \n> This is a sort of hack but serves the purpose for the moment.\n\nShould we instead change the -F option (and the -D and -S options too I\nsuppose) to act at the stream level instead of the camera level ?\n\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  src/apps/cam/file_sink.cpp | 16 +++++++++++-----\n>  1 file changed, 11 insertions(+), 5 deletions(-)\n> \n> diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp\n> index 76e21db9..1a866137 100644\n> --- a/src/apps/cam/file_sink.cpp\n> +++ b/src/apps/cam/file_sink.cpp\n> @@ -7,6 +7,7 @@\n>  \n>  #include <array>\n>  #include <assert.h>\n> +#include <errno.h>\n>  #include <fcntl.h>\n>  #include <iomanip>\n>  #include <iostream>\n> @@ -133,11 +134,16 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer,\n>  \tif (fileType_ == FileType::Ppm) {\n>  \t\tret = PPMWriter::write(filename.c_str(), stream->configuration(),\n>  \t\t\t\t       image->data(0));\n> -\t\tif (ret < 0)\n> -\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n> -\t\t\t\t  << \"'\" << std::endl;\n> -\n> -\t\treturn;\n> +\t\tif (ret == -EINVAL) {\n> +\t\t\tfilename += \".raw\";\n> +\t\t\tstd::cerr << \"cannot write file in PPM format, writing `\"\n> +\t\t\t\t  << filename << \"' instead\" << std::endl;\n> +\t\t} else {\n> +\t\t\tif (ret < 0)\n> +\t\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n> +\t\t\t\t\t  << \"'\" << std::endl;\n> +\t\t\treturn;\n> +\t\t}\n>  \t}\n>  \n>  \tfd = open(filename.c_str(), O_CREAT | O_WRONLY |","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 AD9F3C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat, 25 Jan 2025 21:04:59 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C6A066855D;\n\tSat, 25 Jan 2025 22:04:58 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 506DB6187B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 25 Jan 2025 22:04:57 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id DF9654C7;\n\tSat, 25 Jan 2025 22:03:51 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"LM/Nn5Z3\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1737839032;\n\tbh=hUWpKheKBf/E8tYIsw0EPeyYSnAkIV+NYJr5pdOuTI0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=LM/Nn5Z3m0VDJc94ZIVEsxpZEUnfd+Rl23XsPA6Xj7s22o0phvJrpxzJWKqLsNvOm\n\tasSVi8zFgZlZpqlqZ55d12nvmH5u+/plb4sgCCUCuGxvY0vPqU434VhZ3nPpXmmCSe\n\t5vbU3A6L/STrkJzAqUc4EekT779bKwWTHRAG+ZWs=","Date":"Sat, 25 Jan 2025 23:04:46 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","Message-ID":"<20250125210446.GH1805@pendragon.ideasonboard.com>","References":"<20250124215806.158024-1-mzamazal@redhat.com>\n\t<20250124215806.158024-14-mzamazal@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20250124215806.158024-14-mzamazal@redhat.com>","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>"}},{"id":33208,"web_url":"https://patchwork.libcamera.org/comment/33208/","msgid":"<851pwoo3nv.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","date":"2025-01-27T12:13:40","subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Laurent,\n\nthank you for review.\n\nLaurent Pinchart <laurent.pinchart@ideasonboard.com> writes:\n\n> Hi Milan,\n>\n> Thank you for the patch.\n>\n> On Fri, Jan 24, 2025 at 10:58:04PM +0100, Milan Zamazal wrote:\n>> `cam' application can be requested to write its output as a PPM file.\n>> However, this is supported only for certain formats (only BGR888\n>> currently).  If the output format cannot be written, `cam' reports an\n>> error and doesn't write anything.\n>> \n>> This is all right with a single stream input but impractical with\n>> multiple streams of different output formats (e.g. a processed stream +\n>> a raw stream) where some of them can be written in the supported format\n>> while the other not.  In such a case, it's better to write the supported\n>> formats as PPM files and the unsupported formats as raw files, with the\n>> corresponding warning on stderr.  `.raw' extension is added to the file\n>> name in such a case to make clear it's not a PPM file.\n>> \n>> This is a sort of hack but serves the purpose for the moment.\n>\n> Should we instead change the -F option (and the -D and -S options too I\n> suppose) to act at the stream level instead of the camera level ?\n\nSomething like this would be useful.  But maybe rather than changing the\ngiven options (how?), it would be simpler to add a keyword to -s,\ne.g. output=file/sdl/kms.  What do you think?\n\n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  src/apps/cam/file_sink.cpp | 16 +++++++++++-----\n>>  1 file changed, 11 insertions(+), 5 deletions(-)\n>> \n>> diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp\n>> index 76e21db9..1a866137 100644\n>> --- a/src/apps/cam/file_sink.cpp\n>> +++ b/src/apps/cam/file_sink.cpp\n>> @@ -7,6 +7,7 @@\n>>  \n>>  #include <array>\n>>  #include <assert.h>\n>> +#include <errno.h>\n>>  #include <fcntl.h>\n>>  #include <iomanip>\n>>  #include <iostream>\n>> @@ -133,11 +134,16 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer,\n>>  \tif (fileType_ == FileType::Ppm) {\n>>  \t\tret = PPMWriter::write(filename.c_str(), stream->configuration(),\n>>  \t\t\t\t       image->data(0));\n>> -\t\tif (ret < 0)\n>> -\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n>> -\t\t\t\t  << \"'\" << std::endl;\n>> -\n>> -\t\treturn;\n>> +\t\tif (ret == -EINVAL) {\n>> +\t\t\tfilename += \".raw\";\n>> +\t\t\tstd::cerr << \"cannot write file in PPM format, writing `\"\n>> +\t\t\t\t  << filename << \"' instead\" << std::endl;\n>> +\t\t} else {\n>> +\t\t\tif (ret < 0)\n>> +\t\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n>> +\t\t\t\t\t  << \"'\" << std::endl;\n>> +\t\t\treturn;\n>> +\t\t}\n>>  \t}\n>>  \n>>  \tfd = open(filename.c_str(), O_CREAT | O_WRONLY |","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 53CFEBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jan 2025 12:13:50 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3E6DB6855D;\n\tMon, 27 Jan 2025 13:13:49 +0100 (CET)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3AB7468549\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jan 2025 13:13:47 +0100 (CET)","from mail-ej1-f69.google.com (mail-ej1-f69.google.com\n\t[209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-192-JD9hO5S4Mfu5y5Bkzwqjcg-1; Mon, 27 Jan 2025 07:13:44 -0500","by mail-ej1-f69.google.com with SMTP id\n\ta640c23a62f3a-aa67fcbb549so461387266b.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jan 2025 04:13:43 -0800 (PST)","from mzamazal-thinkpadp1gen3.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-ab675e121b8sm579758366b.30.2025.01.27.04.13.41\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 27 Jan 2025 04:13:41 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"Ark4OoHm\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1737980026;\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\tin-reply-to:in-reply-to:references:references;\n\tbh=uq/RmN7t/USutgn2AgAG6aQzWSrVElOgQhgHi1YI+DE=;\n\tb=Ark4OoHmzJlrPWfX6t0M1dCdbgsIqGrcWX9mvyO9oIn16/dp4/wK/NOFazOsUePjFu1FGf\n\t87i5BWHMUe5jZ1iM60yJ9/yGJOkp+bfqaVgLplq9j53fpO0ki9VaVGAbk5h09YPpd81X8V\n\twC9snzBAp1gnZkgzCOUdJ/EowaShH8w=","X-MC-Unique":"JD9hO5S4Mfu5y5Bkzwqjcg-1","X-Mimecast-MFC-AGG-ID":"JD9hO5S4Mfu5y5Bkzwqjcg","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1737980022; x=1738584822;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=uq/RmN7t/USutgn2AgAG6aQzWSrVElOgQhgHi1YI+DE=;\n\tb=MlVx+rwG8Y7mGemiAgkI/ImKyg56rioOpq/Z8ltmY3kBjdmtLoy3mCXjgPeusj1LN6\n\t2STbhpVBnpdPRQ0b04vxo60Z2KWM+2J8To3FIALvqfnr279sto60kToZcJWCzfIcLySC\n\tKu9mvuxpoacoOtAAnVTpwjGx25yXWOfRK44GlxbvaPmcNsRIRoVE3teD7yQEX8HEG3TG\n\tis5PZF9FhprUVTvImm7KgtDDJcPGWZZqQHSly7CC5JwGp6hDudWSu8YSm24hiBYsGwuG\n\t0s+2ovQW+hh8+2MMZvvbN33pKHHAhlPT/R0LlbvDRI5G5QXfjSlCIjGuZH2CMt6L8VB+\n\tBCug==","X-Gm-Message-State":"AOJu0Yw+PIaXB80AdS22cVDo/g8Y0rXvkWBZoRqfALIZSzB7tUmhkPaz\n\teQzgpQLzg93CWPDjSKPF9eDMJyJY2SigluDzOzjjBfvqQsi2JXDdY8xFvzlUXn5cWm9GaXHwdi/\n\tOfcjZGPnXBVecWvqAaHzY3hB8oafZvDrjRHasBCLX1FkCKaxNwLjG5mOl9pwBHUVEMS2t1rzV1K\n\tjzJm4V1uKtV+LyEsY+fjLItO39MaDsSyYvRRyjxirV6v6vQhNpneohVfY=","X-Gm-Gg":"ASbGncvSvoVKqpaU06dWvs6PsTpOsq24ntnYGDTslFo87fFGjsjczK/ZnmoderYsY7H\n\t+LHyur+49z7XtsHYHRPzWbXrLEI9y27txJ95+04aPDD3fHzTG6DvsHrsDf4DVG+2abZ4+gVLFAi\n\tQ2yRjPf3ISiYUGlQb6nwjR9SaxG6FxIp5XkX4HOhIwv6W+8W+cMsDKnU8FfM+TA35pY9GfFiMFD\n\tPtRShX6CMv9C2prOtxFZKQqEO5FgFsWRfBRYDihDbv7zoWPrKZH8oJhA22hixnpxxNdMj6GyrAD\n\td55lD6wAy0+ORgpAaFtDFDFuszTNdCBOjWI1//Dpu+FN4ER1Mo+1067ViA==","X-Received":["by 2002:a17:907:7f9f:b0:aab:d8de:217e with SMTP id\n\ta640c23a62f3a-ab38b163550mr3599150266b.26.1737980022356; \n\tMon, 27 Jan 2025 04:13:42 -0800 (PST)","by 2002:a17:907:7f9f:b0:aab:d8de:217e with SMTP id\n\ta640c23a62f3a-ab38b163550mr3599146366b.26.1737980021858; \n\tMon, 27 Jan 2025 04:13:41 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IEQsm9gVN7nDb8/GLCEq0CUsb6HWlG+16RkW3IdW0y1/Pg6gdShSLf96Nk+hOTMU6UDeFX1IQ==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","In-Reply-To":"<20250125210446.GH1805@pendragon.ideasonboard.com> (Laurent\n\tPinchart's message of \"Sat, 25 Jan 2025 23:04:46 +0200\")","References":"<20250124215806.158024-1-mzamazal@redhat.com>\n\t<20250124215806.158024-14-mzamazal@redhat.com>\n\t<20250125210446.GH1805@pendragon.ideasonboard.com>","Date":"Mon, 27 Jan 2025 13:13:40 +0100","Message-ID":"<851pwoo3nv.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"HmraHFS2L4gLA2XPbBHO1a0ORlArjjmjel7nCpc17kU_1737980023","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>"}},{"id":33212,"web_url":"https://patchwork.libcamera.org/comment/33212/","msgid":"<20250127174536.GL17899@pendragon.ideasonboard.com>","date":"2025-01-27T17:45:36","subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Mon, Jan 27, 2025 at 01:13:40PM +0100, Milan Zamazal wrote:\n> Laurent Pinchart writes:\n> > On Fri, Jan 24, 2025 at 10:58:04PM +0100, Milan Zamazal wrote:\n> >> `cam' application can be requested to write its output as a PPM file.\n> >> However, this is supported only for certain formats (only BGR888\n> >> currently).  If the output format cannot be written, `cam' reports an\n> >> error and doesn't write anything.\n> >> \n> >> This is all right with a single stream input but impractical with\n> >> multiple streams of different output formats (e.g. a processed stream +\n> >> a raw stream) where some of them can be written in the supported format\n> >> while the other not.  In such a case, it's better to write the supported\n> >> formats as PPM files and the unsupported formats as raw files, with the\n> >> corresponding warning on stderr.  `.raw' extension is added to the file\n> >> name in such a case to make clear it's not a PPM file.\n> >> \n> >> This is a sort of hack but serves the purpose for the moment.\n> >\n> > Should we instead change the -F option (and the -D and -S options too I\n> > suppose) to act at the stream level instead of the camera level ?\n> \n> Something like this would be useful.  But maybe rather than changing the\n> given options (how?),\n\nThe OptionParser class supports hierarchical options, the addOption()\nfunction takes a parent as its last argument.\n\n> it would be simpler to add a keyword to -s,\n> e.g. output=file/sdl/kms.  What do you think?\n\nThat's an interesting idea too. Should we then deprecate the -F, -D and\n-S options ? I'm a bit concerned about how disturbing that would be.\n\n> >> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> >> ---\n> >>  src/apps/cam/file_sink.cpp | 16 +++++++++++-----\n> >>  1 file changed, 11 insertions(+), 5 deletions(-)\n> >> \n> >> diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp\n> >> index 76e21db9..1a866137 100644\n> >> --- a/src/apps/cam/file_sink.cpp\n> >> +++ b/src/apps/cam/file_sink.cpp\n> >> @@ -7,6 +7,7 @@\n> >>  \n> >>  #include <array>\n> >>  #include <assert.h>\n> >> +#include <errno.h>\n> >>  #include <fcntl.h>\n> >>  #include <iomanip>\n> >>  #include <iostream>\n> >> @@ -133,11 +134,16 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer,\n> >>  \tif (fileType_ == FileType::Ppm) {\n> >>  \t\tret = PPMWriter::write(filename.c_str(), stream->configuration(),\n> >>  \t\t\t\t       image->data(0));\n> >> -\t\tif (ret < 0)\n> >> -\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n> >> -\t\t\t\t  << \"'\" << std::endl;\n> >> -\n> >> -\t\treturn;\n> >> +\t\tif (ret == -EINVAL) {\n> >> +\t\t\tfilename += \".raw\";\n> >> +\t\t\tstd::cerr << \"cannot write file in PPM format, writing `\"\n> >> +\t\t\t\t  << filename << \"' instead\" << std::endl;\n> >> +\t\t} else {\n> >> +\t\t\tif (ret < 0)\n> >> +\t\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n> >> +\t\t\t\t\t  << \"'\" << std::endl;\n> >> +\t\t\treturn;\n> >> +\t\t}\n> >>  \t}\n> >>  \n> >>  \tfd = open(filename.c_str(), O_CREAT | O_WRONLY |","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 DC8C5BDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 27 Jan 2025 17:45:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id E9E876855D;\n\tMon, 27 Jan 2025 18:45:48 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3ADB768549\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Jan 2025 18:45:48 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 1A3BABC0;\n\tMon, 27 Jan 2025 18:44:41 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"s6r3JeLh\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1737999881;\n\tbh=1wZAiqUlG/sUtq79CeXUlgA7AYVNrzenLrYjLn+aIlM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=s6r3JeLhT6tCM2753ktGeKxGjLdVRq0cqR3gTOxU3jJ+5ZWXhOGIuPtNm7GldH0rK\n\t5bS9x1QVQq64hT+e21AYFY2Ob67OzCyMMCfPh4lh6ssZRYeUCieNpHwjUQuLXdOo/+\n\tZ5D6wesZa+3xqtN9ZWlQ8iEh1nN1H4mPO6tny5mc=","Date":"Mon, 27 Jan 2025 19:45:36 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","Message-ID":"<20250127174536.GL17899@pendragon.ideasonboard.com>","References":"<20250124215806.158024-1-mzamazal@redhat.com>\n\t<20250124215806.158024-14-mzamazal@redhat.com>\n\t<20250125210446.GH1805@pendragon.ideasonboard.com>\n\t<851pwoo3nv.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<851pwoo3nv.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","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>"}},{"id":33592,"web_url":"https://patchwork.libcamera.org/comment/33592/","msgid":"<85senf8hwc.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-03-14T20:41:07","subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Laurent Pinchart <laurent.pinchart@ideasonboard.com> writes:\n\n> On Mon, Jan 27, 2025 at 01:13:40PM +0100, Milan Zamazal wrote:\n>> Laurent Pinchart writes:\n>> > On Fri, Jan 24, 2025 at 10:58:04PM +0100, Milan Zamazal wrote:\n>\n>> >> `cam' application can be requested to write its output as a PPM file.\n>> >> However, this is supported only for certain formats (only BGR888\n>> >> currently).  If the output format cannot be written, `cam' reports an\n>> >> error and doesn't write anything.\n>> >> \n>> >> This is all right with a single stream input but impractical with\n>> >> multiple streams of different output formats (e.g. a processed stream +\n>> >> a raw stream) where some of them can be written in the supported format\n>> >> while the other not.  In such a case, it's better to write the supported\n>> >> formats as PPM files and the unsupported formats as raw files, with the\n>> >> corresponding warning on stderr.  `.raw' extension is added to the file\n>> >> name in such a case to make clear it's not a PPM file.\n>> >> \n>> >> This is a sort of hack but serves the purpose for the moment.\n>> >\n>> > Should we instead change the -F option (and the -D and -S options too I\n>> > suppose) to act at the stream level instead of the camera level ?\n>> \n>> Something like this would be useful.  But maybe rather than changing the\n>> given options (how?),\n>\n> The OptionParser class supports hierarchical options, the addOption()\n> function takes a parent as its last argument.\n\nEventually, I decided to add new options to act at the stream level and\nkeeping the original ones to act at the camera level.  Hopefully to get\nthe best of both.\n\nUnfortunately, it's more complicated (and more work) than I initially\nexpected.  I posted RFC patches, let's see.  One bug fix and some\ncleanup included.\n\n>> it would be simpler to add a keyword to -s,\n>> e.g. output=file/sdl/kms.  What do you think?\n>\n> That's an interesting idea too.\n\nI rejected the idea because it doesn't match well with what happens with\nthe stream keywords.\n\n> Should we then deprecate the -F, -D and -S options ? I'm a bit\n> concerned about how disturbing that would be.\n>\n>> >> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> >> ---\n>> >>  src/apps/cam/file_sink.cpp | 16 +++++++++++-----\n>> >>  1 file changed, 11 insertions(+), 5 deletions(-)\n>> >> \n>> >> diff --git a/src/apps/cam/file_sink.cpp b/src/apps/cam/file_sink.cpp\n>> >> index 76e21db9..1a866137 100644\n>> >> --- a/src/apps/cam/file_sink.cpp\n>> >> +++ b/src/apps/cam/file_sink.cpp\n>> >> @@ -7,6 +7,7 @@\n>> >>  \n>> >>  #include <array>\n>> >>  #include <assert.h>\n>> >> +#include <errno.h>\n>> >>  #include <fcntl.h>\n>> >>  #include <iomanip>\n>> >>  #include <iostream>\n>> >> @@ -133,11 +134,16 @@ void FileSink::writeBuffer(const Stream *stream, FrameBuffer *buffer,\n>> >>  \tif (fileType_ == FileType::Ppm) {\n>> >>  \t\tret = PPMWriter::write(filename.c_str(), stream->configuration(),\n>> >>  \t\t\t\t       image->data(0));\n>> >> -\t\tif (ret < 0)\n>> >> -\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n>> >> -\t\t\t\t  << \"'\" << std::endl;\n>> >> -\n>> >> -\t\treturn;\n>> >> +\t\tif (ret == -EINVAL) {\n>> >> +\t\t\tfilename += \".raw\";\n>> >> +\t\t\tstd::cerr << \"cannot write file in PPM format, writing `\"\n>> >> +\t\t\t\t  << filename << \"' instead\" << std::endl;\n>> >> +\t\t} else {\n>> >> +\t\t\tif (ret < 0)\n>> >> +\t\t\t\tstd::cerr << \"failed to write PPM file `\" << filename\n>> >> +\t\t\t\t\t  << \"'\" << std::endl;\n>> >> +\t\t\treturn;\n>> >> +\t\t}\n>> >>  \t}\n>> >>  \n>> >>  \tfd = open(filename.c_str(), O_CREAT | O_WRONLY |","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 32CF4C32F4\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Mar 2025 20:41:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3647B68777;\n\tFri, 14 Mar 2025 21:41:15 +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 3361968777\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Mar 2025 21:41:13 +0100 (CET)","from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n\t[209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-625-D4aM82idPi2etmHAh3hHtw-1; Fri, 14 Mar 2025 16:41:10 -0400","by mail-wr1-f69.google.com with SMTP id\n\tffacd0b85a97d-3912d9848a7so1897431f8f.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Mar 2025 13:41:10 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-43d1ffb62c1sm27666535e9.4.2025.03.14.13.41.07\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 14 Mar 2025 13:41:08 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"Y9O2ui+w\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1741984872;\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\tin-reply-to:in-reply-to:references:references;\n\tbh=u5whm6LVNuWNWh5UHJdZ5dgFyzkpoonvDxr/q8/+iGU=;\n\tb=Y9O2ui+waNwXcdeaUKYt2XalnbHwjAZrsOIaaELo68zN5Bgj7PqUqbFpNPLv7BZneJiuA4\n\tw7/LZVP7Ew52vwFDMW5NIbFKI6aFILI32gO5UhJTDDCo1a+EIaIiE5pSta3EoIcJdm7aXO\n\tL2PUijwnD0oYH8sefVeBEeFoRM7WPL8=","X-MC-Unique":"D4aM82idPi2etmHAh3hHtw-1","X-Mimecast-MFC-AGG-ID":"D4aM82idPi2etmHAh3hHtw_1741984870","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1741984869; x=1742589669;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=u5whm6LVNuWNWh5UHJdZ5dgFyzkpoonvDxr/q8/+iGU=;\n\tb=TP5izUMXdn/m8r6mSPoczhyPfsuGzQ9b/MyIwU64CRN7+YAwTYoXUYSFFCLPSdEwnl\n\tQYGLNSCDFMMVVxRniB8s/LereQG4vw/Gr6JEkbVptJp6CrRRUPT9URXisMPPXIimm1tP\n\t/DG73mljkRAbRuCZzbygnixAQzT5v80nNEdh3ErQvqm+YUrrSHu7EtEECHbVJXsiU/WV\n\tgilAhNUVtIQO28WoaBvr8F5kqSQ0mfEHHFo3xrHrjSoVglkzv/0Ho9jswWPu1XK3ZtQE\n\twWMlqwwuaeT2wNFznWfV79XwkzMh7XhomUVOWnWC5/+kTF8hwFqnp+bBM93ismj4cvLO\n\tamJQ==","X-Gm-Message-State":"AOJu0YwFznGZeekFVua9ni8SLM/dQylJ1HzjjZuo3OpnOi0bNDxY1Lu2\n\t6hiCCIIdSnZMwU0w+ewvPY4lCUTB+dKwyawQeOCBAv8QYTX2WpDnQkk4FmHQQiQ280ZLSlPv58v\n\tqeGNkVNcLQ+HrZpw8aQQFdWezCjfbGmKyC0SZBkYH4R6Oq5zY6vVzN3kf6+sKde8fJoQm05fZSC\n\tzZ34e9p3jY3un7849mac2/Cr+BfE+n415RdeGN556nnqKd9q4dE26ZYQg=","X-Gm-Gg":"ASbGncsLRU1oh6m2lsD5P2I1we9lQ/zdLND5dwhL6dLxrRf4UVDwS/SNWeVjR8K/q4Y\n\tYcm7wYHQIQzPoJX3THTEsxmic1p5v5Mj0iZ5U/uBmnRt1qco//QjqS8doaYcoegxr2OVcxndIfI\n\t8xFktM3qYDRacMohXe94PnqVe5QCVgPNEBF2/OTfD7TRrlf/3lbyb1USrTkfC0f0VcsAaLnHJHy\n\tGTITi0vicVlRkgkmoi/kNdJ66OPxs1IgtBcsq/tMkK9QTr2sIpxUyB9GL97Qk+YIYXVEHsmxEky\n\tGM0YgHK0eR36lccly5o90GLe05HQaqeyNtCfo+30VV6gCx30KD1HIoNTCYq8gdItTF4a","X-Received":["by 2002:a5d:5f46:0:b0:391:386d:5971 with SMTP id\n\tffacd0b85a97d-395b7a5c328mr8585464f8f.14.1741984869186; \n\tFri, 14 Mar 2025 13:41:09 -0700 (PDT)","by 2002:a5d:5f46:0:b0:391:386d:5971 with SMTP id\n\tffacd0b85a97d-395b7a5c328mr8585445f8f.14.1741984868774; \n\tFri, 14 Mar 2025 13:41:08 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IFc0fge9IjeDG5oPNu5dbOsmHq0BiueCKzrZJq8CrFV9W+jIMOOzeBkctg6GuOf/Z4wC1qz4w==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [RFC PATCH v2 13/13] apps: cam: Write raw file if PPM cannot be\n\twritten","In-Reply-To":"<20250127174536.GL17899@pendragon.ideasonboard.com> (Laurent\n\tPinchart's message of \"Mon, 27 Jan 2025 19:45:36 +0200\")","References":"<20250124215806.158024-1-mzamazal@redhat.com>\n\t<20250124215806.158024-14-mzamazal@redhat.com>\n\t<20250125210446.GH1805@pendragon.ideasonboard.com>\n\t<851pwoo3nv.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>\n\t<20250127174536.GL17899@pendragon.ideasonboard.com>","Date":"Fri, 14 Mar 2025 21:41:07 +0100","Message-ID":"<85senf8hwc.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"IxjxDto0fhdns7h0qYMJCV7bEnefgTMIb0iJ6k7blf4_1741984870","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>"}}]