Skip to main content

ffmpeg_next/codec/subtitle/
rect.rs

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