why is a negative shift value illegal?

Jeff Petkau jpet at eskimo.com
Sun Jan 14 16:39:48 EST 2001


Rainer Deyke <root at rainerdeyke.com> wrote in message
news:Nhb86.43336$ge4.16574483 at news2.rdc2.tx.home.com...
> Consider 16 bit color formats.  Red, green, and blue components are packed
> into a single 16 bit value.  For any given 16 bit color format, each
> component has a mask, from which can be derived its position and length.
> For example:
>
> Pixel format: rrrrrggggggbbbbb
>
> red_mask = 0xf800
> red_position = 11
> red_length = 5
> green_mask = 0x07e0
> green_postion = 5
> green_length = 6
> blue_mask = 0x001f
> blue_position = 0
> blue_length = 5
>
> To operate on an individual component, on needs to isolate it, shift it to
> the right by its position, and promote it to an 8 bit value by shifting it
> to the left:
>
> red = ((color & red_mask) >> red_position) << (8 - red_length)
>
> The left shift value can be precalculated, of course.  However, if
negative
> shift values were allowed, the two shifts could be reduced to a single
> shift:

Kind of offtopic, but that's not a very good way to convert colors.
In your example, white (0xffff) would be converted to (248,248,248)
when it should be (255,255,255). A better conversion is:

    r = ((color & red_mask) >> red_position)*255 / (2**red_length-1)
    g = ((color & green_mask) >> green_position)*255/ (2**green_length-1)
    b = ((color & blue_mask) >> blue_position)*255 / (2**blue_length-1)

but the division is kind of expensive in some circumstances. You can also
fill with the most significant bits of each component instead of with
zero:

    r = (color & red_mask) >> red_position
    r = (r << 8-red_length) | (r >> red_length+red_length-8)

Gah. That's hideous. Well, when you're hardwiring the component sizes
it works ok. (Of course, it's not very robust at all--it breaks with
component sizes <4 or >8. It would work better if we had signed
shifts, so I suppose I agree with your original point.)

--Jeff






More information about the Python-list mailing list