Coverage Report

Created: 2025-07-23 06:46

/src/mp4san/webpsan/src/parse/vp8l.rs
Line
Count
Source
1
#![allow(missing_docs)]
2
3
use std::fmt::Debug;
4
use std::io::{Cursor, Read};
5
use std::num::NonZeroU16;
6
use std::result::Result as StdResult;
7
8
use bitstream_io::{BitRead, BitReader, LE};
9
use bytes::{Buf, BytesMut};
10
use derive_more::Display;
11
use mediasan_common::ensure_attach;
12
use mediasan_common::parse::FourCC;
13
use mediasan_common::Result;
14
15
use crate::Error;
16
17
use super::bitstream::BitBufReader;
18
use super::chunk_type::VP8L;
19
use super::lossless::LosslessImage;
20
use super::{ParseChunk, ParseError};
21
22
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23
pub struct Vp8lChunk {
24
    width: NonZeroU16,
25
    height: NonZeroU16,
26
    pub alpha_is_used: bool,
27
}
28
29
//
30
// private types
31
//
32
33
#[derive(Clone, Copy, Debug, Display)]
34
#[display("invalid VP8L signature `0x{_0:x}` != `0x{}`", Vp8lChunk::SIGNATURE)]
35
struct InvalidSignature(u8);
36
37
//
38
// Vp8lChunk impls
39
//
40
41
impl Vp8lChunk {
42
    const SIGNATURE: u8 = 0x2F;
43
44
3.93k
    pub fn width(&self) -> NonZeroU16 {
45
3.93k
        self.width
46
3.93k
    }
47
48
3.93k
    pub fn height(&self) -> NonZeroU16 {
49
3.93k
        self.height
50
3.93k
    }
51
52
3.40k
    pub fn sanitize_image_data<R: Read>(&self, input: R) -> StdResult<(), Error> {
53
3.40k
        let mut reader = BitBufReader::<_, LE>::with_capacity(input, 4096);
54
3.40k
        let _image = LosslessImage::read(&mut reader, self.width.into(), self.height.into())?;
55
318
        Ok(())
56
3.40k
    }
57
}
58
59
impl ParseChunk for Vp8lChunk {
60
    const NAME: FourCC = VP8L;
61
62
    const ENCODED_LEN: u32 = 5;
63
64
3.50k
    fn parse(buf: &mut BytesMut) -> Result<Self, ParseError> {
65
3.50k
        let mut header = [0; Self::ENCODED_LEN as usize];
66
3.50k
        buf.copy_to_slice(&mut header);
67
3.50k
        let mut reader = BitReader::<_, LE>::new(Cursor::new(header));
68
3.50k
69
3.50k
        let signature = reader.read(8).unwrap();
70
3.50k
71
3.50k
        ensure_attach!(
72
3.50k
            signature == Self::SIGNATURE,
73
14
            ParseError::InvalidInput,
74
14
            InvalidSignature(signature)
75
        );
76
77
3.49k
        let width = NonZeroU16::MIN.saturating_add(reader.read(14).unwrap());
78
3.49k
        let height = NonZeroU16::MIN.saturating_add(reader.read(14).unwrap());
79
3.49k
        let alpha_is_used = reader.read_bit().unwrap();
80
3.49k
        let version = reader.read(3).unwrap();
81
3.49k
82
3.49k
        ensure_attach!(version == 0, ParseError::UnsupportedVp8lVersion(version));
83
84
3.49k
        Ok(Self { width, height, alpha_is_used })
85
3.50k
    }
86
}