Well, it kinda works
This commit is contained in:
		
							
								
								
									
										
											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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user