Re: Как переводить из YV12 в RGB24?
От: romson  
Дата: 14.07.04 10:57
Оценка:
Здравствуйте, Hatawa, Вы писали:

H>Заранее спасибо.


Способов много. Например, взять кусочек XviD'а:

/*    yuv -> rgb def's */

#define RGB_Y_OUT        1.164
#define B_U_OUT            2.018
#define Y_ADD_OUT        16

#define G_U_OUT            0.391
#define G_V_OUT            0.813
#define U_ADD_OUT        128

#define R_V_OUT            1.596
#define V_ADD_OUT        128


#define SCALEBITS_OUT    13
#define FIX_OUT(x)        ((uint16_t) ((x) * (1L<<SCALEBITS_OUT) + 0.5))

/* initialize rgb lookup tables */

void
colorspace_init(void)
{
    int32_t i;

    for (i = 0; i < 256; i++) {
        RGB_Y_tab[i] = FIX_OUT(RGB_Y_OUT) * (i - Y_ADD_OUT);
        B_U_tab[i] = FIX_OUT(B_U_OUT) * (i - U_ADD_OUT);
        G_U_tab[i] = FIX_OUT(G_U_OUT) * (i - U_ADD_OUT);
        G_V_tab[i] = FIX_OUT(G_V_OUT) * (i - V_ADD_OUT);
        R_V_tab[i] = FIX_OUT(R_V_OUT) * (i - V_ADD_OUT);
    }
}

/* yuv 4:2:0 planar -> rgb24 */

void
yv12_to_rgb24_c(uint8_t * dst,
                int dst_stride,
                uint8_t * y_src,
                uint8_t * u_src,
                uint8_t * v_src,
                int y_stride,
                int uv_stride,
                int width,
                int height)
{
    const uint32_t dst_dif = 6 * dst_stride - 3 * width;
    int32_t y_dif = 2 * y_stride - width;

    uint8_t *dst2 = dst + 3 * dst_stride;
    uint8_t *y_src2 = y_src + y_stride;
    uint32_t x, y;

    if (height < 0) {            /* flip image? */
        height = -height;
        y_src += (height - 1) * y_stride;
        y_src2 = y_src - y_stride;
        u_src += (height / 2 - 1) * uv_stride;
        v_src += (height / 2 - 1) * uv_stride;
        y_dif = -width - 2 * y_stride;
        uv_stride = -uv_stride;
    }

    for (y = height / 2; y; y--) {
        /* process one 2x2 block per iteration */
        for (x = 0; x < (uint32_t) width / 2; x++) {
            int u, v;
            int b_u, g_uv, r_v, rgb_y;
            int r, g, b;

            u = u_src[x];
            v = v_src[x];

            b_u = B_U_tab[u];
            g_uv = G_U_tab[u] + G_V_tab[v];
            r_v = R_V_tab[v];

            rgb_y = RGB_Y_tab[*y_src];
            b = (rgb_y + b_u) >> SCALEBITS_OUT;
            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
            r = (rgb_y + r_v) >> SCALEBITS_OUT;
            dst[0] = MAX(0, MIN(255, b));
            dst[1] = MAX(0, MIN(255, g));
            dst[2] = MAX(0, MIN(255, r));

            y_src++;
            rgb_y = RGB_Y_tab[*y_src];
            b = (rgb_y + b_u) >> SCALEBITS_OUT;
            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
            r = (rgb_y + r_v) >> SCALEBITS_OUT;
            dst[3] = MAX(0, MIN(255, b));
            dst[4] = MAX(0, MIN(255, g));
            dst[5] = MAX(0, MIN(255, r));
            y_src++;

            rgb_y = RGB_Y_tab[*y_src2];
            b = (rgb_y + b_u) >> SCALEBITS_OUT;
            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
            r = (rgb_y + r_v) >> SCALEBITS_OUT;
            dst2[0] = MAX(0, MIN(255, b));
            dst2[1] = MAX(0, MIN(255, g));
            dst2[2] = MAX(0, MIN(255, r));
            y_src2++;

            rgb_y = RGB_Y_tab[*y_src2];
            b = (rgb_y + b_u) >> SCALEBITS_OUT;
            g = (rgb_y - g_uv) >> SCALEBITS_OUT;
            r = (rgb_y + r_v) >> SCALEBITS_OUT;
            dst2[3] = MAX(0, MIN(255, b));
            dst2[4] = MAX(0, MIN(255, g));
            dst2[5] = MAX(0, MIN(255, r));
            y_src2++;

            dst += 6;
            dst2 += 6;
        }

        dst += dst_dif;
        dst2 += dst_dif;

        y_src += y_dif;
        y_src2 += y_dif;

        u_src += uv_stride;
        v_src += uv_stride;
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.