From ada6f13d71a7b57a10717aca4d84f58cfefd5a14 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Sat, 21 Jan 2023 22:37:18 +0100 Subject: Add libglitter_desaturate_{double,float} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 3 +++ TODO | 3 ++- common.h | 1 + config.mk | 2 +- libglitter.h | 38 +++++++++++++++++++++++++++++++-- libglitter_desaturate_double.c | 48 ++++++++++++++++++++++++++++++++++++++++++ libglitter_desaturate_float.c | 6 ++++++ 7 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 libglitter_desaturate_double.c create mode 100644 libglitter_desaturate_float.c diff --git a/Makefile b/Makefile index b0f2b07..e36b3fb 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ OBJ =\ libglitter_compose_uint32.o\ libglitter_compose_uint64.o\ libglitter_compose_uint8.o\ + libglitter_desaturate_double.o\ + libglitter_desaturate_float.o\ libglitter_create_render_context.o\ libglitter_free_render_context.o\ libglitter_update_render_context.o @@ -42,6 +44,7 @@ libglitter_compose_uint16.o: libglitter_compose_uint64.c libglitter_compose_doub libglitter_compose_uint32.o: libglitter_compose_uint64.c libglitter_compose_double.c libglitter_compose_uint64.o: libglitter_compose_double.c libglitter_compose_uint8.o: libglitter_compose_uint64.c libglitter_compose_double.c +libglitter_desaturate_float.o: libglitter_desaturate_double.c .c.o: $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) diff --git a/TODO b/TODO index 65602ac..743943b 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ -Add colour space conversion and saturation +Add colour space conversion +Add function to output primary chromas from an EDID Add support for GPU-acceleration Add man pages Add tests diff --git a/common.h b/common.h index b3a287b..6566fd0 100644 --- a/common.h +++ b/common.h @@ -4,6 +4,7 @@ #include "libglitter.h" #include +#include #include #include #include diff --git a/config.mk b/config.mk index 9b16e1d..64c9979 100644 --- a/config.mk +++ b/config.mk @@ -5,4 +5,4 @@ CC = cc CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE CFLAGS = -std=c99 -Wall -g -LDFLAGS = +LDFLAGS = -lm diff --git a/libglitter.h b/libglitter.h index 68a7b0e..0fc5888 100644 --- a/libglitter.h +++ b/libglitter.h @@ -70,7 +70,7 @@ void libglitter_free_render_context(LIBGLITTER_RENDER_CONTEXT *); * model's transfer function: it does not directly give * you appropriate sRGB values * - * @param outputs Array of output rasters, on for each subpixel colour. + * @param outputs Array of output rasters, one for each subpixel colour. * The function may change the offset for each raster, * as such, the given pointer shall not be used anywhere * else during the execution of the function and the @@ -105,7 +105,7 @@ void libglitter_compose_float(float **, const float *restrict, size_t, size_t, * model's transfer function: it does not directly give * you appropriate sRGB values * - * @param outputs Array of output rasters, on for each subpixel colour. + * @param outputs Array of output rasters, one for each subpixel colour. * The function may change the offset for each raster, * as such, the given pointer shall not be used anywhere * else during the execution of the function and the @@ -149,4 +149,38 @@ void libglitter_compose_uint8(uint8_t **, const uint8_t *restrict, size_t, size_ size_t, size_t, const LIBGLITTER_RENDER_CONTEXT *); +/** + * Transform rasters from fully using subpixel rendering to + * balance between subpixel rendering and greyscale antialiasing + * + * @param rasters Array of rasters, one for each subpixel colour. + * The function may change the offset for each raster, + * as such, the given pointer shall not be used anywhere + * else during the execution of the function and the + * inner pointers shall be considered undefined after + * the execution of the function + * @param nrasters The number of rasters + * @param rowsize The number of cells in a row in each raster + * @param cellsize The number of values stored in each raster, + * between each cell, plus 1 (that is, the number of + * values per cell) + * @param width The horizontal number of pixels in the rasters + * @param height The vertical number of pixels in the rasters + * @param saturation The subpixel rendering saturation, 1 for regular + * subpixel rendering, 0 for greyscale, values + * inbetween for a compromise + * @param primary_ys The CIE Y value (in e.g. CIE xyY or CIE XYZ) for + * each subpixel colour; or `NULL` for the sRGB values + * (this is only allowed if there are exactly 3 rasters) + */ +void libglitter_desaturate_double(double **, size_t, size_t, size_t, size_t, size_t, double, const double *); + +/** + * This value is identical to `libglitter_desaturate_double`, + * apart from it parameter types, see `libglitter_desaturate_double` + * for details about this function + */ +void libglitter_desaturate_float(float **, size_t, size_t, size_t, size_t, size_t, float, const float *); + + #endif diff --git a/libglitter_desaturate_double.c b/libglitter_desaturate_double.c new file mode 100644 index 0000000..62eaa3a --- /dev/null +++ b/libglitter_desaturate_double.c @@ -0,0 +1,48 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +#if defined(__GNUC__) && !defined(__clang__) +# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants" +#endif + + +void +libglitter_desaturate_double(double **rasters, size_t nrasters, size_t rowsize, size_t cellsize, + size_t width, size_t height, double saturation, const double *primary_ys) +{ + size_t y, x, ch, raster_y, raster_i; + double intensity; + + rowsize *= cellsize; + + if (nrasters == 3) { + double *raster1 = rasters[0]; + double *raster2 = rasters[1]; + double *raster3 = rasters[2]; + double primary1_y = primary_ys ? primary_ys[0] : (double)0.212673370378408277403536885686; + double primary2_y = primary_ys ? primary_ys[1] : (double)0.715151730491031756287156895269; + double primary3_y = primary_ys ? primary_ys[2] : (double)0.072174899130559869164791564344; + for (y = 0, raster_y = 0; y < height; y++, raster_y += rowsize) { + for (x = 0, raster_i = raster_y; x < width; x++, raster_i += cellsize) { + intensity = raster1[raster_i] * primary1_y; + intensity += raster2[raster_i] * primary2_y; + intensity += raster3[raster_i] * primary3_y; + raster1[raster_i] = fma(raster1[raster_i] - intensity, saturation, intensity); + raster2[raster_i] = fma(raster2[raster_i] - intensity, saturation, intensity); + raster3[raster_i] = fma(raster3[raster_i] - intensity, saturation, intensity); + } + } + + } else { + for (y = 0, raster_y = 0; y < height; y++, raster_y += rowsize) { + for (x = 0, raster_i = raster_y; x < width; x++, raster_i += cellsize) { + intensity = 0; + for (ch = 0; ch < nrasters; ch++) + intensity += rasters[ch][raster_i] * primary_ys[ch]; + for (ch = 0; ch < nrasters; ch++) + rasters[ch][raster_i] = fma(rasters[ch][raster_i] - intensity, saturation, intensity); + } + } + } +} diff --git a/libglitter_desaturate_float.c b/libglitter_desaturate_float.c new file mode 100644 index 0000000..54488a3 --- /dev/null +++ b/libglitter_desaturate_float.c @@ -0,0 +1,6 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#define libglitter_desaturate_double libglitter_desaturate_float +#define double float +#define fma fmaf +#include "libglitter_desaturate_double.c" -- cgit v1.2.3-70-g09d2