MCPcopy Create free account
hub / github.com/FastLED/FastLED / build_lut

Function build_lut

src/fl/gfx/rgbw_colorimetric.cpp.hpp:861–945  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

859}
860
861LutTable build_lut(const ProfileCache& cache, int grid_n,
862 LutInterp interp) FL_NOEXCEPT {
863 LutTable lut;
864 // Guard against degenerate grids: N < 2 would divide-by-zero in the
865 // 1/(N-1) step below, and negative N would overflow the allocation size.
866 // Return an empty LutTable so callers can detect failure via .N == 0.
867 if (grid_n < 2) {
868 return lut;
869 }
870 const fl::size_t n = static_cast<fl::size_t>(grid_n);
871 lut.N = grid_n;
872 lut.interp = interp;
873 const fl::size_t stride =
874 (interp == LutInterp::Hermite) ? kLutStrideHermite : kLutStrideBilinear;
875 lut.cells = fl::make_unique<i16[]>(n * n * stride);
876
877 const float* R = cache.profile->xy_r;
878 const float* G = cache.profile->xy_g;
879 const float* B = cache.profile->xy_b;
880 const float xmin = fl::min(fl::min(R[0], G[0]), B[0]);
881 const float xmax = fl::max(fl::max(R[0], G[0]), B[0]);
882 const float ymin = fl::min(fl::min(R[1], G[1]), B[1]);
883 const float ymax = fl::max(fl::max(R[1], G[1]), B[1]);
884 const float xpad = (xmax - xmin) * 0.02f;
885 const float ypad = (ymax - ymin) * 0.02f;
886 lut.xy_min[0] = xmin - xpad;
887 lut.xy_min[1] = ymin - ypad;
888 lut.xy_max[0] = xmax + xpad;
889 lut.xy_max[1] = ymax + ypad;
890
891 i16* cells = lut.cells.get();
892 const int N = grid_n;
893 const float inv_Nm1 = 1.0f / static_cast<float>(N - 1);
894 const float cell_dx = (lut.xy_max[0] - lut.xy_min[0]) * inv_Nm1;
895 const float cell_dy = (lut.xy_max[1] - lut.xy_min[1]) * inv_Nm1;
896
897 auto sample = [&](float x, float y, float out[4]) FL_NOEXCEPT {
898 const float xy[2] = {x, y};
899 solve_strict_subgamut_xy(cache, xy, 1.0f, out);
900 };
901
902 for (int j = 0; j < N; ++j) {
903 const float y = lut.xy_min[1] + cell_dy * j;
904 for (int i = 0; i < N; ++i) {
905 const float x = lut.xy_min[0] + cell_dx * i;
906 float v[4];
907 sample(x, y, v);
908 i16* cell = &cells[(j * N + i) * stride];
909 cell[0] = quantize_lut_cell(v[0]);
910 cell[1] = quantize_lut_cell(v[1]);
911 cell[2] = quantize_lut_cell(v[2]);
912 cell[3] = quantize_lut_cell(v[3]);
913
914 if (interp != LutInterp::Hermite) continue;
915
916 // Numerical partials in cell-parameter (t) units. Sample
917 // half-a-cell ahead / behind in world coords, clamped to the LUT
918 // domain so edges fall back to one-sided differences. With

Callers

nothing calls this directly

Calls 6

maxFunction · 0.85
solve_strict_subgamut_xyFunction · 0.85
sampleFunction · 0.85
quantize_lut_cellFunction · 0.85
clampFunction · 0.85
getMethod · 0.45

Tested by

no test coverage detected