windows下存储位图及YUV转RGB

 

static int av_create_bmp(char* filename,BYTE *pRGBBuffer,int width,int height,int bpp)
{
    BITMAPFILEHEADER bmpheader;
    BITMAPINFO bmpinfo;
    FILE *fp;

    fp = fopen(filename,"wb");
    if(!fp)return -1;

    bmpheader.bfType = ('M'<<8)|'B';
    bmpheader.bfReserved1 = 0;
    bmpheader.bfReserved2 = 0;
    bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;

    bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpinfo.bmiHeader.biWidth = width;
    bmpinfo.bmiHeader.biHeight = height;
    bmpinfo.bmiHeader.biPlanes = 1;
    bmpinfo.bmiHeader.biBitCount = bpp;
    bmpinfo.bmiHeader.biCompression = BI_RGB;
    bmpinfo.bmiHeader.biSizeImage = 0;
    bmpinfo.bmiHeader.biXPelsPerMeter = 100;
    bmpinfo.bmiHeader.biYPelsPerMeter = 100;
    bmpinfo.bmiHeader.biClrUsed = 0;
    bmpinfo.bmiHeader.biClrImportant = 0;

    fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
    fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
    fwrite(pRGBBuffer,width*height*bpp/8,1,fp);
    fclose(fp);

    return 0;
}


