Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 
 
 

210 рядки
6.6 KiB

  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. #include <ruby.h>
  12. #include <caca.h>
  13. #include <errno.h>
  14. #include "common.h"
  15. VALUE cDither;
  16. void dither_free(void *dither)
  17. {
  18. caca_free_dither((caca_dither_t *)dither);
  19. }
  20. static VALUE dither_alloc(VALUE klass)
  21. {
  22. VALUE obj;
  23. obj = Data_Wrap_Struct(klass, 0, dither_free, NULL);
  24. return obj;
  25. }
  26. static VALUE dither_initialize(VALUE self, VALUE bpp, VALUE w, VALUE h, VALUE pitch, VALUE rmask, VALUE gmask, VALUE bmask, VALUE amask)
  27. {
  28. caca_dither_t *dither;
  29. dither = caca_create_dither(NUM2UINT(bpp), NUM2UINT(w), NUM2UINT(h), NUM2UINT(pitch), NUM2ULONG(rmask), NUM2ULONG(gmask), NUM2ULONG(bmask), NUM2ULONG(amask));
  30. if(dither == NULL)
  31. {
  32. rb_raise(rb_eRuntimeError, "%s", strerror(errno));
  33. }
  34. _SELF = dither;
  35. return self;
  36. }
  37. static VALUE set_dither_palette(VALUE self, VALUE palette)
  38. {
  39. int i;
  40. unsigned int *red, *blue, *green, *alpha;
  41. VALUE v, r, g, b, a;
  42. int error = 0;
  43. if(RARRAY_LEN(palette) != 256)
  44. {
  45. rb_raise(rb_eArgError, "Palette must contain 256 elements");
  46. }
  47. red = ALLOC_N(unsigned int, 256);
  48. if(!red)
  49. rb_raise(rb_eNoMemError,"Out of memory");
  50. green = ALLOC_N(unsigned int, 256);
  51. if(!green)
  52. {
  53. free(red);
  54. rb_raise(rb_eNoMemError,"Out of memory");
  55. }
  56. blue = ALLOC_N(unsigned int, 256);
  57. if(!blue)
  58. {
  59. free(red);
  60. free(green);
  61. rb_raise(rb_eNoMemError,"Out of memory");
  62. }
  63. alpha = ALLOC_N(unsigned int, 256);
  64. if(!alpha)
  65. {
  66. free(red);
  67. free(green);
  68. free(blue);
  69. rb_raise(rb_eNoMemError,"Out of memory");
  70. }
  71. for(i=0; i<256; i++)
  72. {
  73. v = rb_ary_entry(palette, i);
  74. if((TYPE(v) == T_ARRAY) && (RARRAY_LEN(v) == 4))
  75. {
  76. r = rb_ary_entry(v,0);
  77. g = rb_ary_entry(v,1);
  78. b = rb_ary_entry(v,2);
  79. a = rb_ary_entry(v,3);
  80. if(rb_obj_is_kind_of(r, rb_cInteger) &&
  81. rb_obj_is_kind_of(g, rb_cInteger) &&
  82. rb_obj_is_kind_of(b, rb_cInteger) &&
  83. rb_obj_is_kind_of(a, rb_cInteger))
  84. {
  85. red[i] = NUM2INT(r);
  86. green[i] = NUM2INT(g);
  87. blue[i] = NUM2INT(b);
  88. alpha[i] = NUM2INT(a);
  89. } else
  90. error = 1;
  91. }
  92. else
  93. error = 1;
  94. }
  95. if(error)
  96. {
  97. free(red);
  98. free(green);
  99. free(blue);
  100. free(alpha);
  101. rb_raise(rb_eArgError, "Invalid palette");
  102. }
  103. if(caca_set_dither_palette(_SELF, red, green, blue, alpha)<0)
  104. {
  105. free(red);
  106. free(green);
  107. free(blue);
  108. free(alpha);
  109. rb_raise(rb_eRuntimeError, "%s", strerror(errno));
  110. }
  111. free(red);
  112. free(green);
  113. free(blue);
  114. free(alpha);
  115. return palette;
  116. }
  117. static VALUE set_dither_palette2(VALUE self, VALUE palette)
  118. {
  119. set_dither_palette(self, palette);
  120. return self;
  121. }
  122. #define set_float(x) \
  123. static VALUE set_##x(VALUE self, VALUE x) \
  124. { \
  125. if(caca_set_dither_##x(_SELF, (float)NUM2DBL(x))<0) \
  126. rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
  127. \
  128. return x; \
  129. } \
  130. \
  131. static VALUE set_##x##2(VALUE self, VALUE x) \
  132. { \
  133. set_##x(self, x); \
  134. return self; \
  135. }
  136. set_float(brightness)
  137. set_float(gamma)
  138. set_float(contrast)
  139. #define get_set_str_from_list(x) \
  140. get_double_list(dither_##x) \
  141. static VALUE set_dither_##x(VALUE self, VALUE x) \
  142. { \
  143. if(caca_set_dither_##x(_SELF, StringValuePtr(x))<0) \
  144. { \
  145. rb_raise(rb_eRuntimeError, "%s", strerror(errno)); \
  146. } \
  147. return x; \
  148. } \
  149. \
  150. static VALUE set_dither_##x##2(VALUE self, VALUE x) \
  151. { \
  152. set_dither_##x(self, x); \
  153. return self; \
  154. }
  155. get_set_str_from_list(antialias)
  156. get_set_str_from_list(color)
  157. get_set_str_from_list(charset)
  158. get_set_str_from_list(algorithm)
  159. void Init_caca_dither(VALUE mCaca)
  160. {
  161. cDither = rb_define_class_under(mCaca, "Dither", rb_cObject);
  162. rb_define_alloc_func(cDither, dither_alloc);
  163. rb_define_method(cDither, "initialize", dither_initialize, 8);
  164. rb_define_method(cDither, "palette=", set_dither_palette, 1);
  165. rb_define_method(cDither, "set_palette", set_dither_palette2, 1);
  166. rb_define_method(cDither, "brightness=", set_brightness, 1);
  167. rb_define_method(cDither, "set_brightness", set_brightness2, 1);
  168. rb_define_method(cDither, "gamma=", set_gamma, 1);
  169. rb_define_method(cDither, "set_gamma", set_gamma2, 1);
  170. rb_define_method(cDither, "contrast=", set_contrast, 1);
  171. rb_define_method(cDither, "set_contrast", set_contrast2, 1);
  172. rb_define_method(cDither, "antialias_list", dither_antialias_list, 0);
  173. rb_define_method(cDither, "antialias=", set_dither_antialias, 1);
  174. rb_define_method(cDither, "set_antialias", set_dither_antialias2, 1);
  175. rb_define_method(cDither, "color_list", dither_color_list, 0);
  176. rb_define_method(cDither, "color=", set_dither_color, 1);
  177. rb_define_method(cDither, "set_color", set_dither_color2, 1);
  178. rb_define_method(cDither, "charset_list", dither_charset_list, 0);
  179. rb_define_method(cDither, "charset=", set_dither_charset, 1);
  180. rb_define_method(cDither, "set_charset", set_dither_charset2, 1);
  181. rb_define_method(cDither, "algorithm_list", dither_algorithm_list, 0);
  182. rb_define_method(cDither, "algorithm=", set_dither_algorithm, 1);
  183. rb_define_method(cDither, "set_algorithm", set_dither_algorithm2, 1);
  184. }