pgs_parse/
pgs_wds_segment.rs

1use std::rc::Rc;
2
3use crate::{pgs_memory_buffer::{BigEndian, ReadBytes}, Error, PgsMemoryBuffer, PgsSegmentHeader, Result};
4
5/// Represents the definition of a display window within a Window Definition Segment (WDS).
6///
7/// The `PgsWdsSegmentWindowDefinition` structure contains details about the position and size of
8/// a window where subtitles will be displayed on the screen.
9#[derive(Debug)]
10pub struct PgsWdsSegmentWindowDefinition {
11    pub window_id: u8,
12    pub window_horizontal_position: u16,
13    pub window_vertical_position: u16,
14    pub window_width: u16,
15    pub window_height: u16
16}
17
18impl PgsWdsSegmentWindowDefinition {
19    fn new(window_id: u8,
20        window_horizontal_position: u16,
21        window_vertical_position: u16,
22        window_width: u16,
23        window_height: u16) -> Self {
24        PgsWdsSegmentWindowDefinition {
25            window_id,
26            window_horizontal_position,
27            window_vertical_position,
28            window_width,
29            window_height
30        }
31    }
32}
33
34/// Represents a Window Definition Segment (WDS) in a Presentation Graphic Stream (PGS).
35///
36/// The `PgsWdsSegment` structure contains information about multiple windows used for displaying subtitles.
37/// Each window is defined by its ID, position, and size.
38#[derive(Debug)]
39pub struct PgsWdsSegment {
40    pub header: PgsSegmentHeader,
41    pub number_of_windows: u8,
42    pub windows: Vec<PgsWdsSegmentWindowDefinition>
43}
44
45impl PgsWdsSegment {
46    fn new(header: PgsSegmentHeader, number_of_windows: u8, windows: Vec<PgsWdsSegmentWindowDefinition>) -> Self {
47        PgsWdsSegment {
48            header,
49            number_of_windows,
50            windows
51        }
52    }
53
54    /// Parses a `PgsWdsSegment` from raw data.
55    ///
56    /// # Parameters
57    /// - `header`: The segment header.
58    /// - `data`: Raw byte data containing the segment information.
59    ///
60    /// # Returns
61    /// - `Ok(Rc<PgsWdsSegment>)`: A reference-counted pointer to the parsed `PgsWdsSegment`.
62    /// - `Err(Error)`: An error if the data is invalid or cannot be parsed.
63    pub fn from_data(header: PgsSegmentHeader, data: &[u8]) -> Result<Rc<PgsWdsSegment>> {
64        if data.len() < header.segment_length as usize {
65            return Err(Error::InvalidSegmentDataLength);
66        }
67
68        let mut buffer: PgsMemoryBuffer = PgsMemoryBuffer::from(data);
69        let number_of_windows = buffer.read_u8()?;
70        let mut windows: Vec<PgsWdsSegmentWindowDefinition> = Vec::new();
71        for _ in 0..number_of_windows {
72            let window_id = buffer.read_u8()?;
73            let window_horizontal_position = buffer.read_u16::<BigEndian>()?;
74            let window_vertical_position = buffer.read_u16::<BigEndian>()?;
75            let window_width = buffer.read_u16::<BigEndian>()?;
76            let window_height = buffer.read_u16::<BigEndian>()?;
77            windows.push(PgsWdsSegmentWindowDefinition::new(window_id, window_horizontal_position, window_vertical_position, window_width, window_height))
78        }
79
80        Ok(Rc::new(PgsWdsSegment::new(header, number_of_windows, windows)))
81    }
82}