1 /*
2 * libcaca Ruby bindings
3 * Copyright (c) 2007-2012 Pascal Terjan <pterjan@linuxfr.org>
4 *
5 * This library is free software. It comes without any warranty, to
6 * the extent permitted by applicable law. You can redistribute it
7 * and/or modify it under the terms of the Do What the Fuck You Want
8 * to Public License, Version 2, as published by Sam Hocevar. See
9 * http://www.wtfpl.net/ for more details.
10 */
11
12 #include <ruby.h>
13 #include <caca.h>
14 #include <errno.h>
15 #include "common.h"
16
17 VALUE cDither;
18
dither_free(void * dither)19 void dither_free(void *dither)
20 {
21 caca_free_dither((caca_dither_t *)dither);
22 }
23
dither_alloc(VALUE klass)24 static VALUE dither_alloc(VALUE klass)
25 {
26 VALUE obj;
27 obj = Data_Wrap_Struct(klass, 0, dither_free, NULL);
28 return obj;
29 }
30
dither_initialize(VALUE self,VALUE bpp,VALUE w,VALUE h,VALUE pitch,VALUE rmask,VALUE gmask,VALUE bmask,VALUE amask)31 static VALUE dither_initialize(VALUE self, VALUE bpp, VALUE w, VALUE h, VALUE pitch, VALUE rmask, VALUE gmask, VALUE bmask, VALUE amask)
32 {
33 caca_dither_t *dither;
34
35 dither = caca_create_dither(NUM2UINT(bpp), NUM2UINT(w), NUM2UINT(h), NUM2UINT(pitch), NUM2ULONG(rmask), NUM2ULONG(gmask), NUM2ULONG(bmask), NUM2ULONG(amask));
36 if(dither == NULL)
37 {
38 rb_raise(rb_eRuntimeError, "%s", strerror(errno));
39 }
40 _SELF = dither;
41 return self;
42 }
43
set_dither_palette(VALUE self,VALUE palette)44 static VALUE set_dither_palette(VALUE self, VALUE palette)
45 {
46 int i;
47 unsigned int *red, *blue, *green, *alpha;
48 VALUE v, r, g, b, a;
49 int error = 0;
50
51 if(RARRAY_LEN(palette) != 256)
52 {
53 rb_raise(rb_eArgError, "Palette must contain 256 elements");
54 }
55
56 red = ALLOC_N(unsigned int, 256);
57 if(!red)
58 rb_raise(rb_eNoMemError,"Out of memory");
59
60 green = ALLOC_N(unsigned int, 256);
61 if(!green)
62 {
63 free(red);
64 rb_raise(rb_eNoMemError,"Out of memory");
65 }
66
67 blue = ALLOC_N(unsigned int, 256);
68 if(!blue)
69 {
70 free(red);
71 free(green);
72 rb_raise(rb_eNoMemError,"Out of memory");
73 }
74
75 alpha = ALLOC_N(unsigned int, 256);
76 if(!alpha)
77 {
78 free(red);
79 free(green);
80 free(blue);
81 rb_raise(rb_eNoMemError,"Out of memory");
82 }
83
84 for(i=0; i<256; i++)
85 {
86 v = rb_ary_entry(palette, i);
87 if((TYPE(v) == T_ARRAY) && (RARRAY_LEN(v) == 4))
88 {
89 r = rb_ary_entry(v,0);
90 g = rb_ary_entry(v,1);
91 b = rb_ary_entry(v,2);
92 a = rb_ary_entry(v,3);
93 if(rb_obj_is_kind_of(r, rb_cInteger) &&
94 rb_obj_is_kind_of(g, rb_cInteger) &&
95 rb_obj_is_kind_of(b, rb_cInteger) &&
96 rb_obj_is_kind_of(a, rb_cInteger))
97 {
98 red[i] = NUM2INT(r);
99 green[i] = NUM2INT(g);
100 blue[i] = NUM2INT(b);
101 alpha[i] = NUM2INT(a);
102 } else
103 error = 1;
104 }
105 else
106 error = 1;
107 }
108
109 if(error)
110 {
111 free(red);
112 free(green);
113 free(blue);
114 free(alpha);
115 rb_raise(rb_eArgError, "Invalid palette");
116 }
117
118 if(caca_set_dither_palette(_SELF, red, green, blue, alpha)<0)
119 {
120 free(red);
121 free(green);
122 free(blue);
123 free(alpha);
124 rb_raise(rb_eRuntimeError, "%s", strerror(errno));
125 }
126
127 free(red);
128 free(green);
129 free(blue);
130 free(alpha);
131
132 return palette;
133 }
134
set_dither_palette2(VALUE self,VALUE palette)135 static VALUE set_dither_palette2(VALUE self, VALUE palette)
136 {
137 set_dither_palette(self, palette);
138 return self;
139 }
140
141 #define set_float(x) \
142 static VALUE set_##x(VALUE self, VALUE x) \
143 { \
144 if(caca_set_dither_##x(_SELF, (float)NUM2DBL(x))<0) \
145 rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
146 \
147 return x; \
148 } \
149 \
150 static VALUE set_##x##2(VALUE self, VALUE x) \
151 { \
152 set_##x(self, x); \
153 return self; \
154 }
155
156 set_float(brightness)
set_float(gamma)157 set_float(gamma)
158 set_float(contrast)
159
160 #define get_set_str_from_list(x) \
161 get_double_list(dither_##x) \
162 static VALUE set_dither_##x(VALUE self, VALUE x) \
163 { \
164 if(caca_set_dither_##x(_SELF, StringValuePtr(x))<0) \
165 { \
166 rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
167 } \
168 return x; \
169 } \
170 \
171 static VALUE set_dither_##x##2(VALUE self, VALUE x) \
172 { \
173 set_dither_##x(self, x); \
174 return self; \
175 }
176
177 get_set_str_from_list(antialias)
178 get_set_str_from_list(color)
179 get_set_str_from_list(charset)
180 get_set_str_from_list(algorithm)
181
182 void Init_caca_dither(VALUE mCaca)
183 {
184 cDither = rb_define_class_under(mCaca, "Dither", rb_cObject);
185 rb_define_alloc_func(cDither, dither_alloc);
186
187 rb_define_method(cDither, "initialize", dither_initialize, 8);
188 rb_define_method(cDither, "palette=", set_dither_palette, 1);
189 rb_define_method(cDither, "set_palette", set_dither_palette2, 1);
190 rb_define_method(cDither, "brightness=", set_brightness, 1);
191 rb_define_method(cDither, "set_brightness", set_brightness2, 1);
192 rb_define_method(cDither, "gamma=", set_gamma, 1);
193 rb_define_method(cDither, "set_gamma", set_gamma2, 1);
194 rb_define_method(cDither, "contrast=", set_contrast, 1);
195 rb_define_method(cDither, "set_contrast", set_contrast2, 1);
196 rb_define_method(cDither, "antialias_list", dither_antialias_list, 0);
197 rb_define_method(cDither, "antialias=", set_dither_antialias, 1);
198 rb_define_method(cDither, "set_antialias", set_dither_antialias2, 1);
199 rb_define_method(cDither, "color_list", dither_color_list, 0);
200 rb_define_method(cDither, "color=", set_dither_color, 1);
201 rb_define_method(cDither, "set_color", set_dither_color2, 1);
202 rb_define_method(cDither, "charset_list", dither_charset_list, 0);
203 rb_define_method(cDither, "charset=", set_dither_charset, 1);
204 rb_define_method(cDither, "set_charset", set_dither_charset2, 1);
205 rb_define_method(cDither, "algorithm_list", dither_algorithm_list, 0);
206 rb_define_method(cDither, "algorithm=", set_dither_algorithm, 1);
207 rb_define_method(cDither, "set_algorithm", set_dither_algorithm2, 1);
208 }
209
210