@@ -638,6 +638,34 @@ fn read_scalar_enum(scalar: vx_scalar) -> Option<vx_enum> {
638638 }
639639}
640640
641+ fn read_scalar_i32 ( scalar : vx_scalar ) -> Option < i32 > {
642+ if scalar. is_null ( ) {
643+ return None ;
644+ }
645+ unsafe {
646+ let s = & * ( scalar as * const crate :: c_api_data:: VxCScalarData ) ;
647+ if s. data . len ( ) >= 4 {
648+ Some ( i32:: from_le_bytes ( [ s. data [ 0 ] , s. data [ 1 ] , s. data [ 2 ] , s. data [ 3 ] ] ) )
649+ } else {
650+ None
651+ }
652+ }
653+ }
654+
655+ fn read_scalar_f32 ( scalar : vx_scalar ) -> Option < f32 > {
656+ if scalar. is_null ( ) {
657+ return None ;
658+ }
659+ unsafe {
660+ let s = & * ( scalar as * const crate :: c_api_data:: VxCScalarData ) ;
661+ if s. data . len ( ) >= 4 {
662+ Some ( f32:: from_le_bytes ( [ s. data [ 0 ] , s. data [ 1 ] , s. data [ 2 ] , s. data [ 3 ] ] ) )
663+ } else {
664+ None
665+ }
666+ }
667+ }
668+
641669fn is_image_reference ( ref_id : u64 ) -> bool {
642670 if let Ok ( types) = REFERENCE_TYPES . lock ( ) {
643671 if let Some ( ref_type) = types. get ( & ( ref_id as usize ) ) {
@@ -1090,6 +1118,7 @@ pub extern "C" fn vxVerifyGraph(graph: vx_graph) -> vx_status {
10901118 ( "org.khronos.openvx.non_linear_filter" , vec ! [ 3 ] ) , // [input, matrix, border, output]
10911119 // Enhanced Vision kernels
10921120 ( "org.khronos.openvx.copy" , vec ! [ 1 ] ) , // [input, output] - param 1 is output
1121+ ( "org.khronos.openvx.bilateral_filter" , vec ! [ 4 ] ) , // [src, diameter, sigma_space, sigma_values, dst]
10931122 ( "org.khronos.openvx.non_max_suppression" , vec ! [ 3 ] ) , // [input, mask, win_size, output]
10941123 ( "org.khronos.openvx.hough_lines_p" , vec ! [ 6 , 7 ] ) , // [input, rho, theta, threshold, line_length, line_gap, lines_array, num_lines]
10951124 ( "org.khronos.openvx.match_template" , vec ! [ 3 ] ) , // [src, templ, matching_method, output]
@@ -3272,6 +3301,33 @@ fn dispatch_kernel_with_border_impl(
32723301 VX_ERROR_INVALID_PARAMETERS
32733302 }
32743303 }
3304+ // BilateralFilter (Enhanced Vision)
3305+ "org.khronos.openvx.bilateral_filter" => {
3306+ if params. len ( ) >= 5 {
3307+ let src = params[ 0 ] as vx_tensor ;
3308+ let diameter_scalar = params[ 1 ] as vx_scalar ;
3309+ let sigma_space_scalar = params[ 2 ] as vx_scalar ;
3310+ let sigma_values_scalar = params[ 3 ] as vx_scalar ;
3311+ let dst = params[ 4 ] as vx_tensor ;
3312+ if !src. is_null ( ) && !dst. is_null ( ) {
3313+ let diameter = read_scalar_i32 ( diameter_scalar) . unwrap_or ( 0 ) ;
3314+ let sigma_space = read_scalar_f32 ( sigma_space_scalar) . unwrap_or ( 0.0 ) ;
3315+ let sigma_values = read_scalar_f32 ( sigma_values_scalar) . unwrap_or ( 0.0 ) ;
3316+ crate :: vxu_impl:: vxu_bilateral_filter_impl (
3317+ unsafe { crate :: c_api:: vxGetContext ( src as vx_reference ) } ,
3318+ src as vx_reference ,
3319+ diameter,
3320+ sigma_space,
3321+ sigma_values,
3322+ dst as vx_reference ,
3323+ )
3324+ } else {
3325+ VX_ERROR_INVALID_PARAMETERS
3326+ }
3327+ } else {
3328+ VX_ERROR_INVALID_PARAMETERS
3329+ }
3330+ }
32753331 // Multiply
32763332 "org.khronos.openvx.multiply" => {
32773333 if params. len ( ) >= 6 {
@@ -5148,11 +5204,11 @@ pub extern "C" fn vxRegisterPyramidLevelImage(
51485204}
51495205
51505206// Tensor registry
5151- static TENSORS : Lazy < Mutex < HashMap < usize , Arc < VxCTensor > > > > =
5207+ pub static TENSORS : Lazy < Mutex < HashMap < usize , Arc < VxCTensor > > > > =
51525208 Lazy :: new ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
51535209
51545210// Tensor data storage (raw bytes keyed by tensor address)
5155- static TENSOR_DATA : Lazy < Mutex < HashMap < usize , Vec < u8 > > > > =
5211+ pub static TENSOR_DATA : Lazy < Mutex < HashMap < usize , Vec < u8 > > > > =
51565212 Lazy :: new ( || Mutex :: new ( HashMap :: new ( ) ) ) ;
51575213
51585214// Tensor context association
@@ -13258,22 +13314,61 @@ macro_rules! ev_vxu_stub {
1325813314}
1325913315
1326013316// ---- Image kernels still missing ----
13261- ev_node_stub ! ( vxBilateralFilterNode(
13317+ #[ no_mangle]
13318+ pub extern "C" fn vxBilateralFilterNode (
1326213319 graph : vx_graph ,
1326313320 src : vx_tensor ,
1326413321 diameter : vx_int32 ,
1326513322 sigma_space : vx_float32 ,
1326613323 sigma_values : vx_float32 ,
1326713324 dst : vx_tensor ,
13268- ) ) ;
13269- ev_vxu_stub ! ( vxuBilateralFilter(
13270- context: vx_context,
13325+ ) -> vx_node {
13326+ if graph. is_null ( ) || src. is_null ( ) || dst. is_null ( ) {
13327+ return std:: ptr:: null_mut ( ) ;
13328+ }
13329+ let context = crate :: c_api:: vxGetContext ( graph as vx_reference ) ;
13330+ if context. is_null ( ) {
13331+ return std:: ptr:: null_mut ( ) ;
13332+ }
13333+ unsafe {
13334+ let mut diameter_scalar = vxCreateScalar ( context, VX_TYPE_INT32 , & diameter as * const _ as * const c_void ) ;
13335+ let mut sigma_space_scalar = vxCreateScalar ( context, VX_TYPE_FLOAT32 , & sigma_space as * const _ as * const c_void ) ;
13336+ let mut sigma_values_scalar = vxCreateScalar ( context, VX_TYPE_FLOAT32 , & sigma_values as * const _ as * const c_void ) ;
13337+ if diameter_scalar. is_null ( ) || sigma_space_scalar. is_null ( ) || sigma_values_scalar. is_null ( ) {
13338+ vxReleaseScalar ( & mut diameter_scalar) ;
13339+ vxReleaseScalar ( & mut sigma_space_scalar) ;
13340+ vxReleaseScalar ( & mut sigma_values_scalar) ;
13341+ return std:: ptr:: null_mut ( ) ;
13342+ }
13343+ let node = create_node_with_params (
13344+ graph,
13345+ "org.khronos.openvx.bilateral_filter" ,
13346+ & [
13347+ src as vx_reference ,
13348+ diameter_scalar as vx_reference ,
13349+ sigma_space_scalar as vx_reference ,
13350+ sigma_values_scalar as vx_reference ,
13351+ dst as vx_reference ,
13352+ ] ,
13353+ ) ;
13354+ vxReleaseScalar ( & mut diameter_scalar) ;
13355+ vxReleaseScalar ( & mut sigma_space_scalar) ;
13356+ vxReleaseScalar ( & mut sigma_values_scalar) ;
13357+ node
13358+ }
13359+ }
13360+
13361+ #[ no_mangle]
13362+ pub extern "C" fn vxuBilateralFilter (
13363+ _context : vx_context ,
1327113364 src : vx_tensor ,
1327213365 diameter : vx_int32 ,
1327313366 sigma_space : vx_float32 ,
1327413367 sigma_values : vx_float32 ,
1327513368 dst : vx_tensor ,
13276- ) ) ;
13369+ ) -> vx_status {
13370+ unsafe { crate :: vxu_impl:: vxu_bilateral_filter_impl ( _context, src as vx_reference , diameter, sigma_space, sigma_values, dst as vx_reference ) }
13371+ }
1327713372
1327813373#[ no_mangle]
1327913374pub extern "C" fn vxLBPNode (
0 commit comments