core_video/
image_buffer.rs

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