YUV RGB 转换

来源:互联网 发布:c语言char怎么赋值 编辑:程序博客网 时间:2024/05/22 08:04

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

[cpp] view plaincopyprint?
  1. <span style="font-size: 14px;">#include <math.h> 
  2. #include <stdint.h> 
  3.   
  4. #define ALIGN_2K(x) ((x + 2047) & ~ 2047) 
  5. struct Buffer { 
  6.     void * data; 
  7.     size_t size; 
  8.     size_t width, height; 
  9. }; 
  10.   
  11. static int convertRGB888toRGB565(struct Buffer src,struct Buffer dst); 
  12. static int convertRGB888toYCbCr420SP(struct Buffer src,struct Buffer dst); 
  13.   
  14. int main() { 
  15.     struct Buffer src, dst; 
  16.   
  17.     FILE * in = fopen("input.yuv","rb"); 
  18.     FILE * out = fopen("output.yuv","wb"); 
  19.     int width = 800; 
  20.     int height = 480; 
  21.     uint8_t *srcData = malloc(width * height * 3); 
  22.     uint8_t *dstData = malloc(width * height + ALIGN_2K(width * height)); 
  23.     fread(srcData, width * height * 3, 1, in); 
  24.   
  25.     src.data = srcData; 
  26.     src.size = width * height * 3; 
  27.     src.width = WIDTH; 
  28.     src.height = HEIGHT; 
  29.   
  30.     dst.data = dstData; 
  31.     dst.size = width * height + ALIGN_2K(width * height); 
  32.     dst.width = WIDTH; 
  33.     dst.height = HEIGHT; 
  34.      
  35.     convertRGB888toYCbCr420SP(src, dst); 
  36.   
  37.     fwrite(dstData, width * height + ALIGN_2K(width * height), 1, out); 
  38.   
  39.     free(srcData); 
  40.     free(dstData); 
  41.     fclose(in); 
  42.     fclose(out); 
  43.   
  44.     return 0; 
  45.   
  46.   
  47.   
  48. static int convertRGB888toRGB565(struct Buffer src,struct Buffer dst) { 
  49.     uint8_t *srcData, *dstData; 
  50.   
  51.     srcData = (uint8_t *)src.data; 
  52.     dstData = (uint8_t *)dst.data; 
  53.   
  54.     for (int c = 0, i = 0; c < src.width * src.height;) { 
  55.             //scale down each component to 5 or 6 bits 
  56.             uint8_t r, g, b; 
  57.             r = srcData[c++]; 
  58.             g = srcData[c++]; 
  59.             b = srcData[c++]; 
  60.             r = (uint8_t)((srcData[c++]/255.0)*31); //R component 
  61.             g = (uint8_t)((srcData[c++]/255.0)*63); //G component 
  62.             b = (uint8_t)((srcData[c++]/255.0)*31); //B component 
  63.             dstData[i++] = ((r & 0x1f) << 3) | ((g >> 3) & 0x7); //R (5 bits) +  G (upper 3 bits) 
  64.             dstData[i++] = ((g & 0x7) << 5) | (b & 0x1f); //G (lower 3 bits) + B (5 bits) 
  65.     } 
  66.   
  67.     return 0; 
  68.   
  69.   
  70. static int convertRGB888toYCbCr420SP(struct Buffer src,struct Buffer dst) { 
  71.     uint8_t *srcData, *dstData; 
  72.   
  73.     srcData = (uint8_t *)src.data; 
  74.     dstData = (uint8_t *)dst.data; 
  75.   
  76.     //derive the luma 
  77.     for (int c = 0, i = 0, j = 0; c < src.width * src.height * 3;) { 
  78.         uint8_t r, g, b; 
  79.         r = srcData[c++]; 
  80.         g = srcData[c++]; 
  81.         b = srcData[c++]; 
  82.         //stolen from wikipedia 
  83.         uint8_t y, cb, cr; 
  84.   
  85.         y = (uint8_t)(16 + (65.481 * r + 128.553 * g + 24.966 * b)/256); 
  86.         cb = (uint8_t)(128 + (-37.979 * r - 74.203 * g + 112 * b)/256); 
  87.         cr = (uint8_t)(128 + (112 * r - 93.786 * g - 18.214 * b)/256); 
  88.         dstData[i++] = y; 
  89.         (dstData + ALIGN_2K(src.width * src.height))[j++] = cb; 
  90.         (dstData + ALIGN_2K(src.width * src.height))[j++] = cr; 
  91.     } 
  92.     return 0; 
  93. }</span> 

0 0