about summary refs log tree commit diff
path: root/gifprobe/src/main.rs
blob: 35a137f56fc5ef33fbc119e474c18771fe2ce421 (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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::{convert::TryInto, fs::File, io::Write, path::Path};

use gifed::{
	block::{extension::GraphicControl, Block, ColorTable, IndexedImage, Version},
	reader::GifReader,
	writer::{GifBuilder, ImageBuilder},
	Color,
};
use owo_colors::OwoColorize;

fn main() {
	let file = if let Some(file) = std::env::args().skip(1).next() {
		file
	} else {
		println!("usage: gifprobe file.gif");
		return;
	};

	let gif = GifReader::file(&file).unwrap();

	println!("Version {}", gif.header.yellow());
	println!(
		"Logical Screen Descriptor\n\tDimensions {}x{}",
		gif.screen_descriptor.width.yellow(),
		gif.screen_descriptor.height.yellow()
	);

	if gif.screen_descriptor.color_table_present() {
		println!(
			"\tGlobal Color Table Present {}\n\tGlobal Color Table Size {}",
			"Yes".green(),
			gif.screen_descriptor.color_table_len().green()
		);
	} else {
		println!(
			"\tGlobal Color Table Present {}\n\tGlobal Color Table Size {}",
			"No".red(),
			gif.screen_descriptor.color_table_len().red()
		);
	}

	let mut img_count = 0;
	let mut hundreths: usize = 0;

	for block in gif.blocks {
		match block {
			Block::IndexedImage(img) => {
				describe_image(&img);
				img_count += 1;
			}
			Block::GraphicControlExtension(gce) => {
				hundreths += gce.delay_time() as usize;

				println!(
					"Graphic Control Extension\n\tDelay Time {}\n\tDispose {}",
					format!("{}s", gce.delay_time() as f32 / 100.0).yellow(),
					gce.disposal_method().unwrap().yellow()
				)
			}
			Block::LoopingExtension(_) => todo!(),
			Block::CommentExtension(cmt) => {
				println!("Comment Extension\n\tLength {}", cmt.len())
			}
			Block::ApplicationExtension(app) => {
				let auth = app.authentication_code();
				println!(
					"Application Extension\n\tIdentifier {}\n\tAuthentication {:02X} {:02X} {:02X}",
					app.identifier().yellow(),
					auth[0].yellow(),
					auth[1].yellow(),
					auth[2].yellow()
				);
			}
		}
	}

	println!(
		"{} is {}.{}s long and has {} frames",
		file,
		hundreths / 100,
		hundreths % 100,
		img_count
	);
}

fn describe_image(bli: &IndexedImage) {
	println!(
		"Image\n\tOffset {}x{}\n\tDimensions {}x{}",
		bli.image_descriptor.left.yellow(),
		bli.image_descriptor.top.yellow(),
		bli.image_descriptor.width.yellow(),
		bli.image_descriptor.height.yellow(),
	);

	if bli.image_descriptor.color_table_present() {
		println!(
			"\tLocal Color Table Present {}\n\tLocal Color Table Size {}",
			"Yes".green(),
			bli.image_descriptor.color_table_size().green()
		);
	} else {
		println!(
			"\tLocal Color Table Present {}\n\tLocal Color Table Size {}",
			"No".red(),
			bli.image_descriptor.color_table_size().red()
		);
	}
}