summaryrefslogtreecommitdiff
path: root/subprojects/pixpat/pixpat-native/src/pipeline.h
blob: 09e13bced400ae65ef9880fa865c1f8f1cd6910b (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
#pragma once

#include <cstddef>

#include "color.h"
#include "layout.h"

// Inlined source → color → sink composition. The intermediate Pixel
// values stay in registers across stages; there is no normalized RGB16
// or YUV16 buffer between source and sink. Block size is dictated by
// the sink: 1x1 for non-subsampled formats, h_sub × v_sub for chroma-
// subsampled ones.

namespace pixpat
{

template <typename Source, typename Sink>
struct Converter {
	using Xfm = ColorXfm<typename Source::Pixel, typename Sink::Pixel>;
	static constexpr size_t bh = Sink::block_h;
	static constexpr size_t bw = Sink::block_w;

	static void run(const Buffer<Source::Layout::num_planes>& src,
	                Buffer<Sink::Layout::num_planes>& dst,
	                size_t W, size_t H,
	                size_t by_start, size_t by_end,
	                ColorSpec spec) noexcept
	{
		const ColorCoeffs c = coeffs_for(spec);
		for (size_t by = by_start; by < by_end; by += bh) {
			for (size_t bx = 0; bx < W; bx += bw) {
				typename Sink::Pixel block[bh][bw];
				for (size_t dy = 0; dy < bh; ++dy)
					for (size_t dx = 0; dx < bw; ++dx)
						block[dy][dx] = Xfm::apply(
							Source::read(src, bx + dx, by + dy,
							             W, H), c);
				Sink::write_block(dst, bx, by, block);
			}
		}
	}
};

} // namespace pixpat