-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
We've been needing this for a while for the game engines but we also need it to support decoding webp images for use in the editor with the Rive Renderer. I haven't instrumented the build properly to use SIMD extensions, but I left some notes for how to do so. This PR unblocks the use of WebP, let's do some perf improvements in a follow up that perhaps the runtime team can own? Diffs= 160d9eefb Add webp decoder. (#7883) Co-authored-by: Luigi Rosso <[email protected]> Co-authored-by: rivessamr <[email protected]>
- Loading branch information
1 parent
a8b7f00
commit 6acee5a
Showing
10 changed files
with
259 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
e992059d6354434e91cde562e463f51bff7eac58 | ||
160d9eefb4d3e42b620053987fcc8654e98d40a6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
#include "rive/decoders/bitmap_decoder.hpp" | ||
#include "webp/decode.h" | ||
#include "webp/demux.h" | ||
#include <stdio.h> | ||
#include <vector> | ||
#include <memory> | ||
|
||
std::unique_ptr<Bitmap> DecodeWebP(const uint8_t bytes[], size_t byteCount) | ||
{ | ||
WebPDecoderConfig config; | ||
if (!WebPInitDecoderConfig(&config)) | ||
{ | ||
fprintf(stderr, "DecodeWebP - Library version mismatch!\n"); | ||
return nullptr; | ||
} | ||
config.options.dithering_strength = 50; | ||
config.options.alpha_dithering_strength = 100; | ||
|
||
if (!WebPGetInfo(bytes, byteCount, nullptr, nullptr)) | ||
{ | ||
fprintf(stderr, "DecodeWebP - Input file doesn't appear to be WebP format.\n"); | ||
} | ||
|
||
WebPData data = {bytes, byteCount}; | ||
WebPDemuxer* demuxer = WebPDemux(&data); | ||
if (demuxer == nullptr) | ||
{ | ||
fprintf(stderr, "DecodeWebP - Could not create demuxer.\n"); | ||
} | ||
|
||
WebPIterator currentFrame; | ||
if (!WebPDemuxGetFrame(demuxer, 1, ¤tFrame)) | ||
{ | ||
fprintf(stderr, "DecodeWebP - WebPDemuxGetFrame couldn't get frame.\n"); | ||
WebPDemuxDelete(demuxer); | ||
return nullptr; | ||
} | ||
config.output.colorspace = MODE_RGBA; | ||
|
||
uint32_t width = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_WIDTH); | ||
uint32_t height = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_HEIGHT); | ||
|
||
size_t pixelBufferSize = | ||
static_cast<size_t>(width) * static_cast<size_t>(height) * static_cast<size_t>(4); | ||
std::unique_ptr<uint8_t[]> pixelBuffer = std::make_unique<uint8_t[]>(pixelBufferSize); | ||
|
||
config.output.u.RGBA.rgba = (uint8_t*)pixelBuffer.get(); | ||
config.output.u.RGBA.stride = (int)(width * 4); | ||
config.output.u.RGBA.size = pixelBufferSize; | ||
config.output.is_external_memory = 1; | ||
|
||
if (WebPDecode(currentFrame.fragment.bytes, currentFrame.fragment.size, &config) != | ||
VP8_STATUS_OK) | ||
{ | ||
fprintf(stderr, "DecodeWebP - WebPDemuxGetFrame couldn't decode.\n"); | ||
WebPDemuxReleaseIterator(¤tFrame); | ||
WebPDemuxDelete(demuxer); | ||
return nullptr; | ||
} | ||
|
||
WebPDemuxReleaseIterator(¤tFrame); | ||
WebPDemuxDelete(demuxer); | ||
|
||
return std::make_unique<Bitmap>(width, | ||
height, | ||
Bitmap::PixelFormat::RGBA, | ||
std::move(pixelBuffer)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
dofile('rive_build_config.lua') | ||
|
||
local dependency = require('dependency') | ||
libwebp = dependency.github('webmproject/libwebp', 'v1.4.0') | ||
|
||
project('libwebp') | ||
do | ||
kind('StaticLib') | ||
optimize('Speed') -- Always optimize image encoding/decoding, even in debug builds. | ||
|
||
includedirs({ libwebp }) | ||
|
||
-- Leaving some notes here for future perf improvements. Define these when | ||
-- we can determine we're on a compatible platform/perf gain is worth it. | ||
-- | ||
-- Some extra details about each of these: | ||
-- https://github.com/webmproject/libwebp/blob/main/cmake/config.h.in | ||
defines({ | ||
-- 'WEBP_USE_NEON=1', | ||
-- 'WEBP_HAVE_NEON_RTCD=1', -- runtime detection of NEON extensions | ||
-- 'WEBP_HAVE_SSE41=1', | ||
-- 'WEBP_USE_THREAD=1' | ||
}) | ||
|
||
files({ | ||
-- common dsp | ||
libwebp .. '/src/dsp/alpha_processing.c', | ||
libwebp .. '/src/dsp/cpu.c', | ||
libwebp .. '/src/dsp/dec.c', | ||
libwebp .. '/src/dsp/dec_clip_tables.c', | ||
libwebp .. '/src/dsp/filters.c', | ||
libwebp .. '/src/dsp/lossless.c', | ||
libwebp .. '/src/dsp/rescaler.c', | ||
libwebp .. '/src/dsp/upsampling.c', | ||
libwebp .. '/src/dsp/yuv.c', | ||
|
||
-- encoder dsp | ||
libwebp .. '/src/dsp/cost.c', | ||
libwebp .. '/src/dsp/enc.c', | ||
libwebp .. '/src/dsp/lossless_enc.c', | ||
libwebp .. '/src/dsp/ssim.c', | ||
|
||
-- decoder | ||
libwebp .. '/src/dec/alpha_dec.c', | ||
libwebp .. '/src/dec/buffer_dec.c', | ||
libwebp .. '/src/dec/frame_dec.c', | ||
libwebp .. '/src/dec/idec_dec.c', | ||
libwebp .. '/src/dec/io_dec.c', | ||
libwebp .. '/src/dec/quant_dec.c', | ||
libwebp .. '/src/dec/tree_dec.c', | ||
libwebp .. '/src/dec/vp8_dec.c', | ||
libwebp .. '/src/dec/vp8l_dec.c', | ||
libwebp .. '/src/dec/webp_dec.c', | ||
|
||
-- libwebpdspdecode_sse41_la_SOURCES = | ||
libwebp .. '/src/dsp/alpha_processing_sse41.c', | ||
libwebp .. '/src/dsp/dec_sse41.c', | ||
libwebp .. '/src/dsp/lossless_sse41.c', | ||
libwebp .. '/src/dsp/upsampling_sse41.c', | ||
libwebp .. '/src/dsp/yuv_sse41.c', | ||
|
||
-- libwebpdspdecode_sse2_la_SOURCES = | ||
libwebp .. '/src/dsp/alpha_processing_sse2.c', | ||
libwebp .. '/src/dsp/common_sse2.h', | ||
libwebp .. '/src/dsp/dec_sse2.c', | ||
libwebp .. '/src/dsp/filters_sse2.c', | ||
libwebp .. '/src/dsp/lossless_sse2.c', | ||
libwebp .. '/src/dsp/rescaler_sse2.c', | ||
libwebp .. '/src/dsp/upsampling_sse2.c', | ||
libwebp .. '/src/dsp/yuv_sse2.c', | ||
|
||
-- neon sources | ||
-- TODO: define WEBP_HAVE_NEON when we're on a platform that supports it. | ||
libwebp .. '/src/dsp/alpha_processing_neon.c', | ||
libwebp .. '/src/dsp/dec_neon.c', | ||
libwebp .. '/src/dsp/filters_neon.c', | ||
libwebp .. '/src/dsp/lossless_neon.c', | ||
libwebp .. '/src/dsp/neon.h', | ||
libwebp .. '/src/dsp/rescaler_neon.c', | ||
libwebp .. '/src/dsp/upsampling_neon.c', | ||
libwebp .. '/src/dsp/yuv_neon.c', | ||
|
||
-- libwebpdspdecode_msa_la_SOURCES = | ||
libwebp .. '/src/dsp/dec_msa.c', | ||
libwebp .. '/src/dsp/filters_msa.c', | ||
libwebp .. '/src/dsp/lossless_msa.c', | ||
libwebp .. '/src/dsp/msa_macro.h', | ||
libwebp .. '/src/dsp/rescaler_msa.c', | ||
libwebp .. '/src/dsp/upsampling_msa.c', | ||
|
||
-- libwebpdspdecode_mips32_la_SOURCES = | ||
libwebp .. '/src/dsp/dec_mips32.c', | ||
libwebp .. '/src/dsp/mips_macro.h', | ||
libwebp .. '/src/dsp/rescaler_mips32.c', | ||
libwebp .. '/src/dsp/yuv_mips32.c', | ||
|
||
-- libwebpdspdecode_mips_dsp_r2_la_SOURCES = | ||
libwebp .. '/src/dsp/alpha_processing_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/dec_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/filters_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/lossless_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/mips_macro.h', | ||
libwebp .. '/src/dsp/rescaler_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/upsampling_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/yuv_mips_dsp_r2.c', | ||
|
||
-- libwebpdsp_sse2_la_SOURCES = | ||
libwebp .. '/src/dsp/cost_sse2.c', | ||
libwebp .. '/src/dsp/enc_sse2.c', | ||
libwebp .. '/src/dsp/lossless_enc_sse2.c', | ||
libwebp .. '/src/dsp/ssim_sse2.c', | ||
|
||
-- libwebpdsp_sse41_la_SOURCES = | ||
libwebp .. '/src/dsp/enc_sse41.c', | ||
libwebp .. '/src/dsp/lossless_enc_sse41.c', | ||
|
||
-- libwebpdsp_neon_la_SOURCES = | ||
libwebp .. '/src/dsp/cost_neon.c', | ||
libwebp .. '/src/dsp/enc_neon.c', | ||
libwebp .. '/src/dsp/lossless_enc_neon.c', | ||
|
||
-- libwebpdsp_msa_la_SOURCES = | ||
libwebp .. '/src/dsp/enc_msa.c', | ||
libwebp .. '/src/dsp/lossless_enc_msa.c', | ||
|
||
-- libwebpdsp_mips32_la_SOURCES = | ||
libwebp .. '/src/dsp/cost_mips32.c', | ||
libwebp .. '/src/dsp/enc_mips32.c', | ||
libwebp .. '/src/dsp/lossless_enc_mips32.c', | ||
|
||
-- libwebpdsp_mips_dsp_r2_la_SOURCES = | ||
libwebp .. '/src/dsp/cost_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/enc_mips_dsp_r2.c', | ||
libwebp .. '/src/dsp/lossless_enc_mips_dsp_r2.c', | ||
|
||
-- COMMON_SOURCES = | ||
libwebp .. '/src/utils/bit_reader_utils.c', | ||
libwebp .. '/src/utils/bit_reader_utils.h', | ||
libwebp .. '/src/utils/color_cache_utils.c', | ||
libwebp .. '/src/utils/filters_utils.c', | ||
libwebp .. '/src/utils/huffman_utils.c', | ||
libwebp .. '/src/utils/palette.c', | ||
libwebp .. '/src/utils/quant_levels_dec_utils.c', | ||
libwebp .. '/src/utils/rescaler_utils.c', | ||
libwebp .. '/src/utils/random_utils.c', | ||
libwebp .. '/src/utils/thread_utils.c', | ||
libwebp .. '/src/utils/utils.c', | ||
|
||
-- ENC_SOURCES = | ||
libwebp .. '/src/utils/bit_writer_utils.c', | ||
libwebp .. '/src/utils/huffman_encode_utils.c', | ||
libwebp .. '/src/utils/quant_levels_utils.c', | ||
|
||
-- libwebpdemux_la_SOURCES = | ||
libwebp .. '/src/demux/anim_decode.c', | ||
libwebp .. '/src/demux/demux.c', | ||
}) | ||
|
||
filter({ 'system:windows', 'toolset:clang' }) | ||
do | ||
-- https://github.com/webmproject/libwebp/blob/233e86b91f4e0af7833d50013e3b978f825f73f5/src/dsp/cpu.h#L57 | ||
-- webp automaticall enables these for windows so we need to compile | ||
-- with the correct settings or we get an error. | ||
buildoptions({ '-mssse3', '-msse4.1' }) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ do | |
'libpng', | ||
'zlib', | ||
'libjpeg', | ||
'libwebp', | ||
}) | ||
|
||
files({ | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters