Atlas - yuv_rgb_std_func.h
Home / ext / SDL2 / src / video / yuv2rgb Lines: 1 | Size: 6333 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1// Copyright 2016 Adrien Descamps 2// Distributed under BSD 3-Clause License 3 4/* You need to define the following macros before including this file: 5 STD_FUNCTION_NAME 6 YUV_FORMAT 7 RGB_FORMAT 8*/ 9 10#if RGB_FORMAT == RGB_FORMAT_RGB565 11 12#define PACK_PIXEL(rgb_ptr) \ 13 *(Uint16 *)rgb_ptr = \ 14 ((((Uint16)clampU8(y_tmp+r_tmp)) << 8 ) & 0xF800) | \ 15 ((((Uint16)clampU8(y_tmp+g_tmp)) << 3) & 0x07E0) | \ 16 (((Uint16)clampU8(y_tmp+b_tmp)) >> 3); \ 17 rgb_ptr += 2; \ 18 19#elif RGB_FORMAT == RGB_FORMAT_RGB24 20 21#define PACK_PIXEL(rgb_ptr) \ 22 rgb_ptr[0] = clampU8(y_tmp+r_tmp); \ 23 rgb_ptr[1] = clampU8(y_tmp+g_tmp); \ 24 rgb_ptr[2] = clampU8(y_tmp+b_tmp); \ 25 rgb_ptr += 3; \ 26 27#elif RGB_FORMAT == RGB_FORMAT_RGBA 28 29#define PACK_PIXEL(rgb_ptr) \ 30 *(Uint32 *)rgb_ptr = \ 31 (((Uint32)clampU8(y_tmp+r_tmp)) << 24) | \ 32 (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \ 33 (((Uint32)clampU8(y_tmp+b_tmp)) << 8) | \ 34 0x000000FF; \ 35 rgb_ptr += 4; \ 36 37#elif RGB_FORMAT == RGB_FORMAT_BGRA 38 39#define PACK_PIXEL(rgb_ptr) \ 40 *(Uint32 *)rgb_ptr = \ 41 (((Uint32)clampU8(y_tmp+b_tmp)) << 24) | \ 42 (((Uint32)clampU8(y_tmp+g_tmp)) << 16) | \ 43 (((Uint32)clampU8(y_tmp+r_tmp)) << 8) | \ 44 0x000000FF; \ 45 rgb_ptr += 4; \ 46 47#elif RGB_FORMAT == RGB_FORMAT_ARGB 48 49#define PACK_PIXEL(rgb_ptr) \ 50 *(Uint32 *)rgb_ptr = \ 51 0xFF000000 | \ 52 (((Uint32)clampU8(y_tmp+r_tmp)) << 16) | \ 53 (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \ 54 (((Uint32)clampU8(y_tmp+b_tmp)) << 0); \ 55 rgb_ptr += 4; \ 56 57#elif RGB_FORMAT == RGB_FORMAT_ABGR 58 59#define PACK_PIXEL(rgb_ptr) \ 60 *(Uint32 *)rgb_ptr = \ 61 0xFF000000 | \ 62 (((Uint32)clampU8(y_tmp+b_tmp)) << 16) | \ 63 (((Uint32)clampU8(y_tmp+g_tmp)) << 8) | \ 64 (((Uint32)clampU8(y_tmp+r_tmp)) << 0); \ 65 rgb_ptr += 4; \ 66 67#else 68#error PACK_PIXEL unimplemented 69#endif 70 71 72void STD_FUNCTION_NAME( 73 uint32_t width, uint32_t height, 74 const uint8_t *Y, const uint8_t *U, const uint8_t *V, uint32_t Y_stride, uint32_t UV_stride, 75 uint8_t *RGB, uint32_t RGB_stride, 76 YCbCrType yuv_type) 77{ 78 const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); 79#if YUV_FORMAT == YUV_FORMAT_420 80 #define y_pixel_stride 1 81 #define uv_pixel_stride 1 82 #define uv_x_sample_interval 2 83 #define uv_y_sample_interval 2 84#elif YUV_FORMAT == YUV_FORMAT_422 85 #define y_pixel_stride 2 86 #define uv_pixel_stride 4 87 #define uv_x_sample_interval 2 88 #define uv_y_sample_interval 1 89#elif YUV_FORMAT == YUV_FORMAT_NV12 90 #define y_pixel_stride 1 91 #define uv_pixel_stride 2 92 #define uv_x_sample_interval 2 93 #define uv_y_sample_interval 2 94#endif 95 96 uint32_t x, y; 97 for(y=0; y<(height-(uv_y_sample_interval-1)); y+=uv_y_sample_interval) 98 { 99 const uint8_t *y_ptr1=Y+y*Y_stride, 100 *y_ptr2=Y+(y+1)*Y_stride, 101 *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, 102 *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; 103 104 uint8_t *rgb_ptr1=RGB+y*RGB_stride; 105 106 #if uv_y_sample_interval > 1 107 uint8_t *rgb_ptr2=RGB+(y+1)*RGB_stride; 108 #endif 109 110 for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) 111 { 112 // Compute U and V contributions, common to the four pixels 113 114 int32_t u_tmp = ((*u_ptr)-128); 115 int32_t v_tmp = ((*v_ptr)-128); 116 117 int32_t r_tmp = (v_tmp*param->v_r_factor); 118 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 119 int32_t b_tmp = (u_tmp*param->u_b_factor); 120 121 // Compute the Y contribution for each pixel 122 123 int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); 124 PACK_PIXEL(rgb_ptr1); 125 126 y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); 127 PACK_PIXEL(rgb_ptr1); 128 129 #if uv_y_sample_interval > 1 130 y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); 131 PACK_PIXEL(rgb_ptr2); 132 133 y_tmp = ((y_ptr2[y_pixel_stride]-param->y_shift)*param->y_factor); 134 PACK_PIXEL(rgb_ptr2); 135 #endif 136 137 y_ptr1+=2*y_pixel_stride; 138 y_ptr2+=2*y_pixel_stride; 139 u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 140 v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 141 } 142 143 /* Catch the last pixel, if needed */ 144 if (uv_x_sample_interval == 2 && x == (width-1)) 145 { 146 // Compute U and V contributions, common to the four pixels 147 148 int32_t u_tmp = ((*u_ptr)-128); 149 int32_t v_tmp = ((*v_ptr)-128); 150 151 int32_t r_tmp = (v_tmp*param->v_r_factor); 152 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 153 int32_t b_tmp = (u_tmp*param->u_b_factor); 154 155 // Compute the Y contribution for each pixel 156 157 int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); 158 PACK_PIXEL(rgb_ptr1); 159 160 #if uv_y_sample_interval > 1 161 y_tmp = ((y_ptr2[0]-param->y_shift)*param->y_factor); 162 PACK_PIXEL(rgb_ptr2); 163 #endif 164 } 165 } 166 167 /* Catch the last line, if needed */ 168 if (uv_y_sample_interval == 2 && y == (height-1)) 169 { 170 const uint8_t *y_ptr1=Y+y*Y_stride, 171 *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, 172 *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; 173 174 uint8_t *rgb_ptr1=RGB+y*RGB_stride; 175 176 for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) 177 { 178 // Compute U and V contributions, common to the four pixels 179 180 int32_t u_tmp = ((*u_ptr)-128); 181 int32_t v_tmp = ((*v_ptr)-128); 182 183 int32_t r_tmp = (v_tmp*param->v_r_factor); 184 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 185 int32_t b_tmp = (u_tmp*param->u_b_factor); 186 187 // Compute the Y contribution for each pixel 188 189 int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); 190 PACK_PIXEL(rgb_ptr1); 191 192 y_tmp = ((y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); 193 PACK_PIXEL(rgb_ptr1); 194 195 y_ptr1+=2*y_pixel_stride; 196 u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 197 v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 198 } 199 200 /* Catch the last pixel, if needed */ 201 if (uv_x_sample_interval == 2 && x == (width-1)) 202 { 203 // Compute U and V contributions, common to the four pixels 204 205 int32_t u_tmp = ((*u_ptr)-128); 206 int32_t v_tmp = ((*v_ptr)-128); 207 208 int32_t r_tmp = (v_tmp*param->v_r_factor); 209 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 210 int32_t b_tmp = (u_tmp*param->u_b_factor); 211 212 // Compute the Y contribution for each pixel 213 214 int32_t y_tmp = ((y_ptr1[0]-param->y_shift)*param->y_factor); 215 PACK_PIXEL(rgb_ptr1); 216 } 217 } 218 219 #undef y_pixel_stride 220 #undef uv_pixel_stride 221 #undef uv_x_sample_interval 222 #undef uv_y_sample_interval 223} 224 225#undef STD_FUNCTION_NAME 226#undef YUV_FORMAT 227#undef RGB_FORMAT 228#undef PACK_PIXEL 229[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.