public static Babl?Create(string name, BablTrcType type, double gamma, int lutNum, float[] lut) { trc = new BablTrc(type, gamma); int i; if (lutNum is not 0) { for (i = 0; trcDb[i] is not null; i++) { if (trcDb[i] !.LutSize == lutNum && trcDb[i] !.Lut.SequenceEqual(lut)) { return(trcDb[i] !); } } } else { for (i = 0; trcDb[i] is not null; i++) { if (trcDb[i] !.Equals(type, lutNum, gamma)) { return(trcDb[i] !); } } } if (i >= MaxTrcs - 1) { Log("too many BablTrcs"); return(null); } if (name is not "") { trc.Name = name; } else if (lutNum is not 0) { trc.Name = "lut-trc"; } else { trc.Name = $"trc-{type}-{gamma}"; } if (lutNum is not 0) { int j; trc.Lut = new float[lutNum]; trc.InvLut = new float[lutNum]; lut.CopyTo(trc.Lut, 0); for (j = 0; j < lutNum; j++) { int k; var min = 0.0; var max = 1.0; for (k = 0; k < 16; k++) { var guess = (min + max) / 2; var reversedIndex = LutToLinear(trc, (float)guess) * (lutNum - 1.0); if (reversedIndex < j) { min = guess; } else if (reversedIndex > j) { max = guess; } } trc.InvLut[j] = (float)(min + max) / 2; } } trc.FuncToLinearBuffered = ToLinearBufferedGeneric; trc.FuncFromLinearBuffered = FromLinearBufferedGeneric; switch (trc.TrcType) { case BablTrcType.Linear: trc.FuncToLinear = Linear; trc.FuncFromLinear = Linear; trc.FuncFromLinearBuffered = LinearBuffered; trc.FuncToLinearBuffered = LinearBuffered; break; case BablTrcType.FormulaGamma: trc.FuncToLinear = GammaToLinear; trc.FuncFromLinear = GammaFromLinear; trc.FuncToLinearBuffered = GammaToLinearBuffered; trc.FuncFromLinearBuffered = GammaFromLinearBuffered; trc.GammaToLinearX0 = (float)GammaX0; trc.GammaToLinearX1 = (float)GammaX1; trc.GammaToLinearPoly = Polynomial.ApproximateGamma(trc.Gamma, trc.GammaToLinearX0, trc.GammaToLinearX1, GammaDegree, GammaScale); trc.GammaFromLinearX0 = (float)GammaX0; trc.GammaFromLinearX1 = (float)GammaX1; trc.GammaFromLinearPoly = Polynomial.ApproximateGamma(trc.Rgamma, trc.GammaFromLinearX0, trc.GammaFromLinearX1, GammaDegree, GammaScale); break; case BablTrcType.FormulaCie: trc.Lut = new float[4]; { for (var j = 0; j < 4; j++) { trc.Lut[j] = lut[j]; } } trc.FuncToLinear = FormulaCieToLinear; trc.FuncFromLinear = FormulaCieFromLinear; trc.GammaToLinearX0 = lut[4]; trc.GammaToLinearX1 = (float)GammaX1; trc.GammaToLinearPoly = Polynomial.ApproximateGamma(trc.Rgamma, trc.GammaToLinearX0, trc.GammaToLinearX1, GammaDegree, GammaScale); trc.GammaFromLinearX0 = lut[3] * lut[4]; trc.GammaFromLinearX1 = (float)GammaX1; trc.GammaFromLinearPoly = Polynomial.ApproximateGamma(trc.Rgamma, trc.GammaFromLinearX0, trc.GammaFromLinearX1, GammaDegree, GammaScale); break; case BablTrcType.FormulaSrgb: trc.Lut = new float[7]; { for (var j = 0; j < 7; j++) { trc.Lut[j] = lut[j]; } } trc.FuncToLinear = FormulaSrgbToLinear; trc.FuncFromLinear = FormulaSrgbFromLinear; trc.GammaToLinearX0 = lut[4]; trc.GammaToLinearX1 = (float)GammaX1; trc.GammaToLinearPoly = Polynomial.ApproximateGamma(trc.Gamma, trc.GammaToLinearX0, trc.GammaToLinearX1, GammaDegree, GammaScale); trc.GammaFromLinearX0 = lut[3] * lut[4]; trc.GammaFromLinearX1 = (float)GammaX1; trc.GammaFromLinearPoly = Polynomial.ApproximateGamma(trc.Rgamma, trc.GammaFromLinearX0, trc.GammaFromLinearX1, GammaDegree, GammaScale); break; case BablTrcType.Srgb: trc.FuncToLinear = SrgbToLinear; trc.FuncFromLinear = SrgbFromLinear; trc.FuncFromLinearBuffered = SrgbFromLinearBuffered; trc.FuncToLinearBuffered = SrgbToLinearBuffered; break; case BablTrcType.Lut: trc.FuncToLinear = LutToLinear; trc.FuncFromLinear = LutFromLinear; break; } trcDb[i] = trc; return(trc); }