1use gif::DisposalMethod;
2use imgref::{ImgRef, ImgRefMut};
3use rgb::RGBA8;
4
5enum SavedState {
6 Previous(Vec<RGBA8>),
7 Background,
8 Keep,
9}
10
11pub struct Disposal {
12 saved: SavedState,
13 left: u16, top: u16,
14 width: u16, height: u16,
15}
16
17impl Default for Disposal {
18 fn default() -> Self {
19 Disposal {
20 saved: SavedState::Keep,
21 top: 0, left: 0, width: 0, height: 0,
22 }
23 }
24}
25
26impl Disposal {
27 pub fn dispose(&self, mut pixels: ImgRefMut<'_, RGBA8>) {
28 if self.width == 0 || self.height == 0 {
29 return;
30 }
31
32 let mut dest = pixels.sub_image_mut(self.left.into(), self.top.into(), self.width.into(), self.height.into());
33 match &self.saved {
34 SavedState::Background => {
35 let bg = RGBA8::default();
36 for px in dest.pixels_mut() { *px = bg; }
37 },
38 SavedState::Previous(saved) => {
39 for (px, &src) in dest.pixels_mut().zip(saved.iter()) { *px = src; }
40 },
41 SavedState::Keep => {},
42 }
43 }
44
45 pub fn new(method: gif::DisposalMethod, left: u16, top: u16, width: u16, height: u16, pixels: ImgRef<'_, RGBA8>) -> Self {
46 Disposal {
47 saved: match method {
48 DisposalMethod::Previous => SavedState::Previous(pixels.sub_image(left.into(), top.into(), width.into(), height.into()).pixels().collect()),
49 DisposalMethod::Background => SavedState::Background,
50 _ => SavedState::Keep,
51 },
52 left, top, width, height,
53 }
54 }
55}