[Pixman] [RFC] mmx: add and use expand_4xpacked565

Bill Spitzak spitzak at gmail.com
Thu May 17 16:59:50 PDT 2012

```
Søren Sandmann wrote:
> Søren Sandmann <sandmann at cs.au.dk> writes:
>
>>> Given a pixel with only the red component of these values, the results
>>> are off-by-one.
>>>
>>> 0x03 -> 0x19 (0x18)
>>> 0x07 -> 0x3A (0x39)
>>> 0x18 -> 0xC5 (0xC6)
>>> 0x1C -> 0xE6 (0xE7)
>>>
>>> (Same for blue, and green has many more cases)
>>>
>>> It uses
>>> R8 = ( R5 * 527 + 23 ) >> 6;
>>> G8 = ( G6 * 259 + 33 ) >> 6;
>>> B8 = ( B5 * 527 + 23 ) >> 6;
>>>
>>> I don't guess there's a way to tweak this to produce the same results
>>> we get from expand565, is there?
>> Maybe I'm missing something, but this certainly produces the correct
>> result:
>>
>>     r8 = (r5 * 8 + r5 / 4) = r5 * (8 + 0.25) = r5 * (32 + 1) / 4
>>        = (r5 * 33) >> 2
>
> I should maybe expand a bit more on this: Pixman uses bit replication
> when it goes from lower bit depths to higher ones. That is, a five bit
> value:
>
>         abcdef
>
> is expanded to
>
>         abcdefabc
>
> which corresponds to a left-shifting r5 by 3 and adding r5 right-shifted
> by 2. This is the computation that is turned into a multiplication and a
> shift in the formula above.
>
> A more correct way to expand would be
>
>         floor ((r5 / 31.0) * 255.0 + 0.5)
>
> but this is fairly expensive (although it can be done with integer
> arithmetic and without divisions, and may actually be equivalent to your
> formula -- I haven't checked).

for i in range(0,32):
print i,int((i*33)/4),int(i*255/31.0+.5)

0 0 0
1 8 8
2 16 16
3 24 25 *
4 33 33
5 41 41
6 49 49
7 57 58 *
8 66 66
9 74 74
10 82 82
11 90 90
12 99 99
13 107 107
14 115 115
15 123 123
16 132 132
17 140 140
18 148 148
19 156 156
20 165 165
21 173 173
22 181 181
23 189 189
24 198 197 *
25 206 206
26 214 214
27 222 222
28 231 230 *
29 239 239
30 247 247
31 255 255

Asterix marks the examples where these are unequal.
```