-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathlv_alpha_blend.cpp
More file actions
99 lines (76 loc) · 3.56 KB
/
lv_alpha_blend.cpp
File metadata and controls
99 lines (76 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "config.h"
#include "lv_alpha_blend.h"
#include "lv_common.h"
#include "lv_cpu.h"
#include "lv_alpha_blend_orc.h"
#include <cassert>
namespace {
#pragma pack(1)
struct rgb16_t {
#if VISUAL_LITTLE_ENDIAN == 1
std::uint16_t b:5, g:6, r:5;
#else
std::uint16_t r:5, g:6, b:5;
#endif
};
#pragma pack()
static_assert (sizeof (rgb16_t) == 2);
} // anonymous namespace
namespace LV {
void alpha_blend_8 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha)
{
assert (dst.data () != src1.data ());
assert (dst.data () != src2.data ());
assert (src1.size () == src2.size ());
auto size {static_cast<int> (std::min (dst.size (), src1.size ()))};
::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size);
}
void alpha_blend_16 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha)
{
assert (dst.data () != src1.data ());
assert (dst.data () != src2.data ());
assert (src1.size () == src2.size ());
auto dst_ptr = reinterpret_cast<rgb16_t*> (dst.data ());
auto src1_ptr = reinterpret_cast<rgb16_t const*> (src1.data ());
auto src2_ptr = reinterpret_cast<rgb16_t const*> (src2.data ());
auto size {static_cast<int> (std::min (dst.size (), src1.size ()))};
auto pixel_count {size / sizeof (rgb16_t)};
for (std::size_t i {0}; i < pixel_count; i++) {
dst_ptr[i].r = (alpha * (src2_ptr[i].r - src1_ptr[i].r)) / 255 + src1_ptr[i].r;
dst_ptr[i].g = (alpha * (src2_ptr[i].g - src1_ptr[i].g)) / 255 + src1_ptr[i].g;
dst_ptr[i].b = (alpha * (src2_ptr[i].b - src1_ptr[i].b)) / 255 + src1_ptr[i].b;
}
}
void alpha_blend_24 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha)
{
assert (dst.data () != src1.data ());
assert (dst.data () != src2.data ());
assert (src1.size () == src2.size ());
auto size {static_cast<int> (std::min (dst.size (), src1.size ()))};
::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size * 3);
}
void alpha_blend_32 (std::span<std::uint8_t> dst, std::span<std::uint8_t const> src1, std::span<std::uint8_t const> src2, std::uint8_t alpha)
{
assert (dst.data () != src1.data ());
assert (dst.data () != src2.data ());
assert (src1.size () == src2.size ());
auto size {static_cast<int> (std::min (dst.size (), src1.size ()))};
::simd_interpolate_8 (dst.data (), src1.data (), src2.data (), alpha, size * 4);
}
} // LV namespace
void visual_alpha_blend_8 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha)
{
simd_interpolate_8 (dest, src1, src2, alpha, (int) size);
}
void visual_alpha_blend_16 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha)
{
LV::alpha_blend_16 ({dest, size}, {src1, size}, {src2, size}, alpha);
}
void visual_alpha_blend_24 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha)
{
simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 3);
}
void visual_alpha_blend_32 (uint8_t *LV_RESTRICT dest, const uint8_t *LV_RESTRICT src1, const uint8_t *LV_RESTRICT src2, visual_size_t size, uint8_t alpha)
{
simd_interpolate_8 (dest, src1, src2, alpha, (int) size * 4);
}