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]] [[package]]
name = "kamadak-exif" name = "kamadak-exif"
version = "0.5.5" version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef4fc70d0ab7e5b6bafa30216a6b48705ea964cdfc29c050f2412295eba58077" checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837"
dependencies = [ dependencies = [
"mutate_once", "mutate_once",
] ]

View file

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

View file

@ -49,10 +49,13 @@ pub fn load(handle: &image::Handle) -> Result<Buffer, image::Error> {
use bitflags::bitflags; use bitflags::bitflags;
bitflags! { bitflags! {
#[derive(Debug)]
struct Operation: u8 { struct Operation: u8 {
const FLIP_HORIZONTALLY = 0b001; const FLIP_HORIZONTALLY = 0b1;
const ROTATE_180 = 0b010; const ROTATE_180 = 0b10;
const FLIP_DIAGONALLY = 0b100; 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) .get_field(exif::Tag::Orientation, exif::In::PRIMARY)
.and_then(|field| field.value.get_uint(0)) .and_then(|field| field.value.get_uint(0))
.and_then(|value| u8::try_from(value).ok()) .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)) .unwrap_or_else(Self::empty))
} }
@ -79,14 +92,22 @@ pub fn load(handle: &image::Handle) -> Result<Buffer, image::Error> {
) -> ::image::DynamicImage { ) -> ::image::DynamicImage {
use ::image::imageops; use ::image::imageops;
if self.contains(Self::FLIP_DIAGONALLY) { if self.contains(Operation::ROTATE_90) {
imageops::flip_vertical_in_place(&mut image); image = imageops::rotate90(&image).into();
} }
if self.contains(Self::ROTATE_180) { if self.contains(Self::ROTATE_180) {
imageops::rotate180_in_place(&mut image); 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) { if self.contains(Self::FLIP_HORIZONTALLY) {
imageops::flip_horizontal_in_place(&mut image); imageops::flip_horizontal_in_place(&mut image);
} }