From 35444bf35a56805029a090a408d5a51464803cae Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 21 May 2014 07:43:09 +0200 Subject: m + add gamma sets with mapping function rather than lookup tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/libgamma-error.h | 6 ++ src/libgamma-facade.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/libgamma-facade.h | 120 +++++++++++++++++++++++ src/libgamma-method.h | 35 +++++-- 4 files changed, 420 insertions(+), 8 deletions(-) diff --git a/src/libgamma-error.h b/src/libgamma-error.h index a3c5387..acafacf 100644 --- a/src/libgamma-error.h +++ b/src/libgamma-error.h @@ -25,6 +25,12 @@ */ #define LIBGAMMA_NO_SUCH_ADJUSTMENT_METHOD -1 +/** + * `errno` has be set with a standard error number + * to indicate the what has gone wrong + */ +#define LIBGAMMA_ERRNO_SET -2 + #endif diff --git a/src/libgamma-facade.c b/src/libgamma-facade.c index e957fc2..ed23e9f 100644 --- a/src/libgamma-facade.c +++ b/src/libgamma-facade.c @@ -1302,6 +1302,273 @@ int libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t* restrict this, } + +/** + * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps_fun* red_function, + libgamma_gamma_ramps_fun* green_function, + libgamma_gamma_ramps_fun* blue_function) +{ + libgamma_crtc_information_t info; + libgamma_gamma_ramps_t ramps; + size_t i, n; + int e; + + if (libgamma_get_crtc_information(&info, this, CRTC_INFO_GAMMA_SIZE)) + { + e = info.gamma_size_error; + if (e < 0) + return e; + return errno = e, LIBGAMMA_ERRNO_SET; + } + + n = ramps. red_size = info. red_gamma_size; + n += ramps.green_size = info.green_gamma_size; + n += ramps. blue_size = info. blue_gamma_size; + + ramps. red = malloc(n * sizeof(uint16_t)); + ramps.green = ramps. red + ramps. red_size; + ramps. blue = ramps.green + ramps.green_size; + if (ramps.red == NULL) + return LIBGAMMA_ERRNO_SET; + + for (i = 0, n = ramps.red_size; i < n; i++) + ramps.red[i] = red_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.green_size; i < n; i++) + ramps.green[i] = green_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.blue_size; i < n; i++) + ramps.blue[i] = blue_function((float)i / (float)(n - 1)); + + e = libgamma_crtc_set_gamma_ramps(this, ramps); + free(ramps.red); + return e; +} + + +/** + * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps32_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps32_fun* red_function, + libgamma_gamma_ramps32_fun* green_function, + libgamma_gamma_ramps32_fun* blue_function) +{ + libgamma_crtc_information_t info; + libgamma_gamma_ramps32_t ramps; + size_t i, n; + int e; + + if (libgamma_get_crtc_information(&info, this, CRTC_INFO_GAMMA_SIZE)) + { + e = info.gamma_size_error; + if (e < 0) + return e; + return errno = e, LIBGAMMA_ERRNO_SET; + } + + n = ramps. red_size = info. red_gamma_size; + n += ramps.green_size = info.green_gamma_size; + n += ramps. blue_size = info. blue_gamma_size; + + ramps. red = malloc(n * sizeof(uint32_t)); + ramps.green = ramps. red + ramps. red_size; + ramps. blue = ramps.green + ramps.green_size; + if (ramps.red == NULL) + return LIBGAMMA_ERRNO_SET; + + for (i = 0, n = ramps.red_size; i < n; i++) + ramps.red[i] = red_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.green_size; i < n; i++) + ramps.green[i] = green_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.blue_size; i < n; i++) + ramps.blue[i] = blue_function((float)i / (float)(n - 1)); + + e = libgamma_crtc_set_gamma_ramps32(this, ramps); + free(ramps.red); + return e; +} + + +/** + * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps64_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps64_fun* red_function, + libgamma_gamma_ramps64_fun* green_function, + libgamma_gamma_ramps64_fun* blue_function) +{ + libgamma_crtc_information_t info; + libgamma_gamma_ramps64_t ramps; + size_t i, n; + int e; + + if (libgamma_get_crtc_information(&info, this, CRTC_INFO_GAMMA_SIZE)) + { + e = info.gamma_size_error; + if (e < 0) + return e; + return errno = e, LIBGAMMA_ERRNO_SET; + } + + n = ramps. red_size = info. red_gamma_size; + n += ramps.green_size = info.green_gamma_size; + n += ramps. blue_size = info. blue_gamma_size; + + ramps. red = malloc(n * sizeof(uint64_t)); + ramps.green = ramps. red + ramps. red_size; + ramps. blue = ramps.green + ramps.green_size; + if (ramps.red == NULL) + return LIBGAMMA_ERRNO_SET; + + for (i = 0, n = ramps.red_size; i < n; i++) + ramps.red[i] = red_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.green_size; i < n; i++) + ramps.green[i] = green_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.blue_size; i < n; i++) + ramps.blue[i] = blue_function((float)i / (float)(n - 1)); + + e = libgamma_crtc_set_gamma_ramps64(this, ramps); + free(ramps.red); + return e; +} + + +/** + * Set the gamma ramps for a CRTC, `float` function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_rampsf_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_rampsf_fun* red_function, + libgamma_gamma_rampsf_fun* green_function, + libgamma_gamma_rampsf_fun* blue_function) +{ + libgamma_crtc_information_t info; + libgamma_gamma_rampsf_t ramps; + size_t i, n; + int e; + + if (libgamma_get_crtc_information(&info, this, CRTC_INFO_GAMMA_SIZE)) + { + e = info.gamma_size_error; + if (e < 0) + return e; + return errno = e, LIBGAMMA_ERRNO_SET; + } + + n = ramps. red_size = info. red_gamma_size; + n += ramps.green_size = info.green_gamma_size; + n += ramps. blue_size = info. blue_gamma_size; + + ramps. red = malloc(n * sizeof(float)); + ramps.green = ramps. red + ramps. red_size; + ramps. blue = ramps.green + ramps.green_size; + if (ramps.red == NULL) + return LIBGAMMA_ERRNO_SET; + + for (i = 0, n = ramps.red_size; i < n; i++) + ramps.red[i] = red_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.green_size; i < n; i++) + ramps.green[i] = green_function((float)i / (float)(n - 1)); + + for (i = 0, n = ramps.blue_size; i < n; i++) + ramps.blue[i] = blue_function((float)i / (float)(n - 1)); + + e = libgamma_crtc_set_gamma_rampsf(this, ramps); + free(ramps.red); + return e; +} + + +/** + * Set the gamma ramps for a CRTC, `double` function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_rampsd_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_rampsd_fun* red_function, + libgamma_gamma_rampsd_fun* green_function, + libgamma_gamma_rampsd_fun* blue_function) +{ + libgamma_crtc_information_t info; + libgamma_gamma_rampsd_t ramps; + size_t i, n; + int e; + + if (libgamma_get_crtc_information(&info, this, CRTC_INFO_GAMMA_SIZE)) + { + e = info.gamma_size_error; + if (e < 0) + return e; + return errno = e, LIBGAMMA_ERRNO_SET; + } + + n = ramps. red_size = info. red_gamma_size; + n += ramps.green_size = info.green_gamma_size; + n += ramps. blue_size = info. blue_gamma_size; + + ramps. red = malloc(n * sizeof(double)); + ramps.green = ramps. red + ramps. red_size; + ramps. blue = ramps.green + ramps.green_size; + if (ramps.red == NULL) + return LIBGAMMA_ERRNO_SET; + + for (i = 0, n = ramps.red_size; i < n; i++) + ramps.red[i] = red_function((double)i / (double)(n - 1)); + + for (i = 0, n = ramps.green_size; i < n; i++) + ramps.green[i] = green_function((double)i / (double)(n - 1)); + + for (i = 0, n = ramps.blue_size; i < n; i++) + ramps.blue[i] = blue_function((double)i / (double)(n - 1)); + + e = libgamma_crtc_set_gamma_rampsd(this, ramps); + free(ramps.red); + return e; +} + + + #ifdef HAVE_NO_GAMMA_METHODS # pragma GCC diagnostic pop #endif diff --git a/src/libgamma-facade.h b/src/libgamma-facade.h index 8aae48f..a8e7636 100644 --- a/src/libgamma-facade.h +++ b/src/libgamma-facade.h @@ -25,6 +25,50 @@ #include + +/** + * Mapping function from [0, 1] float encoding value to [0, 2¹⁶ − 1] integer output value + * + * @param encoding [0, 1] float encoding value + * @return [0, 2¹⁶ − 1] integer output value + */ +typedef uint16_t libgamma_gamma_ramps_fun(float encoding); + +/** + * Mapping function from [0, 1] float encoding value to [0, 2³² − 1] integer output value + * + * @param encoding [0, 1] float encoding value + * @return [0, 2³² − 1] integer output value + */ +typedef uint32_t libgamma_gamma_ramps32_fun(float encoding); + +/** + * Mapping function from [0, 1] float encoding value to [0, 2⁶⁴ − 1] integer output value + * + * @param encoding [0, 1] float encoding value + * @return [0, 2⁶⁴ − 1] integer output value + */ +typedef uint64_t libgamma_gamma_ramps64_fun(float encoding); + +/** + * Mapping function from [0, 1] float encoding value to [0, 1] float output value + * + * @param encoding [0, 1] float encoding value + * @return [0, 1] float output value + */ +typedef float libgamma_gamma_rampsf_fun(float encoding); + +/** + * Mapping function from [0, 1] double precision float encoding + * value to [0, 1] double precision float output value + * + * @param encoding [0, 1] float encoding value + * @return [0, 1] float output value + */ +typedef double libgamma_gamma_rampsd_fun(double encoding); + + + /** * Return the capabilities of an adjustment method * @@ -354,5 +398,81 @@ int libgamma_crtc_set_gamma_rampsd(libgamma_crtc_state_t* restrict this, libgamma_gamma_rampsd_t ramps); +/** + * Set the gamma ramps for a CRTC, 16-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps_fun* red_function, + libgamma_gamma_ramps_fun* green_function, + libgamma_gamma_ramps_fun* blue_function); + +/** + * Set the gamma ramps for a CRTC, 32-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps32_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps32_fun* red_function, + libgamma_gamma_ramps32_fun* green_function, + libgamma_gamma_ramps32_fun* blue_function); + +/** + * Set the gamma ramps for a CRTC, 64-bit gamma-depth function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_ramps64_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_ramps64_fun* red_function, + libgamma_gamma_ramps64_fun* green_function, + libgamma_gamma_ramps64_fun* blue_function); + +/** + * Set the gamma ramps for a CRTC, `float` function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_rampsf_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_rampsf_fun* red_function, + libgamma_gamma_rampsf_fun* green_function, + libgamma_gamma_rampsf_fun* blue_function); + +/** + * Set the gamma ramps for a CRTC, `double` function version + * + * Note that this will probably involve the library allocating temporary data + * + * @param this The CRTC state + * @parma ramps The gamma ramps to apply + * @return Zero on success, otherwise (negative) the value of an + * error identifier provided by this library + */ +int libgamma_crtc_set_gamma_rampsd_f(libgamma_crtc_state_t* restrict this, + libgamma_gamma_rampsd_fun* red_function, + libgamma_gamma_rampsd_fun* green_function, + libgamma_gamma_rampsd_fun* blue_function); + + #endif diff --git a/src/libgamma-method.h b/src/libgamma-method.h index 1f54f62..8e953b3 100644 --- a/src/libgamma-method.h +++ b/src/libgamma-method.h @@ -148,10 +148,18 @@ typedef struct libgamma_method_capabilities { * Whether the adjustment method supports `libgamma_crtc_restore` */ int crtc_restore : 1; + + /** + * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size` + * fields in `libgamma_crtc_information_t` will always have the same + * values as each other for the adjustment method + */ + int identical_gamma_sizes : 1; /** - * Whether the `gamma_size` field in `libgamma_crtc_information_t` - * will always be filled with the same value for the adjustment method + * Whether the `red_gamma_size`, `green_gamma_size` and `blue_gamma_size` + * fields in `libgamma_crtc_information_t` will always be filled with the + * same value for the adjustment method */ int fixed_gamma_size : 1; @@ -324,7 +332,8 @@ typedef struct libgamma_crtc_state { /** * For a `libgamma_crtc_information_t` fill in the - * value for `gamma_size` and report errors to `gamma_size_error` + * values for `red_gamma_size`, `green_gamma_size` and `blue_gamma_size` + * and report errors to `gamma_size_error` */ #define CRTC_INFO_GAMMA_SIZE (1 << 5) @@ -477,9 +486,19 @@ typedef struct libgamma_crtc_information { /** - * The size of the encoding axes of gamma ramps + * The size of the encoding axis of the red gamma ramp + */ + size_t red_gamma_size; + + /** + * The size of the encoding axis of the green gamma ramp + */ + size_t green_gamma_size; + + /** + * The size of the encoding axis of the blue gamma ramp */ - size_t gamma_size; + size_t blue_gamma_size; /** * Zero on success, positive it holds the value `errno` had @@ -790,17 +809,17 @@ typedef struct libgamma_gamma_rampsd /** * The gamma ramp for the red channel */ - float* red; + double* red; /** * The gamma ramp for the green channel */ - float* green; + double* green; /** * The gamma ramp for the blue channel */ - float* blue; + double* blue; } libgamma_gamma_rampsd_t; -- cgit v1.2.3-70-g09d2