~ software engineer creating usable, accessible, humane, & ethical technology ~
jaredforth / webp Goto Github PK
View Code? Open in Web Editor NEWWebP Image Conversion Library
License: Other
WebP Image Conversion Library
License: Other
~ software engineer creating usable, accessible, humane, & ethical technology ~
Hi! Thanks for this crate.
I'm trying to use webp
alongside other parts of the image
crate, but I need to set features of the image
crate (particularly, disabling rayon because I am compiling for wasm32). When depending on the webp crate, it pulls in image
with all default features.
Can you please change your dependency on image
to include default-features = false
, and only explicitly enable the features you need in the img
feature?
If you'd like, I can send a PR which implements this change.
When I use the Encoder
to load a DynamicImage
, and then encode that image to webp, the encode
function returns WebPMemory
. The issue is that I want to perform more actions with the image, like resizing and there is no easy way to convert WebPMemory
back to DynamicImage
.
I can see the WebPImage
has a to_image
function that converts back to DynamicImage
but for some reason, it's not possible to create a WebPImage
from WebPMemory
, in fact, the WebPImage::new
is not even public.
Is there a way to convert WebPMemory
to DynamicImage
? If not, how hard it is to implement that and release a new version to support this?
...
cargo:warning=#include <assert.h>
cargo:warning= ^~~~~~~~~~
cargo:warning=1 error generated.
exit status: 1
--- stderr
error occurred: Command "clang" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "--target=wasm32-unknown-unknown" "-I" "/Users/leping/.cargo/registry/src/github.com-1ecc6299db9ec823/libwebp-sys-0.4.2/vendor" "-Wall" "-Wextra" "-fvisibility=hidden" "-DNDEBUG=1" "-D_THREAD_SAFE=1" "-o" "/Users/leping/Desktop/online-webp-tool/target/wasm32-unknown-unknown/release/build/libwebp-sys-a70f591a50f6f57f/out/alpha_dec.o" "-c" "/Users/leping/.cargo/registry/src/github.com-1ecc6299db9ec823/libwebp-sys-0.4.2/vendor/src/dec/alpha_dec.c" with args "clang" did not execute successfully (status code exit status: 1).
Error: Compiling your crate to WebAssembly failed
Caused by: failed to execute `cargo build`: exited with exit status: 101
full command: "cargo" "build" "--lib" "--release" "--target" "wasm32-unknown-unknown"
Can I use this crate in wasm?
I compress an image weighing 1.9 mb and a resolution of 750 by 16000 pixels (16000 pixels - length), and the output I get an image weighing 0 bytes in the format .webp, with other large images are fine.
What can be the problem? A piece of code is taken from the convert.rs example.
Hey there,
do you have any plans upgrading the image dependency? I forked your repo and upgraded to 0.23.13. I needed to add a match condition to the new function in the Encoder struct, but then it compiles.
_ => {
unreachable!()
}
I was not able to check it thoroughly. If you are interested to upgrade, I can create a pull request. I did not yet, because my IDE automatically called rustfmt on save with my preferences and I do not know what yours are.
Greetings,
Lewin
I created a crate that downloads pre-built libwebp binary files from Google and links to them. By doing this, we effectively avoid any potential issues with local builds, including upstream changes breaking the build.
https://github.com/zzwxh/webp_encoder
WebPImage::as_image
should be called to_image
to reflect what it does. It does not take any references and is not a cheap conversion because it copies data.
This somehow relates to #7, but seems different enough to me to create a new issue for this.
I am using your crate in my html5-picture. Since webp
calls unreacheable!
when a color profile is not supported, I am required to use panic::catch_unwind
to be able to skip unsupported color profiles.
To prevent me from checking for supported color profiles and synchronize my crate every time webp
changes and gets new implementations, it would be awesome that the from_XXX
functions return Result<Self>
instead of Self
. This way it would be possible to skip unsupported profiles without catching a panic resulting in cleaner code.
While this repository works perfectly fine to convert images to WebP it was not really well documented. So I made a quick example showing on how you could use this module:
https://users.rust-lang.org/t/converting-png-jpeg-image-to-webp/71080/3?u=oniel
Hi!
libwebp-sys just released version 0.9.1 that includes not-yet-released code from libwebp git's 1.3.0 branch. libwebp 1.3.0 appears to be affected by CVE-2023-1999, which might allow arbitrary code execution by a remote attacker because of a double-free.
The CVE situation is a bit confusing because Google hasn't released 1.3.1, even though they fixed the double free in February and the CVE was filed last month (without any details), and Firefox shipped that patch in Firefox 112, refering to CVE-2023-1999, many weeks ago. Ubuntu just updated libwebp in their archives a few days ago to include the patch.
So it might be a good idea to update this crate's libwebp-sys version, too.
If you get any image that is 5000px wide and 3000px tall, and you have 128 mb of ram. You will get a segfault.
Shouldn't the encoder "know" how much memory is left on the system and just use that given amount at most... Even though it slows down the processing? At least it doesnt seg fault.
This can be reproduced by running the convert
example.
valgrind logs:
valgrind --tool=memcheck --leak-check=yes ./target/release/examples/convert
==312736== Memcheck, a memory error detector
==312736== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==312736== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==312736== Command: ./target/release/examples/convert
==312736==
==312736==
==312736== HEAP SUMMARY:
==312736== in use at exit: 49,621,476 bytes in 249 blocks
==312736== total heap usage: 10,265 allocs, 10,016 frees, 278,325,615 bytes allocated
==312736==
==312736== 4,608 bytes in 16 blocks are possibly lost in loss record 16 of 24
==312736== at 0x48469B3: calloc (vg_replace_malloc.c:1554)
==312736== by 0x4011792: calloc (rtld-malloc.h:44)
==312736== by 0x4011792: allocate_dtv (dl-tls.c:375)
==312736== by 0x40121D1: _dl_allocate_tls (dl-tls.c:634)
==312736== by 0x4A29F87: allocate_stack (allocatestack.c:423)
==312736== by 0x4A29F87: pthread_create@@GLIBC_2.34 (pthread_create.c:652)
==312736== by 0x2B024E: std::sys::unix::thread::Thread::new (thread.rs:87)
==312736== by 0x28CC5B: std::thread::Builder::spawn (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x288AA3: <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x289EC1: rayon_core::registry::Registry::new (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x288D44: rayon_core::registry::default_global_registry (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x1262D5: std::sys_common::once::futex::Once::call (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x288BD3: rayon_core::registry::global_registry (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x28C147: rayon_core::current_num_threads (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736==
==312736== 13,500,000 bytes in 1 blocks are possibly lost in loss record 23 of 24
==312736== at 0x4841848: malloc (vg_replace_malloc.c:431)
==312736== by 0x12F34A: WebPPictureAllocYUVA (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12D205: ImportYUVAFromRGBA (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12E733: WebPPictureARGBToYUVADithered (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12FFB2: WebPEncode (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12C648: webp::encoder::Encoder::encode_advanced (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12C4D7: webp::encoder::Encoder::encode (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12BB98: convert::main (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12B702: std::sys_common::backtrace::__rust_begin_short_backtrace (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12BF68: std::rt::lang_start::{{closure}} (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x2A66AD: call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (function.rs:287)
==312736== by 0x2A66AD: do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panicking.rs:485)
==312736== by 0x2A66AD: try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (panicking.rs:449)
==312736== by 0x2A66AD: catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panic.rs:140)
==312736== by 0x2A66AD: {closure#2} (rt.rs:148)
==312736== by 0x2A66AD: do_call<std::rt::lang_start_internal::{closure_env#2}, isize> (panicking.rs:485)
==312736== by 0x2A66AD: try<isize, std::rt::lang_start_internal::{closure_env#2}> (panicking.rs:449)
==312736== by 0x2A66AD: catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> (panic.rs:140)
==312736== by 0x2A66AD: std::rt::lang_start_internal (rt.rs:148)
==312736== by 0x12BDF4: main (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736==
==312736== 36,000,124 bytes in 1 blocks are definitely lost in loss record 24 of 24
==312736== at 0x4841848: malloc (vg_replace_malloc.c:431)
==312736== by 0x12F56E: WebPPictureAlloc (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12EF54: WebPPictureImportRGBA (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12C5D6: webp::encoder::Encoder::encode_advanced (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12C4D7: webp::encoder::Encoder::encode (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12BB98: convert::main (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12B702: std::sys_common::backtrace::__rust_begin_short_backtrace (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x12BF68: std::rt::lang_start::{{closure}} (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736== by 0x2A66AD: call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (function.rs:287)
==312736== by 0x2A66AD: do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panicking.rs:485)
==312736== by 0x2A66AD: try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> (panicking.rs:449)
==312736== by 0x2A66AD: catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> (panic.rs:140)
==312736== by 0x2A66AD: {closure#2} (rt.rs:148)
==312736== by 0x2A66AD: do_call<std::rt::lang_start_internal::{closure_env#2}, isize> (panicking.rs:485)
==312736== by 0x2A66AD: try<isize, std::rt::lang_start_internal::{closure_env#2}> (panicking.rs:449)
==312736== by 0x2A66AD: catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> (panic.rs:140)
==312736== by 0x2A66AD: std::rt::lang_start_internal (rt.rs:148)
==312736== by 0x12BDF4: main (in /home/kavin/Workspace/webp/target/release/examples/convert)
==312736==
==312736== LEAK SUMMARY:
==312736== definitely lost: 36,000,124 bytes in 1 blocks
==312736== indirectly lost: 0 bytes in 0 blocks
==312736== possibly lost: 13,504,608 bytes in 17 blocks
==312736== still reachable: 116,744 bytes in 231 blocks
==312736== suppressed: 0 bytes in 0 blocks
==312736== Reachable blocks (those to which a pointer was found) are not shown.
==312736== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==312736==
==312736== For lists of detected and suppressed errors, rerun with: -s
==312736== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
I want to start off by saying thank you for this awesome crate! It has really made my development a lot easier and above all safer. I'm currently building a media proxy in Rust to download an image and then send it back to the client, encoded in a specified format, and with set dimensions. When I tried doing this with the translucent image below, I got a weird output.
(I was forced to convert the WebP image to PNG because GitHub wouldn't allow a WebP image to be uploaded, but it looks the same as the WebP).
A temporary fix right now is to convert the DynImage
to a RgbImage
before encoding it, and this just strips the alpha channel completely. I understand that implementing alpha channel support might be tricky, but could a temporary workaround be implemented? I'm certain that many would appreciate a non-transparent image above a glitched one :)
This is my workaround (please keep in mind that I am very new to Rust!):
fn webp(img: &DynamicImage, quality: f32) -> Result<Vec<u8>, image::ImageError> {
let (width, height) = img.dimensions();
let rgb = img.to_rgb();
let encoded = webp::Encoder::from_rgb(&rgb, width, height).encode(quality);
Ok(encoded.to_vec())
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.