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
|
use std::{convert::TryInto, fs::File, io::Write, path::Path};
use gifed::{
block::{
extension::{Extension, GraphicControl},
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 {
gifed::block::Block::IndexedImage(img) => {
describe_image(&img);
img_count += 1;
}
gifed::block::Block::Extension(ext) => match ext {
gifed::block::extension::Extension::GraphicControl(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()
)
}
gifed::block::extension::Extension::Looping(_) => todo!(),
gifed::block::extension::Extension::Comment(cmt) => {
println!("Comment Extension\n\tLength {}", cmt.len())
}
gifed::block::extension::Extension::Application(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()
);
}
}
|