playa_ffmpeg/codec/subtitle/
rect.rs

1use std::{ffi::CStr, marker::PhantomData, str::from_utf8_unchecked};
2
3use super::{Flags, Type};
4use crate::ffi::*;
5#[cfg(not(feature = "ffmpeg_5_0"))]
6use {crate::format, Picture};
7
8pub enum Rect<'a> {
9    None(*const AVSubtitleRect),
10    Bitmap(Bitmap<'a>),
11    Text(Text<'a>),
12    Ass(Ass<'a>),
13}
14
15impl<'a> Rect<'a> {
16    pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
17        match Type::from(unsafe { (*ptr).type_ }) {
18            Type::None => Rect::None(ptr),
19            Type::Bitmap => Rect::Bitmap(unsafe { Bitmap::wrap(ptr) }),
20            Type::Text => Rect::Text(unsafe { Text::wrap(ptr) }),
21            Type::Ass => Rect::Ass(unsafe { Ass::wrap(ptr) }),
22        }
23    }
24
25    pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
26        match *self {
27            Rect::None(ptr) => ptr,
28            Rect::Bitmap(ref b) => unsafe { b.as_ptr() },
29            Rect::Text(ref t) => unsafe { t.as_ptr() },
30            Rect::Ass(ref a) => unsafe { a.as_ptr() },
31        }
32    }
33}
34
35impl<'a> Rect<'a> {
36    pub fn flags(&self) -> Flags {
37        unsafe {
38            Flags::from_bits_truncate(match *self {
39                Rect::None(ptr) => (*ptr).flags,
40                Rect::Bitmap(ref b) => (*b.as_ptr()).flags,
41                Rect::Text(ref t) => (*t.as_ptr()).flags,
42                Rect::Ass(ref a) => (*a.as_ptr()).flags,
43            })
44        }
45    }
46}
47
48pub struct Bitmap<'a> {
49    ptr: *const AVSubtitleRect,
50
51    _marker: PhantomData<&'a ()>,
52}
53
54impl<'a> Bitmap<'a> {
55    pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
56        Bitmap { ptr, _marker: PhantomData }
57    }
58
59    pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
60        self.ptr
61    }
62}
63
64impl<'a> Bitmap<'a> {
65    pub fn x(&self) -> usize {
66        unsafe { (*self.as_ptr()).x as usize }
67    }
68
69    pub fn y(&self) -> usize {
70        unsafe { (*self.as_ptr()).y as usize }
71    }
72
73    pub fn width(&self) -> u32 {
74        unsafe { (*self.as_ptr()).w as u32 }
75    }
76
77    pub fn height(&self) -> u32 {
78        unsafe { (*self.as_ptr()).h as u32 }
79    }
80
81    pub fn colors(&self) -> usize {
82        unsafe { (*self.as_ptr()).nb_colors as usize }
83    }
84
85    // XXX: must split Picture and PictureMut
86    #[cfg(not(feature = "ffmpeg_5_0"))]
87    pub fn picture(&self, format: format::Pixel) -> Picture<'a> {
88        unsafe { Picture::wrap(&(*self.as_ptr()).pict as *const _ as *mut _, format, (*self.as_ptr()).w as u32, (*self.as_ptr()).h as u32) }
89    }
90}
91
92pub struct Text<'a> {
93    ptr: *const AVSubtitleRect,
94
95    _marker: PhantomData<&'a ()>,
96}
97
98impl<'a> Text<'a> {
99    pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
100        Text { ptr, _marker: PhantomData }
101    }
102
103    pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
104        self.ptr
105    }
106}
107
108impl<'a> Text<'a> {
109    pub fn get(&self) -> &str {
110        unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes()) }
111    }
112}
113
114pub struct Ass<'a> {
115    ptr: *const AVSubtitleRect,
116
117    _marker: PhantomData<&'a ()>,
118}
119
120impl<'a> Ass<'a> {
121    pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
122        Ass { ptr, _marker: PhantomData }
123    }
124
125    pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
126        self.ptr
127    }
128}
129
130impl<'a> Ass<'a> {
131    pub fn get(&self) -> &str {
132        unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes()) }
133    }
134}