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....\n");
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!\n");
dRet = CheckBitmapFileHeader(biFileHeader);
CHECK_FAIL_RETURN(dRet);
LOG_DBG("ReadBmpInfo: check bitmap file header success!\n"); dRet = fread(biInfoHeader, sizeof(BitmapInfoHeader), 1, pBmpFile);
CHECK_NULL_RETURN(dRet);
LOG_DBG("ReadBmpInfo: read bitmap info header success!\n");
dRet = CheckBitmapInfoHeader(biInfoHeader);
CHECK_FAIL_RETURN(dRet);
LOG_DBG("ReadBmpInfo: check bitmap info header success!\n"); 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...\n");
dRet = fread(biInfo->rgbQuad, sizeof(RgbQuad), biInfo->rgbQuadSize, pBmpFile);
CHECK_FAIL_RETURN(dRet);
LOG_DBG("ReadBmpInfo: read RGB quad success!\n");
LOG_DBG("....end ReadBmpInfo....\n"); 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....\n");
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!\n");
LOG_DBG("ReadBmpData: Width|%d,RowBytes|%d,Height|%d,Size|%d\n", biWidth, dwRowBytes, biHeight, dwRowBytes*biHeight); dRet = fread(buff, dwRowBytes, biHeight, pBmpFile);
CHECK_NULL_RETURN(dRet);
LOG_DBG("ReadBmpData: read pixel matrix success! dRet|%d\n", 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....\n"); return SUCCESS;
} DWORD ReleaseBmpSpace(BitmapHandle *biHandle)
{
LOG_DBG("....start ReleaseBmpSpace....\n");
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....\n"); 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\n",biFileHeader->bfType, biFileHeader->bfSize, biFileHeader->bfOffBits);
LOG_INF("BitmapInfoHeader: Size|%d,Width|%d,Height|%d,Planes|%d,BitCount|%d,Compression|%d\n",
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\n",
biInfoHeader->biSizeImage,biInfoHeader->biXPelsPerMeter,biInfoHeader->biYPelsPerMeter,biInfoHeader->biClrUsed,biInfoHeader->biClrImportant);
LOG_INF("RgbQuad: %d\n", (rgbQuad == NULL ? 0 : sizeof(rgbQuad)/sizeof(RgbQuad))); return SUCCESS;
} int main(int argc, char *argv[])
{
FILE *pBmpFile;
BitmapHandle biHandle;
/*
printf("short:%d\n", sizeof(short));
printf("long: %d\n", sizeof(long));
printf("BitmapFileHeader:%d\n", sizeof(BitmapFileHeader));
printf("BitmapInfoHeader:%d\n", sizeof(BitmapInfoHeader));
printf("RgbQuad:%d\n", sizeof(RgbQuad));
DWORD dwRowBits;
DWORD dwRowBytes;
dwRowBits = 8448;
dwRowBytes = (dwRowBits & 0x7 == 0 ? 0 : 1) + (dwRowBits >> 3);
printf("dwRowBytes:%d,%d\n", ((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!\n"); ReadBmpInfo(pBmpFile, &biHandle);
ReadBmpData(pBmpFile, &biHandle);
fclose(pBmpFile); LogBmpInfo(&biHandle); system("pause"); ReleaseBmpSpace(&biHandle);
return 0;
}
bitmap解码的更多相关文章
- Android性能优化之Bitmap的内存优化
1.BitmapFactory解析Bitmap的原理 BitmapFactory提供的解析Bitmap的静态工厂方法有以下五种: Bitmap decodeFile(...) Bitmap decod ...
- Android性能优化系列之Bitmap图片优化
https://blog.csdn.net/u012124438/article/details/66087785 在Android开发过程中,Bitmap往往会给开发者带来一些困扰,因为对Bitma ...
- fackbook的Fresco (FaceBook推出的Android图片加载库-Fresco)
[Android开发经验]FaceBook推出的Android图片加载库-Fresco 欢迎关注ndroid-tech-frontier开源项目,定期翻译国外Android优质的技术.开源库.软件 ...
- OOM总结
本文主要信息是来自互联网,我只是自己做了一点总结和摘要. OOM发生的原因 简单的说通过不同的内存分配方式对不同的对象进行操作,会因为android系统版本的差异而产生不同的行为.主要是2.0和4.0 ...
- Android 调用jepg库进行图片压缩,保持图片不失真
1. 浅谈为什么Android和iOS图片质量差距那么大? 首先来说,作为一个安卓狗,机器当然用的是安卓的手机.现在的安卓手机大多数都会以高清拍照,动不动就几千万柔光相机来吸引各种买家.买来后,拍照发 ...
- Fresco-FaceBook推出的Android图片加载库
在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和alpha通道总共要占用4 ...
- Android图片加载库Fresco
在Android设备上面,快速高效的显示图片是极为重要的.过去的几年里,我们在如何高效的存储图像这方面遇到了很多问题.图片太大,但是手机的内存却很小.每一个像素的R.G.B和alpha通道总共要占用4 ...
- Android性能优化之图片压缩优化
1 分类Android图片压缩结合多种压缩方式,常用的有尺寸压缩.质量压缩.采样率压缩以及通过JNI调用libjpeg库来进行压缩. 参考此方法:Android-BitherCompress 备注:对 ...
- Android 关于虹软人脸识别SDK引擎使用总结
虹软 最近开放了人脸识别的SDK引擎(免费的哦),刚好有Android版的,就体验了一波.下面来说说Android版的SDK使用心得: ArcFace 虹软人脸认知引擎简介 目前开放的版本有人脸比对( ...
随机推荐
- 如何修复VUM在客户端启用之后报数据库连接失败的问题
在上一篇随笔中介绍了关于重新注册VMware Update Manager(VUM)至vCenter Server中的方法,最近有朋友反应,原本切换过去好好的更新服务为什么某次使用一下就不灵了? 当时 ...
- React.js入门必须知道的那些事
首先,React.js是facebook在2013年5月开源的一个前端框架,React不是一个MVC框架,它是构建易于可重复调用的web组件,侧重于UI, 也就是view层, React为了更高超的性 ...
- 分布式系统理论进阶 - Paxos
引言 <分布式系统理论基础 - 一致性.2PC和3PC>一文介绍了一致性.达成一致性需要面临的各种问题以及2PC.3PC模型,Paxos协议在节点宕机恢复.消息无序或丢失.网络分化的场景下 ...
- 安卓v7支持包下的ListView替代品————RecyclerView
RecyclerView这个控件也出来很久了,相信大家也学习的差不多了,如果还没学习的,或许我可以带领大家体验一把这个艺术般的控件. 项目已经同步至github:https://github.com/ ...
- Bootstrap 4-alpha 初体验
What is Bootstrap? 第一句话就是废话了,作为新时代有理想有节操的开发人员无人不知无人不晓.可能就是熟悉程度因为各种原因不尽相同,有人只是知道他大概是个什么东西,有些人可能基本可以使用 ...
- vue.mixin与vue.extend
vue.mixin 全局注册一个混合,影响注册之后所有创建的每个 Vue 实例.谨慎使用全局混合对象,因为会影响到每个单独创建的 Vue 实例(包括第三方模板).大多数情况下,只应当应用于自定义选项, ...
- 跨平台运行 Rafy 首次部署记录
一直想在 Linux 上使用 MONO 试试运行 Rafy,最近因为业务需要,总算是真正地试验了一次.下面是本次部署记录的一些要点. Linux 这次部署,我是和两位同事一起来试验的.由于我们对 Li ...
- Redis命令拾遗一(字符串类型)
文章归博客园和作者“蜗牛”共同所有 .转载和爬虫请注明原文Redis系列链接 http://www.cnblogs.com/tdws/tag/NoSql/ Redis有五种基本数据类型.他们分别是字符 ...
- 【转载】10 个实用技巧,让 Finder 带你飞
来自:http://sspai.com/27403/ Finder 是 Mac 电脑的系统程序,有的功能类似 Windows 的资源管理器.它是我们打开 Mac 首先见到的「笑脸」,有了它,我们可以组 ...
- LinqToXml (一) Create Xml file By Dom /Linq
目前,在xml 应用编程领域比较流行的开发模型是W3C 提供的DOM(文档对象模型),在.net Framework 通过命名空间 System.Xml 对该技术提供了支持.随着Linq to XMl ...