summaryrefslogtreecommitdiff
path: root/src/apps/common/ppm_writer.cpp
blob: d6c8641d8b3382ac743fedcc131f8c2b3cd0ace6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2024 Red Hat, Inc.
 *
 * PPM writer
 */

#include "ppm_writer.h"

#include <fstream>
#include <iostream>

#include <libcamera/formats.h>
#include <libcamera/pixel_format.h>

using namespace libcamera;

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;
		return -EINVAL;
	}

	std::ofstream output(filename, std::ios::binary);
	if (!output) {
		std::cerr << "Failed to open ppm file: " << filename << std::endl;
		return -EINVAL;
	}

	output << "P6" << std::endl
	       << config.size.width << " " << config.size.height << std::endl
	       << "255" << std::endl;
	if (!output) {
		std::cerr << "Failed to write the file header" << std::endl;
		return -EINVAL;
	}

	const unsigned int rowLength = config.size.width * 3;
	const char *row = reinterpret_cast<const char *>(data.data());
	for (unsigned int y = 0; y < config.size.height; y++, row += config.stride) {
		output.write(row, rowLength);
		if (!output) {
			std::cerr << "Failed to write image data at row " << y << std::endl;
			return -EINVAL;
		}
	}

	return 0;
}