// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. use super::{frame_header::PermutationNonserialized, permutation::Permutation}; use crate::{ bit_reader::BitReader, entropy_coding::decode::{Histograms, SymbolReader, unpack_signed}, error::Error, }; pub enum U32 { Bits(usize), BitsOffset { n: usize, off: u32 }, Val(u32), } impl U32 { pub fn read(&self, br: &mut BitReader) -> Result { match *self { U32::Bits(n) => Ok(br.read_noinline(n)? as u32), U32::BitsOffset { n, off } => Ok(br.read_noinline(n)? as u32 + off), U32::Val(val) => Ok(val), } } } pub enum U32Coder { Direct(U32), Select(U32, U32, U32, U32), } #[derive(Default)] pub struct Empty {} pub trait UnconditionalCoder where Self: Sized, { type Nonserialized; fn read_unconditional( config: &Config, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result; } impl UnconditionalCoder<()> for bool { type Nonserialized = Empty; fn read_unconditional( _: &(), br: &mut BitReader, _: &Self::Nonserialized, ) -> Result { Ok(br.read_noinline(1)? != 0) } } impl UnconditionalCoder<()> for f32 { type Nonserialized = Empty; fn read_unconditional( _: &(), br: &mut BitReader, _: &Self::Nonserialized, ) -> Result { use crate::util::f16; let ret = f16::from_bits(br.read_noinline(16)? as u16); if !ret.is_finite() { Err(Error::FloatNaNOrInf) } else { Ok(ret.to_f32()) } } } impl UnconditionalCoder for u32 { type Nonserialized = Empty; fn read_unconditional( config: &U32Coder, br: &mut BitReader, _: &Self::Nonserialized, ) -> Result { let u = match config { U32Coder::Direct(u) => u, U32Coder::Select(u0, u1, u2, u3) => { let selector = br.read_noinline(2)?; match selector { 0 => u0, 1 => u1, 2 => u2, _ => u3, } } }; u.read(br) } } impl UnconditionalCoder for i32 { type Nonserialized = Empty; fn read_unconditional( config: &U32Coder, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result { let u = u32::read_unconditional(config, br, nonserialized)?; Ok(unpack_signed(u)) } } impl UnconditionalCoder<()> for u64 { type Nonserialized = Empty; fn read_unconditional( _: &(), br: &mut BitReader, _: &Self::Nonserialized, ) -> Result { match br.read_noinline(2)? { 0 => Ok(0), 1 => Ok(1 + br.read_noinline(4)?), 2 => Ok(17 + br.read_noinline(8)?), _ => { let mut result: u64 = br.read_noinline(12)?; let mut shift = 12; while br.read_noinline(1)? == 1 { if shift >= 60 { assert_eq!(shift, 60); return Ok(result | (br.read_noinline(4)? << shift)); } result |= br.read_noinline(8)? << shift; shift += 8; } Ok(result) } } } } impl UnconditionalCoder<()> for String { type Nonserialized = Empty; fn read_unconditional( _: &(), br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result { let len = u32::read_unconditional( &U32Coder::Select( U32::Val(0), U32::Bits(4), U32::BitsOffset { n: 5, off: 16 }, U32::BitsOffset { n: 10, off: 48 }, ), br, nonserialized, )?; let mut ret = String::new(); ret.reserve(len as usize); for _ in 0..len { match br.read_noinline(8) { Ok(c) => ret.push(c as u8 as char), Err(Error::OutOfBounds(n)) => { // Use saturating arithmetic to prevent underflow on malformed input // ret.len()+1 cannot overflow since ret.len() <= isize::MAX let remaining = (len as usize) .saturating_add(n) .saturating_sub(ret.len() + 1); return Err(Error::OutOfBounds(remaining)); } Err(e) => return Err(e), } } Ok(ret) } } impl UnconditionalCoder<()> for Permutation { type Nonserialized = PermutationNonserialized; fn read_unconditional( _: &(), br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result { // TODO: This is quadratic when incrementally parsing byte by byte, // we might want to find a better way of reading the permutation. let ret = if nonserialized.permuted { let size = nonserialized.num_entries; let num_contexts = 8; let histograms = Histograms::decode(num_contexts, br, /*allow_lz77=*/ true)?; let mut reader = SymbolReader::new(&histograms, br, None)?; Permutation::decode(size, 0, &histograms, br, &mut reader) } else { Ok(Permutation::default()) }; br.jump_to_byte_boundary()?; ret } } impl, Config, const N: usize> UnconditionalCoder for [T; N] { type Nonserialized = T::Nonserialized; fn read_unconditional( config: &Config, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result<[T; N], Error> { use array_init::try_array_init; try_array_init(|_| T::read_unconditional(config, br, nonserialized)) } } pub struct VectorCoder { pub size_coder: U32Coder, pub value_coder: T, } impl> UnconditionalCoder> for Vec { type Nonserialized = T::Nonserialized; fn read_unconditional( config: &VectorCoder, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result, Error> { let len = u32::read_unconditional(&config.size_coder, br, &Empty {})?; let mut ret: Vec = Vec::new(); ret.reserve_exact(len as usize); for _ in 0..len { ret.push(T::read_unconditional( &config.value_coder, br, nonserialized, )?); } Ok(ret) } } pub trait ConditionalCoder where Self: Sized, { type Nonserialized; fn read_conditional( config: &Config, condition: bool, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result; } impl> ConditionalCoder for Option { type Nonserialized = T::Nonserialized; fn read_conditional( config: &Config, condition: bool, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result, Error> { if condition { Ok(Some(T::read_unconditional(config, br, nonserialized)?)) } else { Ok(None) } } } impl ConditionalCoder<()> for String { type Nonserialized = Empty; fn read_conditional( _: &(), condition: bool, br: &mut BitReader, nonserialized: &Empty, ) -> Result { if condition { String::read_unconditional(&(), br, nonserialized) } else { Ok(String::new()) } } } impl> ConditionalCoder> for Vec { type Nonserialized = T::Nonserialized; fn read_conditional( config: &VectorCoder, condition: bool, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result, Error> { if condition { Vec::read_unconditional(config, br, nonserialized) } else { Ok(Vec::new()) } } } pub trait DefaultedElementCoder where Self: Sized, { type Nonserialized; fn read_defaulted_element( config: &Config, condition: bool, default: T, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result; } impl DefaultedElementCoder, T> for Vec where T: UnconditionalCoder + Clone, { type Nonserialized = T::Nonserialized; fn read_defaulted_element( config: &VectorCoder, condition: bool, default: T, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result { let len = u32::read_unconditional(&config.size_coder, br, &Empty {})?; if condition { let mut ret: Vec = Vec::new(); ret.reserve_exact(len as usize); for _ in 0..len { ret.push(T::read_unconditional( &config.value_coder, br, nonserialized, )?); } Ok(ret) } else { Ok(vec![default; len as usize]) } } } pub trait DefaultedCoder where Self: Sized, { type Nonserialized; fn read_defaulted( config: &Config, condition: bool, default: Self, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result; } impl> DefaultedCoder for T { type Nonserialized = T::Nonserialized; fn read_defaulted( config: &Config, condition: bool, default: Self, br: &mut BitReader, nonserialized: &Self::Nonserialized, ) -> Result { if condition { Ok(T::read_unconditional(config, br, nonserialized)?) } else { Ok(default) } } } // TODO(veluca93): this will likely need to be implemented differently if // there are extensions. #[derive(Debug, PartialEq, Default, Clone)] pub struct Extensions {} impl UnconditionalCoder<()> for Extensions { type Nonserialized = Empty; fn read_unconditional( _: &(), br: &mut BitReader, _: &Self::Nonserialized, ) -> Result { let selector = u64::read_unconditional(&(), br, &Empty {})?; let mut total_size: u64 = 0; for i in 0..64 { if (selector & (1u64 << i)) != 0 { let size = u64::read_unconditional(&(), br, &Empty {})?; let sum = total_size.checked_add(size); if let Some(s) = sum { total_size = s; } else { return Err(Error::SizeOverflow); } } } let total_size = usize::try_from(total_size); if let Ok(ts) = total_size { br.skip_bits(ts)?; } else { return Err(Error::SizeOverflow); } Ok(Extensions {}) } }