[babl] babl: code handling ICC v4, CIE TRC formulas
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] babl: code handling ICC v4, CIE TRC formulas
- Date: Fri, 7 Aug 2020 21:14:02 +0000 (UTC)
commit f25c510ae26866b2a7261428b373e38ffaa8dda5
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Aug 7 23:12:15 2020 +0200
babl: code handling ICC v4, CIE TRC formulas
babl/babl-icc.c | 24 ++++++++++++---
babl/babl-internal.h | 2 ++
babl/babl-trc.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++
babl/babl-trc.h | 3 +-
4 files changed, 108 insertions(+), 5 deletions(-)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index aa5a3862d..7d1fd6705 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -384,9 +384,27 @@ babl_trc_from_icc (ICC *state,
g = icc_read (s15f16, offset + 12 + 4 * 0);
return babl_trc_gamma (g);
break;
+ case 1:
+ {
+ float a,b,c;
+ g = icc_read (s15f16, offset + 12 + 4 * 0);
+ a = icc_read (s15f16, offset + 12 + 4 * 1);
+ b = icc_read (s15f16, offset + 12 + 4 * 2);
+ c = 0;
+ return babl_trc_formula_cie (g, a, b, c);
+ }
+ case 2:
+ {
+ float a,b,c;
+ g = icc_read (s15f16, offset + 12 + 4 * 0);
+ a = icc_read (s15f16, offset + 12 + 4 * 1);
+ b = icc_read (s15f16, offset + 12 + 4 * 2);
+ c = icc_read (s15f16, offset + 12 + 4 * 3);
+ return babl_trc_formula_cie (g, a, b, c);
+ }
case 3:
{
- float a,b,c,d, e, f;
+ float a,b,c,d,e,f;
g = icc_read (s15f16, offset + 12 + 4 * 0);
a = icc_read (s15f16, offset + 12 + 4 * 1);
b = icc_read (s15f16, offset + 12 + 4 * 2);
@@ -408,8 +426,6 @@ babl_trc_from_icc (ICC *state,
f = icc_read (s15f16, offset + 12 + 4 * 6);
return babl_trc_formula_srgb (g, a, b, c, d, e, f);
}
- case 1: // NYI
- case 2: // NYI - can share code, like srgb formulas
default:
*error = "unhandled parametric TRC";
fprintf (stderr, "unhandled parametric TRC type %i\n", function_type);
@@ -534,6 +550,7 @@ switch (trc->type)
break;
}
case BABL_TRC_FORMULA_SRGB:
+ case BABL_TRC_FORMULA_CIE:
{
int lut_size = 512;
if (flags == BABL_ICC_COMPACT_TRC_LUT)
@@ -671,7 +688,6 @@ babl_space_to_icc_rgb (const Babl *babl,
icc_write (u8, state->o + 12 + i, description[i]);
}
-
icc_write (u32, 0, state->no + 0);
length = state->no + 0;
}
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 1efdb0f2f..56e95e4a2 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -386,6 +386,8 @@ babl_conversion_create_name (Babl *source, Babl *destination, int type,
void _babl_space_add_universal_rgb (const Babl *space);
const Babl *
babl_trc_formula_srgb (double gamma, double a, double b, double c, double d, double e, double f);
+const Babl *
+babl_trc_formula_cie (double gamma, double a, double b, double c);
const Babl *babl_space_match_trc_matrix (const Babl *trc_red,
diff --git a/babl/babl-trc.c b/babl/babl-trc.c
index b1ba8a81b..d8a69dd21 100644
--- a/babl/babl-trc.c
+++ b/babl/babl-trc.c
@@ -200,6 +200,44 @@ _babl_trc_formula_srgb_to_linear (const Babl *trc_,
}
return c * x + f;
}
+static inline float
+_babl_trc_formula_cie_from_linear (const Babl *trc_,
+ float value)
+{
+ BablTRC *trc = (void*)trc_;
+ float x= value;
+ float a = trc->lut[1];
+ float b = trc->lut[2];
+ float c = trc->lut[3];
+
+ if (x > c)
+ {
+ float v = _babl_trc_gamma_from_linear ((Babl *) trc, x - c);
+ v = (v-b)/a;
+ if (v < 0.0 || v >= 0.0)
+ return v;
+ }
+ return 0.0;
+}
+
+static inline float
+_babl_trc_formula_cie_to_linear (const Babl *trc_,
+ float value)
+{
+ BablTRC *trc = (void*)trc_;
+ float x= value;
+ float a = trc->lut[1];
+ float b = trc->lut[2];
+ float c = trc->lut[3];
+
+ if (x >= -b / a)
+ {
+ return _babl_trc_gamma_to_linear ((Babl *) trc, a * x + b) + c;
+ }
+ return c;
+}
+
+
static inline float
_babl_trc_srgb_to_linear (const Babl *trc_,
@@ -421,6 +459,33 @@ babl_trc_new (const char *name,
trc_db[i].poly_gamma_from_linear_x1,
POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
break;
+ case BABL_TRC_FORMULA_CIE:
+ trc_db[i].lut = babl_calloc (sizeof (float), 4);
+ {
+ int j;
+ for (j = 0; j < 4; j++)
+ trc_db[i].lut[j] = lut[j];
+ }
+ trc_db[i].fun_to_linear = _babl_trc_formula_cie_to_linear;
+ trc_db[i].fun_from_linear = _babl_trc_formula_cie_from_linear;
+
+ trc_db[i].poly_gamma_to_linear_x0 = lut[4];
+ trc_db[i].poly_gamma_to_linear_x1 = POLY_GAMMA_X1;
+ babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_to_linear,
+ trc_db[i].gamma,
+ trc_db[i].poly_gamma_to_linear_x0,
+ trc_db[i].poly_gamma_to_linear_x1,
+ POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+
+ trc_db[i].poly_gamma_from_linear_x0 = lut[3] * lut[4];
+ trc_db[i].poly_gamma_from_linear_x1 = POLY_GAMMA_X1;
+ babl_polynomial_approximate_gamma (&trc_db[i].poly_gamma_from_linear,
+ trc_db[i].rgamma,
+ trc_db[i].poly_gamma_from_linear_x0,
+ trc_db[i].poly_gamma_from_linear_x1,
+ POLY_GAMMA_DEGREE, POLY_GAMMA_SCALE);
+ break;
+
case BABL_TRC_FORMULA_SRGB:
trc_db[i].lut = babl_calloc (sizeof (float), 7);
{
@@ -510,6 +575,25 @@ babl_trc_formula_srgb (double g,
return babl_trc_new (name, BABL_TRC_FORMULA_SRGB, g, 0, params);
}
+const Babl *
+babl_trc_formula_cie (double g,
+ double a,
+ double b,
+ double c)
+{
+ char name[128];
+ int i;
+ float params[4]={g, a, b, c};
+
+ snprintf (name, sizeof (name), "%.6f %.6f %.4f %.4f", g, a, b, c);
+ for (i = 0; name[i]; i++)
+ if (name[i] == ',') name[i] = '.';
+ while (name[strlen(name)-1]=='0')
+ name[strlen(name)-1]='\0';
+ return babl_trc_new (name, BABL_TRC_FORMULA_CIE, g, 0, params);
+}
+
+
const Babl *
babl_trc_gamma (double gamma)
{
diff --git a/babl/babl-trc.h b/babl/babl-trc.h
index 380a73610..cfe742c60 100644
--- a/babl/babl-trc.h
+++ b/babl/babl-trc.h
@@ -30,7 +30,8 @@ typedef enum {BABL_TRC_LINEAR,
BABL_TRC_FORMULA_GAMMA,
BABL_TRC_SRGB,
BABL_TRC_FORMULA_SRGB,
- BABL_TRC_LUT}
+ BABL_TRC_LUT,
+ BABL_TRC_FORMULA_CIE}
BablTRCType;
typedef struct
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]