Haio
0.2.X
Homebrew Asset IO/CDN
Toggle main menu visibility
Loading...
Searching...
No Matches
rgba8888.cpp
Go to the documentation of this file.
1
#include <
haio_convert.hpp
>
2
3
namespace
Haio::Codecs
{
4
5
/**
6
* jfif colour, which is full range bt.601 and not the studio range video uses. a
7
* decoder written against the video coefficients produces a picture that is visibly
8
* washed out rather than obviously wrong, which is the sort of mistake that ships.
9
*
10
* the two chroma planes are half size in both directions, so each of their samples
11
* covers a two by two block of luma.
12
*/
13
template
<>
14
Result<void>
Move<Color::YUV420, Color::RGBA8888>
(
Bytes
src, std::span<uint8_t> dst,
Size
size) {
15
if
(size.
width
% 2 != 0 || size.
height
% 2 != 0) {
16
HAIO_FAIL
(
InvalidInput
,
"yuv420 needs even width and height"
);
17
}
18
19
const
auto
width =
static_cast<
size_t
>
(size.
width
);
20
const
auto
height =
static_cast<
size_t
>
(size.
height
);
21
const
auto
pixels = width * height;
22
const
auto
half = width / 2;
23
const
auto
chroma = half * (height / 2);
24
25
if
(src.size() < pixels + chroma * 2 || dst.size() < pixels * 4) {
26
HAIO_FAIL
(
InvalidInput
,
"yuv420 to rgba8888 got a buffer that is too small"
);
27
}
28
29
const
auto
* luma = src.data();
30
const
auto
* blue = luma + pixels;
31
const
auto
* red = blue + chroma;
32
33
const
auto
clamp = [](
int
value) {
34
return
static_cast<
uint8_t
>
(value < 0 ? 0 : value > 255 ? 255 : value);
35
};
36
37
for
(
size_t
y = 0; y < height; y++) {
38
const
auto
chromaRow = (y / 2) * half;
39
for
(
size_t
x = 0; x < width; x++) {
40
const
int
Y = luma[y * width + x];
41
const
int
Cb = blue[chromaRow + x / 2] - 128;
42
const
int
Cr = red[chromaRow + x / 2] - 128;
43
44
// the coefficients are the jfif ones, scaled by 1024 to stay in integers
45
const
auto
at = (y * width + x) * 4;
46
dst[at + 0] = clamp(Y + ((1436 * Cr) >> 10));
47
dst[at + 1] = clamp(Y - ((352 * Cb + 731 * Cr) >> 10));
48
dst[at + 2] = clamp(Y + ((1815 * Cb) >> 10));
49
dst[at + 3] = 0xFF;
50
}
51
}
52
return
{};
53
}
54
55
template
<>
56
Result<Image<Color::RGBA8888>
>
Convert<Color::YUV420, Color::RGBA8888>
(
Image<Color::YUV420>
src) {
57
return
convertVia<Color::YUV420, Color::RGBA8888>
(std::move(src));
58
}
59
60
}
HAIO_FAIL
#define HAIO_FAIL(why, message)
Definition
haio_codec.hpp:258
haio_convert.hpp
Haio::Codecs
Definition
haio_codec.hpp:136
Haio::Codecs::convertVia
Result< Image< To > > convertVia(Image< From > src)
Definition
haio_convert.hpp:21
Haio::Codecs::Convert< Color::YUV420, Color::RGBA8888 >
Result< Image< Color::RGBA8888 > > Convert< Color::YUV420, Color::RGBA8888 >(Image< Color::YUV420 > src)
Definition
rgba8888.cpp:56
Haio::Codecs::Move< Color::YUV420, Color::RGBA8888 >
Result< void > Move< Color::YUV420, Color::RGBA8888 >(Bytes src, std::span< uint8_t > dst, Size size)
Definition
rgba8888.cpp:14
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
yuv420
rgba8888.cpp
Generated by
1.18.0