void YUV_TO_RGB24(uint8_t *puc_y,int stride_y,uint8_t *puc_u,uint8_t *puc_v, int stride_uv, 
                  uint8_t *puc_out,int width_y,int height_y,int stride_out) 
{
    int y, horiz_count;
    uint8_t *puc_out_remembered;
    //int stride_out = width_y * 3;

    if (height_y < 0) {
        //we are flipping our output upside-down
        height_y  = -height_y;
        puc_y     += (height_y   - 1) * stride_y ;
        puc_u     += (height_y/2 - 1) * stride_uv;
        puc_v     += (height_y/2 - 1) * stride_uv;
        stride_y  = -stride_y;
        stride_uv = -stride_uv;
    }

    horiz_count = -(width_y >> 3);

    for (y=0; y<height_y; y++) {
        if (y == height_y-1) {
            //this is the last output line - we need to be careful not to overrun the end of this line
            uint8_t temp_buff[3*MAXIMUM_Y_WIDTH+1];
            puc_out_remembered = puc_out;
            puc_out = temp_buff; //write the RGB to a temporary store
        }
        _asm {
                push eax
                push ebx
                push ecx
                push edx
                push edi

                mov eax, puc_out       
                mov ebx, puc_y       
                mov ecx, puc_u       
                mov edx, puc_v
                mov edi, horiz_count

horiz_loop:

                movd mm2, [ecx]
                pxor mm7, mm7

                movd mm3, [edx]
                punpcklbw mm2, mm7       

                movq mm0, [ebx]          
                punpcklbw mm3, mm7       

                movq mm1, mmw_0x00ff     

                psubusb mm0, mmb_0x10    

                psubw mm2, mmw_0x0080    
                pand mm1, mm0            

                psubw mm3, mmw_0x0080    
                psllw mm1, 3             

                psrlw mm0, 8             
                psllw mm2, 3             

                pmulhw mm1, mmw_mult_Y   //0x2568
                psllw mm0, 3             

                psllw mm3, 3             
                movq mm5, mm3            

                pmulhw mm5, mmw_mult_V_R //0x3343
                movq mm4, mm2            

                pmulhw mm0, mmw_mult_Y   
                movq mm7, mm1            

                pmulhw mm2, mmw_mult_U_G //0xf36e
                paddsw mm7, mm5

                pmulhw mm3, mmw_mult_V_G //0xe5e2
                packuswb mm7, mm7

                pmulhw mm4, mmw_mult_U_B //0x40cf
                paddsw mm5, mm0      

                packuswb mm5, mm5
                paddsw mm2, mm3          

                movq mm3, mm1            
                movq mm6, mm1            

                paddsw mm3, mm4
                paddsw mm6, mm2

                punpcklbw mm7, mm5
                paddsw mm2, mm0

                packuswb mm6, mm6
                packuswb mm2, mm2

                packuswb mm3, mm3
                paddsw mm4, mm0

                packuswb mm4, mm4
                punpcklbw mm6, mm2

                punpcklbw mm3, mm4

                // 32-bit shuffle.
                pxor mm0, mm0

                movq mm1, mm6
                punpcklbw mm1, mm0

                movq mm0, mm3
                punpcklbw mm0, mm7

                movq mm2, mm0

                punpcklbw mm0, mm1
                punpckhbw mm2, mm1

                // 24-bit shuffle and sav
                movd   [eax], mm0
                psrlq mm0, 32

                movd  3[eax], mm0

                movd  6[eax], mm2


                psrlq mm2, 32            

                movd  9[eax], mm2        

                // 32-bit shuffle.
                pxor mm0, mm0            

                movq mm1, mm6            
                punpckhbw mm1, mm0       

                movq mm0, mm3            
                punpckhbw mm0, mm7       

                movq mm2, mm0            

                punpcklbw mm0, mm1       
                punpckhbw mm2, mm1       

                // 24-bit shuffle and sav
                movd 12[eax], mm0        
                psrlq mm0, 32            

                movd 15[eax], mm0        
                add ebx, 8               

                movd 18[eax], mm2        
                psrlq mm2, 32            

                add ecx, 4               
                add edx, 4               

                movd 21[eax], mm2        
                add eax, 24              

                inc edi
                jne horiz_loop

                pop edi
                pop edx
                pop ecx
                pop ebx
                pop eax

                emms
        }


        if (y == height_y-1) {
            //last line of output - we have used the temp_buff and need to copy
            int x = 3 * width_y;                  //interation counter
            uint8_t *ps = puc_out;                // source pointer (temporary line store)
            uint8_t *pd = puc_out_remembered;     // dest pointer
            while (x--) *(pd++) = *(ps++);          // copy the line
        }

        puc_y   += stride_y;
        if (y%2) {
            puc_u   += stride_uv;
            puc_v   += stride_uv;
        }
        puc_out += stride_out; 
    }
}
  1. static int av_create_bmp(char* filename,BYTE *pRGBBuffer,int width,int height,int bpp)
  2. {
  3.     BITMAPFILEHEADER bmpheader;
  4.     BITMAPINFO bmpinfo;
  5.     FILE *fp;
  6.     fp = fopen(filename,"wb");
  7.     if(!fp)return -1;
  8.     bmpheader.bfType = ('M'<<8)|'B';
  9.     bmpheader.bfReserved1 = 0;
  10.     bmpheader.bfReserved2 = 0;
  11.     bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  12.     bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;
  13.     bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  14.     bmpinfo.bmiHeader.biWidth = width;
  15.     bmpinfo.bmiHeader.biHeight = height;
  16.     bmpinfo.bmiHeader.biPlanes = 1;
  17.     bmpinfo.bmiHeader.biBitCount = bpp;
  18.     bmpinfo.bmiHeader.biCompression = BI_RGB;
  19.     bmpinfo.bmiHeader.biSizeImage = 0;
  20.     bmpinfo.bmiHeader.biXPelsPerMeter = 100;
  21.     bmpinfo.bmiHeader.biYPelsPerMeter = 100;
  22.     bmpinfo.bmiHeader.biClrUsed = 0;
  23.     bmpinfo.bmiHeader.biClrImportant = 0;
  24.     fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
  25.     fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
  26.     fwrite(pRGBBuffer,width*height*bpp/8,1,fp);
  27.     fclose(fp);
  28.     return 0;
  29. }

  1. void YUV_TO_RGB24(uint8_t *puc_y,int stride_y,uint8_t *puc_u,uint8_t *puc_v, int stride_uv, 
  2.                   uint8_t *puc_out,int width_y,int height_y,int stride_out) 
  3. {
  4.     int y, horiz_count;
  5.     uint8_t *puc_out_remembered;
  6.     //int stride_out = width_y * 3;
  7.     if (height_y < 0) {
  8.         //we are flipping our output upside-down
  9.         height_y  = -height_y;
  10.         puc_y     += (height_y   - 1) * stride_y ;
  11.         puc_u     += (height_y/2 - 1) * stride_uv;
  12.         puc_v     += (height_y/2 - 1) * stride_uv;
  13.         stride_y  = -stride_y;
  14.         stride_uv = -stride_uv;
  15.     }
  16.     horiz_count = -(width_y >> 3);
  17.     for (y=0; y<height_y; y++) {
  18.         if (y == height_y-1) {
  19.             //this is the last output line - we need to be careful not to overrun the end of this line
  20.             uint8_t temp_buff[3*MAXIMUM_Y_WIDTH+1];
  21.             puc_out_remembered = puc_out;
  22.             puc_out = temp_buff; //write the RGB to a temporary store
  23.         }
  24.         _asm {
  25.                 push eax
  26.                 push ebx
  27.                 push ecx
  28.                 push edx
  29.                 push edi
  30.                 mov eax, puc_out       
  31.                 mov ebx, puc_y       
  32.                 mov ecx, puc_u       
  33.                 mov edx, puc_v
  34.                 mov edi, horiz_count
  35. horiz_loop:
  36.                 movd mm2, [ecx]
  37.                 pxor mm7, mm7
  38.                 movd mm3, [edx]
  39.                 punpcklbw mm2, mm7       
  40.                 movq mm0, [ebx]          
  41.                 punpcklbw mm3, mm7       
  42.                 movq mm1, mmw_0x00ff     
  43.                 psubusb mm0, mmb_0x10    
  44.                 psubw mm2, mmw_0x0080    
  45.                 pand mm1, mm0            
  46.                 psubw mm3, mmw_0x0080    
  47.                 psllw mm1, 3             
  48.                 psrlw mm0, 8             
  49.                 psllw mm2, 3             
  50.                 pmulhw mm1, mmw_mult_Y   //0x2568
  51.                 psllw mm0, 3             
  52.                 psllw mm3, 3             
  53.                 movq mm5, mm3            
  54.                 pmulhw mm5, mmw_mult_V_R //0x3343
  55.                 movq mm4, mm2            
  56.                 pmulhw mm0, mmw_mult_Y   
  57.                 movq mm7, mm1            
  58.                 pmulhw mm2, mmw_mult_U_G //0xf36e
  59.                 paddsw mm7, mm5
  60.                 pmulhw mm3, mmw_mult_V_G //0xe5e2
  61.                 packuswb mm7, mm7
  62.                 pmulhw mm4, mmw_mult_U_B //0x40cf
  63.                 paddsw mm5, mm0      
  64.                 packuswb mm5, mm5
  65.                 paddsw mm2, mm3          
  66.                 movq mm3, mm1            
  67.                 movq mm6, mm1            
  68.                 paddsw mm3, mm4
  69.                 paddsw mm6, mm2
  70.                 punpcklbw mm7, mm5
  71.                 paddsw mm2, mm0
  72.                 packuswb mm6, mm6
  73.                 packuswb mm2, mm2
  74.                 packuswb mm3, mm3
  75.                 paddsw mm4, mm0
  76.                 packuswb mm4, mm4
  77.                 punpcklbw mm6, mm2
  78.                 punpcklbw mm3, mm4
  79.                 // 32-bit shuffle.
  80.                 pxor mm0, mm0
  81.                 movq mm1, mm6
  82.                 punpcklbw mm1, mm0
  83.                 movq mm0, mm3
  84.                 punpcklbw mm0, mm7
  85.                 movq mm2, mm0
  86.                 punpcklbw mm0, mm1
  87.                 punpckhbw mm2, mm1
  88.                 // 24-bit shuffle and sav
  89.                 movd   [eax], mm0
  90.                 psrlq mm0, 32
  91.                 movd  3[eax], mm0
  92.                 movd  6[eax], mm2
  93.                 psrlq mm2, 32            
  94.                 movd  9[eax], mm2        
  95.                 // 32-bit shuffle.
  96.                 pxor mm0, mm0            
  97.                 movq mm1, mm6            
  98.                 punpckhbw mm1, mm0       
  99.                 movq mm0, mm3            
  100.                 punpckhbw mm0, mm7       
  101.                 movq mm2, mm0            
  102.                 punpcklbw mm0, mm1       
  103.                 punpckhbw mm2, mm1       
  104.                 // 24-bit shuffle and sav
  105.                 movd 12[eax], mm0        
  106.                 psrlq mm0, 32            
  107.                 movd 15[eax], mm0        
  108.                 add ebx, 8               
  109.                 movd 18[eax], mm2        
  110.                 psrlq mm2, 32            
  111.                 add ecx, 4               
  112.                 add edx, 4               
  113.                 movd 21[eax], mm2        
  114.                 add eax, 24              
  115.                 inc edi
  116.                 jne horiz_loop
  117.                 pop edi
  118.                 pop edx
  119.                 pop ecx
  120.                 pop ebx
  121.                 pop eax
  122.                 emms
  123.         }
  124.         if (y == height_y-1) {
  125.             //last line of output - we have used the temp_buff and need to copy
  126.             int x = 3 * width_y;                  //interation counter
  127.             uint8_t *ps = puc_out;                // source pointer (temporary line store)
  128.             uint8_t *pd = puc_out_remembered;     // dest pointer
  129.             while (x--) *(pd++) = *(ps++);          // copy the line
  130.         }
  131.         puc_y   += stride_y;
  132.         if (y%2) {
  133.             puc_u   += stride_uv;
  134.             puc_v   += stride_uv;
  135.         }
  136.         puc_out += stride_out; 
  137.     }
  138. }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值