载入中...
搜索中...
未找到
WebPHandler.cpp
浏览该文件的文档.
1#include "WebPHandler.h"
2
3#include "common/Exception.h"
4
5#include <webp/demux.h>
6
7#include <cstring>
8#include <limits>
9#include <memory>
10
11namespace eve::image {
12
13bool WebPHandler::canDecode(const char *data, size_t size) {
14 return data != nullptr && size >= 12 && std::memcmp(data, "RIFF", 4) == 0 && std::memcmp(data + 8, "WEBP", 4) == 0;
15}
16
17medialoader::FormatHandler::DecodedImage WebPHandler::decode(const char *data, size_t size) {
18 if (!canDecode(data, size)) throw eve::Exception("Invalid WebP container");
19 const WebPData encoded{reinterpret_cast<const uint8_t *>(data), size};
20 std::unique_ptr<WebPAnimDecoder, decltype(&WebPAnimDecoderDelete)> decoder(WebPAnimDecoderNew(&encoded, nullptr),
21 WebPAnimDecoderDelete);
22 if (!decoder) throw eve::Exception("Could not decode WebP container");
23 WebPAnimInfo info{};
24 if (!WebPAnimDecoderGetInfo(decoder.get(), &info) || info.canvas_width == 0 || info.canvas_height == 0 ||
25 info.canvas_width > static_cast<uint32_t>(std::numeric_limits<int>::max()) ||
26 info.canvas_height > static_cast<uint32_t>(std::numeric_limits<int>::max()) ||
27 info.canvas_width > std::numeric_limits<size_t>::max() / 4 / info.canvas_height)
28 throw eve::Exception("Invalid WebP dimensions");
29 uint8_t *frame = nullptr;
30 int timestamp = 0;
31 if (!WebPAnimDecoderGetNext(decoder.get(), &frame, &timestamp) || frame == nullptr)
32 throw eve::Exception("Could not decode WebP first frame");
33 DecodedImage result;
34 result.width = static_cast<int>(info.canvas_width);
35 result.height = static_cast<int>(info.canvas_height);
36 result.format = medialoader::PIXELFORMAT_RGBA8;
37 result.size = static_cast<size_t>(result.width) * static_cast<size_t>(result.height) * 4;
38 auto pixels = std::make_unique<unsigned char[]>(result.size);
39 std::memcpy(pixels.get(), frame, result.size);
40 result.data = pixels.release();
41 return result;
42}
43
44} // namespace eve::image
uint8_t * pixels
float size
Definition TreeMesh.cpp:156
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
DecodedImage decode(const char *data, size_t size) override
Decodes the first composited frame to caller-owned RGBA8 pixels.
bool canDecode(const char *data, size_t size) override
Recognizes a RIFF WebP container without decoding or allocating pixels.
glm::uvec4 info