heif: Ignore EXIF rotation info for now
Ideally we would check if HEIF has transformations but that will only work when libheif 1.16 is supported Closes #157
This commit is contained in:
parent
3dc9e40bcb
commit
dbf662ed3a
5 changed files with 104 additions and 47 deletions
|
|
@ -19,6 +19,7 @@
|
|||
use super::*;
|
||||
use crate::decoder::tiling::{self, FrameBufferExt};
|
||||
use crate::deps::*;
|
||||
use crate::image_metadata::ImageMetadata;
|
||||
use crate::util;
|
||||
use crate::util::gettext::*;
|
||||
use crate::util::ToBufRead;
|
||||
|
|
@ -71,6 +72,13 @@ impl Heif {
|
|||
.context(gettext("Failed to decode image"))?;
|
||||
let handle = ctx.primary_image_handle()?;
|
||||
|
||||
let mut metadata = Self::exif(&handle, &file);
|
||||
|
||||
// TODO: Later use libheif 1.16 to get info if there is a transformation
|
||||
metadata.heif_transform = true;
|
||||
|
||||
updater.send(DecoderUpdate::Metadata(metadata));
|
||||
|
||||
tiles.set_original_dimensions((handle.width(), handle.height()));
|
||||
|
||||
let rgb_chroma = if handle.luma_bits_per_pixel() > 8 {
|
||||
|
|
@ -155,6 +163,36 @@ impl Heif {
|
|||
cancellable: cancellable_,
|
||||
}
|
||||
}
|
||||
|
||||
fn exif(handle: &libheif_rs::ImageHandle, file: &gio::File) -> ImageMetadata {
|
||||
let mut meta_ids = vec![0];
|
||||
handle.metadata_block_ids(&mut meta_ids, b"Exif");
|
||||
|
||||
if let Some(meta_id) = meta_ids.first() {
|
||||
match handle.metadata(*meta_id) {
|
||||
Ok(mut exif_bytes) => {
|
||||
if let Some(skip) = exif_bytes
|
||||
.get(0..4)
|
||||
.map(|x| u32::from_be_bytes(x.try_into().unwrap()) as usize)
|
||||
{
|
||||
if exif_bytes.len() > skip + 4 {
|
||||
exif_bytes.drain(0..skip + 4);
|
||||
return ImageMetadata::from_exif_bytes(exif_bytes);
|
||||
} else {
|
||||
log::warn!("EXIF data has far too few bytes in {}", file.uri());
|
||||
}
|
||||
} else {
|
||||
log::warn!("EXIF data has far too few bytes in {}", file.uri());
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::warn!("Unable to decode EXIF data for {}: {err}", file.uri());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageMetadata::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Decoded<'a> {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
use super::*;
|
||||
use crate::decoder::tiling::{self, FrameBufferExt};
|
||||
use crate::deps::*;
|
||||
use crate::image_metadata::ImageMetadata;
|
||||
use crate::util;
|
||||
use crate::util::gettext::*;
|
||||
use crate::util::{BufReadSeek, ToBufRead};
|
||||
|
|
@ -95,7 +96,9 @@ impl ImageRsOther {
|
|||
tiles: Arc<ArcSwap<tiling::FrameBuffer>>,
|
||||
cancellable: gio::Cancellable,
|
||||
) {
|
||||
updater.spawn_error_handled(move || {
|
||||
updater.clone().spawn_error_handled(move || {
|
||||
updater.send(DecoderUpdate::Metadata(ImageMetadata::load(&file)));
|
||||
|
||||
let reader = Self::reader(&file, format, &cancellable)?;
|
||||
let dimensions = reader
|
||||
.into_dimensions()
|
||||
|
|
@ -157,6 +160,8 @@ impl ImageRsOther {
|
|||
cancellable: gio::Cancellable,
|
||||
) -> std::thread::JoinHandle<()> {
|
||||
updater.clone().spawn_error_handled(move || {
|
||||
updater.send(DecoderUpdate::Metadata(ImageMetadata::load(&file)));
|
||||
|
||||
let mut nth_frame = 1;
|
||||
|
||||
// We are currently decoding for each repetition of the animation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue