Skip to content

Instantly share code, notes, and snippets.

@Darker
Created September 11, 2020 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Darker/7c80af680a1bb3a38fe0286bb08e0c05 to your computer and use it in GitHub Desktop.
Save Darker/7c80af680a1bb3a38fe0286bb08e0c05 to your computer and use it in GitHub Desktop.
#define E .0000001f
bool fEqual(float x, float y)
{
return (x+E > y && x-E < y);
}
float4 rgba2hsla(float4 rgba) {
float M = max(rgba.x, rgba.y);
M = max(M, rgba.z);
float m = min(rgba.x, rgba.y);
m = min(m, rgba.z);
float chroma = M-m; //calculate chroma
float lightness = (M+m)/2.0f;
float saturation = chroma/(1.0f-fabs(2.0f*lightness-1.0f));
float hue = 0;
if (fEqual(rgba.x, M))
hue = fmod((rgba.y - rgba.z)/chroma, 6.0f);
if (fEqual(rgba.y, M))
hue = (((rgba.z - rgba.x))/chroma) + 2;
if (fEqual(rgba.z, M))
hue = (((rgba.x - rgba.y))/chroma) + 4;
hue *= 60.0f;
return (float4)(hue, saturation, lightness, rgba.w);
}
float hue2rgb(float p, float q, float t) {
if(t < 0.0f) t += 1;
if(t > 1.0f) t -= 1;
if(t < (float)(1/6)) return p + (q - p) * 6.0f * t;
if(t < (float)(1/2)) return q;
if(t < (float)(2/3)) return p + (q - p) * (2/3 - t) * 6.0f;
return p;
}
// Convert <0,1> ranged rgba floats to <0,255> uchars
uchar4 floatrgba2ucharrgba(float4 in) {
return (uchar4)(convert_uchar_rte(in.x*255.0f),
convert_uchar_rte(in.y*255.0f),
convert_uchar_rte(in.z*255.0f),
convert_uchar_rte(in.w*255.0f));
// return (uchar4)((in.x*255.0f),
// (in.y*255.0f),
// (in.z*255.0f),
// (in.w*255.0f));
}
float4 hsl2rgb_stackoverflow(float4 gMem)
{
float4 rgb = (float4)(0,0,0,gMem.w);
if(fEqual(gMem.y,0.0f)){
rgb.x = rgb.y = rgb.z = gMem.z; // achromatic
}
else {
//calculate chroma
float chroma = (1.0f - fabs( (float)(2.0f*gMem.z - 1.0f) )) * gMem.y;
float H = gMem.x/60.0f;
float x = chroma * (1.0f - fabs( fmod(H, 2.0f) - 1.0f ));
switch((int)H)
{
case 0:
rgb = (float4)(chroma, x, 0,gMem.w);
break;
case 1:
rgb = (float4)(x, chroma, 0,gMem.w);
break;
case 2:
rgb = (float4)(0, chroma, x,gMem.w);
break;
case 3:
rgb = (float4)(0, x, chroma,gMem.w);
break;
case 4:
rgb = (float4)(x, 0, chroma,gMem.w);
break;
case 5:
rgb = (float4)(chroma, 0, x,gMem.w);
break;
default:
rgb = (float4)(0, 0, 0,gMem.w);
}
rgb += gMem.z - .5f*chroma;
return rgb;
}
}
__kernel void saturate(
__global const uchar* src_ptr,
__global uchar* out_ptr)
{
const int it = get_global_id(0);
const uchar b = src_ptr[3*it + 0];
const uchar g = src_ptr[3*it + 1];
const uchar r = src_ptr[3*it + 2];
float4 rgba = (float4)(r,g,b,1.0f);
rgba /= 255.0f;
float4 hsla = rgba2hsla(rgba);
//hsla.y = sqrt(hsla.y);
//float4 rgbaNew = hsla2rgba(hsla);
float4 rgbaNew = hsl2rgb_stackoverflow(hsla);
uchar4 rgbaNewInt = floatrgba2ucharrgba(rgbaNew);
//rgbaNewInt = (uchar4)(hsla.y*255, hsla.y*255, hsla.y*255, hsla.w*255);
out_ptr[3*it + 0] = rgbaNewInt.z;
out_ptr[3*it + 1] = rgbaNewInt.y;
out_ptr[3*it + 2] = rgbaNewInt.x;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment