about summary refs log tree commit diff
path: root/src/block/extension/mod.rs
blob: fb5eb2041601e2d1dba44691daf1333ad956e283 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
mod application;
mod graphiccontrol;

pub use graphiccontrol::{DisposalMethod, GraphicControl};

pub use self::application::Application;

pub enum Extension {
	GraphicControl(GraphicControl),
	Looping(u16),
	Comment(Vec<u8>), // Plain Text
	Application(Application),
}

impl From<&Extension> for Box<[u8]> {
	fn from(ext: &Extension) -> Self {
		let mut vec = vec![];
		vec.push(0x21); // Push the extension introducer

		match ext {
			Extension::GraphicControl(gc) => {
				vec.push(0xF9); // Graphic control label
				vec.push(0x04); // Block size for this extension is always 4
				vec.push(gc.packed);
				vec.extend_from_slice(&gc.delay_time.to_le_bytes());
				vec.push(gc.transparency_index);
			}
			Extension::Looping(count) => {
				vec.push(0xFF); // Application extension label
				vec.push(0x0B); // 11 bytes in this block
				vec.extend_from_slice(b"NETSCAPE2.0"); // App. ident. and "auth code"
				vec.push(0x03); // Sub-block length
				vec.push(0x01); // Identifies netscape looping extension
				vec.extend_from_slice(&count.to_le_bytes());
			}
			Extension::Comment(_) => todo!(),
			Extension::Application(_) => todo!(),
		}

		vec.push(0x00); // Zero-length data block indicates end of extension
		vec.into_boxed_slice()
	}
}

impl From<GraphicControl> for Extension {
	fn from(gce: GraphicControl) -> Self {
		Extension::GraphicControl(gce)
	}
}