add webp support

This commit is contained in:
Green Sky 2023-08-02 15:06:19 +02:00
parent bdfe44399a
commit 2dba4f8fbb
No known key found for this signature in database
6 changed files with 99 additions and 1 deletions

View File

@ -16,4 +16,5 @@ add_subdirectory(./sdl)
add_subdirectory(./imgui) add_subdirectory(./imgui)
add_subdirectory(./stb) add_subdirectory(./stb)
add_subdirectory(./libwebp)

6
external/libwebp/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
set(WEBP_LINK_STATIC ON CACHE INTERNAL "")
add_subdirectory(./libwebp EXCLUDE_FROM_ALL)

View File

@ -20,6 +20,8 @@ add_executable(tomato
./image_loader_sdl_bmp.cpp ./image_loader_sdl_bmp.cpp
./image_loader_stb.hpp ./image_loader_stb.hpp
./image_loader_stb.cpp ./image_loader_stb.cpp
./image_loader_webp.hpp
./image_loader_webp.cpp
./theme.hpp ./theme.hpp
./texture_uploader.hpp ./texture_uploader.hpp
@ -57,5 +59,6 @@ target_link_libraries(tomato PUBLIC
imgui_backend_sdlrenderer3 imgui_backend_sdlrenderer3
stb_image stb_image
webpdemux
) )

78
src/image_loader_webp.cpp Normal file
View File

@ -0,0 +1,78 @@
#include "./image_loader_webp.hpp"
#include <webp/demux.h>
#include <webp/mux.h>
#include <cassert>
ImageLoaderWebP::ImageInfo ImageLoaderWebP::loadInfoFromMemory(const uint8_t* data, uint64_t data_size) {
ImageInfo res;
WebPData webp_data;
WebPDataInit(&webp_data);
webp_data.bytes = data;
webp_data.size = data_size;
WebPAnimDecoderOptions dec_options;
WebPAnimDecoderOptionsInit(&dec_options);
// Tune 'dec_options' as needed.
dec_options.color_mode = MODE_RGBA;
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
if (dec == nullptr) {
return res;
}
WebPAnimInfo anim_info;
WebPAnimDecoderGetInfo(dec, &anim_info);
res.width = anim_info.canvas_width;
res.height = anim_info.canvas_height;
return res;
}
ImageLoaderWebP::ImageResult ImageLoaderWebP::loadFromMemoryRGBA(const uint8_t* data, uint64_t data_size) {
ImageResult res;
WebPData webp_data;
WebPDataInit(&webp_data);
webp_data.bytes = data;
webp_data.size = data_size;
WebPAnimDecoderOptions dec_options;
WebPAnimDecoderOptionsInit(&dec_options);
// Tune 'dec_options' as needed.
dec_options.color_mode = MODE_RGBA;
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
if (dec == nullptr) {
return res;
}
WebPAnimInfo anim_info;
WebPAnimDecoderGetInfo(dec, &anim_info);
res.width = anim_info.canvas_width;
res.height = anim_info.canvas_height;
int prev_timestamp = 0;
while (WebPAnimDecoderHasMoreFrames(dec)) {
uint8_t* buf;
int timestamp;
WebPAnimDecoderGetNext(dec, &buf, &timestamp);
// ... (Render 'buf' based on 'timestamp').
// ... (Do NOT free 'buf', as it is owned by 'dec').
// just be dumb and append
auto& new_frame = res.frames.emplace_back();
new_frame.ms = timestamp-prev_timestamp;
prev_timestamp = timestamp;
new_frame.data.insert(new_frame.data.end(), buf, buf+(res.width*res.height*4));
}
WebPAnimDecoderDelete(dec);
assert(anim_info.frame_count == res.frames.size());
return res;
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "./image_loader.hpp"
struct ImageLoaderWebP : public ImageLoaderI {
ImageInfo loadInfoFromMemory(const uint8_t* data, uint64_t data_size) override;
ImageResult loadFromMemoryRGBA(const uint8_t* data, uint64_t data_size) override;
};

View File

@ -2,6 +2,7 @@
#include "./image_loader_sdl_bmp.hpp" #include "./image_loader_sdl_bmp.hpp"
#include "./image_loader_stb.hpp" #include "./image_loader_stb.hpp"
#include "./image_loader_webp.hpp"
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp> #include <solanaceae/tox_contacts/components.hpp>
@ -15,7 +16,7 @@
ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) { ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>()); _image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
//_image_loaders.push_back(std::make_unique<ImageLoaderWebP>()); _image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
_image_loaders.push_back(std::make_unique<ImageLoaderSTB>()); _image_loaders.push_back(std::make_unique<ImageLoaderSTB>());
} }