pgs_parse/
pgs_pds_segment.rs

1//! # PGS Palette Definition Segment (PDS)
2//!
3//! This module defines the `PgsPdsSegment` struct, which represents the Palette Definition Segment (PDS)
4//! in the Presentation Graphic Stream (PGS) format. The PDS defines color palettes used by the subtitles
5//! or other graphical elements in a PGS file.
6
7use std::{io::Read, rc::Rc};
8
9use crate::{pgs_memory_buffer::ReadBytes, Error, PgsMemoryBuffer, PgsSegmentHeader, Result};
10
11/// Struct representing an individual palette entry in a PDS.
12/// Each palette entry consists of the palette ID and its corresponding color values (Y, Cr, Cb).
13#[derive(Debug)]
14pub struct PgsPdsSegmentPaletteEntry {
15    pub palette_entry_id: u8,
16    pub luminance: u8, // (Y)
17    pub color_difference_red: u8, // (Cr)
18    pub color_difference_blue: u8, // (Cb)
19    pub transparency: u8
20}
21
22impl PgsPdsSegmentPaletteEntry {
23    fn new(palette_entry_id: u8,
24        luminance: u8,
25        color_difference_red: u8,
26        color_difference_blue: u8,
27        transparency: u8) -> Self {
28        PgsPdsSegmentPaletteEntry{
29            palette_entry_id,
30            luminance,
31            color_difference_red,
32            color_difference_blue,
33            transparency
34        }
35    }
36}
37
38/// Struct representing a Palette Definition Segment (PDS) in a PGS file.
39/// The PDS defines a color palette that can be used by various objects in the PGS file.
40#[derive(Debug)]
41pub struct PgsPdsSegment {
42    pub header: PgsSegmentHeader,
43    pub palette_id: u8,
44    pub palette_version_number: u8,
45    pub palette_entries: Vec<PgsPdsSegmentPaletteEntry>
46}
47
48impl PgsPdsSegment {
49    fn new(header: PgsSegmentHeader,
50        palette_id: u8,
51        palette_version_number: u8,
52        palette_entries: Vec<PgsPdsSegmentPaletteEntry>) -> Self {
53        PgsPdsSegment {
54            header,
55            palette_id,
56            palette_version_number,
57            palette_entries
58        }
59    }
60
61    /// Parses a `PgsPdsSegment` from the provided header and raw data buffer.
62    ///
63    /// This method reads the palette ID, version number, and individual palette entries from the data buffer.
64    /// Each palette entry consists of luminance, color difference (Cr, Cb), and transparency values.
65    ///
66    /// # Parameters
67    /// - `header`: The segment header.
68    /// - `data`: A slice of raw data representing the contents of the PDS segment.
69    ///
70    /// # Errors
71    /// Returns `Error::InvalidSegmentDataLength` if the length of the provided data is less than expected.
72    ///
73    /// # Returns
74    /// An `Rc<PgsPdsSegment>` containing the parsed segment.
75    pub fn from_data(header: PgsSegmentHeader, data: &[u8]) -> Result<Rc<PgsPdsSegment>> {
76        if data.len() < header.segment_length as usize {
77            return Err(Error::InvalidSegmentDataLength);
78        }
79
80        let mut buffer: PgsMemoryBuffer = PgsMemoryBuffer::from(data);
81        let palette_id = buffer.read_u8()?;
82        let palette_version_number = buffer.read_u8()?;
83
84        let mut palette_buf: Vec<u8> = Vec::new();
85        buffer.read_to_end(&mut palette_buf)?;
86
87        // TODO: Return error if palette_buf.len() % 5 is not 0
88        let palette_count = (palette_buf.len() as u32  - 2) / 5;
89
90        let mut buffer: PgsMemoryBuffer = PgsMemoryBuffer::from(palette_buf);
91        let mut palette_entries: Vec<PgsPdsSegmentPaletteEntry> = Vec::new();
92        for _ in 0..palette_count {
93            let palette_entry_id = buffer.read_u8()?;
94            let luminance = buffer.read_u8()?;
95            let color_difference_red = buffer.read_u8()?;
96            let color_difference_blue = buffer.read_u8()?;
97            let transparency = buffer.read_u8()?;
98            palette_entries.push(PgsPdsSegmentPaletteEntry::new(palette_entry_id, luminance, color_difference_red, color_difference_blue, transparency))
99        }
100
101
102        Ok(Rc::new(PgsPdsSegment::new(header, palette_id, palette_version_number, palette_entries)))
103    }
104}