diff --git a/util/rgb2lab.c b/util/rgb2lab.c index 15d666937..b91a2617e 100644 --- a/util/rgb2lab.c +++ b/util/rgb2lab.c @@ -39,41 +39,62 @@ float lab_distance(struct color *c0, struct color *c1) return sqrtf(sum); } +const float xyz_table[256] = { + 0.000000f, 0.030353f, 0.060705f, 0.091058f, 0.121411f, 0.151763f, 0.182116f, 0.212469f, + 0.242822f, 0.273174f, 0.303527f, 0.334654f, 0.367651f, 0.402472f, 0.439144f, 0.477695f, + 0.518152f, 0.560539f, 0.604883f, 0.651209f, 0.699541f, 0.749903f, 0.802319f, 0.856812f, + 0.913406f, 0.972122f, 1.032982f, 1.096009f, 1.161224f, 1.228649f, 1.298303f, 1.370208f, + 1.444384f, 1.520851f, 1.599629f, 1.680737f, 1.764195f, 1.850022f, 1.938236f, 2.028857f, + 2.121901f, 2.217388f, 2.315336f, 2.415763f, 2.518686f, 2.624122f, 2.732089f, 2.842604f, + 2.955683f, 3.071344f, 3.189603f, 3.310476f, 3.433981f, 3.560131f, 3.688945f, 3.820436f, + 3.954624f, 4.091520f, 4.231141f, 4.373503f, 4.518620f, 4.666508f, 4.817182f, 4.970656f, + 5.126946f, 5.286066f, 5.448028f, 5.612849f, 5.780543f, 5.951124f, 6.124607f, 6.301003f, + 6.480328f, 6.662595f, 6.847818f, 7.036011f, 7.227186f, 7.421358f, 7.618539f, 7.818743f, + 8.021983f, 8.228271f, 8.437622f, 8.650046f, 8.865561f, 9.084172f, 9.305898f, 9.530748f, + 9.758737f, 9.989874f, 10.224174f, 10.461649f, 10.702312f, 10.946172f, 11.193243f, 11.443539f, + 11.697067f, 11.953843f, 12.213880f, 12.477184f, 12.743770f, 13.013649f, 13.286834f, 13.563335f, + 13.843163f, 14.126330f, 14.412848f, 14.702728f, 14.995980f, 15.292616f, 15.592647f, 15.896087f, + 16.202940f, 16.513222f, 16.826939f, 17.144112f, 17.464739f, 17.788841f, 18.116423f, 18.447498f, + 18.782076f, 19.120165f, 19.461781f, 19.806931f, 20.155624f, 20.507870f, 20.863686f, 21.223072f, + 21.586052f, 21.952623f, 22.322798f, 22.696589f, 23.074007f, 23.455065f, 23.839766f, 24.228119f, + 24.620140f, 25.015837f, 25.415215f, 25.818291f, 26.225073f, 26.635567f, 27.049786f, 27.467737f, + 27.889431f, 28.314880f, 28.744089f, 29.177071f, 29.613832f, 30.054384f, 30.498737f, 30.946899f, + 31.398874f, 31.854683f, 32.314323f, 32.777817f, 33.245159f, 33.716366f, 34.191444f, 34.670406f, + 35.153271f, 35.640026f, 36.130688f, 36.625271f, 37.123775f, 37.626221f, 38.132610f, 38.642952f, + 39.157257f, 39.675529f, 40.197788f, 40.724026f, 41.254269f, 41.788513f, 42.326775f, 42.869057f, + 43.415371f, 43.965725f, 44.520126f, 45.078583f, 45.641106f, 46.207706f, 46.778385f, 47.353153f, + 47.932022f, 48.514999f, 49.102089f, 49.693306f, 50.288658f, 50.888145f, 51.491779f, 52.099567f, + 52.711521f, 53.327648f, 53.947960f, 54.572456f, 55.201149f, 55.834049f, 56.471165f, 57.112492f, + 57.758053f, 58.407848f, 59.061890f, 59.720188f, 60.382740f, 61.049568f, 61.720665f, 62.396049f, + 63.075722f, 63.759697f, 64.447975f, 65.140572f, 65.837494f, 66.538734f, 67.244324f, 67.954254f, + 68.668549f, 69.387192f, 70.110199f, 70.837593f, 71.569359f, 72.305527f, 73.046089f, 73.791054f, + 74.540436f, 75.294235f, 76.052460f, 76.815125f, 77.582237f, 78.353790f, 79.129807f, 79.910286f, + 80.695236f, 81.484665f, 82.278587f, 83.076996f, 83.879913f, 84.687332f, 85.499268f, 86.315727f, + 87.136719f, 87.962234f, 88.792320f, 89.626945f, 90.466133f, 91.309868f, 92.158203f, 93.011093f, + 93.868591f, 94.730659f, 95.597351f, 96.468628f, 97.344543f, 98.225060f, 99.110222f, 100.000000f +}; void rgb2lab (struct color *rgb, struct color *lab) { - float t; float v[3]; - float xyz[3]; + float x,y,z; + const float c = 16.0f/ 116.0f; - for (int i=0; i<3; i++) { - t = rgb->v[i]/255.0f; - if (t > 0.04045f) { - t = powf(((t+0.055f) / 1.055f), 2.4); - } else { - t/= 12.92f; - } - v[i]=t*100.0f; - } + v[0] = xyz_table[rgb->v[0]]; + v[1] = xyz_table[rgb->v[1]]; + v[2] = xyz_table[rgb->v[2]]; + x = (v[0] * 0.4124f + v[1] * 0.3576f + v[2] * 0.1805f) / 95.047f ; + y = (v[0] * 0.2126f + v[1] * 0.7152f + v[2] * 0.0722f) / 100.0f ; + z = (v[0] * 0.0193f + v[1] * 0.1192f + v[2] * 0.9505f) / 108.883f ; - xyz[0] = (v[0] * 0.4124f + v[1] * 0.3576f + v[2] * 0.1805f) / 95.047f ; - xyz[1] = (v[0] * 0.2126f + v[1] * 0.7152f + v[2] * 0.0722f) / 100.0f ; - xyz[2] = (v[0] * 0.0193f + v[1] * 0.1192f + v[2] * 0.9505f) / 108.883f ; + x = (x>0.008856f)? cbrtf(x) : (x * 7.787f) + c; + y = (y>0.008856f)? cbrtf(y) : (y * 7.787f) + c; + z = (z>0.008856f)? cbrtf(z) : (z * 7.787f) + c; - for (int i=0; i<3; i++) { - t = xyz[i]; - if (t > 0.008856f) { - t = powf(t, 0.333333f); - } else { - t = (7.787f * t) + (16.0f/ 116.0f); - } - xyz[i]=t; - } - - lab->L = (116.0f * xyz[1]-16.0f); - lab->A = (500.0f * (xyz[0]-xyz[1])); - lab->B = (200.0f * (xyz[1]-xyz[2])); + lab->L = (116.0f * y-16.0f); + lab->A = (500.0f * (x-y)); + lab->B = (200.0f * (y-z)); } static inline int fround(float flt)