apps: cam: Support PPM output for other RGB formats
GPU ISP can produce only 32-bit output. Let's add support to the PPM writer for all the common RGB image formats so that we can store GPU ISP output as PPM files. Contingent alpha values are ignored as there is no support for the alpha channel in PPM. There is no obvious performance penalty in my environment compared to output in the raw format. Signed-off-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Milan Zamazal <mzamazal@redhat.com> Reviewed-by: Pavel Machek <pavel@ucw.cz> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
committed by
Kieran Bingham
parent
67220496ed
commit
baea40a8a5
@@ -10,6 +10,7 @@
|
||||
#include <errno.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include <libcamera/formats.h>
|
||||
#include <libcamera/pixel_format.h>
|
||||
@@ -20,9 +21,34 @@ int PPMWriter::write(const char *filename,
|
||||
const StreamConfiguration &config,
|
||||
const Span<uint8_t> &data)
|
||||
{
|
||||
if (config.pixelFormat != formats::BGR888) {
|
||||
std::cerr << "Only BGR888 output pixel format is supported ("
|
||||
<< config.pixelFormat << " requested)" << std::endl;
|
||||
struct FormatTransformation {
|
||||
unsigned int rPos;
|
||||
unsigned int gPos;
|
||||
unsigned int bPos;
|
||||
unsigned int bytesPerPixel;
|
||||
};
|
||||
|
||||
static const std::map<libcamera::PixelFormat, FormatTransformation> transforms = {
|
||||
{ libcamera::formats::R8, { 0, 0, 0, 1 } },
|
||||
{ libcamera::formats::RGB888, { 2, 1, 0, 3 } },
|
||||
{ libcamera::formats::BGR888, { 0, 1, 2, 3 } },
|
||||
{ libcamera::formats::ARGB8888, { 2, 1, 0, 4 } },
|
||||
{ libcamera::formats::XRGB8888, { 2, 1, 0, 4 } },
|
||||
{ libcamera::formats::ABGR8888, { 0, 1, 2, 4 } },
|
||||
{ libcamera::formats::XBGR8888, { 0, 1, 2, 4 } },
|
||||
{ libcamera::formats::RGBA8888, { 3, 2, 1, 4 } },
|
||||
{ libcamera::formats::RGBX8888, { 3, 2, 1, 4 } },
|
||||
{ libcamera::formats::BGRA8888, { 1, 2, 3, 4 } },
|
||||
{ libcamera::formats::BGRX8888, { 1, 2, 3, 4 } },
|
||||
};
|
||||
|
||||
FormatTransformation transformation;
|
||||
if (auto search = transforms.find(config.pixelFormat); search != transforms.end()) {
|
||||
transformation = search->second;
|
||||
} else {
|
||||
std::cerr
|
||||
<< "Only RGB output pixel formats are supported ("
|
||||
<< config.pixelFormat << " requested)" << std::endl;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -42,8 +68,22 @@ int PPMWriter::write(const char *filename,
|
||||
|
||||
const unsigned int rowLength = config.size.width * 3;
|
||||
const char *row = reinterpret_cast<const char *>(data.data());
|
||||
const bool transform = config.pixelFormat != formats::BGR888;
|
||||
std::vector<char> transformedRow(transform ? rowLength : 0);
|
||||
|
||||
for (unsigned int y = 0; y < config.size.height; y++, row += config.stride) {
|
||||
output.write(row, rowLength);
|
||||
if (transform) {
|
||||
for (unsigned int x = 0; x < config.size.width; x++) {
|
||||
transformedRow[x * 3] =
|
||||
row[x * transformation.bytesPerPixel + transformation.rPos];
|
||||
transformedRow[x * 3 + 1] =
|
||||
row[x * transformation.bytesPerPixel + transformation.gPos];
|
||||
transformedRow[x * 3 + 2] =
|
||||
row[x * transformation.bytesPerPixel + transformation.bPos];
|
||||
}
|
||||
}
|
||||
|
||||
output.write(transform ? transformedRow.data() : row, rowLength);
|
||||
if (!output) {
|
||||
std::cerr << "Failed to write image data at row " << y << std::endl;
|
||||
return -EIO;
|
||||
|
||||
Reference in New Issue
Block a user