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.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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 *res)
  61. {
  62. rpn_if_default_data_t *data;
  63. size_t cur_arg, i, rgb_imax;
  64. rpn_value_t *values;
  65. data = (rpn_if_default_data_t*)rif->params->data;
  66. switch(data->pos_flag)
  67. {
  68. case RPN_IF_POSITION_LINEAR:
  69. rpn_if_resf_linear(rif, pos, res);
  70. cur_arg = 1;
  71. break;
  72. case RPN_IF_POSITION_XY:
  73. rpn_if_resf_xy(rif, pos, res);
  74. cur_arg = 2;
  75. break;
  76. case RPN_IF_POSITION_XDIM:
  77. rpn_if_resf_xdim(rif, pos, res);
  78. cur_arg = *(data->size_lim);
  79. break;
  80. }
  81. if(cur_arg > rif->params->rpn_argc)
  82. {
  83. /** LOG ERROR ! should never append... */
  84. return -1;
  85. }
  86. rgb_imax = 3; /* rgba */
  87. values = rpn_if_getitem(rif, *pos);
  88. /**@todo if(res) set the values in res too ! */
  89. switch(data->res_flag)
  90. {
  91. case RPN_IF_RES_BOOL:
  92. *values = 1;
  93. break;
  94. case RPN_IF_RES_CONST:
  95. *values = *(data->const_val);
  96. break;
  97. case RPN_IF_RES_COUNT:
  98. (*values)++;
  99. break;
  100. case RPN_IF_RES_CONST_RGBA:
  101. rgb_imax = 4;
  102. //case RPN_IF_RES_CONST_RGB:
  103. for(i=0;i<rgb_imax;i++)
  104. {
  105. values[i] = data->const_val[i];
  106. }
  107. break;
  108. case RPN_IF_RES_RGBA:
  109. rgb_imax = 4;
  110. case RPN_IF_RES_RGB:
  111. for(i=0;i<rgb_imax;i++)
  112. {
  113. values[i] = rif->rpn_res[cur_arg+i];
  114. }
  115. break;
  116. case RPN_IF_RES_XFUN:
  117. for(i=0; i<rif->params->rpn_sz - cur_arg; i++)
  118. {
  119. values[i] = rif->rpn_res[cur_arg+i];
  120. }
  121. break;
  122. default:
  123. /* LOG ERROR */
  124. return -1;
  125. }
  126. return 0;
  127. }
  128. int rpn_if_argf_linear(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  129. {
  130. rpn_if_default_data_t *data;
  131. data = (rpn_if_default_data_t*)rif->params->data;
  132. if(data->size_lim && pos >= *data->size_lim)
  133. {
  134. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  135. {
  136. return -1;
  137. }
  138. pos %= *(data->size_lim);
  139. }
  140. args[0] = pos;
  141. return 0;
  142. }
  143. int rpn_if_resf_linear(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  144. {
  145. rpn_if_default_data_t *data;
  146. size_t res;
  147. data = (rpn_if_default_data_t*)rif->params->data;
  148. res = rif->rpn_res[0];
  149. if(data->size_lim && res >= *data->size_lim)
  150. {
  151. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  152. {
  153. return -1;
  154. }
  155. res %= *(data->size_lim);
  156. }
  157. *pos = res;
  158. return 0;
  159. }
  160. int rpn_if_argf_xy(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  161. {
  162. rpn_if_default_data_t *data;
  163. data = (rpn_if_default_data_t*)rif->params->data;
  164. if(!data->size_lim)
  165. {
  166. return -1;
  167. }
  168. args[0] = pos % data->size_lim[0];
  169. args[1] = pos / data->size_lim[0];
  170. if(args[1] > data->size_lim[1])
  171. {
  172. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  173. {
  174. return -1;
  175. }
  176. args[1] %= data->size_lim[1];
  177. }
  178. return 0;
  179. }
  180. int rpn_if_resf_xy(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  181. {
  182. rpn_if_default_data_t *data;
  183. size_t xy[2];
  184. data = (rpn_if_default_data_t*)rif->params->data;
  185. xy[0] = rif->rpn_res[0];
  186. xy[1] = rif->rpn_res[1];
  187. if(!data->size_lim)
  188. {
  189. return -1;
  190. }
  191. if(xy[0] >= data->size_lim[0] || xy[1] >= data->size_lim[1])
  192. {
  193. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  194. {
  195. return -1;
  196. }
  197. xy[0] %= data->size_lim[0];
  198. xy[1] %= data->size_lim[1];
  199. }
  200. *pos = xy[0]+(xy[1]*data->size_lim[0]);
  201. return 0;
  202. }
  203. int rpn_if_argf_xdim(rpn_if_t *rif, size_t pos, rpn_value_t *args)
  204. {
  205. rpn_if_default_data_t *data;
  206. size_t i, curdim_sz, curpos;
  207. data = (rpn_if_default_data_t*)rif->params->data;
  208. if(!data->size_lim)
  209. {
  210. return -1;
  211. }
  212. if(*(data->size_lim) < 1)
  213. {
  214. return -1;
  215. }
  216. /**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
  217. curdim_sz = 1;
  218. curpos = pos;
  219. for(i=0; i<*(data->size_lim)-1; i++)
  220. {
  221. curdim_sz *= data->size_lim[i+1];
  222. args[i] = curpos % curdim_sz;
  223. curpos /= curdim_sz;
  224. }
  225. args[i] = curpos;
  226. if(args[i] >= curdim_sz)
  227. {
  228. if(data->pos_flag && RPN_IF_POSITION_OF_ERR)
  229. {
  230. return -1;
  231. }
  232. args[i] %= curdim_sz;
  233. }
  234. return 0;
  235. }
  236. int rpn_if_resf_xdim(rpn_if_t *rif, size_t *pos, rpn_value_t *_data)
  237. {
  238. rpn_if_default_data_t *data;
  239. size_t i, res, cur, curlim, prevlim;
  240. data = (rpn_if_default_data_t*)rif->params->data;
  241. res = 0;
  242. if(!data->size_lim)
  243. {
  244. return -1;
  245. }
  246. if(*(data->size_lim) < 1)
  247. {
  248. return -1;
  249. }
  250. /**@todo check if *(data->size_lim) overflow rif->params->rpn_argc */
  251. res = rif->rpn_res[0];
  252. if(res >= data->size_lim[1])
  253. {
  254. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  255. {
  256. return -1;
  257. }
  258. res %= data->size_lim[1];
  259. }
  260. for(i=1; i < *(data->size_lim); i++)
  261. {
  262. cur = rif->rpn_res[i];
  263. prevlim = data->size_lim[i];
  264. curlim = data->size_lim[i+1];
  265. if(cur >= curlim)
  266. {
  267. if(data->pos_flag & RPN_IF_POSITION_OF_ERR)
  268. {
  269. return -1;
  270. }
  271. cur %= curlim;
  272. }
  273. res += cur * prevlim;
  274. }
  275. *pos = res;
  276. return 0;
  277. }