• bitmap解码


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define BYTE unsigned char
    #define WORD short
    #define DWORD long
    
    #define SUCCESS 0
    #define FAILURE 0xFFFFFFFF
    #define VOID void
    
    #define CHECK_NULL_POINT(x) { if(NULL == (x)) return FAILURE;}
    #define CHECK_NULL_RETURN(x) { if(0 == (x)) return FAILURE; }
    #define CHECK_FALSE_RETURN(x) { if(!(x)) return FAILURE; }
    #define CHECK_FAIL_RETURN(x) { if(FAILURE == (x)) return FAILURE; }
    #define GET_RGB_QUAD_SIZE(x) (1 == (x) ? 2 : (4 == (x) ? 16 : (8 == (x) ? 256 : (16 == (x) ? 65536 : 0))))
    
    #define LOG_ERR(format, ...) do { printf("[ ERR ]: "); printf(format, ##__VA_ARGS__); } while (0)
    #define LOG_DBG(format, ...) do { printf("[ DBG ]: "); printf(format, ##__VA_ARGS__); } while (0)
    #define LOG_INF(format, ...) do { printf("[ INF ]: "); printf(format, ##__VA_ARGS__); } while (0)
    
    
    
    typedef struct tagBitmapFileHeader
    {
    	WORD bfAlign; //字节对齐
    	WORD bfType;//位图文件的类型,必须为BM(1-2字节)
    	DWORD bfSize;//位图文件的大小,以字节为单位(3-6字节,低位在前)
    	WORD bfReserved1;//位图文件保留字,必须为0(7-8字节)
    	WORD bfReserved2;//位图文件保留字,必须为0(9-10字节)
    	DWORD bfOffBits;//位图数据的起始位置,以相对于位图(11-14字节,低位在前)
    	//文件头的偏移量表示,以字节为单位
    }BitmapFileHeader;
    
    typedef struct tagBitmapInfoHeader{
    	DWORD biSize;//本结构所占用字节数(15-18字节)
    	DWORD biWidth;//位图的宽度,以像素为单位(19-22字节)
    	DWORD biHeight;//位图的高度,以像素为单位(23-26字节)
    	WORD biPlanes;//目标设备的级别,必须为1(27-28字节)
    	WORD biBitCount;//每个像素所需的位数,必须是1(双色),(29-30字节)
    	//4(16色),8(256色)16(高彩色)或24(真彩色)之一
    	DWORD biCompression;//位图压缩类型,必须是0(不压缩),(31-34字节)
    	//1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
    	DWORD biSizeImage;//位图的大小(其中包含了为了补齐行数是4的倍数而添加的空字节),以字节为单位(35-38字节)
    	DWORD biXPelsPerMeter;//位图水平分辨率,每米像素数(39-42字节)
    	DWORD biYPelsPerMeter;//位图垂直分辨率,每米像素数(43-46字节)
    	DWORD biClrUsed;//位图实际使用的颜色表中的颜色数(47-50字节)
    	DWORD biClrImportant;//位图显示过程中重要的颜色数(51-54字节)
    }BitmapInfoHeader;
    /**
     * 	当biBitCount = 1, 4, 8时,分别有2, 16, 256个表项;
     *	当biBitCount = 24时,没有颜色表项。	
     */
    typedef struct tagRgbQuad{
    	BYTE rgbBlue;//蓝色的亮度(值范围为0-255)
    	BYTE rgbGreen;//绿色的亮度(值范围为0-255)
    	BYTE rgbRed;//红色的亮度(值范围为0-255)
    	BYTE rgbReserved;//保留,必须为0
    }RgbQuad;
    
    typedef struct tagBitmapInfo{
    	BitmapInfoHeader biInfoHeader;//位图信息头
    	RgbQuad *rgbQuad; //颜色表
    	WORD rgbQuadSize; // 颜色表大小
    }BitmapInfo;
    
    typedef struct tagBitmapHandle{
    	BitmapFileHeader biFileHeader; // 文件头
    	BitmapInfo biInfo; // 位图信息头 + 颜色表
    	BYTE **bPixelMatrix; // 像素矩阵
    }BitmapHandle;
    
    DWORD InitBitmapHandle(BitmapHandle *biHandle)
    {
    	CHECK_NULL_POINT(biHandle);
    	memset(biHandle, 0, sizeof(BitmapHandle));
    
    	return SUCCESS;
    }
    
    DWORD CheckBitmapFileHeader(BitmapFileHeader *biFileHeader)
    {
    	CHECK_NULL_POINT(biFileHeader);
    	CHECK_FALSE_RETURN(0x4D42 == biFileHeader->bfType);
    	return SUCCESS;
    }
    
    DWORD CheckBitmapInfoHeader(BitmapInfoHeader *biInfoHeader)
    {
    	WORD biBitCount;
    	CHECK_NULL_POINT(biInfoHeader);
    	CHECK_FALSE_RETURN(1 == biInfoHeader->biPlanes);
    	biBitCount = biInfoHeader->biBitCount;
    	CHECK_FALSE_RETURN(1 == biBitCount || 4 == biBitCount || 8 == biBitCount 
    		|| 16 == biBitCount || 24 == biBitCount);
    	CHECK_FALSE_RETURN(0 == biInfoHeader->biCompression);
    	return SUCCESS;
    }
    
    DWORD ReadBmpInfo(FILE *pBmpFile, BitmapHandle *biHandle)
    {
    	DWORD dRet;
    	BitmapFileHeader *biFileHeader;
    	BitmapInfo *biInfo;
    	BitmapInfoHeader *biInfoHeader;
    	
    	LOG_DBG("....start ReadBmpInfo....
    ");
    	CHECK_NULL_POINT(pBmpFile);
    	CHECK_NULL_POINT(biHandle);
    
    	biFileHeader = &biHandle->biFileHeader;
    	biInfo = &biHandle->biInfo;
    	biInfoHeader = &biInfo->biInfoHeader;
    	
    	dRet = fread(&biFileHeader->bfType, sizeof(BitmapFileHeader)-sizeof(WORD), 1, pBmpFile);
    	CHECK_NULL_RETURN(dRet);
    	LOG_DBG("ReadBmpInfo: read bitmap file header success!
    ");
    	dRet = CheckBitmapFileHeader(biFileHeader);
    	CHECK_FAIL_RETURN(dRet);
    	LOG_DBG("ReadBmpInfo: check bitmap file header success!
    ");
    
    	dRet = fread(biInfoHeader, sizeof(BitmapInfoHeader), 1, pBmpFile);
    	CHECK_NULL_RETURN(dRet);
    	LOG_DBG("ReadBmpInfo: read bitmap info header success!
    ");
    	dRet = CheckBitmapInfoHeader(biInfoHeader);
    	CHECK_FAIL_RETURN(dRet);
    	LOG_DBG("ReadBmpInfo: check bitmap info header success!
    ");
    
    	biInfo->rgbQuadSize = GET_RGB_QUAD_SIZE(biInfoHeader->biBitCount);
    	biInfo->rgbQuad = (biInfo->rgbQuadSize == 0) ? NULL : ((RgbQuad*)malloc(biInfo->rgbQuadSize*sizeof(RgbQuad)));
    	CHECK_NULL_POINT(biInfo->rgbQuad);
    	LOG_DBG("ReadBmpInfo: start read RGB quad...
    ");
    	dRet = fread(biInfo->rgbQuad, sizeof(RgbQuad), biInfo->rgbQuadSize, pBmpFile);
    	CHECK_FAIL_RETURN(dRet);
    	LOG_DBG("ReadBmpInfo: read RGB quad success!
    ");
    	LOG_DBG("....end ReadBmpInfo....
    ");
    	
    	return SUCCESS;
    }
    
    DWORD ReadBmpData(FILE *pBmpFile, BitmapHandle *biHandle)
    {
    	DWORD biWidth;
    	DWORD biHeight;
    	WORD biBitCount;
    	DWORD dwRowBits;
    	DWORD dwRowBytes;
    	WORD loop;
    	BYTE *buff;
    	DWORD dRet;
    	BitmapInfo *biInfo;
    	BitmapInfoHeader *biInfoHeader;
    	
    	LOG_DBG("....start ReadBmpData....
    ");
    	CHECK_NULL_POINT(pBmpFile);
    	CHECK_NULL_POINT(biHandle);
    
    	biInfo = &biHandle->biInfo;
    	CHECK_NULL_POINT(biInfo);
    	biInfoHeader = &biHandle->biInfo.biInfoHeader;
    	CHECK_NULL_POINT(biInfoHeader);
    	
    	biWidth = biInfoHeader->biWidth;
    	biHeight = biInfoHeader->biHeight;
    	biBitCount = biInfoHeader->biBitCount;
    	dwRowBits = biWidth * biBitCount;
    	
    	dwRowBytes = dwRowBits >> 3 + ((dwRowBits & 0x7) == 0 ? 0 : 1); // dwRowBits / 8 + (dwRowBits % 8 == 0 ? 0 : 1)
    	dwRowBytes = dwRowBytes + ((4 - (dwRowBytes & 0x3))  & 0x3); // dwRowBytes + (4 - dwRowBytes % 4) % 4
    	
    	buff = (BYTE*)malloc(dwRowBytes*biHeight*sizeof(BYTE));
    	CHECK_NULL_POINT(buff);
    	LOG_DBG("ReadBmpData: alloc buff for pixel matrix success!
    ");
    	LOG_DBG("ReadBmpData: Width|%d,RowBytes|%d,Height|%d,Size|%d
    ", biWidth, dwRowBytes, biHeight, dwRowBytes*biHeight);
    	
    	dRet = fread(buff, dwRowBytes, biHeight, pBmpFile);
    	CHECK_NULL_RETURN(dRet);
    	LOG_DBG("ReadBmpData: read pixel matrix success! dRet|%d
    ", dRet);
    
    	biHandle->bPixelMatrix = (BYTE**)malloc(biHeight*sizeof(BYTE*));
    	CHECK_NULL_POINT(biHandle->bPixelMatrix);
    
    
    	for(loop = 0; loop < biHeight; loop++) 
    	{
    		biHandle->bPixelMatrix[loop] = &buff[loop*dwRowBytes];
    	}
    	
    	LOG_DBG("....end ReadBmpData....
    ");
    	
    	return SUCCESS;
    }
    
    DWORD ReleaseBmpSpace(BitmapHandle *biHandle)
    {
    	LOG_DBG("....start ReleaseBmpSpace....
    ");
    	CHECK_NULL_POINT(biHandle);
    	
    	if(biHandle->biInfo.rgbQuad != NULL) free(biHandle->biInfo.rgbQuad);
    	if(biHandle->bPixelMatrix != NULL)
    	{
    		if(biHandle->bPixelMatrix[0] != NULL) 
    			free(biHandle->bPixelMatrix[0]);
    		free(biHandle->bPixelMatrix);
    	}
    //	free(biHandle);
    	LOG_DBG("....end ReleaseBmpSpace....
    ");
    	
    	return SUCCESS;
    }
    
    DWORD LogBmpInfo(BitmapHandle *biHandle)
    {
    	BitmapFileHeader *biFileHeader;
    	BitmapInfo *biInfo;
    	BitmapInfoHeader *biInfoHeader;
    	RgbQuad * rgbQuad;
    	
    	CHECK_NULL_POINT(biHandle);
    	biFileHeader = &biHandle->biFileHeader;
    	biInfo = &biHandle->biInfo;
    	biInfoHeader = &biInfo->biInfoHeader;
    	rgbQuad = biInfo->rgbQuad;
    	
    	LOG_INF("BitmapFileHeader: Type|%x,Size|%d,Offset|%d
    ",biFileHeader->bfType, biFileHeader->bfSize, biFileHeader->bfOffBits);
    	LOG_INF("BitmapInfoHeader: Size|%d,Width|%d,Height|%d,Planes|%d,BitCount|%d,Compression|%d
    ", 
    		biInfoHeader->biSize,biInfoHeader->biWidth,biInfoHeader->biHeight,biInfoHeader->biPlanes,biInfoHeader->biBitCount,biInfoHeader->biCompression);
    	LOG_INF("BitmapInfoHeader: SizeImage|%d,XPelsPerM|%d,YPelsPerM|%d,ClrUsed|%d,ClrImportant|%d
    ",
    		biInfoHeader->biSizeImage,biInfoHeader->biXPelsPerMeter,biInfoHeader->biYPelsPerMeter,biInfoHeader->biClrUsed,biInfoHeader->biClrImportant);
    	LOG_INF("RgbQuad: %d
    ", (rgbQuad == NULL ? 0 : sizeof(rgbQuad)/sizeof(RgbQuad)));
    	
    	return SUCCESS;
    }
    
    int main(int argc, char *argv[])
    {
    	FILE *pBmpFile;
    	BitmapHandle biHandle;
    /*
    	printf("short:%d
    ", sizeof(short));
    	printf("long: %d
    ", sizeof(long));
    	printf("BitmapFileHeader:%d
    ", sizeof(BitmapFileHeader));
    	printf("BitmapInfoHeader:%d
    ", sizeof(BitmapInfoHeader));
    	printf("RgbQuad:%d
    ", sizeof(RgbQuad));
    	DWORD dwRowBits;
    	DWORD dwRowBytes;
    	dwRowBits = 8448;
    	dwRowBytes = (dwRowBits & 0x7 == 0 ? 0 : 1) + (dwRowBits >> 3);
    	printf("dwRowBytes:%d,%d
    ", ((dwRowBits & 0x7) == 0 ? 0 : 1), (dwRowBits >> 3));
    	system("pause");
    	*/
    //	CHECK_FAIL_RETURN(2 == argc);
    //	pBmpFile = fopen(argv[1], "rb");
    	pBmpFile = fopen("C:\Users\10207695\Documents\Visual Studio 2010\Projects\desp\Debug\01.bmp", "rb");
    
    	CHECK_NULL_POINT(pBmpFile);
    	LOG_DBG("Main: open bitmap file success!
    ");
    	
    	ReadBmpInfo(pBmpFile, &biHandle);
    	ReadBmpData(pBmpFile, &biHandle);
    	fclose(pBmpFile);
    
    	LogBmpInfo(&biHandle);
    
    	system("pause");
    	
    	ReleaseBmpSpace(&biHandle);
    	return 0;
    }
  • 相关阅读:
    四种常见的 POST 提交数据方式
    HTTP 协议中的 Transfer-Encoding
    一些安全相关的HTTP响应头
    密钥交换(密钥协商)算法及其原理
    SSL/TLS协议详解(下)——TLS握手协议
    SSL/TLS协议详解(中)——证书颁发机构
    SSL/TLS协议详解(上):密码套件,哈希,加密,密钥交换算法
    Maven的-pl -am -amd参数
    关于Sidecar Pattern
    Java Reference核心原理分析
  • 原文地址:https://www.cnblogs.com/rmthy/p/6198250.html
Copyright © 2020-2023  润新知