diff --git a/.github/scripts/setup-system.sh b/.github/scripts/setup-system.sh index 2df0ee997..acf69aec3 100755 --- a/.github/scripts/setup-system.sh +++ b/.github/scripts/setup-system.sh @@ -146,8 +146,6 @@ if [ "$SYSNAME" = "Linux" ]; then # FFmpeg dependencies DEBIAN_FFMPEG_DEPS="libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev ffmpeg" - DEBIAN_LIBHEIF_DEPS="libheif1 libheif-dev" - # Webkit2gtk requires gstreamer plugins for video playback to work DEBIAN_VIDEO_DEPS="gstreamer1.0-libav gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly" @@ -158,7 +156,7 @@ if [ "$SYSNAME" = "Linux" ]; then DEBIAN_LIBP2P_DEPS="protobuf-compiler" sudo apt-get -y update - sudo apt-get -y install ${SPACEDRIVE_CUSTOM_APT_FLAGS:-} $DEBIAN_TAURI_DEPS $DEBIAN_FFMPEG_DEPS $DEBIAN_LIBHEIF_DEPS $DEBIAN_BINDGEN_DEPS $DEBIAN_LIBP2P_DEPS $DEBIAN_VIDEO_DEPS + sudo apt-get -y install ${SPACEDRIVE_CUSTOM_APT_FLAGS:-} $DEBIAN_TAURI_DEPS $DEBIAN_FFMPEG_DEPS $DEBIAN_BINDGEN_DEPS $DEBIAN_LIBP2P_DEPS $DEBIAN_VIDEO_DEPS elif has pacman; then echo "Detected pacman!" echo "Installing dependencies with pacman..." @@ -172,15 +170,13 @@ if [ "$SYSNAME" = "Linux" ]; then # FFmpeg dependencies ARCH_FFMPEG_DEPS="ffmpeg" - ARCH_LIBHEIF_DEPS="libheif" - # Bindgen dependencies - it's used by a dependency of Spacedrive ARCH_BINDGEN_DEPS="clang" # Protobuf compiler - https://github.com/archlinux/svntogit-packages/blob/packages/protobuf/trunk/PKGBUILD provides `libprotoc` ARCH_LIBP2P_DEPS="protobuf" - sudo pacman -Sy --needed $ARCH_TAURI_DEPS $ARCH_FFMPEG_DEPS $ARCH_LIBHEIF_DEPS $ARCH_BINDGEN_DEPS $ARCH_LIBP2P_DEPS $ARCH_VIDEO_DEPS + sudo pacman -Sy --needed $ARCH_TAURI_DEPS $ARCH_FFMPEG_DEPS $ARCH_BINDGEN_DEPS $ARCH_LIBP2P_DEPS $ARCH_VIDEO_DEPS elif has dnf; then echo "Detected dnf!" echo "Installing dependencies with dnf..." @@ -202,9 +198,6 @@ if [ "$SYSNAME" = "Linux" ]; then # FFmpeg dependencies FEDORA_FFMPEG_DEPS="ffmpeg ffmpeg-devel" - # libheif dependencies - FEDORA_LIBHEIF_DEPS="libheif libheif-devel" - # Webkit2gtk requires gstreamer plugins for video playback to work FEDORA_VIDEO_DEPS="gstreamer1-plugin-libav gstreamer1-plugins-base gstreamer1-plugins-good gstreamer1-plugins-good-extras gstreamer1-plugins-bad-free gstreamer1-plugins-bad-free-extras gstreamer1-plugins-ugly-free" @@ -226,7 +219,7 @@ if [ "$SYSNAME" = "Linux" ]; then 'https://docs.fedoraproject.org/en-US/quick-docs/setup_rpmfusion' fi - sudo dnf install $FEDORA_TAURI_DEPS $FEDORA_BINDGEN_DEPS $FEDORA_LIBP2P_DEPS $FEDORA_VIDEO_DEPS $FEDORA_LIBHEIF_DEPS + sudo dnf install $FEDORA_TAURI_DEPS $FEDORA_BINDGEN_DEPS $FEDORA_LIBP2P_DEPS $FEDORA_VIDEO_DEPS sudo dnf group install "C Development Tools and Libraries" else err "Your Linux distro '$(lsb_release -s -d)' is not supported by this script." \ diff --git a/Cargo.lock b/Cargo.lock index 2b3c9381e..8c6c6de43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6900,7 +6900,6 @@ version = "0.1.0" dependencies = [ "image", "libheif-rs", - "png", "thiserror", ] diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 6a531be8d..41700fea6 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -9,11 +9,7 @@ repository.workspace = true edition.workspace = true [dependencies] -tauri = { version = "1.3.0", features = [ - "api-all", - "linux-protocol-headers", - "macos-private-api", -] } +tauri = { version = "1.3.0", features = ["api-all", "linux-protocol-headers", "macos-private-api"] } rspc = { workspace = true, features = ["tauri"] } httpz = { workspace = true, features = [ "axum", diff --git a/core/src/object/preview/thumbnail/mod.rs b/core/src/object/preview/thumbnail/mod.rs index 40ab10493..e92b4f1e1 100644 --- a/core/src/object/preview/thumbnail/mod.rs +++ b/core/src/object/preview/thumbnail/mod.rs @@ -113,7 +113,7 @@ pub struct ThumbnailerJobStep { } // TOOD(brxken128): validate avci and avcs -#[cfg(all(feature = "heif", any(target_os = "macos", target_os = "linux")))] +#[cfg(all(feature = "heif", target_os = "macos"))] const HEIF_EXTENSIONS: [&str; 7] = ["heif", "heifs", "heic", "heics", "avif", "avci", "avcs"]; pub async fn generate_image_thumbnail>( @@ -122,7 +122,7 @@ pub async fn generate_image_thumbnail>( ) -> Result<(), Box> { // Webp creation has blocking code let webp = block_in_place(|| -> Result, Box> { - #[cfg(all(feature = "heif", any(target_os = "macos", target_os = "linux")))] + #[cfg(all(feature = "heif", target_os = "macos"))] let img = { let ext = file_path.as_ref().extension().unwrap().to_ascii_lowercase(); if HEIF_EXTENSIONS @@ -135,7 +135,7 @@ pub async fn generate_image_thumbnail>( } }; - #[cfg(not(all(feature = "heif", any(target_os = "macos", target_os = "linux"))))] + #[cfg(not(all(feature = "heif", target_os = "macos")))] let img = image::open(file_path)?; let (w, h) = img.dimensions(); @@ -183,13 +183,13 @@ pub const fn can_generate_thumbnail_for_video(video_extension: &VideoExtension) pub const fn can_generate_thumbnail_for_image(image_extension: &ImageExtension) -> bool { use ImageExtension::*; - #[cfg(all(feature = "heif", any(target_os = "macos", target_os = "linux")))] + #[cfg(all(feature = "heif", target_os = "macos"))] let res = matches!( image_extension, Jpg | Jpeg | Png | Webp | Gif | Heic | Heics | Heif | Heifs | Avif ); - #[cfg(not(all(feature = "heif", any(target_os = "macos", target_os = "linux"))))] + #[cfg(not(all(feature = "heif", target_os = "macos")))] let res = matches!(image_extension, Jpg | Jpeg | Png | Webp | Gif); res diff --git a/crates/heif/Cargo.toml b/crates/heif/Cargo.toml index ad2560ebf..80e7f28c6 100644 --- a/crates/heif/Cargo.toml +++ b/crates/heif/Cargo.toml @@ -8,6 +8,5 @@ edition.workspace = true [dependencies] libheif-rs = "0.19.2" -png = "0.17.8" -thiserror = "1.0.40" image = "0.24.6" +thiserror = "1.0.40" diff --git a/crates/heif/src/lib.rs b/crates/heif/src/lib.rs index a4b7a115c..c86b4d317 100644 --- a/crates/heif/src/lib.rs +++ b/crates/heif/src/lib.rs @@ -6,7 +6,6 @@ use std::{ use image::DynamicImage; use libheif_rs::{ColorSpace, HeifContext, LibHeif, RgbChroma}; -use png::{BitDepth, ColorType}; use thiserror::Error; type HeifResult = Result; @@ -20,12 +19,12 @@ const HEIF_MAXIMUM_FILE_SIZE: u64 = 1048576 * 20; pub enum HeifError { #[error("error with libheif: {0}")] LibHeif(#[from] libheif_rs::HeifError), - #[error("error while encoding to png: {0}")] - PngEncode(#[from] png::EncodingError), #[error("error while loading the image (via the `image` crate): {0}")] Image(#[from] image::ImageError), #[error("io error: {0}")] Io(#[from] std::io::Error), + #[error("there was an error while converting the image to an `RgbImage`")] + RgbImageConversion, #[error("the image provided is unsupported")] Unsupported, #[error("the image provided is too large (over 20MiB)")] @@ -53,6 +52,10 @@ pub fn heif_to_dynamic_image(path: &Path) -> HeifResult { // TODO(brxken128): add support for images with individual r/g/b channels // i'm unable to find a sample to test with, but it should follow the same principles as this one if let Some(i) = img.planes().interleaved { + if i.bits_per_pixel != 8 { + return Err(HeifError::InvalidBitDepth); + } + let data = i.data.to_vec(); let mut reader = Cursor::new(data); @@ -70,19 +73,10 @@ pub fn heif_to_dynamic_image(path: &Path) -> HeifResult { } } - let mut writer = Cursor::new(vec![]); + let rgb_img = image::RgbImage::from_raw(img.width(), img.height(), sequence) + .ok_or(HeifError::RgbImageConversion)?; - let mut png_encoder = png::Encoder::new(&mut writer, i.width, i.height); - png_encoder.set_color(ColorType::Rgb); - png_encoder - .set_depth(BitDepth::from_u8(i.bits_per_pixel).ok_or(HeifError::InvalidBitDepth)?); - - let mut png_writer = png_encoder.write_header()?; - png_writer.write_image_data(&sequence)?; - png_writer.finish()?; - - image::load_from_memory_with_format(&writer.into_inner(), image::ImageFormat::Png) - .map_err(HeifError::Image) + Ok(DynamicImage::ImageRgb8(rgb_img)) } else { Err(HeifError::Unsupported) }