1 | use std::ffi::CStr; |
2 | use std::marker::PhantomData; |
3 | use std::str::from_utf8_unchecked; |
4 | |
5 | use super::{Flags, Type}; |
6 | use ffi::*; |
7 | #[cfg (not(feature = "ffmpeg_5_0" ))] |
8 | use {format, Picture}; |
9 | |
10 | pub enum Rect<'a> { |
11 | None(*const AVSubtitleRect), |
12 | Bitmap(Bitmap<'a>), |
13 | Text(Text<'a>), |
14 | Ass(Ass<'a>), |
15 | } |
16 | |
17 | impl<'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: *const {unknown}) => ptr, |
30 | Rect::Bitmap(ref b: &Bitmap<'_>) => b.as_ptr(), |
31 | Rect::Text(ref t: &Text<'_>) => t.as_ptr(), |
32 | Rect::Ass(ref a: &Ass<'_>) => a.as_ptr(), |
33 | } |
34 | } |
35 | } |
36 | |
37 | impl<'a> Rect<'a> { |
38 | pub fn flags(&self) -> Flags { |
39 | unsafe { |
40 | Flags::from_bits_truncate(bits:match *self { |
41 | Rect::None(ptr: *const {unknown}) => (*ptr).flags, |
42 | Rect::Bitmap(ref b: &Bitmap<'_>) => (*b.as_ptr()).flags, |
43 | Rect::Text(ref t: &Text<'_>) => (*t.as_ptr()).flags, |
44 | Rect::Ass(ref a: &Ass<'_>) => (*a.as_ptr()).flags, |
45 | }) |
46 | } |
47 | } |
48 | } |
49 | |
50 | pub struct Bitmap<'a> { |
51 | ptr: *const AVSubtitleRect, |
52 | |
53 | _marker: PhantomData<&'a ()>, |
54 | } |
55 | |
56 | impl<'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 | |
69 | impl<'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 | |
104 | pub struct Text<'a> { |
105 | ptr: *const AVSubtitleRect, |
106 | |
107 | _marker: PhantomData<&'a ()>, |
108 | } |
109 | |
110 | impl<'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 | |
123 | impl<'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 | |
129 | pub struct Ass<'a> { |
130 | ptr: *const AVSubtitleRect, |
131 | |
132 | _marker: PhantomData<&'a ()>, |
133 | } |
134 | |
135 | impl<'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 | |
148 | impl<'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 | } |
153 | |