@@ -2181,6 +2181,115 @@ impl InternalTexture {
21812181 }
21822182 }
21832183
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+
21842293 #[ doc( alias = "SDL_LockTexture" ) ]
21852294 pub fn with_lock < F , R , R2 > ( & mut self , rect : R2 , func : F ) -> Result < R , String >
21862295 where
@@ -2346,6 +2455,22 @@ impl<'r> Texture<'r> {
23462455 . update_yuv ( rect, y_plane, y_pitch, u_plane, u_pitch, v_plane, v_pitch)
23472456 }
23482457
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+
23492474 /// Locks the texture for **write-only** pixel access.
23502475 /// The texture must have been created with streaming access.
23512476 ///
@@ -2543,6 +2668,22 @@ impl Texture {
25432668 . update_yuv ( rect, y_plane, y_pitch, u_plane, u_pitch, v_plane, v_pitch)
25442669 }
25452670
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+
25462687 /// Locks the texture for **write-only** pixel access.
25472688 /// The texture must have been created with streaming access.
25482689 ///
0 commit comments