Skip to main content

opus_headers/
ogg_page.rs

1use crate::error::{ParseError, Result};
2use crate::read_ext::ReadExt;
3use std::io::Read;
4
5pub(crate) struct OggPage {
6    pub version: u8,
7    pub header_type: u8,
8    pub granule_position: i64,
9    pub bitstream_serial_number: u32,
10    pub page_sequence_number: u32,
11    pub crc_checksum: u32,
12    pub page_segments: u8,
13    pub segment_table: Vec<u8>, // contains the amount of bytes of payload: bytes = sum(segment_table_entries)
14    pub payload: Vec<u8>,
15}
16
17impl OggPage {
18    pub(crate) fn parse<T: Read>(mut reader: T) -> Result<OggPage> {
19        // test ogg magic and read page
20        if &reader.read_four_bytes()? != b"OggS" {
21            return Err(ParseError::InvalidOggPage);
22        }
23
24        let version = reader.read_u8_le()?;
25        let header_type = reader.read_u8_le()?;
26        let granule_position = reader.read_i64_le()?;
27        let bitstream_serial_number = reader.read_u32_le()?;
28        let page_sequence_number = reader.read_u32_le()?;
29        let crc_checksum = reader.read_u32_le()?;
30        let page_segments = reader.read_u8_le()?;
31        let segment_table = reader.read_byte_vec(page_segments as usize)?;
32
33        let total_segments = segment_table.iter().map(|&b| b as usize).sum();
34        let payload = reader.read_byte_vec(total_segments)?;
35
36        Ok(OggPage {
37            version,
38            header_type,
39            granule_position,
40            bitstream_serial_number,
41            page_sequence_number,
42            crc_checksum,
43            page_segments,
44            segment_table,
45            payload,
46        })
47    }
48}