// LG-Cine Log to Rec.709 2.4 gamma (Rec. 1886) // for 709L decoded case // ver. 2017-08-31 __CONSTANT__ float Mat_XYZ[] = { 2.070508203, -1.326703945, 0.206680579, 0.365025137, 0.680458525, -0.045463559, -0.04950397, -0.04950397, 1.188095285, }; __CONSTANT__ float Mat_709[] = { 0.212639006, 0.715168679, 0.072192315, -0.114592178, -0.385407822, 0.5, 0.5, -0.454155517, -0.045844483, }; __CONSTANT__ float Mat_RGB[] = { 1.0, -0.018578786, 0.127119219, 1.0, 0.018578786, -0.127119219, 1.0, 0.686805438, -0.072848539, }; __CONSTANT__ float Mat_OUT[] = { 3.240969942, -1.537383178, -0.49861076, -0.969243636, 1.875967502, 0.041555057, 0.05563008, -0.203976959, 1.056971514, }; __DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B) { float3 yuv, rgb, xyz; // foward transform of 709L YCbCr matrix yuv.x = (Mat_709[0]*p_R + Mat_709[1]*p_G + Mat_709[2]*p_B)*219.0/255.0+16.0/255.0; yuv.y = (Mat_709[3]*p_R + Mat_709[4]*p_G + Mat_709[5]*p_B)*224.0/255.0; yuv.z = (Mat_709[6]*p_R + Mat_709[7]*p_G + Mat_709[8]*p_B)*224.0/255.0; // Inverse transform of LG-Cine Log rgb.x = Mat_RGB[0]*yuv.x + Mat_RGB[1]*yuv.y + Mat_RGB[2]*yuv.z; rgb.y = Mat_RGB[3]*yuv.x + Mat_RGB[4]*yuv.y + Mat_RGB[5]*yuv.z; rgb.z = Mat_RGB[6]*yuv.x + Mat_RGB[7]*yuv.y + Mat_RGB[8]*yuv.z; rgb.x = rgb.x < 1.0/1024.0 ? 1.0/1024.0 : rgb.x; rgb.y = rgb.y < 1.0/1024.0 ? 1.0/1024.0 : rgb.y; rgb.z = rgb.z < 1.0/1024.0 ? 1.0/1024.0 : rgb.z; rgb.x = log((_expf((rgb.x - 0.600083459f)/0.106382979f) - 0.003550082f)/0.18); rgb.y = log((_expf((rgb.y - 0.600083459f)/0.106382979f) - 0.003550082f)/0.18); rgb.z = log((_expf((rgb.z - 0.600083459f)/0.106382979f) - 0.003550082f)/0.18); rgb.x = _exp2f(rgb.x)*0.18; rgb.y = _exp2f(rgb.y)*0.18; rgb.z = _exp2f(rgb.z)*0.18; xyz.x = Mat_XYZ[0]*rgb.x + Mat_XYZ[1]*rgb.y + Mat_XYZ[2]*rgb.z; xyz.y = Mat_XYZ[3]*rgb.x + Mat_XYZ[4]*rgb.y + Mat_XYZ[5]*rgb.z; xyz.z = Mat_XYZ[6]*rgb.x + Mat_XYZ[7]*rgb.y + Mat_XYZ[8]*rgb.z; // Forward transform of Rec.709 2.4 gamma (Rec.1886) rgb.x = Mat_OUT[0]*xyz.x + Mat_OUT[1]*xyz.y + Mat_OUT[2]*xyz.z ; rgb.y = Mat_OUT[3]*xyz.x + Mat_OUT[4]*xyz.y + Mat_OUT[5]*xyz.z ; rgb.z = Mat_OUT[6]*xyz.x + Mat_OUT[7]*xyz.y + Mat_OUT[8]*xyz.z ; rgb.x = rgb.x < 0 ? 0 : _powf(rgb.x, 1.0f/2.4f); rgb.y = rgb.y < 0 ? 0 : _powf(rgb.y, 1.0f/2.4f); rgb.z = rgb.z < 0 ? 0 : _powf(rgb.z, 1.0f/2.4f); return rgb; }