@@ -2181,6 +2181,115 @@ impl InternalTexture {
2181
2181
}
2182
2182
}
2183
2183
2184
+ #[ doc( alias = "SDL_UpdateNVTexture" ) ]
2185
+ pub fn update_nv < R > (
2186
+ & mut self ,
2187
+ rect : R ,
2188
+ y_plane : & [ u8 ] ,
2189
+ y_pitch : usize ,
2190
+ uv_plane : & [ u8 ] ,
2191
+ uv_pitch : usize ,
2192
+ ) -> Result < ( ) , UpdateTextureYUVError >
2193
+ where
2194
+ R : Into < Option < Rect > > ,
2195
+ {
2196
+ use self :: UpdateTextureYUVError :: * ;
2197
+
2198
+ let rect = rect. into ( ) ;
2199
+
2200
+ let rect_raw_ptr = match rect {
2201
+ Some ( ref rect) => rect. raw ( ) ,
2202
+ None => ptr:: null ( ) ,
2203
+ } ;
2204
+
2205
+ if let Some ( ref r) = rect {
2206
+ if r. x ( ) % 2 != 0 {
2207
+ return Err ( XMustBeMultipleOfTwoForFormat ( r. x ( ) ) ) ;
2208
+ } else if r. y ( ) % 2 != 0 {
2209
+ return Err ( YMustBeMultipleOfTwoForFormat ( r. y ( ) ) ) ;
2210
+ } else if r. width ( ) % 2 != 0 {
2211
+ return Err ( WidthMustBeMultipleOfTwoForFormat ( r. width ( ) ) ) ;
2212
+ } else if r. height ( ) % 2 != 0 {
2213
+ return Err ( HeightMustBeMultipleOfTwoForFormat ( r. height ( ) ) ) ;
2214
+ }
2215
+ } ;
2216
+
2217
+ // If the destination rectangle lies outside the texture boundaries,
2218
+ // SDL_UpdateNVTexture will write outside allocated texture memory.
2219
+ let tex_info = self . query ( ) ;
2220
+ if let Some ( ref r) = rect {
2221
+ let tex_rect = Rect :: new ( 0 , 0 , tex_info. width , tex_info. height ) ;
2222
+ let inside = match r. intersection ( tex_rect) {
2223
+ Some ( intersection) => intersection == * r,
2224
+ None => false ,
2225
+ } ;
2226
+ // The destination rectangle cannot lie outside the texture boundaries
2227
+ if !inside {
2228
+ return Err ( RectNotInsideTexture ( * r) ) ;
2229
+ }
2230
+ }
2231
+
2232
+ // We need the height in order to check the array slice lengths.
2233
+ // Checking the lengths can prevent buffer overruns in SDL_UpdateNVTexture.
2234
+ let height = match rect {
2235
+ Some ( ref r) => r. height ( ) ,
2236
+ None => tex_info. height ,
2237
+ } as usize ;
2238
+
2239
+ //let wrong_length =
2240
+ if y_plane. len ( ) != ( y_pitch * height) {
2241
+ return Err ( InvalidPlaneLength {
2242
+ plane : "y" ,
2243
+ length : y_plane. len ( ) ,
2244
+ pitch : y_pitch,
2245
+ height,
2246
+ } ) ;
2247
+ }
2248
+ if uv_plane. len ( ) != ( uv_pitch * height) {
2249
+ return Err ( InvalidPlaneLength {
2250
+ plane : "uv" ,
2251
+ length : uv_plane. len ( ) ,
2252
+ pitch : uv_pitch,
2253
+ height : height,
2254
+ } ) ;
2255
+ }
2256
+
2257
+ let y_pitch = match validate_int ( y_pitch as u32 , "y_pitch" ) {
2258
+ Ok ( p) => p,
2259
+ Err ( _) => {
2260
+ return Err ( PitchOverflows {
2261
+ plane : "y" ,
2262
+ value : y_pitch,
2263
+ } )
2264
+ }
2265
+ } ;
2266
+ let uv_pitch = match validate_int ( uv_pitch as u32 , "uv_pitch" ) {
2267
+ Ok ( p) => p,
2268
+ Err ( _) => {
2269
+ return Err ( PitchOverflows {
2270
+ plane : "uv" ,
2271
+ value : uv_pitch,
2272
+ } )
2273
+ }
2274
+ } ;
2275
+
2276
+ let result = unsafe {
2277
+ sys:: SDL_UpdateNVTexture (
2278
+ self . raw ,
2279
+ rect_raw_ptr,
2280
+ y_plane. as_ptr ( ) ,
2281
+ y_pitch,
2282
+ uv_plane. as_ptr ( ) ,
2283
+ uv_pitch,
2284
+ )
2285
+ } ;
2286
+ if result != 0 {
2287
+ Err ( SdlError ( get_error ( ) ) )
2288
+ } else {
2289
+ Ok ( ( ) )
2290
+ }
2291
+ }
2292
+
2184
2293
#[ doc( alias = "SDL_LockTexture" ) ]
2185
2294
pub fn with_lock < F , R , R2 > ( & mut self , rect : R2 , func : F ) -> Result < R , String >
2186
2295
where
@@ -2346,6 +2455,22 @@ impl<'r> Texture<'r> {
2346
2455
. update_yuv ( rect, y_plane, y_pitch, u_plane, u_pitch, v_plane, v_pitch)
2347
2456
}
2348
2457
2458
+ /// Update a rectangle within a planar NV12 or NV21 texture with new pixel data.
2459
+ #[ inline]
2460
+ pub fn update_nv < R > (
2461
+ & mut self ,
2462
+ rect : R ,
2463
+ y_plane : & [ u8 ] ,
2464
+ y_pitch : usize ,
2465
+ uv_plane : & [ u8 ] ,
2466
+ uv_pitch : usize ,
2467
+ ) -> Result < ( ) , UpdateTextureYUVError >
2468
+ where
2469
+ R : Into < Option < Rect > > ,
2470
+ {
2471
+ InternalTexture { raw : self . raw } . update_nv ( rect, y_plane, y_pitch, uv_plane, uv_pitch)
2472
+ }
2473
+
2349
2474
/// Locks the texture for **write-only** pixel access.
2350
2475
/// The texture must have been created with streaming access.
2351
2476
///
@@ -2543,6 +2668,22 @@ impl Texture {
2543
2668
. update_yuv ( rect, y_plane, y_pitch, u_plane, u_pitch, v_plane, v_pitch)
2544
2669
}
2545
2670
2671
+ /// Update a rectangle within a planar NV12 or NV21 texture with new pixel data.
2672
+ #[ inline]
2673
+ pub fn update_nv < R > (
2674
+ & mut self ,
2675
+ rect : R ,
2676
+ y_plane : & [ u8 ] ,
2677
+ y_pitch : usize ,
2678
+ uv_plane : & [ u8 ] ,
2679
+ uv_pitch : usize ,
2680
+ ) -> Result < ( ) , UpdateTextureYUVError >
2681
+ where
2682
+ R : Into < Option < Rect > > ,
2683
+ {
2684
+ InternalTexture { raw : self . raw } . update_nv ( rect, y_plane, y_pitch, uv_plane, uv_pitch)
2685
+ }
2686
+
2546
2687
/// Locks the texture for **write-only** pixel access.
2547
2688
/// The texture must have been created with streaming access.
2548
2689
///
0 commit comments