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 {
|
for _ in 0..quality {
|
||||||
let ix = reader.read_u8()?;
|
let ix = reader.read_u8()?;
|
||||||
let val = decode_value(reader.read_u16()?);
|
coefs[ix as usize] = reader.read_u16()? as i16 as i32 * 256;
|
||||||
coefs[ix as usize] = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut transform = |zero: usize, stride: usize| {
|
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 row in 0..16 { transform(row * 16, 1); }
|
||||||
for col in 0..16 { transform(col, 16); }
|
for col in 0..16 { transform(col, 16); }
|
||||||
|
|
||||||
for i in 0..256 {
|
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(())
|
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 {
|
for i in 0..quality {
|
||||||
let ix = indices[i as usize];
|
let ix = indices[i as usize];
|
||||||
writer.write_u8(ix as u8)?;
|
writer.write_u8(ix as u8)?;
|
||||||
writer.write_u16(encode_value(coefs[ix]))?;
|
writer.write_u16((coefs[ix] / 256) as i16 as u16)?;
|
||||||
};
|
};
|
||||||
Ok(())
|
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() {
|
fn main() {
|
||||||
// run_for("zonked".to_string(), 9, 2, Some(330000));
|
// run_for("zonked".to_string(), 9, 2, Some(330000));
|
||||||
|
run_for("kapu".to_string());
|
||||||
run_for("lohikar".to_string());
|
run_for("lohikar".to_string());
|
||||||
run_for("zonked".to_string());
|
run_for("zonked".to_string());
|
||||||
run_for("avatar2".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