//------------------------------------------------------------------------------
// Pd Spectral Toolkit
//
// rgbtable.c
//
// Outputs red, green, and blue values based on an input value
//
// Created by Cooper on 9/22/12.
// Updated for 64 Bit Support in September 2019.
// Copyright (C) 2019 Cooper Baker. All Rights Reserved.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// headers
//------------------------------------------------------------------------------
#include "m_pd.h"
// utility header for Pd Spectral Toolkit project
#include "utility.h"
// disable compiler warnings on windows
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#define COLOR_TABLE_SIZE 1000000
//------------------------------------------------------------------------------
// rgbtable_class - pointer to this object's definition
//------------------------------------------------------------------------------
t_class* rgbtable_class;
//------------------------------------------------------------------------------
// SCHEME_ID - enumerated color scheme names
//------------------------------------------------------------------------------
enum SCHEME_ID
{
RGB,
PURPLE_YELLOW,
BLUE_GREEN,
AMBER,
RED,
GREEN,
BLUE,
GREY
};
//------------------------------------------------------------------------------
// rgbtable - data structure holding this object's data
//------------------------------------------------------------------------------
typedef struct rgbtable
{
// this object - must always be first variable in struct
t_object object;
// float variable to hold input value
t_float value;
// id of the selected color scheme
t_int scheme_id;
// pointers to outlets
t_outlet* outlet_r;
t_outlet* outlet_g;
t_outlet* outlet_b;
// meta pointers to the color tables
t_float* r;
t_float* g;
t_float* b;
// pointers to the color tables
t_float* r_rgb;
t_float* g_rgb;
t_float* b_rgb;
t_float* r_py;
t_float* g_py;
t_float* b_py;
t_float* r_bg;
t_float* g_bg;
t_float* b_bg;
t_float* r_a;
t_float* g_a;
t_float* b_a;
t_float* r_r;
t_float* g_r;
t_float* b_r;
t_float* r_g;
t_float* g_g;
t_float* b_g;
t_float* r_b;
t_float* g_b;
t_float* b_b;
t_float* r_gr;
t_float* g_gr;
t_float* b_gr;
} t_rgbtable;
//------------------------------------------------------------------------------
// function prototypes
//------------------------------------------------------------------------------
void rgbtable_bang ( t_rgbtable* object );
void rgbtable_float ( t_rgbtable* object, t_floatarg number );
void rgbtable_set_scheme ( t_rgbtable* object );
void* rgbtable_new ( t_symbol* selector, t_int items, t_atom* list );
static void rgbtable_free ( t_rgbtable* object );
void rgbtable_setup ( void );
//------------------------------------------------------------------------------
// rgbtable_bang - causes output
//------------------------------------------------------------------------------
void rgbtable_bang( t_rgbtable* object )
{
// calculate table index
t_int index = object->value *= COLOR_TABLE_SIZE - 1;
// output rgb values
outlet_float( object->outlet_r, object->r[ index ] );
outlet_float( object->outlet_g, object->g[ index ] );
outlet_float( object->outlet_b, object->b[ index ] );
}
//------------------------------------------------------------------------------
// rgbtable_float - default float handler
//------------------------------------------------------------------------------
void rgbtable_float( t_rgbtable* object, t_floatarg number )
{
// store number in to the object's "value" variable
object->value = Clip( number, 0, 1 );
rgbtable_bang( object );
}
//------------------------------------------------------------------------------
// rgbtable_message_parse - parses incoming messages to set color tables
//------------------------------------------------------------------------------
void rgbtable_message_parse( t_rgbtable* object, t_symbol* selector, t_int items, t_atom* list )
{
// get selector string
const char* message = selector->s_name;
// rgb
if( StringMatch( message, "rgb" ) )
{
object->scheme_id = RGB;
}
// purple yellow
else if( StringMatch( message, "purple-yellow" ) )
{
object->scheme_id = PURPLE_YELLOW;
}
// blue green
else if( StringMatch( message, "blue-green" ) )
{
object->scheme_id = BLUE_GREEN;
}
// amber
else if( StringMatch( message, "amber" ) )
{
object->scheme_id = AMBER;
}
// red
else if( StringMatch( message, "red" ) )
{
object->scheme_id = RED;
}
// green
else if( StringMatch( message, "green" ) )
{
object->scheme_id = GREEN;
}
// blue
else if( StringMatch( message, "blue" ) )
{
object->scheme_id = BLUE;
}
// grey
else if( StringMatch( message, "grey" ) )
{
object->scheme_id = GREY;
}
// unknown
else
{
pd_error( object, "rgbtable: unknown color scheme name" );
}
rgbtable_set_scheme( object );
}
//------------------------------------------------------------------------------
// rgbtable_set_scheme - sets color scheme
//------------------------------------------------------------------------------
void rgbtable_set_scheme( t_rgbtable* object )
{
switch( object->scheme_id )
{
case RGB : object->r = object->r_rgb;
object->g = object->g_rgb;
object->b = object->b_rgb;
break;
case PURPLE_YELLOW : object->r = object->r_py;
object->g = object->g_py;
object->b = object->b_py;
break;
case BLUE_GREEN : object->r = object->r_bg;
object->g = object->g_bg;
object->b = object->b_bg;
break;
case AMBER : object->r = object->r_a;
object->g = object->g_a;
object->b = object->b_a;
break;
case RED : object->r = object->r_r;
object->g = object->g_r;
object->b = object->b_r;
break;
case GREEN : object->r = object->r_g;
object->g = object->g_g;
object->b = object->b_g;
break;
case BLUE : object->r = object->r_b;
object->g = object->g_b;
object->b = object->b_b;
break;
case GREY : object->r = object->r_b;
object->g = object->g_b;
object->b = object->b_b;
break;
}
}
//------------------------------------------------------------------------------
// rgbtable_new - initialize the object upon instantiation ( aka "constructor" )
//------------------------------------------------------------------------------
void* rgbtable_new( t_symbol* selector, t_int items, t_atom* list )
{
// declare a pointer to this class
t_rgbtable* object;
// generate a new object and save its pointer in "object"
object = ( t_rgbtable* )pd_new( rgbtable_class );
// generate outlets and save their pointers
object->outlet_r = outlet_new( &object->object, gensym( "float" ) );
object->outlet_g = outlet_new( &object->object, gensym( "float" ) );
object->outlet_b = outlet_new( &object->object, gensym( "float" ) );
// initialize the pointers
//--------------------------------------------------------------------------
// meta pointers
object->r = NULL;
object->g = NULL;
object->b = NULL;
// rgb
object->r_rgb = NULL;
object->g_rgb = NULL;
object->b_rgb = NULL;
// purple yellow
object->r_py = NULL;
object->g_py = NULL;
object->b_py = NULL;
// blue green
object->r_bg = NULL;
object->g_bg = NULL;
object->b_bg = NULL;
// amber
object->r_a = NULL;
object->g_a = NULL;
object->b_a = NULL;
// red
object->r_r = NULL;
object->g_r = NULL;
object->b_r = NULL;
// green
object->r_g = NULL;
object->g_g = NULL;
object->b_g = NULL;
// blue
object->r_b = NULL;
object->g_b = NULL;
object->b_b = NULL;
// grey
object->r_gr = NULL;
object->g_gr = NULL;
object->b_gr = NULL;
// allocate memory for the color tables
//--------------------------------------------------------------------------
// rgb
object->r_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// purple yellow
object->r_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// blue green
object->r_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// amber
object->r_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// red
object->r_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// green
object->r_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// blue
object->r_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// grey
object->r_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// color curve calculation variables
t_int i;
t_float x;
// iterate through the tables
for( i = 0 ; i < COLOR_TABLE_SIZE ; ++i )
{
// calculate x from 0 to 1
x = ( float )i / COLOR_TABLE_SIZE;
// calculate the color curves and store into tables
//----------------------------------------------------------------------
// rgb
object->r_rgb[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * x * x ) );
object->g_rgb[ i ] = 0.5 * ( 1.0 - Cosine( C_2_PI * x * x ) );
object->b_rgb[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) ) ) * Power( x, 0.75 ) * 3;
// purple yellow
object->r_py[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * Power( x, 1.5 ) ) );
object->g_py[ i ] = x * x * x * x;
object->b_py[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) ) ) * Power( x, 0.75 ) * 1.25;
// blue green
object->r_bg[ i ] = x * x * x * x;
object->g_bg[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * Power( x, 1.5 ) ) );
object->b_bg[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) ) ) * Power( x, 0.75 ) * 1.25;
// amber
object->r_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->g_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
object->b_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
// red
object->r_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->g_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x * x ) ) );
object->b_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x * x ) ) );
// green
object->r_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
object->g_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->b_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
// blue
object->r_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
object->g_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
object->b_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
// grey
object->r_gr[ i ] = x;
object->g_gr[ i ] = x;
object->b_gr[ i ] = x;
}
// set default color scheme id
object->scheme_id = RGB;
// set the color scheme
rgbtable_set_scheme( object );
if( items > 0 )
{
if( list[ 0 ].a_type == A_SYMBOL )
{
t_symbol init_selector;
init_selector.s_name = list[ 0 ].a_w.w_symbol->s_name;
rgbtable_message_parse( object, &init_selector, 0, NULL );
}
else
{
// notify of invalid arguments
pd_error( object, "rgbtable: invalid argument type" );
}
}
if( items > 1 )
{
// notify of extra arguments
pd_error( object, "rgbtable: extra arguments ignored" );
}
// return the pointer to this class
return ( void* )object;
}
//------------------------------------------------------------------------------
// rgbtable_free - cleans up memory allocated by this object
//------------------------------------------------------------------------------
void rgbtable_free( t_rgbtable* object )
{
// if memory is allocated
// {
// deallocate the memory
// set the memory pointer to null
// }
// rgb
if( object->r_rgb )
{
free( object->r_rgb );
object->r_rgb = NULL;
}
if( object->g_rgb )
{
free( object->g_rgb );
object->g_rgb = NULL;
}
if( object->b_rgb )
{
free( object->b_rgb );
object->b_rgb = NULL;
}
// purple yellow
if( object->r_py )
{
free( object->r_py );
object->r_py = NULL;
}
if( object->g_py )
{
free( object->g_py );
object->g_py = NULL;
}
if( object->b_py )
{
free( object->b_py );
object->b_py = NULL;
}
// blue green
if( object->r_bg )
{
free( object->r_bg );
object->r_bg = NULL;
}
if( object->g_bg )
{
free( object->g_bg );
object->g_bg = NULL;
}
if( object->b_bg )
{
free( object->b_bg );
object->b_bg = NULL;
}
// amber
if( object->r_a )
{
free( object->r_a );
object->r_a = NULL;
}
if( object->g_a )
{
free( object->g_a );
object->g_a = NULL;
}
if( object->b_a )
{
free( object->b_a );
object->b_a = NULL;
}
// red
if( object->r_r )
{
free( object->r_r );
object->r_r = NULL;
}
if( object->g_r )
{
free( object->g_r );
object->g_r = NULL;
}
if( object->b_r )
{
free( object->b_r );
object->b_r = NULL;
}
// green
if( object->r_g )
{
free( object->r_g );
object->r_g = NULL;
}
if( object->g_g )
{
free( object->g_g );
object->g_g = NULL;
}
if( object->b_g )
{
free( object->b_g );
object->b_g = NULL;
}
// blue
if( object->r_b )
{
free( object->r_b );
object->r_b = NULL;
}
if( object->g_b )
{
free( object->g_b );
object->g_b = NULL;
}
if( object->b_b )
{
free( object->b_b );
object->b_b = NULL;
}
}
//------------------------------------------------------------------------------
// rgbtable setup - defines this object and its properties to Pd
//------------------------------------------------------------------------------
void rgbtable_setup( void )
{
// create a new class and assign its pointer to rgbtable_class
rgbtable_class = class_new( gensym( "rgbtable" ), ( t_newmethod )rgbtable_new, ( t_method )rgbtable_free, sizeof( t_rgbtable ), 0, A_GIMME, 0 );
// add default float handler
class_addfloat( rgbtable_class, rgbtable_float );
// add default bang handler
class_addbang( rgbtable_class, rgbtable_bang );
// add message handler
class_addmethod( rgbtable_class, ( t_method )rgbtable_message_parse, gensym( "anything" ), A_GIMME, 0 );
}
//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------
// Pd Spectral Toolkit
//
// rgbtable.c
//
// Outputs red, green, and blue values based on an input value
//
// Created by Cooper on 9/22/12.
// Updated for 64 Bit Support in September 2019.
// Copyright (C) 2019 Cooper Baker. All Rights Reserved.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// headers
//------------------------------------------------------------------------------
#include "m_pd.h"
// utility header for Pd Spectral Toolkit project
#include "utility.h"
// disable compiler warnings on windows
#ifdef NT
#pragma warning( disable : 4244 )
#pragma warning( disable : 4305 )
#endif
#define COLOR_TABLE_SIZE 1000000
//------------------------------------------------------------------------------
// rgbtable_class - pointer to this object's definition
//------------------------------------------------------------------------------
t_class* rgbtable_class;
//------------------------------------------------------------------------------
// SCHEME_ID - enumerated color scheme names
//------------------------------------------------------------------------------
enum SCHEME_ID
{
RGB,
PURPLE_YELLOW,
BLUE_GREEN,
AMBER,
RED,
GREEN,
BLUE,
GREY
};
//------------------------------------------------------------------------------
// rgbtable - data structure holding this object's data
//------------------------------------------------------------------------------
typedef struct rgbtable
{
// this object - must always be first variable in struct
t_object object;
// float variable to hold input value
t_float value;
// id of the selected color scheme
t_int scheme_id;
// pointers to outlets
t_outlet* outlet_r;
t_outlet* outlet_g;
t_outlet* outlet_b;
// meta pointers to the color tables
t_float* r;
t_float* g;
t_float* b;
// pointers to the color tables
t_float* r_rgb;
t_float* g_rgb;
t_float* b_rgb;
t_float* r_py;
t_float* g_py;
t_float* b_py;
t_float* r_bg;
t_float* g_bg;
t_float* b_bg;
t_float* r_a;
t_float* g_a;
t_float* b_a;
t_float* r_r;
t_float* g_r;
t_float* b_r;
t_float* r_g;
t_float* g_g;
t_float* b_g;
t_float* r_b;
t_float* g_b;
t_float* b_b;
t_float* r_gr;
t_float* g_gr;
t_float* b_gr;
} t_rgbtable;
//------------------------------------------------------------------------------
// function prototypes
//------------------------------------------------------------------------------
void rgbtable_bang ( t_rgbtable* object );
void rgbtable_float ( t_rgbtable* object, t_floatarg number );
void rgbtable_set_scheme ( t_rgbtable* object );
void* rgbtable_new ( t_symbol* selector, t_int items, t_atom* list );
static void rgbtable_free ( t_rgbtable* object );
void rgbtable_setup ( void );
//------------------------------------------------------------------------------
// rgbtable_bang - causes output
//------------------------------------------------------------------------------
void rgbtable_bang( t_rgbtable* object )
{
// calculate table index
t_int index = object->value *= COLOR_TABLE_SIZE - 1;
// output rgb values
outlet_float( object->outlet_r, object->r[ index ] );
outlet_float( object->outlet_g, object->g[ index ] );
outlet_float( object->outlet_b, object->b[ index ] );
}
//------------------------------------------------------------------------------
// rgbtable_float - default float handler
//------------------------------------------------------------------------------
void rgbtable_float( t_rgbtable* object, t_floatarg number )
{
// store number in to the object's "value" variable
object->value = Clip( number, 0, 1 );
rgbtable_bang( object );
}
//------------------------------------------------------------------------------
// rgbtable_message_parse - parses incoming messages to set color tables
//------------------------------------------------------------------------------
void rgbtable_message_parse( t_rgbtable* object, t_symbol* selector, t_int items, t_atom* list )
{
// get selector string
const char* message = selector->s_name;
// rgb
if( StringMatch( message, "rgb" ) )
{
object->scheme_id = RGB;
}
// purple yellow
else if( StringMatch( message, "purple-yellow" ) )
{
object->scheme_id = PURPLE_YELLOW;
}
// blue green
else if( StringMatch( message, "blue-green" ) )
{
object->scheme_id = BLUE_GREEN;
}
// amber
else if( StringMatch( message, "amber" ) )
{
object->scheme_id = AMBER;
}
// red
else if( StringMatch( message, "red" ) )
{
object->scheme_id = RED;
}
// green
else if( StringMatch( message, "green" ) )
{
object->scheme_id = GREEN;
}
// blue
else if( StringMatch( message, "blue" ) )
{
object->scheme_id = BLUE;
}
// grey
else if( StringMatch( message, "grey" ) )
{
object->scheme_id = GREY;
}
// unknown
else
{
pd_error( object, "rgbtable: unknown color scheme name" );
}
rgbtable_set_scheme( object );
}
//------------------------------------------------------------------------------
// rgbtable_set_scheme - sets color scheme
//------------------------------------------------------------------------------
void rgbtable_set_scheme( t_rgbtable* object )
{
switch( object->scheme_id )
{
case RGB : object->r = object->r_rgb;
object->g = object->g_rgb;
object->b = object->b_rgb;
break;
case PURPLE_YELLOW : object->r = object->r_py;
object->g = object->g_py;
object->b = object->b_py;
break;
case BLUE_GREEN : object->r = object->r_bg;
object->g = object->g_bg;
object->b = object->b_bg;
break;
case AMBER : object->r = object->r_a;
object->g = object->g_a;
object->b = object->b_a;
break;
case RED : object->r = object->r_r;
object->g = object->g_r;
object->b = object->b_r;
break;
case GREEN : object->r = object->r_g;
object->g = object->g_g;
object->b = object->b_g;
break;
case BLUE : object->r = object->r_b;
object->g = object->g_b;
object->b = object->b_b;
break;
case GREY : object->r = object->r_b;
object->g = object->g_b;
object->b = object->b_b;
break;
}
}
//------------------------------------------------------------------------------
// rgbtable_new - initialize the object upon instantiation ( aka "constructor" )
//------------------------------------------------------------------------------
void* rgbtable_new( t_symbol* selector, t_int items, t_atom* list )
{
// declare a pointer to this class
t_rgbtable* object;
// generate a new object and save its pointer in "object"
object = ( t_rgbtable* )pd_new( rgbtable_class );
// generate outlets and save their pointers
object->outlet_r = outlet_new( &object->object, gensym( "float" ) );
object->outlet_g = outlet_new( &object->object, gensym( "float" ) );
object->outlet_b = outlet_new( &object->object, gensym( "float" ) );
// initialize the pointers
//--------------------------------------------------------------------------
// meta pointers
object->r = NULL;
object->g = NULL;
object->b = NULL;
// rgb
object->r_rgb = NULL;
object->g_rgb = NULL;
object->b_rgb = NULL;
// purple yellow
object->r_py = NULL;
object->g_py = NULL;
object->b_py = NULL;
// blue green
object->r_bg = NULL;
object->g_bg = NULL;
object->b_bg = NULL;
// amber
object->r_a = NULL;
object->g_a = NULL;
object->b_a = NULL;
// red
object->r_r = NULL;
object->g_r = NULL;
object->b_r = NULL;
// green
object->r_g = NULL;
object->g_g = NULL;
object->b_g = NULL;
// blue
object->r_b = NULL;
object->g_b = NULL;
object->b_b = NULL;
// grey
object->r_gr = NULL;
object->g_gr = NULL;
object->b_gr = NULL;
// allocate memory for the color tables
//--------------------------------------------------------------------------
// rgb
object->r_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_rgb = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// purple yellow
object->r_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_py = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// blue green
object->r_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_bg = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// amber
object->r_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_a = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// red
object->r_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_r = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// green
object->r_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_g = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// blue
object->r_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_b = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// grey
object->r_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->g_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
object->b_gr = calloc( COLOR_TABLE_SIZE, sizeof( float ) );
// color curve calculation variables
t_int i;
t_float x;
// iterate through the tables
for( i = 0 ; i < COLOR_TABLE_SIZE ; ++i )
{
// calculate x from 0 to 1
x = ( float )i / COLOR_TABLE_SIZE;
// calculate the color curves and store into tables
//----------------------------------------------------------------------
// rgb
object->r_rgb[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * x * x ) );
object->g_rgb[ i ] = 0.5 * ( 1.0 - Cosine( C_2_PI * x * x ) );
object->b_rgb[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) ) ) * Power( x, 0.75 ) * 3;
// purple yellow
object->r_py[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * Power( x, 1.5 ) ) );
object->g_py[ i ] = x * x * x * x;
object->b_py[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) ) ) * Power( x, 0.75 ) * 1.25;
// blue green
object->r_bg[ i ] = x * x * x * x;
object->g_bg[ i ] = 0.5 * ( 1.0 - Cosine( C_PI * Power( x, 1.5 ) ) );
object->b_bg[ i ] = ( 1.0 - ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) ) ) * Power( x, 0.75 ) * 1.25;
// amber
object->r_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->g_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
object->b_a[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
// red
object->r_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->g_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x * x ) ) );
object->b_r[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x * x ) ) );
// green
object->r_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
object->g_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
object->b_g[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
// blue
object->r_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x * x ) ) );
object->g_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x * x ) ) );
object->b_b[ i ] = ( 0.5 * ( 1.0 - Cosine( C_PI * x ) ) );
// grey
object->r_gr[ i ] = x;
object->g_gr[ i ] = x;
object->b_gr[ i ] = x;
}
// set default color scheme id
object->scheme_id = RGB;
// set the color scheme
rgbtable_set_scheme( object );
if( items > 0 )
{
if( list[ 0 ].a_type == A_SYMBOL )
{
t_symbol init_selector;
init_selector.s_name = list[ 0 ].a_w.w_symbol->s_name;
rgbtable_message_parse( object, &init_selector, 0, NULL );
}
else
{
// notify of invalid arguments
pd_error( object, "rgbtable: invalid argument type" );
}
}
if( items > 1 )
{
// notify of extra arguments
pd_error( object, "rgbtable: extra arguments ignored" );
}
// return the pointer to this class
return ( void* )object;
}
//------------------------------------------------------------------------------
// rgbtable_free - cleans up memory allocated by this object
//------------------------------------------------------------------------------
void rgbtable_free( t_rgbtable* object )
{
// if memory is allocated
// {
// deallocate the memory
// set the memory pointer to null
// }
// rgb
if( object->r_rgb )
{
free( object->r_rgb );
object->r_rgb = NULL;
}
if( object->g_rgb )
{
free( object->g_rgb );
object->g_rgb = NULL;
}
if( object->b_rgb )
{
free( object->b_rgb );
object->b_rgb = NULL;
}
// purple yellow
if( object->r_py )
{
free( object->r_py );
object->r_py = NULL;
}
if( object->g_py )
{
free( object->g_py );
object->g_py = NULL;
}
if( object->b_py )
{
free( object->b_py );
object->b_py = NULL;
}
// blue green
if( object->r_bg )
{
free( object->r_bg );
object->r_bg = NULL;
}
if( object->g_bg )
{
free( object->g_bg );
object->g_bg = NULL;
}
if( object->b_bg )
{
free( object->b_bg );
object->b_bg = NULL;
}
// amber
if( object->r_a )
{
free( object->r_a );
object->r_a = NULL;
}
if( object->g_a )
{
free( object->g_a );
object->g_a = NULL;
}
if( object->b_a )
{
free( object->b_a );
object->b_a = NULL;
}
// red
if( object->r_r )
{
free( object->r_r );
object->r_r = NULL;
}
if( object->g_r )
{
free( object->g_r );
object->g_r = NULL;
}
if( object->b_r )
{
free( object->b_r );
object->b_r = NULL;
}
// green
if( object->r_g )
{
free( object->r_g );
object->r_g = NULL;
}
if( object->g_g )
{
free( object->g_g );
object->g_g = NULL;
}
if( object->b_g )
{
free( object->b_g );
object->b_g = NULL;
}
// blue
if( object->r_b )
{
free( object->r_b );
object->r_b = NULL;
}
if( object->g_b )
{
free( object->g_b );
object->g_b = NULL;
}
if( object->b_b )
{
free( object->b_b );
object->b_b = NULL;
}
}
//------------------------------------------------------------------------------
// rgbtable setup - defines this object and its properties to Pd
//------------------------------------------------------------------------------
void rgbtable_setup( void )
{
// create a new class and assign its pointer to rgbtable_class
rgbtable_class = class_new( gensym( "rgbtable" ), ( t_newmethod )rgbtable_new, ( t_method )rgbtable_free, sizeof( t_rgbtable ), 0, A_GIMME, 0 );
// add default float handler
class_addfloat( rgbtable_class, rgbtable_float );
// add default bang handler
class_addbang( rgbtable_class, rgbtable_bang );
// add message handler
class_addmethod( rgbtable_class, ( t_method )rgbtable_message_parse, gensym( "anything" ), A_GIMME, 0 );
}
//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------