From ce4c7033010ac6f69f863aaf27d30ed159e0dc75 Mon Sep 17 00:00:00 2001 From: Jaakko Ruohio Date: Wed, 8 Apr 2026 06:36:51 +0300 Subject: [PATCH 1/4] Fix crash when trying to load animated WebP, return dummy matrix --- src/decoding.jl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/decoding.jl b/src/decoding.jl index e423311..75089a0 100644 --- a/src/decoding.jl +++ b/src/decoding.jl @@ -37,6 +37,15 @@ function decode( return image end +function decode_animated_first_frame( + ::Type{TColor}, data::AbstractVector{UInt8}; transpose = false +)::Matrix{TColor} where {TColor <: Colorant} + width = Ref{Int32}(-1) + height = Ref{Int32}(-1) + WebPGetInfo(pointer(data), length(data), width, height) + transpose ? ones(TColor, width[], height[]) : ones(TColor, height[], width[]) +end + function decode( data::AbstractVector{UInt8}; kwargs... )::Union{Matrix{RGB{N0f8}}, Matrix{RGBA{N0f8}}} @@ -47,7 +56,12 @@ function decode( ) has_alpha = bitstream_features[].has_alpha != 0 TColor = has_alpha ? RGBA{N0f8} : RGB{N0f8} - return decode(TColor, data; kwargs...) + if bitstream_features[].has_animation == 1 + @warn("Loading animated WebP not supported.") + decode_animated_first_frame(TColor, data; kwargs...) + else + decode(TColor, data; kwargs...) + end end function read_webp( From a1c35beb3fbe5cbd4955ab2d1082f7a326b1d849 Mon Sep 17 00:00:00 2001 From: Jaakko Ruohio Date: Wed, 8 Apr 2026 22:37:53 +0300 Subject: [PATCH 2/4] Add animation data to decoding tests --- test/decoding_tests.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/decoding_tests.jl b/test/decoding_tests.jl index dd7d571..3db207e 100644 --- a/test/decoding_tests.jl +++ b/test/decoding_tests.jl @@ -26,6 +26,12 @@ using WebP "5_webp_ll.webp" => (300, 300), ), ), + animation = ( + url = "https://storage.googleapis.com/downloads.webmproject.org/webp/images/", + data = Dict( + "dancing_banana2.lossless.webp" => (1050, 990), + ), + ) ) for gallery in webp_galleries for (filename, image_size) in gallery.data From af6350820e1020a10293fb301f1eefe9004ade1f Mon Sep 17 00:00:00 2001 From: Jaakko Ruohio Date: Wed, 8 Apr 2026 22:41:31 +0300 Subject: [PATCH 3/4] animated webp handling in decode-function --- src/decoding.jl | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/decoding.jl b/src/decoding.jl index 75089a0..b884ab0 100644 --- a/src/decoding.jl +++ b/src/decoding.jl @@ -18,8 +18,20 @@ function decode( else throw(ArgumentError("Unsupported color type: $TColor")) end + + bitstream_features = Ref{Wrapper.WebPBitstreamFeatures}() + # WebPGetFeatures is not available in libwebp dynamic library, but WebPGetFeaturesInternal is equivalent: https://github.com/webmproject/libwebp/blob/v1.4.0/src/webp/decode.h#L441 + Wrapper.WebPGetFeaturesInternal( + pointer(data), length(data), bitstream_features, Wrapper.WEBP_DECODER_ABI_VERSION + ) width = Ref{Int32}(-1) height = Ref{Int32}(-1) + if bitstream_features[].has_animation == 1 + @warn("Animated WebP not supported") + WebPGetInfo(pointer(data), length(data), width, height) + image = transpose ? ones(TColor, width[], height[]) : ones(TColor, height[], width[]) + return image + end decoded_data_ptr = webp_decode_fn(pointer(data), length(data), width, height) decoded_data_size = (sizeof(TDecodedColor), Int(width[]), Int(height[])) decoded_data = unsafe_wrap(Array{UInt8, 3}, decoded_data_ptr, decoded_data_size) @@ -37,15 +49,6 @@ function decode( return image end -function decode_animated_first_frame( - ::Type{TColor}, data::AbstractVector{UInt8}; transpose = false -)::Matrix{TColor} where {TColor <: Colorant} - width = Ref{Int32}(-1) - height = Ref{Int32}(-1) - WebPGetInfo(pointer(data), length(data), width, height) - transpose ? ones(TColor, width[], height[]) : ones(TColor, height[], width[]) -end - function decode( data::AbstractVector{UInt8}; kwargs... )::Union{Matrix{RGB{N0f8}}, Matrix{RGBA{N0f8}}} @@ -56,12 +59,7 @@ function decode( ) has_alpha = bitstream_features[].has_alpha != 0 TColor = has_alpha ? RGBA{N0f8} : RGB{N0f8} - if bitstream_features[].has_animation == 1 - @warn("Loading animated WebP not supported.") - decode_animated_first_frame(TColor, data; kwargs...) - else - decode(TColor, data; kwargs...) - end + return decode(TColor, data; kwargs...) end function read_webp( From ebbcbe1283a6f6a7e8324fb2ff81121482e3fe4e Mon Sep 17 00:00:00 2001 From: Jaakko Ruohio Date: Thu, 9 Apr 2026 16:41:14 +0300 Subject: [PATCH 4/4] Run JuliaFormatter --- src/decoding.jl | 3 ++- test/decoding_tests.jl | 6 ++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/decoding.jl b/src/decoding.jl index b884ab0..eedea5a 100644 --- a/src/decoding.jl +++ b/src/decoding.jl @@ -29,7 +29,8 @@ function decode( if bitstream_features[].has_animation == 1 @warn("Animated WebP not supported") WebPGetInfo(pointer(data), length(data), width, height) - image = transpose ? ones(TColor, width[], height[]) : ones(TColor, height[], width[]) + image = + transpose ? ones(TColor, width[], height[]) : ones(TColor, height[], width[]) return image end decoded_data_ptr = webp_decode_fn(pointer(data), length(data), width, height) diff --git a/test/decoding_tests.jl b/test/decoding_tests.jl index 3db207e..e7f7c61 100644 --- a/test/decoding_tests.jl +++ b/test/decoding_tests.jl @@ -28,10 +28,8 @@ using WebP ), animation = ( url = "https://storage.googleapis.com/downloads.webmproject.org/webp/images/", - data = Dict( - "dancing_banana2.lossless.webp" => (1050, 990), - ), - ) + data = Dict("dancing_banana2.lossless.webp" => (1050, 990)), + ), ) for gallery in webp_galleries for (filename, image_size) in gallery.data