# little fun with bits

This topic is 4988 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi guys! Right now, I'm coding some simple graphical filter (Gaussian blur to be exact). I have my image in memory and I need to take a pixel, the one left to it and the other one right to it. Sum these pixels like left + 2 * current + right and divide all by four. And here goes my question. As I have 24 bits per pixel I wonder if I can sum/multiply/divide those pixels as 4 bytes integer (with mask removing the last one byte that goes for next pixel) or I have to extract the colors? Thx in advance Ondra
//can I do this?
current = (current & 0xFF000000) | ((left & 0xFFFFFF) + 2 * (current & 0xFFFFFF) +  (right & 0xFFFFFF));


##### Share on other sites
No. You can't do that because the results of math operations will cross into adjacent colors. For example,

00 00 ff (bright blue) * 2 = 00 01 fe (slightly darker blue with a little green)
00 03 00 (very dark green) / 4 = 00 00 c0 (bright blue)

##### Share on other sites
MMX is predestined for this kind of stuff!

##### Share on other sites
If you don't have mmx or want a portable version using one of the following might be an option.
Loosing some precision:

New = (Left & 0xfcfcfcfc) + ((Current & 0xfcfcfcfc) << 1) + (Right & 0xfcfcfcfc);

Or more accurate:

LeftRB = Left & 0xff00ff;
LeftG = Left & 0x00ff00;
CurrentRB = Current & 0xff00ff;
CurrentG = Current & 0x00ff00;
RightRB = Right & 0xff00ff;
RightG = Right & 0x00ff00;
New = (((LeftRB + CurrentRB + CurrentRB + RightRB) >> 2) & 0xff00ff) | (((LeftG + CurrentG + CurrentG + RightG) >> 2) & 0x00ff00);

It's also quite useful for blending etc since you can do a multiply after splitting into 0xff00ff and 0x00ff00. You can easily extend this to ARGB with some additional shifts.

##### Share on other sites
eq knows the stuff.

Your idea as you may have already noticed doesn't quite work, but this will:
redblue = (((left & 0xFF00FF) + ((current & 0xFF00FF)<<1) + (right & 0xFF00FF))>>2) & 0xFF00FF;
green = (((left & 0xFF00) + ((current & 0xFF00)<<1) + (right & 0xFF00))>>2) & 0xFF00;
current = redblue | green;

However this trick is more useful for 32-bit where data is aligned to 4-byte boundaries. It may not be any faster than operating on single bytes for 24-bit.
i.e.
unsigned char *inPixels, *outPixels;*outPixels++ = (*(inPixels-3) + (*(inPixels)<<1) + *(inPixels+3)) >> 2;inPixels++;

repeat for red, green and blue.

Try both and if both work, pick the faster one.

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 10
• 11
• 13
• 9
• 11
• ### Forum Statistics

• Total Topics
634092
• Total Posts
3015447
×