| /** |
| * \brief Image warping kernel function. |
| * \param[in] input Input image object. |
| * \param[out] output scaled output image object. |
| * \param[in] warp_config: image warping parameters |
| */ |
| |
| #ifndef WARP_Y |
| #define WARP_Y 1 |
| #endif |
| |
| // 8 bytes for each Y pixel |
| #define PIXEL_X_STEP 8 |
| |
| typedef struct { |
| int frame_id; |
| int width; |
| int height; |
| float trim_ratio; |
| float proj_mat[9]; |
| } CLWarpConfig; |
| |
| __kernel void |
| kernel_image_warp_8_pixel ( |
| __read_only image2d_t input, |
| __write_only image2d_t output, |
| CLWarpConfig warp_config) |
| { |
| // dest coordinate |
| int d_x = get_global_id(0); |
| int d_y = get_global_id(1); |
| |
| int out_width = get_image_width (output); |
| int out_height = get_image_height (output); |
| |
| const sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR; |
| |
| // source coordinate |
| float s_x = 0.0f; |
| float s_y = 0.0f; |
| float warp_x = 0.0f; |
| float warp_y = 0.0f; |
| float w = 0.0f; |
| |
| float t_x = 0.0f; |
| float t_y = 0.0f; |
| |
| float16 pixel = 0.0f; |
| float* output_pixel = (float*)(&pixel); |
| int i = 0; |
| |
| t_y = d_y; |
| #pragma unroll |
| for (i = 0; i < PIXEL_X_STEP; i++) { |
| t_x = (float)(PIXEL_X_STEP * d_x + i); |
| |
| s_x = warp_config.proj_mat[0] * t_x + |
| warp_config.proj_mat[1] * t_y + |
| warp_config.proj_mat[2]; |
| s_y = warp_config.proj_mat[3] * t_x + |
| warp_config.proj_mat[4] * t_y + |
| warp_config.proj_mat[5]; |
| w = warp_config.proj_mat[6] * t_x + |
| warp_config.proj_mat[7] * t_y + |
| warp_config.proj_mat[8]; |
| w = w != 0.0f ? 1.0f / w : 0.0f; |
| |
| warp_x = (s_x * w) / (float)(PIXEL_X_STEP * out_width); |
| warp_y = (s_y * w) / (float)out_height; |
| |
| #if WARP_Y |
| output_pixel[i] = read_imagef(input, sampler, (float2)(warp_x, warp_y)).x; |
| #else |
| float2 temp = read_imagef(input, sampler, (float2)(warp_x, warp_y)).xy; |
| output_pixel[2 * i] = temp.x; |
| output_pixel[2 * i + 1] = temp.y; |
| #endif |
| } |
| |
| #if WARP_Y |
| write_imageui(output, (int2)(d_x, d_y), convert_uint4(as_ushort4(convert_uchar8(pixel.lo * 255.0f)))); |
| #else |
| write_imageui(output, (int2)(d_x, d_y), as_uint4(convert_uchar16(pixel * 255.0f))); |
| #endif |
| |
| } |
| |
| __kernel void |
| kernel_image_warp_1_pixel ( |
| __read_only image2d_t input, |
| __write_only image2d_t output, |
| CLWarpConfig warp_config) |
| { |
| // dest coordinate |
| int d_x = get_global_id(0); |
| int d_y = get_global_id(1); |
| |
| int out_width = get_image_width (output); |
| int out_height = get_image_height (output); |
| |
| const sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR; |
| |
| // source coordinate |
| float s_x = warp_config.proj_mat[0] * d_x + |
| warp_config.proj_mat[1] * d_y + |
| warp_config.proj_mat[2]; |
| float s_y = warp_config.proj_mat[3] * d_x + |
| warp_config.proj_mat[4] * d_y + |
| warp_config.proj_mat[5]; |
| float w = warp_config.proj_mat[6] * d_x + |
| warp_config.proj_mat[7] * d_y + |
| warp_config.proj_mat[8]; |
| w = w != 0.0f ? 1.0f / w : 0.0f; |
| |
| float warp_x = (s_x * w) / (float)out_width; |
| float warp_y = (s_y * w) / (float)out_height; |
| |
| float4 pixel = read_imagef(input, sampler, (float2)(warp_x, warp_y)); |
| |
| write_imagef(output, (int2)(d_x, d_y), pixel); |
| } |
| |