summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-09-30 16:11:30 +0700
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2021-09-30 16:15:15 +0700
commit21d138aa28a518ca0893eec4abbda95b07ba56bc (patch)
tree289761020cf657f178fed9a81531598562886766 /wgpu
parent4fd2e1a57d1f7df98cdae955991f127a122a3644 (diff)
downloadiced-21d138aa28a518ca0893eec4abbda95b07ba56bc.tar.gz
iced-21d138aa28a518ca0893eec4abbda95b07ba56bc.tar.bz2
iced-21d138aa28a518ca0893eec4abbda95b07ba56bc.zip
Refactor `Orientation` into `Operation` in `image::raster`
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/Cargo.toml1
-rw-r--r--wgpu/src/image/raster.rs94
2 files changed, 42 insertions, 53 deletions
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index c860bbf1..af841036 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -35,6 +35,7 @@ log = "0.4"
guillotiere = "0.6"
futures = "0.3"
kamadak-exif = "0.5"
+bitflags = "1.3"
[dependencies.bytemuck]
version = "1.4"
diff --git a/wgpu/src/image/raster.rs b/wgpu/src/image/raster.rs
index 826b4539..21659039 100644
--- a/wgpu/src/image/raster.rs
+++ b/wgpu/src/image/raster.rs
@@ -2,6 +2,8 @@ use crate::image::atlas::{self, Atlas};
use iced_native::image;
use std::collections::{HashMap, HashSet};
+use bitflags::bitflags;
+
#[derive(Debug)]
pub enum Memory {
Host(::image_rs::ImageBuffer<::image_rs::Bgra<u8>, Vec<u8>>),
@@ -43,27 +45,27 @@ impl Cache {
let memory = match handle.data() {
image::Data::Path(path) => {
if let Ok(image) = ::image_rs::open(path) {
- let orientation = std::fs::File::open(path)
+ let operation = std::fs::File::open(path)
.ok()
.map(std::io::BufReader::new)
.and_then(|mut reader| {
- Orientation::from_exif(&mut reader).ok()
+ Operation::from_exif(&mut reader).ok()
})
- .unwrap_or(Orientation::Default);
+ .unwrap_or_else(Operation::empty);
- Memory::Host(orientation.apply(image.to_bgra8()))
+ Memory::Host(operation.perform(image.to_bgra8()))
} else {
Memory::NotFound
}
}
image::Data::Bytes(bytes) => {
if let Ok(image) = ::image_rs::load_from_memory(&bytes) {
- let orientation = Orientation::from_exif(
- &mut std::io::Cursor::new(bytes),
- )
- .unwrap_or(Orientation::Default);
+ let operation =
+ Operation::from_exif(&mut std::io::Cursor::new(bytes))
+ .ok()
+ .unwrap_or_else(Operation::empty);
- Memory::Host(orientation.apply(image.to_bgra8()))
+ Memory::Host(operation.perform(image.to_bgra8()))
} else {
Memory::Invalid
}
@@ -146,66 +148,52 @@ impl Cache {
}
}
-#[derive(Debug, Clone, Copy)]
-enum Orientation {
- Default,
- FlippedHorizontally,
- FlippedVertically,
- Rotated90,
- Rotated180,
- Rotated270,
- Rotated90AndFlippedHorizontally,
- Rotated90AndFlippedVertically,
+bitflags! {
+ struct Operation: u8 {
+ const FLIP_HORIZONTALLY = 0b001;
+ const ROTATE_180 = 0b010;
+ const FLIP_DIAGONALLY = 0b100;
+ }
}
-impl Orientation {
+impl Operation {
// Meaning of the returned value is described e.g. at:
// https://magnushoff.com/articles/jpeg-orientation/
fn from_exif<R>(reader: &mut R) -> Result<Self, exif::Error>
where
R: std::io::BufRead + std::io::Seek,
{
+ use std::convert::TryFrom;
+
let exif = exif::Reader::new().read_from_container(reader)?;
Ok(exif
.get_field(::exif::Tag::Orientation, ::exif::In::PRIMARY)
.and_then(|field| field.value.get_uint(0))
- .map(|value| match value {
- 2 => Orientation::FlippedHorizontally,
- 3 => Orientation::Rotated180,
- 4 => Orientation::FlippedVertically,
- 5 => Orientation::Rotated90AndFlippedHorizontally,
- 6 => Orientation::Rotated90,
- 7 => Orientation::Rotated90AndFlippedVertically,
- 8 => Orientation::Rotated270,
- _ => Orientation::Default,
- })
- .unwrap_or(Orientation::Default))
+ .and_then(|value| u8::try_from(value).ok())
+ .and_then(|value| Self::from_bits(value.saturating_sub(1)))
+ .unwrap_or_else(Self::empty))
}
- fn apply(
- self,
- mut img: ::image_rs::ImageBuffer<::image_rs::Bgra<u8>, Vec<u8>>,
- ) -> image_rs::ImageBuffer<::image_rs::Bgra<u8>, Vec<u8>> {
- use image_rs::imageops::*;
+ fn perform<I>(self, mut image: I) -> I
+ where
+ I: image_rs::GenericImage,
+ {
+ use image_rs::imageops;
- match self {
- Self::FlippedHorizontally => flip_horizontal_in_place(&mut img),
- Self::Rotated180 => rotate180_in_place(&mut img),
- Self::FlippedVertically => flip_vertical_in_place(&mut img),
- Self::Rotated90AndFlippedHorizontally => {
- img = rotate90(&img);
- flip_horizontal_in_place(&mut img);
- }
- Self::Rotated90 => img = rotate90(&img),
- Self::Rotated90AndFlippedVertically => {
- img = rotate90(&img);
- flip_vertical_in_place(&mut img);
- }
- Self::Rotated270 => img = rotate270(&img),
- Self::Default => {}
- };
+ if self.contains(Self::FLIP_DIAGONALLY) {
+ imageops::flip_horizontal_in_place(&mut image);
+ imageops::flip_vertical_in_place(&mut image);
+ }
+
+ if self.contains(Self::ROTATE_180) {
+ imageops::rotate180_in_place(&mut image);
+ }
+
+ if self.contains(Self::FLIP_HORIZONTALLY) {
+ imageops::flip_horizontal_in_place(&mut image);
+ }
- img
+ image
}
}