image-rs / image

Encoding and decoding images in Rust
Apache License 2.0
4.86k stars 597 forks source link

Freeze when trying to open and save jpg and webp files #2282

Closed qarmin closed 1 month ago

qarmin commented 1 month ago

image-rs 59358a63822993d10c96ff8d9b062378d3e4f94d

code

fn check_file(file_path: &str) {
    let res = match image::open(file_path) {
        Ok(res) => res,
        Err(e) => {
            eprintln!("Error: {}", e);
            return;
        }
    };
    println!("Image: {file_path}");
    for format in [
        ImageFormat::Avif,
    ]
        .into_iter()
    {
        let buffer: Vec<u8> = Vec::new();
        println!("Before write_to {format:?}");
        if let Err(e) = res.write_to(&mut Cursor::new(buffer), format) {
            eprintln!("Error: {}", e);
        };
        println!("After write_to {format:?}");
    }
}

files - Broken.zip

output from one of the files

Error: The encoder or decoder for Farbfeld does not support the color type `Rgb8`
Error: The parameter is malformed: the image width must be `1..=256`, instead width 3024 was provided
Error: The image format `Dds` is not supported
Error: Format error encoding Hdr:
hdr format currently only supports the `Rgb32F` color type
Error: Format error encoding OpenExr:
writing color type Rgb8 not yet supported
timeout: sending signal TERM to command ‘image’

##### Automatic Fuzzer note, output status "Some(124)", output signal "None"
fintelia commented 1 month ago

What's the timeout and which encoder is hitting it?

qarmin commented 1 month ago

The problem is with AVIF encoder In CI (2 available threads) I hit limit 100 seconds which for me was really big number. I didn't check it on computer, because I was thinking that the problem is with permanent freeze, not slow conversion, because JPEG was saved in less than second

time image ZDJ\ 81_IDX_55_RAND_29058914884018118014144.jpg 
Image: ZDJ 81_IDX_55_RAND_29058914884018118014144.jpg
Before write_to Jpeg
After write_to Jpeg

real    0m0,769s
user    0m0,738s
sys 0m0,031s

But now I checked conversion locally and I see now that conversion is very slow(on i7 - 4 cpu/8 threads)

time image ZDJ\ 81_IDX_55_RAND_29058914884018118014144.jpg 
Image: ZDJ 81_IDX_55_RAND_29058914884018118014144.jpg
Before write_to Avif
After write_to Avif

real    0m46,739s
user    4m32,674s
sys 0m1,027s
time image port_back_IDX_10_RAND_132968686185973752667241.webp 
Image: port_back_IDX_10_RAND_132968686185973752667241.webp
Before write_to Avif
After write_to Avif

real    0m35,478s
user    3m42,638s
sys 0m0,322s

when forcing app to use 1 thread, conversion is even slower - 170s (not sure why time format is so strange)

RAYON_NUM_THREADS=1 time image ZDJ\ 81_IDX_55_RAND_29058914884018118014144.jpg 
Image: ZDJ 81_IDX_55_RAND_29058914884018118014144.jpg
Before write_to Avif
After write_to Avif
171.70user 0.19system 2:51.92elapsed 99%CPU (0avgtext+0avgdata 407832maxresident)k
0inputs+0outputs (0major+108768minor)pagefaults 0swaps
fintelia commented 1 month ago

You can get better performance by enabling the nasm feature which requires that you have nasm installed. Ultimately though, avif is just a much slower format to encode than jpeg which is the tradeoff for getting better compression/quality