From e0b7d30fd437292c88141fb08d60681870b86c6e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 May 2026 17:22:58 +0300 Subject: Squashed 'subprojects/pixpat/' content from commit d444626 git-subtree-dir: subprojects/pixpat git-subtree-split: d444626e6ba988ec6d487800721e447f94b1eaf5 --- pixpat-native/src/formats/bayer.h | 97 +++++++++++ pixpat-native/src/formats/grayscale.h | 78 +++++++++ pixpat-native/src/formats/rgb.h | 267 +++++++++++++++++++++++++++++ pixpat-native/src/formats/yuv_packed.h | 136 +++++++++++++++ pixpat-native/src/formats/yuv_planar.h | 76 ++++++++ pixpat-native/src/formats/yuv_semiplanar.h | 79 +++++++++ 6 files changed, 733 insertions(+) create mode 100644 pixpat-native/src/formats/bayer.h create mode 100644 pixpat-native/src/formats/grayscale.h create mode 100644 pixpat-native/src/formats/rgb.h create mode 100644 pixpat-native/src/formats/yuv_packed.h create mode 100644 pixpat-native/src/formats/yuv_planar.h create mode 100644 pixpat-native/src/formats/yuv_semiplanar.h (limited to 'pixpat-native/src/formats') diff --git a/pixpat-native/src/formats/bayer.h b/pixpat-native/src/formats/bayer.h new file mode 100644 index 0000000..057c342 --- /dev/null +++ b/pixpat-native/src/formats/bayer.h @@ -0,0 +1,97 @@ +#pragma once + +// Bayer raw layouts. Each pixel carries one of R/G/B selected by +// (x mod 2, y mod 2) and BayerOrder; the pattern is on the +// BayerSource/BayerSink template, not the layout itself. Storage shape +// is single-component (C::Y reused as the storage tag) so the same +// 8/10/12/16-bit shapes apply across all four phase patterns. +// +// Each format is a distinct struct (rather than a type alias of one +// another) so each format type can carry its own pattern-specific +// Source/Sink aliases. The shared bit layout lives in a base struct per +// (depth,packing) combination. +// +// ColorKind is RGB because the normalized pixel passed through ColorXfm +// is RGB16 — the sink picks one of r/g/b at write time, and the +// source nearest-neighbor demosaics into RGB16 at read time. + +#include "../layout.h" +#include "../io/bayer.h" + +namespace pixpat::formats +{ + +namespace bayer_detail +{ + +// Per-(depth,packing) base layouts. Every Bayer format derives from +// one of these and pins its own pattern-specific I/O templates. +using Bayer8 = Layout >; +using Bayer10 = Layout >; +using Bayer12 = Layout >; +using Bayer16 = Layout >; +// MIPI CSI-2 packed Bayer (10P: 4 pix in 5 bytes; 12P: 2 pix in 3 +// bytes). The Layout doesn't capture the packed bit layout — the +// BayerPackedSink hand-rolls the byte writes. uint8_t plane shape is +// a placeholder so the dispatch plumbing is uniform. +using Bayer10P = Layout >; +using Bayer12P = Layout >; + +} // namespace bayer_detail + +// Unpacked Bayer (4 patterns × 4 bit depths). +#define PIXPAT_BAYER(name, base, pat) \ + struct name : bayer_detail::base { \ + using Source = BayerSource_ ## pat; \ + using Sink = BayerSink_ ## pat; \ + } + +PIXPAT_BAYER(SRGGB8, Bayer8, RGGB); +PIXPAT_BAYER(SBGGR8, Bayer8, BGGR); +PIXPAT_BAYER(SGRBG8, Bayer8, GRBG); +PIXPAT_BAYER(SGBRG8, Bayer8, GBRG); + +PIXPAT_BAYER(SRGGB10, Bayer10, RGGB); +PIXPAT_BAYER(SBGGR10, Bayer10, BGGR); +PIXPAT_BAYER(SGRBG10, Bayer10, GRBG); +PIXPAT_BAYER(SGBRG10, Bayer10, GBRG); + +PIXPAT_BAYER(SRGGB12, Bayer12, RGGB); +PIXPAT_BAYER(SBGGR12, Bayer12, BGGR); +PIXPAT_BAYER(SGRBG12, Bayer12, GRBG); +PIXPAT_BAYER(SGBRG12, Bayer12, GBRG); + +PIXPAT_BAYER(SRGGB16, Bayer16, RGGB); +PIXPAT_BAYER(SBGGR16, Bayer16, BGGR); +PIXPAT_BAYER(SGRBG16, Bayer16, GRBG); +PIXPAT_BAYER(SGBRG16, Bayer16, GBRG); + +#undef PIXPAT_BAYER + +// MIPI-packed Bayer: pattern + bit depth both encoded in the I/O +// template name (BayerPackedSource_RGGB10, ...). +#define PIXPAT_BAYER_PACKED(name, base, pat_depth) \ + struct name : bayer_detail::base { \ + using Source = BayerPackedSource_ ## pat_depth; \ + using Sink = BayerPackedSink_ ## pat_depth; \ + } + +PIXPAT_BAYER_PACKED(SRGGB10P, Bayer10P, RGGB10); +PIXPAT_BAYER_PACKED(SBGGR10P, Bayer10P, BGGR10); +PIXPAT_BAYER_PACKED(SGRBG10P, Bayer10P, GRBG10); +PIXPAT_BAYER_PACKED(SGBRG10P, Bayer10P, GBRG10); + +PIXPAT_BAYER_PACKED(SRGGB12P, Bayer12P, RGGB12); +PIXPAT_BAYER_PACKED(SBGGR12P, Bayer12P, BGGR12); +PIXPAT_BAYER_PACKED(SGRBG12P, Bayer12P, GRBG12); +PIXPAT_BAYER_PACKED(SGBRG12P, Bayer12P, GBRG12); + +#undef PIXPAT_BAYER_PACKED + +} // namespace pixpat::formats diff --git a/pixpat-native/src/formats/grayscale.h b/pixpat-native/src/formats/grayscale.h new file mode 100644 index 0000000..b1cd294 --- /dev/null +++ b/pixpat-native/src/formats/grayscale.h @@ -0,0 +1,78 @@ +#pragma once + +// Single-component-per-pixel formats. Most are grayscale (Y) modeled as +// a YUV format with synthesized neutral chroma; R8 is the RGB-kind +// counterpart, modeled grey-style with G=B=R on read. Y10/Y12 carry an +// explicit X padding bitfield. XYYY2101010 is multi-pixel-per-word: 3 Y +// samples in 32 bits. + +#include "../layout.h" +#include "../io/gray.h" +#include "../io/gray_packed.h" +#include "../io/mono_rgb.h" + +namespace pixpat::formats +{ + +#define PIXPAT_GRAY(name, ...) \ + struct name : Layout { \ + using Source = GraySource; \ + using Sink = GraySink; \ + } + +PIXPAT_GRAY(Y8, + Plane); + +PIXPAT_GRAY(Y10, + Plane); + +PIXPAT_GRAY(Y12, + Plane); + +PIXPAT_GRAY(Y16, + Plane); + +#undef PIXPAT_GRAY + +// R8: single 8-bit R channel. Read synthesizes G=B=R; write encodes R +// and drops G/B/A. Symmetric to Y8 but ColorKind::RGB so cross-pipeline +// conversions go through the RGB->YUV ColorXfm direction. +struct R8 : Layout > { + using Source = MonoRGBSource; + using Sink = MonoRGBSink; +}; + +struct XYYY2101010 : Layout > { + using Source = MultiPixelGraySource; + using Sink = MultiPixelGraySink; +}; + +// MIPI CSI-2 packed grayscale (Y10P / Y12P). The Layout doesn't capture +// the packed bit layout — GrayPackedSource/Sink delegate to the shared +// CSI-2 helper (io/csi2.h). uint8_t plane shape is a placeholder so +// dispatch plumbing is uniform (mirrors bayer_detail::Bayer10P/12P). +namespace gray_csi2_detail +{ +using Gray10P = Layout >; +using Gray12P = Layout >; +} // namespace gray_csi2_detail + +struct Y10P : gray_csi2_detail::Gray10P { + using Source = GrayPackedSource; + using Sink = GrayPackedSink; +}; + +struct Y12P : gray_csi2_detail::Gray12P { + using Source = GrayPackedSource; + using Sink = GrayPackedSink; +}; + +} // namespace pixpat::formats diff --git a/pixpat-native/src/formats/rgb.h b/pixpat-native/src/formats/rgb.h new file mode 100644 index 0000000..19d007a --- /dev/null +++ b/pixpat-native/src/formats/rgb.h @@ -0,0 +1,267 @@ +#pragma once + +// RGB packed layouts: 8-bit / 16-bit (sub-byte) / 32-bit (10-bit) / +// 64-bit-normalized, all single-plane single-pixel-per-storage-word. +// Names follow the kms++/pixutils register-order convention (MSB-first +// in the storage word), so XRGB8888 has X at bits 31..24 and B at 7..0. + +#include "../layout.h" +#include "../io/packed.h" + +namespace pixpat::formats +{ + +// Helper: every format in this file pairs with PackedSource/PackedSink. +// Each format struct exposes Source / Sink aliases so the catalog row +// in format_catalog.h can stay name-only. +#define PIXPAT_RGB_PACKED(name, ...) \ + struct name : Layout { \ + using Source = PackedSource; \ + using Sink = PackedSink; \ + } + +// --------------------------------------------------------------------- +// 32-bit packed RGB, 8-bit components. +// --------------------------------------------------------------------- + +PIXPAT_RGB_PACKED(XRGB8888, + Plane); + +PIXPAT_RGB_PACKED(ARGB8888, + Plane); + +PIXPAT_RGB_PACKED(XBGR8888, + Plane); + +PIXPAT_RGB_PACKED(ABGR8888, + Plane); + +PIXPAT_RGB_PACKED(RGBX8888, + Plane); + +PIXPAT_RGB_PACKED(RGBA8888, + Plane); + +PIXPAT_RGB_PACKED(BGRX8888, + Plane); + +PIXPAT_RGB_PACKED(BGRA8888, + Plane); + +// --------------------------------------------------------------------- +// 24-bit packed RGB, three bytes per pixel. storage_t is uint32_t but +// only bytes_per_pixel = 3 are read/written via memcpy. +// --------------------------------------------------------------------- + +PIXPAT_RGB_PACKED(RGB888, + Plane); + +PIXPAT_RGB_PACKED(BGR888, + Plane); + +// --------------------------------------------------------------------- +// 16-bit packed RGB, sub-byte components. +// --------------------------------------------------------------------- + +PIXPAT_RGB_PACKED(RGB565, + Plane); + +PIXPAT_RGB_PACKED(BGR565, + Plane); + +// 8-bit packed RGB: 3-bit R / 3-bit G / 2-bit B in a single byte. + +PIXPAT_RGB_PACKED(RGB332, + Plane); + +PIXPAT_RGB_PACKED(XRGB1555, + Plane); + +PIXPAT_RGB_PACKED(ARGB1555, + Plane); + +PIXPAT_RGB_PACKED(XBGR1555, + Plane); + +PIXPAT_RGB_PACKED(ABGR1555, + Plane); + +PIXPAT_RGB_PACKED(XRGB4444, + Plane); + +PIXPAT_RGB_PACKED(ARGB4444, + Plane); + +PIXPAT_RGB_PACKED(XBGR4444, + Plane); + +PIXPAT_RGB_PACKED(ABGR4444, + Plane); + +PIXPAT_RGB_PACKED(RGBX4444, + Plane); + +PIXPAT_RGB_PACKED(RGBA4444, + Plane); + +// --------------------------------------------------------------------- +// 32-bit packed RGB, 10-bit components. +// --------------------------------------------------------------------- + +PIXPAT_RGB_PACKED(XRGB2101010, + Plane); + +PIXPAT_RGB_PACKED(ARGB2101010, + Plane); + +PIXPAT_RGB_PACKED(XBGR2101010, + Plane); + +PIXPAT_RGB_PACKED(ABGR2101010, + Plane); + +PIXPAT_RGB_PACKED(RGBX1010102, + Plane); + +PIXPAT_RGB_PACKED(RGBA1010102, + Plane); + +PIXPAT_RGB_PACKED(BGRX1010102, + Plane); + +PIXPAT_RGB_PACKED(BGRA1010102, + Plane); + +// --------------------------------------------------------------------- +// 64-bit normalized wide RGB (16 bits per component). +// --------------------------------------------------------------------- + +PIXPAT_RGB_PACKED(ABGR16161616, + Plane); + +#undef PIXPAT_RGB_PACKED + +} // namespace pixpat::formats diff --git a/pixpat-native/src/formats/yuv_packed.h b/pixpat-native/src/formats/yuv_packed.h new file mode 100644 index 0000000..8e88f10 --- /dev/null +++ b/pixpat-native/src/formats/yuv_packed.h @@ -0,0 +1,136 @@ +#pragma once + +// Packed YUV layouts: +// VUY888 — 1 pixel / 24-bit, 8-bit Y/U/V (storage uint32_t, +// bytes_per_pixel = 3; parallels BGR888 in the YUV +// register order) +// XVUY8888 — 1 pixel / 32-bit word, 8-bit Y/U/V + 8-bit padding +// XVUY2101010 — 1 pixel / 32-bit word, 10-bit Y/U/V + 2-bit padding +// AVUY16161616 — 1 pixel / 64-bit word, 16-bit Y/U/V/A (normalized) +// YUYV / YVYU / UYVY / VYUY — 4:2:2, 2 pixels / 32-bit word +// Y210 / Y212 / Y216 — 4:2:2, 2 pixels / 64-bit word, with +// each component MSB-aligned in a 16-bit slot +// +// XVUY/AVUY name is register MSB-first (X/A in the top bits). The +// YUYV names follow V4L2 / pixpat memory-byte order (Y0 in byte 0), +// so shifts ascend in name order — opposite of XRGB-style. + +#include "../layout.h" +#include "../io/packed.h" +#include "../io/packed_yuv.h" + +namespace pixpat::formats +{ + +// 1-pixel-per-word packed (single Pixel/Word; uses PackedSource/Sink). + +struct VUY888 : Layout > { + using Source = PackedSource; + using Sink = PackedSink; +}; + +struct XVUY8888 : Layout > { + using Source = PackedSource; + using Sink = PackedSink; +}; + +struct XVUY2101010 : Layout > { + using Source = PackedSource; + using Sink = PackedSink; +}; + +struct AVUY16161616 : Layout > { + using Source = PackedSource; + using Sink = PackedSink; +}; + +// 2-pixel-per-word 4:2:2 (uses PackedYUVSource/Sink). + +#define PIXPAT_PACKED_YUV422(name, ...) \ + struct name : Layout > { \ + using Source = PackedYUVSource; \ + using Sink = PackedYUVSink; \ + } + +PIXPAT_PACKED_YUV422(YUYV, + Comp{ C::Y, 8, 0 }, Comp{ C::U, 8, 8 }, + Comp{ C::Y, 8, 16 }, Comp{ C::V, 8, 24 }); + +PIXPAT_PACKED_YUV422(YVYU, + Comp{ C::Y, 8, 0 }, Comp{ C::V, 8, 8 }, + Comp{ C::Y, 8, 16 }, Comp{ C::U, 8, 24 }); + +PIXPAT_PACKED_YUV422(UYVY, + Comp{ C::U, 8, 0 }, Comp{ C::Y, 8, 8 }, + Comp{ C::V, 8, 16 }, Comp{ C::Y, 8, 24 }); + +PIXPAT_PACKED_YUV422(VYUY, + Comp{ C::V, 8, 0 }, Comp{ C::Y, 8, 8 }, + Comp{ C::U, 8, 16 }, Comp{ C::Y, 8, 24 }); + +#undef PIXPAT_PACKED_YUV422 + +// Y210 / Y212 / Y216: 4:2:2, 2 pixels per 64-bit word, MSB-aligned in +// 16-bit slots. Y210 has 6 unused LSBs per slot, Y212 has 4, Y216 has +// none. The X padding entries pad total_bits to 64 so bytes_per_pixel +// resolves to 8; PackedYUVSink leaves their slots zero via the +// value-array zero-init (see io/packed_yuv.h). +struct Y210 : Layout > { + using Source = PackedYUVSource; + using Sink = PackedYUVSink; +}; + +struct Y212 : Layout > { + using Source = PackedYUVSource; + using Sink = PackedYUVSink; +}; + +struct Y216 : Layout > { + using Source = PackedYUVSource; + using Sink = PackedYUVSink; +}; + +} // namespace pixpat::formats diff --git a/pixpat-native/src/formats/yuv_planar.h b/pixpat-native/src/formats/yuv_planar.h new file mode 100644 index 0000000..bb6a415 --- /dev/null +++ b/pixpat-native/src/formats/yuv_planar.h @@ -0,0 +1,76 @@ +#pragma once + +// YUV planar layouts: 3 separate planes (Y, then U/V or V/U), 8-bit +// components. +// YUV420/YVU420 — h_sub=2, v_sub=2 (a.k.a. I420 / YV12) +// YUV422/YVU422 — h_sub=2, v_sub=1 +// YUV444/YVU444 — h_sub=1, v_sub=1 +// T430 — multi-pixel-per-word planar 4:4:4. + +#include "../layout.h" +#include "../io/planar.h" + +namespace pixpat::formats +{ + +#define PIXPAT_PLANAR(name, ...) \ + struct name : Layout { \ + using Source = PlanarSource; \ + using Sink = PlanarSink; \ + } + +PIXPAT_PLANAR(YUV420, 2, 2, + Plane, + Plane, + Plane); + +PIXPAT_PLANAR(YVU420, 2, 2, + Plane, + Plane, + Plane); + +PIXPAT_PLANAR(YUV422, 2, 1, + Plane, + Plane, + Plane); + +PIXPAT_PLANAR(YVU422, 2, 1, + Plane, + Plane, + Plane); + +PIXPAT_PLANAR(YUV444, 1, 1, + Plane, + Plane, + Plane); + +PIXPAT_PLANAR(YVU444, 1, 1, + Plane, + Plane, + Plane); + +#undef PIXPAT_PLANAR + +// T430: 3-plane multi-pixel-per-word planar 4:4:4. Each plane carries +// 3 × 10-bit samples per uint32_t plus a 2-bit X padding bit-field. +struct T430 : Layout, + Plane, + Plane > { + using Source = MultiPixelPlanarSource; + using Sink = MultiPixelPlanarSink; +}; + +} // namespace pixpat::formats diff --git a/pixpat-native/src/formats/yuv_semiplanar.h b/pixpat-native/src/formats/yuv_semiplanar.h new file mode 100644 index 0000000..34aea22 --- /dev/null +++ b/pixpat-native/src/formats/yuv_semiplanar.h @@ -0,0 +1,79 @@ +#pragma once + +// YUV semiplanar layouts: Y plane + interleaved UV plane. +// NV12/NV21 — 4:2:0 (h_sub=2, v_sub=2) +// NV16/NV61 — 4:2:2 (h_sub=2, v_sub=1) +// P030/P230 — multi-pixel-per-word semiplanar (10-bit Y triplets). + +#include "../layout.h" +#include "../io/semiplanar.h" + +namespace pixpat::formats +{ + +struct NV12 : Layout, + Plane > { + using Source = SemiplanarSource; + using Sink = SemiplanarSink; +}; + +struct NV21 : Layout, + Plane > { + using Source = SemiplanarSource; + using Sink = SemiplanarSink; +}; + +struct NV16 : Layout, + Plane > { + using Source = SemiplanarSource; + using Sink = SemiplanarSink; +}; + +struct NV61 : Layout, + Plane > { + using Source = SemiplanarSource; + using Sink = SemiplanarSink; +}; + +// Multi-pixel-per-word semiplanar (P030: 4:2:0, P230: 4:2:2). Y plane +// holds 3 × 10-bit Y samples per uint32_t (top 2 bits unused). UV plane +// holds 3 × (Cb,Cr) pairs per uint64_t (10 bits each, with 2-bit gaps +// at bits 30-31 and 62-63 — left implicit, no X declared). + +struct P030 : Layout, + Plane > { + using Source = MultiPixelSemiplanarSource; + using Sink = MultiPixelSemiplanarSink; +}; + +struct P230 : Layout, + Plane > { + using Source = MultiPixelSemiplanarSource; + using Sink = MultiPixelSemiplanarSink; +}; + +} // namespace pixpat::formats -- cgit v1.2.3