Haio
0.2.X
Homebrew Asset IO/CDN
Toggle main menu visibility
Loading...
Searching...
No Matches
palette.cpp
Go to the documentation of this file.
1
#include <
haio_convert.hpp
>
2
3
namespace
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
*/
15
template
<>
16
Result<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
*/
54
template
<>
55
Result<Image<Color::PALETTE>
>
Convert<Color::CHR_NES, Color::PALETTE>
(
Image<Color::CHR_NES>
src) {
56
return
convertVia<Color::CHR_NES, Color::PALETTE>
(std::move(src));
57
}
58
59
}
HAIO_FAIL
#define HAIO_FAIL(why, message)
Definition
haio_codec.hpp:258
haio_convert.hpp
Haio::Codecs
Definition
haio_codec.hpp:136
Haio::Codecs::Move< Color::CHR_NES, Color::PALETTE >
Result< void > Move< Color::CHR_NES, Color::PALETTE >(Bytes src, std::span< uint8_t > dst, Size size)
Definition
palette.cpp:16
Haio::Codecs::convertVia
Result< Image< To > > convertVia(Image< From > src)
Definition
haio_convert.hpp:21
Haio::Codecs::Convert< Color::CHR_NES, Color::PALETTE >
Result< Image< Color::PALETTE > > Convert< Color::CHR_NES, Color::PALETTE >(Image< Color::CHR_NES > src)
Definition
palette.cpp:55
Haio::Result
std::expected< T, Error > Result
Definition
haio_codec.hpp:32
Haio::Size::height
int height
Definition
haio_object.hpp:14
Haio::ErrorCode::InvalidInput
@ InvalidInput
Definition
haio_codec.hpp:18
Haio::Bytes
std::span< const uint8_t > Bytes
Definition
haio_codec.hpp:14
Haio::Size::width
int width
Definition
haio_object.hpp:13
Haio::Size
Definition
haio_object.hpp:12
Haio::Image
Definition
haio_codec.hpp:36
library
backend
codecs
color
chr_nes
palette.cpp
Generated by
1.18.0