encfrag.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /********************************************************************
  2. * *
  3. * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
  4. * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
  5. * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6. * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
  7. * *
  8. * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009 *
  9. * by the Xiph.Org Foundation http://www.xiph.org/ *
  10. * *
  11. ********************************************************************
  12. function:
  13. last mod: $Id: encfrag.c 16503 2009-08-22 18:14:02Z giles $
  14. ********************************************************************/
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include "encint.h"
  18. void oc_enc_frag_sub(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
  19. const unsigned char *_src,const unsigned char *_ref,int _ystride){
  20. (*_enc->opt_vtable.frag_sub)(_diff,_src,_ref,_ystride);
  21. }
  22. void oc_enc_frag_sub_c(ogg_int16_t _diff[64],const unsigned char *_src,
  23. const unsigned char *_ref,int _ystride){
  24. int i;
  25. for(i=0;i<8;i++){
  26. int j;
  27. for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-_ref[j]);
  28. _src+=_ystride;
  29. _ref+=_ystride;
  30. }
  31. }
  32. void oc_enc_frag_sub_128(const oc_enc_ctx *_enc,ogg_int16_t _diff[64],
  33. const unsigned char *_src,int _ystride){
  34. (*_enc->opt_vtable.frag_sub_128)(_diff,_src,_ystride);
  35. }
  36. void oc_enc_frag_sub_128_c(ogg_int16_t *_diff,
  37. const unsigned char *_src,int _ystride){
  38. int i;
  39. for(i=0;i<8;i++){
  40. int j;
  41. for(j=0;j<8;j++)_diff[i*8+j]=(ogg_int16_t)(_src[j]-128);
  42. _src+=_ystride;
  43. }
  44. }
  45. unsigned oc_enc_frag_sad(const oc_enc_ctx *_enc,const unsigned char *_x,
  46. const unsigned char *_y,int _ystride){
  47. return (*_enc->opt_vtable.frag_sad)(_x,_y,_ystride);
  48. }
  49. unsigned oc_enc_frag_sad_c(const unsigned char *_src,
  50. const unsigned char *_ref,int _ystride){
  51. unsigned sad;
  52. int i;
  53. sad=0;
  54. for(i=8;i-->0;){
  55. int j;
  56. for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]);
  57. _src+=_ystride;
  58. _ref+=_ystride;
  59. }
  60. return sad;
  61. }
  62. unsigned oc_enc_frag_sad_thresh(const oc_enc_ctx *_enc,
  63. const unsigned char *_src,const unsigned char *_ref,int _ystride,
  64. unsigned _thresh){
  65. return (*_enc->opt_vtable.frag_sad_thresh)(_src,_ref,_ystride,_thresh);
  66. }
  67. unsigned oc_enc_frag_sad_thresh_c(const unsigned char *_src,
  68. const unsigned char *_ref,int _ystride,unsigned _thresh){
  69. unsigned sad;
  70. int i;
  71. sad=0;
  72. for(i=8;i-->0;){
  73. int j;
  74. for(j=0;j<8;j++)sad+=abs(_src[j]-_ref[j]);
  75. if(sad>_thresh)break;
  76. _src+=_ystride;
  77. _ref+=_ystride;
  78. }
  79. return sad;
  80. }
  81. unsigned oc_enc_frag_sad2_thresh(const oc_enc_ctx *_enc,
  82. const unsigned char *_src,const unsigned char *_ref1,
  83. const unsigned char *_ref2,int _ystride,unsigned _thresh){
  84. return (*_enc->opt_vtable.frag_sad2_thresh)(_src,_ref1,_ref2,_ystride,
  85. _thresh);
  86. }
  87. unsigned oc_enc_frag_sad2_thresh_c(const unsigned char *_src,
  88. const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
  89. unsigned _thresh){
  90. unsigned sad;
  91. int i;
  92. sad=0;
  93. for(i=8;i-->0;){
  94. int j;
  95. for(j=0;j<8;j++)sad+=abs(_src[j]-(_ref1[j]+_ref2[j]>>1));
  96. if(sad>_thresh)break;
  97. _src+=_ystride;
  98. _ref1+=_ystride;
  99. _ref2+=_ystride;
  100. }
  101. return sad;
  102. }
  103. static void oc_diff_hadamard(ogg_int16_t _buf[64],const unsigned char *_src,
  104. const unsigned char *_ref,int _ystride){
  105. int i;
  106. for(i=0;i<8;i++){
  107. int t0;
  108. int t1;
  109. int t2;
  110. int t3;
  111. int t4;
  112. int t5;
  113. int t6;
  114. int t7;
  115. int r;
  116. /*Hadamard stage 1:*/
  117. t0=_src[0]-_ref[0]+_src[4]-_ref[4];
  118. t4=_src[0]-_ref[0]-_src[4]+_ref[4];
  119. t1=_src[1]-_ref[1]+_src[5]-_ref[5];
  120. t5=_src[1]-_ref[1]-_src[5]+_ref[5];
  121. t2=_src[2]-_ref[2]+_src[6]-_ref[6];
  122. t6=_src[2]-_ref[2]-_src[6]+_ref[6];
  123. t3=_src[3]-_ref[3]+_src[7]-_ref[7];
  124. t7=_src[3]-_ref[3]-_src[7]+_ref[7];
  125. /*Hadamard stage 2:*/
  126. r=t0;
  127. t0+=t2;
  128. t2=r-t2;
  129. r=t1;
  130. t1+=t3;
  131. t3=r-t3;
  132. r=t4;
  133. t4+=t6;
  134. t6=r-t6;
  135. r=t5;
  136. t5+=t7;
  137. t7=r-t7;
  138. /*Hadamard stage 3:*/
  139. _buf[0*8+i]=(ogg_int16_t)(t0+t1);
  140. _buf[1*8+i]=(ogg_int16_t)(t0-t1);
  141. _buf[2*8+i]=(ogg_int16_t)(t2+t3);
  142. _buf[3*8+i]=(ogg_int16_t)(t2-t3);
  143. _buf[4*8+i]=(ogg_int16_t)(t4+t5);
  144. _buf[5*8+i]=(ogg_int16_t)(t4-t5);
  145. _buf[6*8+i]=(ogg_int16_t)(t6+t7);
  146. _buf[7*8+i]=(ogg_int16_t)(t6-t7);
  147. _src+=_ystride;
  148. _ref+=_ystride;
  149. }
  150. }
  151. static void oc_diff_hadamard2(ogg_int16_t _buf[64],const unsigned char *_src,
  152. const unsigned char *_ref1,const unsigned char *_ref2,int _ystride){
  153. int i;
  154. for(i=0;i<8;i++){
  155. int t0;
  156. int t1;
  157. int t2;
  158. int t3;
  159. int t4;
  160. int t5;
  161. int t6;
  162. int t7;
  163. int r;
  164. /*Hadamard stage 1:*/
  165. r=_ref1[0]+_ref2[0]>>1;
  166. t4=_ref1[4]+_ref2[4]>>1;
  167. t0=_src[0]-r+_src[4]-t4;
  168. t4=_src[0]-r-_src[4]+t4;
  169. r=_ref1[1]+_ref2[1]>>1;
  170. t5=_ref1[5]+_ref2[5]>>1;
  171. t1=_src[1]-r+_src[5]-t5;
  172. t5=_src[1]-r-_src[5]+t5;
  173. r=_ref1[2]+_ref2[2]>>1;
  174. t6=_ref1[6]+_ref2[6]>>1;
  175. t2=_src[2]-r+_src[6]-t6;
  176. t6=_src[2]-r-_src[6]+t6;
  177. r=_ref1[3]+_ref2[3]>>1;
  178. t7=_ref1[7]+_ref2[7]>>1;
  179. t3=_src[3]-r+_src[7]-t7;
  180. t7=_src[3]-r-_src[7]+t7;
  181. /*Hadamard stage 2:*/
  182. r=t0;
  183. t0+=t2;
  184. t2=r-t2;
  185. r=t1;
  186. t1+=t3;
  187. t3=r-t3;
  188. r=t4;
  189. t4+=t6;
  190. t6=r-t6;
  191. r=t5;
  192. t5+=t7;
  193. t7=r-t7;
  194. /*Hadamard stage 3:*/
  195. _buf[0*8+i]=(ogg_int16_t)(t0+t1);
  196. _buf[1*8+i]=(ogg_int16_t)(t0-t1);
  197. _buf[2*8+i]=(ogg_int16_t)(t2+t3);
  198. _buf[3*8+i]=(ogg_int16_t)(t2-t3);
  199. _buf[4*8+i]=(ogg_int16_t)(t4+t5);
  200. _buf[5*8+i]=(ogg_int16_t)(t4-t5);
  201. _buf[6*8+i]=(ogg_int16_t)(t6+t7);
  202. _buf[7*8+i]=(ogg_int16_t)(t6-t7);
  203. _src+=_ystride;
  204. _ref1+=_ystride;
  205. _ref2+=_ystride;
  206. }
  207. }
  208. static void oc_intra_hadamard(ogg_int16_t _buf[64],const unsigned char *_src,
  209. int _ystride){
  210. int i;
  211. for(i=0;i<8;i++){
  212. int t0;
  213. int t1;
  214. int t2;
  215. int t3;
  216. int t4;
  217. int t5;
  218. int t6;
  219. int t7;
  220. int r;
  221. /*Hadamard stage 1:*/
  222. t0=_src[0]+_src[4];
  223. t4=_src[0]-_src[4];
  224. t1=_src[1]+_src[5];
  225. t5=_src[1]-_src[5];
  226. t2=_src[2]+_src[6];
  227. t6=_src[2]-_src[6];
  228. t3=_src[3]+_src[7];
  229. t7=_src[3]-_src[7];
  230. /*Hadamard stage 2:*/
  231. r=t0;
  232. t0+=t2;
  233. t2=r-t2;
  234. r=t1;
  235. t1+=t3;
  236. t3=r-t3;
  237. r=t4;
  238. t4+=t6;
  239. t6=r-t6;
  240. r=t5;
  241. t5+=t7;
  242. t7=r-t7;
  243. /*Hadamard stage 3:*/
  244. _buf[0*8+i]=(ogg_int16_t)(t0+t1);
  245. _buf[1*8+i]=(ogg_int16_t)(t0-t1);
  246. _buf[2*8+i]=(ogg_int16_t)(t2+t3);
  247. _buf[3*8+i]=(ogg_int16_t)(t2-t3);
  248. _buf[4*8+i]=(ogg_int16_t)(t4+t5);
  249. _buf[5*8+i]=(ogg_int16_t)(t4-t5);
  250. _buf[6*8+i]=(ogg_int16_t)(t6+t7);
  251. _buf[7*8+i]=(ogg_int16_t)(t6-t7);
  252. _src+=_ystride;
  253. }
  254. }
  255. unsigned oc_hadamard_sad_thresh(const ogg_int16_t _buf[64],unsigned _thresh){
  256. unsigned sad;
  257. int t0;
  258. int t1;
  259. int t2;
  260. int t3;
  261. int t4;
  262. int t5;
  263. int t6;
  264. int t7;
  265. int r;
  266. int i;
  267. sad=0;
  268. for(i=0;i<8;i++){
  269. /*Hadamard stage 1:*/
  270. t0=_buf[i*8+0]+_buf[i*8+4];
  271. t4=_buf[i*8+0]-_buf[i*8+4];
  272. t1=_buf[i*8+1]+_buf[i*8+5];
  273. t5=_buf[i*8+1]-_buf[i*8+5];
  274. t2=_buf[i*8+2]+_buf[i*8+6];
  275. t6=_buf[i*8+2]-_buf[i*8+6];
  276. t3=_buf[i*8+3]+_buf[i*8+7];
  277. t7=_buf[i*8+3]-_buf[i*8+7];
  278. /*Hadamard stage 2:*/
  279. r=t0;
  280. t0+=t2;
  281. t2=r-t2;
  282. r=t1;
  283. t1+=t3;
  284. t3=r-t3;
  285. r=t4;
  286. t4+=t6;
  287. t6=r-t6;
  288. r=t5;
  289. t5+=t7;
  290. t7=r-t7;
  291. /*Hadamard stage 3:*/
  292. r=abs(t0+t1);
  293. r+=abs(t0-t1);
  294. r+=abs(t2+t3);
  295. r+=abs(t2-t3);
  296. r+=abs(t4+t5);
  297. r+=abs(t4-t5);
  298. r+=abs(t6+t7);
  299. r+=abs(t6-t7);
  300. sad+=r;
  301. if(sad>_thresh)break;
  302. }
  303. return sad;
  304. }
  305. unsigned oc_enc_frag_satd_thresh(const oc_enc_ctx *_enc,
  306. const unsigned char *_src,const unsigned char *_ref,int _ystride,
  307. unsigned _thresh){
  308. return (*_enc->opt_vtable.frag_satd_thresh)(_src,_ref,_ystride,_thresh);
  309. }
  310. unsigned oc_enc_frag_satd_thresh_c(const unsigned char *_src,
  311. const unsigned char *_ref,int _ystride,unsigned _thresh){
  312. ogg_int16_t buf[64];
  313. oc_diff_hadamard(buf,_src,_ref,_ystride);
  314. return oc_hadamard_sad_thresh(buf,_thresh);
  315. }
  316. unsigned oc_enc_frag_satd2_thresh(const oc_enc_ctx *_enc,
  317. const unsigned char *_src,const unsigned char *_ref1,
  318. const unsigned char *_ref2,int _ystride,unsigned _thresh){
  319. return (*_enc->opt_vtable.frag_satd2_thresh)(_src,_ref1,_ref2,_ystride,
  320. _thresh);
  321. }
  322. unsigned oc_enc_frag_satd2_thresh_c(const unsigned char *_src,
  323. const unsigned char *_ref1,const unsigned char *_ref2,int _ystride,
  324. unsigned _thresh){
  325. ogg_int16_t buf[64];
  326. oc_diff_hadamard2(buf,_src,_ref1,_ref2,_ystride);
  327. return oc_hadamard_sad_thresh(buf,_thresh);
  328. }
  329. unsigned oc_enc_frag_intra_satd(const oc_enc_ctx *_enc,
  330. const unsigned char *_src,int _ystride){
  331. return (*_enc->opt_vtable.frag_intra_satd)(_src,_ystride);
  332. }
  333. unsigned oc_enc_frag_intra_satd_c(const unsigned char *_src,int _ystride){
  334. ogg_int16_t buf[64];
  335. oc_intra_hadamard(buf,_src,_ystride);
  336. return oc_hadamard_sad_thresh(buf,UINT_MAX)
  337. -abs(buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]+buf[6]+buf[7]);
  338. }
  339. void oc_enc_frag_copy2(const oc_enc_ctx *_enc,unsigned char *_dst,
  340. const unsigned char *_src1,const unsigned char *_src2,int _ystride){
  341. (*_enc->opt_vtable.frag_copy2)(_dst,_src1,_src2,_ystride);
  342. }
  343. void oc_enc_frag_copy2_c(unsigned char *_dst,
  344. const unsigned char *_src1,const unsigned char *_src2,int _ystride){
  345. int i;
  346. int j;
  347. for(i=8;i-->0;){
  348. for(j=0;j<8;j++)_dst[j]=_src1[j]+_src2[j]>>1;
  349. _dst+=_ystride;
  350. _src1+=_ystride;
  351. _src2+=_ystride;
  352. }
  353. }
  354. void oc_enc_frag_recon_intra(const oc_enc_ctx *_enc,
  355. unsigned char *_dst,int _ystride,const ogg_int16_t _residue[64]){
  356. (*_enc->opt_vtable.frag_recon_intra)(_dst,_ystride,_residue);
  357. }
  358. void oc_enc_frag_recon_inter(const oc_enc_ctx *_enc,unsigned char *_dst,
  359. const unsigned char *_src,int _ystride,const ogg_int16_t _residue[64]){
  360. (*_enc->opt_vtable.frag_recon_inter)(_dst,_src,_ystride,_residue);
  361. }