1use std::ptr;
2
3use crate::base::CGFloat;
4use crate::color_space::CGColorSpace;
5use crate::data_provider::{CGDataProvider, CGDataProviderRef};
6use crate::geometry::CGRect;
7use core_foundation::base::{CFRetain, CFTypeID};
8use core_foundation::data::CFData;
9use foreign_types::{foreign_type, ForeignType, ForeignTypeRef};
10
11#[repr(C)]
12pub enum CGImageAlphaInfo {
13 CGImageAlphaNone, CGImageAlphaPremultipliedLast, CGImageAlphaPremultipliedFirst, CGImageAlphaLast, CGImageAlphaFirst, CGImageAlphaNoneSkipLast, CGImageAlphaNoneSkipFirst, CGImageAlphaOnly, }
22
23#[repr(C)]
24pub enum CGImageByteOrderInfo {
25 CGImageByteOrderMask = 0x7000,
26 CGImageByteOrder16Little = 1 << 12,
27 CGImageByteOrder32Little = 2 << 12,
28 CGImageByteOrder16Big = 3 << 12,
29 CGImageByteOrder32Big = 4 << 12,
30}
31
32foreign_type! {
33 #[doc(hidden)]
34 pub unsafe type CGImage {
35 type CType = crate::sys::CGImage;
36 fn drop = CGImageRelease;
37 fn clone = |p| CFRetain(p as *const _) as *mut _;
38 }
39}
40
41impl CGImage {
42 pub fn new(
43 width: usize,
44 height: usize,
45 bits_per_component: usize,
46 bits_per_pixel: usize,
47 bytes_per_row: usize,
48 colorspace: &CGColorSpace,
49 bitmap_info: u32,
50 provider: &CGDataProvider,
51 should_interpolate: bool,
52 rendering_intent: u32,
53 ) -> Self {
54 unsafe {
55 let result = CGImageCreate(
56 width,
57 height,
58 bits_per_component,
59 bits_per_pixel,
60 bytes_per_row,
61 colorspace.as_ptr(),
62 bitmap_info,
63 provider.as_ptr(),
64 ptr::null_mut(),
65 should_interpolate,
66 rendering_intent,
67 );
68 assert!(!result.is_null());
69 Self::from_ptr(result)
70 }
71 }
72
73 pub fn type_id() -> CFTypeID {
74 unsafe { CGImageGetTypeID() }
75 }
76}
77
78impl CGImageRef {
79 pub fn width(&self) -> usize {
80 unsafe { CGImageGetWidth(self.as_ptr()) }
81 }
82
83 pub fn height(&self) -> usize {
84 unsafe { CGImageGetHeight(self.as_ptr()) }
85 }
86
87 pub fn bits_per_component(&self) -> usize {
88 unsafe { CGImageGetBitsPerComponent(self.as_ptr()) }
89 }
90
91 pub fn bits_per_pixel(&self) -> usize {
92 unsafe { CGImageGetBitsPerPixel(self.as_ptr()) }
93 }
94
95 pub fn bytes_per_row(&self) -> usize {
96 unsafe { CGImageGetBytesPerRow(self.as_ptr()) }
97 }
98
99 pub fn color_space(&self) -> CGColorSpace {
100 unsafe {
101 let cs = CGImageGetColorSpace(self.as_ptr());
102 CFRetain(cs as *mut _);
103 CGColorSpace::from_ptr(cs)
104 }
105 }
106
107 pub fn data(&self) -> CFData {
110 let data_provider =
111 unsafe { CGDataProviderRef::from_ptr(CGImageGetDataProvider(self.as_ptr())) };
112 data_provider.copy_data()
113 }
114
115 pub fn cropped(&self, rect: CGRect) -> Option<CGImage> {
118 let image_ptr = unsafe { CGImageCreateWithImageInRect(self.as_ptr(), rect) };
119 if !image_ptr.is_null() {
120 Some(unsafe { CGImage::from_ptr(image_ptr) })
121 } else {
122 None
123 }
124 }
125}
126
127#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
128extern "C" {
129 fn CGImageGetTypeID() -> CFTypeID;
130 fn CGImageGetWidth(image: crate::sys::CGImageRef) -> usize;
131 fn CGImageGetHeight(image: crate::sys::CGImageRef) -> usize;
132 fn CGImageGetBitsPerComponent(image: crate::sys::CGImageRef) -> usize;
133 fn CGImageGetBitsPerPixel(image: crate::sys::CGImageRef) -> usize;
134 fn CGImageGetBytesPerRow(image: crate::sys::CGImageRef) -> usize;
135 fn CGImageGetColorSpace(image: crate::sys::CGImageRef) -> crate::sys::CGColorSpaceRef;
136 fn CGImageGetDataProvider(image: crate::sys::CGImageRef) -> crate::sys::CGDataProviderRef;
137 fn CGImageRelease(image: crate::sys::CGImageRef);
138 fn CGImageCreate(
139 width: usize,
140 height: usize,
141 bitsPerComponent: usize,
142 bitsPerPixel: usize,
143 bytesPerRow: usize,
144 space: crate::sys::CGColorSpaceRef,
145 bitmapInfo: u32,
146 provider: crate::sys::CGDataProviderRef,
147 decode: *const CGFloat,
148 shouldInterpolate: bool,
149 intent: u32,
150 ) -> crate::sys::CGImageRef;
151 fn CGImageCreateWithImageInRect(
152 image: crate::sys::CGImageRef,
153 rect: CGRect,
154 ) -> crate::sys::CGImageRef;
155
156 }