aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO10
-rw-r--r--doc/info/chap/clut-manipulation.texinfo4
-rw-r--r--doc/info/chap/colour-spaces.texinfo351
-rw-r--r--doc/info/chap/overview.texinfo4
-rw-r--r--src/libclut.c34
5 files changed, 373 insertions, 30 deletions
diff --git a/TODO b/TODO
deleted file mode 100644
index 121ac9d..0000000
--- a/TODO
+++ /dev/null
@@ -1,10 +0,0 @@
-The sRGB gamut expressed in CIE xyY:
-
- Chromaticity Red Green Blue White point
- x 0.6400 0.3000 0.1500 0.31271
- y 0.3300 0.6000 0.0600 0.32902
- Y 0.212656 0.715158 0.072186 1.0000
-
-A function is needed that given the values (sans Y) of a
-monitor's gamut, converts from sRGB to the monitor's RGB.
-An inverse function of this is also needed.
diff --git a/doc/info/chap/clut-manipulation.texinfo b/doc/info/chap/clut-manipulation.texinfo
index 477e107..99fc0f0 100644
--- a/doc/info/chap/clut-manipulation.texinfo
+++ b/doc/info/chap/clut-manipulation.texinfo
@@ -10,8 +10,8 @@ colour lookup table that shall be manipulated.
Pointer to the gamma ramps. This must be a pointer
to an instance of a @code{struct} that must at least
have the array members @code{red}, @code{green}, and
-@code{blue}, whose elements shall be of the time
-specified by the parameter @code{type}. The struct
+@code{blue}, whose elements shall be of the type
+specified by the parameter @code{type}. The @code{struct}
must also have the scalar members @code{red_size},
@code{green_size}, and @code{blue_size}, and shall be
of the type @code{size_t}; they shall specify the
diff --git a/doc/info/chap/colour-spaces.texinfo b/doc/info/chap/colour-spaces.texinfo
index 86662c6..7b9d751 100644
--- a/doc/info/chap/colour-spaces.texinfo
+++ b/doc/info/chap/colour-spaces.texinfo
@@ -1,6 +1,11 @@
@node Colour Spaces
@chapter Colour Spaces
+@menu
+* RGB Conversion:: RGB colour space conversion functions.
+@end menu
+
+
@command{libclut} has a number of functions for converting
between colour space models. The supported colour space models
are [0, 1] sRGB, [0, 1] linear RGB, CIE xyY, CIE XYZ, and CIE Lab.
@@ -245,3 +250,349 @@ Output parameter for the Z parameter.
@end table
@end table
+
+@node RGB Conversion
+@section RGB Conversion
+
+@command{libclut} provides a functions for converting
+RGB values between RGB colour spaces. An RGB colour space
+is described using @code{struct libclut_rgb_colour_space}
+(also known as @code{libclut_rgb_colour_space_t}). It
+describes the colour of the red, green, and blue,
+stimuli as well as the white point, in CIE xyY. It does
+however not describe the colour space's gamma function,
+because sRGB uses a irregular gamma function, and
+ECI@tie{}RGB@tie{}v2 uses L*. The structure contains
+the following @code{double}:s:
+
+@table @code
+@item red_x
+The CIE xyY x-value of the red stimulus.
+@item red_y
+The CIE xyY y-value of the red stimulus.
+@item red_Y
+The CIE xyY Y-value of the red stimulus.
+@item green_x
+The CIE xyY x-value of the green stimulus.
+@item green_y
+The CIE xyY y-value of the green stimulus.
+@item green_Y
+The CIE xyY Y-value of the green stimulus.
+@item blue_x
+The CIE xyY x-value of the blue stimulus.
+@item blue_y
+The CIE xyY y-value of the blue stimulus.
+@item blue_Y
+The CIE xyY Y-value of the blue stimulus.
+@item white_x
+The CIE xyY x-value of the white point.
+@item white_y
+The CIE xyY y-value of the white point.
+@item white_Y
+The CIE xyY Y-value of the white point.
+@end table
+
+@code{libclut} provides macros used to initialise a
+@code{struct libclut_rgb_colour_space} with values
+for a number of RGB colour spaces. These are listed
+below, along with the gamma each colour space uses.
+
+@multitable {PAL/SECAM RGB} {@b{Gamma}} {@code{LIBCLUT_RGB_COLOUR_SPACE_WIDE_GAMUT_RGB_INITIALISER}}
+@item
+@b{Model}
+@tab
+@b{Gamma}
+@tab
+@b{Initialiser}
+@item
+sRGB
+@tab
+sRGB
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_SRGB_INITIALISER}
+@item
+Adobe RGB (1998)
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_ADOBE_RGB_INITIALISER}
+@item
+Apple RGB
+@tab
+1.8
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_APPLE_RGB_INITIALISER}
+@item
+Best RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_BEST_RGB_INITIALISER}
+@item
+Beta RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_BETA_RGB_INITIALISER}
+@item
+Bruce RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_BRUCE_RGB_INITIALISER}
+@item
+CIE RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_CIE_RGB_INITIALISER}
+@item
+ColorMatch RGB
+@tab
+1.8
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_COLORMATCH_RGB_INITIALISER}
+@item
+Don RGB 4
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_DON_RGB_4_INITIALISER}
+@item
+ECI RGB v2
+@tab
+L*
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_ECI_RGB_V2_INITIALISER}
+@item
+Ekta Space PS5
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_EKTA_SPACE_PS5_INITIALISER}
+@item
+NTSC RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_NTSC_RGB_INITIALISER}
+@item
+PAL/SECAM RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_PAL_SECAM_RGB_INITIALISER}
+@item
+ProPhoto RGB
+@tab
+1.8
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_PROPHOTO_RGB_INITIALISER}
+@item
+SMPTE-C RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_SMPTE_C_RGB_INITIALISER}
+@item
+Wide Gamut RGB
+@tab
+2.2
+@tab
+@code{LIBCLUT_RGB_COLOUR_SPACE_WIDE_GAMUT_RGB_INITIALISER}
+@end multitable
+
+To create a description for the sRGB colour space write:
+
+@example
+struct libclut_rgb_colour_space srgb = \
+ LIBCLUT_RGB_COLOUR_SPACE_SRGB_INITIALISER;
+@end example
+
+@command{libgamma} and @command{libcoopgamma} can be used
+to get the x and y values of the user's monitors' red,
+green, and blue stimuli. Otherwise, all values specified
+by @code{LIBCLUT_RGB_COLOUR_SPACE_SRGB_INITIALISER} can
+be used, and the sRGB gamma function can be used. However,
+the Y values of the stimuli may be off, however, this does
+not affect conversion.
+
+sRGB uses an irregular gamma function. @command{libclut}
+assumes that the colour spaces uses this gamma function
+when converting between RGB colour spaces. If you want to
+convert from a colour space with another gamma function,
+you must first convert the gamma function. This can be
+done by linearising the values and then use
+@code{libclut_model_linear_to_standard1},
+@code{libclut_model_linear_to_standard}, or
+@code{libclut_standardise}. If you want to convert to a
+colour spce with another gamma function, you must after
+the conversion also convert the gamma function. This can
+be done by using @code{libclut_model_standard_to_linear1},
+@code{libclut_model_standard_to_linear}, or
+@code{libclut_linearise}, and then converting from linear
+to the proper gamma function. Note that even if you are
+converting between two colour spaces with the same gamma
+function, gamma function conversion must be done (before
+and after) unless they use the sRGB gamma function.
+
+Before RGB colour space conversion can be done, you need
+to create a conversion matrix. It has the type
+
+@example
+typedef double libclut_colour_space_conversion_matrix_t[3][3];
+@end example
+
+@noindent
+and can be created with
+@table @code
+@item int libclut_model_get_rgb_conversion_matrix(*from, *to, M, Minv)
+Create a conversion matrix from one RGB colour space to another
+RGB colour space, and optionally a matrix for an inverse conversion.
+
+Returns 0 on success, and -1 on error. The only possible error is
+@code{EINVAL}, which indicates that there is something wrong with
+the colour spaces and a conversion matrix cannot be created.
+
+This function is not available as a macro, thus, linking with
+@code{-lclut} is required.
+
+Parameters:
+@table @code
+@item const libclut_rgb_colour_space_t* from
+Description of the input colour space.
+@item const libclut_rgb_colour_space_t* to
+Description of the output colour space.
+@item libclut_colour_space_conversion_matrix_t M
+Matrix to fill with values so it can be used for
+converting from the input colour space to the
+output colour space.
+@item libclut_colour_space_conversion_matrix_t Minv
+Matrix to fill with values so it can be used for
+converting from the output colour space to the
+input colour space. (That is, inverse conversion.)
+This parameter may be @code{NULL}.
+@end table
+@end table
+
+You can also create the matrix manually. If you for example
+have a @code{libclut_colour_space_conversion_matrix_t} named
+@code{M}, and want to set the cell at row 1 and column 3, to
+0.5, you make the assignment @code{M[0][2] = 0.5}.
+
+Once you have your conversion matrix, @command{libclut} has
+three macro functions you can used to convert colours between
+RGB colour space. Remember that they require the sRGB gamma
+function.
+
+@table @code
+@item libclut_model_convert_rgb(r, g, b, M, *out_r, *out_g, *out_b)
+Convert a single RGB colour into another RGB colour space.
+The colour space must have same gamma functions as RGB.
+
+This macro is also available a function. If the function is
+used, linking with @code{-lclut} is required, otherwise,
+linking with @code{-lm} is required, or @code{-lclut} if
+@code{libclut_model_standard_to_linear1} or
+@code{libclut_model_linear_to_standard1} is undefined.
+
+Parameters:
+@table @code
+@item double r
+The red value of the colour to convert.
+@item double g
+The green value of the colour to convert.
+@item double b
+The blue value of the colour to convert.
+@item libclut_colour_space_conversion_matrix_t M
+The conversion matrix.
+@item double* out_r
+Output parameter for the red value of the colour after conversion.
+@item double* out_g
+Output parameter for the green value of the colour after conversion.
+@item double* out_b
+Output parameter for the blue value of the colour after conversion.
+@end table
+
+@item libclut_convert_rgb_inplace(clut, max, type, m, trunc)
+Convert the curves between two RGB colour spaces.
+
+The red, green, and blue ramps must be of the same size.
+
+None of the parameter may have side-effects.
+
+Requires linking with @code{-lm}, or @code{-lclut} if
+@code{libclut_model_standard_to_linear1},
+@code{libclut_model_linear_to_standard1}, or
+@code{libclut_model_convert_rgb} is undefined.
+
+Parameters:
+@table @code
+@item clut
+Pointer to the gamma ramps to convert. This must be a pointer to
+an instance of a struct that must at least have the array members
+@code{red}, @code{green}, and @code{blue}, whose elements shall be
+of the type specified by the parameter @code{type}. The @code{struct}
+must also have the scalar members @code{red_size}, @code{green_size},
+and @code{blue_size}, and shall be of the type @code{size_t}; they
+shall specify the number of stops (elements) in the arrays @code{.red},
+@code{.green}, and @code{.blue}, respectively, which shall be the
+gamma ramp for the red, green, and blue channels respectively. Its
+values will be modified to the new values.
+@item max
+The maximum value on each stop in the ramps.
+@item type
+The data type used for each stop in the ramps.
+@item libclut_colour_space_conversion_matrix_t m
+Conversion matrix.
+@item int trunc
+If this is a non-zero value, resulting colours that are
+out of gamut are truncated. (Not necessarily the best
+approximation.)
+@end table
+
+@item libclut_convert_rgb(clut, max, type, m, trunc, out)
+Convert the curves between two RGB colour spaces.
+
+This is a slower version of @code{libclut_convert_rgb_inplace}
+that supports clut:s where the red, green, and blue ramps
+are not of the same size.
+
+None of the parameter may have side-effects.
+
+Requires linking with @code{-lm}. If
+@code{libclut_model_linear_to_standard1},
+@code{libclut_model_standard_to_linear1}, or
+@code{libclut_model_convert_rgb} has been undefined,
+linking with @code{-lclut} is also required.
+
+Parameters:
+@table @code
+@item clut
+Pointer to the gamma ramps to convert. This must be a pointer to
+an instance of a struct that must at least have the array members
+@code{red}, @code{green}, and @code{blue}, whose elements shall be
+of the type specified by the parameter @code{type}. The @code{struct}
+must also have the scalar members @code{red_size}, @code{green_size},
+and @code{blue_size}, and shall be of the type @code{size_t}; they
+shall specify the number of stops (elements) in the arrays @code{.red},
+@code{.green}, and @code{.blue}, respectively, which shall be the
+gamma ramp for the red, green, and blue channels respectively. Its
+values are not modified.
+@item max
+The maximum value on each stop in the ramps.
+@item type
+The data type used for each stop in the ramps.
+@item libclut_colour_space_conversion_matrix_t m
+Conversion matrix.
+@item int trunc
+If this is a non-zero value, resulting colours that are
+out of gamut are truncated. (Not necessarily the best
+approximation.)
+@item clut
+Pointer to the gamma ramps of the output values. Shall be of
+the same data type as @code{clut}. And have the same values on
+@code{.red_size}, @code{.green_size}, and @code{.blue_size} as
+@code{clut}.
+@end table
+@end table
diff --git a/doc/info/chap/overview.texinfo b/doc/info/chap/overview.texinfo
index b2234bf..65a2b76 100644
--- a/doc/info/chap/overview.texinfo
+++ b/doc/info/chap/overview.texinfo
@@ -7,7 +7,7 @@ the header @file{<libclut.h>}. Some functionality also
requires that the objects be linked with @option{-lclut}.
@command{libclut} is designed to work well with
-@command{libgamma} @command{libcoopgamma}, but does not
-require that either is used for any of its
+@command{libgamma} and @command{libcoopgamma}, but does
+not require that either is used for any of its
[@command{libclut}'s] functionality.
diff --git a/src/libclut.c b/src/libclut.c
index aea585e..c783e31 100644
--- a/src/libclut.c
+++ b/src/libclut.c
@@ -241,10 +241,10 @@ static void subrow(double a1[3], double a2[3], double b1[3], double b2[3], doubl
* @param A The inversion of M (as input).
* @return 1 on success, 0 if the matrix is not invertible.
*/
-static int invert(libclut_colourspace_conversion_matrix_t M, libclut_colourspace_conversion_matrix_t A)
+static int invert(libclut_colour_space_conversion_matrix_t M, libclut_colour_space_conversion_matrix_t A)
{
int r0 = 0, r1 = 1, r2 = 2, t, swapped = 0;
- libclut_colourspace_conversion_matrix_t T;
+ libclut_colour_space_conversion_matrix_t T;
A[0][0] = A[1][1] = A[2][2] = 1;
A[0][1] = A[0][2] = A[1][0] = A[1][2] = A[2][0] = A[2][1] = 0;
@@ -306,9 +306,9 @@ static int invert(libclut_colourspace_conversion_matrix_t M, libclut_colourspace
* @param M The output matrix.
* @return Zero on success, -1 on error.
*
- * @throws EINVAL The colourspace cannot be used.
+ * @throws EINVAL The colour space cannot be used.
*/
-static int get_conversion_matrix(const libclut_rgb_colourspace_t* cs, libclut_colourspace_conversion_matrix_t M)
+static int get_conversion_matrix(const libclut_rgb_colour_space_t* cs, libclut_colour_space_conversion_matrix_t M)
{
#define XYY_TO_XYZ(x, y, Y, Xp, Yp, Zp) \
(libclut_0__(Y)) ? \
@@ -318,7 +318,7 @@ static int get_conversion_matrix(const libclut_rgb_colourspace_t* cs, libclut_co
*(Zp) = (1 - (x) - (y)) * (Y) / (y))
double Xr, Yr, Zr, Xg, Yg, Zg, Xb, Yb, Zb, Xw, Yw, Zw, Sr, Sg, Sb;
- libclut_colourspace_conversion_matrix_t M2;
+ libclut_colour_space_conversion_matrix_t M2;
XYY_TO_XYZ(cs->red_x, cs->red_y, 1, &Xr, &Yr, &Zr);
XYY_TO_XYZ(cs->green_x, cs->green_y, 1, &Xg, &Yg, &Zg);
@@ -348,22 +348,22 @@ static int get_conversion_matrix(const libclut_rgb_colourspace_t* cs, libclut_co
/**
* Create a matrix for converting values between
- * two RGB colourspaces.
+ * two RGB colour spaces.
*
- * @param from The input colourspace, the Y-component is only necessary for the whitepoint.
- * @param to The output colourspace, the Y-component is only necessary for the whitepoint.
+ * @param from The input colour space, the Y-component is only necessary for the whitepoint.
+ * @param to The output colour space, the Y-component is only necessary for the whitepoint.
* @param M Output matrix for conversion from `from` to `to`.
* @param Minv Output matrix for conversion from `to` to `from`, may be `NULL`.
* @return Zero on success, -1 on error.
*
- * @throws EINVAL The colourspace cannot be used.
+ * @throws EINVAL The colour space cannot be used.
*/
-int libclut_model_get_rgb_conversion_matrix(const libclut_rgb_colourspace_t* from,
- const libclut_rgb_colourspace_t* to,
- libclut_colourspace_conversion_matrix_t M,
- libclut_colourspace_conversion_matrix_t Minv)
+int libclut_model_get_rgb_conversion_matrix(const libclut_rgb_colour_space_t* from,
+ const libclut_rgb_colour_space_t* to,
+ libclut_colour_space_conversion_matrix_t M,
+ libclut_colour_space_conversion_matrix_t Minv)
{
- libclut_colourspace_conversion_matrix_t A, B;
+ libclut_colour_space_conversion_matrix_t A, B;
if (get_conversion_matrix(from, A))
return -1;
@@ -396,9 +396,11 @@ int libclut_model_get_rgb_conversion_matrix(const libclut_rgb_colourspace_t* fro
/**
- * Convert an RGB colour into another RGB colourspace.
+ * Convert an RGB colour into another RGB colour space.
* None of the parameter may have side-effects.
*
+ * Both RGB colour space must have same gamma functions as RGB.
+ *
* @param r The red component of the colour to convert.
* @param g The green component of the colour to convert.
* @param b The blue component of the colour to convert.
@@ -407,7 +409,7 @@ int libclut_model_get_rgb_conversion_matrix(const libclut_rgb_colourspace_t* fro
* @param out_g Output parameter for the new green component.
* @param out_b Output parameter for the new blue component.
*/
-void (libclut_model_convert_rgb)(double r, double g, double b, libclut_colourspace_conversion_matrix_t M,
+void (libclut_model_convert_rgb)(double r, double g, double b, libclut_colour_space_conversion_matrix_t M,
double *out_r, double *out_g, double *out_b)
{
libclut_model_convert_rgb(r, g, b, M, out_r, out_g, out_b);