image icon indicating copy to clipboard operation
image copied to clipboard

Reading JPEG images inserts rectangular artefacts in v0.25.9

Open alexwlchan opened this issue 2 weeks ago • 6 comments

I've found a bug where rectangular artefacts get inserted into JPEG images read with 0.25.9, but not 0.25.8.

Here's an example of an affected image:

Image

Expected

Images are saved without artefacts.

Actual behaviour

Images are saved with artefacts.

Reproduction steps

  1. I downloaded the fractal.png image from the README and converted it to a JPEG using ImageMagick (magick fractal.png fractal.jpg).

  2. I ran the following script to do four transformations:

    use image::ImageReader;
    
    fn main() {
        let png = ImageReader::open("fractal.png").unwrap().decode().unwrap();
        let jpg = ImageReader::open("fractal.jpg").unwrap().decode().unwrap();
    
        png.save("fractal_0.25.8_png_to_png.png").unwrap();
        png.save("fractal_0.25.8_png_to_jpg.jpg").unwrap();
        jpg.save("fractal_0.25.8_jpg_to_png.png").unwrap();
        jpg.save("fractal_0.25.8_jpg_to_png.jpg").unwrap();
    }
    

The images in 0.25.8 look fine.

The images which were read from JPEGs in 0.25.9 have rectangular artefacts.

Here's a zip file with all my code and images: example.zip

Environment

I'm on macOS 15.6.1, if that's important.

$ cargo --version
cargo 1.89.0 (c24e10642 2025-06-23)

$ rustc --version
rustc 1.89.0 (29483883e 2025-08-04)

alexwlchan avatar Dec 09 '25 23:12 alexwlchan

What's your processor config? I can't reproduce this on x86_64 so assuming this is architecture dependent and some improper SIMD (or non-SIMD) code that is responsible.

$ cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 142
model name	: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
stepping	: 11
microcode	: 0xf6
cpu MHz		: 700.052
cache size	: 8192 KB
physical id	: 0
siblings	: 8
core id		: 0
cpu cores	: 4
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 22
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust sgx bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp vnmi md_clear flush_l1d arch_capabilities
vmx flags	: vnmi preemption_timer invvpid ept_x_only ept_ad ept_1gb flexpriority tsc_offset vtpr mtf vapic ept vpid unrestricted_guest ple pml ept_violation_ve ept_mode_based_exec
bugs		: spectre_v1 spectre_v2 spec_store_bypass mds swapgs itlb_multihit srbds mmio_stale_data retbleed gds vmscape
bogomips	: 4001.60
clflush size	: 64
cache_alignment	: 64
address sizes	: 39 bits physical, 48 bits virtual
power management:

197g avatar Dec 09 '25 23:12 197g

It reproduces on aarch64.

awxkee avatar Dec 09 '25 23:12 awxkee

I can't reproduce this on x86_64 so assuming this is architecture dependent

Yes, I'm on a Mac running Apple Silicon – specifically, an M4 Pro. I'm not sure how to get the equivalent of /proc/cpuinfo on my Mac. 🤔

alexwlchan avatar Dec 09 '25 23:12 alexwlchan

Assuming I messed up in https://github.com/etemesi254/zune-image/pull/299 in the non-SIMD path? Since that's the neon code that is getting executed. Great 🫤

197g avatar Dec 10 '25 00:12 197g

Yes, it fails only with zune-jpeg = 0.5.6. So it seems something wrong there.

awxkee avatar Dec 10 '25 00:12 awxkee

I can reproduce it with SIMD turned off on x86_64 as well, seems pretty likely to be the culprit.

197g avatar Dec 10 '25 00:12 197g

Same problem here, I need to downgrade to 24.0

mathis6787 avatar Dec 13 '25 06:12 mathis6787

Since we identified the fault, a workaround should be to downgrade zune-jpeg to 0.5.5:

cargo update -p [email protected] --precise 0.5.5

Or add an equivalent constraint in any local Cargo.toml

[dependencies]
zune-jpeg = "=0.5.5"

197g avatar Dec 13 '25 13:12 197g

0.5.7 released with the fix.

Aplogies to all

etemesi254 avatar Dec 14 '25 20:12 etemesi254

Thanks @etemesi254, I'm looking to improve the test suite coverage so CI catches this when I'm only testing on recent x86_64 myself.

197g avatar Dec 14 '25 21:12 197g