Repository navigation
Expand file tree
/
Copy pathwebp.cpp
More file actions
73 lines (61 loc) · 1.94 KB
/
Copy pathwebp.cpp
File metadata and controls
73 lines (61 loc) · 1.94 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
#include "webp.hpp"
#include "color.hpp"
#include <cstdint>
#include <cstring>
#include <vector>
#if !defined(AETHERIS_HAS_WEBP)
#define AETHERIS_HAS_WEBP 0
#endif
#if AETHERIS_HAS_WEBP
// The minimal libwebp decoder API. Declaring it here (rather than including
// <webp/decode.h>) keeps the build independent of where the headers live; the
// ABI is stable. This mirrors how upstream Ladybird links libwebp.
extern "C" {
int WebPGetInfo(uint8_t const* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeBGRAInto(uint8_t const* data, size_t data_size, uint8_t* output_buffer, size_t output_buffer_size, int output_stride);
}
#endif
namespace aetheris::rendering {
bool is_webp(std::vector<unsigned char> const& bytes)
{
return bytes.size() >= 12
&& std::memcmp(bytes.data(), "RIFF", 4) == 0
&& std::memcmp(bytes.data() + 8, "WEBP", 4) == 0;
}
bool webp_available()
{
#if AETHERIS_HAS_WEBP
return true;
#else
return false;
#endif
}
bool decode_webp(std::vector<unsigned char> const& bytes, Image& out)
{
#if AETHERIS_HAS_WEBP
if (!is_webp(bytes))
return false;
int width = 0;
int height = 0;
if (WebPGetInfo(bytes.data(), bytes.size(), &width, &height) != 1)
return false;
if (width <= 0 || height <= 0)
return false;
std::vector<uint8_t> buffer(static_cast<size_t>(width) * height * 4);
// WebPDecodeBGRAInto returns non-premultiplied BGRA.
if (WebPDecodeBGRAInto(bytes.data(), bytes.size(), buffer.data(), buffer.size(), width * 4) == nullptr)
return false;
out = Image {};
out.width = width;
out.height = height;
out.pixels.resize(static_cast<size_t>(width) * height);
for (size_t i = 0; i < out.pixels.size(); ++i)
out.pixels[i] = Color { buffer[i * 4 + 2], buffer[i * 4 + 1], buffer[i * 4 + 0], buffer[i * 4 + 3] };
return true;
#else
(void)bytes;
(void)out;
return false;
#endif
}
} // namespace aetheris::rendering