Reading JPEG images inserts rectangular artefacts in v0.25.9
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:
Expected
Images are saved without artefacts.
Actual behaviour
Images are saved with artefacts.
Reproduction steps
-
I downloaded the
fractal.pngimage from the README and converted it to a JPEG using ImageMagick (magick fractal.png fractal.jpg). -
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)
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:
It reproduces on aarch64.
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. 🤔
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 🫤
Yes, it fails only with zune-jpeg = 0.5.6. So it seems something wrong there.
I can reproduce it with SIMD turned off on x86_64 as well, seems pretty likely to be the culprit.
Same problem here, I need to downgrade to 24.0
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"
0.5.7 released with the fix.
Aplogies to all
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.