view src/rovascope/cmaps.c @ 906:16e51fb5908e trunk

[svn] - aosd: beta4, ghosd source was rewritten to support argb visual (x composite extension) as an option, this allows to have real transparency in the OSD
author giacomo
date Sat, 31 Mar 2007 17:44:23 -0700
parents 290588854a9d
children f305ebcc8136
line wrap: on
line source

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <glib.h>

#include "paranormal.h"
#include "actuators.h"

#include "libcalc/calc.h"

#define STD_CMAP_OPTS { "low_index", "The lowest index of the \
color map that should be altered", OPT_TYPE_COLOR_INDEX, { ival: 0 } },\
{ "high_index", "The highest index of the color map that should be \
altered", OPT_TYPE_COLOR_INDEX, { ival: 255 } }

static struct pn_color black = {0, 0, 0};
static struct pn_color white = {255, 255, 255};

/* **************** cmap generation funcs **************** */
static void
cmap_gen_gradient (int step, const struct pn_color *a,
		   const struct pn_color *b,
		   struct pn_color *c)
{
  c->r = a->r + step * ((((float)b->r) - ((float)a->r)) / 256.0);
  c->g = a->g + step * ((((float)b->g) - ((float)a->g)) / 256.0);
  c->b = a->b + step * ((((float)b->b) - ((float)a->b)) / 256.0);
}

/* **************** cmap_gradient **************** */
static struct pn_actuator_option_desc cmap_gradient_opts[] =
{
  STD_CMAP_OPTS,
  { "lcolor", "The low color used in the gradient generation",
    OPT_TYPE_COLOR, { cval: {0, 0, 0} } },
  { "hcolor", "The high color used in the gradient generation",
    OPT_TYPE_COLOR, { cval: {0, 0, 0} } },
  { NULL }
};

static void
cmap_gradient_exec (const struct pn_actuator_option *opts,
		    gpointer data)
{
  int i;

  for (i=opts[0].val.ival; i<=opts[1].val.ival; i++)
    cmap_gen_gradient (((i-opts[0].val.ival)<<8)/(opts[1].val.ival
						  - opts[0].val.ival),
		       &opts[2].val.cval, &opts[3].val.cval,
		       &pn_image_data->cmap[i]);
}

struct pn_actuator_desc builtin_cmap_gradient =
{
  "cmap_gradient",
  "Normal colourmap",
  "Sets the colormap to a gradient going from <lcolor> to "
  "<hcolor>",
  0, cmap_gradient_opts,
  NULL, NULL, cmap_gradient_exec
};

/* **************** cmap_bwgradient **************** */
static struct pn_actuator_option_desc cmap_bwgradient_opts[] =
{
  STD_CMAP_OPTS,
  { "color", "The intermediate color to use in the gradient",
    OPT_TYPE_COLOR, { cval: {191, 191, 191} } },
  { NULL }
};

static void
cmap_bwgradient_exec (const struct pn_actuator_option *opts,
		      gpointer data)
{
  int i;

  for (i=opts[0].val.ival; i<128 && i<=opts[1].val.ival; i++)
    cmap_gen_gradient (i<<1, &black, &opts[2].val.cval,
		       &pn_image_data->cmap[i]);

  for (i=128; i<256 && i<=opts[1].val.ival; i++)
    cmap_gen_gradient ((i-128)<<1, &opts[2].val.cval, &white,
		       &pn_image_data->cmap[i]);
}
    
struct pn_actuator_desc builtin_cmap_bwgradient =
{
  "cmap_bwgradient",
  "Value-based colourmap",
  "Sets the colormap to a gradient going from black to "
  "white, via an intermediate color",
  0, cmap_bwgradient_opts,
  NULL, NULL, cmap_bwgradient_exec
};

/* **************** cmap_dynamic **************** */
static struct pn_actuator_option_desc cmap_dynamic_opts[] =
{
  STD_CMAP_OPTS,
  { "script", "The script to run on each step.",
    OPT_TYPE_STRING, { sval: "red = red + 0.01; blue = blue + 0.01; green = green + 0.01;" } },
  { NULL }
};

typedef struct {
  expression_t *expr;
  symbol_dict_t *dict;
} PnDynamicColourmapData;

static void
cmap_dynamic_init(gpointer *data)
{
  *data = g_new0(PnDynamicColourmapData, 1);
}

static void
cmap_dynamic_cleanup(gpointer data)
{
  PnDynamicColourmapData *d = (PnDynamicColourmapData *) data;

  if (d->expr)
    expr_free(d->expr);
  if (d->dict)
    dict_free(d->dict);

  g_free(d);
}

static void
cmap_dynamic_exec(const struct pn_actuator_option *opts,
		  gpointer data)
{
  PnDynamicColourmapData *d = (PnDynamicColourmapData *) data;
  gint i, j;
  gdouble *rf, *bf, *gf, *inf;
  gint rn, bn, gn;

  if (!d->dict && !d->expr)
    {
       d->dict = dict_new();
       if (!d->dict)
         return;

       d->expr = expr_compile_string(opts[2].val.sval, d->dict);
       if (!d->expr)
         {
           dict_free(d->dict);
           d->dict = NULL;
           return;
         }
    }

  rf = dict_variable(d->dict, "red");
  gf = dict_variable(d->dict, "green");
  bf = dict_variable(d->dict, "blue");
  inf = dict_variable(d->dict, "index");

  for (i = opts[0].val.ival; i < 255 && i <= opts[1].val.ival; i++)
    {
       *inf = ((gdouble)i / 255.0);

       expr_execute(d->expr, d->dict);

       /* Convert rf/bf/gf to realworld values. */
       rn = (gdouble)(*rf * 255);
       gn = (gdouble)(*gf * 255);
       bn = (gdouble)(*bf * 255);

       pn_image_data->cmap[i].r = rn;
       pn_image_data->cmap[i].g = gn;
       pn_image_data->cmap[i].b = bn;
    }
}

struct pn_actuator_desc builtin_cmap_dynamic =
{
  "cmap_dynamic",
  "Dynamic Colourmap",
  "Scriptable colourmap modifier.",
  0, cmap_dynamic_opts,
  cmap_dynamic_init, cmap_dynamic_cleanup, cmap_dynamic_exec
};