codec/subtitle: refactor Rect handling
This commit is contained in:
parent
7ad3654976
commit
01b5f74fb0
@ -1,17 +1,17 @@
|
||||
pub mod flag;
|
||||
pub use self::flag::Flags;
|
||||
|
||||
mod rect;
|
||||
pub use self::rect::{Rect, Bitmap, Text, Ass};
|
||||
|
||||
mod rect_mut;
|
||||
pub use self::rect_mut::{RectMut, BitmapMut, TextMut, AssMut};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::ffi::CStr;
|
||||
use std::str::from_utf8_unchecked;
|
||||
use std::ops::Deref;
|
||||
|
||||
use libc::{c_uint, uint32_t};
|
||||
use libc::{c_uint, uint32_t, size_t};
|
||||
use ffi::*;
|
||||
use ::format;
|
||||
use ::Picture;
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
||||
pub enum Type {
|
||||
@ -92,6 +92,26 @@ impl Subtitle {
|
||||
pub fn rects(&self) -> RectIter {
|
||||
RectIter::new(&self.0)
|
||||
}
|
||||
|
||||
pub fn rects_mut(&mut self) -> RectMutIter {
|
||||
RectMutIter::new(&mut self.0)
|
||||
}
|
||||
|
||||
pub fn add_rect(&mut self, kind: Type) -> RectMut {
|
||||
unsafe {
|
||||
self.0.num_rects += 1;
|
||||
self.0.rects = av_realloc(self.0.rects as *mut _,
|
||||
(mem::size_of::<*const AVSubtitleRect>() * self.0.num_rects as usize) as size_t)
|
||||
as *mut _;
|
||||
|
||||
let mut rect = av_mallocz(mem::size_of::<AVSubtitleRect>() as size_t) as *mut AVSubtitleRect;
|
||||
(*rect).kind = kind.into();
|
||||
|
||||
*self.0.rects.offset((self.0.num_rects - 1) as isize) = rect;
|
||||
|
||||
RectMut::wrap(rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RectIter<'a> {
|
||||
@ -124,177 +144,50 @@ impl<'a> Iterator for RectIter<'a> {
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
unsafe {
|
||||
((*self.ptr).num_rects as usize, Some((*self.ptr).num_rects as usize))
|
||||
let length = (*self.ptr).num_rects as usize;
|
||||
|
||||
(length - self.cur as usize, Some(length - self.cur as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ExactSizeIterator for RectIter<'a> { }
|
||||
|
||||
pub enum Rect<'a> {
|
||||
None,
|
||||
Bitmap(Bitmap<'a>),
|
||||
Text(Text<'a>),
|
||||
Ass(Ass<'a>),
|
||||
pub struct RectMutIter<'a> {
|
||||
ptr: *mut AVSubtitle,
|
||||
cur: c_uint,
|
||||
|
||||
_marker: PhantomData<&'a Subtitle>,
|
||||
}
|
||||
|
||||
impl<'a> Rect<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
match Type::from((*ptr).kind) {
|
||||
Type::None => Rect::None,
|
||||
Type::Bitmap => Rect::Bitmap(Bitmap::wrap(ptr)),
|
||||
Type::Text => Rect::Text(Text::wrap(ptr)),
|
||||
Type::Ass => Rect::Ass(Ass::wrap(ptr))
|
||||
impl<'a> RectMutIter<'a> {
|
||||
pub fn new(ptr: *mut AVSubtitle) -> Self {
|
||||
RectMutIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
match self {
|
||||
&Rect::None => ptr::null(),
|
||||
&Rect::Bitmap(ref b) => b.as_ptr(),
|
||||
&Rect::Text(ref t) => t.as_ptr(),
|
||||
&Rect::Ass(ref a) => a.as_ptr()
|
||||
}
|
||||
}
|
||||
impl<'a> Iterator for RectMutIter<'a> {
|
||||
type Item = RectMut<'a>;
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
match self {
|
||||
&mut Rect::None => ptr::null_mut(),
|
||||
&mut Rect::Bitmap(ref mut b) => b.as_mut_ptr(),
|
||||
&mut Rect::Text(ref mut t) => t.as_mut_ptr(),
|
||||
&mut Rect::Ass(ref mut a) => a.as_mut_ptr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Rect<'a> {
|
||||
pub fn flags(&self) -> Flags {
|
||||
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
|
||||
unsafe {
|
||||
Flags::from_bits_truncate(match self {
|
||||
&Rect::None => 0,
|
||||
&Rect::Bitmap(ref b) => (*b.as_ptr()).flags,
|
||||
&Rect::Text(ref t) => (*t.as_ptr()).flags,
|
||||
&Rect::Ass(ref a) => (*a.as_ptr()).flags
|
||||
})
|
||||
if self.cur >= (*self.ptr).num_rects {
|
||||
None
|
||||
}
|
||||
else {
|
||||
self.cur += 1;
|
||||
Some(RectMut::wrap(*(*self.ptr).rects.offset((self.cur - 1) as isize)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bitmap<'a> {
|
||||
ptr: *mut AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Bitmap<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
Bitmap { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr as *const _
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Bitmap<'a> {
|
||||
pub fn x(&self) -> usize {
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
unsafe {
|
||||
(*self.as_ptr()).x as usize
|
||||
}
|
||||
}
|
||||
let length = (*self.ptr).num_rects as usize;
|
||||
|
||||
pub fn y(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.as_ptr()).y as usize
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
unsafe {
|
||||
(*self.as_ptr()).w as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
unsafe {
|
||||
(*self.as_ptr()).h as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn colors(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.as_ptr()).nb_colors as usize
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: verify safety
|
||||
pub fn picture(&self, format: format::Pixel) -> Picture<'a> {
|
||||
unsafe {
|
||||
Picture::wrap(&(*self.as_ptr()).pict as *const _ as *mut _, format, (*self.as_ptr()).w as u32, (*self.as_ptr()).h as u32)
|
||||
(length - self.cur as usize, Some(length - self.cur as usize))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Text<'a> {
|
||||
ptr: *mut AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Text<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
Text { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr as *const _
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for Text<'a> {
|
||||
type Target = str;
|
||||
|
||||
fn deref<'b>(&'b self) -> &'b str {
|
||||
unsafe {
|
||||
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ass<'a> {
|
||||
ptr: *mut AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Ass<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
Ass { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr as *const _
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for Ass<'a> {
|
||||
type Target = str;
|
||||
|
||||
fn deref<'b>(&'b self) -> &'b str {
|
||||
unsafe {
|
||||
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> ExactSizeIterator for RectMutIter<'a> { }
|
||||
|
150
src/codec/subtitle/rect.rs
Normal file
150
src/codec/subtitle/rect.rs
Normal file
@ -0,0 +1,150 @@
|
||||
use std::marker::PhantomData;
|
||||
use std::ffi::CStr;
|
||||
use std::str::from_utf8_unchecked;
|
||||
|
||||
use ffi::*;
|
||||
use super::{Type, Flags};
|
||||
use ::{format, Picture};
|
||||
|
||||
pub enum Rect<'a> {
|
||||
None(*const AVSubtitleRect),
|
||||
Bitmap(Bitmap<'a>),
|
||||
Text(Text<'a>),
|
||||
Ass(Ass<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Rect<'a> {
|
||||
pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
|
||||
match Type::from((*ptr).kind) {
|
||||
Type::None => Rect::None(ptr),
|
||||
Type::Bitmap => Rect::Bitmap(Bitmap::wrap(ptr)),
|
||||
Type::Text => Rect::Text(Text::wrap(ptr)),
|
||||
Type::Ass => Rect::Ass(Ass::wrap(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
match self {
|
||||
&Rect::None(ptr) => ptr,
|
||||
&Rect::Bitmap(ref b) => b.as_ptr(),
|
||||
&Rect::Text(ref t) => t.as_ptr(),
|
||||
&Rect::Ass(ref a) => a.as_ptr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Rect<'a> {
|
||||
pub fn flags(&self) -> Flags {
|
||||
unsafe {
|
||||
Flags::from_bits_truncate(match self {
|
||||
&Rect::None(ptr) => (*ptr).flags,
|
||||
&Rect::Bitmap(ref b) => (*b.as_ptr()).flags,
|
||||
&Rect::Text(ref t) => (*t.as_ptr()).flags,
|
||||
&Rect::Ass(ref a) => (*a.as_ptr()).flags
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Bitmap<'a> {
|
||||
ptr: *const AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Bitmap<'a> {
|
||||
pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
|
||||
Bitmap { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Bitmap<'a> {
|
||||
pub fn x(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.as_ptr()).x as usize
|
||||
}
|
||||
}
|
||||
|
||||
pub fn y(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.as_ptr()).y as usize
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
unsafe {
|
||||
(*self.as_ptr()).w as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
unsafe {
|
||||
(*self.as_ptr()).h as u32
|
||||
}
|
||||
}
|
||||
|
||||
pub fn colors(&self) -> usize {
|
||||
unsafe {
|
||||
(*self.as_ptr()).nb_colors as usize
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: must split Picture and PictureMut
|
||||
pub fn picture(&self, format: format::Pixel) -> Picture<'a> {
|
||||
unsafe {
|
||||
Picture::wrap(&(*self.as_ptr()).pict as *const _ as *mut _, format, (*self.as_ptr()).w as u32, (*self.as_ptr()).h as u32)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Text<'a> {
|
||||
ptr: *const AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Text<'a> {
|
||||
pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
|
||||
Text { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Text<'a> {
|
||||
pub fn get(&self) -> &str {
|
||||
unsafe {
|
||||
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Ass<'a> {
|
||||
ptr: *const AVSubtitleRect,
|
||||
|
||||
_marker: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> Ass<'a> {
|
||||
pub unsafe fn wrap(ptr: *const AVSubtitleRect) -> Self {
|
||||
Ass { ptr: ptr, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Ass<'a> {
|
||||
pub fn get(&self) -> &str {
|
||||
unsafe {
|
||||
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes())
|
||||
}
|
||||
}
|
||||
}
|
173
src/codec/subtitle/rect_mut.rs
Normal file
173
src/codec/subtitle/rect_mut.rs
Normal file
@ -0,0 +1,173 @@
|
||||
use std::ops::Deref;
|
||||
use std::ffi::CString;
|
||||
|
||||
use libc::c_int;
|
||||
use ffi::*;
|
||||
use super::{Type, Flags, Bitmap, Text, Ass};
|
||||
|
||||
pub enum RectMut<'a> {
|
||||
None(*mut AVSubtitleRect),
|
||||
Bitmap(BitmapMut<'a>),
|
||||
Text(TextMut<'a>),
|
||||
Ass(AssMut<'a>),
|
||||
}
|
||||
|
||||
impl<'a> RectMut<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
match Type::from((*ptr).kind) {
|
||||
Type::None => RectMut::None(ptr),
|
||||
Type::Bitmap => RectMut::Bitmap(BitmapMut::wrap(ptr)),
|
||||
Type::Text => RectMut::Text(TextMut::wrap(ptr)),
|
||||
Type::Ass => RectMut::Ass(AssMut::wrap(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_ptr(&self) -> *const AVSubtitleRect {
|
||||
match self {
|
||||
&RectMut::None(ptr) => ptr as *const _,
|
||||
&RectMut::Bitmap(ref b) => b.as_ptr(),
|
||||
&RectMut::Text(ref t) => t.as_ptr(),
|
||||
&RectMut::Ass(ref a) => a.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
match self {
|
||||
&mut RectMut::None(ptr) => ptr,
|
||||
&mut RectMut::Bitmap(ref mut b) => b.as_mut_ptr(),
|
||||
&mut RectMut::Text(ref mut t) => t.as_mut_ptr(),
|
||||
&mut RectMut::Ass(ref mut a) => a.as_mut_ptr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RectMut<'a> {
|
||||
pub fn flags(&self) -> Flags {
|
||||
unsafe {
|
||||
Flags::from_bits_truncate(match self {
|
||||
&RectMut::None(ptr) => (*ptr).flags,
|
||||
&RectMut::Bitmap(ref b) => (*b.as_ptr()).flags,
|
||||
&RectMut::Text(ref t) => (*t.as_ptr()).flags,
|
||||
&RectMut::Ass(ref a) => (*a.as_ptr()).flags
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BitmapMut<'a> {
|
||||
immutable: Bitmap<'a>,
|
||||
}
|
||||
|
||||
impl<'a> BitmapMut<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
BitmapMut { immutable: Bitmap::wrap(ptr as *const _) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.as_ptr() as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> BitmapMut<'a> {
|
||||
pub fn set_x(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).x = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_y(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).y = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_width(&mut self, value: u32) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).w = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_height(&mut self, value: u32) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).h = value as c_int;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_colors(&mut self, value: usize) {
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).nb_colors = value as c_int;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for BitmapMut<'a> {
|
||||
type Target = Bitmap<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.immutable
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TextMut<'a> {
|
||||
immutable: Text<'a>,
|
||||
}
|
||||
|
||||
impl<'a> TextMut<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
TextMut { immutable: Text::wrap(ptr as *const _) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.as_ptr() as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TextMut<'a> {
|
||||
pub fn set(&mut self, value: &str) {
|
||||
let value = CString::new(value).unwrap();
|
||||
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).text = av_strdup(value.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for TextMut<'a> {
|
||||
type Target = Text<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.immutable
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AssMut<'a> {
|
||||
immutable: Ass<'a>,
|
||||
}
|
||||
|
||||
impl<'a> AssMut<'a> {
|
||||
pub unsafe fn wrap(ptr: *mut AVSubtitleRect) -> Self {
|
||||
AssMut { immutable: Ass::wrap(ptr) }
|
||||
}
|
||||
|
||||
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVSubtitleRect {
|
||||
self.as_ptr() as *mut _
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AssMut<'a> {
|
||||
pub fn set(&mut self, value: &str) {
|
||||
let value = CString::new(value).unwrap();
|
||||
|
||||
unsafe {
|
||||
(*self.as_mut_ptr()).ass = av_strdup(value.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for AssMut<'a> {
|
||||
type Target = Ass<'a>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.immutable
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user