此文版权属于作者所有,任何人、媒体或者网站转载、借用都必须征得作者本人同意!
typedef struct yuv2rgb_rgb_t {
int r, g, b;
} yuv2rgb_rgb_t;
static inline void rgb_calc(yuv2rgb_rgb_t* rgb, int Y, int Cr, int Cb) {
rgb->r = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
if (rgb->r < 0)
rgb->r = 0;
else if (rgb->r > 255)
rgb->r = 255;
rgb->g = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1) + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
if (rgb->g < 0)
rgb->g = 0;
else if (rgb->g > 255)
rgb->g = 255;
rgb->b = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
if (rgb->b < 0)
rgb->b = 0;
else if (rgb->b > 255)
rgb->b = 255;
}
#define YUV2RGB_SET_RGB(p, rgb) *p++ = (unsigned char)rgb.r; *p++ = (unsigned char)rgb.g; *p++ = (unsigned char)rgb.b; *p++ = 0xff
static void yuv420sp_to_rgba(unsigned char const* yuv420sp, int width, int height, unsigned char* rgba) {
const int width4 = width * 4;
unsigned char const* y0_ptr = yuv420sp;
unsigned char const* y1_ptr = yuv420sp + width;
unsigned char const* cb_ptr = yuv420sp + (width * height);
unsigned char const* cr_ptr = cb_ptr + 1;
unsigned char* rgba0 = rgba;
unsigned char* rgba1 = rgba + width4;
int Y00, Y01, Y10, Y11;
int Cr = 0;
int Cb = 0;
int r, c;
yuv2rgb_rgb_t rgb00, rgb01, rgb10, rgb11;
for (r = 0; r < height / 2; ++r) {
for (c = 0; c < width / 2; ++c, cr_ptr += 2, cb_ptr += 2) {
Cr = *cr_ptr;
Cb = *cb_ptr;
if (Cb < 0)
Cb += 127;
else
Cb -= 128;
if (Cr < 0)
Cr += 127;
else
Cr -= 128;
Y00 = *y0_ptr++;
Y01 = *y0_ptr++;
Y10 = *y1_ptr++;
Y11 = *y1_ptr++;
rgb_calc(&rgb00, Y00, Cr, Cb);
rgb_calc(&rgb01, Y01, Cr, Cb);
rgb_calc(&rgb10, Y10, Cr, Cb);
rgb_calc(&rgb11, Y11, Cr, Cb);
YUV2RGB_SET_RGB(rgba0, rgb00);
YUV2RGB_SET_RGB(rgba0, rgb01);
YUV2RGB_SET_RGB(rgba1, rgb10);
YUV2RGB_SET_RGB(rgba1, rgb11);
}
y0_ptr += width;
y1_ptr += width;
rgba0 += width4;
rgba1 += width4;
}
}