2014-07-03 43 views
0

几天前,我下载了SumatraPDF的来源,并开始探索它。我发现,图书馆MuPDF包含有趣的功能,但不理解它。Mul255 - 这是什么?

static inline int fz_mul255(int a, int b) { 
    int x = a * b + 128; 
    x += x >> 8; 
    return x >> 8; 
} 

在一些其他来源,我发现mul255功能的另一种定义:

(a+1)*b >> 8 

这是什么?帮帮我。

+2

这看起来像是8位小数位的定点数据的四舍五入乘法,其中每个定点数都存储在一个“int”中。然而,在最初的想法中,这两个变体看起来并不相同,并且两个代码都与我期望的函数看起来很像:'(a * b + 128)>> 8'。代码中有关于函数或数据类型的任何辅助信息(注释?)? – njuffa

+0

您的第一个片段可以表示具有八个小数位的四舍五入的定点乘法,然后是缩放257/256,这是255/256的近似倒数。如果没有更多的上下文,这种缩放的目的不明确。 – njuffa

+1

@Glutton:我完全不知道我在评论中写的是否是答案。这大概有一个原因,这个函数叫做'mul255',但是我不清楚。我试图在上面的第二条评论中进一步反向工程,试图以'255'的方式工作。同样令人困惑的是,这个函数有两个相互冲突的定义。因此,如果没有原始海报的进一步佐证,恐怕我在猜测,而不是回答。 – njuffa

回答

0

如果不是第二行(x += x >> 8),我会确切地知道该方法的作用。如果我们将其删除,为了讨论的目的:

static inline int fz_mul255(int a, int b) { 
    int x = a * b + 128; 
    // x += x >> 8; 
    return x >> 8; 
} 

现在的方法倍数A * B,其被定点数具有8个分数位,四舍五入到最接近的结果。具体而言,a * b是倍数,+ 128舍入到最近(记住,这会被移出,所以只有在位7之后导致进位到下一个最高有效位位置时才起作用),并且>> 8纠正该点的位置(因为用整数算术将两个定点值与8个小数位相乘产生具有16个小数位的定点值)。

那么唯一的问题就是'x + = x >> 8'是什么,而我现在恐怕知道了。实际上,它将结果乘以(1 + 1/256)。

+0

参数不是带8个小数位的定点数;它们是缩放整数(255代表1.0)。 – ccxvii

+0

“参数不是带8个小数位的定点数” - 它们是在我回答的上下文中的,但我明白你的意思,这将解释我明确注释的方法中的缩放步骤。 – davmac

1

在图形中,我们经常使用缩放整数值(范围0到255)来表示0.0到1.0范围内的颜色值。

的mul255函数将两个这样的比例整数,使得255 * 255 = 255

在MuPDF的实现是基于从书“肮脏像素”吉姆·布林的精确缩放方法由吉姆·布林。您引用(a+1)*b >> 8的另一个实现是更快但不太准确的近似值。