mhelie

Hello,

I'm writing a simple color corrector to teach myself C#, and have come across a couple of performance problems.

First, I am using Bitmap.LockBits to loop through the pixels (this part seems fast enough!). The problem I am having is having to do if statements in the loop to clamp colors if they're out of range (0-255), and also it seems Math.Pow( ) is really, really slow (which forces me to do an additional if inside the loop, even!)

Here's sample code (for blue, so this is repeated for red and green as well) for the math performed per pixel, per component:

if (tmpBlueGamma != 1.0)
{
  tmp = (float)((Math.Pow((double)(srcR[x * pixelSize] * toFloat), tmpBlueGamma)) * tmpBlueGain + tmpBlueOffset) * 255.0f;
}
else {
  tmp = ((float)(srcR[x * pixelSize]) * tmpBlueGain + tmpBlueOffset);
}
if (tmp < 0.0f) tmp = 0.0f;
if (tmp > 255.0f) tmp = 255.0f;
row[x * pixelSize] = (byte)tmp;


I realize I could do the math in byte instead of float (except for that darn Math.Pow requiring (double)), but that's not where I lose most time. If I take out the Gamma calculation, things speed up considerably; if I also remove clamping, everything is instantaneous. Any help greatly appreciated.


Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

Mark Dawson

Hi,

instead of Math.Pow you can use the shift operators << and >> that will move everything by powers of 2 and is extremely fast.

Mark.






Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

mhelie

Hi Mark,

unfortunately, the power values need to be real numbers, so byte shifting won't work.





Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

Mark Dawson

Hi,

is it possible that you could precaclulate the values in a lookup table so that you only have to calculate them once

Mark.






Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

mhelie

Yes, that's not a bad idea at all! It pretty much means I'd be limited to 8- or 16-bit integer images (or that I'd arbitrarily quantize float images), but still, better to calculate 256 or 65 536 values than all those pixels!

I'll try that right now and see what I get. Any ideas for the clamping ifs in the loop





Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

Mark Dawson

Well if it is somehow possible to restrict your calculated value between 0.0 and 1.0f then you would never go outside of the bounds.




Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

mhelie

Unfortunately, that's not possible; it's entirely OK for a user to increase the gain and clip some colors to white. I guess that's my answer there; I was hoping there might be a different way than with ifs (I tried with Math.Min and Math.Max, but that was even worse!)

BTW, lookup tables do speed things up, but I'm still not fully satisfied. I'm really surprised at how slow Math.Pow is, considering CPUs can handle such things really quickly.





Re: Visual C# General Speeding up pixel loops - speed of Math.Pow() ?

ThE_lOtUs

I would suggest you find an other algorithm. The fun part in graphic programming is there's a 1000 ways to to the same thing.