210 lines
6.6 KiB
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);
|
|
}
|
|
|