1use std::marker::PhantomData;
2use std::mem;
3use std::slice;
4
5use ffi::*;
6use format;
7use libc::{c_int, size_t};
8use Error;
9
10pub struct Picture<'a> {
11 ptr: *mut AVPicture,
12
13 format: format::Pixel,
14 width: u32,
15 height: u32,
16
17 _own: bool,
18 _marker: PhantomData<&'a ()>,
19}
20
21impl<'a> Picture<'a> {
22 pub unsafe fn wrap(
23 ptr: *mut AVPicture,
24 format: format::Pixel,
25 width: u32,
26 height: u32,
27 ) -> Self {
28 Picture {
29 ptr,
30
31 format,
32 width,
33 height,
34
35 _own: false,
36 _marker: PhantomData,
37 }
38 }
39
40 pub unsafe fn as_ptr(&self) -> *const AVPicture {
41 self.ptr as *const _
42 }
43
44 pub unsafe fn as_mut_ptr(&mut self) -> *mut AVPicture {
45 self.ptr
46 }
47}
48
49impl<'a> Picture<'a> {
50 pub fn size(format: format::Pixel, width: u32, height: u32) -> Result<usize, Error> {
51 unsafe {
52 match avpicture_get_size(format.into(), width as c_int, height as c_int) {
53 v if v >= 0 => Ok(v as usize),
54 e => Err(Error::from(e)),
55 }
56 }
57 }
58
59 pub fn new(format: format::Pixel, width: u32, height: u32) -> Result<Self, Error> {
60 unsafe {
61 let ptr = av_malloc(mem::size_of::<AVPicture>() as size_t) as *mut AVPicture;
62
63 match avpicture_alloc(ptr, format.into(), width as c_int, height as c_int) {
64 0 => Ok(Picture {
65 ptr,
66
67 format,
68 width,
69 height,
70
71 _own: true,
72 _marker: PhantomData,
73 }),
74
75 e => Err(Error::from(e)),
76 }
77 }
78 }
79
80 pub fn format(&self) -> format::Pixel {
81 self.format
82 }
83
84 pub fn width(&self) -> u32 {
85 self.width
86 }
87
88 pub fn height(&self) -> u32 {
89 self.height
90 }
91
92 pub fn layout(&self, out: &mut [u8]) -> Result<usize, Error> {
93 unsafe {
94 match avpicture_layout(
95 self.ptr,
96 self.format.into(),
97 self.width as c_int,
98 self.height as c_int,
99 out.as_mut_ptr(),
100 out.len() as c_int,
101 ) {
102 s if s >= 0 => Ok(s as usize),
103 e => Err(Error::from(e)),
104 }
105 }
106 }
107
108 pub fn layout_as(
109 &self,
110 format: format::Pixel,
111 width: u32,
112 height: u32,
113 out: &mut [u8],
114 ) -> Result<usize, Error> {
115 unsafe {
116 match avpicture_layout(
117 self.as_ptr(),
118 format.into(),
119 width as c_int,
120 height as c_int,
121 out.as_mut_ptr(),
122 out.len() as c_int,
123 ) {
124 s if s >= 0 => Ok(s as usize),
125 e => Err(Error::from(e)),
126 }
127 }
128 }
129
130 pub fn crop(&self, source: &mut Picture, top: u32, left: u32) -> Result<(), Error> {
131 if self.format != source.format {
132 return Err(Error::Bug);
133 }
134
135 unsafe {
136 match av_picture_crop(
137 source.as_mut_ptr(),
138 self.as_ptr(),
139 self.format.into(),
140 top as c_int,
141 left as c_int,
142 ) {
143 0 => Ok(()),
144 e => Err(Error::from(e)),
145 }
146 }
147 }
148
149 pub fn data(&self) -> Vec<&[u8]> {
150 let mut result = Vec::new();
151
152 unsafe {
153 for (i, length) in (*self.as_ptr())
154 .linesize
155 .iter()
156 .take_while(|l| **l > 0)
157 .enumerate()
158 {
159 result.push(slice::from_raw_parts(
160 (*self.as_ptr()).data[i],
161 (*length as usize) * (self.height as usize),
162 ))
163 }
164 }
165
166 result
167 }
168
169 pub fn data_mut(&mut self) -> Vec<&mut [u8]> {
170 let mut result = Vec::new();
171
172 unsafe {
173 for (i, length) in (*self.as_ptr())
174 .linesize
175 .iter()
176 .take_while(|l| **l > 0)
177 .enumerate()
178 {
179 result.push(slice::from_raw_parts_mut(
180 (*self.as_ptr()).data[i],
181 (*length as usize) * (self.height as usize),
182 ))
183 }
184 }
185
186 result
187 }
188}
189
190impl<'a> Clone for Picture<'a> {
191 fn clone(&self) -> Self {
192 let mut pic: Picture<'_> = Picture::new(self.format, self.width, self.height).unwrap();
193 pic.clone_from(self);
194
195 pic
196 }
197
198 fn clone_from(&mut self, source: &Self) {
199 unsafe {
200 av_picture_copy(
201 self.as_mut_ptr(),
202 source.as_ptr(),
203 source.format.into(),
204 source.width as c_int,
205 source.height as c_int,
206 );
207 }
208 }
209}
210
211impl<'a> Drop for Picture<'a> {
212 fn drop(&mut self) {
213 if self._own {
214 unsafe {
215 av_free(self.as_mut_ptr() as *mut _);
216 }
217 }
218 }
219}
220