Skip to content

Instantly share code, notes, and snippets.

@alexbatashev
Created October 8, 2017 17:15
Show Gist options
  • Save alexbatashev/79aba4be2300364b5a622cae0402a5e7 to your computer and use it in GitHub Desktop.
Save alexbatashev/79aba4be2300364b5a622cae0402a5e7 to your computer and use it in GitHub Desktop.
#pragma version(1)
#pragma rs java_package_name(com.sample.app)
#include "rs_debug.rsh"
const float XYZ_WHITE_REFERENCE_X = 95.047;
const float XYZ_WHITE_REFERENCE_Y = 100.0;
const float XYZ_WHITE_REFERENCE_Z = 108.883;
const float XYZ_EPSILON = 0.008856;
const float XYZ_KAPPA = 903.3;
rs_allocation gIn;
rs_allocation gOut;
static void rgbToXyz(uchar4 in, float3 out) {
float sr = in.r / 255.0;
sr = (sr < 0.04045 ? sr / 12.92 : powr((sr + 0.055f) / 1.055f, 2.4));
float sg = in.g / 255.0;
sg = sg < 0.04045 ? sg / 12.92 : powr((sg + 0.055f) / 1.05f, 2.4);
float sb = in.b / 255.0;
sb = sb < 0.04045 ? sb / 12.92 : powr((sb + 0.055f) / 1.055f, 2.4);
out.x = 100 * (sr * 0.4124 + sg * 0.3576 + sb * 0.1805);
out.y = 100 * (sr * 0.2126 + sg * 0.7152 + sb * 0.0722);
out.z = 100 * (sr * 0.0193 + sg * 0.1192 + sb * 0.9505);
}
static float cubic_root(float x) {
return 1 + (x - 1) / 3.0 - (x - 1) * (x - 1) / 9.0 + 5 * (x - 1) * (x - 1) * (x - 1) / 81.0;
}
static float pivotXyzComponent(float component) {
return component > XYZ_EPSILON
? cubic_root(component)
: (XYZ_KAPPA * component + 16.0) / 116.0;
}
static float maxf(float a, float b) {
return a > b ? a : b;
}
static void xyzToLab(float3 xyz, float3 lab) {
float x = pivotXyzComponent(xyz.x / XYZ_WHITE_REFERENCE_X);
float y = pivotXyzComponent(xyz.y / XYZ_WHITE_REFERENCE_Y);
float z = pivotXyzComponent(xyz.z / XYZ_WHITE_REFERENCE_Z);
rsDebug("x is ", x);
rsDebug("y is ", y);
rsDebug("z is ", z);
lab.x = maxf(0.0, 116.0 * y - 16.0);
lab.y = 500.0 * (x - y);
lab.z = 200.0 * (y - z);
rsDebug("lab before is ", lab);
}
static void labtoxyz(float3 lab, float3 xyz) {
float fy = (lab.x + 16.0) / 116.0;
float fx = lab.y / 500.0 + fy;
float fz = fy - lab.z / 200.0;
float tmp = pow(fx, 3);
float xr = tmp > XYZ_EPSILON ? tmp : (116.0 * fx - 16.0) / XYZ_KAPPA;
float yr = lab.x > XYZ_KAPPA * XYZ_EPSILON ? pow(fy, 3) : lab.x / XYZ_KAPPA;
tmp = pow(fz, 3);
float zr = tmp > XYZ_EPSILON ? tmp : (116.0 * fz - 16.0) / XYZ_KAPPA;
xyz.x = xr * XYZ_WHITE_REFERENCE_X;
xyz.y = yr * XYZ_WHITE_REFERENCE_Y;
xyz.z = zr * XYZ_WHITE_REFERENCE_Z;
}
static void xyztorgb(float3 xyz, uchar4 argb) {
float r = (xyz.x * 3.2406 + xyz.y * -1.5372 + xyz.z * -0.4986) / 100.0;
float g = (xyz.x * -0.9689 + xyz.y * 1.8758 + xyz.z * 0.0415) / 100.0;
float b = (xyz.x * 0.0557 + xyz.y * -0.2040 + xyz.z * 1.0570) / 100.0;
r = r > 0.0031308 ? 1.055 * powr(r, 1 / 2.4) - 0.055 : 12.92 * r;
g = g > 0.0031308 ? 1.055 * powr(g, 1 / 2.4) - 0.055 : 12.92 * g;
b = b > 0.0031308 ? 1.055 * powr(b, 1 / 2.4) - 0.055 : 12.92 * b;
argb.a = 255;
uint ir = (uint)round(r * 255.0f);
uint ig = (uint)round(g * 255.0f);
uint ib = (uint)round(b * 255.0f);
argb.r = ir > 255 ? 255 : (uchar)ir;
argb.g = ig > 255 ? 255 : (uchar)ig;
argb.b = ib > 255 ? 255 : (uchar)ib;
}
void RS_KERNEL rgb2lab_kernel(uchar4 in, uint32_t x, uint32_t y) {
float3 xyz;
rgbToXyz(in, xyz);
float3 lab;
xyzToLab(xyz, lab);
rsDebug("lab out is ", lab);
rsSetElementAt_float3(gOut, lab, x, y);
}
uchar4 RS_KERNEL lab2rgb_kernel(float3 in) {
rsDebug("in is ", in);
float3 xyz;
labtoxyz(in, xyz);
rsDebug("l2r xyz out is ", xyz);
uchar4 argb;
xyztorgb(xyz, argb);
rsDebug("argb out is ", argb);
return argb;
}
void rgbToLab() {
rsDebug("woa!", 0);
rsForEach(rgb2lab_kernel, gIn);
rsDebug("out[0][0]=", rsGetElementAt_float3(gOut, 0, 0));
rsDebug("out[0][1]=", rsGetElementAt_float3(gOut, 0, 1));
rsDebug("out[1][0]=", rsGetElementAt_float3(gOut, 1, 0));
}
void labToRgb() {
rsForEach(lab2rgb_kernel, gIn, gOut);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment