1#[derive(Copy, Clone)]
2enum Value {
3 Short(u16),
4 Long(u32),
5 Rational(u32, u32),
6 DataOffset,
7}
8
9pub fn wrap(data: &[u8], width: u32, height: u32) -> Vec<u8> {
10 use Value::*;
11 let header_data = [
12 (256, Long(width)), (257, Long(height)), (259, Short(4)), (262, Short(0)), (273, DataOffset), (274, Short(1)), (278, Long(height)), (279, Long(data.len() as u32)), (282, Rational(200, 1)), (283, Rational(200, 1)), (296, Short(2)), ];
24 let rat_data_len = 2 * 8; let ifd_end = 4 + 4 + 2 + 12 * header_data.len() + 4; let header_size = ifd_end + rat_data_len;
31
32 let mut out = Vec::with_capacity(header_size + data.len());
33
34 out.extend_from_slice(&[73, 73, 42, 0]);
35 let ifd_offset: u32 = 8;
36 out.extend_from_slice(&ifd_offset.to_le_bytes());
37
38 out.extend_from_slice(&u16::to_le_bytes(header_data.len() as u16));
39
40 let mut num_rat = 0;
41 for &(tag, val) in header_data.iter() {
42 let (typ_num, val) = match val {
43 Short(n) => (3, n as u32),
44 Long(n) => (4, n),
45 Rational(_, _) => {
46 let o = ifd_end + 8 * num_rat;
47 num_rat += 1;
48 (5, o as u32)
49 }
50 DataOffset => (4, header_size as u32),
51 };
52 let count = 1;
53 out.extend_from_slice(&u16::to_le_bytes(tag));
54 out.extend_from_slice(&u16::to_le_bytes(typ_num));
55 out.extend_from_slice(&u32::to_le_bytes(count));
56 out.extend_from_slice(&u32::to_le_bytes(val));
57 }
58 out.extend_from_slice(&[0; 4]);
60
61 for &(_, val) in header_data.iter() {
63 if let Value::Rational(nom, denom) = val {
64 out.extend_from_slice(&nom.to_le_bytes());
65 out.extend_from_slice(&denom.to_le_bytes());
66 }
67 }
68
69 assert_eq!(out.len(), header_size);
70 out.extend_from_slice(data);
71 out
72}