I am trying to create Brightness and Contrast filters similar to new Adobe Photoshop or Lightroom Brightness and Contrast filters. I am doing RGB -> XYZ - xyY conversion and with increasing pixel Brightness (Y) ( not linear increase, Brightness increase is calculated depending on pixels Brightness) and then converting back to XYZ and RGB trying to get as similar as possible values to test image that I used to increase Brightness in Adobe. I am not getting similar results as I think I am missing something, maybe gamma calculation or as images are in sRGB space some color space conversion, or I simple have bug in Color conversion code? So here are Color conversion function I used (in Objective-C) :
-(void) convertRGBcolor:(cColorRGB*) pRGB toXYZcolor:(zColorXYZ*) pXYZ
{
if(pRGB == nil || pXYZ == nil) {
return;
}
double var_R = ( pRGB->r / 255.0 );
double var_G = ( pRGB->g / 255.0 );
double var_B = ( pRGB->b / 255.0 );
if ( var_R > 0.04045 ) var_R = pow((( var_R + 0.055 ) / 1.055 ) , 2.4);
else var_R = var_R / 12.92;
if ( var_G > 0.04045 ) var_G = pow((( var_G + 0.055 ) / 1.055 ) , 2.4);
else var_G = var_G / 12.92;
if ( var_B > 0.04045 ) var_B = pow((( var_B + 0.055 ) / 1.055 ) , 2.4);
else var_B = var_B / 12.92;
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
//Observer. = 2°, Illuminant = D65
pXYZ->X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
pXYZ->Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
pXYZ->Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
}
-(void) convertXYZcolor:(zColorXYZ*) pXYZ toRGBcolor:(cColorRGB*) pRGB
{
if(pRGB == nil || pXYZ == nil) {
return;
}
double var_X = pXYZ->X / 100; //X from 0 to 95.047
double var_Y = pXYZ->Y / 100; //Y from 0 to 100.000
double var_Z = pXYZ->Z / 100; //Z from 0 to 108.883
double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
double var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415;
double var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
if ( var_R > 0.0031308 ) var_R = 1.055 * ( pow( var_R,(1/2.4))) - 0.055;
else var_R = 12.92 * var_R;
if ( var_G > 0.0031308 ) var_G = 1.055 * ( pow( var_G,(1/2.4))) - 0.055;
else var_G = 12.92 * var_G;
if ( var_B > 0.0031308 ) var_B = 1.055 * ( pow( var_B,(1/2.4))) - 0.055;
else var_B = 12.92 * var_B;
pRGB->r = var_R * 255;
pRGB->g = var_G * 255;
pRGB->b = var_B * 255;
}
-(void) convertYxycolor:(zColorYxy*) pYxy toXYZcolor:(zColorXYZ*) pXYZ
{
if(pYxy == nil || pXYZ == nil) {
return;
}
pXYZ->X = pYxy->x * ( pYxy->Y / pYxy->y );
pXYZ->Y = pYxy->Y;
pXYZ->Z = ( 1 - pYxy->x - pYxy->y ) * ( pYxy->Y / pYxy->y );
}
-(void) convertXYZcolor:(zColorXYZ*) pXYZ toYxycolor:(zColorYxy*) pYxy
{
if(pYxy == nil || pXYZ == nil) {
return;
}
pYxy->Y = pXYZ->Y;
pYxy->x = pXYZ->X / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
pYxy->y = pXYZ->Y / ( pXYZ->X + pXYZ->Y + pXYZ->Z );
}