Shifting back to something
word color;
crap = ((color & 0xffc0) >> 1) | (color & 0x1f)
I have this shifting code. I have no idea what the purpose is of this code, but I suspect it has something to do with switching between 555 to 565 colors.
How would I create a funct开发者_JS百科ion that does the exact opposite as the code above? That converts the variable back to the original color number?
You can't. "And" (&
) and "or" (|
) don't have an inverse (neither does bit shifting if you overflow). Meaning that there could be multiple values of color
that could turn into crap
.
I suspect it has something to do with switching between 555 to 565 colors.
Yes, that's what it's doing. color
will be the 565 representation, and crap
the corresponding 555 representation.
Lets look at what each operation does. I'll refer to the three fields as a
(5 bits), b
(6 bits, transformed to 5) and c
(5 bits).
(color & 0xffc0)
clears the bottom 6 bits of the word, removing c
and the least significant bit of b
, preserving a
and the most significant 5 bits of b
.
>> 1
shifts these bits right, so we now have a
(5 bits), b
(5 bits), and an empty 5-bit field.
(color & 0x1f)
clears all the bits except for the bottom 5 bits - that is, it preserves 'c' and removes the other fields.
Finally, |
combines the two values, giving a
and b
from the left-hand side, and c
from the right-hand side, each in 5 bits.
How would I create a function that does the exact opposite as the code above? That converts the variable back to the original color number?
color = ((crap & 0xffe0) << 1) | (crap & 0x1f);
Note that the least significant bit of b
is now zero, whatever it was to start with. That information was lost in the first transformation, and can't be recovered.
Strictly speaking, you can't, since the transformation irreversibly deletes the fifth least significant bit of color
(it does preserve all the other bits).
Assuming the fifth bit didn't contain any useful data to begin with, the following will give you the inverse of your transformation:
color = ((crap & 0xffe0) << 1 | (crap & 0x1f))
Again, this restores color
except for the fifth bit, which has been lost.
Yes, this looks like it converts from 565 RGB to 555 RGB by discaring the lowest bit of G.
You're losing one bit, so you can't invert it exactly (the lowest bit of G is just gone), but you can approximate the inverse by doing something like this:
color = ((crap & 0xffe0) << 1) | (crap & 0x1f)
The first part, ((crap & 0xffe0) << 1)
is just masking out the R and G components and shifting them back up. The last part, | (crap & 0x1f)
, is masking out the blue and adding it back into the result.
精彩评论