aboutsummaryrefslogtreecommitdiff
path: root/vendor/gif/tests/roundtrip.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gif/tests/roundtrip.rs')
-rw-r--r--vendor/gif/tests/roundtrip.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/gif/tests/roundtrip.rs b/vendor/gif/tests/roundtrip.rs
new file mode 100644
index 0000000..c121508
--- /dev/null
+++ b/vendor/gif/tests/roundtrip.rs
@@ -0,0 +1,103 @@
+use gif::{ColorOutput, Decoder, Encoder, Frame};
+
+#[test]
+fn encode_roundtrip() {
+ const ORIGINAL: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/samples/2x2.gif"));
+ round_trip_from_image(ORIGINAL);
+}
+
+fn round_trip_from_image(original: &[u8]) {
+ let (width, height, global_palette);
+ let frames: Vec<Frame> = {
+ let mut decoder = Decoder::new(original).unwrap();
+ width = decoder.width();
+ height = decoder.height();
+ global_palette = decoder
+ .global_palette()
+ .unwrap_or_default()
+ .to_vec();
+ core::iter::from_fn(move || {
+ decoder.read_next_frame().unwrap().cloned()
+ }).collect()
+ };
+
+ let mut encoder = Encoder::new(vec![], width, height, &global_palette).unwrap();
+ for frame in &frames {
+ encoder.write_frame(frame).unwrap();
+ }
+ let buffer = encoder.into_inner().unwrap();
+
+ {
+ let mut decoder = Decoder::new(&buffer[..]).expect("Invalid info encoded");
+ assert_eq!(decoder.width(), width);
+ assert_eq!(decoder.height(), height);
+ assert_eq!(global_palette, decoder.global_palette().unwrap_or_default());
+ let new_frames: Vec<_> = core::iter::from_fn(move || {
+ decoder.read_next_frame().unwrap().cloned()
+ }).collect();
+ assert_eq!(new_frames.len(), frames.len(), "Diverging number of frames");
+ for (new, reference) in new_frames.iter().zip(&frames) {
+ assert_eq!(new.delay, reference.delay);
+ assert_eq!(new.dispose, reference.dispose);
+ assert_eq!(new.transparent, reference.transparent);
+ assert_eq!(new.needs_user_input, reference.needs_user_input);
+ assert_eq!(new.top, reference.top);
+ assert_eq!(new.left, reference.left);
+ assert_eq!(new.width, reference.width);
+ assert_eq!(new.height, reference.height);
+ assert_eq!(new.interlaced, reference.interlaced);
+ assert_eq!(new.palette, reference.palette);
+ assert_eq!(new.buffer, reference.buffer);
+ }
+ }
+}
+
+#[test]
+#[cfg(feature = "color_quant")]
+fn encode_roundtrip_few_colors() {
+ const WIDTH: u16 = 128;
+ const HEIGHT: u16 = 128;
+
+ // Build an image with a single red pixel, that NeuQuant won't
+ // sample, in order to check that we do appropriatelyq specialise the
+ // few-colors case.
+ let mut pixels: Vec<u8> = vec![255; WIDTH as usize * HEIGHT as usize * 4];
+ // Top-left pixel is always sampled, so use the second pixel.
+ pixels[5] = 0;
+ pixels[6] = 0;
+ // Set speed to 30 to handily avoid sampling that one pixel.
+ //
+ // We clone "pixels", since the parameter is replaced with a
+ // paletted version, and later we want to compare the output with
+ // the original RGBA image.
+ let mut frame = Frame::from_rgba_speed(WIDTH, HEIGHT, &mut pixels.clone(), 30);
+
+ let mut buffer = vec![];
+ {
+ let mut encoder = Encoder::new(&mut buffer, WIDTH, HEIGHT, &[]).unwrap();
+ encoder.write_frame(&frame).unwrap();
+
+ frame.make_lzw_pre_encoded();
+ encoder.write_lzw_pre_encoded_frame(&frame).unwrap();
+ }
+
+ {
+ let mut decoder = {
+ let mut builder = Decoder::<&[u8]>::build();
+ builder.set_color_output(ColorOutput::RGBA);
+ builder.read_info(&buffer[..]).expect("Invalid info encoded")
+ };
+
+ // Only check key fields, assuming "round_trip_from_image"
+ // covers the rest. We are primarily concerned with quantisation.
+ assert_eq!(decoder.width(), WIDTH);
+ assert_eq!(decoder.height(), HEIGHT);
+ let new_frames: Vec<_> = core::iter::from_fn(move || {
+ decoder.read_next_frame().unwrap().cloned()
+ }).collect();
+ assert_eq!(new_frames.len(), 2, "Diverging number of frames");
+ // NB: reference.buffer can't be used as it contains the palette version.
+ assert_eq!(new_frames[0].buffer, pixels);
+ assert_eq!(new_frames[1].buffer, pixels);
+ }
+}