-2

I'm working on a program that works with images. I'm having trouble on a function that adjusts contrast and brightness. I need to calculate a value for each RGB component based on what input I recieve from the user. The problem is, I need to make sure the final value after said calculation isn't greater than 255 or less than 0. So it can fit inside a byte.

temp = c * dataPtr[0] + b; //variable temp is of type double.

if (temp > 255)
{
    temp = 255;
}
else if (temp < 0)
{
    temp = 0.0;
}

dataPtr[0] = (byte)(Math.Round(temp)); 

I'm repeating this for every RGB component of every pixel, so the ifs are getting executed a million times, most of the times needlessly.

I thought about just casting a double back to byte but it just reads the first byte of the double and doesn't max out the value if it's greater than what a byte can handle. Is there any obvious way to optmize this this range-check that I'm just missing? Thank you.

Rufus L
  • 36,127
  • 5
  • 30
  • 43
João Simões
  • 193
  • 10
  • I think you should show what `b` and `c` are as well... – Ron Beyer Sep 26 '18 at 00:33
  • They're completely irrelevant for the question in hand. It's just a calculation that may sometimes result in values greater than 255 or lesser than 0; If so, it should be maxed out at 255 or 0 respectively. – João Simões Sep 26 '18 at 00:36
  • You could do `temp = Math.Max(0, Math.Min(255, temp));`, which is less typing but no fewer conditions being executed. – Rufus L Sep 26 '18 at 00:58
  • @RufusL The conundrum here is reducing execution time. I thought the ifs were the ones adding overhead but it turns out the Math.round is the operation that's actually slowing it down. – João Simões Sep 26 '18 at 01:13
  • Yeah, that makes sense. The `if` statements should be pretty fast, but looking at the source for [`Math.Round`](https://referencesource.microsoft.com/mscorlib/R/f0afe85387e48317.html), there's a lot more going on there. – Rufus L Sep 26 '18 at 01:32
  • If you don't mind always rounding down, casting to an `int` is almost twice as fast as `Math.Round`. – Rufus L Sep 26 '18 at 01:41
  • https://stackoverflow.com/questions/2683442/where-can-i-find-the-clamp-function-in-net. Depending on what you're targeting you may also have [System.Math.Clamp](https://learn.microsoft.com/en-us/dotnet/api/system.math.clamp?view=netcore-2.0), but as others have said there's nothing "wrong" with `if`. – Jake Sep 26 '18 at 03:19

1 Answers1

1

No. if is the "gold standard" way of comparing values. If you need to make sure the the value is in a range if is the way to do it. If you must have an alternative: use an existing type that can only handle values 0-255, but then "overflow" behavior is "less defined". If you make your own type it probably uses if inside it anyway.

Your reasons "lots of needless ifs" is nothing to worry about.

John3136
  • 28,809
  • 4
  • 51
  • 69