[babl] palette: add capability to use palette formats with separate alpha
- From: Ãyvind KolÃs <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] palette: add capability to use palette formats with separate alpha
- Date: Sat, 17 Mar 2012 17:04:21 +0000 (UTC)
commit 9d2aa7d13ac421935de1e87301c48af50b0ceb59
Author: Ãyvind KolÃs <pippin gimp org>
Date: Sat Mar 17 17:02:44 2012 +0000
palette: add capability to use palette formats with separate alpha
Also refactored to make babl-palette.c only use public API.
babl/babl-fish-path.c | 6 +-
babl/babl-format.c | 14 +++
babl/babl-ids.h | 1 -
babl/babl-palette.c | 226 +++++++++++++++++++++++++++++++++++--------------
babl/babl.h | 18 ++++-
tests/palette.c | 39 ++++++++-
6 files changed, 230 insertions(+), 74 deletions(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index c7caa35..a2d1a68 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -287,7 +287,8 @@ babl_fish_path (const Babl *source,
pc.fish_path = babl;
pc.to_format = (Babl *) destination;
- babl_mutex_lock (babl_format_mutex);
+ if (babl_in_fish_path <= 0)
+ babl_mutex_lock (babl_format_mutex);
/* we hold a global lock whilerunning get_conversion_path since
* it depends on keeping the various format.visited members in
* a consistent state, this code path is not performance critical
@@ -298,7 +299,8 @@ babl_fish_path (const Babl *source,
get_conversion_path (&pc, (Babl *) source, 0, max_path_length ());
babl_in_fish_path--;
- babl_mutex_unlock (babl_format_mutex);
+ if (babl_in_fish_path <= 0)
+ babl_mutex_unlock (babl_format_mutex);
babl_free (pc.current_path);
}
diff --git a/babl/babl-format.c b/babl/babl-format.c
index d95384e..21d33e9 100644
--- a/babl/babl-format.c
+++ b/babl/babl-format.c
@@ -619,4 +619,18 @@ babl_format_loss (Babl *babl)
return loss;
}
+
+void *
+babl_get_user_data (Babl *babl)
+{
+ return babl->format.model->data;
+}
+
+void
+babl_set_user_data (Babl *babl, void *data)
+{
+ babl->format.model_data = data;
+ babl->format.model->data = babl->format.model_data;
+}
+
BABL_CLASS_IMPLEMENT (format)
diff --git a/babl/babl-ids.h b/babl/babl-ids.h
index f26add8..f0f6c61 100644
--- a/babl/babl-ids.h
+++ b/babl/babl-ids.h
@@ -85,7 +85,6 @@ enum {
BABL_CB,
BABL_CR,
BABL_PADDING,
- BABL_PAL,
BABL_COMPONENT_LAST_INTERNAL,
BABL_FORMAT_BASE = 100000,
diff --git a/babl/babl-palette.c b/babl/babl-palette.c
index c8f10d0..9fc525a 100644
--- a/babl/babl-palette.c
+++ b/babl/babl-palette.c
@@ -16,17 +16,10 @@
* <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
#include <stdlib.h>
-
-#include "babl-internal.h"
-#include "babl-classes.h"
+#include <string.h>
+#include <stdio.h>
#include "babl.h"
-#include "babl-ids.h"
-#include "util.h"
-#include "rgb-constants.h"
-#include "math.h"
-#include "babl-base.h"
typedef struct BablPalette
{
@@ -40,10 +33,10 @@ static BablPalette *make_pal (Babl *format, void *data, int count)
{
BablPalette *pal = NULL;
int bpp = babl_format_get_bytes_per_pixel (format);
- pal = babl_malloc (sizeof (BablPalette));
+ pal = malloc (sizeof (BablPalette));
pal->count = count;
pal->format = format;
- pal->data = babl_malloc (bpp * count);
+ pal->data = malloc (bpp * count);
memcpy (pal->data, data, bpp * count);
return pal;
}
@@ -67,7 +60,6 @@ static unsigned char defpal_data[4*16] =
0 ,255,255,255,
255,255,255,255,
};
-
static BablPalette *default_palette (void)
{
static BablPalette pal;
@@ -76,7 +68,10 @@ static BablPalette *default_palette (void)
return &pal;
inited = 1;
pal.count = 16;
- pal.format = babl_format ("RGBA u8");
+ pal.format = babl_format ("RGBA u8"); /* dynamically generated, so
+ the default palette can
+ not be fully static.
+ */
pal.data = defpal_data;
return &pal;
}
@@ -92,13 +87,9 @@ rgba_to_pal (char *src,
Babl *fish;
int bpp;
- if (babl_in_fish_path)
- babl_mutex_unlock (babl_format_mutex);
fish = babl_fish (
pal->format,
- babl_format_from_id (BABL_RGBA_DOUBLE));
- if (babl_in_fish_path)
- babl_mutex_lock (babl_format_mutex);
+ babl_format ("RGBA double"));
bpp = babl_format_get_bytes_per_pixel (pal->format);
while (n--)
@@ -140,6 +131,63 @@ rgba_to_pal (char *src,
}
static long
+rgba_to_pala (char *src,
+ char *dst,
+ long n,
+ void *foo,
+ void *dst_model_data)
+{
+ BablPalette *pal = dst_model_data;
+ Babl *fish;
+ int bpp;
+
+ fish = babl_fish (
+ pal->format,
+ babl_format ("RGBA double"));
+
+ bpp = babl_format_get_bytes_per_pixel (pal->format);
+
+ while (n--)
+ {
+ int idx;
+
+ int best_idx = 0;
+ double best_diff = 100000;
+ double *srcf;
+ double alpha;
+
+ srcf = ((double *) src);
+ alpha = srcf[3];
+
+ for (idx = 0; idx<pal->count; idx++)
+ {
+ double diff;
+ double palpx[4];
+
+ /* oh horror, at least cache the format */
+ babl_process (fish, ((char*)pal->data) + idx * bpp,
+ palpx, 1);
+
+ diff = (palpx[0] - srcf[0]) * (palpx[0] - srcf[0]) +
+ (palpx[1] - srcf[1]) * (palpx[1] - srcf[1]) +
+ (palpx[2] - srcf[2]) * (palpx[2] - srcf[2]);
+ if (diff < best_diff)
+ {
+ best_diff = diff;
+ best_idx = idx;
+ }
+ }
+
+ ((double *) dst)[0] = best_idx / 256.0;
+ ((double *) dst)[1] = alpha;
+
+ src += sizeof (double) * 4;
+ dst += sizeof (double) * 2;
+ }
+ return n;
+}
+
+static long
pal_to_rgba (char *src,
char *dst,
long n,
@@ -149,14 +197,13 @@ pal_to_rgba (char *src,
BablPalette *pal = src_model_data;
Babl *fish = babl_fish (
pal->format,
- babl_format_from_id (BABL_RGBA_DOUBLE));
+ babl_format ("RGBA double"));
int bpp = babl_format_get_bytes_per_pixel (pal->format);
while (n--)
{
- int idx;
+ int idx = (((double *) src)[0]) * 256.0;
- idx = (((double *) src)[0]) * 256.0;
if (idx < 0) idx = 0;
if (idx >= pal->count) idx = pal->count-1;
@@ -171,7 +218,42 @@ pal_to_rgba (char *src,
return n;
}
-Babl *babl_new_palette (const char *name)
+
+static long
+pala_to_rgba (char *src,
+ char *dst,
+ long n,
+ void *src_model_data,
+ void *foo)
+{
+ BablPalette *pal = src_model_data;
+ Babl *fish = babl_fish (
+ pal->format,
+ babl_format ("RGBA double"));
+ int bpp = babl_format_get_bytes_per_pixel (pal->format);
+
+ while (n--)
+ {
+ int idx = (((double *) src)[0]) * 256.0;
+ double alpha = (((double *) src)[1]);
+
+
+ if (idx < 0) idx = 0;
+ if (idx >= pal->count) idx = pal->count-1;
+
+ babl_process (fish,
+ ((char*)pal->data) + idx * bpp,
+ dst, 1);
+
+ ((double *)dst)[3] *= alpha;
+
+ src += sizeof (double) * 2;
+ dst += sizeof (double) * 4;
+ }
+ return n;
+}
+
+Babl *babl_new_palette (const char *name, int with_alpha)
{
Babl *model;
Babl *format;
@@ -180,46 +262,69 @@ Babl *babl_new_palette (const char *name)
if (!name)
{
static int cnt = 0;
- sprintf (cname, "pal-%i", cnt++);
+ sprintf (cname, "_babl-int-%i", cnt++);
name = cname;
}
+ /* re-registering is a no-op */
babl_component_new (
"I",
- "id", BABL_PAL,
"luma",
"chroma",
"alpha",
NULL);
- model = babl_model_new (
- "name", name,
- babl_component_from_id (BABL_PAL),
- NULL);
- model->model.data = (void*) 0x012;
-
- babl_conversion_new (
- model,
- babl_model_from_id (BABL_RGBA),
- "linear", pal_to_rgba,
- NULL
- );
-
- babl_conversion_new (
- babl_model_from_id (BABL_RGBA),
- model,
- "linear", rgba_to_pal,
- NULL
- );
-
- format = babl_format_new ("name", name, model,
- babl_type ("u8"),
- babl_component ("I"), NULL);
-
- format->format.model_data = default_palette ();
- format->format.model->data = format->format.model_data;
+ if (with_alpha)
+ {
+ model = babl_model_new ("name", name,
+ babl_component ("I"),
+ babl_component ("A"),
+ NULL);
+ format = babl_format_new ("name", name, model,
+ babl_type ("u8"),
+ babl_component ("I"),
+ babl_component ("A"),
+ NULL);
+
+ babl_conversion_new (
+ model,
+ babl_model ("RGBA"),
+ "linear", pala_to_rgba,
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ model,
+ "linear", rgba_to_pala,
+ NULL
+ );
+ }
+ else
+ {
+ model = babl_model_new ("name", name,
+ babl_component ("I"),
+ NULL);
+ babl_conversion_new (
+ model,
+ babl_model ("RGBA"),
+ "linear", pal_to_rgba,
+ NULL
+ );
+
+ babl_conversion_new (
+ babl_model ("RGBA"),
+ model,
+ "linear", rgba_to_pal,
+ NULL
+ );
+ format = babl_format_new ("name", name, model,
+ babl_type ("u8"),
+ babl_component ("I"), NULL);
+ }
+ babl_set_user_data (format, default_palette ());
babl_sanity ();
return format;
}
@@ -230,25 +335,18 @@ babl_palette_set_palette (Babl *babl,
void *data,
int count)
{
- if (babl->format.model->data != default_palette ())
- {
- BablPalette *pal = babl->format.model->data;
- babl_free (pal->data);
- babl_free (pal);
- }
- babl->format.model_data = make_pal (format, data, count);
- babl->format.model->data = babl->format.model_data;
+ babl_palette_reset (babl);
+ babl_set_user_data (babl, make_pal (format, data, count));
}
void
babl_palette_reset (Babl *babl)
{
- if (babl->format.model->data != default_palette ())
+ if (babl_get_user_data (babl) != default_palette ())
{
- BablPalette *pal = babl->format.model->data;
- babl_free (pal->data);
- babl_free (pal);
+ BablPalette *pal = babl_get_user_data (babl);
+ free (pal->data);
+ free (pal);
}
- babl->format.model_data = default_palette ();
- babl->format.model->data = babl->format.model_data;
+ babl_set_user_data (babl, default_palette ());
}
diff --git a/babl/babl.h b/babl/babl.h
index e4b0082..57b2895 100644
--- a/babl/babl.h
+++ b/babl/babl.h
@@ -202,9 +202,10 @@ Babl * babl_conversion_new (void *first_arg,
/**
* create a new palette based format, name is optional pass in NULL to get
- * an anonymous format.
+ * an anonymous format. If you pass in with_alpha the format also gets
+ * an 8bit alpha channel.
*/
-Babl *babl_new_palette (const char *name);
+Babl *babl_new_palette (const char *name, int with_alpha);
/**
* Assign a palette to a palette format, the data is a single span of pixels
@@ -221,6 +222,19 @@ void babl_palette_set_palette (Babl *babl,
void babl_palette_reset (Babl *babl);
+/**
+ * associate a data pointer with a format/model, this data can be accessed and
+ * used from the conversion functions, encoding color profiles, palettes or
+ * similar with the data.
+ */
+void babl_set_user_data (Babl *babl, void *data);
+
+/**
+ * get data set with babl_set_user_data
+ */
+void * babl_get_user_data (Babl *babl);
+
+
/*
* Backwards compatibility stuff
diff --git a/tests/palette.c b/tests/palette.c
index 02f79ac..afd52f9 100644
--- a/tests/palette.c
+++ b/tests/palette.c
@@ -58,8 +58,8 @@ main (int argc,
{
unsigned char in[][1] = {{ 0},{ 1},{ 2},{15}};
unsigned char out[][4] = {{0,0,0,255},{127,0,0,255},{0,127,0,255},{255,255,255,255}};
- Babl *palA = babl_new_palette (NULL);
- Babl *palB = babl_new_palette (NULL);
+ Babl *palA = babl_new_palette (NULL, 0);
+ Babl *palB = babl_new_palette (NULL, 0);
CHECK_CONV("pal to rgba", unsigned char,
palA, babl_format("RGBA u8"),
@@ -79,7 +79,16 @@ main (int argc,
unsigned char out[][1] = {{ 0},{ 1},{ 2}};
CHECK_CONV("rgba to pal", unsigned char,
- babl_format("RGBA u8"), babl_new_palette ("palC"),
+ babl_format("RGBA u8"), babl_new_palette ("palC", 0),
+ in, out);
+ }
+
+ {
+ unsigned char in[][4] = {{0,0,0,255},{140,0,0,255},{0,127,0,127}};
+ unsigned char out[][2] = {{ 0,255},{ 1,255},{ 2,127}};
+
+ CHECK_CONV("rgba to pal+alpha", unsigned char,
+ babl_format("RGBA u8"), babl_new_palette ("palD", 1),
in, out);
}
@@ -91,10 +100,10 @@ main (int argc,
1.0, 0.2
};
- unsigned char in[][1] = {{ 0},{ 1},{ 2}};
+ unsigned char in[][1] = {{ 0},{ 1},{ 2}};
unsigned char out[][4] = {{128,128,128,255},{59,59,59,107},{255,255,255,51}};
- Babl *pal = babl_new_palette (NULL);
+ Babl *pal = babl_new_palette (NULL, 0);
babl_palette_set_palette (pal, babl_format ("YA float"), palette, 3);
@@ -103,6 +112,26 @@ main (int argc,
in, out);
}
+ /* check with a custom floating point palette, _and_ alpha component */
+ {
+ float palette[] = {
+ 0.5, 1.0,
+ 0.23, 0.42,
+ 1.0, 0.2
+ };
+
+ unsigned char in[][2] = {{ 0,255},{0,127},{ 1,255},{ 2,255}};
+ unsigned char out[][4] = {{128,128,128,255},{128,128,128,127},{59,59,59,107},{255,255,255,51}};
+
+ Babl *pal = babl_new_palette (NULL, 1);
+
+ babl_palette_set_palette (pal, babl_format ("YA float"), palette, 3);
+
+ CHECK_CONV("rgba to YA float pal+alpha", unsigned char,
+ pal, babl_format("RGBA u8"),
+ in, out);
+ }
+
babl_exit ();
return !OK;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]