const WHITE_CODES: &[(u8, u16, u16)] = &[
(8, 53, 0),
(6, 7, 1),
(4, 7, 2),
(4, 8, 3),
(4, 11, 4),
(4, 12, 5),
(4, 14, 6),
(4, 15, 7),
(5, 19, 8),
(5, 20, 9),
(5, 7, 10),
(5, 8, 11),
(6, 8, 12),
(6, 3, 13),
(6, 52, 14),
(6, 53, 15),
(6, 42, 16),
(6, 43, 17),
(7, 39, 18),
(7, 12, 19),
(7, 8, 20),
(7, 23, 21),
(7, 3, 22),
(7, 4, 23),
(7, 40, 24),
(7, 43, 25),
(7, 19, 26),
(7, 36, 27),
(7, 24, 28),
(8, 2, 29),
(8, 3, 30),
(8, 26, 31),
(8, 27, 32),
(8, 18, 33),
(8, 19, 34),
(8, 20, 35),
(8, 21, 36),
(8, 22, 37),
(8, 23, 38),
(8, 40, 39),
(8, 41, 40),
(8, 42, 41),
(8, 43, 42),
(8, 44, 43),
(8, 45, 44),
(8, 4, 45),
(8, 5, 46),
(8, 10, 47),
(8, 11, 48),
(8, 82, 49),
(8, 83, 50),
(8, 84, 51),
(8, 85, 52),
(8, 36, 53),
(8, 37, 54),
(8, 88, 55),
(8, 89, 56),
(8, 90, 57),
(8, 91, 58),
(8, 74, 59),
(8, 75, 60),
(8, 50, 61),
(8, 51, 62),
(8, 52, 63),
(5, 27, 64),
(5, 18, 128),
(6, 23, 192),
(7, 55, 256),
(8, 54, 320),
(8, 55, 384),
(8, 100, 448),
(8, 101, 512),
(8, 104, 576),
(8, 103, 640),
(9, 204, 704),
(9, 205, 768),
(9, 210, 832),
(9, 211, 896),
(9, 212, 960),
(9, 213, 1024),
(9, 214, 1088),
(9, 215, 1152),
(9, 216, 1216),
(9, 217, 1280),
(9, 218, 1344),
(9, 219, 1408),
(9, 152, 1472),
(9, 153, 1536),
(9, 154, 1600),
(6, 24, 1664),
(9, 155, 1728),
(11, 8, 1792),
(11, 12, 1856),
(11, 13, 1920),
(12, 18, 1984),
(12, 19, 2048),
(12, 20, 2112),
(12, 21, 2176),
(12, 22, 2240),
(12, 23, 2304),
(12, 28, 2368),
(12, 29, 2432),
(12, 30, 2496),
(12, 31, 2560),
];
const BLACK_CODES: &[(u8, u16, u16)] = &[
(10, 55, 0),
(3, 2, 1),
(2, 3, 2),
(2, 2, 3),
(3, 3, 4),
(4, 3, 5),
(4, 2, 6),
(5, 3, 7),
(6, 5, 8),
(6, 4, 9),
(7, 4, 10),
(7, 5, 11),
(7, 7, 12),
(8, 4, 13),
(8, 7, 14),
(9, 24, 15),
(10, 23, 16),
(10, 24, 17),
(10, 8, 18),
(11, 103, 19),
(11, 104, 20),
(11, 108, 21),
(11, 55, 22),
(11, 40, 23),
(11, 23, 24),
(11, 24, 25),
(12, 202, 26),
(12, 203, 27),
(12, 204, 28),
(12, 205, 29),
(12, 104, 30),
(12, 105, 31),
(12, 106, 32),
(12, 107, 33),
(12, 210, 34),
(12, 211, 35),
(12, 212, 36),
(12, 213, 37),
(12, 214, 38),
(12, 215, 39),
(12, 108, 40),
(12, 109, 41),
(12, 218, 42),
(12, 219, 43),
(12, 84, 44),
(12, 85, 45),
(12, 86, 46),
(12, 87, 47),
(12, 100, 48),
(12, 101, 49),
(12, 82, 50),
(12, 83, 51),
(12, 36, 52),
(12, 55, 53),
(12, 56, 54),
(12, 39, 55),
(12, 40, 56),
(12, 88, 57),
(12, 89, 58),
(12, 43, 59),
(12, 44, 60),
(12, 90, 61),
(12, 102, 62),
(12, 103, 63),
(10, 15, 64),
(12, 200, 128),
(12, 201, 192),
(12, 91, 256),
(12, 51, 320),
(12, 52, 384),
(12, 53, 448),
(13, 108, 512),
(13, 109, 576),
(13, 74, 640),
(13, 75, 704),
(13, 76, 768),
(13, 77, 832),
(13, 114, 896),
(13, 115, 960),
(13, 116, 1024),
(13, 117, 1088),
(13, 118, 1152),
(13, 119, 1216),
(13, 82, 1280),
(13, 83, 1344),
(13, 84, 1408),
(13, 85, 1472),
(13, 90, 1536),
(13, 91, 1600),
(13, 100, 1664),
(13, 101, 1728),
(11, 8, 1792),
(11, 12, 1856),
(11, 13, 1920),
(12, 18, 1984),
(12, 19, 2048),
(12, 20, 2112),
(12, 21, 2176),
(12, 22, 2240),
(12, 23, 2304),
(12, 28, 2368),
(12, 29, 2432),
(12, 30, 2496),
(12, 31, 2560),
];
fn push_code(bits: &mut Vec<u8>, color: bool, run: u32) {
let table: &[(u8, u16, u16)] = if color { WHITE_CODES } else { BLACK_CODES };
let mut remaining = run;
let makeup: Vec<(u8, u16, u16)> = table.iter().filter(|e| e.2 >= 64).rev().copied().collect();
for &(len, code, r) in &makeup {
while remaining >= u32::from(r) {
for i in (0..len).rev() {
bits.push(((code >> i) & 1) as u8);
}
remaining -= u32::from(r);
}
}
let Some(&(len, code, _)) = table
.iter()
.find(|e| u32::from(e.2) == remaining && e.2 < 64)
else {
return;
};
for i in (0..len).rev() {
bits.push(((code >> i) & 1) as u8);
}
}
pub fn encode_mh_page(rows: &[Vec<u8>], width: usize) -> Vec<u8> {
let mut bits = Vec::new();
for row in rows {
debug_assert_eq!(row.len(), width);
bits.extend([0u8; 11]);
bits.push(1);
bits.push(1);
let mut color = false;
let mut pos = 0usize;
let changes: Vec<(usize, u8)> = {
let mut out = Vec::new();
let mut cur = 0u8;
for (i, &px) in row.iter().enumerate() {
if px != cur {
out.push((i, px));
cur = px;
}
}
out
};
for &(px, c) in &changes {
push_code(&mut bits, !color, (px - pos) as u32);
pos = px;
color = c != 0;
}
push_code(&mut bits, !color, (width - pos) as u32);
}
for _ in 0..6 {
bits.extend([0u8; 11]);
bits.push(1);
bits.push(1);
}
while bits.len() % 8 != 0 {
bits.push(0);
}
bits.chunks(8)
.map(|c| c.iter().fold(0u8, |a, &b| (a << 1) | b))
.collect()
}
pub fn encode_mh_page_no_rtc(rows: &[Vec<u8>], width: usize) -> Vec<u8> {
let full = encode_mh_page(rows, width);
let end = full.len() - 9;
full[..end].to_vec()
}