YUV RGB 转换

来源:互联网 发布:阿里云快照策略 编辑:程序博客网 时间:2024/06/03 11:53

在网上看到一个开源项目的代码,写的非常整洁,易懂,特此记录下来,网址忘了,还望见谅!!

#include <math.h>#include <stdint.h> #define ALIGN_2K(x) ((x + 2047) & ~ 2047)struct Buffer {    void * data;    size_t size;    size_t width, height;}; static int convertRGB888toRGB565(struct Buffer src, struct Buffer dst);static int convertRGB888toYCbCr420SP(struct Buffer src, struct Buffer dst); int main() {    struct Buffer src, dst;     FILE * in = fopen("input.yuv", "rb");    FILE * out = fopen("output.yuv", "wb");    int width = 800;    int height = 480;    uint8_t *srcData = malloc(width * height * 3);    uint8_t *dstData = malloc(width * height + ALIGN_2K(width * height));    fread(srcData, width * height * 3, 1, in);     src.data = srcData;    src.size = width * height * 3;    src.width = WIDTH;    src.height = HEIGHT;     dst.data = dstData;    dst.size = width * height + ALIGN_2K(width * height);    dst.width = WIDTH;    dst.height = HEIGHT;        convertRGB888toYCbCr420SP(src, dst);     fwrite(dstData, width * height + ALIGN_2K(width * height), 1, out);     free(srcData);    free(dstData);    fclose(in);    fclose(out);     return 0;  } static int convertRGB888toRGB565(struct Buffer src, struct Buffer dst) {    uint8_t *srcData, *dstData;     srcData = (uint8_t *)src.data;    dstData = (uint8_t *)dst.data;     for (int c = 0, i = 0; c < src.width * src.height;) {            //scale down each component to 5 or 6 bits            uint8_t r, g, b;            r = srcData[c++];            g = srcData[c++];            b = srcData[c++];            r = (uint8_t)((srcData[c++]/255.0)*31); //R component            g = (uint8_t)((srcData[c++]/255.0)*63); //G component            b = (uint8_t)((srcData[c++]/255.0)*31); //B component            dstData[i++] = ((r & 0x1f) << 3) | ((g >> 3) & 0x7); //R (5 bits) +  G (upper 3 bits)            dstData[i++] = ((g & 0x7) << 5) | (b & 0x1f); //G (lower 3 bits) + B (5 bits)    }     return 0;}  static int convertRGB888toYCbCr420SP(struct Buffer src, struct Buffer dst) {    uint8_t *srcData, *dstData;     srcData = (uint8_t *)src.data;    dstData = (uint8_t *)dst.data;     //derive the luma    for (int c = 0, i = 0, j = 0; c < src.width * src.height * 3;) {        uint8_t r, g, b;        r = srcData[c++];        g = srcData[c++];        b = srcData[c++];        //stolen from wikipedia        uint8_t y, cb, cr;         y = (uint8_t)(16 + (65.481 * r + 128.553 * g + 24.966 * b)/256);        cb = (uint8_t)(128 + (-37.979 * r - 74.203 * g + 112 * b)/256);        cr = (uint8_t)(128 + (112 * r - 93.786 * g - 18.214 * b)/256);        dstData[i++] = y;        (dstData + ALIGN_2K(src.width * src.height))[j++] = cb;        (dstData + ALIGN_2K(src.width * src.height))[j++] = cr;    }    return 0;}


原创粉丝点击