use std::env; use std::io::prelude::*; use std::fs::File; use std::path::Path; const ELUT_SIZE: usize = 512; fn main() { generate_half_to_float_lookup(); generate_elut_lookup(); } fn init_elut() -> [u16; ELUT_SIZE] { let mut elut = [0u16; ELUT_SIZE]; for i in 0i32..0x100 { let e = (i & 0x0ff) - (127 - 15); if e <= 0 || e >= 30 { elut[i as usize] = 0 as u16; elut[i as usize | 0x100] = 0 as u16; } else { elut[i as usize] = (e << 10) as u16; elut[i as usize | 0x100] = ((e << 10) | 0x8000) as u16; } } elut } fn generate_elut_lookup() { let elut = init_elut(); let file_path = format!("{}/elut_table.rs", env::var("OUT_DIR").unwrap()); let path = Path::new(&file_path); let mut file = File::create(&path).unwrap(); file.write_all(format!("static ELUT_TABLE: [u16; {}] = [\n", ELUT_SIZE).as_bytes()).unwrap(); for x in elut.iter() { file.write_all(format!("\t{},\n", x).as_bytes()).unwrap(); } file.write_all("];".as_bytes()).unwrap(); } fn half_to_float(value: u32) -> u32 { let s: u32 = (value>> 15) & 0x00000001; let mut e: u32 = (value >> 10) & 0x0000001f; let mut m: u32 = value & 0x000003ff; if e == 0 { if m == 0 { return s << 31; } else { while (m & 0x00000400) == 0 { m = m << 1; e = e.wrapping_sub(1); } e = e.wrapping_add(1); m = m & !0x00000400; } } else if e == 31 { if m == 0 { return (s << 31) | 0x7f800000; } else { return (s << 31) | 0x7f800000 | (m << 13); } } e = e.wrapping_add(127 - 15); m = m << 13; (s << 31) | (e << 23) | m } fn generate_half_to_float_lookup() { let file_path = format!("{}/to_float_lookup.rs", env::var("OUT_DIR").unwrap()); let path = Path::new(&file_path); let mut file = File::create(&path).unwrap(); let max = 1 << 16; file.write_all(format!("static FLOAT_LOOKUP: [u32; {}] = [\n", max).as_bytes()).unwrap(); for x in 0..max { file.write_all(format!("\t{:#x},\n", half_to_float(x)).as_bytes()).unwrap(); } file.write_all("];".as_bytes()).unwrap(); }