Skip to main content
gamedev.net
🔒 Locked

flipping color bits

Started by michaweyel May 12, 2004 at 3:58 AM 8 replies 1.2k views
Original Post
michaweyel
michaweyel
Hi. Let''s see if i can describe what i want...what i need to do is to flip the bits of the color bytes of an RGB value. Lets say i have R=00001111 i want it to be 11110000 and so on. I tried to use the Win-API function "SetDeviceGammaRamp()", but it doesn''t allow all gamma ramps to be set (only Bill G. knows why) and SDL_SetGammaRamp() calls SetDeviceGammaRamp() so this doesn''t work neither. Can this somehow be done in OpenGL? Maybe with glPixelTransfer() or glPixelMap()? But as i understand it, they always operate with floating point values. Btw, I just need it for my output window(SDL), not for the whole screen. Thanks, Michael
rypyr
rypyr
Your post is not clear.

When you say "flip" are you saying:

- turn all 1''s into 0''s and all 0''s into 1''s?
- Or are you saying to reverse the bits?

If it''s the first, then why not just do it directly in your code using exclusive OR:

R ^= 0xFFFFFFFF;
G ^= 0xFFFFFFFF;
B ^= 0xFFFFFFFF;

By the way, in OpenGL wouldn''t (1.0-r) would be the equivalent of this?

Why do you need this?

Regards,
Jeff



[ CodeDread ]
michaweyel
michaweyel
ooops, sorry.
i want to reverse the bits, e.g.

10000000 -> 00000001

i need it for some special display hardware. it's located between graphics card and display device. It's a prototype and unfortunatly has a bug so that it reverses the bit order of the color information.


[edited by - michaweyel on May 13, 2004 4:34:44 AM]
rypyr
rypyr
Well, the only thing I can suggest is to come up with a function that will do this and then try to optimize it:


inline Uint8 reverseUint8(Uint8 src)
{
Uint8 dest = ((src & 0x01)<<7) | ((src & 0x02)<<5) |
((src & 0x04)<<3) | ((src & 0x08)<<1) |
((src & 0x10)>>1) | ((src & 0x20)>>3) |
((src & 0x40)>>5) | ((src & 0x80)>>7);
return dest;
}


Is there a way to do the above in-place rather than copying? I''m thinking of that xor trick that doesn''t require a temp variable...

I am pretty ignorant when it comes to assembly, but I quickly looked at the Pentium Instruction and there is a "Bit Scan Reverse" instruction, maybe that will help? Of course you will need to write versions of the assembly for each processor type since you''re using SDL.

Regards,
Jeff


[ CodeDread ]
rypyr
rypyr
And if you can spare 256 bytes of RAM, a simple look-up table will do nicely:


Uint8 Reverse[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
...
};


The pattern repeats so it's not THAT hard to generate this manually (but why bother - use the above function).

And it's also simple to do this with only 16 bytes of RAM but slightly slower than the 256-byte approach:


Uint8 ReverseNibble[16] = {
0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
};
inline Uint8 ReverseUint8(Uint8 src) {
return (ReverseNibble[src&0xF]<<4) | (ReverseNibble[(src>>4)]);
}


Regards,
Jeff

Edit: Saw the pattern in the 8-bit approach and then thought about the 4-bit approach.


[ CodeDread ]

[edited by - rypyr on May 13, 2004 3:48:07 PM]
michaweyel
michaweyel
Hey rypyr.
Thanks for the help, but my problem is not the bit-reversal itself, but how do map the incoming color information from OpenGL (which is always(?) float?) to my array of flipped bytes. It would be easy, if the rgb''s from OpenGL would come in as one-byte-integers. is this possible? (sorry, my first post didn''t really explain the problem...)
Vaporisator
Vaporisator
mmmh floatColorValue * 255 ?
Yesterday we still stood at the verge of the abyss,today we're a step onward! Don't klick me!!!
WarAmp
WarAmp
If you are writing the opengl application, then you can use glColor4ub() which uses an unsigned byte for each color channel... Altho I think I may have misunderstood what you meant.

To invert the Float color value, doesnt (1.0f - Color) work?
Waramp.Before you insult a man, walk a mile in his shoes.That way, when you do insult him, you'll be a mile away, and you'll have his shoes.
rypyr
rypyr
He''s not looking for "invert", he''s looking for bit reversal...


[ CodeDread ]
michaweyel
michaweyel
Okay, what i currecntly do is

glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
unsigned short gammatable[256];
for(unsigned int c = 0; c < 256; c++)
{
unsigned char temp = (unsigned char)c;
unsigned short result = 0;
for(int i = 0; i < 8; i++)
{
if(temp&BIT[i])
result += pow(2, (7-i));
}
gammatable[c] = result | (result << 8);
}

glPixelMapusv(GL_PIXEL_MAP_R_TO_R, 256, gammatable);
glPixelMapusv(GL_PIXEL_MAP_G_TO_G, 256, gammatable);
glPixelMapusv(GL_PIXEL_MAP_B_TO_B, 256, gammatable);


so i have a map with unsigned short that have high and low byte in the order in which i want them to be. But how does OpenGL index this table? How do i know which incoming color maps to gamatable[123] for example?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.