BMP转yuV

时间:2024-05-21 18:03:25

BMP转yuVBMP转yuVBMP转yuVBMP转yuVBMP转yuV

三、实验代码

#include <stdio.h>

#include<math.h>

#include <malloc.h>

#include<windows.h>

#include "bmp2yuv.h"

#include "stdlib.h"

 

#define u_int8_t       unsigned __int8

#define u_int             unsigned __int32

#define u_int32_t     unsigned __int32

 

void BMP2RGB(FILE * pFile, BITMAPFILEHEADER&file_h, BITMAPINFOHEADER &info_h, unsignedchar * rgbDataOut)

{

 

         u_int32_t w, h, width, height;

         u_int Loop, i, j;

         unsignedchar mask, *dataBuf, *Data;

 

         //判断像素的实际点阵数

         if(((info_h.biWidth / 8 * info_h.biBitCount) % 4) == 0)

 

                   w = info_h.biWidth;

         else

                   w = (info_h.biWidth*info_h.biBitCount+ 31) / 32 * 4;

         if((info_h.biHeight % 2) == 0)

                   h = info_h.biHeight;

         else

                   h = info_h.biHeight + 1;

 

         width = w / 8 * info_h.biBitCount;//width为实际一行的字节数

         height = h;//height为列数

 

 

         //开辟实际字节数量的缓冲区,读数据,一次读取一个字节

         dataBuf = (unsignedchar*)malloc(width*height);

         Data = (unsignedchar*)malloc(width*height);

 

         fseek(pFile, file_h.bfOffBits, 0);

         if(fread(dataBuf, 1, width*height, pFile) == 0)

         {

                   printf("read file error!\n\n");

                   exit(0);

         }

         //倒序存放

         for (i= 0; i < height; i++)

         for (j= 0; j < width; j++)

         {

                   Data[i*width + j] =dataBuf[(height - i - 1)*width + j];

         }

 

         //根据不同像素位数执行不同操作

         switch(info_h.biBitCount)

         {

         case24:

                   memcpy(rgbDataOut, Data,height*width);

                   if(dataBuf)

                            free(dataBuf);

                   if(Data)

                            free(Data);

                   return;

         case16:

                   if(info_h.biCompression == BI_RGB)

                   {

                            for (Loop = 0; Loop < height * width; Loop += 2)

                            {

                                     *rgbDataOut= (Data[Loop] & 0x1F) << 3;

                                     *(rgbDataOut+ 1) = ((Data[Loop] & 0xE0) >> 2) + ((Data[Loop + 1] & 0x03)<< 6);

                                     *(rgbDataOut+ 2) = (Data[Loop + 1] & 0x7C) << 1;

                                     rgbDataOut+= 3;

                            }

                   }

                   /*biCompression成员的值是BI_RGB时,它没有调色板。16位中,最低的5位表示蓝色分量,

                   中间的5位表示绿色分量,高的5位表示红色分量,一共占用了15位,

                   最高的一位保留,设为0。这种格式也被称作555  16位位图。*/

                   if(dataBuf)

                            free(dataBuf);

                   if(Data)

                            free(Data);

                   return;

         default:

                   RGBQUAD *pRGB = (RGBQUAD*)malloc(sizeof(RGBQUAD)*(unsigned long long)pow(float(2),info_h.biBitCount));

                   if(!MakePalette(pFile, file_h, info_h, pRGB))

                            printf("No palette!");

                   for(Loop = 0; Loop<height*width; Loop++)

                   {

                            switch (info_h.biBitCount)

                            {

                            case 1:

                                     mask =0x80;

                                     break;

                            case 2:

                                     mask =0xC0;

                                     break;

                            case 4:

                                     mask =0xF0;

                                     break;

                            case 8:

                                     mask =0xFF;

                            }

                            int shiftCnt = 1;

                            while (mask)

                            {

                                     unsignedchar index = mask == 0xFF ? Data[Loop] :((Data[Loop] & mask) >> (8 - shiftCnt * info_h.biBitCount));

                                     *rgbDataOut= pRGB[index].rgbBlue;

                                     *(rgbDataOut+ 1) = pRGB[index].rgbGreen;

                                     *(rgbDataOut+ 2) = pRGB[index].rgbRed;

 

                                     if (info_h.biBitCount == 8)

                                               mask= 0;

                                     else

                                               mask>>= info_h.biBitCount;

                                     rgbDataOut+= 3;

                                     shiftCnt++;

                            }

                   }

 

                   if(dataBuf)

                            free(dataBuf);

                   if(Data)

                      free(Data);

                   if(pRGB)

                            free(pRGB);

                   return;

         }

}

 

bool MakePalette(FILE * pFile, BITMAPFILEHEADER&file_h, BITMAPINFOHEADER & info_h, RGBQUAD *pRGB_out)

{

         if((file_h.bfOffBits - sizeof(BITMAPFILEHEADER)-info_h.biSize)== sizeof(RGBQUAD)*pow(float(2),info_h.biBitCount))

         {

                   //fseek(pFile,file_h.bfOffBits - (unsigned int)pow(float(2), info_h.biBitCount), 0);

                   fseek(pFile, sizeof(BITMAPFILEHEADER)+info_h.biSize, 0);

                   fread(pRGB_out, sizeof(RGBQUAD), (unsignedint)pow(float(2),info_h.biBitCount), pFile);

                   returntrue;

         }

         else

                   returnfalse;

}

四、实验结果

BMP转yuV