RGB位图转YUV420

本代码只是为了生成YUV数据用于测试. 以下代码有多处可以再优化

uint8_t* yuvArray(uint8_t* rgb, int w, int h)
//+ (unsigned char*)yuvArray: (uint8_t*) rgb width:(int) w height:(int) h  //这是objective-c的写法
{
    int pixelCount = w*h;
    uint8_t* yuv888 = malloc(pixelCount*3);
    uint8_t R,G,B,Y,U,V;
    int n = 0;
    int yuv888bytes = pixelCount*3;
    for(int i=0; i<yuv888bytes; ){
        R = rgb[i++];
        G = rgb[i++];
        B = rgb[i++];
        
        Y =  (int) ((0.257 * R) + (0.504 * G) + (0.098 * B) + 16);
        U =  (int) (-(0.148 * R) - (0.291 * G) + (0.439 * B) + 128);
        V =  (int) ((0.439 * R) - (0.368 * G) - (0.071 * B) + 128);
        yuv888[n++] = Y;
        yuv888[n++] = U;
        yuv888[n++] = V;
    }
    uint8_t* yuv420 = malloc(pixelCount*3/2);
    uint8_t* y = yuv420;
    uint8_t* ptr;
    n = 0;
     /** 生成Y数据 */
    for(int i=0; i<yuv888bytes; i+=3){
        y[n++] = yuv888[i];
    }
    
    n=0;
    uint8_t* u = yuv420 + pixelCount;
    ptr = yuv888;
    int lineszieBytes = w*3;
    /** 生成U数据 */
    for(int i=0; i<h; i+=2){
        for(int j=1; j<lineszieBytes; j+=6){
            u[n++] = (ptr[j] + ptr[j+3] + ptr[j + lineszieBytes] + ptr[j + lineszieBytes + 3])/4;
        }
        ptr += lineszieBytes*2;
    }

    n=0;
    uint8_t* v = yuv420 + pixelCount + w*h/4;
    ptr = yuv888;
    /** 此次可以与上面共用同一个循环, 减少循环次数 */
    for(int i=0; i<h; i+=2){
        for(int j=2; j<lineszieBytes; j+=6){
            v[n++] = (ptr[j] + ptr[j+3] + ptr[j + lineszieBytes] + ptr[j + lineszieBytes + 3])/4;
        }
        ptr += lineszieBytes*2;
    }
    free(yuv888);
    return yuv420;
}

猜你喜欢

转载自blog.csdn.net/wzj_whut/article/details/85254286