[babl] babl-icc: add support for some ICCv4 profiles
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] babl-icc: add support for some ICCv4 profiles
- Date: Fri, 1 Sep 2017 20:53:42 +0000 (UTC)
commit bb791e8e551aa920bfef565e9ba7b562aa8e4b89
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Sep 1 22:52:27 2017 +0200
babl-icc: add support for some ICCv4 profiles
RGB Matrix profiles with not too complex (or sRGB) parametric TRCs is what
should work fine.
babl/babl-icc.c | 119 +++++++++++++++++++++++++++++++++++++++++------------
babl/babl-space.h | 7 +++
2 files changed, 100 insertions(+), 26 deletions(-)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 41cee50..5ae66bc 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -305,6 +305,38 @@ static const Babl *babl_trc_from_icc (ICC *state, int offset,
{
int count = icc_read (u32, offset + 8);
int i;
+ if (!strcmp (state->data + offset, "para"))
+ {
+ int function_type = icc_read (u16, offset + 8);
+ float g;
+ switch (function_type)
+ {
+ case 0:
+ g = icc_read (s15f16, offset + 12 + 2 * 0);
+ return babl_trc_gamma (g);
+ break;
+
+ case 3:
+#if 0
+ float a,b,c,d,e,f;
+ g = icc_read (s15f16, offset + 12 + 2 * 0);
+ a = icc_read (s15f16, offset + 12 + 2 * 1);
+ b = icc_read (s15f16, offset + 12 + 2 * 2);
+ c = icc_read (s15f16, offset + 12 + 2 * 3);
+ d = icc_read (s15f16, offset + 12 + 2 * 4);
+ e = icc_read (s15f16, offset + 12 + 2 * 5);
+ f = icc_read (s15f16, offset + 12 + 2 * 6);
+#endif
+ return babl_trc ("sRGB"); // XXX: not true... and I suspect the CIE L* curve might be
expressed as this,
+ // formula as well, depending on arguments.
+ break;
+ default:
+ fprintf (stdout, "unhandled parametric TRC type %i\n", function_type);
+ return babl_trc_gamma (2.2);
+ break;
+ }
+ }
+ else
{
if (count == 0)
{
@@ -401,11 +433,11 @@ switch (trc->type)
}
break;
default:
- icc_allocate_tag (state, "rTRC", 14);
+ icc_allocate_tag (state, name, 14);
icc_write (sign, state->o, "curv");
icc_write (u32, state->o + 4, 0);
icc_write (u32, state->o + 8, 1);
- icc_write (u16, state->o + 12, 0);
+ icc_write (u8f8, state->o + 12, trc->gamma);
break;
}
}
@@ -423,10 +455,10 @@ const char *babl_space_to_icc (const Babl *babl, int *ret_length)
symmetry_test (state);
- icc_write (sign, 4, "babl"); // ICC verison
- icc_write (u8, 8, 2); // ICC verison
- icc_write (u8, 9, 0x20); // 2.2 for now..
- icc_write (u32,64, 0); // rendering intent
+ icc_write (sign, 4, "babl"); // ICC verison
+ icc_write (u8, 8, 2); // ICC verison
+ icc_write (u8, 9, 0x20); // 2.2 for now..
+ icc_write (u32,64, 0); // rendering intent
icc_write (s15f16,68, 0.96421); // Illuminant
icc_write (s15f16,72, 1.0);
@@ -438,12 +470,12 @@ const char *babl_space_to_icc (const Babl *babl, int *ret_length)
icc_write (sign, 16, "RGB ");
icc_write (sign, 20, "XYZ ");
- icc_write (u16, 24, 2222); // babl profiles
+ icc_write (u16, 24, 2222); // babl profiles
icc_write (u16, 26, 11); // should
- icc_write (u16, 28, 11); // use a fixed
+ icc_write (u16, 28, 11); // use a fixed
icc_write (u16, 30, 3); // date
- icc_write (u16, 32, 44); // that gets updated
- icc_write (u16, 34, 55); // when the generator
+ icc_write (u16, 32, 44); // that gets updated
+ icc_write (u16, 34, 55); // when the generator changes
icc_write (sign, 36, "acsp"); // changes
@@ -538,23 +570,27 @@ babl_space_from_icc (const char *icc_data,
int icc_length,
char **error)
{
- ICC *state = icc_state_new ((char*)icc_data, icc_length, 0);
-
- int profile_size = icc_read (u32, 0);
- int icc_ver_major = icc_read (u8, 8);
+ ICC *state = icc_state_new ((char*)icc_data, icc_length, 0);
+ int profile_size = icc_read (u32, 0);
+ //int icc_ver_major = icc_read (u8, 8);
const Babl *trc_red = NULL;
const Babl *trc_green = NULL;
const Babl *trc_blue = NULL;
+ char *descr = NULL;
+ char *copyright = NULL;
+
sign_t profile_class, color_space;
if (profile_size != icc_length)
{
*error = "icc profile length inconsistency";
}
+#if 0
else if (icc_ver_major > 2)
{
*error = "only ICC v2 profiles supported";
}
+#endif
else
{
profile_class = icc_read (sign, 12);
@@ -595,10 +631,31 @@ babl_space_from_icc (const char *icc_data,
return NULL;
}
+
+ {
+ int offset, element_size;
+ icc_tag (state, "desc", &offset, &element_size);
+ if (!strcmp (state->data + offset, "mluc"))
+ {
+ descr = babl_strdup ("[babl-icc doesnt decode unicode]");
+ }
+ else
+ if (!strcmp (state->data + offset, "desc"))
+ {
+ descr = babl_strdup (state->data + offset + 12);
+ }
+ }
+
+ {
+ int offset, element_size;
+ icc_tag (state, "cprt", &offset, &element_size);
+ copyright = babl_strdup (state->data + offset + 8);
+ }
+
if (icc_tag (state, "rXYZ", NULL, NULL) &&
- icc_tag (state, "gXYZ", NULL, NULL) &&
- icc_tag (state, "bXYZ", NULL, NULL) &&
- icc_tag (state, "wtpt", NULL, NULL))
+ icc_tag (state, "gXYZ", NULL, NULL) &&
+ icc_tag (state, "bXYZ", NULL, NULL) &&
+ icc_tag (state, "wtpt", NULL, NULL))
{
int offset, element_size;
double rx, gx, bx;
@@ -623,15 +680,20 @@ babl_space_from_icc (const char *icc_data,
wX = icc_read (s15f16, offset + 8);
wY = icc_read (s15f16, offset + 8 + 4);
wZ = icc_read (s15f16, offset + 8 + 4 * 2);
-
+
babl_free (state);
- return babl_space_from_rgbxyz_matrix (NULL,
+ {
+ Babl *ret = (void*)babl_space_from_rgbxyz_matrix (NULL,
wX, wY, wZ,
rx, gx, bx,
ry, gy, by,
rz, gz, bz,
trc_red, trc_green, trc_blue);
+ ret->space.description = descr;
+ ret->space.copyright = copyright;
+ return ret;
+ }
}
else if (icc_tag (state, "chrm", NULL, NULL) &&
icc_tag (state, "wtpt", NULL, NULL))
@@ -669,13 +731,18 @@ babl_space_from_icc (const char *icc_data,
double wZ = icc_read (s15f16, offset + 8 + 4 * 2);
babl_free (state);
- return babl_space_from_chromaticities (NULL,
+ {
+ Babl *ret = (void*) babl_space_from_chromaticities (NULL,
wX / (wX + wY + wZ),
wY / (wX + wY + wZ),
red_x, red_y,
green_x, green_y,
blue_x, blue_y,
trc_red, trc_green, trc_blue);
+ ret->space.description = descr;
+ ret->space.copyright = copyright;
+ return ret;
+ }
}
}
@@ -689,22 +756,22 @@ static void symmetry_test (ICC *state)
{
icc_write (s8, 8,-2);
assert (icc_read (s8, 8) == -2);
- icc_write (s8, 8, 3); // ICC verison
+ icc_write (s8, 8, 3);
assert (icc_read (s8, 8) == 3);
- icc_write (u8, 8, 2); // ICC verison
+ icc_write (u8, 8, 2);
assert (icc_read (u8, 8) == 2);
- icc_write (u16, 8, 3); // ICC verison
+ icc_write (u16, 8, 3);
assert (icc_read (u16, 8) == 3);
- icc_write (s16, 8, -3); // ICC verison
+ icc_write (s16, 8, -3);
assert (icc_read (s16, 8) == -3);
- icc_write (s16, 8, 9); // ICC verison
+ icc_write (s16, 8, 9);
assert (icc_read (s16, 8) == 9);
- icc_write (u32, 8, 4); // ICC verison
+ icc_write (u32, 8, 4);
assert (icc_read (u32, 8) == 4);
}
diff --git a/babl/babl-space.h b/babl/babl-space.h
index c256ac2..b899f41 100644
--- a/babl/babl-space.h
+++ b/babl/babl-space.h
@@ -56,6 +56,13 @@ typedef struct
/* and before converting a span, all that needs to be
rigged is merging matrices */
+ /* we should here also add more things read from ICC profile,
+ * making it possible to round-trip data. Unless it is sRGB, when
+ * standard should win.
+ */
+
+ char *description; /* meta data possibly read from ICC */
+ char *copyright;
} BablSpace;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]