公式:位图字节对齐

最近工作涉及了位图4字节对齐问题,前人代码中用了下面的公式(width * bitCounts + 31) / 32 * 4,来计算图像每行的字节数,但是一直不理解公式的原理,经过网上搜索,看过别人文章,以及自己琢磨,发现原理如下:

  1. 首先来自于这样一个公式:(width * bitCounts / 8 + 3) / 4 * 4,该公式含义比上面的公式要容易理解一些,比如biWidth * biBitCount代表了对齐前每行的总位数,位图有1位、2位、4位、8位、16位、24位、32位等,大于8位的都是8的倍数,所以biWidth * biBitCount / 8是对齐前的总字节数,要4字节对齐,除以4,看余数多少,不够多少补多少。

而因为除以4的余数只能是0、1、2、3这四种情况,0就是刚好整除不需要再补,1、2、3分别需要补3、2、1个字节才能凑足4字节。那么

我们在除之前先补上3个字节会是什么情况呢,对于四种余数情形,分别是余3(3+0)、0(3+1)、1(3+2)、2(3+3),对于整数操作(width * bitCounts / 8 + 3) / 4得到的结果不会有余数,刚好达到了我们需要补足4字节的目的;

另外再考虑能不能先补上别的数字,例如1、2,根据前面余数情况分析,补1会漏掉余数为1、2的情况,补2会漏掉余数为1的情况;

再考虑补上4或者更大数字的情况,余数为0的情形补4就多了4字节,数字再往上就更加多余,所以补上最大余数刚刚合适。

  1. 上面的分析对于位宽大于等于8的位图已经正确,但小于8位的情况,width * bitCounts不一定是8的整数倍,所以我们先不要除以8,而是按照4字节等于32个bit位来计算,我们看看需要补多少位使得刚好32位对齐,那么就有公式:

(width * bitCounts + n)/ 32 * 4

跟1中的分析方法相同,n应为32的最大余数31,所以得到最终公式:(width * bitCounts + 31)/ 32 * 4。

易语言以下公式:

位与 (宽度 × 位深 ÷ 83, 位取反 (3))
左移 (右移 (宽度 × 位深 + 31, 5), 2)
.版本 2

.子程序 对齐, 整数型
.参数 待对齐数, 整数型
.参数 对齐长度, 整数型, , 1 2 4 8 16 32 64 ...

对齐长度 = 逆向位扫描 (对齐长度)
.如果真 (对齐长度 > 0)
    对齐长度 = 左移 (1, 对齐长度)1
    返回 (位与 (待对齐数 + 对齐长度, 位取反 (对齐长度)))
.如果真结束
返回 (待对齐数)

.子程序 逆向位扫描, 整数型
.参数 待扫描数, 整数型

置入代码 ({ 15, 189, 69, 8, 201, 194, 4, 0 })
' 十六进制:0F BD 45 08 C9 C2 04 00
' bsr eax, dword ptr [ebp+08h]
' leave
' retn 4
返回 (0)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值