1use std::collections::BTreeMap;
2use std::io;
3
4use io::BufWriter;
5use io::Write;
6
7use io::BufRead;
8use io::Cursor;
9use io::Read;
10
11use exif::Exif;
12use exif::Reader;
13
14pub fn exif2map(ex: &Exif) -> BTreeMap<String, String> {
15 let fields = ex.fields();
16 let mapd = fields.map(|field| {
17 let val: String = format!("{}", field.display_value());
18 let tag: String = field.tag.to_string();
19 (tag, val)
20 });
21 BTreeMap::from_iter(mapd)
22}
23
24pub fn map2wtr<W>(m: &BTreeMap<String, String>, mut wtr: W) -> Result<(), io::Error>
25where
26 W: Write,
27{
28 serde_json::to_writer(&mut wtr, m)?;
29 wtr.flush()
30}
31
32pub fn map2stdout(m: &BTreeMap<String, String>) -> Result<(), io::Error> {
33 let o = io::stdout();
34 let mut ol = o.lock();
35 map2wtr(m, BufWriter::new(&mut ol))?;
36 ol.flush()
37}
38
39pub fn parse_exif_bytes(rdr: &Reader, ebytes: Vec<u8>) -> Result<Exif, io::Error> {
40 rdr.read_raw(ebytes).map_err(io::Error::other)
41}
42
43pub fn parse_img_bytes(rdr: &Reader, img: &[u8]) -> Result<Exif, io::Error> {
44 let mut c = Cursor::new(img);
45 rdr.read_from_container(&mut c).map_err(io::Error::other)
46}
47
48pub fn parse_img_reader<R>(erdr: &Reader, rdr: R, max_input_bytes: u64) -> Result<Exif, io::Error>
49where
50 R: BufRead,
51{
52 let mut buf: Vec<u8> = vec![];
53 let mut taken = rdr.take(max_input_bytes);
54 taken.read_to_end(&mut buf)?;
55 parse_img_bytes(erdr, &buf)
56}
57
58pub const MAX_INPUT_BYTES_DEFAULT: u64 = 16777216;
59
60pub fn parse_img_stdin(erdr: &Reader, max_input_bytes: u64) -> Result<Exif, io::Error> {
61 parse_img_reader(erdr, io::stdin().lock(), max_input_bytes)
62}
63
64pub fn parse_img_stdin_default() -> Result<Exif, io::Error> {
65 let rdr = Reader::new();
66 parse_img_stdin(&rdr, MAX_INPUT_BYTES_DEFAULT)
67}
68
69pub fn stdin2img2exif2json2stdout_default() -> Result<(), io::Error> {
70 let meta: Exif = parse_img_stdin_default()?;
71 let mp: BTreeMap<_, _> = exif2map(&meta);
72 map2stdout(&mp)
73}
74
75pub fn stdin2img2exif2json2stdout(max_input_bytes: u64) -> Result<(), io::Error> {
76 let rdr = Reader::new();
77 let meta: Exif = parse_img_stdin(&rdr, max_input_bytes)?;
78 let mp: BTreeMap<_, _> = exif2map(&meta);
79 map2stdout(&mp)
80}