Let's call this canonical for now
This commit is contained in:
		
							
								
								
									
										
											BIN
										
									
								
								inputs/kapu.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								inputs/kapu.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 23 KiB | 
| @@ -11,8 +11,7 @@ pub fn decode_tile<R: Read>( | ||||
|  | ||||
|     for _ in 0..quality { | ||||
|         let ix = reader.read_u8()?; | ||||
|         let val = decode_value(reader.read_u16()?); | ||||
|         coefs[ix as usize] = val; | ||||
|         coefs[ix as usize] = reader.read_u16()? as i16 as i32 * 256; | ||||
|     } | ||||
|  | ||||
|     let mut transform = |zero: usize, stride: usize| { | ||||
| @@ -33,33 +32,13 @@ pub fn decode_tile<R: Read>( | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for i in 0..16 { | ||||
|             coefs[ixs[i]] /= 16; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     for row in 0..16 { transform(row * 16, 1); } | ||||
|     for col in 0..16 { transform(col, 16); } | ||||
|  | ||||
|     for i in 0..256 { | ||||
|         data[i] = coefs[i].max(0).min(255) as u8; | ||||
|         data[i] = (coefs[i] / 256).max(0).min(255) as u8; | ||||
|     } | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| pub fn decode_value(enc: u16) -> i32 { | ||||
|     return (enc as i16) as i32 * 16; | ||||
|     /* | ||||
|     // 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; | ||||
|     let value = if sign { -magnitude } else {magnitude }; | ||||
|  | ||||
|     // unquantize | ||||
|     return value * 32; | ||||
|     */ | ||||
| } | ||||
| @@ -57,51 +57,7 @@ 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(encode_value(coefs[ix]))?; | ||||
|         writer.write_u16((coefs[ix] / 256) as i16 as u16)?; | ||||
|     }; | ||||
|     Ok(()) | ||||
| } | ||||
|  | ||||
| pub fn encode_value(value: i32) -> u16 { | ||||
|     return ((value / 16) as i16) as u16; | ||||
|     /* | ||||
|     // quantize | ||||
|     let value = value / 32; | ||||
|  | ||||
|     // mu law | ||||
|     let sign = value < 0; | ||||
|     let mut rescaled = value.abs() + 33; | ||||
|     let mut exponent = 0; | ||||
|  | ||||
|     while rescaled > 64 { | ||||
|         exponent += 1; | ||||
|         rescaled >>= 1; | ||||
|     } | ||||
|     assert!(exponent <= 7); | ||||
|  | ||||
|     let mantissa = (rescaled >> 1) & 0xf; | ||||
|  | ||||
|     return ( | ||||
|         if sign { 128 } else { 0 } | | ||||
|         exponent << 4 | | ||||
|         mantissa | ||||
|     ) as u8; | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| mod test { | ||||
|     use quickcheck_macros::quickcheck; | ||||
|  | ||||
|     use crate::decode_tile::decode_value; | ||||
|  | ||||
|     use super::encode_value; | ||||
|  | ||||
|     #[quickcheck] | ||||
|     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)) | ||||
|     } | ||||
|     */ | ||||
| } | ||||
| @@ -12,6 +12,7 @@ mod protocol; | ||||
|  | ||||
| fn main() { | ||||
|     // run_for("zonked".to_string(), 9, 2, Some(330000)); | ||||
|     run_for("kapu".to_string()); | ||||
|     run_for("lohikar".to_string()); | ||||
|     run_for("zonked".to_string()); | ||||
|     run_for("avatar2".to_string()); | ||||
|   | ||||
| @@ -1,66 +0,0 @@ | ||||
| // Ported from:  | ||||
| // - https://colab.research.google.com/drive/1WjtKwUcqxWafAumFO9ET74RsckZSsw6n#scrollTo=e3r9-RBpcgwH | ||||
|  | ||||
| // Specialized for: | ||||
| // | ||||
| // - Input domain: 0-255 | ||||
| // - Tile size: 16x16 | ||||
| // | ||||
| // Rather than dividing by 16 at the end of a decode phase, | ||||
| // we divide by 16 at the end of the _encode_ phase | ||||
| // | ||||
| // The normal range would be something like -255 * 256 to 255 * 256 | ||||
| // (-65280 to 65280) but this reduces it (now it's something like -4080 to 4080) | ||||
| // | ||||
| // This simplifies the decoder (which can be i16) and means it can be written | ||||
| // using i16s instead of i32s | ||||
| // | ||||
| // We could probably shrink the range more by recentering to -128-127, but does | ||||
| // it even matter? Reasonable encodings like A-law and mu-law can handle both. | ||||
| // | ||||
| // (Take my opinions on the range with a grain of salt: I've calculated it but I | ||||
| //  haven't measured it) | ||||
| // | ||||
| struct Transform<'d> { | ||||
|     data: &'d mut [i32], | ||||
|     zero: usize, | ||||
|     stride: usize, | ||||
| } | ||||
|  | ||||
| impl<'d> Transform<'d> { | ||||
|     pub fn encode(&mut self) { | ||||
|         self.transform(); | ||||
|         self.divide(16); | ||||
|     } | ||||
|  | ||||
|     pub fn decode(&mut self) { | ||||
|         self.transform(); | ||||
|     } | ||||
|  | ||||
|     pub fn ix(&self, i: usize) -> usize { | ||||
|         self.zero + t * self.stride | ||||
|     } | ||||
|  | ||||
|     fn transform(&mut self) { | ||||
|         for bit in [8, 4, 2, 1] { | ||||
|             for i in 0..16 { | ||||
|                 if i & bit == 0 { | ||||
|                     let j = i | bit; | ||||
|  | ||||
|                     let ival = self.data[self.ix(i)]; | ||||
|                     let jval = self.data[self.ix(j)]; | ||||
|  | ||||
|                     self.data[self.ix(i)] = ival.wrapping_add(jval); | ||||
|                     self.data[self.ix(j)] = ival.wrapping_sub(jval); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn divide(&mut self, divisor: i32) { | ||||
|         for i in 0..16 { | ||||
|             self.data[self.ix(i)] = self.data[self.ix(j)] / divisor; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user