software/scaling: add software scaling feature
This commit is contained in:
parent
6c8a8f2edd
commit
8ceac13065
18
Cargo.toml
18
Cargo.toml
@ -5,16 +5,16 @@ authors = ["meh. <meh@schizofreni.co>"]
|
|||||||
license = "WTFPL"
|
license = "WTFPL"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["codec", "device", "filter", "format", "resample", "postprocessing", "software-resample", "software-scaling"]
|
default = ["codec", "device", "filter", "format", "resampling", "postprocessing", "software-resampling", "software-scaling"]
|
||||||
|
|
||||||
codec = ["ffmpeg-sys/avcodec"]
|
codec = ["ffmpeg-sys/avcodec"]
|
||||||
device = ["ffmpeg-sys/avdevice", "format"]
|
device = ["ffmpeg-sys/avdevice", "format"]
|
||||||
filter = ["ffmpeg-sys/avfilter"]
|
filter = ["ffmpeg-sys/avfilter"]
|
||||||
format = ["ffmpeg-sys/avformat", "codec"]
|
format = ["ffmpeg-sys/avformat", "codec"]
|
||||||
resample = ["ffmpeg-sys/avresample"]
|
resampling = ["ffmpeg-sys/avresample"]
|
||||||
postprocessing = ["ffmpeg-sys/postproc"]
|
postprocessing = ["ffmpeg-sys/postproc"]
|
||||||
software-resample = ["ffmpeg-sys/swresample"]
|
software-resampling = ["ffmpeg-sys/swresample"]
|
||||||
software-scaling = ["ffmpeg-sys/swscale"]
|
software-scaling = ["ffmpeg-sys/swscale", "codec"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
|
@ -47,6 +47,8 @@ pub use codec::threading;
|
|||||||
#[cfg(feature = "device")]
|
#[cfg(feature = "device")]
|
||||||
pub mod device;
|
pub mod device;
|
||||||
|
|
||||||
|
pub mod software;
|
||||||
|
|
||||||
fn init_error() {
|
fn init_error() {
|
||||||
util::error::register_all();
|
util::error::register_all();
|
||||||
}
|
}
|
||||||
|
2
src/software/mod.rs
Normal file
2
src/software/mod.rs
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#[cfg(feature = "software-scaling")]
|
||||||
|
pub mod scaling;
|
14
src/software/scaling/capability.rs
Normal file
14
src/software/scaling/capability.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use libc::c_uint;
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
flags Capabilities: c_uint {
|
||||||
|
const MMX = SWS_CPU_CAPS_MMX,
|
||||||
|
const MMXEXT = SWS_CPU_CAPS_MMXEXT,
|
||||||
|
const MMX2 = SWS_CPU_CAPS_MMX2,
|
||||||
|
const _3DNOW = SWS_CPU_CAPS_3DNOW,
|
||||||
|
const ALTIVEC = SWS_CPU_CAPS_ALTIVEC,
|
||||||
|
const BFIN = SWS_CPU_CAPS_BFIN,
|
||||||
|
const SSE2 = SWS_CPU_CAPS_SSE2,
|
||||||
|
}
|
||||||
|
}
|
41
src/software/scaling/color_space.rs
Normal file
41
src/software/scaling/color_space.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use libc::c_int;
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
||||||
|
pub enum ColorSpace {
|
||||||
|
Default,
|
||||||
|
|
||||||
|
ITU709,
|
||||||
|
FCC,
|
||||||
|
ITU601,
|
||||||
|
ITU624,
|
||||||
|
SMPTE170M,
|
||||||
|
SMPTE240M,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<c_int> for ColorSpace {
|
||||||
|
fn from(value: c_int) -> ColorSpace {
|
||||||
|
match value {
|
||||||
|
SWS_CS_ITU709 => ColorSpace::ITU709,
|
||||||
|
SWS_CS_FCC => ColorSpace::FCC,
|
||||||
|
SWS_CS_DEFAULT => ColorSpace::Default,
|
||||||
|
SWS_CS_SMPTE240M => ColorSpace::SMPTE240M,
|
||||||
|
|
||||||
|
_ => ColorSpace::Default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<c_int> for ColorSpace {
|
||||||
|
fn into(self) -> c_int {
|
||||||
|
match self {
|
||||||
|
ColorSpace::Default => SWS_CS_DEFAULT,
|
||||||
|
ColorSpace::ITU709 => SWS_CS_ITU709,
|
||||||
|
ColorSpace::FCC => SWS_CS_FCC,
|
||||||
|
ColorSpace::ITU601 => SWS_CS_ITU601,
|
||||||
|
ColorSpace::ITU624 => SWS_CS_ITU624,
|
||||||
|
ColorSpace::SMPTE170M => SWS_CS_SMPTE170M,
|
||||||
|
ColorSpace::SMPTE240M => SWS_CS_SMPTE240M
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
102
src/software/scaling/context.rs
Normal file
102
src/software/scaling/context.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use std::ptr;
|
||||||
|
|
||||||
|
use libc::{c_int};
|
||||||
|
use ffi::*;
|
||||||
|
use ::{Error, Picture};
|
||||||
|
use ::util::format;
|
||||||
|
use super::Flags;
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
pub ptr: *mut SwsContext,
|
||||||
|
|
||||||
|
input: Definition,
|
||||||
|
output: Definition,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||||
|
pub struct Definition {
|
||||||
|
pub format: format::Pixel,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub fn get(src_format: format::Pixel, src_w: u32, src_h: u32,
|
||||||
|
dst_format: format::Pixel, dst_w: u32, dst_h: u32,
|
||||||
|
flags: Flags) -> Result<Self, Error> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = sws_getContext(src_w as c_int, src_h as c_int, src_format.into(),
|
||||||
|
dst_w as c_int, dst_h as c_int, dst_format.into(),
|
||||||
|
flags.bits(),
|
||||||
|
ptr::null_mut(), ptr::null_mut(), ptr::null_mut());
|
||||||
|
|
||||||
|
if ptr != ptr::null_mut() {
|
||||||
|
Ok(Context {
|
||||||
|
ptr: ptr,
|
||||||
|
|
||||||
|
input: Definition {
|
||||||
|
format: src_format,
|
||||||
|
width: src_w,
|
||||||
|
height: src_h,
|
||||||
|
},
|
||||||
|
|
||||||
|
output: Definition {
|
||||||
|
format: dst_format,
|
||||||
|
width: dst_w,
|
||||||
|
height: dst_h,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Err(Error::InvalidData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cached(&mut self,
|
||||||
|
src_format: format::Pixel, src_w: u32, src_h: u32,
|
||||||
|
dst_format: format::Pixel, dst_w: u32, dst_h: u32,
|
||||||
|
flags: Flags) {
|
||||||
|
unsafe {
|
||||||
|
self.ptr = sws_getCachedContext(self.ptr,
|
||||||
|
src_w as c_int, src_h as c_int, src_format.into(),
|
||||||
|
dst_w as c_int, dst_h as c_int, dst_format.into(),
|
||||||
|
flags.bits(), ptr::null_mut(), ptr::null_mut(), ptr::null());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input(&self) -> &Definition {
|
||||||
|
&self.input
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(&self) -> &Definition {
|
||||||
|
&self.output
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&self, input: &Picture, output: &mut Picture) -> Result<(), Error> {
|
||||||
|
if input.format() != self.input.format || input.width() != self.input.width || input.height() != self.input.height {
|
||||||
|
return Err(Error::InputChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
if output.format() != self.output.format || output.width() != self.output.width || output.height() != self.output.height {
|
||||||
|
return Err(Error::OutputChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
sws_scale(self.ptr,
|
||||||
|
(*input.ptr).data.as_ptr() as *const *const _, (*input.ptr).linesize.as_ptr() as *const _,
|
||||||
|
0, self.output.height as c_int,
|
||||||
|
(*output.ptr).data.as_ptr() as *mut *mut _, (*output.ptr).linesize.as_ptr() as *mut _);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Context {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
sws_freeContext(self.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/software/scaling/extensions.rs
Normal file
35
src/software/scaling/extensions.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use libc::c_int;
|
||||||
|
use ffi::*;
|
||||||
|
use util::format;
|
||||||
|
use ::{Picture, decoder, Error};
|
||||||
|
use super::{Context, Flags, flag};
|
||||||
|
|
||||||
|
impl<'a> Picture<'a> {
|
||||||
|
pub fn scaler(&self, width: u32, height: u32, flags: Flags) -> Result<Context, Error> {
|
||||||
|
Context::get(self.format(), self.width(), self.height(),
|
||||||
|
self.format(), width, height,
|
||||||
|
flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn converter(&self, format: format::Pixel) -> Result<Context, Error> {
|
||||||
|
Context::get(self.format(), self.width(), self.height(),
|
||||||
|
format, self.width(), self.height(),
|
||||||
|
flag::FAST_BILINEAR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl decoder::Video {
|
||||||
|
pub fn scaler(&self, width: u32, height: u32, flags: Flags) -> Result<Context, Error> {
|
||||||
|
Context::get(self.format(), self.width(), self.height(),
|
||||||
|
self.format(), width, height,
|
||||||
|
flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn converter(&self, format: format::Pixel) -> Result<Context, Error> {
|
||||||
|
Context::get(self.format(), self.width(), self.height(),
|
||||||
|
format, self.width(), self.height(),
|
||||||
|
flag::FAST_BILINEAR)
|
||||||
|
}
|
||||||
|
}
|
80
src/software/scaling/filter.rs
Normal file
80
src/software/scaling/filter.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
use ffi::*;
|
||||||
|
use super::Vector;
|
||||||
|
|
||||||
|
pub struct Filter {
|
||||||
|
pub ptr: *mut SwsFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filter {
|
||||||
|
pub fn get(luma_g_blur: f32, chroma_g_blur: f32,
|
||||||
|
luma_sharpen: f32, chroma_sharpen: f32,
|
||||||
|
chroma_h_shift: f32, chroma_v_shift: f32) -> Self {
|
||||||
|
unsafe {
|
||||||
|
Filter {
|
||||||
|
ptr: sws_getDefaultFilter(luma_g_blur, chroma_g_blur,
|
||||||
|
luma_sharpen, chroma_sharpen,
|
||||||
|
chroma_h_shift, chroma_v_shift, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::get(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn luma_horizontal(&self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn luma_horizontal_mut(&mut self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn luma_vertical(&self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn luma_vertical_mut(&mut self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chroma_horizontal(&self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chroma_horizontal_mut(&mut self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chroma_vertical(&self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn chroma_vertical_mut(&mut self) -> Vector {
|
||||||
|
unsafe {
|
||||||
|
Vector::wrap((*self.ptr).lumV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Filter {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
sws_freeFilter(self.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
src/software/scaling/flag.rs
Normal file
28
src/software/scaling/flag.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use libc::c_int;
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
flags Flags: c_int {
|
||||||
|
const FAST_BILINEAR = SWS_FAST_BILINEAR,
|
||||||
|
const BILINEAR = SWS_BILINEAR,
|
||||||
|
const BICUBIC = SWS_BICUBIC,
|
||||||
|
const X = SWS_X,
|
||||||
|
const POINT = SWS_POINT,
|
||||||
|
const AREA = SWS_AREA,
|
||||||
|
const BICUBLIN = SWS_BICUBLIN,
|
||||||
|
const GAUSS = SWS_GAUSS,
|
||||||
|
const SINC = SWS_SINC,
|
||||||
|
const LANCZOS = SWS_LANCZOS,
|
||||||
|
const SPLINE = SWS_SPLINE,
|
||||||
|
const SRC_V_CHR_DROP_MASK = SWS_SRC_V_CHR_DROP_MASK,
|
||||||
|
const SRC_V_CHR_DROP_SHIFT = SWS_SRC_V_CHR_DROP_SHIFT,
|
||||||
|
const PARAM_DEFAULT = SWS_PARAM_DEFAULT,
|
||||||
|
const PRINT_INFO = SWS_PRINT_INFO,
|
||||||
|
const FULL_CHR_H_INT = SWS_FULL_CHR_H_INT,
|
||||||
|
const FULL_CHR_H_INP = SWS_FULL_CHR_H_INP,
|
||||||
|
const DIRECT_BGR = SWS_DIRECT_BGR,
|
||||||
|
const ACCURATE_RND = SWS_ACCURATE_RND,
|
||||||
|
const BITEXACT = SWS_BITEXACT,
|
||||||
|
const ERROR_DIFFUSION = SWS_ERROR_DIFFUSION,
|
||||||
|
}
|
||||||
|
}
|
44
src/software/scaling/mod.rs
Normal file
44
src/software/scaling/mod.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
pub mod flag;
|
||||||
|
pub use self::flag::Flags;
|
||||||
|
|
||||||
|
pub mod capability;
|
||||||
|
pub use self::capability::Capabilities;
|
||||||
|
|
||||||
|
pub mod color_space;
|
||||||
|
pub use self::color_space::ColorSpace;
|
||||||
|
|
||||||
|
pub mod support;
|
||||||
|
|
||||||
|
pub mod vector;
|
||||||
|
pub use self::vector::Vector;
|
||||||
|
|
||||||
|
pub mod filter;
|
||||||
|
pub use self::filter::Filter;
|
||||||
|
|
||||||
|
pub mod context;
|
||||||
|
pub use self::context::Context;
|
||||||
|
|
||||||
|
mod extensions;
|
||||||
|
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
pub fn version() -> u32 {
|
||||||
|
unsafe {
|
||||||
|
swscale_version()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn configuration() -> &'static str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr(swscale_configuration()).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn license() -> &'static str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr(swscale_license()).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
20
src/software/scaling/support.rs
Normal file
20
src/software/scaling/support.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use ffi::*;
|
||||||
|
use ::util::format;
|
||||||
|
|
||||||
|
pub fn input(format: format::Pixel) -> bool {
|
||||||
|
unsafe {
|
||||||
|
sws_isSupportedInput(format.into()) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(format: format::Pixel) -> bool {
|
||||||
|
unsafe {
|
||||||
|
sws_isSupportedOutput(format.into()) != 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn endianness_conversion(format: format::Pixel) -> bool {
|
||||||
|
unsafe {
|
||||||
|
sws_isSupportedEndiannessConversion(format.into()) != 0
|
||||||
|
}
|
||||||
|
}
|
108
src/software/scaling/vector.rs
Normal file
108
src/software/scaling/vector.rs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::slice;
|
||||||
|
|
||||||
|
use libc::{c_int, c_double};
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
pub struct Vector<'a> {
|
||||||
|
pub ptr: *mut SwsVector,
|
||||||
|
|
||||||
|
_own: bool,
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Vector<'a> {
|
||||||
|
pub fn wrap(ptr: *mut SwsVector) -> Self {
|
||||||
|
Vector { ptr: ptr, _own: false, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(length: usize) -> Self {
|
||||||
|
unsafe {
|
||||||
|
Vector { ptr: sws_allocVec(length as c_int), _own: true, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gaussian(variance: f64, quality: f64) -> Self {
|
||||||
|
unsafe {
|
||||||
|
Vector { ptr: sws_getGaussianVec(variance as c_double, quality as c_double), _own: true, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(value: f64, length: usize) -> Self {
|
||||||
|
unsafe {
|
||||||
|
Vector { ptr: sws_getConstVec(value as c_double, length as c_int), _own: true, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn identity() -> Self {
|
||||||
|
unsafe {
|
||||||
|
Vector { ptr: sws_getIdentityVec(), _own: true, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scale(&mut self, scalar: f64) {
|
||||||
|
unsafe {
|
||||||
|
sws_scaleVec(self.ptr, scalar as c_double);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn normalize(&mut self, height: f64) {
|
||||||
|
unsafe {
|
||||||
|
sws_normalizeVec(self.ptr, height as c_double);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn conv(&mut self, other: &Vector) {
|
||||||
|
unsafe {
|
||||||
|
sws_convVec(self.ptr, other.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, other: &Vector) {
|
||||||
|
unsafe {
|
||||||
|
sws_addVec(self.ptr, other.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sub(&mut self, other: &Vector) {
|
||||||
|
unsafe {
|
||||||
|
sws_subVec(self.ptr, other.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shift(&mut self, value: usize) {
|
||||||
|
unsafe {
|
||||||
|
sws_shiftVec(self.ptr, value as c_int);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn coefficients(&self) -> &[f64] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts((*self.ptr).coeff, (*self.ptr).length as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn coefficients_mut(&self) -> &[f64] {
|
||||||
|
unsafe {
|
||||||
|
slice::from_raw_parts_mut((*self.ptr).coeff, (*self.ptr).length as usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Clone for Vector<'a> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
unsafe {
|
||||||
|
Vector { ptr: sws_cloneVec(self.ptr), _own: true, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Drop for Vector<'a> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
if self._own {
|
||||||
|
sws_freeVec(self.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user