前阵系统要编译到64位系统环境下,不会64位汇编。只好把代码里涉及到汇编的图像格式转换改成纯运算的方法。

因为是浮点运算,速度很慢。后来抽时间换成乘法查表的方式,计算速度没有像预期那样飙升,因为是用的工作站,或许是因为CPU本身浮点运算够强,不过多少有点益处。

如果换成加法也查表,那就大概需要16MB的空间,把加法运算也加进来查表应该不会提升太多,就没考虑了。

写法上用的C方式,借鉴类似C++的对象结构

  1. #ifndef _RGB_UYVY_INCLUDE_H_  
  2. #define _RGB_UYVY_INCLUDE_H_  
  3.  
  4. typedef struct 
  5. {  
  6.     FLOAT r_table[256];  
  7.     FLOAT g_table[256];  
  8.     FLOAT b_table[256];  
  9. }rgb2yuv_table_t;  
  10.  
  11. static rgb2yuv_table_t* create_rgb_y_table()  
  12. {  
  13.     rgb2yuv_table_t* p_table;  
  14.     INT i;  
  15.  
  16.     p_table = (rgb2yuv_table_t*)malloc(sizeof(rgb2yuv_table_t));  
  17.     if (!p_table)  
  18.         return NULL;  
  19.  
  20.     for (i = 0; i <= 255; i++)  
  21.     {  
  22.         p_table->r_table[i] = 0.299f*i;  
  23.         p_table->g_table[i] = 0.587f*i;  
  24.         p_table->b_table[i] = 0.114f*i;  
  25.     }  
  26.  
  27.     return p_table;  
  28. }  
  29.  
  30. static rgb2yuv_table_t* create_rgb_u_table()  
  31. {  
  32.     rgb2yuv_table_t* p_table;  
  33.     INT i;  
  34.  
  35.     p_table = (rgb2yuv_table_t*)malloc(sizeof(rgb2yuv_table_t));  
  36.     if (!p_table)  
  37.         return NULL;  
  38.  
  39.     for (i = 0; i <= 255; i++)  
  40.     {  
  41.         p_table->r_table[i] = (-0.169f)*i;  
  42.         p_table->g_table[i] = (-0.331f)*i;  
  43.         p_table->b_table[i] = 0.5f*i + 128;  
  44.     }  
  45.  
  46.     return p_table;  
  47. }  
  48.  
  49. static rgb2yuv_table_t* create_rgb_v_table()  
  50. {  
  51.     rgb2yuv_table_t* p_table;  
  52.     INT i;  
  53.  
  54.     p_table = (rgb2yuv_table_t*)malloc(sizeof(rgb2yuv_table_t));  
  55.     if (!p_table)  
  56.         return NULL;  
  57.  
  58.     for (i = 0; i <= 255; i++)  
  59.     {  
  60.         p_table->r_table[i] = 0.5f*i;  
  61.         p_table->g_table[i] = (-0.419f)*i;  
  62.         p_table->b_table[i] = (-0.082f)*i + 128;  
  63.     }  
  64.  
  65.     return p_table;  
  66. }  
  67.  
  68. typedef struct   
  69. {  
  70.     INT i_width;  
  71.     INT i_height;  
  72.  
  73.     INT i_rgb_pixel_byte;  
  74.  
  75.     rgb2yuv_table_t* p_y_table;  
  76.     rgb2yuv_table_t* p_u_table;  
  77.     rgb2yuv_table_t* p_v_table;  
  78.  
  79. } rgb_yuv_sys_t;  
  80.  
  81. static void release_rgb_uyvy(HANDLE handle)  
  82. {  
  83.     rgb_yuv_sys_t* p_sys = (rgb_yuv_sys_t*)handle;  
  84.  
  85.     if (!p_sys)  
  86.         return;  
  87.  
  88.     if (p_sys->p_y_table)  
  89.         free(p_sys->p_y_table);  
  90.  
  91.     if (p_sys->p_u_table)  
  92.         free(p_sys->p_u_table);  
  93.  
  94.     if (p_sys->p_v_table)  
  95.         free(p_sys->p_v_table);  
  96.  
  97.     free(p_sys);  
  98. }  
  99.  
  100. static HANDLE create_rgb_uyvy(INT i_width, INT i_height, INT i_rgb_pixel_bits)  
  101. {  
  102.     rgb_yuv_sys_t* p_sys = (rgb_yuv_sys_t*)malloc(sizeof(rgb_yuv_sys_t));  
  103.     if (!p_sys)  
  104.         return NULL;  
  105.  
  106.     ZeroMemory(p_sys, sizeof(rgb_yuv_sys_t));  
  107.  
  108.     p_sys->i_width = i_width;  
  109.     p_sys->i_height = i_height;  
  110.     p_sys->i_rgb_pixel_byte = i_rgb_pixel_bits / 8;  
  111.  
  112.     p_sys->p_y_table = create_rgb_y_table();  
  113.     if (!p_sys->p_y_table)  
  114.     {  
  115.         release_rgb_uyvy(p_sys);   
  116.         return NULL;  
  117.     }  
  118.  
  119.     p_sys->p_u_table = create_rgb_u_table();  
  120.     if (!p_sys->p_u_table)  
  121.     {  
  122.         release_rgb_uyvy(p_sys);   
  123.         return NULL;  
  124.     }  
  125.  
  126.     p_sys->p_v_table = create_rgb_v_table();  
  127.     if (!p_sys->p_v_table)  
  128.     {  
  129.         release_rgb_uyvy(p_sys);   
  130.         return NULL;  
  131.     }  
  132.  
  133.     return (HANDLE)p_sys;  
  134. }  
  135.  
  136. #define rgb_yuv_pixel(r, g, b, yuv, p_sys)\  
  137.     (yuv) = (BYTE)((p_sys)->r_table[(r)] + (p_sys)->g_table[(g)] + (p_sys)->b_table[(b)])  
  138.  
  139. static void rgb_uyvy(HANDLE handle, BYTE* p_in_r, BYTE* p_in_g, BYTE* p_in_b, BYTE* p_out_uyuv)  
  140. {  
  141.     INT i_line;  
  142.     INT i_pixel;  
  143.  
  144.     rgb_yuv_sys_t* p_table = (rgb_yuv_sys_t*)handle;  
  145.  
  146.     INT i_width = p_table->i_width;  
  147.     INT i_height = p_table->i_height;  
  148.     INT i_rgb_pixel_byte = p_table->i_rgb_pixel_byte;  
  149.  
  150.     rgb2yuv_table_t* p_y_table = p_table->p_y_table;  
  151.     rgb2yuv_table_t* p_u_table = p_table->p_u_table;  
  152.     rgb2yuv_table_t* p_v_table = p_table->p_v_table;  
  153.  
  154.     BYTE* p_y = p_out_uyuv + 1;  
  155.     BYTE* p_u = p_out_uyuv;  
  156.     BYTE* p_v = p_out_uyuv + 2;  
  157.  
  158.     for (i_line = 0; i_line < i_height; i_line++)  
  159.     {  
  160.         for (i_pixel = 0; i_pixel < i_width; i_pixel++)  
  161.         {  
  162.             if ( (i_line+1)%2 )  
  163.             {  
  164.                 rgb_yuv_pixel(*p_in_r, *p_in_g, *p_in_b, *p_y, p_y_table);  
  165.                 rgb_yuv_pixel(*p_in_r, *p_in_g, *p_in_b, *p_u, p_u_table);  
  166.                 rgb_yuv_pixel(*p_in_r, *p_in_g, *p_in_b, *p_v, p_v_table);  
  167.                 p_y += 2; p_u += 4; p_v += 4;  
  168.             }  
  169.             else 
  170.             {  
  171.                 rgb_yuv_pixel(*p_in_r, *p_in_g, *p_in_b, *p_in_y, p_y_table);     
  172.                 p_y += 2;  
  173.             }  
  174.             p_in_r += i_rgb_pixel_byte; p_in_g += i_rgb_pixel_byte; p_in_b += i_rgb_pixel_byte;  
  175.         }  
  176.     }  
  177. }  
  178.  
  179. #endif // _RGB_UYVY_INCLUDE_H_ 

 

具体使用方法:

  1. HANDLE  h_rgb_uyvy = NULL;  
  2. INT     i_width;  
  3. INT     i_height;  
  4. BYTE*   p_rgb32;  
  5. BYTE*   p_uyvy;  
  6.  
  7. h_rgb_uyvy = create_rgb_uyvy(i_width, i_height, 32);  
  8. if (!h_rgb_uyvy)  
  9. {  
  10.     release_rgb_uyvy(h_rgb_uyvy);  
  11.     return;  
  12. }  
  13.  
  14. rgb_uyvy(h_rgb_uyvy, p_rgb32+2, p_rgb32+1, p_rgb32, p_uyvy);  
  15. ....  
  16.  
  17. release_rgb_uyvy(h_rgb_uyvy);  
  18. h_rgb_uyvy = NULL;