aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile17
-rw-r--r--README16
-rw-r--r--TODO1
-rw-r--r--libglitter.789
-rw-r--r--libglitter.h80
-rw-r--r--libglitter_colour_model_convert_rasters_double.3150
-rw-r--r--libglitter_colour_model_convert_rasters_double.c (renamed from libglitter_colour_space_convert_rasters_double.c)6
l---------libglitter_colour_model_convert_rasters_float.31
-rw-r--r--libglitter_colour_model_convert_rasters_float.c6
-rw-r--r--libglitter_colour_space_convert_rasters_float.c6
-rw-r--r--libglitter_compose_double.3150
l---------libglitter_compose_float.31
l---------libglitter_compose_uint16.31
l---------libglitter_compose_uint32.31
l---------libglitter_compose_uint64.31
l---------libglitter_compose_uint8.31
-rw-r--r--libglitter_create_render_context.3137
-rw-r--r--libglitter_desaturate_double.3141
l---------libglitter_desaturate_float.31
-rw-r--r--libglitter_enable_acceleration.3113
-rw-r--r--libglitter_enable_acceleration.c35
l---------libglitter_free_render_context.31
-rw-r--r--libglitter_get_colour_model_conversion_matrix_double.3124
-rw-r--r--libglitter_get_colour_model_conversion_matrix_double.c (renamed from libglitter_get_colour_space_conversion_matrix_double.c)17
l---------libglitter_get_colour_model_conversion_matrix_float.31
-rw-r--r--libglitter_get_colour_model_conversion_matrix_float.c (renamed from libglitter_get_colour_space_conversion_matrix_float.c)18
l---------libglitter_per_channel_desaturate_double.31
l---------libglitter_per_channel_desaturate_float.31
-rw-r--r--libglitter_reorder_rasters.376
l---------libglitter_split_uint32_raster.31
-rw-r--r--libglitter_split_uint64_raster.367
l---------libglitter_update_render_context.31
32 files changed, 1181 insertions, 81 deletions
diff --git a/Makefile b/Makefile
index d031557..b9c4d73 100644
--- a/Makefile
+++ b/Makefile
@@ -17,8 +17,8 @@ LIB_NAME = glitter
OBJ =\
- libglitter_colour_space_convert_rasters_double.o\
- libglitter_colour_space_convert_rasters_float.o\
+ libglitter_colour_model_convert_rasters_double.o\
+ libglitter_colour_model_convert_rasters_float.o\
libglitter_compose_double.o\
libglitter_compose_float.o\
libglitter_compose_uint16.o\
@@ -30,8 +30,8 @@ OBJ =\
libglitter_desaturate_float.o\
libglitter_create_render_context.o\
libglitter_free_render_context.o\
- libglitter_get_colour_space_conversion_matrix_double.o\
- libglitter_get_colour_space_conversion_matrix_float.o\
+ libglitter_get_colour_model_conversion_matrix_double.o\
+ libglitter_get_colour_model_conversion_matrix_float.o\
libglitter_per_channel_desaturate_double.o\
libglitter_per_channel_desaturate_float.o\
libglitter_reorder_rasters.o\
@@ -43,6 +43,9 @@ HDR =\
common.h\
libglitter.h
+MAN3 = $(OBJ:.o=.3)
+MAN7 = libglitter.7
+
LOBJ = $(OBJ:.o=.lo)
TESTS = $(OBJ:.o=.test)
@@ -89,6 +92,10 @@ install: libglitter.a libglitter.$(LIBEXT)
ln -sf -- libglitter.$(LIBMINOREXT) "$(DESTDIR)$(PREFIX)/lib/libglitter.$(LIBMAJOREXT)"
ln -sf -- libglitter.$(LIBMAJOREXT) "$(DESTDIR)$(PREFIX)/lib/libglitter.$(LIBEXT)"
cp -- libglitter.h "$(DESTDIR)$(PREFIX)/include/"
+ mkdir -- "$(DESTDIR)$(MANPREFIX)/man3"
+ mkdir -- "$(DESTDIR)$(MANPREFIX)/man7"
+ cp -P -- $(MAN3) "$(DESTDIR)$(MANPREFIX)/man3/"
+ cp -P -- $(MAN7) "$(DESTDIR)$(MANPREFIX)/man7/"
uninstall:
-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libglitter.a"
@@ -96,6 +103,8 @@ uninstall:
-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libglitter.$(LIBMINOREXT)"
-rm -f -- "$(DESTDIR)$(PREFIX)/lib/libglitter.$(LIBEXT)"
-rm -f -- "$(DESTDIR)$(PREFIX)/include/libglitter.h"
+ -cd -- "$(DESTDIR)$(MANPREFIX)/man3" && rm -f -- $(MAN3)
+ -cd -- "$(DESTDIR)$(MANPREFIX)/man7" && rm -f -- $(MAN7)
clean:
-rm -f -- *.o *.a *.lo *.su *.so *.so.* *.dll *.dylib *.test
diff --git a/README b/README
index 4cd5f25..f4996a7 100644
--- a/README
+++ b/README
@@ -39,15 +39,15 @@ DESCRIPTION
float(3).
Then, if the application cannot output directly to the
- output's colour space, the application can use
- libglitter_get_colour_space_conversion_matrix_double(3)
- and libglitter_colour_space_convert_rasters_double(3) or
- libglitter_get_colour_space_conversion_matrix_float(3)
- and libglitter_colour_space_convert_rasters_float(3) to
- convert a colour space the application can output in. It is
+ output's colour model, the application can use
+ libglitter_get_colour_model_conversion_matrix_double(3)
+ and libglitter_colour_model_convert_rasters_double(3) or
+ libglitter_get_colour_model_conversion_matrix_float(3)
+ and libglitter_colour_model_convert_rasters_float(3) to
+ convert a colour model the application can output in. It is
however out of the scope of libglitter to get the output's
- colour space and the conversion matrix to any other colour
- space than sRGB or CIE XYZ.
+ colour model and the conversion matrix to any other colour
+ model than sRGB or CIE XYZ.
The finally step of the rendering process is out of scope for
libglitter, but is to ensure that all floating-point values
diff --git a/TODO b/TODO
deleted file mode 100644
index 6c085d3..0000000
--- a/TODO
+++ /dev/null
@@ -1 +0,0 @@
-Add man pages
diff --git a/libglitter.7 b/libglitter.7
new file mode 100644
index 0000000..a446eeb
--- /dev/null
+++ b/libglitter.7
@@ -0,0 +1,89 @@
+.TH LIBGLITTER 7 LIBGLITTER
+.SH NAME
+libglitter - Subpixel-rendering library
+.SH DESCRIPTION
+.B libglitter
+is a C library for subpixel-rendered text from an
+greyscale-antialiased text image.
+.B libglitter
+is designed to be
+used in conjunction with other font libraries: it can neither
+rasterise glyphs nor does it know about the montor's subpixel
+layout or rendering configurations.
+.PP
+To use
+.B libglitter
+you first apply hinting to the text so that
+the glyph outlines aligns with the output's pixel-grid as
+closely as possible. The next step is to get the output's
+subpixel arrangement and scaling factor, then assuming that
+the output's subpixel arrangement is subpixel-rendering
+compatible and that its native resolution is used, you
+rasterise the text using greyscale-antialiasing into a raster
+sized according to the output's horizontal and vertical
+subpixel densities (rather than pixel densities as normally
+done with greyscale-antialiasing; some subpixels may have be
+counted multiple times depending on the subpixel arrangement).
+After this you create an uninitialised colour raster for text
+and the output's pixel density, and split it into one raster
+per colour channel using
+.BR libglitter_split_uint64_raster (3)
+or
+.BR libglitter_split_uint32_raster (3),
+this is when
+.B libglitter
+is first used in this process; alternatively you create one
+raster for each colour channel directly. Then you use
+.BR libglitter_compose_double (3),
+.BR libglitter_compose_float (3),
+.BR libglitter_compose_uint64 (3),
+.BR libglitter_compose_uint32 (3),
+.BR libglitter_compose_uint16 (3),
+or
+.BR libglitter_compose_uint8 (3)
+to create the subpixel-antialiased image of the text; you may
+have to first call
+.BR libglitter_reorder_rasters (3)
+to put the rasters in the expected order.
+.PP
+An optional next step is to use lessen the intensity of the
+subpixel-antialiasing with
+.BR libglitter_desaturate_double (3),
+.BR libglitter_desaturate_float (3),
+.BR libglitter_per_channel_desaturate_double (3),
+or
+.BR libglitter_per_channel_desaturate_float (3).
+.PP
+Then, if the application cannot output directly to the
+output's colour model, the application can use
+.BR libglitter_get_colour_model_conversion_matrix_double (3)
+and
+.BR libglitter_colour_model_convert_rasters_double (3)
+or
+.BR libglitter_get_colour_model_conversion_matrix_float (3)
+and
+.BR libglitter_colour_model_convert_rasters_float (3)
+to convert a colour model the application can output in. It is
+however out of the scope of
+.B libglitter
+to get the output's
+colour model and the conversion matrix to any other colour
+model than sRGB or CIE XYZ.
+.PP
+The finally step of the rendering process is out of scope for
+.BR libglitter ,
+but is to ensure that all floating-point values
+(if floating-point rasters are used) are withing [0, 1] and
+convert the rasters, which only contain ink-on intensities,
+into the desired colour's with the output's transfer function
+applied.
+.PP
+The application may also desire to call
+.BR libglitter_enable_acceleration (3)
+at the beginning of its execution to enable
+any implemented and supported hardware acceleration. This
+may however be an expensive process, and may not be
+desirable for all applications.
+.PP
+.SH SEE ALSO
+.BR libfonts (7)
diff --git a/libglitter.h b/libglitter.h
index 0bc65b1..9b2f30f 100644
--- a/libglitter.h
+++ b/libglitter.h
@@ -9,32 +9,32 @@
/**
* The application will use `double`-typed rasters
*/
-#define LIBGLITTER_FEATURE_DOUBLE_TYPE UINT64_C(0x0000000000000001)
+#define LIBGLITTER_FEATURE_DOUBLE_TYPE UINT64_C(0x0000000000000001)
/**
* The application will use `float`-typed rasters
*/
-#define LIBGLITTER_FEATURE_FLOAT_TYPE UINT64_C(0x0000000000000002)
+#define LIBGLITTER_FEATURE_FLOAT_TYPE UINT64_C(0x0000000000000002)
/**
* The application will use `uint64_t`-typed rasters
*/
-#define LIBGLITTER_FEATURE_UINT64_TYPE UINT64_C(0x0000000000000004)
+#define LIBGLITTER_FEATURE_UINT64_TYPE UINT64_C(0x0000000000000004)
/**
* The application will use `uint32_t`-typed rasters
*/
-#define LIBGLITTER_FEATURE_UINT32_TYPE UINT64_C(0x0000000000000008)
+#define LIBGLITTER_FEATURE_UINT32_TYPE UINT64_C(0x0000000000000008)
/**
* The application will use `uint16_t`-typed rasters
*/
-#define LIBGLITTER_FEATURE_UINT16_TYPE UINT64_C(0x0000000000000010)
+#define LIBGLITTER_FEATURE_UINT16_TYPE UINT64_C(0x0000000000000010)
/**
* The application will use `uint8_t`-typed rasters
*/
-#define LIBGLITTER_FEATURE_UINT8_TYPE UINT64_C(0x0000000000000020)
+#define LIBGLITTER_FEATURE_UINT8_TYPE UINT64_C(0x0000000000000020)
/**
* The allocation will use at least one of the functions
@@ -45,21 +45,28 @@
* `libglitter_compose_uint16`, and
* `libglitter_compose_uint8`
*/
-#define LIBGLITTER_FEATURE_COMPOSE UINT64_C(0x0000000000000040)
+#define LIBGLITTER_FEATURE_COMPOSE UINT64_C(0x0000000000000040)
/**
* The allocation will use at least one of the functions
* `libglitter_desaturate_double`, and
* `libglitter_desaturate_float`
*/
-#define LIBGLITTER_FEATURE_DESATURATION UINT64_C(0x0000000000000080)
+#define LIBGLITTER_FEATURE_CU_DESATURATION UINT64_C(0x0000000000000080) /* CU = channel-uniform */
/**
* The allocation will use at least one of the functions
- * `libglitter_colour_space_convert_rasters_double`, and
- * `libglitter_colour_space_convert_rasters_float`
+ * `libglitter_per_channel_desaturate_double`, and
+ * `libglitter_per_channel_desaturate_float`
*/
-#define LIBGLITTER_FEATURE_COLOUR_SPACE UINT64_C(0x0000000000000100)
+#define LIBGLITTER_FEATURE_PC_DESATURATION UINT64_C(0x0000000000000100) /* PC = per channel */
+
+/**
+ * The allocation will use at least one of the functions
+ * `libglitter_colour_model_convert_rasters_double`, and
+ * `libglitter_colour_model_convert_rasters_float`
+ */
+#define LIBGLITTER_FEATURE_COLOUR_MODEL UINT64_C(0x0000000000000200)
/**
@@ -116,8 +123,9 @@ enum libglitter_colour {
* - LIBGLITTER_FEATURE_UINT16_TYPE,
* - LIBGLITTER_FEATURE_UINT8_TYPE,
* - LIBGLITTER_FEATURE_COMPOSE,
- * - LIBGLITTER_FEATURE_DESATURATION, and
- * - LIBGLITTER_FEATURE_COLOUR_SPACE.
+ * - LIBGLITTER_FEATURE_CU_DESATURATION,
+ * - LIBGLITTER_FEATURE_PC_DESATURATION, and
+ * - LIBGLITTER_FEATURE_COLOUR_MODEL.
* @param async Whether the function shall return immediately
* rather than when complete
* @param callback Callback function that is called at function
@@ -130,11 +138,12 @@ enum libglitter_colour {
* also be `NULL` if no callback function shall be
* called
* @param userdata User-specific data to pass into `callback`, may be `NULL`
+ * @param unused Reserved for future use, shall be `NULL`
* @return 1 on success with hardware acceleration enabled,
* 0 on success without hardware acceleration enabled,
* or -1 on failure
*/
-int libglitter_enable_acceleration(uint64_t, int, void (*)(int, int, void *), void *);
+int libglitter_enable_acceleration(uint64_t, int, void (*)(int, int, void *), void *, void *);
/**
@@ -161,7 +170,8 @@ int libglitter_enable_acceleration(uint64_t, int, void (*)(int, int, void *), vo
*
* If `noutputs` is 3 and either `widthmul` or `heightmul` is 3 and
* the other one is 1, `ncellvalues` will not be used as it is preknown
- * that all its values are 1
+ * that all its values are 1; in the future this could also happen for
+ * other situations where `noutputs == widthmul * heightmul`
*/
LIBGLITTER_RENDER_CONTEXT *libglitter_create_render_context(size_t, size_t, size_t, size_t,
const uint8_t *, const uint8_t *);
@@ -400,13 +410,13 @@ void libglitter_per_channel_desaturate_float(float **, size_t, size_t, size_t, s
/**
* Get the matrix each pixel shall be multiplied with
- * to convert it from the output's colour space to sRGB
+ * to convert it from the output's colour model to sRGB
* or CIE XYZ
*
* This is useful when the output does not use sRGB, or
* CIE XYZ, but the application does. If the application
- * uses some other colour space, this function can output
- * the conversion matrix for the CIE XYZ colour space,
+ * uses some other colour model, this function can output
+ * the conversion matrix for the CIE XYZ colour model,
* which can that be right-hand multiplied to get the
* conversion matrix for some other colour; but be aware
* that the output matrix is in column-major order, not
@@ -423,25 +433,30 @@ void libglitter_per_channel_desaturate_float(float **, size_t, size_t, size_t, s
* @param white_y The CIE y value (as in CIE xyY) of the output's white point
* @param white_Y The CIE Y value (as in CIE xyY) of the output's white point, normally 1
* @param xyz Whether the output conversion matrix should be to CIE XYZ rather the sRGB
+ * @param c1Yp Output parameter for the first primary colour CIE Y value, or `NULL`
+ * @param c2Yp Output parameter for the second primary colour CIE Y value, or `NULL`
+ * @param c3Yp Output parameter for the third primary colour CIE Y value, or `NULL`
*
* `LIBGLITTER_ILLUMINANT_D65` can be input in place of
* `white_x, white_y, white_Y` (it expands to three arguments)
* if the output's whitepoint is the D65 illuminant
*/
-void libglitter_get_colour_space_conversion_matrix_double(double[3][3], double, double, double, double,
- double, double, double, double, double, int);
+void libglitter_get_colour_model_conversion_matrix_double(double[3][3], double, double, double, double,
+ double, double, double, double, double, int,
+ double *, double *, double *);
/**
- * This value is identical to `libglitter_get_colour_space_conversion_matrix_double`,
- * apart from it parameter types, see `libglitter_get_colour_space_conversion_matrix_double`
+ * This value is identical to `libglitter_get_colour_model_conversion_matrix_double`,
+ * apart from it parameter types, see `libglitter_get_colour_model_conversion_matrix_double`
* for details about this function
*/
-void libglitter_get_colour_space_conversion_matrix_float(float[3][3], float, float, float, float,
- float, float, float, float, float, int);
+void libglitter_get_colour_model_conversion_matrix_float(float[3][3], float, float, float, float,
+ float, float, float, float, float, int,
+ float *, float *, float *);
/**
- * Convert set of rasters from one colour space to another
+ * Convert set of rasters from one colour model to another
*
* @param n The number of input rasters
* @param m The number of output rasters
@@ -467,18 +482,19 @@ void libglitter_get_colour_space_conversion_matrix_float(float[3][3], float, flo
* values per cell)
* @param width The horizontal number of pixels in the rasters
* @param height The vertical number of pixels in the rasters
- * @param matrix Colour space conversion matrix, in column-major order
+ * @param matrix Colour model conversion matrix, in column-major order
*/
-void libglitter_colour_space_convert_rasters_double(size_t n, size_t m, double **, const double **, size_t,
- size_t, size_t, size_t, size_t, size_t, const double[n][m]);
+void libglitter_colour_model_convert_rasters_double(size_t n, size_t m, double **, const double **, size_t,
+ size_t, size_t, size_t, size_t, size_t, const double[m][n]);
/**
- * This value is identical to `libglitter_colour_space_convert_rasters_double`,
- * apart from it parameter types, see `libglitter_colour_space_convert_rasters_double`
+ * This value is identical to `libglitter_colour_model_convert_rasters_double`,
+ * apart from it parameter types, see `libglitter_colour_model_convert_rasters_double`
* for details about this function
*/
-void libglitter_colour_space_convert_rasters_float(size_t n, size_t m, float **, const float **, size_t,
- size_t, size_t, size_t, size_t, size_t, const float[n][m]);
+void libglitter_colour_model_convert_rasters_float(size_t n, size_t m, float **, const float **, size_t,
+ size_t, size_t, size_t, size_t, size_t, const float[m][n]);
#endif
+/* TODO add `restrict` where appropriate */
diff --git a/libglitter_colour_model_convert_rasters_double.3 b/libglitter_colour_model_convert_rasters_double.3
new file mode 100644
index 0000000..329b638
--- /dev/null
+++ b/libglitter_colour_model_convert_rasters_double.3
@@ -0,0 +1,150 @@
+.TH LIBGLITTER_COLOUR_MODEL_CONVERT_RASTERS_* 3 LIBGLITTER
+.SH NAME
+LIBGLITTER_COLOUR_MODEL_CONVERT_RASTERS_* - Change colour model used for a set of corasters
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_colour_model_convert_rasters_double(size_t \fIn\fP, size_t \fIm\fP, double *\fIoutputs\fP[m],
+ const double *\fIinputs\fP[n], size_t \fIoutput_rowsize\fP,
+ size_t \fIoutput_cellsize\fP, size_t \fIinput_rowsize\fP,
+ size_t \fIinput_cellsize\fP, size_t \fIwidth\fP,
+ size_t \fIheight\fP, const double \fImatrix\fP[m][n]);
+
+void libglitter_colour_model_convert_rasters_float(size_t \fIn\fP, size_t \fIm\fP, float *\fIoutputs\fP[m],
+ const float *\fIinputs\fP[n], size_t \fIoutput_rowsize\fP,
+ size_t \fIoutput_cellsize\fP, size_t \fIinput_rowsize\fP,
+ size_t \fIinput_cellsize\fP, size_t \fIwidth\fP,
+ size_t \fIheight\fP, const float \fImatrix\fP[m][n]);
+.fi
+.PP
+Link with
+.IR "-lglitter -lm" .
+.SH DESCRIPTION
+The
+.BR libglitter_colour_model_convert_rasters_double ()
+and
+.BR libglitter_colour_model_convert_rasters_float ()
+functions convert a set of rasters (one per source
+colour channel) into another set of rasters (one per
+target colour channel) using a different colour model.
+This is useful for application that cannot output
+directly in the output's colour model.
+.PP
+.I n
+shall be the number of source colour channels
+(input rasters), and
+.I m
+shall be the number of target colour channels
+(output rasters).
+.PP
+.I outputs
+shall be the list of output rasters: it is to its elements
+that the function will write. Note that the rasters shall
+already be allocated. Additionally, the function may offset
+the input pointers in this list during execution. Therefore,
+the contents of this list shall be considered undefined
+immediately when the function is called, and may not be
+modified before the function terminates. The application
+must therefore have the pointers to these rasters saved
+elsewhere. The order the rasters shall have in the list
+.I outputs
+is determined how the colour model conversion matrix
+.RI ( matrix )
+was constructed: if it was created using the
+.BR libglitter_colour_model_convert_rasters_double (3),
+function, or the
+.BR libglitter_colour_model_convert_rasters_float (3),
+function, the order shall be (0) red, (1) green, (2) blue
+or (0) X, (1) Y, (2) Z.
+.PP
+.I inputs
+shall be the list of input rasters: it is from its elements
+that the function will read. The function may offset the
+input pointers in this list during execution. Therefore,
+the contents of this list shall be considered undefined
+immediately when the function is called, and may not be
+modified before the function terminates. The application
+must therefore have the pointers to these rasters saved
+elsewhere. The order the rasters shall have in the list
+.I inputs
+is determined how the colour model conversion matrix
+.RI ( matrix )
+was constructed: if it was created using the
+.BR libglitter_colour_model_convert_rasters_double (3),
+function, or the
+.BR libglitter_colour_model_convert_rasters_float (3),
+function, the order shall the order the output's primary
+colours' chromas hade in the function's argument list.
+.PP
+.I output_cellsize
+shall be the number of elements in an output raster the
+pointer to the raster must be offset with to get to a
+pointer to the next cell in the raster.
+.PP
+.I output_rowsize
+shall be the number of cells (not elements; but rather the
+number of elements divided by
+.IR output_cellsize )
+in an output raster the pointer to the raster must be
+offset with to get a pointer to the next row but the
+same column in the raster
+.PP
+.I input_cellsize
+shall be the number of elements in an input raster the
+pointer to the raster must be offset with to get to a
+pointer to the next cell in the raster.
+.PP
+.I input_rowsize
+shall be the number of cells (not elements; but rather the
+number of elements divided by
+.IR input_cellsize )
+in an input raster the pointer to the raster must be
+offset with to get a pointer to the next row but the
+same column in the raster
+.PP
+.I width
+and
+.I height
+shall describe the affected area in the rasters.
+.I width
+shall be the number of pixels the rasters have
+horizontally, and
+.I height
+shall be the number of pixels the rasters have
+vertically.
+.PP
+.I matrix
+shall be column-major conversion matrix from the source
+colour model (the output's colour model) to the target
+colour model (the application's colour model).
+.PP
+All rasters are in row-major order and must be distinct.
+.PP
+By default, these functions do not use hardware acceleration,
+they run on the CPU. However the
+.BR libglitter_enable_acceleration (3)
+may be able to enable hardware acceleration for these
+functions. It will require at least the following bits in
+its first argument to enable hardware acceleration:
+.RS
+.TP
+.I LIBGLITTER_FEATURE_COLOUR_MODEL | LIBGLITTER_FEATURE_DOUBLE_TYPE
+for
+.BR libglitter_colour_model_convert_rasters_double ()
+or
+.TP
+.I LIBGLITTER_FEATURE_COLOUR_MODEL | LIBGLITTER_FEATURE_FLOAT_TYPE
+for
+.BR libglitter_colour_model_convert_rasters_float ().
+.RE
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_colour_model_convert_rasters_double (3),
+.BR libglitter_compose_double (3),
+.BR libglitter_desaturate_double (3)
diff --git a/libglitter_colour_space_convert_rasters_double.c b/libglitter_colour_model_convert_rasters_double.c
index 8fa497e..143cd4e 100644
--- a/libglitter_colour_space_convert_rasters_double.c
+++ b/libglitter_colour_model_convert_rasters_double.c
@@ -30,7 +30,7 @@ multiply_nn(size_t n, double **outputs, size_t opos, const double **inputs, size
static void
multiply_nm(size_t n, size_t m, double **outputs /* m */, size_t opos, const double **inputs /* n */,
- size_t ipos, const double matrix[n][m], double buffer[n])
+ size_t ipos, const double matrix[m][n], double buffer[n])
{
size_t i, j;
for (j = 0; j < n; j++)
@@ -44,9 +44,9 @@ multiply_nm(size_t n, size_t m, double **outputs /* m */, size_t opos, const dou
void
-libglitter_colour_space_convert_rasters_double(size_t n, size_t m, double **outputs /* m */, const double **inputs /* n */,
+libglitter_colour_model_convert_rasters_double(size_t n, size_t m, double **outputs /* m */, const double **inputs /* n */,
size_t output_rowsize, size_t output_cellsize, size_t input_rowsize,
- size_t input_cellsize, size_t width, size_t height, const double matrix[n][m])
+ size_t input_cellsize, size_t width, size_t height, const double matrix[m][n])
{
size_t y, x, output_i, input_i, output_blanking, input_blanking;
double *buffer;
diff --git a/libglitter_colour_model_convert_rasters_float.3 b/libglitter_colour_model_convert_rasters_float.3
new file mode 120000
index 0000000..f8e36a0
--- /dev/null
+++ b/libglitter_colour_model_convert_rasters_float.3
@@ -0,0 +1 @@
+libglitter_colour_model_convert_rasters_double.3 \ No newline at end of file
diff --git a/libglitter_colour_model_convert_rasters_float.c b/libglitter_colour_model_convert_rasters_float.c
new file mode 100644
index 0000000..f12322f
--- /dev/null
+++ b/libglitter_colour_model_convert_rasters_float.c
@@ -0,0 +1,6 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#define libglitter_colour_model_convert_rasters_double libglitter_colour_model_convert_rasters_float
+#define double float
+#define fma fmaf
+#include "libglitter_colour_model_convert_rasters_double.c"
diff --git a/libglitter_colour_space_convert_rasters_float.c b/libglitter_colour_space_convert_rasters_float.c
deleted file mode 100644
index c77835a..0000000
--- a/libglitter_colour_space_convert_rasters_float.c
+++ /dev/null
@@ -1,6 +0,0 @@
-/* See LICENSE file for copyright and license details. */
-#include "common.h"
-#define libglitter_colour_space_convert_rasters_double libglitter_colour_space_convert_rasters_float
-#define double float
-#define fma fmaf
-#include "libglitter_colour_space_convert_rasters_double.c"
diff --git a/libglitter_compose_double.3 b/libglitter_compose_double.3
new file mode 100644
index 0000000..36bbf02
--- /dev/null
+++ b/libglitter_compose_double.3
@@ -0,0 +1,150 @@
+.TH LIBGLITTER_COMPOSE_* 3 LIBGLITTER
+.SH NAME
+libglitter_compose_* - Convert a subpixel-resolution raster to multiple pixel-resolution rasters
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_compose_double(double **\fIoutputs\fP, const double *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+
+void libglitter_compose_float(float **\fIoutputs\fP, const float *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+
+void libglitter_compose_uint64(uint64_t **\fIoutputs\fP, const uint64_t *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+
+void libglitter_compose_uint32(uint32_t **\fIoutputs\fP, const uint32_t *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+
+void libglitter_compose_uint16(uint16_t **\fIoutputs\fP, const uint16_t *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+
+void libglitter_compose_uint8(uint8_t **\fIoutputs\fP, const uint8_t *\fIinput\fP,
+ size_t \fIoutput_rowsize\fP, size_t \fIoutput_cellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const LIBGLITTER_RENDER_CONTEXT *\fIrender_ctx\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter" .
+.SH DESCRIPTION
+The
+.BR libglitter_compose_double (),
+.BR libglitter_compose_float (),
+.BR libglitter_compose_uint64 (),
+.BR libglitter_compose_uint32 (),
+.BR libglitter_compose_uint16 (),
+and
+.BR libglitter_compose_uint8 (),
+functions convert, based on input used to create the
+.I render_ctx
+argument (the
+.BR libglitter_create_render_context (3)
+function is used to create
+.IR render_ctx ),
+a raster (input to the function via the
+.I input
+parameter) with a text rendered with greyscale antialiasing
+on subpixel resolution (rather than pixel resolution) into
+a set of rasters with pixel resolution: one raster per colour
+channel.
+.PP
+.I outputs
+shall be the list of output rasters: it is to its elements
+that the function will write. Note that the rasters shall
+already be allocated. Additionally, the function may offset
+the input pointers in this list during execution. Therefore,
+the contents of this list shall be considered undefined
+immediately when the function is called, and may not be
+modified before the function terminates. The application
+must therefore have the pointers to these rasters saved
+elsewhere. The order the rasters shall have in the list
+.I outputs
+is determined when creating
+.IR render_ctx .
+.PP
+.I output_cellsize
+shall be the number of elements in an output raster the
+pointer to the raster must be offset with to get to a
+pointer to the next cell in the raster.
+.PP
+.I output_rowsize
+shall be the number of cells (not elements; but rather
+the number of elements divided by
+.IR output_cellsize )
+in an output raster the pointer to the raster must be
+offset with to get a pointer to the next row but the
+same column in the raster
+.PP
+.I width
+and
+.I height
+shall describe the affected area in the output rasters.
+.I width
+shall be the number of pixels the rasters have
+horizontally, and
+.I height
+shall be the number of pixels the rasters have
+vertically. It shall not be the number of subpixels
+in the input rasters, but rather the number of pixels,
+which is easiest to think of in terms of the size of
+the output rasters (minus any unused area, however
+the pointers must point to the first used pixel).
+.PP
+All rasters are in row-major order.
+.PP
+By default, these functions do not use hardware acceleration,
+they run on the CPU. However the
+.BR libglitter_enable_acceleration (3)
+may be able to enable hardware acceleration for these
+functions. It will require at least the following bits in
+its first argument to enable hardware acceleration:
+.RS
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_DOUBLE_TYPE
+for
+.BR libglitter_compose_double (),
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_FLOAT_TYPE
+for
+.BR libglitter_compose_float (),
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_UINT64_TYPE
+for
+.BR libglitter_compose_uint64 (),
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_UINT32_TYPE
+for
+.BR libglitter_compose_uint32 (),
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_UINT16_TYPE
+for
+.BR libglitter_compose_uint16 (),
+or
+.TP
+.I LIBGLITTER_FEATURE_COMPOSE | LIBGLITTER_FEATURE_UINT8_TYPE
+for
+.BR libglitter_compose_uint8 ().
+.RE
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_colour_model_convert_rasters_double (3),
+.BR libglitter_desaturate_double (3),
+.BR libglitter_reorder_rasters (3),
+.BR libglitter_split_uint64_raster (3)
diff --git a/libglitter_compose_float.3 b/libglitter_compose_float.3
new file mode 120000
index 0000000..869c46a
--- /dev/null
+++ b/libglitter_compose_float.3
@@ -0,0 +1 @@
+libglitter_compose_double.3 \ No newline at end of file
diff --git a/libglitter_compose_uint16.3 b/libglitter_compose_uint16.3
new file mode 120000
index 0000000..869c46a
--- /dev/null
+++ b/libglitter_compose_uint16.3
@@ -0,0 +1 @@
+libglitter_compose_double.3 \ No newline at end of file
diff --git a/libglitter_compose_uint32.3 b/libglitter_compose_uint32.3
new file mode 120000
index 0000000..869c46a
--- /dev/null
+++ b/libglitter_compose_uint32.3
@@ -0,0 +1 @@
+libglitter_compose_double.3 \ No newline at end of file
diff --git a/libglitter_compose_uint64.3 b/libglitter_compose_uint64.3
new file mode 120000
index 0000000..869c46a
--- /dev/null
+++ b/libglitter_compose_uint64.3
@@ -0,0 +1 @@
+libglitter_compose_double.3 \ No newline at end of file
diff --git a/libglitter_compose_uint8.3 b/libglitter_compose_uint8.3
new file mode 120000
index 0000000..869c46a
--- /dev/null
+++ b/libglitter_compose_uint8.3
@@ -0,0 +1 @@
+libglitter_compose_double.3 \ No newline at end of file
diff --git a/libglitter_create_render_context.3 b/libglitter_create_render_context.3
new file mode 100644
index 0000000..574ccf6
--- /dev/null
+++ b/libglitter_create_render_context.3
@@ -0,0 +1,137 @@
+.TH LIBGLITTER_*_RENDER_CONTEXT 3 LIBGLITTER
+.SH NAME
+libglitter_create_render_context - Precompute data for libglitter_compose_*(3)
+.br
+libglitter_update_render_context - Precompute data for updated information for libglitter_compose_*(3)
+.br
+libglitter_free_render_context - Deallocate precompute data for libglitter_compose_*(3)
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+LIBGLITTER_RENDER_CONTEXT *
+libglitter_create_render_context(size_t \fInoutputs\fP, size_t \fIrowsize\fP,
+ size_t \fIwidthmul\fP, size_t \fIheightmul\fP,
+ const uint8_t *\fIcellmap\fP,
+ const uint8_t *\fIncellvalues\fP);
+
+void libglitter_update_render_context(LIBGLITTER_RENDER_CONTEXT *\fIthis\fP, size_t \fIrowsize\fP);
+
+void libglitter_free_render_context(LIBGLITTER_RENDER_CONTEXT *\fIthis\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter" .
+.SH DESCRIPTION
+The
+.BR libglitter_create_render_context ()
+function precalculates information required for the
+.BR libglitter_compose_double (3)
+function and similar functions.
+.PP
+The
+.I noutputs
+argument shall be the number of rasters the
+.BR libglitter_compose_double (3)
+function and similar functions, output to; that is,
+the number of primary colours of the output (normally
+three: red, green, and blue).
+.PP
+The
+.I rowsize
+argument shall the number of cells the input raster
+has per row. It required that the input raster's
+cells are contigious for each row, meaning that
+moving one element over moves one cell over, so
+there is not cell size parameter. If the input
+raster is modified to have a different number of
+cellss per row, the returned object must be updated
+using the
+.BR libglitter_update_render_context ()
+function.
+.PP
+The
+.I widthmul
+argument shall be the number of cells the input
+raster has in the horizontal dimension per pixel.
+For the standard horizontally stacked vertical
+stripes for red, green, and blue, this value is
+three. A cell is not necessarily a subpixel, in
+some layouts, some subpixels occupy multiple cells.
+.PP
+The
+.I heighmul
+argument shall be the number of cells the input
+raster has in the vertical dimension per pixel.
+For the standard horizontally stacked vertical
+stripes for red, green, and blue, this value is
+one.
+.PP
+The
+.I cellmap
+argument shall be a list of size
+.IR (heightmul*widthmul) ,
+more specifically, it shall be a row-major matrix
+of height
+.I heightmul
+and width
+.IR widthmul .
+Its elements shall be values in [0,
+.IR noutputs ),
+specifying which subpixel occupies each cell
+for any pixel in the input raster.
+.PP
+Any pointer output by the
+.BR libglitter_create_render_context ()
+function can, and (unless it is the null pointer)
+should be, deallocated using the
+.BR libglitter_free_render_context ()
+function.
+.PP
+For any value
+.I i
+in [0,
+.IR noutputs ),
+.I ncellvalues[i]
+shall be the number of times the value
+.I i
+appears in
+.IR cellmap .
+.RE
+.SH RETURN VALUES
+The
+.BR libglitter_create_render_context ()
+function returns, upon successful completion,
+a pointer to newly allocated memory. On failure,
+it returns
+.IR NULL .
+.PP
+The
+.BR libglitter_update_render_context ()
+and
+.BR libglitter_free_render_context ()
+functions do not return any value.
+.SH ERRORS
+The
+.BR libglitter_create_render_context ()
+can fail with the following errors:
+.TP
+.B ENOMEM
+Could not allocate enough memory.
+.PP
+The
+.BR libglitter_update_render_context ()
+and
+.BR libglitter_free_render_context ()
+functions cannot fail.
+.SH NOTES
+In some (common) cases, the library infer the
+values stored in
+.I ncellvalues
+rather than read
+.IR ncellvalues .
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_compose_double (3),
+.BR libglitter_reorder_rasters (3)
diff --git a/libglitter_desaturate_double.3 b/libglitter_desaturate_double.3
new file mode 100644
index 0000000..057efb7
--- /dev/null
+++ b/libglitter_desaturate_double.3
@@ -0,0 +1,141 @@
+.TH LIBGLITTER_*DESATURATE_* 3 LIBGLITTER
+.SH NAME
+libglitter_*desature_* - Create a blend between subpixel- and greyscale-antialiasing
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_desaturate_double(double **\fIrasters\fP, size_t \fInrasters\fP,
+ size_t \fIrowsize\fP, size_t \fIcellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ double \fIsaturation\fP,
+ const double *\fIprimary_ys\fP);
+
+void libglitter_desaturate_float(float **\fIrasters\fP, size_t \fInrasters\fP,
+ size_t \fIrowsize\fP, size_t \fIcellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ float \fIsaturation\fP,
+ const float *\fIprimary_ys\fP);
+
+void libglitter_per_channel_desaturate_double(double **\fIrasters\fP, size_t \fInrasters\fP,
+ size_t \fIrowsize\fP, size_t \fIcellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const double \fIsaturations\fP,
+ const double *\fIprimary_ys\fP);
+
+void libglitter_per_channel_desaturate_float(float **\fIrasters\fP, size_t \fInrasters\fP,
+ size_t \fIrowsize\fP, size_t \fIcellsize\fP,
+ size_t \fIwidth\fP, size_t \fIheight\fP,
+ const float \fIsaturations\fP,
+ const float *\fIprimary_ys\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter -lm" .
+.SH DESCRIPTION
+The
+.BR libglitter_desaturate_double (),
+.BR libglitter_desaturate_float (),
+.BR libglitter_per_channel_desaturate_double (),
+and
+.BR libglitter_per_channel_desaturate_float (),
+functions desaturates a set of corasters (makes them more grey).
+.PP
+.I rasters
+shall be the list of rasters, which are modified in place.
+The function may offset the input pointers in this list
+during execution. Therefore, the contents of this list shall
+be considered undefined immediately when the function is
+called, and may not be modified before the function terminates.
+The application must therefore have the pointers to these
+rasters saved elsewhere.
+.PP
+The number of rasters shall be specified as the
+.I nrasters
+argument.
+.PP
+.I cellsize
+shall be the number of elements in a raster the pointer
+to the raster must be offset with to get to a pointer to
+the next cell in the raster.
+.PP
+.I rowsize
+shall be the number of cells (not elements; but rather the
+number of elements divided by
+.IR input_cellsize )
+in a raster the pointer to the raster must be offset with
+to get a pointer to the next row but the same column in
+the raster
+.PP
+.I width
+and
+.I height
+shall describe the affected area in the rasters.
+.I width
+shall be the number of pixels the rasters have
+horizontally, and
+.I height
+shall be the number of pixels the rasters have
+vertically.
+.PP
+For the
+.BR libglitter_desaturate_double ()
+and
+.BR libglitter_desaturate_float ()
+functions, the
+.I saturation
+argument shall be how saturated the subpixel-antialiasing shall
+be, where 0 renders greyscale-antialiasing and 1 renders regular
+subpixel-antialiasing. For the
+.BR libglitter_per_channel_desaturate_double ()
+and
+.BR libglitter_per_channel_desaturate_float ()
+functions this parameter is replaced with the
+.I saturations
+parameter which shall be a list of one saturation value per
+raster: these functions let the user desaturate each channel
+by a different amount.
+.PP
+Each primary colour's CIE Y value shall be provided via the
+.I primary_ys
+parameter. If you only have the output's primary colours'
+chroma as CIE xy values, and the output's white point, the
+.BR libglitter_get_colour_model_conversion_matrix_double (3)
+and
+.BR libglitter_get_colour_model_conversion_matrix_float (3)
+can calculate and output the primary colour's CIE Y values.
+.PP
+By default, these functions do not use hardware acceleration,
+they run on the CPU. However the
+.BR libglitter_enable_acceleration (3)
+may be able to enable hardware acceleration for these
+functions. It will require at least the following bits in
+its first argument to enable hardware acceleration:
+.RS
+.TP
+.I LIBGLITTER_FEATURE_CU_DESATURATION | LIBGLITTER_FEATURE_DOUBLE_TYPE
+for
+.BR libglitter_desaturate_double (),
+.TP
+.I LIBGLITTER_FEATURE_CU_DESATURATION | LIBGLITTER_FEATURE_FLOAT_TYPE
+for
+.BR libglitter_desaturate_float (),
+.TP
+.I LIBGLITTER_FEATURE_PC_DESATURATION | LIBGLITTER_FEATURE_DOUBLE_TYPE
+for
+.BR libglitter_per_channel_desaturate_double (),
+or
+.TP
+.I LIBGLITTER_FEATURE_PC_DESATURATION | LIBGLITTER_FEATURE_FLOAT_TYPE
+for
+.BR libglitter_per_channel_desaturate_float ().
+.RE
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_colour_model_convert_rasters_double (3),
+.BR libglitter_compose_double (3)
diff --git a/libglitter_desaturate_float.3 b/libglitter_desaturate_float.3
new file mode 120000
index 0000000..28942e9
--- /dev/null
+++ b/libglitter_desaturate_float.3
@@ -0,0 +1 @@
+libglitter_desaturate_double.3 \ No newline at end of file
diff --git a/libglitter_enable_acceleration.3 b/libglitter_enable_acceleration.3
new file mode 100644
index 0000000..3f3f833
--- /dev/null
+++ b/libglitter_enable_acceleration.3
@@ -0,0 +1,113 @@
+.TH LIBGLITTER_ENABLE_ACCELERATION 3 LIBGLITTER
+.SH NAME
+libglitter_enable_acceleration - Enable hardware acceleration
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+int libglitter_enable_acceleration(uint64_t \fIfeatures\fP, int \fIasync\fP,
+ void (*\fIcallback\fP)(int, int, void *),
+ void *\fIuserdata\fP, void *\fIunused\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter" .
+.SH DESCRIPTION
+The
+.BR libglitter_enable_acceleration ()
+function is planned to in the future enable hardware
+acceleration. Because it can be expansive to enable hardware
+acceleration (such as compiling code for the acceleration
+hardware (normally a graphics card)), and depending on the
+use case, it could also be too expensive to issue commands
+to the acceleration hardware, (1) hardware acceleration
+is not enabled by default, and (2) it can be enabled
+asynchronous, meaning that the applications can use the
+CPU implementations of the libraries functions at the
+beginning of its runtime and enable hardware acceleration
+in the background, and once it has been enabled, the
+library will shift over to using the hardware acceleration.
+.PP
+The
+.I features
+parameter is used to specify which functions to enable
+hardware acceleration for. Recognised values are documented
+separately, in the documentation for the affected functions.
+Any unsupported bit, or combination, is silently ignored.
+.PP
+To enable hardware acceleration asynchronously, specify a
+non-zero value as the
+.I async
+argument. To enable hardware acceleration synchronously
+(meaning that the function does not return until either
+hardware acceleration has been enabled or failed to be
+enabled), specify zero as the
+.I async
+argument.
+.PP
+Unless
+.I callback
+is
+.IR NULL ,
+the function will call
+.I *callback
+immedately before it or the thread it spawns terminates.
+The first argument will be set to the value the function
+would return if
+.I async
+was 0, and the second argument will be set to the value
+the function will set
+.I errno
+to if
+.I async
+was 0 (note that the function call still set
+.I errno
+if it returns a negative value even if
+.I async
+is not 0). The third argument will be
+.IR userdata .
+.PP
+The
+.I userdata
+argument not used except for being passed into
+.IR *callback .
+.PP
+The
+.I unused
+parameter is reserved for future use,
+.I NULL
+must be specified at the moment.
+.SH RETURN VALUES
+The
+.BR libglitter_enable_acceleration ()
+function returns the value 1 if it completes successfully
+with hardware acceleration enabled, the value 0 if it
+completes successfully without hardware acceleration enabled
+(this is what will usually happen if
+.I async
+is set to a non-zero value, but another value may still be
+provided as the first argument to
+.IR *callback ),
+and a negative value on failure. The value -1 is reserved
+for when the function sets
+.I errno
+to specify the error. Other negative values may be used
+in the future to specify errors that do not have a good
+.I errno
+value.
+.SH ERRORS
+Currently none.
+.SH FUTURE DIRECTIONS
+The
+.BR libglitter_enable_acceleration ()
+function, once properly implemented, will require additional
+linking flags, including (probably)
+.I -pthread
+(for asynchronous operation) and linking to libraries needed
+to use hardware acceleration.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_colour_model_convert_rasters_double (3),
+.BR libglitter_compose_double (3),
+.BR libglitter_desaturate_double (3)
diff --git a/libglitter_enable_acceleration.c b/libglitter_enable_acceleration.c
index 791fe71..5539116 100644
--- a/libglitter_enable_acceleration.c
+++ b/libglitter_enable_acceleration.c
@@ -4,10 +4,11 @@
int
-libglitter_enable_acceleration(uint64_t features, int async, void (*callback)(int r, int e, void *u), void *userdata)
+libglitter_enable_acceleration(uint64_t features, int async, void (*callback)(int r, int e, void *u), void *userdata, void *unused)
{
(void) features;
(void) async;
+ (void) unused;
/* TODO add support for hardware acceleration */
@@ -45,30 +46,30 @@ int
main(void)
{
char data = 'u';
- ASSERT(!libglitter_enable_acceleration(0, 0, NULL, NULL));
- ASSERT(!libglitter_enable_acceleration(0, 1, NULL, NULL));
- ASSERT(!libglitter_enable_acceleration(~0, 0, NULL, NULL));
- ASSERT(!libglitter_enable_acceleration(~0, 1, NULL, NULL));
- ASSERT(!libglitter_enable_acceleration(0, 0, NULL, &data));
- ASSERT(!libglitter_enable_acceleration(0, 1, NULL, &data));
- ASSERT(!libglitter_enable_acceleration(~0, 0, NULL, &data));
- ASSERT(!libglitter_enable_acceleration(~0, 1, NULL, &data));
+ ASSERT(!libglitter_enable_acceleration(0, 0, NULL, NULL, NULL));
+ ASSERT(!libglitter_enable_acceleration(0, 1, NULL, NULL, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 0, NULL, NULL, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 1, NULL, NULL, NULL));
+ ASSERT(!libglitter_enable_acceleration(0, 0, NULL, &data, NULL));
+ ASSERT(!libglitter_enable_acceleration(0, 1, NULL, &data, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 0, NULL, &data, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 1, NULL, &data, NULL));
ASSERT(callback_calls == 0);
- ASSERT(!libglitter_enable_acceleration(0, 0, callback, &data));
+ ASSERT(!libglitter_enable_acceleration(0, 0, callback, &data, NULL));
ASSERT(callback_calls == 1);
- ASSERT(!libglitter_enable_acceleration(0, 1, callback, &data));
+ ASSERT(!libglitter_enable_acceleration(0, 1, callback, &data, NULL));
ASSERT(callback_calls == 2);
- ASSERT(!libglitter_enable_acceleration(~0, 0, callback, &data));
+ ASSERT(!libglitter_enable_acceleration(~0, 0, callback, &data, NULL));
ASSERT(callback_calls == 3);
- ASSERT(!libglitter_enable_acceleration(~0, 1, callback, &data));
+ ASSERT(!libglitter_enable_acceleration(~0, 1, callback, &data, NULL));
ASSERT(callback_calls == 4);
- ASSERT(!libglitter_enable_acceleration(0, 0, callback_null, NULL));
+ ASSERT(!libglitter_enable_acceleration(0, 0, callback_null, NULL, NULL));
ASSERT(callback_calls == 5);
- ASSERT(!libglitter_enable_acceleration(0, 1, callback_null, NULL));
+ ASSERT(!libglitter_enable_acceleration(0, 1, callback_null, NULL, NULL));
ASSERT(callback_calls == 6);
- ASSERT(!libglitter_enable_acceleration(~0, 0, callback_null, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 0, callback_null, NULL, NULL));
ASSERT(callback_calls == 7);
- ASSERT(!libglitter_enable_acceleration(~0, 1, callback_null, NULL));
+ ASSERT(!libglitter_enable_acceleration(~0, 1, callback_null, NULL, NULL));
ASSERT(callback_calls == 8);
return 0;
}
diff --git a/libglitter_free_render_context.3 b/libglitter_free_render_context.3
new file mode 120000
index 0000000..63bb093
--- /dev/null
+++ b/libglitter_free_render_context.3
@@ -0,0 +1 @@
+libglitter_create_render_context.3 \ No newline at end of file
diff --git a/libglitter_get_colour_model_conversion_matrix_double.3 b/libglitter_get_colour_model_conversion_matrix_double.3
new file mode 100644
index 0000000..adf06e5
--- /dev/null
+++ b/libglitter_get_colour_model_conversion_matrix_double.3
@@ -0,0 +1,124 @@
+.TH LIBGLITTER_GET_COLOUR_MODEL_CONVERSION_MATRIX_* 3 LIBGLITTER
+.SH NAME
+libglitter_get_colour_model_conversion_matrix_* - Create a column-major colour model conversion matrix
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_get_colour_model_conversion_matrix_double(double \fImatrix\fP[3][3],
+ double \fIc1x\fP, double \fIc1y\fP,
+ double \fIc2x\fP, double \fIc2y\fP,
+ double \fIc3x\fP, double \fIc3y\fP,
+ double \fIwhite_x\fP, double \fIwhite_y\fP,
+ double \fIwhite_Y\fP, int \fIxyz\fP,
+ double *\fIc1Yp\fP, double *\fIc2Yp\fP,
+ double *\fIc3Yp\fP);
+
+void libglitter_get_colour_model_conversion_matrix_float(float \fImatrix\fP[3][3],
+ float \fIc1x\fP, float \fIc1y\fP,
+ float \fIc2x\fP, float \fIc2y\fP,
+ float \fIc3x\fP, float \fIc3y\fP,
+ float \fIwhite_x\fP, float \fIwhite_y\fP,
+ float \fIwhite_Y\fP, int \fIxyz\fP,
+ float *\fIc1Yp\fP, float *\fIc2Yp\fP,
+ float *\fIc3Yp\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter -lm" .
+.SH DESCRIPTION
+The
+.BR libglitter_get_colour_model_conversion_matrix_double ()
+and
+.BR libglitter_get_colour_model_conversion_matrix_float ()
+functions calculate the CIE XYZ values for an output's
+primary colours from there chromas expressed as CIE xy
+values (CIE xyY sans Y) and the output's whitepoint's
+CIE xyY values. It is assumed that the output uses additive
+colour mixing and that the blackpoint is perfect black.
+After calculating the primary colours' CIE XYZ values,
+the functions either output, to
+.I matrix
+a column-major conversion matrix from the output's colour
+model to CIE XYZ (if
+.I xyz
+is non-zero) or a column-major conversion matrix from the
+output's colour model to [0, 1]-normalised sRGB (otherwise).
+.PP
+The x and y values of the output's first primary colour
+shall be input as the
+.I c1x
+and
+.I c1y
+arguments, the second primary colour's values as
+.I c2x
+and
+.I c2y
+and the third primary colour's values as
+.I c3x
+and
+.IR c3y .
+.PP
+.IR white_x ,
+.IR white_y ,
+and
+.IR white_Y
+shall be the output's whitepoint's CIE xyY values
+(x, y, and Y respectively).
+.I white_Y
+is normally 1, and if it is, and if the whitepoint is
+also the D65 illuminant (which it usually is), the macro
+.I LIBGLITTER_ILLUMINANT_D65
+can be used to specify these three arguments (it expands
+into three arguments):
+.RS
+.nf
+
+void libglitter_get_colour_model_conversion_matrix_double(double \fImatrix\fP[3][3],
+ double \fIc1x\fP, double \fIc1y\fP,
+ double \fIc2x\fP, double \fIc2y\fP,
+ double \fIc3x\fP, double \fIc3y\fP,
+ LIBGLITTER_ILLUMINANT_D65,
+ int \fIxyz\fP, double *\fIc1Yp\fP,
+ double *\fIc2Yp\fP, double *\fIc3Yp\fP);
+
+void libglitter_get_colour_model_conversion_matrix_float(float \fImatrix\fP[3][3],
+ float \fIc1x\fP, float \fIc1y\fP,
+ float \fIc2x\fP, float \fIc2y\fP,
+ float \fIc3x\fP, float \fIc3y\fP,
+ LIBGLITTER_ILLUMINANT_D65,
+ int \fIxyz\fP, float *\fIc1Yp\fP,
+ float *\fIc2Yp\fP, float *\fIc3Yp\fP);
+.fi
+.RE
+.PP
+Unless
+.I c1Yp
+is
+.IR NULL ,
+.I *c1Yp
+is set to the first primary colour's CIE Y value.
+Likewise, unless
+.I c2Yp
+is
+.IR NULL ,
+.I *c2Yp
+is set to the second primary colour's CIE Y value,
+and unless
+.I c3Yp
+is
+.IR NULL ,
+.I *c3Yp
+is set to the third primary colour's CIE Y value,
+.PP
+The output's three primary colours not form a straight
+line: they must render a three dimensional colour space.
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_colour_model_convert_rasters_double (3),
+.BR libglitter_desaturate_double (3)
diff --git a/libglitter_get_colour_space_conversion_matrix_double.c b/libglitter_get_colour_model_conversion_matrix_double.c
index 285f625..eb8a87d 100644
--- a/libglitter_get_colour_space_conversion_matrix_double.c
+++ b/libglitter_get_colour_model_conversion_matrix_double.c
@@ -29,7 +29,7 @@ static const double srgb[3][3] = {
static void
-invert(double m[3][4]) /* row-major order */
+eliminate(double m[3][4]) /* row-major order */
{
double t;
size_t i;
@@ -49,16 +49,17 @@ invert(double m[3][4]) /* row-major order */
void
-libglitter_get_colour_space_conversion_matrix_double(double matrix[3][3], double c1x, double c1y,
+libglitter_get_colour_model_conversion_matrix_double(double matrix[3][3], double c1x, double c1y,
double c2x, double c2y, double c3x, double c3y,
- double white_x, double white_y, double white_Y, int xyz)
+ double white_x, double white_y, double white_Y,
+ int xyz, double *c1Yp, double *c2Yp, double *c3Yp)
{
double mat[3][4];
double x1, x2, x3;
double y1, y2, y3;
double z1, z2, z3;
- /* Get colour space in CIE XYZ (the matrix is in row-major order) */
+ /* Get colour model in CIE XYZ (the matrix is in row-major order) */
mat[0][0] = x1 = X(c1x, c1y);
mat[0][1] = x2 = X(c2x, c2y);
mat[0][2] = x3 = X(c3x, c3y);
@@ -71,10 +72,16 @@ libglitter_get_colour_space_conversion_matrix_double(double matrix[3][3], double
mat[2][1] = z2 = Z(c2x, c2y);
mat[2][2] = z3 = Z(c3x, c3y);
mat[2][3] = Z(white_x, white_y) * white_Y;
- invert(mat);
+ eliminate(mat);
y1 = mat[0][3];
y2 = mat[1][3];
y3 = mat[2][3];
+ if (c1Yp)
+ *c1Yp = y1;
+ if (c2Yp)
+ *c2Yp = y2;
+ if (c3Yp)
+ *c3Yp = y3;
/* [x1, x2, x3; y1, y2, y3; z1, z2, z3] is
* the output RGB-to-CIE XYZ conversion matrix.
diff --git a/libglitter_get_colour_model_conversion_matrix_float.3 b/libglitter_get_colour_model_conversion_matrix_float.3
new file mode 120000
index 0000000..eeab8a0
--- /dev/null
+++ b/libglitter_get_colour_model_conversion_matrix_float.3
@@ -0,0 +1 @@
+libglitter_get_colour_model_conversion_matrix_double.3 \ No newline at end of file
diff --git a/libglitter_get_colour_space_conversion_matrix_float.c b/libglitter_get_colour_model_conversion_matrix_float.c
index 6f71baf..771151d 100644
--- a/libglitter_get_colour_space_conversion_matrix_float.c
+++ b/libglitter_get_colour_model_conversion_matrix_float.c
@@ -4,16 +4,18 @@
void
-libglitter_get_colour_space_conversion_matrix_float(float matrix[3][3], float c1x, float c1y,
+libglitter_get_colour_model_conversion_matrix_float(float matrix[3][3], float c1x, float c1y,
float c2x, float c2y, float c3x, float c3y,
- float white_x, float white_y, float white_Y, int xyz)
+ float white_x, float white_y, float white_Y,
+ int xyz, float *c1Yp, float *c2Yp, float *c3Yp)
{
- double double_matrix[3][3];
- libglitter_get_colour_space_conversion_matrix_double(double_matrix,
+ double double_matrix[3][3], c1Y, c2Y, c3Y;
+ libglitter_get_colour_model_conversion_matrix_double(double_matrix,
(double)c1x, (double)c1y,
(double)c2x, (double)c2y,
(double)c3x, (double)c3y,
- (double)white_x, (double)white_y, (double)white_Y, xyz);
+ (double)white_x, (double)white_y, (double)white_Y,
+ xyz, &c1Y, &c2Y, &c3Y);
matrix[0][0] = (float)double_matrix[0][0];
matrix[0][1] = (float)double_matrix[0][1];
matrix[0][2] = (float)double_matrix[0][2];
@@ -23,6 +25,12 @@ libglitter_get_colour_space_conversion_matrix_float(float matrix[3][3], float c1
matrix[2][0] = (float)double_matrix[2][0];
matrix[2][1] = (float)double_matrix[2][1];
matrix[2][2] = (float)double_matrix[2][2];
+ if (c1Yp)
+ *c1Yp = (float)c1Y;
+ if (c2Yp)
+ *c2Yp = (float)c2Y;
+ if (c3Yp)
+ *c3Yp = (float)c3Y;
}
diff --git a/libglitter_per_channel_desaturate_double.3 b/libglitter_per_channel_desaturate_double.3
new file mode 120000
index 0000000..28942e9
--- /dev/null
+++ b/libglitter_per_channel_desaturate_double.3
@@ -0,0 +1 @@
+libglitter_desaturate_double.3 \ No newline at end of file
diff --git a/libglitter_per_channel_desaturate_float.3 b/libglitter_per_channel_desaturate_float.3
new file mode 120000
index 0000000..703044f
--- /dev/null
+++ b/libglitter_per_channel_desaturate_float.3
@@ -0,0 +1 @@
+libglitter_per_channel_desaturate_double.3 \ No newline at end of file
diff --git a/libglitter_reorder_rasters.3 b/libglitter_reorder_rasters.3
new file mode 100644
index 0000000..03aaf92
--- /dev/null
+++ b/libglitter_reorder_rasters.3
@@ -0,0 +1,76 @@
+.TH LIBGLITTER_REORDER_RASTERS 3 LIBGLITTER
+.SH NAME
+libglitter_reorder_rasters - Reorder rasters from the application's order to the physical order
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_reorder_rasters(void **\fIrasters\fP,
+ enum libglitter_colour \fIcolour1\fP,
+ enum libglitter_colour \fIcolour2\fP,
+ enum libglitter_colour \fIcolour3\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter" .
+.SH DESCRIPTION
+The
+.BR libglitter_reorder_rasters (),
+function reorders a set of three rasters to the
+order desired by the
+.BR libglitter_compose_double (3)
+function and similar functions.
+.PP
+The
+.I rasters
+argument shall be a list of three rasters, in
+the order (0) red, (1) green, (2) blue. During
+the execution of the function, the function
+will reorder the elements in this list. So that
+it matches the order expected by the
+.BR libglitter_compose_double (3)
+function and similar functions, which is
+determined the mean in the values in the
+.I cellmap
+argument input to the
+.BR libglitter_create_render_context (3)
+function. These meaning of these values is
+specified via the
+.IR colour1 ,
+.IR colour2 ,
+and
+.I colour3
+parameters. The
+.IR colour1
+argument shall specify colour of subpixel
+whose index is 0
+.IR cellmap ,
+likewise the
+.IR colour2
+argument shall specify colour of subpixel
+whose index is 1
+.IR cellmap ,
+and the
+.IR colour3
+argument shall specify colour of subpixel
+whose index is 2.
+.PP
+Exactly one of
+.IR colour1 ,
+.IR colour2 ,
+and
+.I colour3
+shall be
+.IR LIBGLITTER_CHANNEL_RED ,
+exactly one shall be
+.IR LIBGLITTER_CHANNEL_GREEN ,
+and exactly one shall be
+.IR LIBGLITTER_CHANNEL_BLUE .
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_split_uint64_raster (3)
diff --git a/libglitter_split_uint32_raster.3 b/libglitter_split_uint32_raster.3
new file mode 120000
index 0000000..1dfe00f
--- /dev/null
+++ b/libglitter_split_uint32_raster.3
@@ -0,0 +1 @@
+libglitter_split_uint64_raster.3 \ No newline at end of file
diff --git a/libglitter_split_uint64_raster.3 b/libglitter_split_uint64_raster.3
new file mode 100644
index 0000000..001b279
--- /dev/null
+++ b/libglitter_split_uint64_raster.3
@@ -0,0 +1,67 @@
+.TH LIBGLITTER_SPLIT_*_RASTER 3 LIBGLITTER
+.SH NAME
+libglitter_split_*_raster - Split an integer raster into mutliple rasters with narrower integers
+.SH SYNOPSIS
+.LP
+.nf
+#include <libglitter.h>
+
+void libglitter_split_uint64_raster(uint16_t *\fIrasters\fP[3], uint16_t **\fIalphap\fP, uint64_t *\fIraster\fP,
+ uint64_t \fIred\fP, uint64_t \fIgreen\fP, uint64_t \fIblue\fP);
+
+void libglitter_split_uint32_raster(uint8_t *\fIrasters\fP[3], uint8_t **\fIalphap\fP, uint32_t *\fIraster\fP,
+ uint32_t \fIred\fP, uint32_t \fIgreen\fP, uint32_t \fIblue\fP);
+.fi
+.PP
+Link with
+.IR "-lglitter" .
+.SH DESCRIPTION
+The
+.BR libglitter_split_uint64_raster ()
+and
+.BR libglitter_split_uint32_raster ()
+functions split the colour raster input in to the
+.I raster
+parameter into four intensity rasters, and output
+the raster for the red channel to
+.IR rasters[0] ,
+the raster for the green channel to
+.IR rasters[1] ,
+and the raster for the blue channel to
+.IR rasters[2] ,
+and unless
+.I alphap
+is null, it also outputs the alpha raster to
+.IR *alphap .
+.PP
+For the
+.BR libglitter_split_uint64_raster ()
+function,
+.I red
+shall be the value
+.I 0xFFFF
+shifted to make out a colour that is pure
+primary red,
+.I green
+shall be the value
+.I 0xFFFF
+shifted to make out a colour that is pure
+primary green, and
+.I blue
+shall be the value
+.I 0xFFFF
+shifted to make out a colour that is pure
+primary blue.
+For the
+.BR libglitter_split_uint32_raster ()
+function, the value
+.I 0xFF
+is used rather than
+.IR 0xFFFF .
+.SH RETURN VALUES
+None.
+.SH ERRORS
+None.
+.SH SEE ALSO
+.BR libglitter (7),
+.BR libglitter_reorder_rasters (3)
diff --git a/libglitter_update_render_context.3 b/libglitter_update_render_context.3
new file mode 120000
index 0000000..63bb093
--- /dev/null
+++ b/libglitter_update_render_context.3
@@ -0,0 +1 @@
+libglitter_create_render_context.3 \ No newline at end of file