yuv420sp to rgba 算法

12 篇文章 0 订阅

此文版权属于作者所有,任何人、媒体或者网站转载、借用都必须征得作者本人同意!

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;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值