#[derive(Copy, Clone)]
enum Value {
Short(u16),
Long(u32),
Rational(u32, u32),
DataOffset,
}
pub fn wrap(data: &[u8], width: u32, height: u32) -> Vec<u8> {
use Value::*;
let header_data = [
(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)), ];
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;
let mut out = Vec::with_capacity(header_size + data.len());
out.extend_from_slice(&[73, 73, 42, 0]);
let ifd_offset: u32 = 8;
out.extend_from_slice(&ifd_offset.to_le_bytes());
out.extend_from_slice(&u16::to_le_bytes(header_data.len() as u16));
let mut num_rat = 0;
for &(tag, val) in header_data.iter() {
let (typ_num, val) = match val {
Short(n) => (3, n as u32),
Long(n) => (4, n),
Rational(_, _) => {
let o = ifd_end + 8 * num_rat;
num_rat += 1;
(5, o as u32)
}
DataOffset => (4, header_size as u32)
};
let count = 1;
out.extend_from_slice(&u16::to_le_bytes(tag));
out.extend_from_slice(&u16::to_le_bytes(typ_num));
out.extend_from_slice(&u32::to_le_bytes(count));
out.extend_from_slice(&u32::to_le_bytes(val));
}
out.extend_from_slice(&[0; 4]);
for &(_, val) in header_data.iter() {
if let Value::Rational(nom, denom) = val {
out.extend_from_slice(&nom.to_le_bytes());
out.extend_from_slice(&denom.to_le_bytes());
}
}
assert_eq!(out.len(), header_size);
out.extend_from_slice(data);
out
}