Atlas - yuv_rgb_std_func.h
Home / ext / SDL / src / video / yuv2rgb Lines: 1 | Size: 7263 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#elif RGB_FORMAT == RGB_FORMAT_XBGR2101010 68 69#define PACK_PIXEL(rgb_ptr) \ 70 *(Uint32 *)rgb_ptr = \ 71 0xC0000000 | \ 72 (((Uint32)clamp10(y_tmp+b_tmp)) << 20) | \ 73 (((Uint32)clamp10(y_tmp+g_tmp)) << 10) | \ 74 (((Uint32)clamp10(y_tmp+r_tmp)) << 0); \ 75 rgb_ptr += 4; \ 76 77#else 78#error PACK_PIXEL unimplemented 79#endif 80 81 82#ifdef _MSC_VER /* Visual Studio analyzer can't tell that we're building this with different constants */ 83#pragma warning(push) 84#pragma warning(disable : 6239) 85#endif 86 87#undef YUV_TYPE 88#if YUV_BITS > 8 89#define YUV_TYPE uint16_t 90#else 91#define YUV_TYPE uint8_t 92#endif 93#undef UV_OFFSET 94#define UV_OFFSET (1 << ((YUV_BITS)-1)) 95 96#undef GET 97#if YUV_BITS == 10 98#define GET(X) ((X) >> 6) 99#else 100#define GET(X) (X) 101#endif 102 103void STD_FUNCTION_NAME( 104 uint32_t width, uint32_t height, 105 const YUV_TYPE *Y, const YUV_TYPE *U, const YUV_TYPE *V, uint32_t Y_stride, uint32_t UV_stride, 106 uint8_t *RGB, uint32_t RGB_stride, 107 YCbCrType yuv_type) 108{ 109 const YUV2RGBParam *const param = &(YUV2RGB[yuv_type]); 110#if YUV_FORMAT == YUV_FORMAT_420 111 #define y_pixel_stride 1 112 #define uv_pixel_stride 1 113 #define uv_x_sample_interval 2 114 #define uv_y_sample_interval 2 115#elif YUV_FORMAT == YUV_FORMAT_422 116 #define y_pixel_stride 2 117 #define uv_pixel_stride 4 118 #define uv_x_sample_interval 2 119 #define uv_y_sample_interval 1 120#elif YUV_FORMAT == YUV_FORMAT_NV12 121 #define y_pixel_stride 1 122 #define uv_pixel_stride 2 123 #define uv_x_sample_interval 2 124 #define uv_y_sample_interval 2 125#endif 126 127 Y_stride /= sizeof(YUV_TYPE); 128 UV_stride /= sizeof(YUV_TYPE); 129 130 uint32_t x, y; 131 for(y=0; y<(height-(uv_y_sample_interval-1)); y+=uv_y_sample_interval) 132 { 133 const YUV_TYPE *y_ptr1=Y+y*Y_stride, 134 *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, 135 *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; 136 137 #if uv_y_sample_interval > 1 138 const YUV_TYPE *y_ptr2=Y+(y+1)*Y_stride; 139 #endif 140 141 uint8_t *rgb_ptr1=RGB+y*RGB_stride; 142 143 #if uv_y_sample_interval > 1 144 uint8_t *rgb_ptr2=RGB+(y+1)*RGB_stride; 145 #endif 146 147 for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) 148 { 149 // Compute U and V contributions, common to the four pixels 150 151 int32_t u_tmp = (GET(*u_ptr)-UV_OFFSET); 152 int32_t v_tmp = (GET(*v_ptr)-UV_OFFSET); 153 154 int32_t r_tmp = (v_tmp*param->v_r_factor); 155 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 156 int32_t b_tmp = (u_tmp*param->u_b_factor); 157 158 // Compute the Y contribution for each pixel 159 160 int32_t y_tmp = (GET(y_ptr1[0]-param->y_shift)*param->y_factor); 161 PACK_PIXEL(rgb_ptr1); 162 163 y_tmp = (GET(y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); 164 PACK_PIXEL(rgb_ptr1); 165 166 #if uv_y_sample_interval > 1 167 y_tmp = (GET(y_ptr2[0]-param->y_shift)*param->y_factor); 168 PACK_PIXEL(rgb_ptr2); 169 170 y_tmp = (GET(y_ptr2[y_pixel_stride]-param->y_shift)*param->y_factor); 171 PACK_PIXEL(rgb_ptr2); 172 #endif 173 174 y_ptr1+=2*y_pixel_stride; 175 #if uv_y_sample_interval > 1 176 y_ptr2+=2*y_pixel_stride; 177 #endif 178 u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 179 v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 180 } 181 182 /* Catch the last pixel, if needed */ 183#if uv_x_sample_interval == 2 184 if (x == (width-1)) 185 { 186 // Compute U and V contributions, common to the four pixels 187 188 int32_t u_tmp = (GET(*u_ptr)-UV_OFFSET); 189 int32_t v_tmp = (GET(*v_ptr)-UV_OFFSET); 190 191 int32_t r_tmp = (v_tmp*param->v_r_factor); 192 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 193 int32_t b_tmp = (u_tmp*param->u_b_factor); 194 195 // Compute the Y contribution for each pixel 196 197 int32_t y_tmp = (GET(y_ptr1[0]-param->y_shift)*param->y_factor); 198 PACK_PIXEL(rgb_ptr1); 199 200 #if uv_y_sample_interval > 1 201 y_tmp = (GET(y_ptr2[0]-param->y_shift)*param->y_factor); 202 PACK_PIXEL(rgb_ptr2); 203 #endif 204 } 205#endif 206 } 207 208 /* Catch the last line, if needed */ 209#if uv_y_sample_interval == 2 210 if (y == (height-1)) 211 { 212 const YUV_TYPE *y_ptr1=Y+y*Y_stride, 213 *u_ptr=U+(y/uv_y_sample_interval)*UV_stride, 214 *v_ptr=V+(y/uv_y_sample_interval)*UV_stride; 215 216 uint8_t *rgb_ptr1=RGB+y*RGB_stride; 217 218 for(x=0; x<(width-(uv_x_sample_interval-1)); x+=uv_x_sample_interval) 219 { 220 // Compute U and V contributions, common to the four pixels 221 222 int32_t u_tmp = (GET(*u_ptr)-UV_OFFSET); 223 int32_t v_tmp = (GET(*v_ptr)-UV_OFFSET); 224 225 int32_t r_tmp = (v_tmp*param->v_r_factor); 226 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 227 int32_t b_tmp = (u_tmp*param->u_b_factor); 228 229 // Compute the Y contribution for each pixel 230 231 int32_t y_tmp = (GET(y_ptr1[0]-param->y_shift)*param->y_factor); 232 PACK_PIXEL(rgb_ptr1); 233 234 y_tmp = (GET(y_ptr1[y_pixel_stride]-param->y_shift)*param->y_factor); 235 PACK_PIXEL(rgb_ptr1); 236 237 y_ptr1+=2*y_pixel_stride; 238 u_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 239 v_ptr+=2*uv_pixel_stride/uv_x_sample_interval; 240 } 241 242 /* Catch the last pixel, if needed */ 243#if uv_x_sample_interval == 2 244 if (x == (width-1)) 245 { 246 // Compute U and V contributions, common to the four pixels 247 248 int32_t u_tmp = (GET(*u_ptr)-UV_OFFSET); 249 int32_t v_tmp = (GET(*v_ptr)-UV_OFFSET); 250 251 int32_t r_tmp = (v_tmp*param->v_r_factor); 252 int32_t g_tmp = (u_tmp*param->u_g_factor + v_tmp*param->v_g_factor); 253 int32_t b_tmp = (u_tmp*param->u_b_factor); 254 255 // Compute the Y contribution for each pixel 256 257 int32_t y_tmp = (GET(y_ptr1[0]-param->y_shift)*param->y_factor); 258 PACK_PIXEL(rgb_ptr1); 259 } 260#endif 261 } 262#endif 263 264 #undef y_pixel_stride 265 #undef uv_pixel_stride 266 #undef uv_x_sample_interval 267 #undef uv_y_sample_interval 268} 269 270#ifdef _MSC_VER 271#pragma warning(pop) 272#endif 273 274#undef STD_FUNCTION_NAME 275#undef YUV_FORMAT 276#undef RGB_FORMAT 277#undef PACK_PIXEL 278[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.