Léon Pelletier
Léon Pelletier

Reputation: 2731

Is this formula repetitive or optimal

I've started to code a image processing program from different image processing algorithms, mostly from René Schulte work, and when benchmarking, I noticed that from all the effects I could find from different sources, a code for applying a 'Softlight' effect was the slowest. I'm not good in optimizing equation, but I feel that the filter is based on a formula that is maybe repeating variables with no reason.

Could this be summarized in something shorter or faster?

// Basically, b is from Image A, and t from Image B
int csoftLight(float b, float t)
      {
          b /= 255;
          t /= 255;

          return (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5))));
       }

[Edit - Results using the equation Mohammed Hossain found about softlight in PS]

// Input: 137 and 113

// Byte version:
int other = ((byte)((B < 128) ? (2 * ((A >> 1) + 64)) * ((float)B / 255) : (255 - (2 * (255 - ((A >> 1) + 64)) * (float)(255 - B) / 255))));
// Returns 116    


// float version:
int res = (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5))));
// Returns 129

[Edit]

Here's the quickest algorithm based on Mohammed Hossain answer:

int csoftLight(byte A, byte B)
{
    return (int)((A < 128) ? (2 * ((B >> 1) + 64)) * ((float)A / 255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float)(255 - A) / 255)));          
}

Upvotes: 5

Views: 155

Answers (1)

Mohammed Hossain
Mohammed Hossain

Reputation: 1319

This answer should help you and clarify some things up a bit: How does photoshop blend two images together?

One of the equations is the soft light algorithm.

#define ChannelBlend_SoftLight(A,B) ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255)))) //not very accurate

It importantly avoids the costly square root operation and less importantly uses bit-shift operators in place of division by 2 (which should be optimized away by smart compilers, anyways). It also uses more integer operations than floating operations, which is more faster.

Here is another formula (courtesy to the owners of this which switches the variable's operations, and it seemingly works...

#define ChannelBlend_SoftLight(A,B) (uint8)(((A < 128) ? (2 * ((B >> 1) + 64)) * ((float) A / 255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float) (255 - A) / 255))));

Upvotes: 4

Related Questions