@@ -14,11 +14,14 @@ use std::mem::MaybeUninit;
1414use crate :: hardware_buffer:: HardwareBufferRef ;
1515
1616#[ repr( i32 ) ]
17- #[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
17+ #[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
1818pub enum BitmapError {
1919 Unknown ,
20+ #[ doc( alias = "ANDROID_BITMAP_RESULT_ALLOCATION_FAILED" ) ]
2021 AllocationFailed = ffi:: ANDROID_BITMAP_RESULT_ALLOCATION_FAILED ,
22+ #[ doc( alias = "ANDROID_BITMAP_RESULT_BAD_PARAMETER" ) ]
2123 BadParameter = ffi:: ANDROID_BITMAP_RESULT_BAD_PARAMETER ,
24+ #[ doc( alias = "ANDROID_BITMAP_RESULT_JNI_EXCEPTION" ) ]
2225 JniException = ffi:: ANDROID_BITMAP_RESULT_JNI_EXCEPTION ,
2326}
2427
@@ -43,16 +46,23 @@ fn construct<T>(with_ptr: impl FnOnce(*mut T) -> i32) -> BitmapResult<T> {
4346}
4447
4548#[ repr( u32 ) ]
46- #[ derive( Copy , Clone , Debug , PartialEq , Eq , IntoPrimitive , TryFromPrimitive ) ]
49+ #[ derive( Clone , Copy , Debug , PartialEq , Eq , IntoPrimitive , TryFromPrimitive ) ]
4750#[ allow( non_camel_case_types) ]
4851pub enum BitmapFormat {
52+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_NONE" ) ]
4953 NONE = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_NONE . 0 ,
54+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_RGBA_8888" ) ]
5055 RGBA_8888 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_RGBA_8888 . 0 ,
56+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_RGB_565" ) ]
5157 RGB_565 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_RGB_565 . 0 ,
5258 #[ deprecated = "Deprecated in API level 13. Because of the poor quality of this configuration, it is advised to use ARGB_8888 instead." ]
59+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_RGBA_4444" ) ]
5360 RGBA_4444 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_RGBA_4444 . 0 ,
61+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_A_8" ) ]
5462 A_8 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_A_8 . 0 ,
63+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_RGBA_F16" ) ]
5564 RGBA_F16 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_RGBA_F16 . 0 ,
65+ #[ doc( alias = "ANDROID_BITMAP_FORMAT_RGBA_1010102" ) ]
5666 RGBA_1010102 = ffi:: AndroidBitmapFormat :: ANDROID_BITMAP_FORMAT_RGBA_1010102 . 0 ,
5767}
5868
@@ -77,26 +87,42 @@ impl AndroidBitmap {
7787 Self { env, inner : bitmap }
7888 }
7989
90+ /// Fills out and returns the [`AndroidBitmapInfo`] struct for the given Java bitmap object.
91+ #[ doc( alias = "AndroidBitmap_getInfo" ) ]
8092 pub fn get_info ( & self ) -> BitmapResult < AndroidBitmapInfo > {
8193 let inner =
8294 construct ( |res| unsafe { ffi:: AndroidBitmap_getInfo ( self . env , self . inner , res) } ) ?;
8395
8496 Ok ( AndroidBitmapInfo { inner } )
8597 }
8698
99+ /// Attempt to lock the pixel address.
100+ ///
101+ /// Locking will ensure that the memory for the pixels will not move until the
102+ /// [`AndroidBitmap::unlock_pixels()`] call, and ensure that, if the pixels had been previously
103+ /// purged, they will have been restored.
104+ ///
105+ /// If this call succeeds, it must be balanced by a call to [`AndroidBitmap::unlock_pixels()`],
106+ /// after which time the address of the pixels should no longer be used.
107+ #[ doc( alias = "AndroidBitmap_lockPixels" ) ]
87108 pub fn lock_pixels ( & self ) -> BitmapResult < * mut std:: os:: raw:: c_void > {
88109 construct ( |res| unsafe { ffi:: AndroidBitmap_lockPixels ( self . env , self . inner , res) } )
89110 }
90111
112+ /// Call this to balance a successful call to [`AndroidBitmap::lock_pixels()`].
113+ #[ doc( alias = "AndroidBitmap_unlockPixels" ) ]
91114 pub fn unlock_pixels ( & self ) -> BitmapResult < ( ) > {
92115 let status = unsafe { ffi:: AndroidBitmap_unlockPixels ( self . env , self . inner ) } ;
93116 BitmapError :: from_status ( status)
94117 }
95118
96- /// Retrieve the native object associated with a `HARDWARE` [`AndroidBitmap`].
119+ /// Retrieve the native object associated with an [`ffi::ANDROID_BITMAP_FLAGS_IS_HARDWARE`]
120+ /// [`AndroidBitmap`] (requires [`AndroidBitmapInfoFlags::is_hardware()`] on
121+ /// [`AndroidBitmapInfo::flags()`] to return [`true`]).
97122 ///
98123 /// Client must not modify it while an [`AndroidBitmap`] is wrapping it.
99124 #[ cfg( feature = "api-level-30" ) ]
125+ #[ doc( alias = "AndroidBitmap_getHardwareBuffer" ) ]
100126 pub fn get_hardware_buffer ( & self ) -> BitmapResult < HardwareBufferRef > {
101127 unsafe {
102128 let result =
@@ -111,27 +137,102 @@ impl AndroidBitmap {
111137 }
112138}
113139
140+ /// Possible values for [`ffi::ANDROID_BITMAP_FLAGS_ALPHA_MASK`] within [`AndroidBitmapInfoFlags`]
141+ #[ cfg( feature = "api-level-30" ) ]
142+ #[ derive( Clone , Copy , Debug ) ]
143+ pub enum AndroidBitmapInfoFlagsAlpha {
144+ /// Pixel components are premultiplied by alpha.
145+ #[ doc( alias = "ANDROID_BITMAP_FLAGS_ALPHA_PREMUL" ) ]
146+ Premultiplied ,
147+ /// Pixels are opaque.
148+ #[ doc( alias = "ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE" ) ]
149+ Opaque ,
150+ /// Pixel components are independent of alpha.
151+ #[ doc( alias = "ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL" ) ]
152+ Unpremultiplied ,
153+ }
154+
155+ /// Bitfield containing information about the bitmap.
156+ #[ cfg( feature = "api-level-30" ) ]
157+ #[ derive( Clone , Copy , Hash , PartialEq , Eq ) ]
158+ #[ repr( transparent) ]
159+ pub struct AndroidBitmapInfoFlags ( u32 ) ;
160+
161+ #[ cfg( feature = "api-level-30" ) ]
162+ impl std:: fmt:: Debug for AndroidBitmapInfoFlags {
163+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
164+ write ! (
165+ f,
166+ "AndroidBitmapInfoFlags({:#x}, alpha: {:?}, is_hardware: {})" ,
167+ self . 0 ,
168+ self . alpha( ) ,
169+ self . is_hardware( )
170+ )
171+ }
172+ }
173+
174+ #[ cfg( feature = "api-level-30" ) ]
175+ impl AndroidBitmapInfoFlags {
176+ /// Returns the alpha value contained in the [`ffi::ANDROID_BITMAP_FLAGS_ALPHA_MASK`] bit range
177+ #[ doc( alias = "ANDROID_BITMAP_FLAGS_ALPHA_MASK" ) ]
178+ pub fn alpha ( self ) -> AndroidBitmapInfoFlagsAlpha {
179+ // Note that ffi::ANDROID_BITMAP_FLAGS_ALPHA_SHIFT is 0 and hence irrelevant.
180+ match self . 0 & ffi:: ANDROID_BITMAP_FLAGS_ALPHA_MASK {
181+ ffi:: ANDROID_BITMAP_FLAGS_ALPHA_PREMUL => AndroidBitmapInfoFlagsAlpha :: Premultiplied ,
182+ ffi:: ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE => AndroidBitmapInfoFlagsAlpha :: Opaque ,
183+ ffi:: ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL => {
184+ AndroidBitmapInfoFlagsAlpha :: Unpremultiplied
185+ }
186+ 3 => todo ! ( "ALPHA_MASK value 3" ) ,
187+ _ => unreachable ! ( ) ,
188+ }
189+ }
190+
191+ /// Returns [`true`] when [`ffi::ANDROID_BITMAP_FLAGS_IS_HARDWARE`] is set, meaning this
192+ /// [`AndroidBitmap`] uses "HARDWARE Config" and its [`HardwareBufferRef`] can be retrieved via
193+ /// [`AndroidBitmap::get_hardware_buffer()`].
194+ #[ doc( alias = "ANDROID_BITMAP_FLAGS_IS_HARDWARE" ) ]
195+ pub fn is_hardware ( self ) -> bool {
196+ // This constant is defined in a separate anonymous enum which bindgen treats as i32.
197+ ( self . 0 & ffi:: ANDROID_BITMAP_FLAGS_IS_HARDWARE as u32 ) != 0
198+ }
199+ }
200+
114201/// A native [`AndroidBitmapInfo`]
115202///
116203/// [`AndroidBitmapInfo`]: https://developer.android.com/ndk/reference/struct/android-bitmap-info#struct_android_bitmap_info
117- #[ derive( Copy , Clone , Debug ) ]
204+ #[ derive( Clone , Copy ) ]
118205pub struct AndroidBitmapInfo {
119206 inner : ffi:: AndroidBitmapInfo ,
120207}
121208
122- // TODO: flesh out when API 30 is released
123- #[ cfg( feature = "api-level-30" ) ]
124- pub type AndroidBitmapInfoFlags = u32 ;
209+ impl std:: fmt:: Debug for AndroidBitmapInfo {
210+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
211+ let mut f = f. debug_struct ( "AndroidBitmapInfo" ) ;
212+ f. field ( "width" , & self . width ( ) )
213+ . field ( "height" , & self . height ( ) )
214+ . field ( "stride" , & self . stride ( ) )
215+ . field ( "format" , & self . try_format ( ) ) ;
216+
217+ #[ cfg( feature = "api-level-30" ) ]
218+ f. field ( "flags" , & self . flags ( ) ) ;
219+
220+ f. finish ( )
221+ }
222+ }
125223
126224impl AndroidBitmapInfo {
225+ /// The bitmap width in pixels.
127226 pub fn width ( & self ) -> u32 {
128227 self . inner . width
129228 }
130229
230+ /// The bitmap height in pixels.
131231 pub fn height ( & self ) -> u32 {
132232 self . inner . height
133233 }
134234
235+ /// The number of byte per row.
135236 pub fn stride ( & self ) -> u32 {
136237 self . inner . stride
137238 }
@@ -155,8 +256,9 @@ impl AndroidBitmapInfo {
155256 format. try_into ( )
156257 }
157258
259+ /// Bitfield containing information about the bitmap.
158260 #[ cfg( feature = "api-level-30" ) ]
159261 pub fn flags ( & self ) -> AndroidBitmapInfoFlags {
160- self . inner . flags
262+ AndroidBitmapInfoFlags ( self . inner . flags )
161263 }
162264}
0 commit comments