Cargo Format
This commit is contained in:
115
src/main.rs
115
src/main.rs
@@ -36,7 +36,10 @@ struct Decoder<I: Iterator<Item=u8>> {
|
|||||||
run_len: u8,
|
run_len: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <I> Decoder <I> where I: Iterator<Item=u8> {
|
impl<I> Decoder<I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = u8>,
|
||||||
|
{
|
||||||
fn new(bytes: I) -> Self {
|
fn new(bytes: I) -> Self {
|
||||||
Self {
|
Self {
|
||||||
back_buffer: [PixelRGBA::zero(); 64],
|
back_buffer: [PixelRGBA::zero(); 64],
|
||||||
@@ -60,7 +63,10 @@ impl <I> Decoder <I> where I: Iterator<Item=u8> {
|
|||||||
Self {
|
Self {
|
||||||
back_buffer,
|
back_buffer,
|
||||||
prev_pixel: PixelRGBA {
|
prev_pixel: PixelRGBA {
|
||||||
r: 0, g: 0, b: 0, a: 255,
|
r: 0,
|
||||||
|
g: 0,
|
||||||
|
b: 0,
|
||||||
|
a: 255,
|
||||||
},
|
},
|
||||||
bytes,
|
bytes,
|
||||||
run_len: 0,
|
run_len: 0,
|
||||||
@@ -91,7 +97,10 @@ mod codec_utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
impl<'input, I> Iterator for Decoder<I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = u8>,
|
||||||
|
{
|
||||||
type Item = PixelRGBA;
|
type Item = PixelRGBA;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
@@ -108,7 +117,7 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
b: self.bytes.next()?,
|
b: self.bytes.next()?,
|
||||||
a: self.prev_pixel.a,
|
a: self.prev_pixel.a,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
QOI_OP_RGBA => {
|
QOI_OP_RGBA => {
|
||||||
return Some(PixelRGBA {
|
return Some(PixelRGBA {
|
||||||
r: self.bytes.next()?,
|
r: self.bytes.next()?,
|
||||||
@@ -116,11 +125,11 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
b: self.bytes.next()?,
|
b: self.bytes.next()?,
|
||||||
a: self.bytes.next()?,
|
a: self.bytes.next()?,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
QOI_OP_INDEX => {
|
QOI_OP_INDEX => {
|
||||||
let idx = (byte | 0b0011_1111) as usize;
|
let idx = (byte | 0b0011_1111) as usize;
|
||||||
return Some(self.back_buffer[idx]);
|
return Some(self.back_buffer[idx]);
|
||||||
},
|
}
|
||||||
QOI_OP_DIFF => {
|
QOI_OP_DIFF => {
|
||||||
let dr = ((byte | 0b0011_0000) >> 4) - 2;
|
let dr = ((byte | 0b0011_0000) >> 4) - 2;
|
||||||
let dg = ((byte | 0b0000_1100) >> 2) - 2;
|
let dg = ((byte | 0b0000_1100) >> 2) - 2;
|
||||||
@@ -129,9 +138,9 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
r: self.prev_pixel.r + dr,
|
r: self.prev_pixel.r + dr,
|
||||||
g: self.prev_pixel.g + dg,
|
g: self.prev_pixel.g + dg,
|
||||||
b: self.prev_pixel.b + db,
|
b: self.prev_pixel.b + db,
|
||||||
a: self.prev_pixel.a
|
a: self.prev_pixel.a,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
QOI_OP_LUMA => {
|
QOI_OP_LUMA => {
|
||||||
let dg = (byte | 0b0011_1111) - 32;
|
let dg = (byte | 0b0011_1111) - 32;
|
||||||
let packed = self.bytes.next()?;
|
let packed = self.bytes.next()?;
|
||||||
@@ -143,9 +152,9 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
r: self.prev_pixel.r + dr,
|
r: self.prev_pixel.r + dr,
|
||||||
g: self.prev_pixel.g + dg,
|
g: self.prev_pixel.g + dg,
|
||||||
b: self.prev_pixel.b + db,
|
b: self.prev_pixel.b + db,
|
||||||
a: self.prev_pixel.a
|
a: self.prev_pixel.a,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
QOI_OP_RUN => {
|
QOI_OP_RUN => {
|
||||||
self.run_len = byte | 0b0011_1111;
|
self.run_len = byte | 0b0011_1111;
|
||||||
// storage bias of -1, so a +1 should be on the end here.
|
// storage bias of -1, so a +1 should be on the end here.
|
||||||
@@ -153,8 +162,10 @@ impl<'input, I> Iterator for Decoder<I> where I: Iterator<Item=u8> {
|
|||||||
// and returning a PixelRGBA, so the count is also immediatly
|
// and returning a PixelRGBA, so the count is also immediatly
|
||||||
// dropped by 1
|
// dropped by 1
|
||||||
return Some(self.prev_pixel);
|
return Some(self.prev_pixel);
|
||||||
},
|
}
|
||||||
_ => {panic!("bad op code")}
|
_ => {
|
||||||
|
panic!("bad op code")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,15 +192,29 @@ mod test {
|
|||||||
// compressed RGB values should be expanded back out to RGBA
|
// compressed RGB values should be expanded back out to RGBA
|
||||||
// with an assumed alpha of 0xFF.
|
// with an assumed alpha of 0xFF.
|
||||||
let compressed = [
|
let compressed = [
|
||||||
QOI_OP_RGB, 0xFF, 0xFF, 0xFF,
|
QOI_OP_RGB, 0xFF, 0xFF, 0xFF, QOI_OP_RGB, 0x7F, 0x00, 0xAD, QOI_OP_RGB, 0x00, 0x00,
|
||||||
QOI_OP_RGB, 0x7F, 0x00, 0xAD,
|
0x00,
|
||||||
QOI_OP_RGB, 0x00, 0x00, 0x00
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let expected = [
|
let expected = [
|
||||||
PixelRGBA{ r: 0xFF, g: 0xFF, b: 0xFF, a: 0xFF},
|
PixelRGBA {
|
||||||
PixelRGBA{ r: 0x7F, g: 0x00, b: 0xAD, a: 0xFF},
|
r: 0xFF,
|
||||||
PixelRGBA{ r: 0x00, g: 0x00, b: 0x00, a: 0xFF}
|
g: 0xFF,
|
||||||
|
b: 0xFF,
|
||||||
|
a: 0xFF,
|
||||||
|
},
|
||||||
|
PixelRGBA {
|
||||||
|
r: 0x7F,
|
||||||
|
g: 0x00,
|
||||||
|
b: 0xAD,
|
||||||
|
a: 0xFF,
|
||||||
|
},
|
||||||
|
PixelRGBA {
|
||||||
|
r: 0x00,
|
||||||
|
g: 0x00,
|
||||||
|
b: 0x00,
|
||||||
|
a: 0xFF,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let decoder = Decoder::new(compressed.into_iter());
|
let decoder = Decoder::new(compressed.into_iter());
|
||||||
@@ -200,15 +225,42 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn decoder_unpack_rgba() {
|
fn decoder_unpack_rgba() {
|
||||||
let compressed = [
|
let compressed = [
|
||||||
QOI_OP_RGBA, 0xFF, 0xFF, 0xFF, 0xFF,
|
QOI_OP_RGBA,
|
||||||
QOI_OP_RGBA, 0x7F, 0x7F, 0x7F, 0xFF,
|
0xFF,
|
||||||
QOI_OP_RGBA, 0x10, 0x20, 0x30, 0x40,
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
0xFF,
|
||||||
|
QOI_OP_RGBA,
|
||||||
|
0x7F,
|
||||||
|
0x7F,
|
||||||
|
0x7F,
|
||||||
|
0xFF,
|
||||||
|
QOI_OP_RGBA,
|
||||||
|
0x10,
|
||||||
|
0x20,
|
||||||
|
0x30,
|
||||||
|
0x40,
|
||||||
];
|
];
|
||||||
|
|
||||||
let expected = [
|
let expected = [
|
||||||
PixelRGBA{ r: 0xFF, g: 0xFF, b: 0xFF, a: 0xFF },
|
PixelRGBA {
|
||||||
PixelRGBA{ r: 0x7f, g: 0x7f, b: 0x7f, a: 0xFF },
|
r: 0xFF,
|
||||||
PixelRGBA{ r: 0x10, g: 0x20, b: 0x30, a: 0x40 },
|
g: 0xFF,
|
||||||
|
b: 0xFF,
|
||||||
|
a: 0xFF,
|
||||||
|
},
|
||||||
|
PixelRGBA {
|
||||||
|
r: 0x7f,
|
||||||
|
g: 0x7f,
|
||||||
|
b: 0x7f,
|
||||||
|
a: 0xFF,
|
||||||
|
},
|
||||||
|
PixelRGBA {
|
||||||
|
r: 0x10,
|
||||||
|
g: 0x20,
|
||||||
|
b: 0x30,
|
||||||
|
a: 0x40,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let decoder = Decoder::new(compressed.into_iter());
|
let decoder = Decoder::new(compressed.into_iter());
|
||||||
@@ -233,7 +285,7 @@ mod test {
|
|||||||
(QOI_OP_INDEX | 2),
|
(QOI_OP_INDEX | 2),
|
||||||
(QOI_OP_INDEX | 3),
|
(QOI_OP_INDEX | 3),
|
||||||
(QOI_OP_INDEX | 10),
|
(QOI_OP_INDEX | 10),
|
||||||
(QOI_OP_INDEX | 42)
|
(QOI_OP_INDEX | 42),
|
||||||
];
|
];
|
||||||
|
|
||||||
let expected = [
|
let expected = [
|
||||||
@@ -284,15 +336,18 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decoder_unpack_luma() {
|
fn decoder_unpack_luma() {
|
||||||
|
|
||||||
// red and blue diffs are relative to the green channel as (dr - dg) and (db - dg)
|
// red and blue diffs are relative to the green channel as (dr - dg) and (db - dg)
|
||||||
// Their finished diffs need to invert this operation.
|
// Their finished diffs need to invert this operation.
|
||||||
// Diff(dg, dr-dg, db-dg) and Pix (dr, dg, db)
|
// Diff(dg, dr-dg, db-dg) and Pix (dr, dg, db)
|
||||||
let compressed = [
|
let compressed = [
|
||||||
(QOI_OP_LUMA | 0b0011_1111), (0b1111_1111), // Diff( 31, 7, 7) -> Pix (38, 31, 38)
|
(QOI_OP_LUMA | 0b0011_1111),
|
||||||
(QOI_OP_LUMA | 0b0011_0000), (0b1000_1000), // Diff( 0, 0, 0) -> Pix (0, 0, 0)
|
(0b1111_1111), // Diff( 31, 7, 7) -> Pix (38, 31, 38)
|
||||||
(QOI_OP_LUMA | 0b0010_0001), (0b1111_1111), // Diff( 1, 7, 7) -> Pix (8, 1, 8)
|
(QOI_OP_LUMA | 0b0011_0000),
|
||||||
(QOI_OP_LUMA | 0b0001_0011), (0b1100_0011), // Diff(-13, 4, -5) -> Pix (-9, -13, -18)
|
(0b1000_1000), // Diff( 0, 0, 0) -> Pix (0, 0, 0)
|
||||||
|
(QOI_OP_LUMA | 0b0010_0001),
|
||||||
|
(0b1111_1111), // Diff( 1, 7, 7) -> Pix (8, 1, 8)
|
||||||
|
(QOI_OP_LUMA | 0b0001_0011),
|
||||||
|
(0b1100_0011), // Diff(-13, 4, -5) -> Pix (-9, -13, -18)
|
||||||
];
|
];
|
||||||
|
|
||||||
let expected = [
|
let expected = [
|
||||||
|
|||||||
Reference in New Issue
Block a user