hackthelobby/libcaca/ruby/caca-dither.c

210 lines
6.6 KiB
C

/*
* libcaca Ruby bindings
* Copyright (c) 2007-2012 Pascal Terjan <pterjan@linuxfr.org>
*
* This library is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What the Fuck You Want
* to Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details.
*/
#include <ruby.h>
#include <caca.h>
#include <errno.h>
#include "common.h"
VALUE cDither;
void dither_free(void *dither)
{
caca_free_dither((caca_dither_t *)dither);
}
static VALUE dither_alloc(VALUE klass)
{
VALUE obj;
obj = Data_Wrap_Struct(klass, 0, dither_free, NULL);
return obj;
}
static VALUE dither_initialize(VALUE self, VALUE bpp, VALUE w, VALUE h, VALUE pitch, VALUE rmask, VALUE gmask, VALUE bmask, VALUE amask)
{
caca_dither_t *dither;
dither = caca_create_dither(NUM2UINT(bpp), NUM2UINT(w), NUM2UINT(h), NUM2UINT(pitch), NUM2ULONG(rmask), NUM2ULONG(gmask), NUM2ULONG(bmask), NUM2ULONG(amask));
if(dither == NULL)
{
rb_raise(rb_eRuntimeError, "%s", strerror(errno));
}
_SELF = dither;
return self;
}
static VALUE set_dither_palette(VALUE self, VALUE palette)
{
int i;
unsigned int *red, *blue, *green, *alpha;
VALUE v, r, g, b, a;
int error = 0;
if(RARRAY_LEN(palette) != 256)
{
rb_raise(rb_eArgError, "Palette must contain 256 elements");
}
red = ALLOC_N(unsigned int, 256);
if(!red)
rb_raise(rb_eNoMemError,"Out of memory");
green = ALLOC_N(unsigned int, 256);
if(!green)
{
free(red);
rb_raise(rb_eNoMemError,"Out of memory");
}
blue = ALLOC_N(unsigned int, 256);
if(!blue)
{
free(red);
free(green);
rb_raise(rb_eNoMemError,"Out of memory");
}
alpha = ALLOC_N(unsigned int, 256);
if(!alpha)
{
free(red);
free(green);
free(blue);
rb_raise(rb_eNoMemError,"Out of memory");
}
for(i=0; i<256; i++)
{
v = rb_ary_entry(palette, i);
if((TYPE(v) == T_ARRAY) && (RARRAY_LEN(v) == 4))
{
r = rb_ary_entry(v,0);
g = rb_ary_entry(v,1);
b = rb_ary_entry(v,2);
a = rb_ary_entry(v,3);
if(rb_obj_is_kind_of(r, rb_cInteger) &&
rb_obj_is_kind_of(g, rb_cInteger) &&
rb_obj_is_kind_of(b, rb_cInteger) &&
rb_obj_is_kind_of(a, rb_cInteger))
{
red[i] = NUM2INT(r);
green[i] = NUM2INT(g);
blue[i] = NUM2INT(b);
alpha[i] = NUM2INT(a);
} else
error = 1;
}
else
error = 1;
}
if(error)
{
free(red);
free(green);
free(blue);
free(alpha);
rb_raise(rb_eArgError, "Invalid palette");
}
if(caca_set_dither_palette(_SELF, red, green, blue, alpha)<0)
{
free(red);
free(green);
free(blue);
free(alpha);
rb_raise(rb_eRuntimeError, "%s", strerror(errno));
}
free(red);
free(green);
free(blue);
free(alpha);
return palette;
}
static VALUE set_dither_palette2(VALUE self, VALUE palette)
{
set_dither_palette(self, palette);
return self;
}
#define set_float(x) \
static VALUE set_##x(VALUE self, VALUE x) \
{ \
if(caca_set_dither_##x(_SELF, (float)NUM2DBL(x))<0) \
rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
\
return x; \
} \
\
static VALUE set_##x##2(VALUE self, VALUE x) \
{ \
set_##x(self, x); \
return self; \
}
set_float(brightness)
set_float(gamma)
set_float(contrast)
#define get_set_str_from_list(x) \
get_double_list(dither_##x) \
static VALUE set_dither_##x(VALUE self, VALUE x) \
{ \
if(caca_set_dither_##x(_SELF, StringValuePtr(x))<0) \
{ \
rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
} \
return x; \
} \
\
static VALUE set_dither_##x##2(VALUE self, VALUE x) \
{ \
set_dither_##x(self, x); \
return self; \
}
get_set_str_from_list(antialias)
get_set_str_from_list(color)
get_set_str_from_list(charset)
get_set_str_from_list(algorithm)
void Init_caca_dither(VALUE mCaca)
{
cDither = rb_define_class_under(mCaca, "Dither", rb_cObject);
rb_define_alloc_func(cDither, dither_alloc);
rb_define_method(cDither, "initialize", dither_initialize, 8);
rb_define_method(cDither, "palette=", set_dither_palette, 1);
rb_define_method(cDither, "set_palette", set_dither_palette2, 1);
rb_define_method(cDither, "brightness=", set_brightness, 1);
rb_define_method(cDither, "set_brightness", set_brightness2, 1);
rb_define_method(cDither, "gamma=", set_gamma, 1);
rb_define_method(cDither, "set_gamma", set_gamma2, 1);
rb_define_method(cDither, "contrast=", set_contrast, 1);
rb_define_method(cDither, "set_contrast", set_contrast2, 1);
rb_define_method(cDither, "antialias_list", dither_antialias_list, 0);
rb_define_method(cDither, "antialias=", set_dither_antialias, 1);
rb_define_method(cDither, "set_antialias", set_dither_antialias2, 1);
rb_define_method(cDither, "color_list", dither_color_list, 0);
rb_define_method(cDither, "color=", set_dither_color, 1);
rb_define_method(cDither, "set_color", set_dither_color2, 1);
rb_define_method(cDither, "charset_list", dither_charset_list, 0);
rb_define_method(cDither, "charset=", set_dither_charset, 1);
rb_define_method(cDither, "set_charset", set_dither_charset2, 1);
rb_define_method(cDither, "algorithm_list", dither_algorithm_list, 0);
rb_define_method(cDither, "algorithm=", set_dither_algorithm, 1);
rb_define_method(cDither, "set_algorithm", set_dither_algorithm2, 1);
}