Fix Exif handling in graphics::image

Fixes #3094.
This commit is contained in:
Héctor Ramón Jiménez 2025-10-29 13:41:20 +01:00
parent f0d0d3d114
commit 6ba6673e2a
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
3 changed files with 30 additions and 9 deletions

4
Cargo.lock generated
View file

@ -2989,9 +2989,9 @@ dependencies = [
[[package]]
name = "kamadak-exif"
version = "0.5.5"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077"
checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837"
dependencies = [
"mutate_once",
]

View file

@ -191,7 +191,7 @@ glam = "0.25"
guillotiere = "0.6"
half = "2.2"
image = { version = "0.25", default-features = false }
kamadak-exif = "0.5"
kamadak-exif = "0.6"
kurbo = "0.10"
lilt = "0.8"
log = "0.4"

View file

@ -49,10 +49,13 @@ pub fn load(handle: &image::Handle) -> Result<Buffer, image::Error> {
use bitflags::bitflags;
bitflags! {
#[derive(Debug)]
struct Operation: u8 {
const FLIP_HORIZONTALLY = 0b001;
const ROTATE_180 = 0b010;
const FLIP_DIAGONALLY = 0b100;
const FLIP_HORIZONTALLY = 0b1;
const ROTATE_180 = 0b10;
const FLIP_VERTICALLY= 0b100;
const ROTATE_90 = 0b1000;
const ROTATE_270 = 0b10000;
}
}
@ -69,7 +72,17 @@ pub fn load(handle: &image::Handle) -> Result<Buffer, image::Error> {
.get_field(exif::Tag::Orientation, exif::In::PRIMARY)
.and_then(|field| field.value.get_uint(0))
.and_then(|value| u8::try_from(value).ok())
.and_then(|value| Self::from_bits(value.saturating_sub(1)))
.map(|value| match value {
1 => Operation::empty(),
2 => Operation::FLIP_HORIZONTALLY,
3 => Operation::ROTATE_180,
4 => Operation::FLIP_VERTICALLY,
5 => Operation::ROTATE_90 | Operation::FLIP_HORIZONTALLY,
6 => Operation::ROTATE_90,
7 => Operation::ROTATE_90 | Operation::FLIP_VERTICALLY,
8 => Operation::ROTATE_270,
_ => Operation::empty(),
})
.unwrap_or_else(Self::empty))
}
@ -79,14 +92,22 @@ pub fn load(handle: &image::Handle) -> Result<Buffer, image::Error> {
) -> ::image::DynamicImage {
use ::image::imageops;
if self.contains(Self::FLIP_DIAGONALLY) {
imageops::flip_vertical_in_place(&mut image);
if self.contains(Operation::ROTATE_90) {
image = imageops::rotate90(&image).into();
}
if self.contains(Self::ROTATE_180) {
imageops::rotate180_in_place(&mut image);
}
if self.contains(Operation::ROTATE_270) {
image = imageops::rotate270(&image).into();
}
if self.contains(Self::FLIP_VERTICALLY) {
imageops::flip_vertical_in_place(&mut image);
}
if self.contains(Self::FLIP_HORIZONTALLY) {
imageops::flip_horizontal_in_place(&mut image);
}