Let's call this canonical for now
This commit is contained in:
parent
bab78aa61a
commit
7d12da32c8
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user