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