From 0ca94399cbdb4c3793b39ed52a0d0d7d0228834c Mon Sep 17 00:00:00 2001 From: Aaron Leopold <36278431+aaronleopold@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:19:20 -0700 Subject: [PATCH 1/3] :rewind: Revert `avif` support After a lot of discussions on Discord and avif-related bugs, I am temporarily reverting the avif additions. This isn't a literal commit revert, I've kept in a few bits for easier re-integration later --- .github/actions/coverage/action.yml | 3 - .github/workflows/ci.yaml | 3 - Cargo.lock | 117 --------- core/Cargo.toml | 3 +- core/src/filesystem/common.rs | 3 +- core/src/filesystem/content_type.rs | 15 -- core/src/filesystem/image/generic.rs | 324 +----------------------- core/src/filesystem/image/process.rs | 11 +- core/src/filesystem/image/webp.rs | 71 +----- docker/Dockerfile | 30 --- docker/entrypoint.sh | 3 - docs/pages/contributing.mdx | 2 +- docs/pages/guides/basics/thumbnails.mdx | 4 +- packages/types/generated.ts | 2 +- scripts/system-setup.sh | 2 +- 15 files changed, 12 insertions(+), 581 deletions(-) diff --git a/.github/actions/coverage/action.yml b/.github/actions/coverage/action.yml index 298807344..b58426084 100644 --- a/.github/actions/coverage/action.yml +++ b/.github/actions/coverage/action.yml @@ -13,9 +13,6 @@ inputs: runs: using: composite steps: - - name: Setup dav1d - uses: ./.github/actions/setup-dav1d - - name: Setup rust uses: ./.github/actions/setup-rust with: diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fb8eec8a8..14df86a6e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -41,9 +41,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup dav1d - uses: ./.github/actions/setup-dav1d - - name: Setup rust uses: ./.github/actions/setup-rust with: diff --git a/Cargo.lock b/Cargo.lock index 765a5991f..560d32d9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -373,20 +373,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "av-data" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b98a3525d00f920df9a2d44cc99b9cc5b7dc70d7fbb612cd755270dbe6552" -dependencies = [ - "byte-slice-cast", - "bytes", - "num-derive 0.4.2", - "num-rational", - "num-traits", - "thiserror", -] - [[package]] name = "av1-grain" version = "0.2.3" @@ -628,15 +614,6 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" -[[package]] -name = "bitreader" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdd859c9d97f7c468252795b35aeccc412bdbb1e90ee6969c4fa6328272eaeff" -dependencies = [ - "cfg-if", -] - [[package]] name = "bitstream-io" version = "1.10.0" @@ -770,12 +747,6 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - [[package]] name = "bytemuck" version = "1.16.3" @@ -947,16 +918,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "cfg-expr" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345c78335be0624ed29012dc10c49102196c6882c12dde65d9f35b02da2aada8" -dependencies = [ - "smallvec", - "target-lexicon", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -1688,28 +1649,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "dav1d" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4b54a40baf633a71c6f0fb49494a7e4ee7bc26f3e727212b6cb915aa1ea1e1" -dependencies = [ - "av-data", - "bitflags 2.4.0", - "dav1d-sys", - "static_assertions", -] - -[[package]] -name = "dav1d-sys" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ecb1c5e8f4dc438eedc1b534a54672fb0e0a56035dae6b50162787bd2c50e95" -dependencies = [ - "libc", - "system-deps 6.2.2", -] - [[package]] name = "dbus" version = "0.9.7" @@ -1721,16 +1660,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dcv-color-primitives" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ad62edfed069700a5b33af6babd29c498d7e33eb01d96ffa8841ee1841634c" -dependencies = [ - "paste", - "wasm-bindgen", -] - [[package]] name = "deflate" version = "1.0.0" @@ -2194,15 +2123,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" -[[package]] -name = "fallible_collections" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88c69768c0a15262df21899142bc6df9b9b823546d4b4b9a7bc2d6c448ec6fd" -dependencies = [ - "hashbrown 0.13.2", -] - [[package]] name = "fastrand" version = "2.0.1" @@ -3210,12 +3130,9 @@ dependencies = [ "bytemuck", "byteorder-lite", "color_quant", - "dav1d", - "dcv-color-primitives", "exr", "gif", "image-webp", - "mp4parse", "num-traits", "png", "qoi", @@ -4225,20 +4142,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "mp4parse" -version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63a35203d3c6ce92d5251c77520acb2e57108c88728695aa883f70023624c570" -dependencies = [ - "bitreader", - "byteorder", - "fallible_collections", - "log", - "num-traits", - "static_assertions", -] - [[package]] name = "multer" version = "2.1.0" @@ -7069,12 +6972,6 @@ dependencies = [ "loom", ] -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "string_cache" version = "0.8.4" @@ -7192,7 +7089,6 @@ dependencies = [ "simple_crypt", "specta", "stump-config-gen", - "system-deps 7.0.2", "temp-env", "tempfile", "thiserror", @@ -7359,19 +7255,6 @@ dependencies = [ "version-compare 0.2.0", ] -[[package]] -name = "system-deps" -version = "7.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "070a0a5e7da2d24be457809c4b3baa57a835fd2829ad8b86f9a049052fe71031" -dependencies = [ - "cfg-expr 0.16.0", - "heck 0.5.0", - "pkg-config", - "toml 0.8.12", - "version-compare 0.2.0", -] - [[package]] name = "tao" version = "0.15.8" diff --git a/core/Cargo.toml b/core/Cargo.toml index fd84e898d..1117f55af 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -14,7 +14,7 @@ email = { path = "../crates/email" } epub = { git = "https://github.com/stumpapp/epub-rs", rev = "38e091abe96875952556ab7dec195022d0230e14" } futures = { workspace = true } globset = "0.4.14" -image = {version = "0.25.2", features = ["avif-native"]} +image = { version = "0.25.2" } infer = "0.16.0" itertools = { workspace = true } prisma-client-rust = { workspace = true } @@ -54,7 +54,6 @@ criterion = { version = "0.5.1", features = ["html_reports", "async_tokio"] } [build-dependencies] chrono = "0.4.37" -system-deps = "7.0.1" [target.'cfg(target_os = "linux")'.dependencies] libc = "0.2.152" diff --git a/core/src/filesystem/common.rs b/core/src/filesystem/common.rs index b1adf9227..6cef35fc8 100644 --- a/core/src/filesystem/common.rs +++ b/core/src/filesystem/common.rs @@ -9,8 +9,7 @@ use walkdir::WalkDir; use super::{media::is_accepted_cover_name, ContentType, FileError}; -pub const ACCEPTED_IMAGE_EXTENSIONS: [&str; 6] = - ["jpg", "png", "jpeg", "webp", "avif", "gif"]; +pub const ACCEPTED_IMAGE_EXTENSIONS: [&str; 5] = ["jpg", "png", "jpeg", "webp", "gif"]; pub fn read_entire_file>(path: P) -> Result, FileError> { let mut file = File::open(path)?; diff --git a/core/src/filesystem/content_type.rs b/core/src/filesystem/content_type.rs index afd0b01c9..a2640751f 100644 --- a/core/src/filesystem/content_type.rs +++ b/core/src/filesystem/content_type.rs @@ -23,7 +23,6 @@ pub enum ContentType { PNG, JPEG, WEBP, - AVIF, GIF, TXT, #[default] @@ -80,7 +79,6 @@ impl ContentType { "jpg" => ContentType::JPEG, "jpeg" => ContentType::JPEG, "webp" => ContentType::WEBP, - "avif" => ContentType::AVIF, "gif" => ContentType::GIF, "txt" => ContentType::TXT, _ => temporary_content_workarounds(extension), @@ -267,7 +265,6 @@ impl ContentType { ContentType::PNG => "png", ContentType::JPEG => "jpg", ContentType::WEBP => "webp", - ContentType::AVIF => "avif", ContentType::GIF => "gif", ContentType::TXT => "txt", ContentType::UNKNOWN => "", @@ -294,7 +291,6 @@ impl From<&str> for ContentType { "image/png" => ContentType::PNG, "image/jpeg" => ContentType::JPEG, "image/webp" => ContentType::WEBP, - "image/avif" => ContentType::AVIF, "image/gif" => ContentType::GIF, _ => ContentType::UNKNOWN, } @@ -316,7 +312,6 @@ impl std::fmt::Display for ContentType { ContentType::PNG => write!(f, "image/png"), ContentType::JPEG => write!(f, "image/jpeg"), ContentType::WEBP => write!(f, "image/webp"), - ContentType::AVIF => write!(f, "image/avif"), ContentType::GIF => write!(f, "image/gif"), ContentType::TXT => write!(f, "text/plain"), ContentType::UNKNOWN => write!(f, "unknown"), @@ -332,7 +327,6 @@ impl From for ContentType { // ImageFormat::JpegXl => ContentType::JPEG, ImageFormat::Png => ContentType::PNG, ImageFormat::Webp => ContentType::WEBP, - ImageFormat::Avif => ContentType::AVIF, } } } @@ -355,7 +349,6 @@ impl TryFrom for image::ImageFormat { ContentType::PNG => Ok(image::ImageFormat::Png), ContentType::JPEG => Ok(image::ImageFormat::Jpeg), ContentType::WEBP => Ok(image::ImageFormat::WebP), - ContentType::AVIF => Ok(image::ImageFormat::Avif), ContentType::GIF => Ok(image::ImageFormat::Gif), ContentType::XHTML => Err(unsupported_error("ContentType::XHTML")), ContentType::XML => Err(unsupported_error("ContentType::XML")), @@ -391,7 +384,6 @@ mod tests { assert_eq!(ContentType::from_extension("jpg"), ContentType::JPEG); assert_eq!(ContentType::from_extension("jpeg"), ContentType::JPEG); assert_eq!(ContentType::from_extension("webp"), ContentType::WEBP); - assert_eq!(ContentType::from_extension("avif"), ContentType::AVIF); assert_eq!(ContentType::from_extension("gif"), ContentType::GIF); assert_eq!(ContentType::from_extension("txt"), ContentType::TXT); assert_eq!(ContentType::from_extension("opf"), ContentType::XML); @@ -414,7 +406,6 @@ mod tests { assert_eq!(ContentType::from_file("test.jpg"), ContentType::JPEG); assert_eq!(ContentType::from_file("test.jpeg"), ContentType::JPEG); assert_eq!(ContentType::from_file("test.webp"), ContentType::WEBP); - assert_eq!(ContentType::from_file("test.avif"), ContentType::AVIF); assert_eq!(ContentType::from_file("test.gif"), ContentType::GIF); assert_eq!(ContentType::from_file("test.txt"), ContentType::TXT); assert_eq!(ContentType::from_file("test.unknown"), ContentType::UNKNOWN); @@ -476,9 +467,6 @@ mod tests { let path = Path::new("test.webp"); assert_eq!(ContentType::from_path(path), ContentType::WEBP); - let path = Path::new("test.avif"); - assert_eq!(ContentType::from_path(path), ContentType::AVIF); - let path = Path::new("test.gif"); assert_eq!(ContentType::from_path(path), ContentType::GIF); @@ -518,7 +506,6 @@ mod tests { assert_eq!(ContentType::PNG.mime_type(), "image/png".to_string()); assert_eq!(ContentType::JPEG.mime_type(), "image/jpeg".to_string()); assert_eq!(ContentType::WEBP.mime_type(), "image/webp".to_string()); - assert_eq!(ContentType::AVIF.mime_type(), "image/avif".to_string()); assert_eq!(ContentType::GIF.mime_type(), "image/gif".to_string()); assert_eq!(ContentType::TXT.mime_type(), "text/plain".to_string()); assert_eq!(ContentType::UNKNOWN.mime_type(), "unknown".to_string()); @@ -530,7 +517,6 @@ mod tests { assert!(ContentType::PNG.is_image()); assert!(ContentType::JPEG.is_image()); assert!(ContentType::WEBP.is_image()); - assert!(ContentType::AVIF.is_image()); assert!(ContentType::GIF.is_image()); assert!(!ContentType::XHTML.is_image()); @@ -557,7 +543,6 @@ mod tests { // Not an OPDS 1.2 legacy image assert!(!ContentType::WEBP.is_opds_legacy_image()); - assert!(!ContentType::AVIF.is_opds_legacy_image()); } #[test] diff --git a/core/src/filesystem/image/generic.rs b/core/src/filesystem/image/generic.rs index 0b1eb2081..eb2a8eb43 100644 --- a/core/src/filesystem/image/generic.rs +++ b/core/src/filesystem/image/generic.rs @@ -7,7 +7,7 @@ use crate::filesystem::{image::process::resized_dimensions, FileError}; use super::process::{self, ImageProcessor, ImageProcessorOptions}; /// An image processor that works for the most common image types, primarily -/// JPEG and PNG and AVIF formats. +/// JPEG and PNG formats. pub struct GenericImageProcessor; impl ImageProcessor for GenericImageProcessor { @@ -36,7 +36,6 @@ impl ImageProcessor for GenericImageProcessor { Ok(ImageFormat::Jpeg) }, process::ImageFormat::Png => Ok(ImageFormat::Png), - process::ImageFormat::Avif => Ok(ImageFormat::Avif), // TODO: change error kind _ => Err(FileError::UnknownError(String::from( "Incorrect image processor for requested format.", @@ -64,7 +63,7 @@ mod tests { use super::*; use crate::filesystem::image::{ - tests::{get_test_avif_path, get_test_jpg_path, get_test_png_path}, + tests::{get_test_jpg_path, get_test_png_path}, ImageFormat, ImageProcessorOptions, }; @@ -209,71 +208,6 @@ mod tests { ); } - //JPG -> AVIF - #[test] - fn test_generate_jpg_to_avif() { - let jpg_path = get_test_jpg_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&jpg_path, options) - .expect("Failed to generate image buffer"); - - assert!(!buffer.is_empty()); - // should be a valid Avif - assert!( - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .is_ok() - ); - } - - #[test] - fn test_generate_jpg_to_avif_with_rescale() { - let jpg_path = get_test_jpg_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - ..Default::default() - }; - - let current_dimensions = - image::image_dimensions(&jpg_path).expect("Failed to get dimensions"); - - let buffer = GenericImageProcessor::generate_from_path(&jpg_path, options) - .expect("Failed to generate image buffer"); - - let new_dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(new_dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(new_dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_jpg_to_avif_with_resize() { - let jpg_path = get_test_jpg_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&jpg_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } - // PNG -> other // PNG -> PNG #[test] @@ -397,258 +331,4 @@ mod tests { assert_eq!(dimensions.0, 100); assert_eq!(dimensions.1, 100); } - - //PNG -> AVIF - #[test] - fn test_generate_png_to_avif() { - let png_path = get_test_png_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&png_path, options) - .expect("Failed to generate image buffer"); - assert!(!buffer.is_empty()); - // should be a valid JPEG - assert!( - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .is_ok() - ); - } - - #[test] - fn test_generate_png_to_avif_with_rescale() { - let png_path = get_test_png_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - ..Default::default() - }; - - let current_dimensions = - image::image_dimensions(&png_path).expect("Failed to get dimensions"); - - let buffer = GenericImageProcessor::generate_from_path(&png_path, options) - .expect("Failed to generate image buffer"); - - let new_dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(new_dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(new_dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_png_to_avif_with_resize() { - let png_path = get_test_png_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&png_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } - - //AVIF -> other - //AVIF -> AVIF - #[test] - fn test_generate_avif_to_avif() { - let avif_path = get_test_avif_path(); - - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - assert!(!buffer.is_empty()); - - // should *still* be a valid AVIF - assert!( - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .is_ok() - ); - } - - #[test] - fn test_generate_avif_to_avif_with_rescale() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - ..Default::default() - }; - - let current_dimensions = - image::image_dimensions(&avif_path).expect("Failed to get dimensions"); - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let new_dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(new_dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(new_dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_avif_to_avif_with_resize() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Avif, - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = - image::load_from_memory_with_format(&buffer, image::ImageFormat::Avif) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } - - //AVIF -> PNG - #[test] - fn test_generate_avif_to_png() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Png, - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - assert!(!buffer.is_empty()); - // should be a valid PNG - assert!( - image::load_from_memory_with_format(&buffer, image::ImageFormat::Png).is_ok() - ); - } - - #[test] - fn test_generate_avif_to_png_with_rescale() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Png, - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - ..Default::default() - }; - - let current_dimensions = - image::image_dimensions(&avif_path).expect("Failed to get dimensions"); - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let new_dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(new_dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(new_dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_avif_to_png_with_resize() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Png, - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } - - //AVIF -> JPG - #[test] - fn test_generate_avif_to_jpg() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Jpeg, - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - assert!(!buffer.is_empty()); - // should be a valid PNG - assert!( - image::load_from_memory_with_format(&buffer, image::ImageFormat::Jpeg) - .is_ok() - ); - } - - #[test] - fn test_generate_avif_to_jpg_with_rescale() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Jpeg, - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - ..Default::default() - }; - - let current_dimensions = - image::image_dimensions(&avif_path).expect("Failed to get dimensions"); - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let new_dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(new_dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(new_dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_avif_to_jpg_with_resize() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - format: ImageFormat::Jpeg, - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - ..Default::default() - }; - - let buffer = GenericImageProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } } diff --git a/core/src/filesystem/image/process.rs b/core/src/filesystem/image/process.rs index d273f7ae0..e527a3e7f 100644 --- a/core/src/filesystem/image/process.rs +++ b/core/src/filesystem/image/process.rs @@ -58,7 +58,7 @@ pub enum ImageFormat { Jpeg, // JpegXl, Png, - Avif, + // Avif, } impl ImageFormat { @@ -69,7 +69,7 @@ impl ImageFormat { ImageFormat::Jpeg => "jpeg", // TODO(339): Support JpegXl and Avif // ImageFormat::JpegXl => "jxl", - ImageFormat::Avif => "avif", + // ImageFormat::Avif => "avif", ImageFormat::Png => "png", } } @@ -79,7 +79,6 @@ impl From for image::ImageFormat { fn from(val: ImageFormat) -> Self { match val { ImageFormat::Webp => image::ImageFormat::WebP, - ImageFormat::Avif => image::ImageFormat::Avif, ImageFormat::Jpeg => image::ImageFormat::Jpeg, // See https://github.com/image-rs/image/issues/1765. Image removed the // unsupported enum variant, which makes this awkward to support... @@ -209,7 +208,7 @@ mod tests { #[test] fn test_image_format_extension() { assert_eq!(ImageFormat::Webp.extension(), "webp"); - assert_eq!(ImageFormat::Avif.extension(), "avif"); + // assert_eq!(ImageFormat::Avif.extension(), "avif"); assert_eq!(ImageFormat::Jpeg.extension(), "jpeg"); // assert_eq!(ImageFormat::JpegXl.extension(), "jxl"); assert_eq!(ImageFormat::Png.extension(), "png"); @@ -221,10 +220,6 @@ mod tests { image::ImageFormat::from(ImageFormat::Webp), image::ImageFormat::WebP ); - assert_eq!( - image::ImageFormat::from(ImageFormat::Avif), - image::ImageFormat::Avif - ); assert_eq!( image::ImageFormat::from(ImageFormat::Jpeg), image::ImageFormat::Jpeg diff --git a/core/src/filesystem/image/webp.rs b/core/src/filesystem/image/webp.rs index 6e82a7dc9..df424a9f4 100644 --- a/core/src/filesystem/image/webp.rs +++ b/core/src/filesystem/image/webp.rs @@ -60,9 +60,7 @@ impl WebpProcessor { mod tests { use super::*; use crate::filesystem::image::{ - tests::{ - get_test_avif_path, get_test_jpg_path, get_test_png_path, get_test_webp_path, - }, + tests::{get_test_jpg_path, get_test_png_path, get_test_webp_path}, ImageFormat, ImageProcessorOptions, }; use std::fs; @@ -223,73 +221,6 @@ mod tests { assert_eq!(dimensions.1, 100); } - #[test] - fn test_generate_webp_from_avif() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - resize_options: None, - format: ImageFormat::Webp, - quality: None, - page: None, - }; - - let result = WebpProcessor::generate_from_path(&avif_path, options); - assert!(result.is_ok()); - - let webp_bytes = result.unwrap(); - // should be a valid webp image - assert!(image::load_from_memory_with_format( - &webp_bytes, - image::ImageFormat::WebP - ) - .is_ok()) - } - - #[test] - fn test_generate_webp_from_avif_with_rescale() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - resize_options: Some(ImageResizeOptions::scaled(0.5, 0.5)), - format: ImageFormat::Webp, - quality: None, - page: None, - }; - - let current_dimensions = - image::image_dimensions(&avif_path).expect("Failed to get dimensions"); - - let buffer = WebpProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, (current_dimensions.0 as f32 * 0.5) as u32); - assert_eq!(dimensions.1, (current_dimensions.1 as f32 * 0.5) as u32); - } - - #[test] - fn test_generate_webp_from_avif_with_resize() { - let avif_path = get_test_avif_path(); - let options = ImageProcessorOptions { - resize_options: Some(ImageResizeOptions::sized(100f32, 100f32)), - format: ImageFormat::Webp, - quality: None, - page: None, - }; - - let buffer = WebpProcessor::generate_from_path(&avif_path, options) - .expect("Failed to generate image buffer"); - - let dimensions = image::load_from_memory(&buffer) - .expect("Failed to load image from buffer") - .dimensions(); - - assert_eq!(dimensions.0, 100); - assert_eq!(dimensions.1, 100); - } - #[test] fn test_generate_webp_from_webp() { let webp_path = get_test_webp_path(); diff --git a/docker/Dockerfile b/docker/Dockerfile index 219d86c6c..ff3e686fa 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -42,19 +42,6 @@ RUN apt-get update && apt-get install -y \ nasm \ libsqlite3-dev; -# Building dav1d for AVIF Support -RUN git clone https://github.com/stumpapp/dav1d.git - -WORKDIR /dav1d - -RUN mkdir build - -WORKDIR /dav1d/build - -RUN meson setup ../; \ - ninja; \ - ninja install - # Cargo build for stump WORKDIR /app @@ -86,22 +73,6 @@ RUN apt-get update && apt-get install -y curl tar; \ tar -xzvf pdfium.tgz -C ./pdfium; \ rm pdfium.tgz -# ------------------------------------------------------------------------------ -# dav1d Copy Stage -# ------------------------------------------------------------------------------ - -FROM debian:buster-slim AS dav1d -ARG TARGETARCH - -COPY --from=builder /usr/local/lib /usr/local/lib - -RUN set -ex; \ - if [ "$TARGETARCH" = "amd64" ]; then \ - cp -r /usr/local/lib/x86_64-linux-gnu/* /usr/local/lib; \ - elif [ "$TARGETARCH" = "arm64" ]; then \ - cp -r /usr/local/lib/aarch64-linux-gnu/* /usr/local/lib; \ - fi - # ------------------------------------------------------------------------------ # Final Stage # ------------------------------------------------------------------------------ @@ -113,7 +84,6 @@ RUN apt-get update && apt-get install -y locales-all && rm -rf /var/lib/apt/list COPY --from=builder /app/stump_server /app/stump COPY --from=pdfium /pdfium /opt/pdfium -COPY --from=dav1d /usr/local/lib/ /usr/local/lib/ COPY --from=frontend /app/build /app/client COPY docker/entrypoint.sh /entrypoint.sh diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 2aa6765c7..52a28e323 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -54,9 +54,6 @@ fi # Change current working directory cd /app -# Make sure shared libraries are linked -echo '/usr/local/lib' >> /etc/ld.so.conf.d/mylibs.conf && ldconfig - if [[ "$PUID" -eq 0 ]]; then # Run as root /app/stump diff --git a/docs/pages/contributing.mdx b/docs/pages/contributing.mdx index 6859af1ab..fff9af64a 100644 --- a/docs/pages/contributing.mdx +++ b/docs/pages/contributing.mdx @@ -23,7 +23,7 @@ If you're completely new to rust and/or web development, I put together a small [Rosetta](https://support.apple.com/en-us/>HT211861). -You need to install [yarn](https://yarnpkg.com), [rust](https://www.rust-lang.org/tools/install), [dav1d](https://github.com/stumpapp/dav1d), and [node](https://nodejs.org/en/download/). Additionally, if you want to run any of the dev scripts on the rust side of things, you'll need to install [cargo-watch](https://crates.io/crates/cargo-watch). Afterwards, run the following: +You need to install [yarn](https://yarnpkg.com), [rust](https://www.rust-lang.org/tools/install), and [node](https://nodejs.org/en/download/). Additionally, if you want to run any of the dev scripts on the rust side of things, you'll need to install [cargo-watch](https://crates.io/crates/cargo-watch). Afterwards, run the following: ```bash yarn run setup diff --git a/docs/pages/guides/basics/thumbnails.mdx b/docs/pages/guides/basics/thumbnails.mdx index e39c1f8e6..aaf3d9f58 100644 --- a/docs/pages/guides/basics/thumbnails.mdx +++ b/docs/pages/guides/basics/thumbnails.mdx @@ -10,7 +10,7 @@ The generation of thumbnails is controlled by the configuration options for a li - Explicitly sizing each thumbnail (height and width in pixels) - Scaling both dimensions of each thumbnail by a factor (e.g. 0.5) -- The format to encode the thumbnail in (e.g. JPEG, PNG, WebP, AVIF) +- The format to encode the thumbnail in (e.g. JPEG, PNG, WebP) - The quality of the encoding (e.g. 0-1.0) Thumbnail generation is optional, and you can disable it entirely if you prefer to use the default image as a thumbnail. @@ -34,12 +34,10 @@ Stump supports generating thumbnails to and from the following formats: - JPEG - PNG - WebP -- AVIF You should ensure that your browser supports the format you plan to use. You can visit the following links to check: - [WebP](https://caniuse.com/webp) -- [AVIF](https://caniuse.com/avif) ### Display diff --git a/packages/types/generated.ts b/packages/types/generated.ts index a153cbe6f..b93c5c785 100644 --- a/packages/types/generated.ts +++ b/packages/types/generated.ts @@ -269,7 +269,7 @@ export type ImageResizeOptions = { mode: ImageResizeMode; height: number; width: /** * Supported image formats for processing images throughout Stump. */ -export type ImageFormat = "Webp" | "Jpeg" | "Png" | "Avif" +export type ImageFormat = "Webp" | "Jpeg" | "Png" /** * Options for processing images throughout Stump. diff --git a/scripts/system-setup.sh b/scripts/system-setup.sh index 4455b0ae6..5f69c25bf 100755 --- a/scripts/system-setup.sh +++ b/scripts/system-setup.sh @@ -6,7 +6,7 @@ source "${SCRIPTS_DIR}/lib" _DEV_SETUP=${DEV_SETUP:=1} _CHECK_CARGO=${CHECK_CARGO:=1} _CHECK_NODE=${CHECK_NODE:=1} -_CHECK_DAV1D=${CHECK_DAV1D:=1} +_CHECK_DAV1D=${CHECK_DAV1D:=0} _FORCE_INSTALL_YARN=${INSTALL_YARN:=0} dev_setup() { From 43664cfe1f436a9a6877593868b86d7119a8d51a Mon Sep 17 00:00:00 2001 From: Aaron Leopold <36278431+aaronleopold@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:09:36 -0700 Subject: [PATCH 2/3] remove prisma generation in dockerfile --- docker/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index ff3e686fa..17a75b730 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -47,9 +47,9 @@ WORKDIR /app COPY . . -RUN cargo prisma generate --schema ./core/prisma/schema.prisma; \ - ./scripts/release/utils.sh -w; \ +RUN ./scripts/release/utils.sh -w; \ set -ex; \ + ./scripts/release/utils.sh -p; \ cargo build --package stump_server --bin stump_server --release; \ cp ./target/release/stump_server ./stump_server From 761cf2abf5507912e8c642c709336b6a31a9826c Mon Sep 17 00:00:00 2001 From: Aaron Leopold <36278431+aaronleopold@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:31:07 -0700 Subject: [PATCH 3/3] try conditional prisma gen --- .github/actions/build-docker/action.yml | 1 + docker/Dockerfile | 14 ++++---------- docker/build.sh | 9 +++++---- docker/build_server.sh | 12 ++++++++++++ scripts/lib | 1 - 5 files changed, 22 insertions(+), 15 deletions(-) create mode 100755 docker/build_server.sh diff --git a/.github/actions/build-docker/action.yml b/.github/actions/build-docker/action.yml index 878b0db35..4d52f66cc 100644 --- a/.github/actions/build-docker/action.yml +++ b/.github/actions/build-docker/action.yml @@ -76,6 +76,7 @@ runs: build-args: | "GIT_REV=${{ env.GIT_REV }}" "TAGS=${{ env.TAGS }}" + "RUN_PRISMA_GENERATE=false" file: docker/Dockerfile platforms: ${{ inputs.platforms }} load: ${{ inputs.load }} diff --git a/docker/Dockerfile b/docker/Dockerfile index 17a75b730..cd0149e63 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -23,13 +23,13 @@ RUN yarn config set network-timeout 300000 && \ FROM rust:1.79.0-slim-buster AS builder -# ARG TARGETARCH ARG GIT_REV +ARG TAGS +ARG RUN_PRISMA_GENERATE ENV GIT_REV=${GIT_REV} - -ARG TAGS ENV TAGS=${TAGS} +ENV RUN_PRISMA_GENERATE=${RUN_PRISMA_GENERATE} RUN apt-get update && apt-get install -y \ build-essential \ @@ -37,9 +37,6 @@ RUN apt-get update && apt-get install -y \ git \ libssl-dev \ pkg-config \ - meson \ - ninja-build \ - nasm \ libsqlite3-dev; # Cargo build for stump @@ -47,10 +44,7 @@ WORKDIR /app COPY . . -RUN ./scripts/release/utils.sh -w; \ - set -ex; \ - ./scripts/release/utils.sh -p; \ - cargo build --package stump_server --bin stump_server --release; \ +RUN RUN_PRISMA_GENERATE=${RUN_PRISMA_GENERATE} ./docker/build_server.sh && \ cp ./target/release/stump_server ./stump_server # ------------------------------------------------------------------------------ diff --git a/docker/build.sh b/docker/build.sh index 371aef626..12cc2f06c 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -1,7 +1,8 @@ #!/bin/bash -FORMAT=${1:-auto} -PLATFORMS=${2:-linux/amd64} -TAG=${3:-nightly} +_FORMAT=${FORMAT:-auto} +_PLATFORMS=${PLATFORMS:-linux/amd64} +_TAG=${TAG:-nightly} +_RUN_PRISMA_GENERATE=${RUN_PRISMA_GENERATE:=false} -docker buildx build -f ./docker/Dockerfile --load --progress=$FORMAT --platform=$PLATFORMS -t aaronleopold/stump:$TAG --build-arg GIT_REV=$(git rev-parse --short HEAD) . +docker buildx build -f ./docker/Dockerfile --load --progress=$_FORMAT --platform=$_PLATFORMS -t aaronleopold/stump:$_TAG --build-arg GIT_REV=$(git rev-parse --short HEAD) --build-arg RUN_PRISMA_GENERATE=$_RUN_PRISMA_GENERATE . diff --git a/docker/build_server.sh b/docker/build_server.sh new file mode 100755 index 000000000..c5a3f26d8 --- /dev/null +++ b/docker/build_server.sh @@ -0,0 +1,12 @@ +#!/bin/bash + + +if [ "$RUN_PRISMA_GENERATE" = "true" ]; then + set -ex; \ + cargo prisma generate --schema ./core/prisma/schema.prisma +fi + +set -ex; \ + ./scripts/release/utils.sh -w; \ + ./scripts/release/utils.sh -p; \ + cargo build --package stump_server --bin stump_server --release \ No newline at end of file diff --git a/scripts/lib b/scripts/lib index a997c7b0b..3f4432ea0 100644 --- a/scripts/lib +++ b/scripts/lib @@ -34,7 +34,6 @@ workspaces_sed_correction() { set -ex; \ sed -i '/core\/integration-tests/d' Cargo.toml; \ sed -i '/apps\/desktop\/src-tauri/d' Cargo.toml; \ - sed -i '/apps\/tui/d' Cargo.toml; \ sed -i '/crates\/prisma-cli/d' Cargo.toml }