diff --git a/imageflow_core/src/codecs/gif.rs b/imageflow_core/src/codecs/gif.rs index ae46d57a2..0827dcd06 100644 --- a/imageflow_core/src/codecs/gif.rs +++ b/imageflow_core/src/codecs/gif.rs @@ -132,14 +132,14 @@ impl Encoder for GifEncoder{ pix[0] = pix[2]; pix[2] = a; } - f = ::gif::Frame::from_rgb(frame.w as u16, frame.h as u16, &mut pixels); + f = from_rgb_with_stride(frame.w as u16, frame.h as u16, &mut pixels, frame.stride as usize); }else { for pix in pixels.chunks_mut(4) { let a = pix[0]; pix[0] = pix[2]; pix[2] = a; } - f = ::gif::Frame::from_rgba(frame.w as u16, frame.h as u16, &mut pixels); + f = from_rgba_with_stride(frame.w as u16, frame.h as u16, &mut pixels, frame.stride as usize); } let mut encoder = ::gif::Encoder::new(io, frame.w as u16, frame.h as u16, &[]).unwrap(); @@ -159,3 +159,22 @@ impl Encoder for GifEncoder{ } } + +fn remove_padding(width: u16, pixels: &[u8], stride: usize) -> Vec{ + pixels.chunks(stride).flat_map(|s| s[0..width as usize * 4].iter().map(|v| *v)).collect() +} + /// Creates a frame from pixels in RGBA format. + /// + /// *Note: This method is not optimized for speed.* + pub fn from_rgba_with_stride(width: u16, height: u16, pixels: &mut [u8], stride: usize) -> ::gif::Frame<'static> { + let mut without_padding = remove_padding(width, pixels, stride); + ::gif::Frame::from_rgba(width, height, &mut without_padding) + } + +/// Creates a frame from pixels in RGB format. +/// +/// *Note: This method is not optimized for speed.* +pub fn from_rgb_with_stride(width: u16, height: u16, pixels: &[u8], stride: usize) -> ::gif::Frame<'static> { + let mut without_padding = remove_padding(width, pixels, stride); + ::gif::Frame::from_rgb(width, height, &mut without_padding) +} diff --git a/imageflow_core/tests/visuals.rs b/imageflow_core/tests/visuals.rs index 404c66437..02f57f2b0 100644 --- a/imageflow_core/tests/visuals.rs +++ b/imageflow_core/tests/visuals.rs @@ -285,6 +285,41 @@ fn test_jpeg_rotation() { } } +// +//#[test] +//fn test_gif_ir4(){ +// let matched = compare(Some(s::IoEnum::Url("https://s3-us-west-2.amazonaws.com/imageflow-resources/test_inputs/waterhouse.jpg".to_owned())), 500, +// "Read".to_owned(), true, DEBUG_GRAPH, vec![ +// s::Node::CommandString{ +// kind: s::CommandStringKind::ImageResizer4, +// value: "width=200&height=200&format=gif".to_owned(), +// decode: Some(0), +// encode: None //Some(1) +// } +// ] +// ); +// assert!(matched); +// +//} + +#[test] +fn smoke_test_gif_ir4(){ + + let steps = vec![ + s::Node::CommandString{ + kind: s::CommandStringKind::ImageResizer4, + value: "width=200&height=200&format=gif".to_owned(), + decode: Some(0), + encode: Some(1) + } + ]; + + smoke_test(Some(s::IoEnum::Url("https://s3-us-west-2.amazonaws.com/imageflow-resources/test_inputs/waterhouse.jpg".to_owned())), + Some(s::IoEnum::OutputBuffer), + DEBUG_GRAPH, + steps, + ); +} #[test]