Well, it kinda works
This commit is contained in:
parent
ea18938dcf
commit
89cb8eead7
BIN
inputs/lohikar.png
Normal file
BIN
inputs/lohikar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 30 KiB |
@ -11,7 +11,7 @@ pub fn decode_tile<R: Read>(
|
||||
|
||||
for _ in 0..quality {
|
||||
let ix = reader.read_u8()?;
|
||||
let val = reader.read_u16()? as i32;
|
||||
let val = decode_value(reader.read_u8()?);
|
||||
coefs[ix as usize] = val;
|
||||
}
|
||||
|
||||
@ -49,11 +49,14 @@ pub fn decode_tile<R: Read>(
|
||||
}
|
||||
|
||||
pub fn decode_value(enc: u8) -> i32 {
|
||||
// mu law
|
||||
let sign = enc & 0x80 != 0;
|
||||
let exponent = (enc >> 4) & 0x7;
|
||||
let mantissa = enc & 0xf;
|
||||
|
||||
let magnitude = ((((mantissa as i32) << 1) | 0b100001) << exponent) - 33;
|
||||
if sign { return -magnitude * 16 }
|
||||
return magnitude * 16;
|
||||
let value = if sign { -magnitude } else {magnitude };
|
||||
|
||||
// unquantize
|
||||
return value * 32;
|
||||
}
|
@ -57,13 +57,16 @@ pub fn encode_tile<W: Write>(
|
||||
for i in 0..quality {
|
||||
let ix = indices[i as usize];
|
||||
writer.write_u8(ix as u8)?;
|
||||
writer.write_u16(coefs[ix] as u16)?;
|
||||
writer.write_u8(encode_value(coefs[ix]))?;
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn encode_value(value: i32) -> u8 {
|
||||
let value = value / 16;
|
||||
// quantize
|
||||
let value = value / 32;
|
||||
|
||||
// mu law
|
||||
let sign = value < 0;
|
||||
let mut rescaled = value.abs() + 33;
|
||||
let mut exponent = 0;
|
||||
@ -72,6 +75,7 @@ pub fn encode_value(value: i32) -> u8 {
|
||||
exponent += 1;
|
||||
rescaled >>= 1;
|
||||
}
|
||||
assert!(exponent <= 7);
|
||||
|
||||
let mantissa = (rescaled >> 1) & 0xf;
|
||||
|
||||
@ -91,61 +95,10 @@ mod test {
|
||||
use super::encode_value;
|
||||
|
||||
#[quickcheck]
|
||||
fn test_encode_value_2(val: u16) -> bool {
|
||||
fn test_encode_value(val: u16) -> bool {
|
||||
let val = (val & (0x8000 | 0x3fff)) as i16;
|
||||
let canon = decode_value(encode_value(val as i32));
|
||||
|
||||
canon == decode_value(encode_value(canon as i32))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encode_value_1() {
|
||||
// ...01abcdx cases
|
||||
assert_eq!(0b00001111, encode_value(0 + (0b111110 - 33)));
|
||||
assert_eq!(0b00001110, encode_value(0 + (0b111100 - 33)));
|
||||
assert_eq!(0b10001111, encode_value(0 - (0b111110 - 33)));
|
||||
assert_eq!(0b10001110, encode_value(0 - (0b111100 - 33)));
|
||||
|
||||
// ...01abcdxx cases
|
||||
assert_eq!(0b00011111, encode_value(0 + (0b1111101 - 33)));
|
||||
assert_eq!(0b00011110, encode_value(0 + (0b1111001 - 33)));
|
||||
assert_eq!(0b10011111, encode_value(0 - (0b1111101 - 33)));
|
||||
assert_eq!(0b10011110, encode_value(0 - (0b1111001 - 33)));
|
||||
|
||||
// ...01abcdxxx cases
|
||||
assert_eq!(0b00101111, encode_value(0 + (0b11111000 - 33)));
|
||||
assert_eq!(0b00101110, encode_value(0 + (0b11110001 - 33)));
|
||||
assert_eq!(0b10101111, encode_value(0 - (0b11111010 - 33)));
|
||||
assert_eq!(0b10101110, encode_value(0 - (0b11110011 - 33)));
|
||||
|
||||
// ...01abcdxxxx cases
|
||||
assert_eq!(0b00111111, encode_value(0 + (0b111110000 - 33)));
|
||||
assert_eq!(0b00111110, encode_value(0 + (0b111100010 - 33)));
|
||||
assert_eq!(0b10111111, encode_value(0 - (0b111110100 - 33)));
|
||||
assert_eq!(0b10111110, encode_value(0 - (0b111100110 - 33)));
|
||||
|
||||
// ...01abcdxxxxx cases
|
||||
assert_eq!(0b01001111, encode_value(0 + (0b1111100000 - 33)));
|
||||
assert_eq!(0b01001110, encode_value(0 + (0b1111000100 - 33)));
|
||||
assert_eq!(0b11001111, encode_value(0 - (0b1111101000 - 33)));
|
||||
assert_eq!(0b11001110, encode_value(0 - (0b1111001100 - 33)));
|
||||
|
||||
// ...01abcdxxxxxx cases
|
||||
assert_eq!(0b01011111, encode_value(0 + (0b11111000000 - 33)));
|
||||
assert_eq!(0b01011110, encode_value(0 + (0b11110001000 - 33)));
|
||||
assert_eq!(0b11011111, encode_value(0 - (0b11111010000 - 33)));
|
||||
assert_eq!(0b11011110, encode_value(0 - (0b11110011000 - 33)));
|
||||
|
||||
// ...01abcdxxxxxxx cases
|
||||
assert_eq!(0b01101111, encode_value(0 + (0b111110000000 - 33)));
|
||||
assert_eq!(0b01101110, encode_value(0 + (0b111100010000 - 33)));
|
||||
assert_eq!(0b11101111, encode_value(0 - (0b111110100000 - 33)));
|
||||
assert_eq!(0b11101110, encode_value(0 - (0b111100110000 - 33)));
|
||||
|
||||
// ...01abcdxxxxxxx cases
|
||||
assert_eq!(0b01111111, encode_value(0 + (0b1111100000000 - 33)));
|
||||
assert_eq!(0b01111110, encode_value(0 + (0b1111000100001 - 33)));
|
||||
assert_eq!(0b11111111, encode_value(0 - (0b1111101000010 - 33)));
|
||||
assert_eq!(0b11111110, encode_value(0 - (0b1111001100011 - 33)));
|
||||
}
|
||||
}
|
@ -12,13 +12,14 @@ mod protocol;
|
||||
|
||||
fn main() {
|
||||
// run_for("zonked".to_string(), 9, 2, Some(330000));
|
||||
run_for("lohikar".to_string());
|
||||
run_for("zonked".to_string());
|
||||
run_for("avatar2".to_string());
|
||||
}
|
||||
fn run_for(name: String) {
|
||||
let image = png_utils::load_image(
|
||||
format!("inputs/{}.png", name),
|
||||
[5, 6, 5, 0]
|
||||
[5, 5, 5, 1]
|
||||
).unwrap();
|
||||
let mut writer = ProtocolWriter::new(vec![]);
|
||||
|
||||
|
@ -13,7 +13,6 @@ pub fn load_image(filename: String, quality: [u8; 4]) -> Result<Image, ImageErro
|
||||
let bytes = &buf[..info.buffer_size()];
|
||||
|
||||
assert_eq!(BitDepth::Eight, reader.info().bit_depth);
|
||||
assert_eq!(ColorType::Rgb, reader.info().color_type);
|
||||
|
||||
let width = reader.info().width;
|
||||
let height = reader.info().height;
|
||||
|
@ -44,7 +44,6 @@ impl<W: Write> ProtocolWriter<W> {
|
||||
self.writer.write_all(&value.to_le_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
impl<R: Read> ProtocolReader<R> {
|
||||
pub fn new(reader: R) -> Self {
|
||||
|
Loading…
Reference in New Issue
Block a user