aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-01-21 22:37:18 +0100
committerMattias Andrée <maandree@kth.se>2023-01-21 22:37:18 +0100
commitada6f13d71a7b57a10717aca4d84f58cfefd5a14 (patch)
tree26ff19d1604bbc4b8b7a2471bb1b4d4a37571dd0
parentm (diff)
downloadlibglitter-ada6f13d71a7b57a10717aca4d84f58cfefd5a14.tar.gz
libglitter-ada6f13d71a7b57a10717aca4d84f58cfefd5a14.tar.bz2
libglitter-ada6f13d71a7b57a10717aca4d84f58cfefd5a14.tar.xz
Add libglitter_desaturate_{double,float}
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile3
-rw-r--r--TODO3
-rw-r--r--common.h1
-rw-r--r--config.mk2
-rw-r--r--libglitter.h38
-rw-r--r--libglitter_desaturate_double.c48
-rw-r--r--libglitter_desaturate_float.c6
7 files changed, 97 insertions, 4 deletions
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 <alloca.h>
+#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
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"