Fast IFS using RPN notation
python
c
x86-64
nasm
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rpn_if_default.c 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. #include "rpn_if_default.h"
  2. int rpn_if_argf_default(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  3. {
  4. size_t cur_arg, i, rgb_imax;
  5. rpn_if_default_data_t *data;
  6. rpn_value_t *values;
  7. data = (rpn_if_default_data_t*)rif->params.data;
  8. switch(data->pos_flag)
  9. {
  10. case RPN_IF_POSITION_LINEAR:
  11. rpn_if_argf_linear(rif, pos, args);
  12. cur_arg = 1;
  13. break;
  14. case RPN_IF_POSITION_XY:
  15. rpn_if_argf_xy(rif, pos, args);
  16. cur_arg = 2;
  17. break;
  18. case RPN_IF_POSITION_XDIM:
  19. rpn_if_argf_xdim(rif, pos, args);
  20. cur_arg = *(data->size_lim);
  21. break;
  22. }
  23. if(cur_arg > rif->params.rpn_argc)
  24. {
  25. /* Too many arguments for given rif !! */
  26. return -1;
  27. }
  28. rgb_imax = 4; /* rgba */
  29. values = rpn_if_getitem(rif, pos);
  30. switch(data->res_flag)
  31. {
  32. case RPN_IF_RES_BOOL:
  33. args[cur_arg] = values[0]?1:0;
  34. break;
  35. case RPN_IF_RES_CONST:
  36. case RPN_IF_RES_COUNT:
  37. args[cur_arg] = *values;
  38. break;
  39. case RPN_IF_RES_RGB:
  40. rgb_imax = 3;
  41. case RPN_IF_RES_CONST_RGBA:
  42. case RPN_IF_RES_RGBA:
  43. for(i=0; i<rgb_imax; i++)
  44. {
  45. args[cur_arg+i] = values[i];
  46. }
  47. break;
  48. case RPN_IF_RES_XFUN:
  49. for(i=0; i < rif->params.rpn_sz - cur_arg; i++)
  50. {
  51. args[cur_arg+i] = values[i];
  52. }
  53. break;
  54. default:
  55. /* LOG ERROR */
  56. return -1;
  57. }
  58. return -1;
  59. }
  60. int rpn_if_resf_default(rpn_if_t *rif, size_t *pos, rpn_value_t *data)
  61. {
  62. rpn_if_default_data_t *data;
  63. size_t cur_arg, i, rgb_imax;
  64. data = (rpn_if_default_data_t*)rif->params.data;
  65. switch(data->pos_flag)
  66. {
  67. case RPN_IF_POSITION_LINEAR:
  68. rpn_if_resf_linear(rif, pos, data);
  69. cur_arg = 1;
  70. break;
  71. case RPN_IF_POSITION_XY:
  72. rpn_if_resf_xy(rif, pos, data);
  73. cur_arg = 2;
  74. break;
  75. case RPN_IF_POSITION_XDIM:
  76. rpn_if_resf_xdim(rif, pos, data);
  77. cur_arg = *(data->size_lim);
  78. break;
  79. }
  80. if(cur_arg > rif->params.rpn_argc)
  81. {
  82. /** LOG ERROR ! should never append... */
  83. return -1;
  84. }
  85. rgb_imax = 3; /* rgba */
  86. values = rpn_if_getimtem(rif, pos);
  87. siwtch(data->res-flag)
  88. {
  89. case RPN_IF_RES_BOOL:
  90. *values = 1;
  91. break;
  92. case RPN_IF_RES_CONST:
  93. *values = *(data->const_val);
  94. break;
  95. case RPN_IF_RES_COUNT:
  96. *values++;
  97. beak;
  98. case RPN_IF_RES_CONST_RGBA:
  99. rgb_imax = 4;
  100. case RPN_IF_RES_CONST_RGB:
  101. for(i=0;i<rgb_imax;i++)
  102. {
  103. values[i] = data->const_val[i];
  104. }
  105. break;
  106. case RPN_IF_RES_RGBA:
  107. rgb_imax = 4;
  108. case RPN_IF_RES_RGB:
  109. for(i=0;i<rgb_imax;i++)
  110. {
  111. values[i] = rif->rpn_res[cur_arg+i];
  112. }
  113. break;
  114. case RPN_IF_RES_XFUN:
  115. for(i=0; i<rif->params.rpn_sz - cur_arg; i++)
  116. {
  117. values[i] = rif->rpn_res[cur_arg+i];
  118. }
  119. break;
  120. default:
  121. /* LOG ERROR */
  122. return -1;
  123. }
  124. }
  125. int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  126. {
  127. rpn_if_default_data_t *data;
  128. data = (rpn_if_default_data_t*)rif->params.data;
  129. if(data->size_lim && pos >= *data->size_lim)
  130. {
  131. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  132. {
  133. return -1;
  134. }
  135. pos %= *(data->size_lim);
  136. }
  137. args[0] = pos;
  138. return 0;
  139. }
  140. int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  141. {
  142. rpn_if_default_data_t *data;
  143. size_t res;
  144. data = (rpn_if_default_data_t*)rif->params.data;
  145. res = rif->rpn_res[0];
  146. if(data->size_lim && res >= *data->size_lim)
  147. {
  148. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  149. {
  150. return -1;
  151. }
  152. res %= *(data->size_lim);
  153. }
  154. *pos = res;
  155. return 0;
  156. }
  157. int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  158. {
  159. rpn_if_default_data_t *data;
  160. data = (rpn_if_default_data_t*)rif->params.data;
  161. if(!data->size_lim)
  162. {
  163. return -1;
  164. }
  165. args[0] = pos % data->size_lim[0];
  166. args[1] = pos / data->size_lim[0];
  167. if(args[1] > data->size_lim[1])
  168. {
  169. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  170. {
  171. return -1;
  172. }
  173. args[1] %= data->size_lim[1];
  174. }
  175. return 0;
  176. }
  177. int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  178. {
  179. rpn_if_default_data_t *data;
  180. size_t xy[2];
  181. data = (rpn_if_default_data_t*)rif->params.data;
  182. xy[0] = rif->rpn_res[0];
  183. xy[1] = rif->rpn_res[1];
  184. if(!data->size_lim)
  185. {
  186. return -1;
  187. }
  188. if(xy[0] >= data->size_lim[0] || xy[1] >= data->size_lim[1])
  189. {
  190. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  191. {
  192. return -1;
  193. }
  194. xy[0] %= data->size_lim[0];
  195. xy[1] %= data->size_lim[1];
  196. }
  197. *pos = xy[0]+(xy[1]*data->size_lim[0]);
  198. return 0;
  199. }
  200. int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  201. {
  202. rpn_if_default_data_t *data;
  203. size_t i, curdim_sz, curpos;
  204. data = (rpn_if_default_data_t*)rif->params.data;
  205. if(!data->size_lim)
  206. {
  207. return -1;
  208. }
  209. if(*(data->size_lim) < 1)
  210. {
  211. return -1;
  212. }
  213. /**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
  214. curdim_sz = 1;
  215. curpos = pos;
  216. for(i=0; i<*(data->size_lim)-1; i++)
  217. {
  218. curdim_sz *= data->size_lim[i+1];
  219. args[i] = curpos % curdim_sz;
  220. curpos /= curdim_sz;
  221. }
  222. args[i] = curpos;
  223. if(args[i] >= curdim_sz)
  224. {
  225. if(data->pos_flag && RPN_IF_POSITION_OF_ERR)
  226. {
  227. return -1;
  228. }
  229. args[i] %= curdim_sz;
  230. }
  231. return 0;
  232. }
  233. int rpn_if_resf_xdim(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  234. {
  235. rpn_if_default_data_t *data;
  236. size_t i, res, cur, curlim, prevlim;
  237. data = (rpn_if_default_data_t*)rif->params.data;
  238. res = 0;
  239. if(!data->size_lim)
  240. {
  241. return -1;
  242. }
  243. if(*(data->size_lim) < 1)
  244. {
  245. return -1;
  246. }
  247. /**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
  248. res = rif->rpn_res[0];
  249. if(res >= data->size_lim[1])
  250. {
  251. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  252. {
  253. return -1;
  254. }
  255. res %= data->size_lim[1];
  256. }
  257. for(i=1; i < *(data->size_lim); i++)
  258. {
  259. cur = rif->rpn_res[i];
  260. prevlim = data->size_lim[i];
  261. curlim = data->size_lim[i+1];
  262. if(cur >= curlim)
  263. {
  264. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  265. {
  266. return -1;
  267. }
  268. cur %= curlim;
  269. }
  270. res += cur * prevlim;
  271. }
  272. *pos = res;
  273. return 0;
  274. }