diff --git a/Cargo.lock b/Cargo.lock index dcdfb0d..b7dab2b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -383,6 +383,7 @@ dependencies = [ "regex", "rstest", "thiserror", + "version-compare", ] [[package]] @@ -597,6 +598,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "which" version = "4.4.2" diff --git a/Cargo.toml b/Cargo.toml index 1f2bef8..3971ddf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ fast_image_resize = { version = "2.7", optional = true} rstest = "0.18" assert_approx_eq = "1.1" bencher = "0.1" +version-compare = "0.1" [[bench]] name = "bench_read" diff --git a/benches/bench_read.rs b/benches/bench_read.rs index ada2dbc..a3e905c 100644 --- a/benches/bench_read.rs +++ b/benches/bench_read.rs @@ -1,6 +1,6 @@ use bencher::{benchmark_group, benchmark_main, Bencher}; use openslide_rs::{traits::Slide, Address, DeepZoomGenerator, OpenSlide, Region, Size}; -use std::path::Path; +use std::{path::Path, sync::Arc}; fn openslide_read_region_256(bench: &mut Bencher) { let slide = OpenSlide::new(Path::new("tests/assets/default.svs")).unwrap(); @@ -52,14 +52,30 @@ fn openslide_read_image_512(bench: &mut Bencher) { fn deepzoom_read_image_256(bench: &mut Bencher) { let slide = OpenSlide::new(Path::new("tests/assets/default.svs")).unwrap(); - let dz = DeepZoomGenerator::new(&slide, 257, 0, false).unwrap(); + let dz: DeepZoomGenerator = + DeepZoomGenerator::new(&slide, 257, 0, false).unwrap(); bench.iter(|| dz.get_tile_rgb(12, Address { x: 0, y: 0 })); } fn deepzoom_read_image_512(bench: &mut Bencher) { let slide = OpenSlide::new(Path::new("tests/assets/default.svs")).unwrap(); - let dz = DeepZoomGenerator::new(&slide, 511, 0, false).unwrap(); + let dz: DeepZoomGenerator = + DeepZoomGenerator::new(&slide, 511, 0, false).unwrap(); + + bench.iter(|| dz.get_tile_rgb(12, Address { x: 0, y: 0 })); +} + +fn deepzoom_read_image_256_arc(bench: &mut Bencher) { + let slide = Arc::new(OpenSlide::new(Path::new("tests/assets/default.svs")).unwrap()); + let dz: DeepZoomGenerator = DeepZoomGenerator::new(slide, 257, 0, false).unwrap(); + + bench.iter(|| dz.get_tile_rgb(12, Address { x: 0, y: 0 })); +} + +fn deepzoom_read_image_512_arc(bench: &mut Bencher) { + let slide = Arc::new(OpenSlide::new(Path::new("tests/assets/default.svs")).unwrap()); + let dz: DeepZoomGenerator = DeepZoomGenerator::new(slide, 511, 0, false).unwrap(); bench.iter(|| dz.get_tile_rgb(12, Address { x: 0, y: 0 })); } @@ -77,6 +93,8 @@ benchmark_group!( benchmark_group!( deepzoom_image, deepzoom_read_image_256, - deepzoom_read_image_512 + deepzoom_read_image_512, + deepzoom_read_image_256_arc, + deepzoom_read_image_512_arc ); benchmark_main!(benches_region, benches_image, deepzoom_image); diff --git a/src/bindings.rs b/src/bindings.rs index e70661b..5a4ca42 100644 --- a/src/bindings.rs +++ b/src/bindings.rs @@ -24,6 +24,16 @@ impl Deref for OpenSlideWrapper { unsafe impl Send for OpenSlideWrapper {} unsafe impl Sync for OpenSlideWrapper {} +pub fn get_version() -> Result { + let version = unsafe { sys::openslide_get_version() }; + if !version.is_null() { + let vendor = unsafe { ffi::CStr::from_ptr(version).to_string_lossy().into_owned() }; + Ok(vendor) + } else { + Err(OpenSlideError::CoreError("Cannot get version".to_string())) + } +} + pub fn detect_vendor(filename: &str) -> Result { let c_filename = ffi::CString::new(filename)?; unsafe { diff --git a/src/wrapper.rs b/src/wrapper.rs index ed18d45..a74041a 100644 --- a/src/wrapper.rs +++ b/src/wrapper.rs @@ -20,6 +20,11 @@ impl Drop for OpenSlide { } impl OpenSlide { + /// Get the version of the OpenSlide library. + pub fn get_version() -> Result { + bindings::get_version() + } + /// This method tries to open the slide at the given filename location. /// /// This function can be expensive; avoid calling it unnecessarily. For example, a tile server diff --git a/tests/properties.rs b/tests/properties.rs index a86a3dd..f5f75c9 100644 --- a/tests/properties.rs +++ b/tests/properties.rs @@ -2,6 +2,7 @@ use fixture::{boxes_tiff, default, hamamatsu, leica, mirax, trestle}; use openslide_rs::{properties::VendorProperties, OpenSlide}; use rstest::rstest; use std::path::Path; +use version_compare::Version; mod fixture; @@ -12,50 +13,61 @@ fn test_slide_properties(#[case] filename: &Path) { println!("{slide:?}"); - assert_eq!( - slide.get_property_names(), - vec![ - "openslide.level-count", - "openslide.level[0].downsample", - "openslide.level[0].height", - "openslide.level[0].tile-height", - "openslide.level[0].tile-width", - "openslide.level[0].width", - "openslide.level[1].downsample", - "openslide.level[1].height", - "openslide.level[1].tile-height", - "openslide.level[1].tile-width", - "openslide.level[1].width", - "openslide.level[2].downsample", - "openslide.level[2].height", - "openslide.level[2].tile-height", - "openslide.level[2].tile-width", - "openslide.level[2].width", - "openslide.level[3].downsample", - "openslide.level[3].height", - "openslide.level[3].tile-height", - "openslide.level[3].tile-width", - "openslide.level[3].width", + let base_expected_result = vec![ + "openslide.level-count", + "openslide.level[0].downsample", + "openslide.level[0].height", + "openslide.level[0].tile-height", + "openslide.level[0].tile-width", + "openslide.level[0].width", + "openslide.level[1].downsample", + "openslide.level[1].height", + "openslide.level[1].tile-height", + "openslide.level[1].tile-width", + "openslide.level[1].width", + "openslide.level[2].downsample", + "openslide.level[2].height", + "openslide.level[2].tile-height", + "openslide.level[2].tile-width", + "openslide.level[2].width", + "openslide.level[3].downsample", + "openslide.level[3].height", + "openslide.level[3].tile-height", + "openslide.level[3].tile-width", + "openslide.level[3].width", + "openslide.quickhash-1", + "openslide.vendor", + "tiff.ResolutionUnit", + "tiff.XResolution", + "tiff.YResolution", + ]; + + let raw_version = OpenSlide::get_version().unwrap(); + let version = Version::from(&raw_version).unwrap(); + + if version > Version::from("3.4.1").unwrap() { + let mut expected_result = base_expected_result; + expected_result.extend(vec![ + "openslide.mpp-x", + "openslide.mpp-y", "openslide.quickhash-1", "openslide.vendor", "tiff.ResolutionUnit", "tiff.XResolution", - "tiff.YResolution" - ] - ); - - assert_eq!( - slide.get_property_value("tiff.YResolution").unwrap(), - "28.340000157438311" - ); - assert_eq!( - slide.get_property_value("tiff.XResolution").unwrap(), - "28.340000157438311" - ); - assert_eq!( - slide.get_property_value("tiff.YResolution").unwrap(), - "28.340000157438311" - ); + "tiff.YResolution", + ]); + assert_eq!(slide.get_property_names(), expected_result); + } else { + let mut expected_result = base_expected_result; + expected_result.extend(vec![ + "openslide.quickhash-1", + "openslide.vendor", + "tiff.ResolutionUnit", + "tiff.XResolution", + "tiff.YResolution", + ]); + assert_eq!(slide.get_property_names(), expected_result); + } } #[rstest] @@ -69,8 +81,16 @@ fn test_tiff_properties(#[case] filename: &Path) { if let VendorProperties::GenericTiff = &properties.vendor_properties { let prop = &properties.tiff_properties; - assert_eq!(prop.x_resolution, Some(28.34)); - assert_eq!(prop.y_resolution, Some(28.34)); + let raw_version = OpenSlide::get_version().unwrap(); + let version = Version::from(&raw_version).unwrap(); + + if version > Version::from("3.4.1").unwrap() { + assert_eq!(prop.x_resolution, Some(28.34)); + assert_eq!(prop.y_resolution, Some(28.34)); + } else { + assert_eq!(prop.x_resolution, None); + assert_eq!(prop.y_resolution, None); + } assert_eq!(prop.resolution_unit, Some("centimeter".to_string())); } else { panic!("Not Aperio") @@ -84,8 +104,8 @@ fn test_tiff_properties(#[case] filename: &Path) { properties.openslide_properties.quickhash_1, Some("c08b056490bac8bcb329d9b8fb175888083d4097952a55fee99997758c728c36".to_string()) ); - assert_eq!(properties.openslide_properties.mpp_x, None); - assert_eq!(properties.openslide_properties.mpp_y, None); + assert_eq!(properties.openslide_properties.mpp_x, Some(352.85815)); + assert_eq!(properties.openslide_properties.mpp_y, Some(352.85815)); assert_eq!(properties.openslide_properties.level_count, Some(4)); assert_eq!( properties.openslide_properties.levels[0].downsample,