/** * Create viewing conditions assuming full adaption. This is primarily useful in color management * applications. * * @param XYZ_w XYZ of adopted whitepoint * @param L_A average luminance of visual surround * @param Y_b adaptation luminance of color background * @param sur the surrounding * @return a fully adapted viewing conditions instance */ public static ViewingConditions createFullyAdapted( CIEXYZ XYZ_w, float L_A, float Y_b, Surrounding sur) { double[] xyz_w = MathTools.floatToDoubleArray(XYZ_w.toCIEXYZ100()); double[] RGB_w = CS_CIECAM02.XYZtoCAT02(xyz_w); double[] RGB_c = calcAdaptedRGBc(XYZ_w, RGB_w, 1.0); return new ViewingConditions(xyz_w, L_A, Y_b, sur, RGB_w, RGB_c); }
/** * Construct a new ViewingConditions instance. The degree of adaption (D) is derived from the * background and surround. This is the standard case treated in CIE 159:2004. * * @param XYZ_w XYZ of adopted whitepoint * @param L_A average luminance of visual surround * @param Y_b adaptation luminance of color background * @param sur the surrounding * @return a ViewingConditions instance */ public static ViewingConditions createAdapted( CIEXYZ XYZ_w, double L_A, double Y_b, Surrounding sur) { double[] xyz_w = MathTools.floatToDoubleArray(XYZ_w.toCIEXYZ100()); // calculate RGB whitepoint double[] RGB_w = CS_CIECAM02.XYZtoCAT02(xyz_w); double D = calcD(L_A, sur); double[] RGB_c = calcAdaptedRGBc(XYZ_w, RGB_w, D); return new ViewingConditions(xyz_w, L_A, Y_b, sur, RGB_w, RGB_c); }
/** * Construct a new ViewingConditions instance. This constructor is for internal use. * * @param XYZ_w XYZ of adopted whitepoint * @param L_A average luminance of visual surround * @param Y_b adaptation luminance of color background * @param sur the surrounding * @param RGB_w the white point in RGB values (equations 7.4-6) * @param RGB_c the adapted RGB values (equations 7.4-6) */ private ViewingConditions( double[] XYZ_w, double L_A, double Y_b, Surrounding sur, double[] RGB_w, double[] RGB_c) { this.XYZ_w = XYZ_w; // XYZ whitepoint this.L_A = L_A; // average luminance of visual surround this.Y_b = Y_b; // adaptation luminance of color background this.surrounding = sur; // calculate increase in brightness and colorfulness caused by brighter viewing environments double L_Ax5 = 5.0 * L_A; double k = 1.0 / (L_Ax5 + 1.0); double kpow4 = Math.pow(k, 4.0); F_L = 0.2 * kpow4 * (L_Ax5) + 0.1 * Math.pow(1.0 - kpow4, 2.0) * Math.pow(L_Ax5, 1.0 / 3.0); // calculate response compression on J and C caused by background lightness. n = Y_b / XYZ_w[1]; z = 1.48 + Math.sqrt(n); N_bb = 0.725 * Math.pow(1.0 / n, 0.2); N_cb = N_bb; // chromatic contrast factors (calculate increase in J, Q, and C caused by dark // backgrounds) // calculate achromatic response to white double[] RGB_wc = new double[] {RGB_c[0] * RGB_w[0], RGB_c[1] * RGB_w[1], RGB_c[2] * RGB_w[2]}; double[] RGBPrime_w = CS_CIECAM02.CAT02toHPE(RGB_wc); double[] RGBPrime_aw = new double[3]; for (int channel = 0; channel < RGBPrime_w.length; channel++) { if (RGBPrime_w[channel] >= 0) { double n = Math.pow(F_L * RGBPrime_w[channel] / 100.0, 0.42); RGBPrime_aw[channel] = 400.0 * n / (n + 27.13) + 0.1; } else { double n = Math.pow(-1.0 * F_L * RGBPrime_w[channel] / 100.0, 0.42); RGBPrime_aw[channel] = -400.0 * n / (n + 27.13) + 0.1; } } A_w = (2.0 * RGBPrime_aw[0] + RGBPrime_aw[1] + RGBPrime_aw[2] / 20.0 - 0.305) * N_bb; D_RGB = RGB_c; }