Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
palette.cpp
Go to the documentation of this file.
2
3namespace Haio::Codecs {
4
5/**
6 * unpacks nes pattern data into one index per byte.
7 *
8 * a tile is sixteen bytes: eight rows of the low bit, then eight rows of the high
9 * bit. so a pixel's two bits sit eight bytes apart, and the leftmost pixel is the
10 * most significant bit rather than the least.
11 *
12 * nothing here needs a palette, which is why it fits Move at all: the indices are
13 * 0 to 3 whatever colours are eventually hung on them.
14 */
15template <>
16Result<void> Move<Color::CHR_NES, Color::PALETTE>(Bytes src, std::span<uint8_t> dst, Size size) {
17 if (size.width % 8 != 0 || size.height % 8 != 0) {
18 HAIO_FAIL(InvalidInput, "nes chr is made of 8x8 tiles, so both sides must be multiples of 8");
19 }
20
21 const auto width = static_cast<size_t>(size.width);
22 const auto height = static_cast<size_t>(size.height);
23 const auto columns = width / 8;
24 const auto tiles = columns * (height / 8);
25
26 if (src.size() < tiles * 16 || dst.size() < width * height) {
27 HAIO_FAIL(InvalidInput, "chr_nes to palette got a buffer that is too small");
28 }
29
30 for (size_t tile = 0; tile < tiles; tile++) {
31 const auto at = tile * 16;
32 const auto originX = (tile % columns) * 8;
33 const auto originY = (tile / columns) * 8;
34
35 for (size_t y = 0; y < 8; y++) {
36 const auto low = src[at + y];
37 const auto high = src[at + y + 8];
38
39 for (size_t x = 0; x < 8; x++) {
40 const auto bit = 7 - x;
41 const auto index = ((low >> bit) & 1) | (((high >> bit) & 1) << 1);
42 dst[(originY + y) * width + originX + x] = static_cast<uint8_t>(index);
43 }
44 }
45 }
46 return {};
47}
48
49/**
50 * the indices arrive without colours. what to hang on them is a separate question,
51 * answered by whoever asked for the conversion, because a chr file does not carry a
52 * palette and never did: the console held it somewhere else entirely.
53 */
54template <>
56 return convertVia<Color::CHR_NES, Color::PALETTE>(std::move(src));
57}
58
59}
#define HAIO_FAIL(why, message)
Result< void > Move< Color::CHR_NES, Color::PALETTE >(Bytes src, std::span< uint8_t > dst, Size size)
Definition palette.cpp:16
Result< Image< To > > convertVia(Image< From > src)
Result< Image< Color::PALETTE > > Convert< Color::CHR_NES, Color::PALETTE >(Image< Color::CHR_NES > src)
Definition palette.cpp:55
std::expected< T, Error > Result
std::span< const uint8_t > Bytes