diff options
| author | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2026-05-08 17:22:58 +0300 |
|---|---|---|
| committer | Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> | 2026-05-08 17:22:58 +0300 |
| commit | 4e2b291a4acdc2cbd39f005c88bda363bc06bd34 (patch) | |
| tree | e90048d5973ad1164b109d575cf577af7daf50be /subprojects/pixpat/pixpat-native/src/io/detail.h | |
| parent | 8f94b39040e79eccd9312ed1e467fe8ebfab8860 (diff) | |
| parent | e0b7d30fd437292c88141fb08d60681870b86c6e (diff) | |
Merge commit 'e0b7d30fd437292c88141fb08d60681870b86c6e' as 'subprojects/pixpat'
Diffstat (limited to 'subprojects/pixpat/pixpat-native/src/io/detail.h')
| -rw-r--r-- | subprojects/pixpat/pixpat-native/src/io/detail.h | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/subprojects/pixpat/pixpat-native/src/io/detail.h b/subprojects/pixpat/pixpat-native/src/io/detail.h new file mode 100644 index 0000000..cb2b9fb --- /dev/null +++ b/subprojects/pixpat/pixpat-native/src/io/detail.h @@ -0,0 +1,62 @@ +#pragma once + +// Per-component encode/decode against the descriptor + memcpy-based +// load/store_word helpers. Shared by every Source / Sink template. + +#include <cstdint> +#include <cstring> + +#include "../layout.h" + +namespace pixpat::detail +{ + +// Decode an N-bit stored value into the 16-bit normalized space and +// encode it back. Decode bit-replicates the stored value across the 16 +// bits so that N-bit max maps to normalized max (e.g. 8-bit 0xFF → +// 0xFFFF, not 0xFF00). Encode is a plain truncating right-shift: the +// replicated bits land in the low (16-N) bits and get dropped, so +// stored→norm→stored is exact for any N in [1, 16]. +// +// `bits` is taken at runtime; in every call site it traces back to a +// constexpr Plane::comps[I].bits read, which the optimizer constant- +// folds after inlining. + +constexpr uint16_t decode_norm(unsigned bits, uint16_t stored) noexcept +{ + const int N = int(bits); + // Loop, not a single OR: one replication only covers 2N bits, so + // N < 8 (RGB565, RGBA4444, 1-bit alpha, ...) needs multiple tiles. + uint32_t result = 0; + for (int s = 16 - N; s > -N; s -= N) { + if (s >= 0) + result |= uint32_t(stored) << s; + else + result |= uint32_t(stored) >> -s; + } + return uint16_t(result); +} + +constexpr uint16_t encode_norm(unsigned bits, uint16_t norm) noexcept +{ + return uint16_t(norm >> (16u - bits)); +} + +// Read one storage word from `p`. memcpy is uniform for tight and +// non-tight (e.g. BGR888 24-bit) layouts; the optimizer folds it to a +// single load when the size is constant. +template <typename Plane> +inline typename Plane::storage_t load_word(const uint8_t* p) noexcept +{ + typename Plane::storage_t word{}; + std::memcpy(&word, p, Plane::bytes_per_pixel); + return word; +} + +template <typename Plane> +inline void store_word(uint8_t* p, typename Plane::storage_t word) noexcept +{ + std::memcpy(p, &word, Plane::bytes_per_pixel); +} + +} // namespace pixpat::detail |
