add webp support
This commit is contained in:
parent
bdfe44399a
commit
2dba4f8fbb
1
external/CMakeLists.txt
vendored
1
external/CMakeLists.txt
vendored
@ -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
6
external/libwebp/CMakeLists.txt
vendored
Normal 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)
|
||||||
|
|
@ -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
78
src/image_loader_webp.cpp
Normal 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, ×tamp);
|
||||||
|
// ... (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;
|
||||||
|
}
|
||||||
|
|
9
src/image_loader_webp.hpp
Normal file
9
src/image_loader_webp.hpp
Normal 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;
|
||||||
|
};
|
||||||
|
|
@ -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>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user