aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--LIBCOLOUR_CIELCHUV.795
-rw-r--r--LIBCOLOUR_RGB.7202
-rw-r--r--LIBCOLOUR_SRGB.72
-rw-r--r--convert-template.c64
-rw-r--r--libcolour-template.c139
-rw-r--r--libcolour.h31
-rw-r--r--test.c43
7 files changed, 463 insertions, 113 deletions
diff --git a/LIBCOLOUR_CIELCHUV.7 b/LIBCOLOUR_CIELCHUV.7
new file mode 100644
index 0000000..1b551c7
--- /dev/null
+++ b/LIBCOLOUR_CIELCHUV.7
@@ -0,0 +1,95 @@
+.TH LIBCOLOUR_CIELCHUV 7 libcolour
+.SH NAME
+LIBCOLOUR_CIELCHUV - CIE LChuv
+.SH DESCRIPTION
+CIE LCh_uv [\(aq_\(aq denotes subscript of
+subsequent characters] (also known as CIE HLC_uv)
+colours are presented with either of
+.nf
+
+ \fBtypedef struct libcolour_cielchuv_f libcolour_cielchuv_f_t;\fP
+ \fBtypedef struct libcolour_cielchuv_lf libcolour_cielchuv_lf_t;\fP
+ \fBtypedef struct libcolour_cielchuv_llf libcolour_cielchuv_llf_t;\fP
+
+.fi
+These
+.BR struct s
+use
+.BR float ,
+.BR double ,
+and
+.BR long\ double ,
+respecitively, for the values stored in them,
+and are otherwise identical.
+.B struct libcolour_cielchuv_f
+is defined as
+.nf
+
+ \fBstruct libcolour_cielchuv_f {\fP
+ \fBenum libcolour_model\fP \fImodel\fP\fB;\fP
+ \fBfloat\fP \fIL\fP\fB;\fP
+ \fBfloat\fP \fIC\fP\fB;\fP
+ \fBfloat\fP \fIh\fP\fB;\fP
+ \fBstruct libcolour_ciexyz\fP \fIwhite\fP\fB;\fP
+ \fBdouble\fP \fIone_revolution\fP\fB;\fP
+ \fB};\fP
+
+.fi
+.I .model
+shall be set to
+.BR LIBCOLOUR_CIELCHUV .
+In
+.BR union\ libcolour_colour_f ,
+.BR union\ libcolour_colour_lf ,
+and
+.BR union\ libcolour_colour_llf ,
+.I .cielchuv
+is used for CIE LChuv colours.
+.P
+.IR .L ,
+.IR .C ,
+and
+.I .h
+hold the L* (luma), C*_uv (chroma), and
+h_uv (hue) values, respectively,
+.I .white
+is the white point, and
+.I .one_revolution
+the The value lowest positive values of
+.I .h
+that is equivalent to 0. 360 if the hue is measured
+in degrees, 400 if the hue is measured in gon, and
+2 pi if the hue is measured radian. Any value can
+be used.
+.I .white
+and
+.I .one_revolution
+are not part of the colour, but rather part of
+the colour space.
+.P
+L* is 0 in black and 100 in white.
+.P
+The call
+.BI libcolour_proper(& c )
+on a
+.B struct libcolour_cielchuv_t
+.I c
+sets
+.I c.white.model
+to
+.BR LIBCOLOUR_CIEXYZ ,
+and if
+.I c.one_revolution
+is 0, it is set to 360.
+Zero is always returned in this case.
+.P
+CIE LCh_uv approximates uniform human colour
+perception using cylindrical representation.
+.P
+CIE LCh_uv is not additive. It is a cylindrical
+representation of CIE 1976 (L*, u*, v*).
+.SH SEE ALSO
+.BR libcolour (7)
+.SH AUTHORS
+Mattias Andrée
+.RI < maandree@kth.se >
diff --git a/LIBCOLOUR_RGB.7 b/LIBCOLOUR_RGB.7
new file mode 100644
index 0000000..af49fe2
--- /dev/null
+++ b/LIBCOLOUR_RGB.7
@@ -0,0 +1,202 @@
+.TH LIBCOLOUR_RGB 7 libcolour
+.SH NAME
+LIBCOLOUR_RGB - Generic RGB
+.SH DESCRIPTION
+Generic RGB colours are presented with either of
+.nf
+
+ \fBtypedef struct libcolour_rgb_f libcolour_rgb_f_t;\fP
+ \fBtypedef struct libcolour_rgb_lf libcolour_rgb_lf_t;\fP
+ \fBtypedef struct libcolour_rgb_llf libcolour_rgb_llf_t;\fP
+
+.fi
+These
+.BR struct s
+use
+.BR float ,
+.BR double ,
+and
+.BR long\ double ,
+respecitively, for the values stored in them,
+and are otherwise identical.
+.B struct libcolour_rgb_f
+is defined as
+.nf
+
+ \fBstruct libcolour_rgb_f {\fP
+ \fBenum libcolour_model\fP \fImodel\fP\fB;\fP
+ \fBfloat\fP \fIR\fP\fB;\fP
+ \fBfloat\fP \fIG\fP\fB;\fP
+ \fBfloat\fP \fIB\fP\fB;\fP
+ \fBint\fP \fIwith_transfer\fP\fB;\fP
+ \fBenum libcolour_encoding_type\fP \fIencoding_type\fP\fB;\fP
+ \fBunion {\fP
+ \fBstruct {\fP
+ \fBfloat\fP \fIgamma\fP\fB;\fP
+ \fB}\fP \fIsimple\fB;\fP
+ \fBstruct {\fP
+ \fBfloat\fP \fIgamma\fP\fB;\fP
+ \fBfloat\fP \fIoffset\fP\fB;\fP
+ \fBfloat\fP \fIslope\fP\fB;\fP
+ \fBfloat\fP \fItransition\fP\fB;\fP
+ \fBfloat\fP \fItransitioninv\fP\fB;\fP
+ \fB}\fP \fIregular\fB;\fP
+ \fBstruct {\fP
+ \fBfloat (*\fP\fIto_encoded_red\fP\fB)(float);\fP
+ \fBfloat (*\fP\fIto_decoded_red\fP\fB)(float);\fP
+ \fBfloat (*\fP\fIto_encoded_green\fP\fB)(float);\fP
+ \fBfloat (*\fP\fIto_decoded_green\fP\fB)(float);\fP
+ \fBfloat (*\fP\fIto_encoded_blue\fP\fB)(float);\fP
+ \fBfloat (*\fP\fIto_decoded_blue\fP\fB)(float);\fP
+ \fB}\fP \fIcustom\fB;\fP
+ \fB}\fP \fItransfer\fB;\fP
+ \fBstruct libcolour_ciexyy\fP \fIred\fP\fB;\fP
+ \fBstruct libcolour_ciexyy\fP \fIgreen\fP\fB;\fP
+ \fBstruct libcolour_ciexyy\fP \fIblue\fP\fB;\fP
+ \fBstruct libcolour_ciexyy\fP \fIwhite\fP\fB;\fP
+ \fBfloat\fP \fIwhite_r\fP\fB;\fP
+ \fBfloat\fP \fIwhite_g\fP\fB;\fP
+ \fBfloat\fP \fIwhite_b\fP\fB;\fP
+ \fBfloat\fP \fIM\fP\fB[3][3];\fP
+ \fBfloat\fP \fIMinv\fP\fB[3][3];\fP
+ \fBenum libcolour_rgb_colour_space\fP \fIcolour_space\fP\fB;\fP
+ \fB};\fP
+
+.fi
+.I .model
+shall be set to
+.BR LIBCOLOUR_RGB .
+In
+.BR union\ libcolour_colour_f ,
+.BR union\ libcolour_colour_lf ,
+and
+.BR union\ libcolour_colour_llf ,
+.I .rgb
+is used for generic RGB colours.
+.P
+.IR .R ,
+.IR .G ,
+and
+.I .B
+hold the red, green, and blue values, respectively,
+and shall have a value between 0 and 1, inclusively,
+for the colour to be in gamut.
+.I .with_transfer
+shall be set to a non-zero value if the specified transfer
+function (\(dqgamma function\(dq) is applied, and zero
+otherwise, meaning colours are linearly encoded.
+.P
+.I .encoding_type
+shall be set to one of the following values:
+.TP
+.B LIBCOLOUR_ENCODING_TYPE_LINEAR
+The colour space does not have a transfer function.
+.TP
+.B LIBCOLOUR_ENCODING_TYPE_SIMPLE
+The colour space uses a simple gamma transfer function
+that only uses the
+.I .transfer.simple.gamma
+parameter.
+.TP
+.B LIBCOLOUR_ENCODING_TYPE_REGULAR
+The colour space uses a linear-gamma hybrid transfer
+function that uses the
+.IR .transfer.simple.gamma ,
+.IR .transfer.simple.offset ,
+.IR .transfer.simple.slope ,
+and
+.I .transfer.simple.transition
+parameters as well as
+.IR .transfer.simple.transitioninv ,
+the inverse value of the
+.I .transfer.simple.transition parameter of the transfer
+function, that is, where the transition takes place in
+the encoded, rather than linear, values. This value is
+set automatically.
+.TP
+.B LIBCOLOUR_ENCODING_TYPE_CUSTOM
+The colour space uses a custom transfer function. When
+this value is used,
+.IR .transfer.custom.to_encoded_red ,
+.IR .transfer.custom.to_encoded_green ,
+and
+.IR .transfer.custom.to_encoded_blue
+shall be set to the function used to apply the red,
+green, and blue channels' transfer functions to a value,
+respectively, and
+.IR .transfer.custom.to_decoded_red ,
+.IR .transfer.custom.to_decoded_green ,
+and
+.IR .transfer.custom.to_decoded_blue
+shall be set to the inverse of those functions.
+.P
+The colour space is defined by
+.I .red
+(the red primary),
+.I .green
+(the green primary),
+.I .blue
+(the blue primary),
+.I .white
+(the white point), and the RGB value of for the white
+point, which is specified by
+.I .white_r
+(the red value for the white point),
+.I .white_g
+(the green value for the white point),
+and
+.IR .white_b
+(the blue value for the white point).
+.IR .white.Y ,
+.IR .white_r ,
+.IR .white_g ,
+and
+.IR .white_b
+should usually be 1.
+.I .M
+is derived from these values, it is the matrix that is
+to convert a colour from the specified RGB colour space
+to CIE 1931 YXZ.
+.I .Minv
+is derived from
+.I .M
+is used to convert in the opposite direction.
+.IR .colour_space ,
+which is set automatically, is the colour space.
+.P
+.BR libcolour_get_rgb_colour_space (3)
+is used to set the transfer function and colour space
+parameters.
+.P
+The RGB colour model is an additive colour model, that is,
+without a transfer function applied, linearily isomorphic
+to CIE 1931 XYZ.
+.P
+The call
+.BI libcolour_proper(& c )
+on a
+.B struct libcolour_rgb_t
+.I c
+(done automatically for predefined colour spaces) sets
+.IR c.red.model ,
+.IR c.green.model ,
+and
+.I c.blue.model
+to
+.BR LIBCOLOUR_CIEXYY ,
+and calculate and sets the Y values for
+.IR c.red ,
+.IR c.green ,
+and
+.IR c.blue .
+Zero is always normally returned, but of there is something
+wrong with with the values of the primaries, −1 is returned
+and
+.I errno
+is set to
+.BR EDOM .
+.SH SEE ALSO
+.BR libcolour (7)
+.SH AUTHORS
+Mattias Andrée
+.RI < maandree@kth.se >
diff --git a/LIBCOLOUR_SRGB.7 b/LIBCOLOUR_SRGB.7
index fd6f819..f5bff7b 100644
--- a/LIBCOLOUR_SRGB.7
+++ b/LIBCOLOUR_SRGB.7
@@ -55,7 +55,7 @@ shall be set to a non-zero value if the sRGB transfer
function (\(dqgamma function\(dq) is applied, and zero
otherwise, meaning colours are linearly encoded.
.P
-The RGB color model, of which sRGB is a specific colour
+The RGB colour model, of which sRGB is a specific colour
space, is an additive colour model, that is, without a
transfer function applied, linearily isomorphic to
CIE 1931 XYZ.
diff --git a/convert-template.c b/convert-template.c
index d06ccc0..223f840 100644
--- a/convert-template.c
+++ b/convert-template.c
@@ -20,8 +20,8 @@
#define PI2 (2 * D(3.14159265358979323846))
#define WASDIV0(X) (xisinf(X) || xisnan(X))
-#define REGULAR(S, T) ((T) <= (S)->transition ? (S)->slope * (T) : (1 + (S)->offset) * xpow((T), 1 / (S)->gamma) - (S)->offset)
-#define INVREGULAR(S, T) ((T) <= (S)->transitioninv ? (T) / (S)->slope : xpow(((T) + (S)->offset) / (1 + (S)->offset), (S)->gamma))
+#define REGULAR(S, T) ((T) <= (S)->TRANSITION ? (S)->SLOPE * (T) : (1 + (S)->OFFSET) * xpow((T), 1 / (S)->GAMMA) - (S)->OFFSET)
+#define INVREGULAR(S, T) ((T) <= (S)->TRANSITIONINV ? (T) / (S)->SLOPE : xpow(((T) + (S)->OFFSET) / (1 + (S)->OFFSET), (S)->GAMMA))
#define TRANSFORM(X, Y, Z, A, B, C, R1C1, R1C2, R1C3, R2C1, R2C2, R2C3, R3C1, R3C2, R3C3)\
do {\
@@ -33,6 +33,20 @@
+#define SLOPE transfer.regular.slope
+#define TRANSITIONINV transfer.regular.transitioninv
+#define TRANSITION transfer.regular.transition
+#define GAMMA transfer.regular.gamma
+#define OFFSET transfer.regular.offset
+#define TO_ENCODED_RED transfer.custom.to_encoded_red
+#define TO_DECODED_RED transfer.custom.to_decoded_red
+#define TO_ENCODED_GREEN transfer.custom.to_encoded_green
+#define TO_DECODED_GREEN transfer.custom.to_decoded_green
+#define TO_ENCODED_BLUE transfer.custom.to_encoded_blue
+#define TO_DECODED_BLUE transfer.custom.to_decoded_blue
+
+
+
static void to_rgb(const libcolour_colour_t *restrict from, libcolour_rgb_t *restrict to);
static void to_srgb(const libcolour_colour_t *restrict from, libcolour_srgb_t *restrict to);
static void to_ciexyy(const libcolour_colour_t *restrict from, libcolour_ciexyy_t *restrict to);
@@ -73,9 +87,9 @@ rgb_encode(libcolour_rgb_t *restrict colour, const libcolour_rgb_t *restrict spa
if (colour->G < 0) g_sign = -1, colour->G = -colour->G;
if (colour->B < 0) b_sign = -1, colour->B = -colour->B;
if (space->encoding_type == LIBCOLOUR_ENCODING_TYPE_SIMPLE) {
- colour->R = xpow(colour->R, 1 / space->gamma);
- colour->G = xpow(colour->G, 1 / space->gamma);
- colour->B = xpow(colour->B, 1 / space->gamma);
+ colour->R = xpow(colour->R, 1 / space->GAMMA);
+ colour->G = xpow(colour->G, 1 / space->GAMMA);
+ colour->B = xpow(colour->B, 1 / space->GAMMA);
} else {
colour->R = REGULAR(space, colour->R);
colour->G = REGULAR(space, colour->G);
@@ -86,9 +100,9 @@ rgb_encode(libcolour_rgb_t *restrict colour, const libcolour_rgb_t *restrict spa
colour->B *= b_sign;
break;
case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
- colour->R = (space->to_encoded_red)(colour->R);
- colour->G = (space->to_encoded_green)(colour->G);
- colour->B = (space->to_encoded_blue)(colour->B);
+ colour->R = (space->TO_ENCODED_RED)(colour->R);
+ colour->G = (space->TO_ENCODED_GREEN)(colour->G);
+ colour->B = (space->TO_ENCODED_BLUE)(colour->B);
break;
default:
fprintf(stderr, "libcolour: invalid encoding type\n");
@@ -109,9 +123,9 @@ rgb_decode(libcolour_rgb_t *restrict colour, const libcolour_rgb_t *restrict spa
if (colour->G < 0) g_sign = -1, colour->G = -colour->G;
if (colour->B < 0) b_sign = -1, colour->B = -colour->B;
if (space->encoding_type == LIBCOLOUR_ENCODING_TYPE_SIMPLE) {
- colour->R = xpow(colour->R, space->gamma);
- colour->G = xpow(colour->G, space->gamma);
- colour->B = xpow(colour->B, space->gamma);
+ colour->R = xpow(colour->R, space->GAMMA);
+ colour->G = xpow(colour->G, space->GAMMA);
+ colour->B = xpow(colour->B, space->GAMMA);
} else {
colour->R = INVREGULAR(space, colour->R);
colour->G = INVREGULAR(space, colour->G);
@@ -122,9 +136,9 @@ rgb_decode(libcolour_rgb_t *restrict colour, const libcolour_rgb_t *restrict spa
colour->B *= b_sign;
break;
case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
- colour->R = (space->to_decoded_red)(colour->R);
- colour->G = (space->to_decoded_green)(colour->G);
- colour->B = (space->to_decoded_blue)(colour->B);
+ colour->R = (space->TO_DECODED_RED)(colour->R);
+ colour->G = (space->TO_DECODED_GREEN)(colour->G);
+ colour->B = (space->TO_DECODED_BLUE)(colour->B);
break;
default:
fprintf(stderr, "libcolour: invalid encoding type\n");
@@ -139,19 +153,19 @@ rgb_same_transfer(const libcolour_rgb_t *restrict a, const libcolour_rgb_t *rest
return 0;
switch (a->encoding_type) {
case LIBCOLOUR_ENCODING_TYPE_SIMPLE:
- return a->gamma == b->gamma;
+ return a->GAMMA == b->GAMMA;
case LIBCOLOUR_ENCODING_TYPE_REGULAR:
- return a->gamma == b->gamma &&
- a->offset == b->offset &&
- a->slope == b->slope &&
- a->transition == b->transition;
+ return a->GAMMA == b->GAMMA &&
+ a->OFFSET == b->OFFSET &&
+ a->SLOPE == b->SLOPE &&
+ a->TRANSITION == b->TRANSITION;
case LIBCOLOUR_ENCODING_TYPE_CUSTOM:
- return a->to_encoded_red == b->to_encoded_red &&
- a->to_encoded_green == b->to_encoded_green &&
- a->to_encoded_blue == b->to_encoded_blue &&
- a->to_decoded_red == b->to_decoded_red &&
- a->to_decoded_green == b->to_decoded_green &&
- a->to_decoded_blue == b->to_decoded_blue;
+ return a->TO_ENCODED_RED == b->TO_ENCODED_RED &&
+ a->TO_ENCODED_GREEN == b->TO_ENCODED_GREEN &&
+ a->TO_ENCODED_BLUE == b->TO_ENCODED_BLUE &&
+ a->TO_DECODED_RED == b->TO_DECODED_RED &&
+ a->TO_DECODED_GREEN == b->TO_DECODED_GREEN &&
+ a->TO_DECODED_BLUE == b->TO_DECODED_BLUE;
default:
return 1;
}
diff --git a/libcolour-template.c b/libcolour-template.c
index 3862fce..80568de 100644
--- a/libcolour-template.c
+++ b/libcolour-template.c
@@ -16,7 +16,22 @@
#endif
-#define MARSHAL_VERSION 0
+#define MARSHAL_VERSION 0
+
+
+
+#define SLOPE transfer.regular.slope
+#define TRANSITIONINV transfer.regular.transitioninv
+#define TRANSITION transfer.regular.transition
+#define GAMMA transfer.regular.gamma
+#define OFFSET transfer.regular.offset
+#define TO_ENCODED_RED transfer.custom.to_encoded_red
+#define TO_DECODED_RED transfer.custom.to_decoded_red
+#define TO_ENCODED_GREEN transfer.custom.to_encoded_green
+#define TO_DECODED_GREEN transfer.custom.to_decoded_green
+#define TO_ENCODED_BLUE transfer.custom.to_encoded_blue
+#define TO_DECODED_BLUE transfer.custom.to_decoded_blue
+
TYPE
@@ -338,8 +353,8 @@ get_transfer_function(libcolour_colour_t *cs)
if (cs->model == LIBCOLOUR_RGB) {
switch (cs->rgb.colour_space) {
case LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2:
- cs->rgb.to_encoded_red = cs->rgb.to_encoded_green = cs->rgb.to_encoded_blue = transfer_function_l_star;
- cs->rgb.to_decoded_red = cs->rgb.to_decoded_green = cs->rgb.to_decoded_blue = invtransfer_function_l_star;
+ cs->rgb.TO_ENCODED_RED = cs->rgb.TO_ENCODED_GREEN = cs->rgb.TO_ENCODED_BLUE = transfer_function_l_star;
+ cs->rgb.TO_DECODED_RED = cs->rgb.TO_DECODED_GREEN = cs->rgb.TO_DECODED_BLUE = invtransfer_function_l_star;
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_EOTF_PQ:
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_OOTF_PQ:
@@ -349,8 +364,8 @@ get_transfer_function(libcolour_colour_t *cs)
/* TODO http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.2100-0-201607-I!!PDF-E.pdf */
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_OETF_HLG:
- cs->rgb.to_encoded_red = cs->rgb.to_encoded_green = cs->rgb.to_encoded_blue = transfer_function_oetf_hlg;
- cs->rgb.to_decoded_red = cs->rgb.to_decoded_green = cs->rgb.to_decoded_blue = invtransfer_function_oetf_hlg;
+ cs->rgb.TO_ENCODED_RED = cs->rgb.TO_ENCODED_GREEN = cs->rgb.TO_ENCODED_BLUE = transfer_function_oetf_hlg;
+ cs->rgb.TO_DECODED_RED = cs->rgb.TO_DECODED_GREEN = cs->rgb.TO_DECODED_BLUE = invtransfer_function_oetf_hlg;
break;
default:
break;
@@ -369,21 +384,21 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
if (get_matrices(cs))
return -1;
if (cs->encoding_type == LIBCOLOUR_ENCODING_TYPE_REGULAR)
- cs->transitioninv = cs->transition * cs->slope;
+ cs->TRANSITIONINV = cs->TRANSITION * cs->SLOPE;
return 0;
case LIBCOLOUR_RGB_COLOUR_SPACE_CUSTOM_FROM_MATRIX:
if (invert(cs->Minv, cs->M, 3) || get_primaries(cs))
return -1;
if (cs->encoding_type == LIBCOLOUR_ENCODING_TYPE_REGULAR)
- cs->transitioninv = cs->transition * cs->slope;
+ cs->TRANSITIONINV = cs->TRANSITION * cs->SLOPE;
return 0;
case LIBCOLOUR_RGB_COLOUR_SPACE_CUSTOM_FROM_INV_MATRIX:
if (invert(cs->M, cs->Minv, 3) || get_primaries(cs))
return -1;
if (cs->encoding_type == LIBCOLOUR_ENCODING_TYPE_REGULAR)
- cs->transitioninv = cs->transition * cs->slope;
+ cs->TRANSITIONINV = cs->TRANSITION * cs->SLOPE;
return 0;
case LIBCOLOUR_RGB_COLOUR_SPACE_SRGB:
@@ -392,10 +407,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->offset = D(0.055);
- cs->gamma = D(2.4);
- cs->slope = D(12.92);
- cs->transition = D(0.0031306684425217108);
+ cs->OFFSET = D(0.055);
+ cs->GAMMA = D(2.4);
+ cs->SLOPE = D(12.92);
+ cs->TRANSITION = D(0.0031306684425217108);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ADOBE_RGB:
@@ -404,7 +419,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_APPLE_RGB:
@@ -413,7 +428,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1550, 0.0700);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(1.8);
+ cs->GAMMA = D(1.8);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_BEST_RGB:
@@ -422,7 +437,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1300, 0.0350);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_BETA_RGB:
@@ -431,7 +446,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1265, 0.0352);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_BRUCE_RGB:
@@ -440,7 +455,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_CIE_RGB:
@@ -449,7 +464,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1670, 0.0090);
cs->white = LIBCOLOUR_ILLUMINANT_E;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_COLORMATCH_RGB:
@@ -458,7 +473,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0750);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(1.8);
+ cs->GAMMA = D(1.8);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_DCI_P3_D65:
@@ -467,7 +482,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.6);
+ cs->GAMMA = D(2.6);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_DCI_P3_THEATER:
@@ -476,7 +491,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = XYY(0.314, 0.351);
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.6);
+ cs->GAMMA = D(2.6);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_DON_RGB_4:
@@ -485,7 +500,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1300, 0.0350);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB:
@@ -494,7 +509,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1400, 0.0800);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(1.8);
+ cs->GAMMA = D(1.8);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2:
@@ -511,7 +526,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1100, 0.0050);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.2);
+ cs->GAMMA = D(2.2);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_601_625_LINE:
@@ -520,10 +535,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0060);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_601_525_LINE:
@@ -532,10 +547,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1550, 0.0700);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_709:
@@ -544,10 +559,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2020:
@@ -556,10 +571,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1310, 0.0460);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_EOTF_PQ:
@@ -589,10 +604,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1400, 0.0800);
cs->white = LIBCOLOUR_ILLUMINANT_C;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_PAL_SECAM_RGB:
@@ -601,10 +616,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1500, 0.0600);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_PROPHOTO_RGB:
@@ -613,7 +628,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.0366, 0.0001);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(1.8);
+ cs->GAMMA = D(1.8);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_SGI_RGB:
@@ -622,7 +637,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1550, 0.0700);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(1.47);
+ cs->GAMMA = D(1.47);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_SMPTE_240M_RGB:
@@ -631,10 +646,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1550, 0.0700);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.1115721957735072);
- cs->slope = D(4.0);
- cs->transition = D(0.022821585552393633);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.1115721957735072);
+ cs->SLOPE = D(4.0);
+ cs->TRANSITION = D(0.022821585552393633);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_SMPTE_C_RGB:
@@ -643,10 +658,10 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1550, 0.0700);
cs->white = LIBCOLOUR_ILLUMINANT_D65;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_REGULAR;
- cs->gamma = 1 / D(0.45);
- cs->offset = D(0.09929682680944);
- cs->slope = D(4.5);
- cs->transition = D(0.018053968510807);
+ cs->GAMMA = 1 / D(0.45);
+ cs->OFFSET = D(0.09929682680944);
+ cs->SLOPE = D(4.5);
+ cs->TRANSITION = D(0.018053968510807);
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_WIDE_GAMUT_RGB:
@@ -655,7 +670,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
cs->blue = XYY(0.1570, 0.0180);
cs->white = LIBCOLOUR_ILLUMINANT_D50;
cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- cs->gamma = D(2.19921875);
+ cs->GAMMA = D(2.19921875);
break;
default:
@@ -663,7 +678,7 @@ libcolour_get_rgb_colour_space(libcolour_rgb_t *cs, libcolour_rgb_colour_space_t
return -1;
}
if (cs->encoding_type == LIBCOLOUR_ENCODING_TYPE_REGULAR)
- cs->transitioninv = cs->transition * cs->slope;
+ cs->TRANSITIONINV = cs->TRANSITION * cs->SLOPE;
cs->colour_space = space;
cs->white_r = cs->white_g = cs->white_b = 1;
if (get_matrices(cs) || libcolour_proper((libcolour_colour_t *)cs))
@@ -722,8 +737,8 @@ libcolour_unmarshal(libcolour_colour_t *colour, const void *buf)
}
if (colour) {
if (colour->model == LIBCOLOUR_RGB) {
- colour->rgb.to_encoded_red = colour->rgb.to_encoded_green = colour->rgb.to_encoded_blue = NULL;
- colour->rgb.to_decoded_red = colour->rgb.to_decoded_green = colour->rgb.to_decoded_blue = NULL;
+ colour->rgb.TO_ENCODED_RED = colour->rgb.TO_ENCODED_GREEN = colour->rgb.TO_ENCODED_BLUE = NULL;
+ colour->rgb.TO_DECODED_RED = colour->rgb.TO_DECODED_GREEN = colour->rgb.TO_DECODED_BLUE = NULL;
}
get_transfer_function(colour);
}
diff --git a/libcolour.h b/libcolour.h
index 63d37a1..e685d8f 100644
--- a/libcolour.h
+++ b/libcolour.h
@@ -396,17 +396,26 @@ typedef struct libcolour_rgb_##RES {\
TYPE B;\
int with_transfer;\
enum libcolour_encoding_type encoding_type;\
- TYPE gamma;\
- TYPE offset;\
- TYPE slope;\
- TYPE transition;\
- TYPE transitioninv;\
- TYPE (*to_encoded_red)(TYPE);\
- TYPE (*to_decoded_red)(TYPE);\
- TYPE (*to_encoded_green)(TYPE);\
- TYPE (*to_decoded_green)(TYPE);\
- TYPE (*to_encoded_blue)(TYPE);\
- TYPE (*to_decoded_blue)(TYPE);\
+ union {\
+ struct {\
+ TYPE gamma;\
+ } simple;\
+ struct {\
+ TYPE gamma;\
+ TYPE offset;\
+ TYPE slope;\
+ TYPE transition;\
+ TYPE transitioninv;\
+ } regular;\
+ struct {\
+ TYPE (*to_encoded_red)(TYPE);\
+ TYPE (*to_decoded_red)(TYPE);\
+ TYPE (*to_encoded_green)(TYPE);\
+ TYPE (*to_decoded_green)(TYPE);\
+ TYPE (*to_encoded_blue)(TYPE);\
+ TYPE (*to_decoded_blue)(TYPE);\
+ } custom;\
+ } transfer;\
struct libcolour_ciexyy_##RES red;\
struct libcolour_ciexyy_##RES green;\
struct libcolour_ciexyy_##RES blue;\
diff --git a/test.c b/test.c
index f6fb2e1..5264694 100644
--- a/test.c
+++ b/test.c
@@ -13,6 +13,21 @@
#define libcolour_unmarshal libcolour_unmarshal_lf
+
+#define SLOPE transfer.regular.slope
+#define TRANSITIONINV transfer.regular.transitioninv
+#define TRANSITION transfer.regular.transition
+#define GAMMA transfer.regular.gamma
+#define OFFSET transfer.regular.offset
+#define TO_ENCODED_RED transfer.custom.to_encoded_red
+#define TO_DECODED_RED transfer.custom.to_decoded_red
+#define TO_ENCODED_GREEN transfer.custom.to_encoded_green
+#define TO_DECODED_GREEN transfer.custom.to_decoded_green
+#define TO_ENCODED_BLUE transfer.custom.to_encoded_blue
+#define TO_DECODED_BLUE transfer.custom.to_decoded_blue
+
+
+
#ifndef SKIP_2CONVERT
static int
test_2convert(libcolour_colour_t *c1, libcolour_colour_t *c2, libcolour_colour_t *c3)
@@ -391,15 +406,15 @@ main(int argc, char *argv[])
if (c2.rgb.white_r != 1 || c2.rgb.white_g != 1 || c2.rgb.white_b != 1 ||
c2.rgb.red.model != LIBCOLOUR_CIEXYY || c2.rgb.green.model != LIBCOLOUR_CIEXYY ||
c2.rgb.blue.model != LIBCOLOUR_CIEXYY || c2.rgb.white.model != LIBCOLOUR_CIEXYY ||
- c2.rgb.colour_space != LIBCOLOUR_RGB_COLOUR_SPACE_SRGB || c2.rgb.gamma != 2.4 ||
- c2.rgb.encoding_type != LIBCOLOUR_ENCODING_TYPE_REGULAR || c2.rgb.slope != 12.92
- || c2.rgb.offset != 0.055 || c2.rgb.transitioninv != c2.rgb.transition * c2.rgb.slope ||
- !ftest(c2.rgb.transition, 0.00313067, 0.00000001)) {
+ c2.rgb.colour_space != LIBCOLOUR_RGB_COLOUR_SPACE_SRGB || c2.rgb.GAMMA != 2.4 ||
+ c2.rgb.encoding_type != LIBCOLOUR_ENCODING_TYPE_REGULAR || c2.rgb.SLOPE != 12.92
+ || c2.rgb.OFFSET != 0.055 || c2.rgb.TRANSITIONINV != c2.rgb.TRANSITION * c2.rgb.SLOPE ||
+ !ftest(c2.rgb.TRANSITION, 0.00313067, 0.00000001)) {
printf("LIBCOLOUR_RGB_COLOUR_SPACE_SRGB failed\n"), rc = 0;
goto colour_spaces_done;
}
- t1 = c2.rgb.transition * c2.rgb.slope;
- t2 = (1 + c2.rgb.offset) * pow(c2.rgb.transition, 1 / c2.rgb.gamma) - c2.rgb.offset;
+ t1 = c2.rgb.TRANSITION * c2.rgb.SLOPE;
+ t2 = (1 + c2.rgb.OFFSET) * pow(c2.rgb.TRANSITION, 1 / c2.rgb.GAMMA) - c2.rgb.OFFSET;
if (!ftest(t1, t2, 0.0000001) || c2.rgb.white.Y != 1 ||
c2.rgb.red.x != 0.64 || c2.rgb.red.y != 0.33 || !ftest(c2.rgb.red.Y, 0.21265, 0.00005) ||
c2.rgb.green.x != 0.30 || c2.rgb.green.y != 0.60 || !ftest(c2.rgb.green.Y, 0.71515, 0.00005) ||
@@ -546,14 +561,14 @@ main(int argc, char *argv[])
}
c1.rgb.encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
- c1.rgb.gamma = 2.2;
+ c1.rgb.GAMMA = 2.2;
c1.rgb.with_transfer = 0;
c1.rgb.R = 0.25;
c1.rgb.G = 0.5;
c1.rgb.B = 0.75;
c4 = c3 = c2 = c1;
c2.rgb.with_transfer = c3.srgb.with_transfer = 1;
- c3.rgb.gamma = c4.rgb.gamma = 1.8;
+ c3.rgb.GAMMA = c4.rgb.GAMMA = 1.8;
if (libcolour_convert(&c1, &c2))
goto fail;
if (libcolour_convert(&c2, &c3))
@@ -621,12 +636,12 @@ colour_spaces_done:
if (libcolour_get_rgb_colour_space(&c1.rgb, LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2))
goto fail;
c3 = c1;
- c1.rgb.to_encoded_red = NULL;
- c1.rgb.to_encoded_green = NULL;
- c1.rgb.to_encoded_blue = NULL;
- c1.rgb.to_decoded_red = NULL;
- c1.rgb.to_decoded_green = NULL;
- c1.rgb.to_decoded_blue = NULL;
+ c1.rgb.TO_ENCODED_RED = NULL;
+ c1.rgb.TO_ENCODED_GREEN = NULL;
+ c1.rgb.TO_ENCODED_BLUE = NULL;
+ c1.rgb.TO_DECODED_RED = NULL;
+ c1.rgb.TO_DECODED_GREEN = NULL;
+ c1.rgb.TO_DECODED_BLUE = NULL;
if (libcolour_marshal(&c1, NULL) > sizeof(buf)) {
printf("libcolour_marshal failed\n"), rc = 0;
goto marshal_done;