Created
October 8, 2017 17:15
-
-
Save alexbatashev/79aba4be2300364b5a622cae0402a5e7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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