diff --git a/README.md b/README.md index bdf09a2..689ae0d 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3); scaler.set_threading_policy(ThreadingPolicy::Adaptive); // ImageStore:: - (u8, 4) represents RGBA, (u8, 3) - RGB etc let store = - ImageStore::::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize); + ImageStore::::from_slice(&mut bytes, dimensions.0 as usize, dimensions.1 as usize).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(dimensions.0 as usize / 2, dimensions.1 as usize / 2), store, @@ -161,7 +161,7 @@ In common, you should not downsize an image in sRGB colorspace, however if speed let mut scaler = Scaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -177,7 +177,7 @@ At the moment only sRGB transfer function is supported. This is also good optimi let mut scaler = LinearScaler::new(ResamplingFunction::Lanczos3); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -190,7 +190,7 @@ let resized = scaler.resize_rgba( let mut scaler = LabScaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -203,7 +203,7 @@ let resized = scaler.resize_rgba( let mut scaler = LuvScaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -216,7 +216,7 @@ let resized = scaler.resize_rgba( let mut scaler = XYZScale::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -229,7 +229,7 @@ let resized = scaler.resize_rgba( let mut scaler = SigmoidalScaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -242,7 +242,7 @@ let resized = scaler.resize_rgba( let mut scaler = LChScaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, @@ -255,7 +255,7 @@ let resized = scaler.resize_rgba( let mut scaler = OklabScaler::new(ResamplingFunction::Hermite); scaler.set_threading_policy(ThreadingPolicy::Single); let store = - ImageStore::::from_slice(&mut bytes, width, height); + ImageStore::::from_slice(&mut bytes, width, height).unwrap(); let resized = scaler.resize_rgba( ImageSize::new(new_width, new_height), store, diff --git a/app/src/main.rs b/app/src/main.rs index cbd88a5..2b9d66d 100644 --- a/app/src/main.rs +++ b/app/src/main.rs @@ -21,7 +21,7 @@ use pic_scale::{ fn main() { // test_fast_image(); - let img = ImageReader::open("./assets/asset_5.png") + let img = ImageReader::open("./assets/beach_horizon.jpg") .unwrap() .decode() .unwrap(); @@ -34,14 +34,14 @@ fn main() { // let start_time = Instant::now(); - let store = ImageStore::::from_slice( + let store = ImageStore::::from_slice( &mut bytes, dimensions.0 as usize, dimensions.1 as usize, ); - let resized = scaler.resize_rgba( + let resized = scaler.resize_rgb( ImageSize::new(dimensions.0 as usize / 2, dimensions.1 as usize / 2), - store, false, + store, ); // let mut r_chan = vec![0u8; dimensions.0 as usize * dimensions.1 as usize]; diff --git a/src/image_store.rs b/src/image_store.rs index 04a2d89..df76613 100644 --- a/src/image_store.rs +++ b/src/image_store.rs @@ -86,14 +86,29 @@ impl ImageStore<'static, T, N> where T: FromPrimitive + Clone + Copy + Debug + Default, { - pub fn new(slice_ref: Vec, width: usize, height: usize) -> ImageStore<'static, T, N> { - ImageStore:: { + pub fn new( + slice_ref: Vec, + width: usize, + height: usize, + ) -> Result, String> { + let expected_size = width * height * N; + if slice_ref.len() != width * height * N { + return Err(format!( + "Image buffer len expected to be {} (w({})*h({})*channels({}) but received {}", + expected_size, + width, + height, + N, + slice_ref.len() + )); + } + Ok(ImageStore:: { buffer: BufferStore::Owned(slice_ref), channels: N, width, height, bit_depth: 0, - } + }) } pub fn alloc(width: usize, height: usize) -> ImageStore<'static, T, N> { diff --git a/src/scaler.rs b/src/scaler.rs index 4803f99..2031306 100644 --- a/src/scaler.rs +++ b/src/scaler.rs @@ -272,7 +272,7 @@ impl Scaling for Scaler { ); let new_image = ImageStore::::new(allocated_store, new_size.width, new_size.height); - return new_image; + return new_image.unwrap(); } let vertical_filters = self.generate_weights(store.height, new_size.height); let horizontal_filters = self.generate_weights(store.width, new_size.width); @@ -352,7 +352,7 @@ impl Scaling for Scaler { impl ScalingF32 for Scaler { fn resize_rgb_f32(&self, new_size: ImageSize, store: ImageStore) -> ImageStore { if self.function == Nearest { - let mut allocated_store: Vec = vec![0f32; new_size.width * 4 * new_size.height]; + let mut allocated_store: Vec = vec![0f32; new_size.width * 3 * new_size.height]; resize_nearest::( &store.buffer.borrow(), store.width, @@ -363,7 +363,7 @@ impl ScalingF32 for Scaler { ); let new_image = ImageStore::::new(allocated_store, new_size.width, new_size.height); - return new_image; + return new_image.unwrap(); } let pool = self @@ -372,13 +372,15 @@ impl ScalingF32 for Scaler { let allocated_store_vertical: Vec = vec![0f32; store.width * 3 * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, store.width, new_size.height) + .unwrap(); let vertical_filters = self.generate_weights(store.height, new_image_vertical.height); store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); let allocated_store_horizontal: Vec = vec![0f32; new_size.width * 3 * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(store.width, new_size.width); new_image_vertical.convolve_horizontal( horizontal_filters, @@ -413,7 +415,8 @@ impl ScalingF32 for Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); if is_alpha_premultiplied { let mut premultiplied_store = @@ -431,14 +434,16 @@ impl ScalingF32 for Scaler { let allocated_store_vertical: Vec = vec![0f32; src_store.width * 4 * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, src_store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, src_store.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(src_store.width, new_size.width); let vertical_filters = self.generate_weights(src_store.height, new_image_vertical.height); src_store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); let allocated_store_horizontal: Vec = vec![0f32; new_size.width * 4 * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); new_image_vertical.convolve_horizontal( horizontal_filters, &mut new_image_horizontal, @@ -476,7 +481,8 @@ impl Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); return new_image; } @@ -486,14 +492,16 @@ impl Scaler { let allocated_store_vertical: Vec = vec![0f32; store.width * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, store.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(store.width, new_size.width); let vertical_filters = self.generate_weights(store.height, new_image_vertical.height); store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); let allocated_store_horizontal: Vec = vec![0f32; new_size.width * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); new_image_vertical.convolve_horizontal( horizontal_filters, &mut new_image_horizontal, @@ -517,7 +525,7 @@ impl Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height).unwrap(); return new_image; } let vertical_filters = self.generate_weights(store.height, new_size.height); @@ -557,7 +565,8 @@ impl ScalingU16 for Scaler { new_size.height, ); let mut new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); new_image.bit_depth = bit_depth; return new_image; } @@ -689,7 +698,8 @@ impl ScalingU16 for Scaler { new_size.height, ); let mut new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); new_image.bit_depth = bit_depth; return new_image; } diff --git a/src/scaler_f16.rs b/src/scaler_f16.rs index 7c6285f..12bc232 100644 --- a/src/scaler_f16.rs +++ b/src/scaler_f16.rs @@ -62,7 +62,8 @@ impl Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); if is_alpha_premultiplied { let mut premultiplied_store = @@ -81,7 +82,8 @@ impl Scaler { let allocated_store_vertical: Vec = vec![f16::from_f32(0.); src_store.width * 4 * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, src_store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, src_store.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(src_store.width, new_size.width); let vertical_filters = self.generate_weights(src_store.height, new_image_vertical.height); src_store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); @@ -89,7 +91,8 @@ impl Scaler { let allocated_store_horizontal: Vec = vec![f16::from_f32(0.); new_size.width * 4 * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); new_image_vertical.convolve_horizontal( horizontal_filters, &mut new_image_horizontal, @@ -126,7 +129,8 @@ impl Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); return new_image; } @@ -137,14 +141,16 @@ impl Scaler { let allocated_store_vertical: Vec = vec![f16::from_f32(0.); store.width * 3 * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, store.width, new_size.height) + .unwrap(); let vertical_filters = self.generate_weights(store.height, new_image_vertical.height); store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); let allocated_store_horizontal: Vec = vec![f16::from_f32(0.); new_size.width * 3 * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(store.width, new_size.width); new_image_vertical.convolve_horizontal( horizontal_filters, @@ -172,7 +178,8 @@ impl Scaler { new_size.height, ); let new_image = - ImageStore::::new(allocated_store, new_size.width, new_size.height); + ImageStore::::new(allocated_store, new_size.width, new_size.height) + .unwrap(); return new_image; } @@ -183,14 +190,16 @@ impl Scaler { let allocated_store_vertical: Vec = vec![f16::from_f32(0.); store.width * 1 * new_size.height]; let mut new_image_vertical = - ImageStore::::new(allocated_store_vertical, store.width, new_size.height); + ImageStore::::new(allocated_store_vertical, store.width, new_size.height) + .unwrap(); let vertical_filters = self.generate_weights(store.height, new_image_vertical.height); store.convolve_vertical(vertical_filters, &mut new_image_vertical, &pool); let allocated_store_horizontal: Vec = vec![f16::from_f32(0.); new_size.width * 1 * new_size.height]; let mut new_image_horizontal = - ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height); + ImageStore::::new(allocated_store_horizontal, new_size.width, new_size.height) + .unwrap(); let horizontal_filters = self.generate_weights(store.width, new_size.width); new_image_vertical.convolve_horizontal( horizontal_filters,