Skip to main content

core_video/
image_buffer.rs

1use std::mem;
2
3use core_foundation::{
4    base::{Boolean, CFGetTypeID, CFType, CFTypeID, CFTypeRef, TCFType, TCFTypeRef},
5    declare_TCFType,
6    dictionary::{CFDictionary, CFDictionaryRef},
7    impl_CFTypeDescription,
8    string::{CFString, CFStringRef},
9};
10use core_graphics::{
11    color_space::{CGColorSpace, CGColorSpaceRef},
12    geometry::{CGRect, CGSize},
13};
14use libc::c_void;
15
16use crate::buffer::{CVBuffer, CVBufferRef, CVBufferRetain, TCVBuffer};
17
18pub type CVImageBufferRef = CVBufferRef;
19
20extern "C" {
21    pub static kCVImageBufferCGColorSpaceKey: CFStringRef;
22    pub static kCVImageBufferCleanApertureKey: CFStringRef;
23    pub static kCVImageBufferCleanApertureWidthKey: CFStringRef;
24    pub static kCVImageBufferCleanApertureHeightKey: CFStringRef;
25    pub static kCVImageBufferCleanApertureHorizontalOffsetKey: CFStringRef;
26    pub static kCVImageBufferCleanApertureVerticalOffsetKey: CFStringRef;
27    pub static kCVImageBufferPreferredCleanApertureKey: CFStringRef;
28    pub static kCVImageBufferFieldCountKey: CFStringRef;
29    pub static kCVImageBufferFieldDetailKey: CFStringRef;
30    pub static kCVImageBufferFieldDetailTemporalTopFirst: CFStringRef;
31    pub static kCVImageBufferFieldDetailTemporalBottomFirst: CFStringRef;
32    pub static kCVImageBufferFieldDetailSpatialFirstLineEarly: CFStringRef;
33    pub static kCVImageBufferFieldDetailSpatialFirstLineLate: CFStringRef;
34    pub static kCVImageBufferPixelAspectRatioKey: CFStringRef;
35    pub static kCVImageBufferPixelAspectRatioHorizontalSpacingKey: CFStringRef;
36    pub static kCVImageBufferPixelAspectRatioVerticalSpacingKey: CFStringRef;
37    pub static kCVImageBufferDisplayDimensionsKey: CFStringRef;
38    pub static kCVImageBufferDisplayWidthKey: CFStringRef;
39    pub static kCVImageBufferDisplayHeightKey: CFStringRef;
40    pub static kCVImageBufferGammaLevelKey: CFStringRef;
41    pub static kCVImageBufferICCProfileKey: CFStringRef;
42    pub static kCVImageBufferYCbCrMatrixKey: CFStringRef;
43    pub static kCVImageBufferYCbCrMatrix_ITU_R_709_2: CFStringRef;
44    pub static kCVImageBufferYCbCrMatrix_ITU_R_601_4: CFStringRef;
45    pub static kCVImageBufferYCbCrMatrix_SMPTE_240M_1995: CFStringRef;
46    pub static kCVImageBufferYCbCrMatrix_DCI_P3: CFStringRef;
47    pub static kCVImageBufferYCbCrMatrix_P3_D65: CFStringRef;
48    pub static kCVImageBufferYCbCrMatrix_ITU_R_2020: CFStringRef;
49    pub static kCVImageBufferColorPrimariesKey: CFStringRef;
50    pub static kCVImageBufferColorPrimaries_ITU_R_709_2: CFStringRef;
51    pub static kCVImageBufferColorPrimaries_EBU_3213: CFStringRef;
52    pub static kCVImageBufferColorPrimaries_SMPTE_C: CFStringRef;
53    pub static kCVImageBufferColorPrimaries_P22: CFStringRef;
54    pub static kCVImageBufferColorPrimaries_DCI_P3: CFStringRef;
55    pub static kCVImageBufferColorPrimaries_P3_D65: CFStringRef;
56    pub static kCVImageBufferColorPrimaries_ITU_R_2020: CFStringRef;
57    pub static kCVImageBufferTransferFunctionKey: CFStringRef;
58    pub static kCVImageBufferTransferFunction_ITU_R_709_2: CFStringRef;
59    pub static kCVImageBufferTransferFunction_SMPTE_240M_1995: CFStringRef;
60    pub static kCVImageBufferTransferFunction_UseGamma: CFStringRef;
61    pub static kCVImageBufferTransferFunction_sRGB: CFStringRef;
62    pub static kCVImageBufferTransferFunction_ITU_R_2020: CFStringRef;
63    pub static kCVImageBufferTransferFunction_SMPTE_ST_428_1: CFStringRef;
64    pub static kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ: CFStringRef;
65    pub static kCVImageBufferTransferFunction_ITU_R_2100_HLG: CFStringRef;
66    pub static kCVImageBufferTransferFunction_Linear: CFStringRef;
67    pub static kCVImageBufferChromaLocationTopFieldKey: CFStringRef;
68    pub static kCVImageBufferChromaLocationBottomFieldKey: CFStringRef;
69    pub static kCVImageBufferChromaLocation_Left: CFStringRef;
70    pub static kCVImageBufferChromaLocation_Center: CFStringRef;
71    pub static kCVImageBufferChromaLocation_TopLeft: CFStringRef;
72    pub static kCVImageBufferChromaLocation_Top: CFStringRef;
73    pub static kCVImageBufferChromaLocation_BottomLeft: CFStringRef;
74    pub static kCVImageBufferChromaLocation_Bottom: CFStringRef;
75    pub static kCVImageBufferChromaLocation_DV420: CFStringRef;
76    pub static kCVImageBufferChromaSubsamplingKey: CFStringRef;
77    pub static kCVImageBufferChromaSubsampling_420: CFStringRef;
78    pub static kCVImageBufferChromaSubsampling_422: CFStringRef;
79    pub static kCVImageBufferChromaSubsampling_411: CFStringRef;
80    pub static kCVImageBufferAlphaChannelIsOpaque: CFStringRef;
81    pub static kCVImageBufferAlphaChannelModeKey: CFStringRef;
82    pub static kCVImageBufferAlphaChannelMode_StraightAlpha: CFStringRef;
83    pub static kCVImageBufferAlphaChannelMode_PremultipliedAlpha: CFStringRef;
84
85    pub fn CVYCbCrMatrixGetIntegerCodePointForString(yCbCrMatrixString: CFStringRef) -> i32;
86    pub fn CVColorPrimariesGetIntegerCodePointForString(colorPrimariesString: CFStringRef) -> i32;
87    pub fn CVTransferFunctionGetIntegerCodePointForString(transferFunctionString: CFStringRef) -> i32;
88    pub fn CVYCbCrMatrixGetStringForIntegerCodePoint(yCbCrMatrixCodePoint: i32) -> CFStringRef;
89    pub fn CVColorPrimariesGetStringForIntegerCodePoint(colorPrimariesCodePoint: i32) -> CFStringRef;
90    pub fn CVTransferFunctionGetStringForIntegerCodePoint(transferFunctionCodePoint: i32) -> CFStringRef;
91
92    pub fn CVImageBufferGetEncodedSize(imageBuffer: CVImageBufferRef) -> CGSize;
93    pub fn CVImageBufferGetDisplaySize(imageBuffer: CVImageBufferRef) -> CGSize;
94    pub fn CVImageBufferGetCleanRect(imageBuffer: CVImageBufferRef) -> CGRect;
95    pub fn CVImageBufferIsFlipped(imageBuffer: CVImageBufferRef) -> Boolean;
96    pub fn CVImageBufferGetColorSpace(imageBuffer: CVImageBufferRef) -> CGColorSpaceRef;
97    pub fn CVImageBufferCreateColorSpaceFromAttachments(attachments: CFDictionaryRef) -> CGColorSpaceRef;
98
99    pub static kCVImageBufferMasteringDisplayColorVolumeKey: CFStringRef;
100    pub static kCVImageBufferContentLightLevelInfoKey: CFStringRef;
101    pub static kCVImageBufferAmbientViewingEnvironmentKey: CFStringRef;
102    pub static kCVImageBufferRegionOfInterestKey: CFStringRef;
103}
104
105pub enum CVImageBufferKeys {
106    CGColorSpace,
107    CleanAperture,
108    PreferredCleanAperture,
109    FieldCount,
110    FieldDetail,
111    PixelAspectRatio,
112    DisplayDimensions,
113    GammaLevel,
114    ICCProfile,
115    YCbCrMatrix,
116    ColorPrimaries,
117    TransferFunction,
118    ChromaLocationTopField,
119    ChromaLocationBottomField,
120    ChromaSubsampling,
121    AlphaChannelIsOpaque,
122    AlphaChannelMode,
123    MasteringDisplayColorVolume,
124    ContentLightLevelInfo,
125    AmbientViewingEnvironment,
126    RegionOfInterest,
127}
128
129impl From<CVImageBufferKeys> for CFStringRef {
130    fn from(key: CVImageBufferKeys) -> CFStringRef {
131        unsafe {
132            match key {
133                CVImageBufferKeys::CGColorSpace => kCVImageBufferCGColorSpaceKey,
134                CVImageBufferKeys::CleanAperture => kCVImageBufferCleanApertureKey,
135                CVImageBufferKeys::PreferredCleanAperture => kCVImageBufferPreferredCleanApertureKey,
136                CVImageBufferKeys::FieldCount => kCVImageBufferFieldCountKey,
137                CVImageBufferKeys::FieldDetail => kCVImageBufferFieldDetailKey,
138                CVImageBufferKeys::PixelAspectRatio => kCVImageBufferPixelAspectRatioKey,
139                CVImageBufferKeys::DisplayDimensions => kCVImageBufferDisplayDimensionsKey,
140                CVImageBufferKeys::GammaLevel => kCVImageBufferGammaLevelKey,
141                CVImageBufferKeys::ICCProfile => kCVImageBufferICCProfileKey,
142                CVImageBufferKeys::YCbCrMatrix => kCVImageBufferYCbCrMatrixKey,
143                CVImageBufferKeys::ColorPrimaries => kCVImageBufferColorPrimariesKey,
144                CVImageBufferKeys::TransferFunction => kCVImageBufferTransferFunctionKey,
145                CVImageBufferKeys::ChromaLocationTopField => kCVImageBufferChromaLocationTopFieldKey,
146                CVImageBufferKeys::ChromaLocationBottomField => kCVImageBufferChromaLocationBottomFieldKey,
147                CVImageBufferKeys::ChromaSubsampling => kCVImageBufferChromaSubsamplingKey,
148                CVImageBufferKeys::AlphaChannelIsOpaque => kCVImageBufferAlphaChannelIsOpaque,
149                CVImageBufferKeys::AlphaChannelMode => kCVImageBufferAlphaChannelModeKey,
150                CVImageBufferKeys::MasteringDisplayColorVolume => kCVImageBufferMasteringDisplayColorVolumeKey,
151                CVImageBufferKeys::ContentLightLevelInfo => kCVImageBufferContentLightLevelInfoKey,
152                CVImageBufferKeys::AmbientViewingEnvironment => kCVImageBufferAmbientViewingEnvironmentKey,
153                CVImageBufferKeys::RegionOfInterest => kCVImageBufferRegionOfInterestKey,
154            }
155        }
156    }
157}
158
159impl From<CVImageBufferKeys> for CFString {
160    fn from(key: CVImageBufferKeys) -> CFString {
161        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
162    }
163}
164
165pub enum CVImageBufferFieldDetail {
166    TemporalTopFirst,
167    TemporalBottomFirst,
168    SpatialFirstLineEarly,
169    SpatialFirstLineLate,
170}
171
172impl From<CVImageBufferFieldDetail> for CFStringRef {
173    fn from(field_detail: CVImageBufferFieldDetail) -> CFStringRef {
174        unsafe {
175            match field_detail {
176                CVImageBufferFieldDetail::TemporalTopFirst => kCVImageBufferFieldDetailTemporalTopFirst,
177                CVImageBufferFieldDetail::TemporalBottomFirst => kCVImageBufferFieldDetailTemporalBottomFirst,
178                CVImageBufferFieldDetail::SpatialFirstLineEarly => kCVImageBufferFieldDetailSpatialFirstLineEarly,
179                CVImageBufferFieldDetail::SpatialFirstLineLate => kCVImageBufferFieldDetailSpatialFirstLineLate,
180            }
181        }
182    }
183}
184
185impl From<CVImageBufferFieldDetail> for CFString {
186    fn from(field_detail: CVImageBufferFieldDetail) -> CFString {
187        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(field_detail)) }
188    }
189}
190
191pub enum CVImageBufferPixelAspectRatio {
192    HorizontalSpacing,
193    VerticalSpacing,
194}
195
196impl From<CVImageBufferPixelAspectRatio> for CFStringRef {
197    fn from(pixel_aspect_ratio: CVImageBufferPixelAspectRatio) -> CFStringRef {
198        unsafe {
199            match pixel_aspect_ratio {
200                CVImageBufferPixelAspectRatio::HorizontalSpacing => kCVImageBufferPixelAspectRatioHorizontalSpacingKey,
201                CVImageBufferPixelAspectRatio::VerticalSpacing => kCVImageBufferPixelAspectRatioVerticalSpacingKey,
202            }
203        }
204    }
205}
206
207impl From<CVImageBufferPixelAspectRatio> for CFString {
208    fn from(pixel_aspect_ratio: CVImageBufferPixelAspectRatio) -> CFString {
209        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(pixel_aspect_ratio)) }
210    }
211}
212
213pub enum CVImageBufferYCbCrMatrix {
214    ITU_R_709_2,
215    ITU_R_601_4,
216    SMPTE_240M_1995,
217    DCI_P3,
218    P3_D65,
219    ITU_R_2020,
220}
221
222impl From<CVImageBufferYCbCrMatrix> for CFStringRef {
223    fn from(ycbcr_matrix: CVImageBufferYCbCrMatrix) -> CFStringRef {
224        unsafe {
225            match ycbcr_matrix {
226                CVImageBufferYCbCrMatrix::ITU_R_709_2 => kCVImageBufferYCbCrMatrix_ITU_R_709_2,
227                CVImageBufferYCbCrMatrix::ITU_R_601_4 => kCVImageBufferYCbCrMatrix_ITU_R_601_4,
228                CVImageBufferYCbCrMatrix::SMPTE_240M_1995 => kCVImageBufferYCbCrMatrix_SMPTE_240M_1995,
229                CVImageBufferYCbCrMatrix::DCI_P3 => kCVImageBufferYCbCrMatrix_DCI_P3,
230                CVImageBufferYCbCrMatrix::P3_D65 => kCVImageBufferYCbCrMatrix_P3_D65,
231                CVImageBufferYCbCrMatrix::ITU_R_2020 => kCVImageBufferYCbCrMatrix_ITU_R_2020,
232            }
233        }
234    }
235}
236
237impl From<CVImageBufferYCbCrMatrix> for CFString {
238    fn from(ycbcr_matrix: CVImageBufferYCbCrMatrix) -> CFString {
239        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(ycbcr_matrix)) }
240    }
241}
242
243pub enum CVImageBufferColorPrimaries {
244    ITU_R_709_2,
245    EBU_3213,
246    SMPTE_C,
247    P22,
248    DCI_P3,
249    P3_D65,
250    ITU_R_2020,
251}
252
253impl From<CVImageBufferColorPrimaries> for CFStringRef {
254    fn from(color_primaries: CVImageBufferColorPrimaries) -> CFStringRef {
255        unsafe {
256            match color_primaries {
257                CVImageBufferColorPrimaries::ITU_R_709_2 => kCVImageBufferColorPrimaries_ITU_R_709_2,
258                CVImageBufferColorPrimaries::EBU_3213 => kCVImageBufferColorPrimaries_EBU_3213,
259                CVImageBufferColorPrimaries::SMPTE_C => kCVImageBufferColorPrimaries_SMPTE_C,
260                CVImageBufferColorPrimaries::P22 => kCVImageBufferColorPrimaries_P22,
261                CVImageBufferColorPrimaries::DCI_P3 => kCVImageBufferColorPrimaries_DCI_P3,
262                CVImageBufferColorPrimaries::P3_D65 => kCVImageBufferColorPrimaries_P3_D65,
263                CVImageBufferColorPrimaries::ITU_R_2020 => kCVImageBufferColorPrimaries_ITU_R_2020,
264            }
265        }
266    }
267}
268
269impl From<CVImageBufferColorPrimaries> for CFString {
270    fn from(color_primaries: CVImageBufferColorPrimaries) -> CFString {
271        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(color_primaries)) }
272    }
273}
274
275pub enum CVImageBufferTransferFunction {
276    ITU_R_709_2,
277    SMPTE_240M_1995,
278    UseGamma,
279    sRGB,
280    ITU_R_2020,
281    SMPTE_ST_428_1,
282    SMPTE_ST_2084_PQ,
283    ITU_R_2100_HLG,
284    Linear,
285}
286
287impl From<CVImageBufferTransferFunction> for CFStringRef {
288    fn from(transfer_function: CVImageBufferTransferFunction) -> CFStringRef {
289        unsafe {
290            match transfer_function {
291                CVImageBufferTransferFunction::ITU_R_709_2 => kCVImageBufferTransferFunction_ITU_R_709_2,
292                CVImageBufferTransferFunction::SMPTE_240M_1995 => kCVImageBufferTransferFunction_SMPTE_240M_1995,
293                CVImageBufferTransferFunction::UseGamma => kCVImageBufferTransferFunction_UseGamma,
294                CVImageBufferTransferFunction::sRGB => kCVImageBufferTransferFunction_sRGB,
295                CVImageBufferTransferFunction::ITU_R_2020 => kCVImageBufferTransferFunction_ITU_R_2020,
296                CVImageBufferTransferFunction::SMPTE_ST_428_1 => kCVImageBufferTransferFunction_SMPTE_ST_428_1,
297                CVImageBufferTransferFunction::SMPTE_ST_2084_PQ => kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ,
298                CVImageBufferTransferFunction::ITU_R_2100_HLG => kCVImageBufferTransferFunction_ITU_R_2100_HLG,
299                CVImageBufferTransferFunction::Linear => kCVImageBufferTransferFunction_Linear,
300            }
301        }
302    }
303}
304
305impl From<CVImageBufferTransferFunction> for CFString {
306    fn from(transfer_function: CVImageBufferTransferFunction) -> CFString {
307        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(transfer_function)) }
308    }
309}
310
311pub enum CVImageBufferChromaLocation {
312    Left,
313    Center,
314    TopLeft,
315    Top,
316    BottomLeft,
317    Bottom,
318    DV420,
319}
320
321impl From<CVImageBufferChromaLocation> for CFStringRef {
322    fn from(chroma_location: CVImageBufferChromaLocation) -> CFStringRef {
323        unsafe {
324            match chroma_location {
325                CVImageBufferChromaLocation::Left => kCVImageBufferChromaLocation_Left,
326                CVImageBufferChromaLocation::Center => kCVImageBufferChromaLocation_Center,
327                CVImageBufferChromaLocation::TopLeft => kCVImageBufferChromaLocation_TopLeft,
328                CVImageBufferChromaLocation::Top => kCVImageBufferChromaLocation_Top,
329                CVImageBufferChromaLocation::BottomLeft => kCVImageBufferChromaLocation_BottomLeft,
330                CVImageBufferChromaLocation::Bottom => kCVImageBufferChromaLocation_Bottom,
331                CVImageBufferChromaLocation::DV420 => kCVImageBufferChromaLocation_DV420,
332            }
333        }
334    }
335}
336
337impl From<CVImageBufferChromaLocation> for CFString {
338    fn from(chroma_location: CVImageBufferChromaLocation) -> CFString {
339        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(chroma_location)) }
340    }
341}
342
343pub enum CVImageBufferChromaSubsampling {
344    CS420,
345    CS422,
346    CS411,
347}
348
349impl From<CVImageBufferChromaSubsampling> for CFStringRef {
350    fn from(chroma_subsampling: CVImageBufferChromaSubsampling) -> CFStringRef {
351        unsafe {
352            match chroma_subsampling {
353                CVImageBufferChromaSubsampling::CS420 => kCVImageBufferChromaSubsampling_420,
354                CVImageBufferChromaSubsampling::CS422 => kCVImageBufferChromaSubsampling_422,
355                CVImageBufferChromaSubsampling::CS411 => kCVImageBufferChromaSubsampling_411,
356            }
357        }
358    }
359}
360
361impl From<CVImageBufferChromaSubsampling> for CFString {
362    fn from(chroma_subsampling: CVImageBufferChromaSubsampling) -> CFString {
363        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(chroma_subsampling)) }
364    }
365}
366
367pub enum CVImageBufferAlphaChannelMode {
368    StraightAlpha,
369    PremultipliedAlpha,
370}
371
372impl From<CVImageBufferAlphaChannelMode> for CFStringRef {
373    fn from(alpha_channel_mode: CVImageBufferAlphaChannelMode) -> CFStringRef {
374        unsafe {
375            match alpha_channel_mode {
376                CVImageBufferAlphaChannelMode::StraightAlpha => kCVImageBufferAlphaChannelMode_StraightAlpha,
377                CVImageBufferAlphaChannelMode::PremultipliedAlpha => kCVImageBufferAlphaChannelMode_PremultipliedAlpha,
378            }
379        }
380    }
381}
382
383impl From<CVImageBufferAlphaChannelMode> for CFString {
384    fn from(alpha_channel_mode: CVImageBufferAlphaChannelMode) -> CFString {
385        unsafe { CFString::wrap_under_get_rule(CFStringRef::from(alpha_channel_mode)) }
386    }
387}
388
389pub fn ycbcr_matrix_get_integer_code_point_for_string(ycbcr_matrix_string: &CFString) -> i32 {
390    unsafe { CVYCbCrMatrixGetIntegerCodePointForString(ycbcr_matrix_string.as_concrete_TypeRef()) }
391}
392
393pub fn color_primaries_get_integer_code_point_for_string(color_primaries_string: &CFString) -> i32 {
394    unsafe { CVColorPrimariesGetIntegerCodePointForString(color_primaries_string.as_concrete_TypeRef()) }
395}
396
397pub fn transfer_function_get_integer_code_point_for_string(transfer_function_string: &CFString) -> i32 {
398    unsafe { CVTransferFunctionGetIntegerCodePointForString(transfer_function_string.as_concrete_TypeRef()) }
399}
400
401pub fn ycbcr_matrix_get_string_for_integer_code_point(ycbcr_matrix_code_point: i32) -> CFString {
402    unsafe { CFString::wrap_under_get_rule(CVYCbCrMatrixGetStringForIntegerCodePoint(ycbcr_matrix_code_point)) }
403}
404
405pub fn color_primaries_get_string_for_integer_code_point(color_primaries_code_point: i32) -> CFString {
406    unsafe { CFString::wrap_under_get_rule(CVColorPrimariesGetStringForIntegerCodePoint(color_primaries_code_point)) }
407}
408
409pub fn transfer_function_get_string_for_integer_code_point(transfer_function_code_point: i32) -> CFString {
410    unsafe { CFString::wrap_under_get_rule(CVTransferFunctionGetStringForIntegerCodePoint(transfer_function_code_point)) }
411}
412
413declare_TCFType!(CVImageBuffer, CVImageBufferRef);
414impl_CFTypeDescription!(CVImageBuffer);
415
416impl CVImageBuffer {
417    #[inline]
418    pub fn as_concrete_TypeRef(&self) -> CVImageBufferRef {
419        self.0
420    }
421
422    #[inline]
423    pub fn as_CFType(&self) -> CFType {
424        unsafe { CFType::wrap_under_get_rule(self.as_CFTypeRef()) }
425    }
426
427    #[inline]
428    pub fn as_CFTypeRef(&self) -> CFTypeRef {
429        self.as_concrete_TypeRef() as CFTypeRef
430    }
431
432    #[inline]
433    pub fn into_CFType(self) -> CFType {
434        let reference = self.as_CFTypeRef();
435        mem::forget(self);
436        unsafe { CFType::wrap_under_create_rule(reference) }
437    }
438
439    #[inline]
440    pub unsafe fn wrap_under_create_rule(reference: CVImageBufferRef) -> CVImageBuffer {
441        CVImageBuffer(reference)
442    }
443
444    #[inline]
445    pub unsafe fn wrap_under_get_rule(reference: CVImageBufferRef) -> CVImageBuffer {
446        CVImageBuffer(CVBufferRetain(reference))
447    }
448
449    #[inline]
450    pub fn type_of(&self) -> CFTypeID {
451        unsafe { CFGetTypeID(self.as_CFTypeRef()) }
452    }
453
454    #[inline]
455    pub fn instance_of<T: TCFType>(&self) -> bool {
456        self.type_of() == T::type_id()
457    }
458}
459
460impl Clone for CVImageBuffer {
461    fn clone(&self) -> CVImageBuffer {
462        unsafe { CVImageBuffer::wrap_under_get_rule(self.0) }
463    }
464}
465
466impl PartialEq for CVImageBuffer {
467    fn eq(&self, other: &CVImageBuffer) -> bool {
468        self.as_CFType().eq(&other.as_CFType())
469    }
470}
471
472impl Eq for CVImageBuffer {}
473
474pub trait TCVImageBuffer: TCVBuffer {
475    #[inline]
476    fn as_image_buffer(&self) -> CVImageBuffer {
477        unsafe { CVImageBuffer::wrap_under_get_rule(self.as_concrete_TypeRef().as_void_ptr() as CVImageBufferRef) }
478    }
479
480    #[inline]
481    fn into_image_buffer(self) -> CVImageBuffer
482    where
483        Self: Sized,
484    {
485        let reference = self.as_concrete_TypeRef().as_void_ptr() as CVImageBufferRef;
486        mem::forget(self);
487        unsafe { CVImageBuffer::wrap_under_create_rule(reference) }
488    }
489}
490
491impl CVImageBuffer {
492    #[inline]
493    pub fn downcast<T: TCVImageBuffer>(&self) -> Option<T> {
494        if self.instance_of::<T>() {
495            unsafe { Some(T::wrap_under_get_rule(T::Ref::from_void_ptr(self.as_concrete_TypeRef() as *const c_void))) }
496        } else {
497            None
498        }
499    }
500
501    #[inline]
502    pub fn downcast_into<T: TCVImageBuffer>(self) -> Option<T> {
503        if self.instance_of::<T>() {
504            unsafe {
505                let reference = T::Ref::from_void_ptr(self.as_concrete_TypeRef() as *const c_void);
506                mem::forget(self);
507                Some(T::wrap_under_create_rule(reference))
508            }
509        } else {
510            None
511        }
512    }
513}
514
515impl CVImageBuffer {
516    #[inline]
517    pub fn as_buffer(&self) -> CVBuffer {
518        unsafe { CVBuffer::wrap_under_get_rule(self.as_concrete_TypeRef() as CVBufferRef) }
519    }
520
521    #[inline]
522    pub fn into_buffer(self) -> CVBuffer
523    where
524        Self: Sized,
525    {
526        let reference = self.as_concrete_TypeRef() as CVBufferRef;
527        mem::forget(self);
528        unsafe { CVBuffer::wrap_under_create_rule(reference) }
529    }
530
531    #[inline]
532    pub fn get_encoded_size(&self) -> CGSize {
533        unsafe { CVImageBufferGetEncodedSize(self.as_concrete_TypeRef()) }
534    }
535
536    #[inline]
537    pub fn get_display_size(&self) -> CGSize {
538        unsafe { CVImageBufferGetDisplaySize(self.as_concrete_TypeRef()) }
539    }
540
541    #[inline]
542    pub fn get_clean_rect(&self) -> CGRect {
543        unsafe { CVImageBufferGetCleanRect(self.as_concrete_TypeRef()) }
544    }
545
546    #[inline]
547    pub fn is_flipped(&self) -> bool {
548        unsafe { CVImageBufferIsFlipped(self.as_concrete_TypeRef()) != 0 }
549    }
550
551    #[inline]
552    pub fn get_color_space(&self) -> Option<CGColorSpace> {
553        unsafe {
554            let color_space = CVImageBufferGetColorSpace(self.as_concrete_TypeRef());
555            if color_space.is_null() {
556                None
557            } else {
558                Some(TCFType::wrap_under_create_rule(color_space))
559            }
560        }
561    }
562}
563
564pub fn create_color_space_from_attachments(attachments: &CFDictionary<CFString, CFType>) -> Option<CGColorSpace> {
565    unsafe {
566        let color_space = CVImageBufferCreateColorSpaceFromAttachments(attachments.as_concrete_TypeRef());
567        if color_space.is_null() {
568            None
569        } else {
570            Some(TCFType::wrap_under_create_rule(color_space))
571        }
572    }
573}