use byteorder::{LittleEndian, ReadBytesExt};
use std::default::Default;
use std::fmt;
use std::io::Read;
use crate::vp8::error::{ImageError, ImageResult};
const MAX_SEGMENTS: usize = 4;
const NUM_DCT_TOKENS: usize = 12;
type Prob = u8;
pub(super) static KEYFRAME_YMODE_PROBS: [Prob; 4] = [145, 156, 163, 128];
pub(super) static KEYFRAME_UV_MODE_PROBS: [Prob; 3] = [142, 114, 183];
type TokenProbTables = [[[[Prob; NUM_DCT_TOKENS - 1]; 3]; 8]; 4];
static COEFF_UPDATE_PROBS: TokenProbTables = [
[
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255],
[249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255],
[234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255],
[250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255],
[254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
],
[
[
[217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255],
[234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255],
],
[
[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
],
[
[
[186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255],
[234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255],
[251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255],
],
[
[255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
],
[
[
[248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255],
[248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255],
],
[
[255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255],
[248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255],
[250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
[
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
],
],
];
pub(super) static COEFF_PROBS: TokenProbTables = [
[
[
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
],
[
[253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128],
[189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128],
[106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128],
],
[
[1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128],
[181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128],
[78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128],
],
[
[1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128],
[184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128],
[77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128],
],
[
[1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128],
[170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128],
[37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128],
],
[
[1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128],
[207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128],
[102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128],
],
[
[1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128],
[177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128],
[80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128],
],
[
[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
],
],
[
[
[198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62],
[131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1],
[68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128],
],
[
[1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128],
[184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128],
[81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128],
],
[
[1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128],
[99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128],
[23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128],
],
[
[1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128],
[109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128],
[44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128],
],
[
[1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128],
[94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128],
[22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128],
],
[
[1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128],
[124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128],
[35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128],
],
[
[1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128],
[121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128],
[45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128],
],
[
[1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128],
[203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128],
[137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128],
],
],
[
[
[253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128],
[175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128],
[73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128],
],
[
[1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128],
[239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128],
[155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128],
],
[
[1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128],
[201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128],
[69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128],
],
[
[1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128],
[223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128],
[141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128],
],
[
[1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128],
[190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128],
[149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
],
[
[1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128],
],
[
[1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128],
[213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128],
[55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128],
],
[
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
[128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128],
],
],
[
[
[202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255],
[126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128],
[61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128],
],
[
[1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128],
[166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128],
[39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128],
],
[
[1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128],
[124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128],
[24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128],
],
[
[1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128],
[149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128],
[28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128],
],
[
[1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128],
[123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128],
[20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128],
],
[
[1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128],
[168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128],
[47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128],
],
[
[1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128],
[141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128],
[42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128],
],
[
[1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
[238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128],
],
],
];
pub(super) struct BoolReader {
buf: Vec<u8>,
index: usize,
pub(super) range: u32,
pub(super) value: u32,
pub(super) bit_count: u8,
}
impl Debug for BoolReader {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("BoolReader")
.field("index", &self.index)
.field("range", &self.range)
.field("value", &self.value)
.field("bit_count", &self.bit_count)
.finish()
}
}
impl BoolReader {
pub(crate) fn new() -> BoolReader {
BoolReader {
buf: Vec::new(),
range: 0,
value: 0,
bit_count: 0,
index: 0,
}
}
pub(crate) fn init(&mut self, buf: Vec<u8>) -> ImageResult<()> {
if buf.len() < 2 {
return Err(ImageError);
}
self.buf = buf;
self.value = (u32::from(self.buf[0]) << 8) | u32::from(self.buf[1]);
self.index = 2;
self.range = 255;
self.bit_count = 0;
Ok(())
}
pub(crate) fn read_bool(&mut self, probability: u8) -> bool {
let split = 1 + (((self.range - 1) * u32::from(probability)) >> 8);
let bigsplit = split << 8;
let retval = if self.value >= bigsplit {
self.range -= split;
self.value -= bigsplit;
true
} else {
self.range = split;
false
};
while self.range < 128 {
self.value <<= 1;
self.range <<= 1;
self.bit_count += 1;
if self.bit_count == 8 {
self.bit_count = 0;
if self.index < self.buf.len() {
self.value |= u32::from(self.buf[self.index]);
self.index += 1;
}
}
}
retval
}
pub(crate) fn read_literal(&mut self, n: u8) -> u8 {
let mut v = 0u8;
let mut n = n;
while n != 0 {
v = (v << 1) + self.read_bool(128u8) as u8;
n -= 1;
}
v
}
pub(crate) fn read_magnitude_and_sign(&mut self, n: u8) -> i32 {
let magnitude = self.read_literal(n);
let sign = self.read_literal(1);
if sign == 1 {
-i32::from(magnitude)
} else {
i32::from(magnitude)
}
}
pub(crate) fn read_flag(&mut self) -> bool {
0 != self.read_literal(1)
}
}
#[derive(Default, Clone)]
pub struct Frame {
pub width: u16,
pub height: u16,
pub(super) horizontal_scale: u8,
pub(super) vertical_scale: u8,
pub keyframe: bool,
pub(super) version: u8,
pub for_display: bool,
pub pixel_type: u8,
pub(super) filter_type: bool, pub(super) filter_level: u8,
pub(super) sharpness_level: u8,
pub(super) first_partition_size: u32,
}
impl Debug for Frame {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Frame")
.field("width", &self.width)
.field("height", &self.height)
.field("keyframe", &self.keyframe)
.field("version", &self.version)
.field("for_display", &self.for_display)
.field("pixel_type", &self.pixel_type)
.field("filter_type", &self.filter_type)
.field("filter_level", &self.filter_level)
.field("sharpness_level", &self.sharpness_level)
.finish()
}
}
#[derive(Clone, Copy, Debug, Default)]
pub(super) struct Segment {
delta_values: bool,
pub(super) quantizer_level: i8,
pub(super) loopfilter_level: i8,
}
#[derive(Clone, Copy, Debug, Default)]
pub(super) struct Quant {
pub(super) y_ac_qi: u8,
pub(super) y_dc_delta: i8,
pub(super) y2_dc_delta: i8,
pub(super) y2_ac_delta: i8,
pub(super) uv_dc_delta: i8,
pub(super) uv_ac_delta: i8,
}
use core::fmt::Debug;
#[derive(Debug)]
pub struct Vp8Decoder<R: Debug> {
r: R,
pub(super) b: BoolReader,
mbwidth: u16,
mbheight: u16,
pub(super) frame: Frame,
pub(super) quant: Quant,
pub(super) segments_enabled: bool,
pub(super) segments_update_map: bool,
pub(super) update_segment_feature_data: bool,
pub(super) segment_feature_mode: bool,
pub(super) lf_adjust_enable: bool,
pub(super) delta_update: bool,
pub(super) segment: [Segment; MAX_SEGMENTS],
pub(super) ref_delta: [i8; 4],
pub(super) mode_delta: [i8; 4],
partitions: [BoolReader; 8],
pub(super) num_partitions: u8,
pub(super) segment_tree_probs: [Prob; 3],
pub(super) token_probs: Box<TokenProbTables>,
prob_intra: Prob,
pub(super) prob_skip_false: Option<Prob>,
}
impl<R: Read + Debug> Vp8Decoder<R> {
pub fn new(r: R) -> Vp8Decoder<R> {
let f = Frame::default();
let s = Segment::default();
Vp8Decoder {
r,
b: BoolReader::new(),
mbwidth: 0,
mbheight: 0,
frame: f,
quant: Quant::default(),
segments_enabled: false,
segments_update_map: false,
update_segment_feature_data: false,
segment_feature_mode: false,
lf_adjust_enable: false,
delta_update: false,
segment: [s; MAX_SEGMENTS],
ref_delta: [0; 4],
mode_delta: [0; 4],
partitions: [
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
BoolReader::new(),
],
num_partitions: 1,
segment_tree_probs: [255u8; 3],
token_probs: Box::new(COEFF_PROBS),
prob_intra: 0u8,
prob_skip_false: None,
}
}
fn update_token_probabilities(&mut self) {
for (i, is) in COEFF_UPDATE_PROBS.iter().enumerate() {
for (j, js) in is.iter().enumerate() {
for (k, ks) in js.iter().enumerate() {
for (t, prob) in ks.iter().enumerate().take(NUM_DCT_TOKENS - 1) {
if self.b.read_bool(*prob) {
let v = self.b.read_literal(8);
self.token_probs[i][j][k][t] = v;
}
}
}
}
}
}
fn init_partitions(&mut self, n: usize) -> ImageResult<()> {
if n > 1 {
let mut sizes = vec![0; 3 * n - 3];
self.r.read_exact(sizes.as_mut_slice())?;
for (i, s) in sizes.chunks(3).enumerate() {
let size = { s }
.read_u24::<LittleEndian>()
.expect("Reading from &[u8] can't fail and the chunk is complete");
let mut buf = vec![0; size as usize];
self.r.read_exact(buf.as_mut_slice())?;
self.partitions[i].init(buf)?;
}
}
let mut buf = Vec::new();
self.r.read_to_end(&mut buf)?;
self.partitions[n - 1].init(buf)?;
Ok(())
}
fn read_quantization_indices(&mut self) {
let yac_abs = i16::from(self.b.read_literal(7));
let ydc_delta = if self.b.read_flag() {
self.b.read_magnitude_and_sign(4)
} else {
0
};
let y2dc_delta = if self.b.read_flag() {
self.b.read_magnitude_and_sign(4)
} else {
0
};
let y2ac_delta = if self.b.read_flag() {
self.b.read_magnitude_and_sign(4)
} else {
0
};
let uvdc_delta = if self.b.read_flag() {
self.b.read_magnitude_and_sign(4)
} else {
0
};
let uvac_delta = if self.b.read_flag() {
self.b.read_magnitude_and_sign(4)
} else {
0
};
let n = if self.segments_enabled {
MAX_SEGMENTS
} else {
1
};
self.quant.y_ac_qi = yac_abs as u8;
self.quant.y_dc_delta = ydc_delta as i8;
self.quant.y2_dc_delta = y2dc_delta as i8;
self.quant.y2_ac_delta = y2ac_delta as i8;
self.quant.uv_dc_delta = uvdc_delta as i8;
self.quant.uv_ac_delta = uvac_delta as i8;
}
fn read_loop_filter_adjustments(&mut self) {
self.delta_update = self.b.read_flag();
if self.delta_update {
for i in 0usize..4 {
let ref_frame_delta_update_flag = self.b.read_flag();
self.ref_delta[i] = if ref_frame_delta_update_flag {
self.b.read_magnitude_and_sign(6) as i8
} else {
0i8
};
}
for i in 0usize..4 {
let mb_mode_delta_update_flag = self.b.read_flag();
self.mode_delta[i] = if mb_mode_delta_update_flag {
self.b.read_magnitude_and_sign(6) as i8
} else {
0i8
};
}
}
}
fn read_segment_updates(&mut self) {
self.segments_update_map = self.b.read_flag();
self.update_segment_feature_data = self.b.read_flag();
if self.update_segment_feature_data {
self.segment_feature_mode = self.b.read_flag();
for i in 0usize..MAX_SEGMENTS {
self.segment[i].delta_values = !self.segment_feature_mode;
}
for i in 0usize..MAX_SEGMENTS {
let update = self.b.read_flag();
self.segment[i].quantizer_level = if update {
self.b.read_magnitude_and_sign(7)
} else {
0i32
} as i8;
}
for i in 0usize..MAX_SEGMENTS {
let update = self.b.read_flag();
self.segment[i].loopfilter_level = if update {
self.b.read_magnitude_and_sign(6)
} else {
0i32
} as i8;
}
}
if self.segments_update_map {
for i in 0usize..3 {
let update = self.b.read_flag();
self.segment_tree_probs[i] = if update { self.b.read_literal(8) } else { 255 };
}
}
}
pub(super) fn read_frame_header(&mut self) -> ImageResult<()> {
let tag = self.r.read_u24::<LittleEndian>()?;
self.frame.keyframe = tag & 1 == 0;
self.frame.version = ((tag >> 1) & 7) as u8;
self.frame.for_display = (tag >> 4) & 1 != 0;
self.frame.first_partition_size = tag >> 5;
if self.frame.keyframe {
let mut tag = [0u8; 3];
self.r.read_exact(&mut tag)?;
if tag != [0x9d, 0x01, 0x2a] {
return Err(ImageError);
}
let w = self.r.read_u16::<LittleEndian>()?;
let h = self.r.read_u16::<LittleEndian>()?;
self.frame.width = w & 0x3FFF;
self.frame.height = h & 0x3FFF;
self.frame.horizontal_scale = (w >> 14) as u8;
self.frame.vertical_scale = (h >> 14) as u8;
self.mbwidth = (self.frame.width + 15) / 16;
self.mbheight = (self.frame.height + 15) / 16;
}
let mut buf = vec![0; self.frame.first_partition_size as usize];
self.r.read_exact(&mut buf)?;
self.b.init(buf)?;
if self.frame.keyframe {
let color_space = self.b.read_literal(1);
self.frame.pixel_type = self.b.read_literal(1);
if color_space != 0 {
return Err(ImageError);
}
}
self.segments_enabled = self.b.read_flag();
if self.segments_enabled {
self.read_segment_updates();
}
self.frame.filter_type = self.b.read_flag();
self.frame.filter_level = self.b.read_literal(6);
self.frame.sharpness_level = self.b.read_literal(3);
self.lf_adjust_enable = self.b.read_flag();
if self.lf_adjust_enable {
self.read_loop_filter_adjustments();
}
self.num_partitions = (1usize << self.b.read_literal(2) as usize) as u8;
let num_partitions = self.num_partitions as usize;
self.init_partitions(num_partitions)?;
self.read_quantization_indices();
if !self.frame.keyframe {
return Err(ImageError);
} else {
let _ = self.b.read_literal(1);
}
self.update_token_probabilities();
let mb_no_skip_coeff = self.b.read_literal(1);
self.prob_skip_false = if mb_no_skip_coeff == 1 {
Some(self.b.read_literal(8))
} else {
None
};
if !self.frame.keyframe {
self.prob_intra = 0;
return Err(ImageError);
} else {
}
Ok(())
}
}