try this:
// TestRGB2Lab.c for msvc
#include <stdio.h>
//#include <stdbool.h>
#include <math.h>
typedef int bool;
#define true 1
#define false 0
typedef struct _VEC3
{
float x,y,z;
} VEC3, *PVEC3;
VEC3 RGB2Lab(VEC3 rgb)
{
VEC3 rv3;
float R = rgb.x;
float G = rgb.y;
float B = rgb.z;
// threshold
float T = 0.008856;
float X = R * 0.412453 + G * 0.357580 + B * 0.180423;
float Y = R * 0.212671 + G * 0.715160 + B * 0.072169;
float Z = R * 0.019334 + G * 0.119193 + B * 0.950227;
bool XT, YT, ZT;
float fX, fY, fZ;
float Y3;
float L;
float a, b;
// Normalize for D65 white point
X = X / 0.950456;
//Y = Y;
Z = Z / 1.088754;
if (X > T) XT = true; else XT = false;
if (Y > T) YT = true; else YT = false;
if (Z > T) ZT = true; else ZT = false;
Y3 = pow(Y, 1 / 3.0);
if (XT) {
fX = pow(X, 1 / 3.0);
} else {
fX = 7.787 * X + 16 / 116;
}
if (YT) {
fY = Y3;
} else {
fY = 7.787 * Y + 16 / 116;
}
if (ZT) {
fZ = pow(Z, 1 / 3.0);
} else {
fZ = 7.787 * Z + 16 / 116;
}
if (YT) {
L = (116 * Y3) - 16.0;
} else {
L = 903.3 * Y;
}
a = 500 * (fX - fY);
b = 200 * (fY - fZ);
//return vec3(L, a, b);
rv3.x = L;
rv3.y = a;
rv3.z = b;
return rv3;
}
VEC3 Lab2RGB(VEC3 lab)
{
VEC3 rv3;
//Thresholds
float T1 = 0.008856;
float T2 = 0.206893;
float X, Y, Z;
float fX, fY, fZ;
float R, G, B;
//Compute Y
bool XT, YT, ZT;
XT = false;
YT = false;
ZT = false;
fY = pow(((lab.x + 16.0) / 116.0), 3);
if (fY > T1) {
YT = true;
}
if (YT) {
fY = fY;
} else {
fY = (lab.x / 903.3);
}
Y = fY;
//Alter fY slightly for further calculations
if (YT) {
fY = pow(fY, 1 / 3.0);
} else {
fY = (7.787 * fY + 16.0 / 116.0);
}
//Compute X
fX = (lab.y / 500.0) + fY;
if (fX > T2) {
XT = true;
}
if (XT) {
X = pow(fX, 3);
} else {
X = ((fX - (16 / 116.0)) / 7.787);
}
//Compute Z
fZ = fY - (lab.z / 200.0);
if (fZ > T2) {
ZT = true;
}
if (ZT) {
Z = pow(fZ, 3);
} else {
Z = ((fZ - (16 / 116.0)) / 7.787);
}
//Normalize for D65 white point
X = X * 0.950456;
Z = Z * 1.088754;
//XYZ to RGB part
R = 3.240479 * X + -1.537150 * Y + -0.498535 * Z;
G = -0.969256 * X + 1.875991 * Y + 0.041556 * Z;
B = 0.055648 * X + -0.204043 * Y + 1.057311 * Z;
rv3.x = R;
rv3.y = G;
rv3.z = B;
return rv3;
//return vec3(R, G, B);
}
int main(int argc, char **argv)
{
VEC3 v3;
v3.x = 50.0;
v3.y = 50.0;
v3.z = 50.0;
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
v3 = Lab2RGB(v3); // pass copy of v3
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
v3 = RGB2Lab(v3); // pass copy of v3
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
return 0;
}
Can anyone try this version with MSVS 2013 in C mode (C99)?
With PellesC one can compile it. // RGB2LabTest.c for C99
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
typedef struct _VEC3
{
float x,y,z;
} VEC3, *pvec3;
VEC3 RGB2Lab(VEC3 rgb)
{
VEC3 rv3;
float R = rgb.x;
float G = rgb.y;
float B = rgb.z;
// threshold
float T = 0.008856;
float X = R * 0.412453 + G * 0.357580 + B * 0.180423;
float Y = R * 0.212671 + G * 0.715160 + B * 0.072169;
float Z = R * 0.019334 + G * 0.119193 + B * 0.950227;
// Normalize for D65 white point
X = X / 0.950456;
//Y = Y;
Z = Z / 1.088754;
bool XT, YT, ZT;
if (X > T) XT = true; else XT = false;
if (Y > T) YT = true; else YT = false;
if (Z > T) ZT = true; else ZT = false;
float Y3 = pow(Y, 1 / 3.0);
float fX, fY, fZ;
if (XT) {
fX = pow(X, 1 / 3.0);
} else {
fX = 7.787 * X + 16 / 116;
}
if (YT) {
fY = Y3;
} else {
fY = 7.787 * Y + 16 / 116;
}
if (ZT) {
fZ = pow(Z, 1 / 3.0);
} else {
fZ = 7.787 * Z + 16 / 116;
}
float L;
if (YT) {
L = (116 * Y3) - 16.0;
} else {
L = 903.3 * Y;
}
float a = 500 * (fX - fY);
float b = 200 * (fY - fZ);
//return vec3(L, a, b);
rv3.x = L;
rv3.y = a;
rv3.z = b;
return rv3;
}
VEC3 Lab2RGB(VEC3 lab)
{
VEC3 rv3;
//Thresholds
float T1 = 0.008856;
float T2 = 0.206893;
float X, Y, Z;
//Compute Y
bool XT, YT, ZT;
XT = false;
YT = false;
ZT = false;
float fY = pow(((lab.x + 16.0) / 116.0), 3);
if (fY > T1) {
YT = true;
}
if (YT) {
fY = fY;
} else {
fY = (lab.x / 903.3);
}
Y = fY;
//Alter fY slightly for further calculations
if (YT) {
fY = pow(fY, 1 / 3.0);
} else {
fY = (7.787 * fY + 16.0 / 116.0);
}
//Compute X
float fX = (lab.y / 500.0) + fY;
if (fX > T2) {
XT = true;
}
if (XT) {
X = pow(fX, 3);
} else {
X = ((fX - (16 / 116.0)) / 7.787);
}
//Compute Z
float fZ = fY - (lab.z / 200.0);
if (fZ > T2) {
ZT = true;
}
if (ZT) {
Z = pow(fZ, 3);
} else {
Z = ((fZ - (16 / 116.0)) / 7.787);
}
//Normalize for D65 white point
X = X * 0.950456;
Z = Z * 1.088754;
//XYZ to RGB part
float R = 3.240479 * X + -1.537150 * Y + -0.498535 * Z;
float G = -0.969256 * X + 1.875991 * Y + 0.041556 * Z;
float B = 0.055648 * X + -0.204043 * Y + 1.057311 * Z;
rv3.x = R;
rv3.y = G;
rv3.z = B;
return rv3;
//return vec3(R, G, B);
}
int main(int argc, char **argv)
{
VEC3 v3;
v3.x = 50.0;
v3.y = 50.0;
v3.z = 50.0;
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
v3 = Lab2RGB(v3); // pass copy of v3
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
v3 = RGB2Lab(v3); // pass copy of v3
printf("x= %0.3f, y= %0.3f, z= %0.3f\n", v3.x, v3.y, v3.z);
return 0;
}