aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--TODO4
-rw-r--r--doc/info/chap/colour-spaces.texinfo20
-rw-r--r--doc/info/content.texinfo2
-rw-r--r--src/libcolour.c76
-rw-r--r--src/libcolour.h9
-rw-r--r--src/test.c20
6 files changed, 80 insertions, 51 deletions
diff --git a/TODO b/TODO
index ada1788..eea773d 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-Colour spaces:
+Colour models:
LMS
L'M'S'
ICtCp
@@ -6,7 +6,9 @@ Colour spaces:
TSL
Y'UV
Hunter 1948 color space (see Wikipedia article on CIELAB)
+ Hunter Rdab
CIELCh (CIEHLC) (see Wikipedia article on CIELAB)
+ IPT
Support for generic additive colour spaces (3 channels and more)
Support for generic subtractive colour spaces (3 channels and more)
diff --git a/doc/info/chap/colour-spaces.texinfo b/doc/info/chap/colour-spaces.texinfo
index 5c88a88..eb26ba0 100644
--- a/doc/info/chap/colour-spaces.texinfo
+++ b/doc/info/chap/colour-spaces.texinfo
@@ -8,7 +8,7 @@
* CIEXYZ:: The CIE 1931 XYZ colour model.
* CIELAB:: The CIE L*a*b* colour model.
* CIELUV:: The CIE 1976 (L*, u*, v*) colour model.
-* CIELCh:: The CIE LCh colour model.
+* CIELChuv:: The CIE LCh@sub{uv} colour model.
* YIQ:: The YIQ colour model.
* YDbDr:: The YDbDr colour model.
* YUV:: The YUV colour model.
@@ -31,7 +31,7 @@ typedef union libcolour_colour @{
struct libcolour_ciexyz ciexyz;
struct libcolour_cielab cielab;
struct libcolour_cieluv cieluv;
- struct libcolour_cielch cielch;
+ struct libcolour_cielchuv cielchuv;
struct libcolour_yiq yiq;
struct libcolour_ydbdr ydbdr;
struct libcolour_yuv yuv;
@@ -297,6 +297,8 @@ The DCI-P3 D65 colour space.
The DCI-P3 Theater colour space.
@item LIBCOLOUR_RGB_COLOUR_SPACE_DON_RGB_4
The Don RGB 4 colour space.
+@item LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB
+The ECI RGB colour space.
@item LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2
The ECI RGB v2 colour space.
@item LIBCOLOUR_RGB_COLOUR_SPACE_EKTA_SPACE_PS5
@@ -539,20 +541,20 @@ Zero is always returned in this case.
-@node CIELCh
+@node CIELChuv
@section CIE LCh@sub{uv}
CIE LCh@sub{uv} (also known as CIE HLC@sub{uv}) colours are presented
-with @code{struct libcolour_cielch} (@code{libcolour_cielch_t}), and
-the @code{.model} member shall be set to @code{LIBCOLOUR_CIELCH}. In
-@code{union libcolour_colour}, @code{.cielch} are used for CIE LCh@sub{uv}
+with @code{struct libcolour_cielchuv} (@code{libcolour_cielchuv_t}), and
+the @code{.model} member shall be set to @code{LIBCOLOUR_CIELCHUV}. In
+@code{union libcolour_colour}, @code{.cielchuv} are used for CIE LCh@sub{uv}
colours. CIE LCh@sub{uv} approximates uniform human colour perception
using cylindrical representation.
-@code{struct libcolour_cielch} has the following members
+@code{struct libcolour_cielchuv} has the following members
@table @code
@item enum libcolour_model model
-Shall be set to @code{LIBCOLOUR_CIELCH}.
+Shall be set to @code{LIBCOLOUR_CIELCHUV}.
@item double L
The L* value. 0 is black, 100 is white.
@item double C
@@ -572,7 +574,7 @@ 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
-@code{struct libcolour_cielch_t c} sets
+@code{struct libcolour_cielchuv_t c} sets
@code{c.white.model} to @code{LIBCOLOUR_CIEXYZ}.
Zero is always returned in this case.
diff --git a/doc/info/content.texinfo b/doc/info/content.texinfo
index 4ad71d5..c8e7811 100644
--- a/doc/info/content.texinfo
+++ b/doc/info/content.texinfo
@@ -29,7 +29,7 @@ Colour Spaces
* CIEXYZ:: The CIE 1931 XYZ colour model.
* CIELAB:: The CIE L*a*b* colour model.
* CIELUV:: The CIE 1976 (L*, u*, v*) colour model.
-* CIELCh:: The CIE LCh colour model.
+* CIELChuv:: The CIE LCh@sub{uv} colour model.
* YIQ:: The YIQ colour model.
* YDbDr:: The YDbDr colour model.
* YUV:: The YUV colour model.
diff --git a/src/libcolour.c b/src/libcolour.c
index dd170af..d2e056b 100644
--- a/src/libcolour.c
+++ b/src/libcolour.c
@@ -38,7 +38,7 @@ static void to_ciexyy(const libcolour_colour_t* restrict from, libcolour_ciexyy_
static void to_ciexyz(const libcolour_colour_t* restrict from, libcolour_ciexyz_t* restrict to);
static void to_cielab(const libcolour_colour_t* restrict from, libcolour_cielab_t* restrict to);
static void to_cieluv(const libcolour_colour_t* restrict from, libcolour_cieluv_t* restrict to);
-static void to_cielch(const libcolour_colour_t* restrict from, libcolour_cielch_t* restrict to);
+static void to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielchuv_t* restrict to);
static void to_yiq(const libcolour_colour_t* restrict from, libcolour_yiq_t* restrict to);
static void to_ydbdr(const libcolour_colour_t* restrict from, libcolour_ydbdr_t* restrict to);
static void to_yuv(const libcolour_colour_t* restrict from, libcolour_yuv_t* restrict to);
@@ -364,7 +364,7 @@ static void cieluv_to_ciexyz(const libcolour_cieluv_t* restrict from, libcolour_
to->Z = Y * (3 / v - 0.75 * u / v - 5);
}
-static void cielch_to_ciexyz(const libcolour_cielch_t* restrict from, libcolour_ciexyz_t* restrict to)
+static void cielchuv_to_ciexyz(const libcolour_cielchuv_t* restrict from, libcolour_ciexyz_t* restrict to)
{
libcolour_cieluv_t tmp;
tmp.model = LIBCOLOUR_CIELUV;
@@ -427,8 +427,8 @@ static void to_ciexyz(const libcolour_colour_t* restrict from, libcolour_ciexyz_
case LIBCOLOUR_CIELUV:
cieluv_to_ciexyz(&from->cieluv, to);
return;
- case LIBCOLOUR_CIELCH:
- cielch_to_ciexyz(&from->cielch, to);
+ case LIBCOLOUR_CIELCHUV:
+ cielchuv_to_ciexyz(&from->cielchuv, to);
return;
case LIBCOLOUR_YUV:
yuv_to_ciexyz(&from->yuv, to);
@@ -504,17 +504,17 @@ static void ciexyz_to_cieluv(const libcolour_ciexyz_t* restrict from, libcolour_
to->v = v * y;
}
-static void cielch_to_cieluv(const libcolour_cielch_t* restrict from, libcolour_cieluv_t* restrict to)
+static void cielchuv_to_cieluv(const libcolour_cielchuv_t* restrict from, libcolour_cieluv_t* restrict to)
{
libcolour_ciexyz_t tmp;
- libcolour_cielch_t tmp2;
+ libcolour_cielchuv_t tmp2;
double L, C, h;
if (to->white.X != from->white.X || to->white.Y != from->white.Y || to->white.Z != from->white.Z) {
tmp.model = LIBCOLOUR_CIEXYZ;
- tmp2.model = LIBCOLOUR_CIELCH;
+ tmp2.model = LIBCOLOUR_CIELCHUV;
tmp2.white = to->white;
to_ciexyz((const libcolour_colour_t*)from, &tmp);
- to_cielch((const libcolour_colour_t*)&tmp, &tmp2);
+ 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;
@@ -538,8 +538,8 @@ static void to_cieluv(const libcolour_colour_t* restrict from, libcolour_cieluv_
case LIBCOLOUR_CIEXYZ:
ciexyz_to_cieluv(&from->ciexyz, to);
return;
- case LIBCOLOUR_CIELCH:
- cielch_to_cieluv(&from->cielch, to);
+ case LIBCOLOUR_CIELCHUV:
+ cielchuv_to_cieluv(&from->cielchuv, to);
return;
case LIBCOLOUR_CIELUV:
if (to->white.X == from->cieluv.white.X &&
@@ -556,7 +556,7 @@ static void to_cieluv(const libcolour_colour_t* restrict from, libcolour_cieluv_
}
-static void cieluv_to_cielch(const libcolour_cieluv_t* restrict from, libcolour_cielch_t* restrict to)
+static void cieluv_to_cielchuv(const libcolour_cieluv_t* restrict from, libcolour_cielchuv_t* restrict to)
{
libcolour_cieluv_t tmp;
double L, u, v;
@@ -573,31 +573,31 @@ static void cieluv_to_cielch(const libcolour_cieluv_t* restrict from, libcolour_
to->h = atan2(v, u);
}
-static void other_to_cielch(const libcolour_colour_t* restrict from, libcolour_cielch_t* restrict to)
+static void other_to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielchuv_t* restrict to)
{
libcolour_cieluv_t tmp;
tmp.model = LIBCOLOUR_CIELUV;
tmp.white = to->white;
to_cieluv(from, &tmp);
- cieluv_to_cielch(&tmp, to);
+ cieluv_to_cielchuv(&tmp, to);
}
-static void to_cielch(const libcolour_colour_t* restrict from, libcolour_cielch_t* restrict to)
+static void to_cielchuv(const libcolour_colour_t* restrict from, libcolour_cielchuv_t* restrict to)
{
switch (from->model) {
case LIBCOLOUR_CIELUV:
- cieluv_to_cielch(&from->cieluv, to);
+ cieluv_to_cielchuv(&from->cieluv, to);
return;
- case LIBCOLOUR_CIELCH:
- if (to->white.X == from->cielch.white.X &&
- to->white.Y == from->cielch.white.Y &&
- to->white.Z == from->cielch.white.Z) {
- *to = from->cielch;
+ case LIBCOLOUR_CIELCHUV:
+ 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;
return;
}
/* fall through */
default:
- other_to_cielch(from, to);
+ other_to_cielchuv(from, to);
return;
}
}
@@ -828,8 +828,8 @@ int libcolour_convert(const libcolour_colour_t* restrict from, libcolour_colour_
case LIBCOLOUR_CIELUV:
to_cieluv(from, &to->cieluv);
break;
- case LIBCOLOUR_CIELCH:
- to_cielch(from, &to->cielch);
+ case LIBCOLOUR_CIELCHUV:
+ to_cielchuv(from, &to->cielchuv);
break;
case LIBCOLOUR_YIQ:
to_yiq(from, &to->yiq);
@@ -941,8 +941,8 @@ int libcolour_proper(libcolour_colour_t* colour)
case LIBCOLOUR_CIELUV:
colour->cieluv.white.model = LIBCOLOUR_CIEXYZ;
break;
- case LIBCOLOUR_CIELCH:
- colour->cielch.white.model = LIBCOLOUR_CIEXYZ;
+ case LIBCOLOUR_CIELCHUV:
+ colour->cielchuv.white.model = LIBCOLOUR_CIEXYZ;
break;
case LIBCOLOUR_RGB:
colour->rgb.red.model = LIBCOLOUR_CIEXYY;
@@ -1096,11 +1096,26 @@ static int invert_(size_t n, double (*Minvp)[n][n], double (*Mp)[n][n])
}
+static double transfer_function_l_star(double t)
+{
+ t = (t > 216. / 24389.) ? cbrt(t) : t * 841. / 108. + 4. / 29.;
+ return t * 1.16 - 0.16;
+}
+
+static double invtransfer_function_l_star(double t)
+{
+ t = (t + 0.16) / 1.16;
+ return (t > 6. / 29.) ? t * t * t : (t - 4. / 29.) * 108 / 841;
+}
+
+
static void 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: /* TODO L* */
+ 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;
break;
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_EOTF_PQ:
case LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_2100_OOTF_PQ:
@@ -1239,6 +1254,15 @@ int libcolour_get_rgb_colour_space(libcolour_rgb_t* cs, libcolour_rgb_colour_spa
cs->gamma = 2.2;
break;
+ case LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB:
+ cs->red = XYY(0.6700, 0.3300);
+ cs->green = XYY(0.2100, 0.7100);
+ cs->blue = XYY(0.1400, 0.0800);
+ cs->white = LIBCOLOUR_ILLUMINANT_D50;
+ cs->encoding_type = LIBCOLOUR_ENCODING_TYPE_SIMPLE;
+ cs->gamma = 1.8;
+ break;
+
case LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2:
cs->red = XYY(0.6700, 0.3300);
cs->green = XYY(0.2100, 0.7100);
diff --git a/src/libcolour.h b/src/libcolour.h
index 8efe779..c68cf11 100644
--- a/src/libcolour.h
+++ b/src/libcolour.h
@@ -72,7 +72,7 @@
X(LIBCOLOUR_CIEXYZ, libcolour_ciexyz_t)\
X(LIBCOLOUR_CIELAB, libcolour_cielab_t)\
X(LIBCOLOUR_CIELUV, libcolour_cieluv_t)\
- X(LIBCOLOUR_CIELCH, libcolour_cielch_t)\
+ X(LIBCOLOUR_CIELCHUV, libcolour_cielchuv_t)\
X(LIBCOLOUR_YIQ, libcolour_yiq_t)\
X(LIBCOLOUR_YDBDR, libcolour_ydbdr_t)\
X(LIBCOLOUR_YUV, libcolour_yuv_t)\
@@ -112,6 +112,7 @@ typedef enum libcolour_rgb_colour_space {
LIBCOLOUR_RGB_COLOUR_SPACE_DCI_P3_D65,
LIBCOLOUR_RGB_COLOUR_SPACE_DCI_P3_THEATER,
LIBCOLOUR_RGB_COLOUR_SPACE_DON_RGB_4,
+ LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB,
LIBCOLOUR_RGB_COLOUR_SPACE_ECI_RGB_V2,
LIBCOLOUR_RGB_COLOUR_SPACE_EKTA_SPACE_PS5,
LIBCOLOUR_RGB_COLOUR_SPACE_ITU_R_BT_601_625_LINE,
@@ -223,13 +224,13 @@ typedef struct libcolour_cieluv {
struct libcolour_ciexyz white;
} libcolour_cieluv_t;
-typedef struct libcolour_cielch {
+typedef struct libcolour_cielchuv {
enum libcolour_model model;
double L;
double C;
double h;
struct libcolour_ciexyz white;
-} libcolour_cielch_t;
+} libcolour_cielchuv_t;
typedef struct libcolour_rgb {
enum libcolour_model model;
@@ -270,7 +271,7 @@ typedef union libcolour_colour {
struct libcolour_ciexyz ciexyz;
struct libcolour_cielab cielab;
struct libcolour_cieluv cieluv;
- struct libcolour_cielch cielch;
+ struct libcolour_cielchuv cielchuv;
struct libcolour_yiq yiq;
struct libcolour_ydbdr ydbdr;
struct libcolour_yuv yuv;
diff --git a/src/test.c b/src/test.c
index 13f4e91..d7e8cf1 100644
--- a/src/test.c
+++ b/src/test.c
@@ -61,11 +61,11 @@ int test_convert(libcolour_colour_t* c1, libcolour_model_t model)
return -1;
return r1 & r2;
case LIBCOLOUR_CIELUV:
- case LIBCOLOUR_CIELCH:
- c2.cielch.white.model = LIBCOLOUR_CIEXYZ;
- c2.cielch.white.X = 1.0294;
- c2.cielch.white.Y = 1;
- c2.cielch.white.Z = 0.9118;
+ case LIBCOLOUR_CIELCHUV:
+ c2.cieluv.white.model = LIBCOLOUR_CIEXYZ;
+ c2.cieluv.white.X = 1.0294;
+ c2.cieluv.white.Y = 1;
+ c2.cieluv.white.Z = 0.9118;
return test_convert_(c1, &c2, &c3);
case LIBCOLOUR_CIEUVW:
c2.cieuvw.u0 = 0.37;
@@ -95,11 +95,11 @@ int test_convert_all(libcolour_model_t model, const char* model_name)
c1.srgb.with_gamma = 0;
break;
case LIBCOLOUR_CIELUV:
- case LIBCOLOUR_CIELCH:
- c1.cielch.white.model = LIBCOLOUR_CIEXYZ;
- c1.cielch.white.X = 1.0294;
- c1.cielch.white.Y = 1;
- c1.cielch.white.Z = 0.9118;
+ case LIBCOLOUR_CIELCHUV:
+ c1.cieluv.white.model = LIBCOLOUR_CIEXYZ;
+ c1.cieluv.white.X = 1.0294;
+ c1.cieluv.white.Y = 1;
+ c1.cieluv.white.Z = 0.9118;
break;
case LIBCOLOUR_CIEUVW:
c1.cieuvw.u0 = 0.37;