[babl] babl-icc: create struct for abstracting ICC file access
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] babl-icc: create struct for abstracting ICC file access
- Date: Wed, 23 Aug 2017 17:55:50 +0000 (UTC)
commit 1d31fd12c0edaa3d21e2fb53e56ebf613cc9dee5
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Aug 23 19:53:43 2017 +0200
babl-icc: create struct for abstracting ICC file access
This also makes the ICC parsing re-entrant by getting rid of global variables.
babl/babl-icc.c | 349 +++++++++++++++++++++++++++-----------------------
babl/babl-internal.h | 9 +-
babl/babl-trc.c | 19 ++-
babl/babl-trc.h | 22 +++-
babl/babl.h | 5 +-
5 files changed, 233 insertions(+), 171 deletions(-)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 2c6a2a0..69f0df0 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -21,6 +21,31 @@
#include <stdio.h>
#include <stdlib.h>
+typedef struct ICC {
+ char *data;
+ int length;
+
+ int tags;
+ int headpos;
+ int o, no;
+ int p;
+ int psize;
+} ICC;
+
+ICC *icc_state_new (char *data, int length, int tags);
+
+ICC *icc_state_new (char *data, int length, int tags)
+{
+ ICC *ret = babl_calloc (sizeof (ICC), 1);
+ ret->data = data;
+ ret->length = length;
+ ret->tags = tags;
+
+ return ret;
+}
+
+
+
#define ICC_HEADER_LEN 128
#define TAG_COUNT_OFF ICC_HEADER_LEN
@@ -38,81 +63,81 @@ typedef struct {
char str[5];
} sign_t;
-#define icc_write(type, offset, value) write_##type(icc,length,offset,value)
-#define icc_read(type, offset) read_##type(icc,length,offset)
+#define icc_write(type, offset, value) write_##type(state,offset,value)
+#define icc_read(type, offset) read_##type(state,offset)
-static void write_u8 (char *icc, int length, int offset, uint8_t value)
+static void write_u8 (ICC *state, int offset, uint8_t value)
{
- if (offset < 0 || offset > length)
+ if (offset < 0 || offset >= state->length)
return;
- *(uint8_t*) (&icc[offset]) = value;
+ *(uint8_t*) (&state->data[offset]) = value;
}
-static void write_s8 (char *icc, int length, int offset, int8_t value)
+static void write_s8 (ICC *state, int offset, int8_t value)
{
- if (offset < 0 || offset > length)
+ if (offset < 0 || offset >= state->length)
return;
- *(int8_t*) (&icc[offset]) = value;
+ *(int8_t*) (&state->data[offset]) = value;
}
-static int read_u8 (const char *icc, int length, int offset)
+static int read_u8 (ICC *state, int offset)
{
/* all reading functions take both the char *pointer and the length of the
* buffer, and all reads thus gets protected by this condition.
*/
- if (offset < 0 || offset > length)
+ if (offset < 0 || offset > state->length)
return 0;
- return *(uint8_t*) (&icc[offset]);
+ return *(uint8_t*) (&state->data[offset]);
}
-static int read_s8 (const char *icc, int length, int offset)
+static int read_s8 (ICC *state, int offset)
{
- if (offset < 0 || offset > length)
+ if (offset < 0 || offset > state->length)
return 0;
- return *(int8_t*) (&icc[offset]);
+ return *(int8_t*) (&state->data[offset]);
}
-static void write_s16 (char *icc, int length, int offset, int16_t value)
+static void write_s16 (ICC *state, int offset, int16_t value)
{
- write_s8 (icc, length, offset + 0, value >> 8);
- write_u8 (icc, length, offset + 1, value & 0xff);
+ write_s8 (state, offset + 0, value >> 8);
+ write_u8 (state, offset + 1, value & 0xff);
}
-static int16_t read_s16 (const char *icc, int length, int offset)
+static int16_t read_s16 (ICC *state, int offset)
{
return icc_read (u8, offset + 1) +
- (read_s8 (icc, length, offset + 0) << 8);
+ (read_s8 (state, offset + 0) << 8); //XXX: transform to icc_read macro
}
-static uint16_t read_u16 (const char *icc, int length, int offset)
+static uint16_t read_u16 (ICC *state, int offset)
{
return icc_read (u8, offset + 1) +
(icc_read (u8, offset + 0) << 8);
}
-static void write_u16 (char *icc, int length, int offset, uint16_t value)
+static void write_u16 (ICC *state, int offset, uint16_t value)
{
- write_u8 (icc, length, offset + 0, value >> 8);
- write_u8 (icc, length, offset + 1, value & 0xff);
+ write_u8 (state, offset + 0, value >> 8);
+ write_u8 (state, offset + 1, value & 0xff);
}
-static u8f8_t read_u8f8_ (const char *icc, int length, int offset)
+static u8f8_t read_u8f8_ (ICC *state, int offset)
{
u8f8_t ret ={icc_read (u8, offset),
icc_read (u8, offset + 1)};
return ret;
}
-static s15f16_t read_s15f16_ (const char *icc, int length, int offset)
+static s15f16_t read_s15f16_ (ICC *state, int offset)
{
s15f16_t ret ={icc_read (s16, offset),
icc_read (u16, offset + 2)};
return ret;
}
-static void write_s15f16_ (char *icc, int length, int offset, s15f16_t val)
+static void write_s15f16_ (ICC *state, int offset, s15f16_t val)
{
icc_write (s16, offset, val.integer),
icc_write (u16, offset + 2, val.fraction);
@@ -136,19 +161,19 @@ static double u8f8_to_d (u8f8_t fix)
return fix.integer + fix.fraction / 255.0;
}
-static void write_s15f16 (char *icc, int length, int offset, double value)
+static void write_s15f16 (ICC *state, int offset, double value)
{
- write_s15f16_ (icc, length, offset, d_to_s15f16 (value));
+ write_s15f16_ (state, offset, d_to_s15f16 (value));
}
-static double read_s15f16 (const char *icc, int length, int offset)
+static double read_s15f16 (ICC *state, int offset)
{
- return s15f16_to_d (read_s15f16_ (icc, length, offset));
+ return s15f16_to_d (read_s15f16_ (state, offset));
}
-static double read_u8f8 (const char *icc, int length, int offset)
+static double read_u8f8 (ICC *state, int offset)
{
- return u8f8_to_d (read_u8f8_ (icc, length, offset));
+ return u8f8_to_d (read_u8f8_ (state, offset));
}
static inline void print_u8f8 (u8f8_t fix)
@@ -195,22 +220,19 @@ static inline void print_s15f16 (s15f16_t fix)
}
}
-static void write_u32 (char *icc,
- int length,
- int offset,
- uint32_t value)
+static void write_u32 (ICC *state, int offset, uint32_t value)
{
int i;
for (i = 0; i < 4; i ++)
{
- write_u8 (icc, length, offset + i,
+ write_u8 (state, offset + i,
(value & 0xff000000) >> 24
);
value <<= 8;
}
}
-static uint32_t read_u32 (const char *icc, int length, int offset)
+static uint32_t read_u32 (ICC *state, int offset)
{
return icc_read (u8, offset + 3) +
(icc_read (u8, offset + 2) << 8) +
@@ -218,8 +240,7 @@ static uint32_t read_u32 (const char *icc, int length, int offset)
(icc_read (u8, offset + 0) << 24);
}
-static sign_t read_sign (const char *icc, int length,
- int offset)
+static sign_t read_sign (ICC *state, int offset)
{
sign_t ret;
ret.str[0]=icc_read (u8, offset);
@@ -230,8 +251,7 @@ static sign_t read_sign (const char *icc, int length,
return ret;
}
-static void write_sign (char *icc, int length,
- int offset, char *sign)
+static void write_sign (ICC *state, int offset, const char *sign)
{
int i;
for (i = 0; i < 4; i ++)
@@ -240,7 +260,7 @@ static void write_sign (char *icc, int length,
/* looks up offset and length for a specific icc tag
*/
-static int icc_tag (const char *icc, int length,
+static int icc_tag (ICC *state,
const char *tag, int *offset, int *el_length)
{
int tag_count = icc_read (u32, TAG_COUNT_OFF);
@@ -261,11 +281,9 @@ static int icc_tag (const char *icc, int length,
return 0;
}
-static const Babl *babl_trc_from_icc (const char *icc,
- int length,
- char **error)
+static const Babl *babl_trc_from_icc (ICC *state, int offset,
+ char **error)
{
- int offset = 0;
{
int count = icc_read (u32, offset + 8);
int i;
@@ -280,8 +298,7 @@ static const Babl *babl_trc_from_icc (const char *icc,
}
else
{
- return babl_trc_gamma (2.2);
-
+ return babl_trc_gamma (10.0);
// XXX: todo implement a curve trc babl type
// as well as detect sRGB curve from LUTs
@@ -297,15 +314,33 @@ static const Babl *babl_trc_from_icc (const char *icc,
return NULL;
}
+static void icc_allocate_tag (ICC *state, const char *tag, int size)
+{
+ state->no+=((4-state->o)%4);state->o = state->no;state->psize = size;
+ icc_write (sign, 128 + 4 + 4 * state->headpos++, tag);
+ icc_write (u32, 128 + 4 + 4 * state->headpos++, state->o);
+ icc_write (u32, 128 + 4 + 4 * state->headpos++, size);
+ state->p = state->no;\
+ state->no+=size;
+}
+
+static void icc_duplicate_tag(ICC *state, const char *tag)
+{
+ icc_write (sign, 128 + 4 + 4 * state->headpos++, tag);
+ icc_write (u32, 128 + 4 + 4 * state->headpos++, state->p);
+ icc_write (u32, 128 + 4 + 4 * state->headpos++, state->psize);
+}
const char *babl_space_rgb_to_icc (const Babl *babl, int *ret_length)
{
const BablSpace *space = &babl->space;
static char icc[8192];
int length=4095;
+ ICC *state = icc_state_new (icc, length, 10);
+
icc[length]=0;
-#if 1
+#if 0
icc_write (s8, 8,-2);
assert (icc_read (s8, 8) == -2);
icc_write (s8, 8, 3); // ICC verison
@@ -352,113 +387,101 @@ const char *babl_space_rgb_to_icc (const Babl *babl, int *ret_length)
icc_write (sign, 36, "acsp"); // changes
-
{
- int headpos = 0;
- int tags;
- int o, no;
- int p = 0;
- int psize = 0;
-
- tags = 10;
- no = o = 128 + 4 + 12 * tags;
-
- icc_write (u32, 128, tags);
-#define icc_allocate_tag(tag, size) \
- no+=((4-o)%4);o = no;psize = size;\
- icc_write (sign, 128 + 4 + 4 * headpos++, tag);\
- icc_write (u32, 128 + 4 + 4 * headpos++, o);\
- icc_write (u32, 128 + 4 + 4 * headpos++, size);\
- p = no;\
- no+=size;
-#define icc_duplicate_tag(tag) \
- icc_write (sign, 128 + 4 + 4 * headpos++, tag);\
- icc_write (u32, 128 + 4 + 4 * headpos++, p); \
- icc_write (u32, 128 + 4 + 4 * headpos++, psize);
-
- icc_allocate_tag ("wtpt", 20);
- icc_write (sign,o, "XYZ ");
- icc_write (u32, o + 4, 0);
- icc_write (s15f16, o + 8, space->whitepoint[0]);
- icc_write (s15f16, o + 12, space->whitepoint[1]);
- icc_write (s15f16, o + 16, space->whitepoint[2]);
-
- icc_allocate_tag ("rXYZ", 20);
- icc_write (sign,o, "XYZ ");
- icc_write (u32, o + 4, 0);
- icc_write (s15f16, o + 8, space->RGBtoXYZ[0]);
- icc_write (s15f16, o + 12, space->RGBtoXYZ[3]);
- icc_write (s15f16, o + 16, space->RGBtoXYZ[6]);
-
- icc_allocate_tag ("gXYZ", 20);
- icc_write (sign,o, "XYZ ");
- icc_write (u32, o + 4, 0);
- icc_write (s15f16, o + 8, space->RGBtoXYZ[1]);
- icc_write (s15f16, o + 12, space->RGBtoXYZ[4]);
- icc_write (s15f16, o + 16, space->RGBtoXYZ[7]);
-
- icc_allocate_tag ("bXYZ", 20);
- icc_write (sign,o, "XYZ ");
- icc_write (u32, o + 4, 0);
- icc_write (s15f16, o + 8, space->RGBtoXYZ[2]);
- icc_write (s15f16, o + 12, space->RGBtoXYZ[5]);
- icc_write (s15f16, o + 16, space->RGBtoXYZ[8]);
-
- icc_allocate_tag ("rTRC", 14);
- icc_write (sign,o, "curv");
- icc_write (u32, o + 4, 0);
- icc_write (u32, o + 8, 1);
- icc_write (u16, o + 12, 334);
+ state->tags = 10; /* note: we could reserve a couple of spots and
+ still use a very simple allocator and
+ still be valid - albeit with tiny waste of
+ space.
+ */
+ state->no = state->o = 128 + 4 + 12 * state->tags;
+
+ icc_write (u32, 128, state->tags);
+
+ icc_allocate_tag (state, "wtpt", 20);
+ icc_write (sign, state->o, "XYZ ");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (s15f16, state->o + 8, space->whitepoint[0]);
+ icc_write (s15f16, state->o + 12, space->whitepoint[1]);
+ icc_write (s15f16, state->o + 16, space->whitepoint[2]);
+
+ icc_allocate_tag (state, "rXYZ", 20);
+ icc_write (sign, state->o, "XYZ ");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (s15f16, state->o + 8, space->RGBtoXYZ[0]);
+ icc_write (s15f16, state->o + 12, space->RGBtoXYZ[3]);
+ icc_write (s15f16, state->o + 16, space->RGBtoXYZ[6]);
+
+ icc_allocate_tag (state, "gXYZ", 20);
+ icc_write (sign, state->o, "XYZ ");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (s15f16, state->o + 8, space->RGBtoXYZ[1]);
+ icc_write (s15f16, state->o + 12, space->RGBtoXYZ[4]);
+ icc_write (s15f16, state->o + 16, space->RGBtoXYZ[7]);
+
+ icc_allocate_tag (state, "bXYZ", 20);
+ icc_write (sign, state->o, "XYZ ");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (s15f16, state->o + 8, space->RGBtoXYZ[2]);
+ icc_write (s15f16, state->o + 12, space->RGBtoXYZ[5]);
+ icc_write (s15f16, state->o + 16, space->RGBtoXYZ[8]);
+
+ icc_allocate_tag (state, "rTRC", 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, 334);
if (space->trc[0] == space->trc[1] &&
space->trc[0] == space->trc[2])
{
- icc_duplicate_tag ("gTRC");
- icc_duplicate_tag ("bTRC");
+ icc_duplicate_tag (state, "gTRC");
+ icc_duplicate_tag (state, "bTRC");
}
else
{
- icc_allocate_tag ("gTRC", 14);
- icc_write (sign,o, "curv");
- icc_write (u32, o + 4, 0);
- icc_write (u32, o + 8, 1); /* forcing a linear curve */
- icc_allocate_tag ("bTRC", 14);
- icc_write (sign,o, "curv");
- icc_write (u32, o + 4, 0);
- icc_write (u32, o + 8, 1); /* forcing a linear curve */
+ icc_allocate_tag (state, "gTRC", 14);
+ icc_write (sign, state->o, "curv");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, 1); /* forcing a linear curve */
+ icc_allocate_tag (state, "bTRC", 14);
+ icc_write (sign, state->o, "curv");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, 1); /* forcing a linear curve */
}
{
char str[128];
int i;
sprintf (str, "babl");
- icc_allocate_tag("desc", 100 + strlen (str) + 1);
- icc_write (sign,o,"desc");
- icc_write (u32, o + 4, 0);
- icc_write (u32, o + 8, strlen(str));
+ icc_allocate_tag(state, "desc", 100 + strlen (str) + 1);
+ icc_write (sign, state->o,"desc");
+ icc_write (u32, state->o + 4, 0);
+ icc_write (u32, state->o + 8, strlen(str));
for (i = 0; str[i]; i++)
- icc_write (u8, o + 12 + i, str[i]);
+ icc_write (u8, state->o + 12 + i, str[i]);
- icc_duplicate_tag ("dmnd");
+ icc_duplicate_tag (state, "dmnd");
}
{
char str[128];
int i;
sprintf (str, "CC0/public domain");
- icc_allocate_tag("cprt", 8 + strlen (str) + 1);
- icc_write (sign,o, "text");
- icc_write (u32, o + 4, 0);
+ icc_allocate_tag(state, "cprt", 8 + strlen (str) + 1);
+ icc_write (sign, state->o, "text");
+ icc_write (u32, state->o + 4, 0);
for (i = 0; str[i]; i++)
- icc_write (u8, o + 8 + i, str[i]);
+ icc_write (u8, state->o + 8 + i, str[i]);
}
- icc_write (u32, 0, no + 3);
- length = no + 3;
+ icc_write (u32, 0, state->no + 3);
+ length = state->no + 3;
}
if (ret_length)
*ret_length = length;
+
+ babl_free (state);
return icc;
}
@@ -467,6 +490,8 @@ babl_space_rgb_icc (const char *icc,
int length,
char **error)
{
+ ICC *state = icc_state_new ((char*)icc, length, 0);
+
int profile_size = icc_read (u32, 0);
int icc_ver_major = icc_read (u8, 8);
const Babl *trc_red = NULL;
@@ -477,54 +502,56 @@ babl_space_rgb_icc (const char *icc,
if (profile_size != length)
{
*error = "icc profile length inconsistency";
- return NULL;
}
- if (icc_ver_major > 2)
+ else if (icc_ver_major > 2)
{
*error = "only ICC v2 profiles supported";
- return NULL;
}
+ else
+ {
profile_class = icc_read (sign, 12);
if (strcmp (profile_class.str, "mntr"))
- {
*error = "not a monitor-class profile";
- return NULL;
- }
+ else
+ {
color_space = icc_read (sign, 16);
if (strcmp (color_space.str, "RGB "))
- {
*error = "not defining an RGB space";
- return NULL;
}
+ }
+
{
int offset, element_size;
- if (icc_tag (icc, length, "rTRC", &offset, &element_size))
+ if (!*error && icc_tag (state, "rTRC", &offset, &element_size))
{
- trc_red = babl_trc_from_icc (icc + offset, element_size, error);
- if (*error) return NULL;
+ trc_red = babl_trc_from_icc (state, offset, error);
}
- if (icc_tag (icc, length, "gTRC", &offset, &element_size))
+ if (!*error && icc_tag (state, "gTRC", &offset, &element_size))
{
- trc_green = babl_trc_from_icc (icc + offset, element_size, error);
- if (*error) return NULL;
+ trc_green = babl_trc_from_icc (state, offset, error);
}
- if (icc_tag (icc, length, "bTRC", &offset, &element_size))
+ if (!*error && icc_tag (state, "bTRC", &offset, &element_size))
{
- trc_blue = babl_trc_from_icc (icc + offset, element_size, error);
- if (*error) return NULL;
+ trc_blue = babl_trc_from_icc (state, offset, error);
}
}
- if (!trc_red || !trc_green || !trc_blue)
+
+ if (!*error && (!trc_red || !trc_green || !trc_blue))
{
*error = "missing TRCs";
- return NULL;
}
- if (icc_tag (icc, length, "rXYZ", NULL, NULL) &&
- icc_tag (icc, length, "gXYZ", NULL, NULL) &&
- icc_tag (icc, length, "bXYZ", NULL, NULL) &&
- icc_tag (icc, length, "wtpt", NULL, NULL))
+ if (*error)
+ {
+ babl_free (state);
+ return NULL;
+ }
+
+ 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))
{
int offset, element_size;
double rx, gx, bx;
@@ -533,22 +560,24 @@ babl_space_rgb_icc (const char *icc,
double wX, wY, wZ;
- icc_tag (icc, length, "rXYZ", &offset, &element_size);
+ icc_tag (state, "rXYZ", &offset, &element_size);
rx = icc_read (s15f16, offset + 8 + 4 * 0);
ry = icc_read (s15f16, offset + 8 + 4 * 1);
rz = icc_read (s15f16, offset + 8 + 4 * 2);
- icc_tag (icc, length, "gXYZ", &offset, &element_size);
+ icc_tag (state, "gXYZ", &offset, &element_size);
gx = icc_read (s15f16, offset + 8 + 4 * 0);
gy = icc_read (s15f16, offset + 8 + 4 * 1);
gz = icc_read (s15f16, offset + 8 + 4 * 2);
- icc_tag (icc, length, "bXYZ", &offset, &element_size);
+ icc_tag (state, "bXYZ", &offset, &element_size);
bx = icc_read (s15f16, offset + 8 + 4 * 0);
by = icc_read (s15f16, offset + 8 + 4 * 1);
bz = icc_read (s15f16, offset + 8 + 4 * 2);
- icc_tag (icc, length, "wtpt", &offset, &element_size);
+ icc_tag (state, "wtpt", &offset, &element_size);
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_rgb_matrix (NULL,
wX, wY, wZ,
@@ -557,14 +586,14 @@ babl_space_rgb_icc (const char *icc,
rz, gz, bz,
trc_red, trc_green, trc_blue);
}
- else if (icc_tag (icc, length, "chrm", NULL, NULL) &&
- icc_tag (icc, length, "wtpt", NULL, NULL))
+ else if (icc_tag (state, "chrm", NULL, NULL) &&
+ icc_tag (state, "wtpt", NULL, NULL))
{
int offset, element_size;
double red_x, red_y, green_x, green_y, blue_x, blue_y;
int channels, phosporant;
- icc_tag (icc, length, "chrm", &offset, &element_size);
+ icc_tag (state, "chrm", &offset, &element_size);
channels = icc_read (u16, offset + 8);
phosporant = icc_read (u16, offset + 10);
@@ -586,11 +615,12 @@ babl_space_rgb_icc (const char *icc,
blue_x = icc_read (s15f16, offset + 28);
blue_y = icc_read (s15f16, offset + 28 + 4);
- icc_tag (icc, length, "wtpt", &offset, &element_size);
+ icc_tag (state, "wtpt", &offset, &element_size);
{
double wX = icc_read (s15f16, offset + 8);
double wY = icc_read (s15f16, offset + 8 + 4);
double wZ = icc_read (s15f16, offset + 8 + 4 * 2);
+ babl_free (state);
return babl_space_rgb_chromaticities (NULL,
wX / (wX + wY + wZ),
@@ -604,5 +634,6 @@ babl_space_rgb_icc (const char *icc,
}
*error = "didnt find RGB primaries";
+ babl_free (state);
return NULL;
}
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index b9c287e..4232710 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -355,9 +355,12 @@ void babl_space_get_chromaticities (const Babl *space,
double *gx, double *gy,
double *bx, double *by);
-const Babl * babl_trc_new (const char *name,
- BablTRCType type,
- double gamma);
+const Babl *
+babl_trc_new (const char *name,
+ BablTRCType type,
+ double gamma,
+ int n_lut,
+ float *lut);
/**
* babl_trc_from_linear:
diff --git a/babl/babl-trc.c b/babl/babl-trc.c
index 9f8cb58..5719e03 100644
--- a/babl/babl-trc.c
+++ b/babl/babl-trc.c
@@ -40,7 +40,9 @@ babl_trc (const char *name)
const Babl *
babl_trc_new (const char *name,
BablTRCType type,
- double gamma)
+ double gamma,
+ int n_lut,
+ float *lut)
{
int i=0;
static BablTRC trc;
@@ -74,6 +76,11 @@ babl_trc_new (const char *name,
return (Babl*)&trc_db[i];
}
+const Babl * babl_trc_lut (const char *name, int n, float *entries)
+{
+ return babl_trc_new (name, BABL_TRC_LUT, 0, n, entries);
+}
+
void
babl_trc_class_for_each (BablEachFunction each_fun,
void *user_data)
@@ -90,24 +97,24 @@ babl_trc_gamma (double gamma)
char name[32];
int i;
if (fabs (gamma - 1.0) < 0.0001)
- return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0);
+ return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL);
sprintf (name, "%.6f", gamma);
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_GAMMA, gamma);
+ return babl_trc_new (name, BABL_TRC_GAMMA, gamma, 0, NULL);
}
+
void
babl_trc_class_init (void)
{
- /* we register sRGB first so that lookups for it is fastest */
- babl_trc_new ("sRGB", BABL_TRC_SRGB, 2.2);
+ babl_trc_new ("sRGB", BABL_TRC_SRGB, 2.2, 0, NULL);
babl_trc_gamma (2.2);
babl_trc_gamma (1.8);
babl_trc_gamma (1.0);
- babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0);
+ babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL);
}
double babl_trc_from_linear (const Babl *trc_, double value)
diff --git a/babl/babl-trc.h b/babl/babl-trc.h
index fd7a0c5..c762810 100644
--- a/babl/babl-trc.h
+++ b/babl/babl-trc.h
@@ -27,7 +27,8 @@ BABL_CLASS_DECLARE (trc);
typedef enum {BABL_TRC_LINEAR,
BABL_TRC_GAMMA,
- BABL_TRC_SRGB} BablTRCType;
+ BABL_TRC_SRGB,
+ BABL_TRC_LUT} BablTRCType;
typedef struct
{
@@ -35,9 +36,20 @@ typedef struct
BablTRCType type;
double gamma;
char name[128];
-
+ float *lut;
+ int lut_size;
} BablTRC;
+static inline double babl_trc_lut_from_linear (const Babl *trc_, double value)
+{
+ return 0;
+}
+
+static inline double babl_trc_lut_to_linear (const Babl *trc_, double value)
+{
+ return 0;
+}
+
static inline double _babl_trc_from_linear (const Babl *trc_, double value)
{
BablTRC *trc = (void*)trc_;
@@ -49,6 +61,8 @@ static inline double _babl_trc_from_linear (const Babl *trc_, double value)
return pow (value, 1.0/trc->gamma);
case BABL_TRC_SRGB:
return babl_linear_to_gamma_2_2 (value);
+ case BABL_TRC_LUT:
+ return babl_trc_lut_from_linear (trc_, value);
}
return value;
}
@@ -64,6 +78,8 @@ static inline double _babl_trc_to_linear (const Babl *trc_, double value)
return pow (value, trc->gamma);
case BABL_TRC_SRGB:
return babl_gamma_2_2_to_linear (value);
+ case BABL_TRC_LUT:
+ return babl_trc_lut_to_linear (trc_, value);
}
return value;
}
@@ -76,6 +92,7 @@ static inline float _babl_trc_from_linearf (const Babl *trc_, float value)
case BABL_TRC_LINEAR: return value;
case BABL_TRC_GAMMA: return powf (value, 1.0f/trc->gamma);
case BABL_TRC_SRGB: return babl_linear_to_gamma_2_2f (value);
+ case BABL_TRC_LUT: return babl_trc_lut_from_linear (trc_, value);
}
return value;
}
@@ -88,6 +105,7 @@ static inline float _babl_trc_to_linearf (const Babl *trc_, float value)
case BABL_TRC_LINEAR: return value;
case BABL_TRC_GAMMA: return powf (value, trc->gamma);
case BABL_TRC_SRGB: return babl_gamma_2_2_to_linearf (value);
+ case BABL_TRC_LUT: return babl_trc_lut_to_linear (trc_, value);
}
return value;
}
diff --git a/babl/babl.h b/babl/babl.h
index b601615..e05ea49 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -91,10 +91,13 @@ const Babl * babl_trc (const char *name);
/**
* babl_trc_gamma:
*
- * Creates a Babl TRC for a specific gamma value.
+ * Creates a Babl TRC for a specific gamma value, it will be given
+ * a name
*/
const Babl * babl_trc_gamma (double gamma);
+const Babl * babl_trc_lut (const char *name, int n, float *entries);
+
/**
* babl_space:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]