aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/info/chap/colour-spaces.texinfo15
-rw-r--r--src/convert.c17
-rw-r--r--src/libcolour.c2
-rw-r--r--src/libcolour.h1
-rw-r--r--src/test.c23
5 files changed, 47 insertions, 11 deletions
diff --git a/doc/info/chap/colour-spaces.texinfo b/doc/info/chap/colour-spaces.texinfo
index a214feb..9455bbc 100644
--- a/doc/info/chap/colour-spaces.texinfo
+++ b/doc/info/chap/colour-spaces.texinfo
@@ -354,7 +354,7 @@ The wide-gamut RGB colour space, also known as
Adobe Wide Gamut RGB.
@end table
-Call @code{libcolour_proper(&c)} on a
+The call @code{libcolour_proper(&c)} on a
@code{struct libcolour_rgb_t c} (done automatically for
predefined colour spaces) sets @code{c.red.model},
@code{c.green.model}, and @code{c.blue.model} to
@@ -521,7 +521,7 @@ The white point.
CIE L*u*v* is not additive, since conversion from
CIE 1931 XYZ is non-linear.
-Call @code{libcolour_proper(&c)} on a
+The call @code{libcolour_proper(&c)} on a
@code{struct libcolour_cieluv_t c} sets
@code{c.white.model} to @code{LIBCOLOUR_CIEXYZ}.
Zero is always returned in this case.
@@ -555,15 +555,20 @@ The C*@sub{uv} value, the chroma.
The h@sub{uv} value, the hue.
@item struct libcolour_ciexyz white
The white point.
+@item double one_revolution
+The value lowest positive values of @code{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.
@end table
CIE LCh@sub{uv} is not additive. It is a cylindrical
representation of CIE 1976 (L*, u*, v*).
-Call @code{libcolour_proper(&c)} on a
+The call @code{libcolour_proper(&c)} on a
@code{struct libcolour_cielchuv_t c} sets
-@code{c.white.model} to @code{LIBCOLOUR_CIEXYZ}.
-Zero is always returned in this case.
+@code{c.white.model} to @code{LIBCOLOUR_CIEXYZ},
+and if @code{c.one_revolution} is 0, it is set
+to 360. Zero is always returned in this case.
@node YIQ
diff --git a/src/convert.c b/src/convert.c
index 5a358c9..9a2c3d9 100644
--- a/src/convert.c
+++ b/src/convert.c
@@ -24,6 +24,8 @@
#define WASDIV0(x) (isinf(x) || isnan(x))
+#define PI (3.14159265358979323846)
+#define PI2 (2 * PI)
@@ -598,11 +600,12 @@ static void cielchuv_to_cieluv(const libcolour_cielchuv_t* restrict from, libcol
tmp.model = LIBCOLOUR_CIEXYZ;
tmp2.model = LIBCOLOUR_CIELCHUV;
tmp2.white = to->white;
+ tmp2.one_revolution = PI2;
to_ciexyz((const libcolour_colour_t*)from, &tmp);
to_cielchuv((const libcolour_colour_t*)&tmp, &tmp2);
L = tmp2.L, C = tmp2.C, h = tmp2.h;
} else {
- L = from->L, C = from->C, h = from->h;
+ L = from->L, C = from->C, h = from->h * PI2 / from->one_revolution;
}
to->L = L;
to->u = C * cos(h);
@@ -655,7 +658,7 @@ static void cieluv_to_cielchuv(const libcolour_cieluv_t* restrict from, libcolou
}
to->L = L;
to->C = sqrt(u * u + v * v);
- to->h = atan2(v, u);
+ to->h = atan2(v, u) / PI2 * to->one_revolution;
}
static void other_to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielchuv_t* restrict to)
@@ -669,6 +672,7 @@ static void other_to_cielchuv(const libcolour_colour_t* restrict from, libcolour
static void to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielchuv_t* restrict to)
{
+ double one_revolution;
switch (from->model) {
case LIBCOLOUR_CIELUV:
cieluv_to_cielchuv(&from->cieluv, to);
@@ -677,7 +681,14 @@ static void to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielc
if (to->white.X == from->cielchuv.white.X &&
to->white.Y == from->cielchuv.white.Y &&
to->white.Z == from->cielchuv.white.Z) {
- *to = from->cielchuv;
+ if (to->one_revolution == from->cielchuv.one_revolution) {
+ *to = from->cielchuv;
+ } else {
+ one_revolution = to->one_revolution;
+ *to = from->cielchuv;
+ to->one_revolution = one_revolution;
+ to->h = to->h / from->cielchuv.one_revolution * one_revolution;
+ }
break;
}
/* fall through */
diff --git a/src/libcolour.c b/src/libcolour.c
index 57f1e80..69014d3 100644
--- a/src/libcolour.c
+++ b/src/libcolour.c
@@ -121,6 +121,8 @@ int libcolour_proper(libcolour_colour_t* colour)
break;
case LIBCOLOUR_CIELCHUV:
colour->cielchuv.white.model = LIBCOLOUR_CIEXYZ;
+ if (colour->cielchuv.one_revolution == 0.)
+ colour->cielchuv.one_revolution = 360.;
break;
case LIBCOLOUR_RGB:
colour->rgb.red.model = LIBCOLOUR_CIEXYY;
diff --git a/src/libcolour.h b/src/libcolour.h
index fe53a4e..6387151 100644
--- a/src/libcolour.h
+++ b/src/libcolour.h
@@ -232,6 +232,7 @@ typedef struct libcolour_cielchuv {
double C;
double h;
struct libcolour_ciexyz white;
+ double one_revolution;
} libcolour_cielchuv_t;
typedef struct libcolour_rgb {
diff --git a/src/test.c b/src/test.c
index 7d5517c..795333f 100644
--- a/src/test.c
+++ b/src/test.c
@@ -94,8 +94,10 @@ static int test_convert_11(libcolour_colour_t* c1, libcolour_model_t model)
if (r2 = test_convert(c1, &c2, &c3), r2 < 0)
return -1;
return r1 & r2;
- case LIBCOLOUR_CIELUV:
case LIBCOLOUR_CIELCHUV:
+ c2.cielchuv.one_revolution = 360.;
+ /* fall though */
+ case LIBCOLOUR_CIELUV:
c2.cieluv.white.model = LIBCOLOUR_CIEXYZ;
c2.cieluv.white.X = 1.0294;
c2.cieluv.white.Y = 1;
@@ -119,8 +121,12 @@ static int test_convert_1n(libcolour_model_t model, const char* model_name, doub
c1.model = model;
switch (model) {
case LIBCOLOUR_CIELAB:
- c1.srgb.R = ch1 * 100, c1.srgb.G = ch2 * 100, c1.srgb.B = ch3 * 100;
+ c1.cielab.L = ch1 * 100, c1.cielab.a = ch2 * 100, c1.cielab.b = ch3 * 100;
break;
+ case LIBCOLOUR_CIELCHUV:
+ if (ch3 > 0.9999)
+ return 1;
+ /* fall though */
default:
c1.srgb.R = ch1, c1.srgb.G = ch2, c1.srgb.B = ch3;
break;
@@ -140,8 +146,11 @@ static int test_convert_1n(libcolour_model_t model, const char* model_name, doub
return rc;
c1.srgb.with_gamma = run;
break;
- case LIBCOLOUR_CIELUV:
case LIBCOLOUR_CIELCHUV:
+ c1.cielchuv.one_revolution = run < 2 ? 360. : 2 * 3.14159265358979323846;
+ c1.cielchuv.h *= c1.cielchuv.one_revolution;
+ /* fall through */
+ case LIBCOLOUR_CIELUV:
c1.cieluv.white.model = LIBCOLOUR_CIEXYZ;
if (run == 0) {
c1.cieluv.white.X = 1.0294;
@@ -151,6 +160,14 @@ static int test_convert_1n(libcolour_model_t model, const char* model_name, doub
c1.cieluv.white.X = 1.03;
c1.cieluv.white.Y = 0.8;
c1.cieluv.white.Z = 0.92;
+ } else if (run == 2 && model == LIBCOLOUR_CIELCHUV) {
+ c1.cieluv.white.X = 1.0294;
+ c1.cieluv.white.Y = 1;
+ c1.cieluv.white.Z = 0.9118;
+ } else if (run == 3 && model == LIBCOLOUR_CIELCHUV) {
+ c1.cieluv.white.X = 1.03;
+ c1.cieluv.white.Y = 0.8;
+ c1.cieluv.white.Z = 0.92;
} else {
return rc;
}