aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libclut.c80
-rw-r--r--src/libclut.h175
2 files changed, 185 insertions, 70 deletions
diff --git a/src/libclut.c b/src/libclut.c
index 0a1b2f4..8963a4d 100644
--- a/src/libclut.c
+++ b/src/libclut.c
@@ -24,9 +24,9 @@
* @param c The linear RGB value.
* @return Corresponding sRGB value.
*/
-double libclut_model_linear_to_standard1(double c)
+double (libclut_model_linear_to_standard1)(double c)
{
- return (c <= 0.0031308) ? (12.92 * c) : ((1.0 + 0.055) * pow(c, 1.0 / 2.4));
+ return libclut_model_linear_to_standard1(c);
}
@@ -40,11 +40,9 @@ double libclut_model_linear_to_standard1(double c)
* @param b Pointer to the linear blue component,
* and output parameter for the blue component.
*/
-void libclut_model_linear_to_standard(double* r, double* g, double* b)
+void (libclut_model_linear_to_standard)(double* r, double* g, double* b)
{
- *r = libclut_model_linear_to_standard1(*r);
- *g = libclut_model_linear_to_standard1(*g);
- *b = libclut_model_linear_to_standard1(*b);
+ libclut_model_linear_to_standard(r, g, b);
}
@@ -54,9 +52,9 @@ void libclut_model_linear_to_standard(double* r, double* g, double* b)
* @param c The sRGB value.
* @return Corresponding linear RGB value.
*/
-double libclut_model_standard_to_linear1(double c)
+double (libclut_model_standard_to_linear1)(double c)
{
- return (c <= 0.04045) ? (c / 12.92) : pow((c + 0.055) / (1.0 + 0.055), 2.4);
+ return libclut_model_standard_to_linear1(c);
}
@@ -70,11 +68,9 @@ double libclut_model_standard_to_linear1(double c)
* @param b Pointer to the blue component, and output
* parameter for the linear blue component.
*/
-void libclut_model_standard_to_linear(double* r, double* g, double* b)
+void (libclut_model_standard_to_linear)(double* r, double* g, double* b)
{
- *r = libclut_model_standard_to_linear1(*r);
- *g = libclut_model_standard_to_linear1(*g);
- *b = libclut_model_standard_to_linear1(*b);
+ libclut_model_standard_to_linear(r, g, b);
}
@@ -87,10 +83,9 @@ void libclut_model_standard_to_linear(double* r, double* g, double* b)
* @param X Output parameter for the X parameter.
* @param Z Output parameter for the Z parameter.
*/
-void libclut_model_ciexyy_to_ciexyz(double x, double y, double Y, double* X, double* Z)
+void (libclut_model_ciexyy_to_ciexyz)(double x, double y, double Y, double* X, double* Z)
{
- *X = (y == 0.0) ? Y : (Y * x / y);
- *Z = (y == 0.0) ? Y : (Y * (1 - x - y) / y);
+ libclut_model_ciexyy_to_ciexyz(x, y, Y, X, Z);
}
@@ -103,13 +98,9 @@ void libclut_model_ciexyy_to_ciexyz(double x, double y, double Y, double* X, dou
* @param x Output parameter for the x parameter.
* @param y Output parameter for the y parameter.
*/
-void libclut_model_ciexyz_to_ciexyy(double X, double Y, double Z, double* x, double* y)
+void (libclut_model_ciexyz_to_ciexyy)(double X, double Y, double Z, double* x, double* y)
{
- double s = X + Y + Z;
- if (s == 0.0)
- *x = *y = 0.0;
- else
- *x = X / s, *y = Y / s;
+ libclut_model_ciexyz_to_ciexyy(X, Y, Z, x, y);
}
@@ -123,11 +114,9 @@ void libclut_model_ciexyz_to_ciexyy(double X, double Y, double Z, double* x, dou
* @param g Output parameter for the green component.
* @param b Output parameter for the blue component.
*/
-void libclut_model_ciexyz_to_linear(double X, double Y, double Z, double* r, double* g, double* b)
+void (libclut_model_ciexyz_to_linear)(double X, double Y, double Z, double* r, double* g, double* b)
{
- *r = ( 3.2404500 * X) + (-1.537140 * Y) + (-0.4985320 * Z);
- *g = (-0.9692660 * X) + ( 1.876010 * Y) + ( 0.0415561 * Z);
- *b = ( 0.0556434 * X) + (-0.204026 * Y) + ( 1.0572300 * Z);
+ libclut_model_ciexyz_to_linear(X, Y, Z, r, g, b);
}
@@ -141,11 +130,9 @@ void libclut_model_ciexyz_to_linear(double X, double Y, double Z, double* r, dou
* @param Y Output parameter for the Y parameter.
* @param Z Output parameter for the Z parameter.
*/
-void libclut_model_linear_to_ciexyz(double r, double g, double b, double* X, double* Y, double* Z)
+void (libclut_model_linear_to_ciexyz)(double r, double g, double b, double* X, double* Y, double* Z)
{
- *X = (0.4124564 * r) + (0.3575761 * g) + (0.1804375 * b);
- *Y = (0.2126729 * r) + (0.7151522 * g) + (0.0721750 * b);
- *Z = (0.0193339 * r) + (0.1191920 * g) + (0.9503041 * b);
+ libclut_model_linear_to_ciexyz(r, g, b, X, Y, Z);
}
@@ -159,12 +146,9 @@ void libclut_model_linear_to_ciexyz(double r, double g, double b, double* X, dou
* @param y Output parameter for the y parameter.
* @param Y Output parameter for the Y parameter.
*/
-void libclut_model_srgb_to_ciexyy(double r, double g, double b, double* x, double* y, double* Y)
+void (libclut_model_srgb_to_ciexyy)(double r, double g, double b, double* x, double* y, double* Y)
{
- double X, Z;
- libclut_model_standard_to_linear(&r, &g, &b);
- libclut_model_linear_to_ciexyz(r, g, b, &X, Y, &Z);
- libclut_model_ciexyz_to_ciexyy(X, *Y, Z, x, y);
+ libclut_model_srgb_to_ciexyy(r, g, b, x, y, Y);
}
@@ -178,12 +162,9 @@ void libclut_model_srgb_to_ciexyy(double r, double g, double b, double* x, doubl
* @param g Output parameter for the green component.
* @param b Output parameter for the blue component.
*/
-void libclut_model_ciexyy_to_srgb(double x, double y, double Y, double* r, double* g, double* b)
+void (libclut_model_ciexyy_to_srgb)(double x, double y, double Y, double* r, double* g, double* b)
{
- double X, Z;
- libclut_model_ciexyy_to_ciexyz(x, y, Y, &X, &Z);
- libclut_model_ciexyz_to_linear(X, Y, Z, r, g, b);
- libclut_model_linear_to_standard(r, g, b);
+ libclut_model_ciexyy_to_srgb(x, y, Y, r, g, b);
}
@@ -197,15 +178,9 @@ void libclut_model_ciexyy_to_srgb(double x, double y, double Y, double* r, doubl
* @param a Output parameter for the a* component.
* @param b Output parameter for the b* component.
*/
-void libclut_model_ciexyz_to_cielab(double X, double Y, double Z, double* L, double* a, double* b)
+void (libclut_model_ciexyz_to_cielab)(double X, double Y, double Z, double* L, double* a, double* b)
{
-#define F(C) ((C) > 0.00885642) ? pow((C), 1.0 / 3.0) : ((7.78 + 703.0 / 99900.0) * (C) + 0.1379310)
- X /= 0.95047, Z /= 1.08883;
- X = F(X), Y = F(Y), Z = F(Z);
- *L = 116.0 * Y - 16.0;
- *a = 500.0 * (X - Y);
- *b = 200.0 * (Y - Z);
-#undef F
+ libclut_model_ciexyz_to_cielab(X, Y, Z, L, a, b);
}
@@ -219,15 +194,8 @@ void libclut_model_ciexyz_to_cielab(double X, double Y, double Z, double* L, dou
* @param Y Output parameter for the Y parameter.
* @param Z Output parameter for the Z parameter.
*/
-void libclut_model_cielab_to_xiexyz(double L, double a, double b, double* X, double* Y, double* Z)
+void (libclut_model_cielab_to_ciexyz)(double L, double a, double b, double* X, double* Y, double* Z)
{
-#define F(C) (((C)*(C)*(C) > 0.00885642) ? ((C)*(C)*(C)) : (((C) - 0.1379310) / (7.78 + 703.0 / 99900.0)))
- *Y = (L + 16.0) / 116.0;
- *X = a / 500.0 + *Y;
- *Z = *Y - b / 200.0;
- *X = F(*X) * 0.95047;
- *Y = F(*Y);
- *Z = F(*Z) * 1.08883;
-#undef F
+ libclut_model_cielab_to_ciexyz(L, a, b, X, Y, Z);
}
diff --git a/src/libclut.h b/src/libclut.h
index e2feb50..c2f31de 100644
--- a/src/libclut.h
+++ b/src/libclut.h
@@ -134,7 +134,8 @@
*
* None of the parameter may have side-effects.
*
- * Requires linking with '-lclut'.
+ * Requires linking with '-lclut', or '-lm' if
+ * `libclut_model_standard_to_linear1` is not undefined.
*
* @param clut Pointer to the gamma ramps, must have the arrays
* `red`, `green`, and `blue`, and the scalars
@@ -165,7 +166,8 @@
*
* None of the parameter may have side-effects.
*
- * Requires linking with '-lclut'.
+ * Requires linking with '-lclut', or '-lm' if
+ * `libclut_model_linear_to_standard1` is not undefined.
*
* @param clut Pointer to the gamma ramps, must have the arrays
* `red`, `green`, and `blue`, and the scalars
@@ -930,15 +932,25 @@
/**
* Convert one component from [0, 1] linear RGB to [0, 1] sRGB.
*
+ * If the macro variant is used, the argument must not have
+ * any side-effects. The macro variant requires linking with
+ * '-lm'.
+ *
* @param c The linear RGB value.
* @return Corresponding sRGB value.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__const__, __leaf__)))
-double libclut_model_linear_to_standard1(double);
+double (libclut_model_linear_to_standard1)(double);
+#define libclut_model_linear_to_standard1(c) \
+ (((double)(c) <= 0.0031308) ? (12.92 * (double)(c)) : ((1.0 + 0.055) * pow((double)(c), 1.0 / 2.4)))
/**
* Convert [0, 1] linear RGB to [0, 1] sRGB.
*
+ * The macro variant requires linking with '-lm',
+ * if the 'libclut_model_linear_to_standard1' is defined,
+ * otherwise it requires linking with '-lclut'.
+ *
* @param r Pointer to the linear red component,
* and output parameter for the red component.
* @param g Pointer to the linear green component,
@@ -946,20 +958,39 @@ double libclut_model_linear_to_standard1(double);
* @param b Pointer to the linear blue component,
* and output parameter for the blue component.
*/
-void libclut_model_linear_to_standard(double*, double*, double*);
+void (libclut_model_linear_to_standard)(double*, double*, double*);
+#define libclut_model_linear_to_standard(r, g, b) \
+ do \
+ { \
+ double *r__ = (r), *g__ = (g), *b__ = (b); \
+ *r__ = libclut_model_linear_to_standard1(*r__); \
+ *g__ = libclut_model_linear_to_standard1(*g__); \
+ *b__ = libclut_model_linear_to_standard1(*b__); \
+ } \
+ while (0)
/**
* Convert one component from [0, 1] sRGB to [0, 1] linear RGB.
*
+ * If the macro variant is used, the argument must not have
+ * any side-effects. The macro variant requires linking with
+ * '-lm'.
+ *
* @param c The sRGB value.
* @return Corresponding linear RGB value.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__const__, __leaf__)))
-double libclut_model_standard_to_linear1(double);
+double (libclut_model_standard_to_linear1)(double);
+#define libclut_model_standard_to_linear1(c) \
+ (((double)(c) <= 0.04045) ? ((double)(c) / 12.92) : pow(((double)(c) + 0.055) / (1.0 + 0.055), 2.4))
/**
* Convert [0, 1] sRGB to [0, 1] linear RGB.
*
+ * The macro variant requires linking with '-lm',
+ * if the 'libclut_model_standard_to_linear1' is defined,
+ * otherwise it requires linking with '-lclut'.
+ *
* @param r Pointer to the red component, and output
* parameter for the linear red component.
* @param g Pointer to the green component, and output
@@ -967,7 +998,16 @@ double libclut_model_standard_to_linear1(double);
* @param b Pointer to the blue component, and output
* parameter for the linear blue component.
*/
-void libclut_model_standard_to_linear(double*, double*, double*);
+void (libclut_model_standard_to_linear)(double*, double*, double*);
+#define libclut_model_standard_to_linear(r, g, b) \
+ do \
+ { \
+ double *r__ = (r), *g__ = (g), *b__ = (b); \
+ *r__ = libclut_model_standard_to_linear1(*r__); \
+ *g__ = libclut_model_standard_to_linear1(*g__); \
+ *b__ = libclut_model_standard_to_linear1(*b__); \
+ } \
+ while (0)
/**
* Convert CIE xyY to CIE XYZ.
@@ -979,7 +1019,15 @@ void libclut_model_standard_to_linear(double*, double*, double*);
* @param Z Output parameter for the Z parameter.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_ciexyy_to_ciexyz(double, double, double, double*, double*);
+void (libclut_model_ciexyy_to_ciexyz)(double, double, double, double*, double*);
+#define libclut_model_ciexyy_to_ciexyz(x, y, Y, X, Z) \
+ do \
+ { \
+ double x__ = (x), y__ = (y), Y__ = (Y), *X__ = (X), *Z__ = (Z); \
+ *X__ = (y__ == 0.0) ? Y__ : (Y__ * x__ / y__); \
+ *Z__ = (y__ == 0.0) ? Y__ : (Y__ * (1.0 - x__ - y__) / y__); \
+ } \
+ while (0)
/**
* Convert CIE XYZ to CIE xyY.
@@ -991,7 +1039,18 @@ void libclut_model_ciexyy_to_ciexyz(double, double, double, double*, double*);
* @param y Output parameter for the y parameter.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_ciexyz_to_ciexyy(double, double, double, double*, double*);
+void (libclut_model_ciexyz_to_ciexyy)(double, double, double, double*, double*);
+#define libclut_model_ciexyz_to_ciexyy(X, Y, Z, x, y) \
+ do \
+ { \
+ double X__ = (X), Y__ = (Y), Z__ = (Z), *x__ = (x), *y__ = (y); \
+ double s__ = X__ + Y__ + Z__; \
+ if (s__ == 0.0) \
+ *x__ = *y__ = 0.0; \
+ else \
+ *x__ = X__ / s__, *y__ = Y__ / s__; \
+ } \
+ while (0)
/**
* Convert CIE XYZ to [0, 1] linear RGB.
@@ -1004,7 +1063,16 @@ void libclut_model_ciexyz_to_ciexyy(double, double, double, double*, double*);
* @param b Output parameter for the blue component.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_ciexyz_to_linear(double, double, double, double*, double*, double*);
+void (libclut_model_ciexyz_to_linear)(double, double, double, double*, double*, double*);
+#define libclut_model_ciexyz_to_linear(X, Y, Z, r, g, b) \
+ do \
+ { \
+ double X__ = (X), Y__ = (Y), Z__ = (Z); \
+ *(r) = ( 3.2404500 * X__) + (-1.537140 * Y__) + (-0.4985320 * Z__); \
+ *(g) = (-0.9692660 * X__) + ( 1.876010 * Y__) + ( 0.0415561 * Z__); \
+ *(b) = ( 0.0556434 * X__) + (-0.204026 * Y__) + ( 1.0572300 * Z__); \
+ } \
+ while (0)
/**
* Convert [0, 1] linear RGB to CIE XYZ.
@@ -1017,11 +1085,28 @@ void libclut_model_ciexyz_to_linear(double, double, double, double*, double*, do
* @param Z Output parameter for the Z parameter.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_linear_to_ciexyz(double, double, double, double*, double*, double*);
+void (libclut_model_linear_to_ciexyz)(double, double, double, double*, double*, double*);
+#define libclut_model_linear_to_ciexyz(r, g, b, X, Y, Z) \
+ do \
+ { \
+ double r__ = (r), g__ = (g), b__ = (b); \
+ *(X) = (0.4124564 * r__) + (0.3575761 * g__) + (0.1804375 * b__); \
+ *(Y) = (0.2126729 * r__) + (0.7151522 * g__) + (0.0721750 * b__); \
+ *(Z) = (0.0193339 * r__) + (0.1191920 * g__) + (0.9503041 * b__); \
+ } \
+ while (0)
/**
* Convert [0, 1] linear RGB to CIE xyY.
*
+ * The macro variant requires linking with '-lclut'
+ * if any of `libclut_model_ciexyz_to_ciexyy`,
+ * `libclut_model_linear_to_ciexyz`, and
+ * `libclut_model_standard_to_linear` are undefined.
+ * The macro variant requires linking with '-lm' if
+ * neither `libclut_model_standard_to_linear` nor
+ * `libclut_model_standard_to_linear1` are undefined.
+ *
* @param r The red component.
* @param g The green component.
* @param b The blue component.
@@ -1029,11 +1114,30 @@ void libclut_model_linear_to_ciexyz(double, double, double, double*, double*, do
* @param y Output parameter for the y parameter.
* @param Y Output parameter for the Y parameter.
*/
-void libclut_model_srgb_to_ciexyy(double, double, double, double*, double*, double*);
+void (libclut_model_srgb_to_ciexyy)(double, double, double, double*, double*, double*);
+#define libclut_model_srgb_to_ciexyy(r, g, b, x, y, Y) \
+ do \
+ { \
+ double r___ = (r), g___ = (g), b___ = (b); \
+ double *x___ = (x), *y___ = (y), *Y___ = (Y); \
+ double X___, Z___; \
+ libclut_model_standard_to_linear(&r___, &g___, &b___); \
+ libclut_model_linear_to_ciexyz(r___, g___, b___, &X___, Y___, &Z___); \
+ libclut_model_ciexyz_to_ciexyy(X___, *Y___, Z___, x___, y___); \
+ } \
+ while (0)
/**
* Convert CIE xyY to [0, 1] sRGB.
*
+ * The macro variant requires linking with '-lclut'
+ * if any of `libclut_model_ciexyy_to_ciexyz`,
+ * `libclut_model_ciexyz_to_linear`, and
+ * `libclut_model_linear_to_standard` are undefined.
+ * The macro variant requires linking with '-lm' if
+ * neither `libclut_model_linear_to_standard` nor
+ * `libclut_model_linear_to_standard1` are undefined.
+ *
* @param x The x parameter.
* @param y The y parameter.
* @param Y The Y parameter.
@@ -1041,11 +1145,24 @@ void libclut_model_srgb_to_ciexyy(double, double, double, double*, double*, doub
* @param g Output parameter for the green component.
* @param b Output parameter for the blue component.
*/
-void libclut_model_ciexyy_to_srgb(double, double, double, double*, double*, double*);
+void (libclut_model_ciexyy_to_srgb)(double, double, double, double*, double*, double*);
+#define libclut_model_ciexyy_to_srgb(x, y, Y, r, g, b) \
+ do \
+ { \
+ double x___ = (x), y___ = (y), Y___ = (Y); \
+ double *r___ = (r), *g___ = (g), *b___ = (b); \
+ double X___, Z___; \
+ libclut_model_ciexyy_to_ciexyz(x___, y___, Y___, &X___, &Z___); \
+ libclut_model_ciexyz_to_linear(X___, Y___, Z___, r___, g___, b___); \
+ libclut_model_linear_to_standard(r___, g___, b___); \
+ } \
+ while(0)
/**
* Convert from CIE XYZ to CIE L*a*b*.
*
+ * The macro variant requires linking with '-lm'.
+ *
* @param X The X parameter.
* @param Y The Y parameter.
* @param Z The Z parameter.
@@ -1054,7 +1171,22 @@ void libclut_model_ciexyy_to_srgb(double, double, double, double*, double*, doub
* @param b Output parameter for the b* component.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_ciexyz_to_cielab(double, double, double, double*, double*, double*);
+void (libclut_model_ciexyz_to_cielab)(double, double, double, double*, double*, double*);
+#define libclut_model_ciexyz_to_cielab(X, Y, Z, L, a, b) \
+ do \
+ { \
+ double X__ = (X), Y__ = (Y), Z__ = (Z); \
+ X__ /= 0.95047, Z__ /= 1.08883; \
+ X__ = LIBCLUT_MODEL_CIEXYZ_TO_CIELAB__(X__); \
+ Y__ = LIBCLUT_MODEL_CIEXYZ_TO_CIELAB__(Y__); \
+ Z__ = LIBCLUT_MODEL_CIEXYZ_TO_CIELAB__(Z__); \
+ *(L) = 116.0 * Y__ - 16.0; \
+ *(a) = 500.0 * (X__ - Y__); \
+ *(b) = 200.0 * (Y__ - Z__); \
+ } \
+ while (0)
+#define LIBCLUT_MODEL_CIEXYZ_TO_CIELAB__(C) \
+ (((C) > 0.00885642) ? pow((C), 1.0 / 3.0) : ((7.78 + 703.0 / 99900.0) * (C) + 0.1379310))
/**
* Convert from CIE L*a*b* to CIE XYZ.
@@ -1067,7 +1199,22 @@ void libclut_model_ciexyz_to_cielab(double, double, double, double*, double*, do
* @param Z Output parameter for the Z parameter.
*/
LIBCLUT_GCC_ONLY__(__attribute__((__leaf__)))
-void libclut_model_cielab_to_xiexyz(double, double, double, double*, double*, double*);
+void (libclut_model_cielab_to_ciexyz)(double, double, double, double*, double*, double*);
+#define libclut_model_cielab_to_ciexyz(L, a, b, X, Y, Z) \
+ do \
+ { \
+ double L__ = (L), a__ = (a), b__ = (b); \
+ double *X__ = (X), *Y__ = (Y), *Z__ = (Z); \
+ *Y__ = (L__ + 16.0) / 116.0; \
+ *X__ = a__ / 500.0 + *Y__; \
+ *Z__ = *Y__ - b__ / 200.0; \
+ *X__ = LIBCLUT_MODEL_CIELAB_TO_CIEXYZ__(*X__) * 0.95047; \
+ *Y__ = LIBCLUT_MODEL_CIELAB_TO_CIEXYZ__(*Y__); \
+ *Z__ = LIBCLUT_MODEL_CIELAB_TO_CIEXYZ__(*Z__) * 1.08883; \
+ } \
+ while (0)
+#define LIBCLUT_MODEL_CIELAB_TO_CIEXYZ__(C) \
+ (((C)*(C)*(C) > 0.00885642) ? ((C)*(C)*(C)) : (((C) - 0.1379310) / (7.78 + 703.0 / 99900.0)))