summaryrefslogtreecommitdiff
path: root/kms++util/src/conv-yuv-packed.h
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-02-02 11:26:23 +0200
committerTomi Valkeinen <tomi.valkeinen@ideasonboard.com>2025-03-26 15:44:00 +0200
commitf758e324e17b52116075bb9175a3dd03d223a424 (patch)
treeb18fba90e2b8498f8228f3eff9bc60adf3153cf2 /kms++util/src/conv-yuv-packed.h
parent6c49fe5b811464f59e3a31b869734071da0ec7c1 (diff)
kms++util: New template based conversion & testpat code
New templated conversion and test pattern code. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Diffstat (limited to 'kms++util/src/conv-yuv-packed.h')
-rw-r--r--kms++util/src/conv-yuv-packed.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/kms++util/src/conv-yuv-packed.h b/kms++util/src/conv-yuv-packed.h
new file mode 100644
index 0000000..3aa01fa
--- /dev/null
+++ b/kms++util/src/conv-yuv-packed.h
@@ -0,0 +1,83 @@
+#pragma once
+
+#include <vector>
+
+#include <kms++/framebuffer.h>
+#include <kms++util/color16.h>
+
+#include "conv-common.h"
+
+namespace kms
+{
+
+/* YUV Packed */
+
+template<ComponentType C0, ComponentType C1, ComponentType C2, ComponentType C3>
+struct YUV_Packed_Format
+ : public FormatLayout<
+ PlaneLayout<uint32_t,
+ ComponentLayout<C0, 8, 0>,
+ ComponentLayout<C1, 8, 8>,
+ ComponentLayout<C2, 8, 16>,
+ ComponentLayout<C3, 8, 24>
+ >
+ >
+{
+};
+
+// Define common packed YUV formats
+using YUYV_Layout = YUV_Packed_Format<ComponentType::Y0, ComponentType::Cb,
+ ComponentType::Y1, ComponentType::Cr>;
+
+using YVYU_Layout = YUV_Packed_Format<ComponentType::Y0, ComponentType::Cr,
+ ComponentType::Y1, ComponentType::Cb>;
+
+using UYVY_Layout = YUV_Packed_Format<ComponentType::Cb, ComponentType::Y0,
+ ComponentType::Cr, ComponentType::Y1>;
+
+using VYUY_Layout = YUV_Packed_Format<ComponentType::Cr, ComponentType::Y0,
+ ComponentType::Cb, ComponentType::Y1>;
+
+template<typename Layout>
+class YUVPackedWriter
+{
+ using Plane = Layout::template plane<0>;
+ using TStorage = Plane::storage_type;
+
+ static constexpr size_t y0_pos = Plane::template find_pos<ComponentType::Y0>();
+ static constexpr size_t y1_pos = Plane::template find_pos<ComponentType::Y1>();
+ static constexpr size_t cb_pos = Plane::template find_pos<ComponentType::Cb>();
+ static constexpr size_t cr_pos = Plane::template find_pos<ComponentType::Cr>();
+
+public:
+ static void write_pattern(IFramebuffer& fb, size_t start_y, size_t end_y,
+ auto&& generate_line)
+ {
+ std::vector<YUV16> linebuf(fb.width());
+
+ auto view = make_strided_fb_view<TStorage>(fb.map(0), fb.height(),
+ fb.width() / 2, // Two pixels per storage unit
+ fb.stride(0));
+
+ for (size_t y = start_y; y <= end_y; y++) {
+ generate_line(y, linebuf);
+
+ for (size_t x = 0; x < fb.width(); x += 2) {
+ // Get two pixels
+ const YUV16& pix0 = linebuf[x];
+ const YUV16& pix1 = linebuf[x + 1];
+
+ std::array<uint8_t, 4> components;
+
+ components[y0_pos] = pix0.y >> 8;
+ components[y1_pos] = pix1.y >> 8;
+ components[cb_pos] = ((pix0.u + pix1.u) / 2) >> 8;
+ components[cr_pos] = ((pix0.v + pix1.v) / 2) >> 8;
+
+ view(y, x / 2) = Plane::pack(components);
+ }
+ }
+ }
+};
+
+} // namespace kms