diff options
Diffstat (limited to 'third_party/skcms/src/GaussNewton.c')
-rw-r--r-- | third_party/skcms/src/GaussNewton.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/third_party/skcms/src/GaussNewton.c b/third_party/skcms/src/GaussNewton.c index 1f7d168dcb..842f7ed804 100644 --- a/third_party/skcms/src/GaussNewton.c +++ b/third_party/skcms/src/GaussNewton.c @@ -8,11 +8,16 @@ #include "../skcms.h" #include "GaussNewton.h" #include "LinearAlgebra.h" +#include "TransferFunction.h" #include <assert.h> +#include <string.h> -bool skcms_gauss_newton_step(float (* t)(float x, const void*), const void* t_ctx, - float (* f)(float x, const float P[4]), - void (*grad_f)(float x, const float P[4], float dfdP[4]), +bool skcms_gauss_newton_step(float (* t)(float x, const void*), + const void* t_ctx, + float (* f)(float x, const void*, const float P[4]), + const void* f_ctx, + void (*grad_f)(float x, const void*, const float P[4], float dfdP[4]), + const void* g_ctx, float P[4], float x0, float x1, int N) { // We'll sample x from the range [x0,x1] (both inclusive) N times with even spacing. @@ -58,10 +63,10 @@ bool skcms_gauss_newton_step(float (* t)(float x, const void*), const void* for (int i = 0; i < N; i++) { float x = x0 + i*dx; - float resid = t(x,t_ctx) - f(x,P); + float resid = t(x,t_ctx) - f(x,f_ctx,P); float dfdP[4] = {0,0,0,0}; - grad_f(x,P, dfdP); + grad_f(x,g_ctx,P, dfdP); for (int r = 0; r < 4; r++) { for (int c = 0; c < 4; c++) { @@ -94,3 +99,25 @@ bool skcms_gauss_newton_step(float (* t)(float x, const void*), const void* P[3] += dP.vals[3]; return true; } + +float skcms_eval_curve(float x, const void* vctx) { + const skcms_Curve* curve = (const skcms_Curve*)vctx; + + if (curve->table_entries == 0) { + return skcms_TransferFunction_eval(&curve->parametric, x); + } + + // TODO: today we should always hit an entry exactly, but if that changes, lerp? + // (We add half to account for slight int -> float -> int round tripping issues.) + int ix = (int)( x*(curve->table_entries - 1) + 0.5f ); + + if (curve->table_8) { + return curve->table_8[ix] * (1/255.0f); + } else { + uint16_t be; + memcpy(&be, curve->table_16 + 2*ix, 2); + + uint16_t le = ((be << 8) | (be >> 8)) & 0xffff; + return le * (1/65535.0f); + } +} |