stats_tools.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include "stats_tools.h"
  4. #include "../src/dct.h"
  5. #include "../src/intra.h"
  6. void mode_data_init(mode_data *_md){
  7. int i;
  8. int j;
  9. _md->n=0;
  10. _md->mean=0;
  11. _md->var=0;
  12. for(i=0;i<B_SZ*B_SZ;i++){
  13. _md->satd_avg[i]=0;
  14. _md->ref_mean[i]=0;
  15. _md->pred_mean[i]=0;
  16. for(j=0;j<B_SZ*B_SZ;j++){
  17. _md->ref_cov[i][j]=0;
  18. _md->pred_cov[i][j]=0;
  19. }
  20. }
  21. }
  22. /* update the input mean and variance */
  23. void mode_data_add_input(mode_data *_md,const unsigned char *_data,int _stride){
  24. int n;
  25. int i;
  26. int j;
  27. n=(_md->n-1)*B_SZ*B_SZ;
  28. for(i=0;i<B_SZ;i++){
  29. for(j=0;j<B_SZ;j++){
  30. double delta;
  31. n++;
  32. delta=_data[_stride*i+j]*INPUT_SCALE-_md->mean;
  33. _md->mean+=delta/n;
  34. _md->var+=delta*delta*(n-1)/n;
  35. }
  36. }
  37. }
  38. void mode_data_add_block(mode_data *_md,const od_coeff *_block,int _stride,
  39. int _ref){
  40. double *mean;
  41. double(*cov)[B_SZ*B_SZ];
  42. double delta[B_SZ*B_SZ];
  43. int i;
  44. int j;
  45. mean=_ref?_md->ref_mean:_md->pred_mean;
  46. cov=_ref?_md->ref_cov:_md->pred_cov;
  47. for(j=0;j<B_SZ;j++){
  48. for(i=0;i<B_SZ;i++){
  49. delta[B_SZ*j+i]=_block[_stride*j+i]-mean[B_SZ*j+i];
  50. mean[B_SZ*j+i]+=delta[B_SZ*j+i]/_md->n;
  51. }
  52. }
  53. for(i=0;i<B_SZ*B_SZ;i++){
  54. for(j=0;j<B_SZ*B_SZ;j++){
  55. cov[i][j]+=delta[i]*delta[j]*(_md->n-1)/_md->n;
  56. }
  57. }
  58. }
  59. void mode_data_combine(mode_data *_a,const mode_data *_b){
  60. double s;
  61. double delta;
  62. int i;
  63. int j;
  64. double delta_ref[B_SZ*B_SZ];
  65. double delta_pred[B_SZ*B_SZ];
  66. s=((double)_b->n)/(_a->n+_b->n);
  67. delta=_b->mean-_a->mean;
  68. _a->mean+=delta*s;
  69. for(i=0;i<B_SZ*B_SZ;i++){
  70. _a->satd_avg[i]+=(_b->satd_avg[i]-_a->satd_avg[i])*s;
  71. delta_ref[i]=_b->ref_mean[i]-_a->ref_mean[i];
  72. _a->ref_mean[i]+=delta_ref[i]*s;
  73. delta_pred[i]=_b->pred_mean[i]-_a->pred_mean[i];
  74. _a->pred_mean[i]+=delta_pred[i]*s;
  75. }
  76. s*=_a->n;
  77. _a->var+=_b->var+delta*s;
  78. for(i=0;i<B_SZ*B_SZ;i++){
  79. for(j=0;j<B_SZ*B_SZ;j++){
  80. _a->ref_cov[i][j]+=_b->ref_cov[i][j]+delta_ref[i]*delta_ref[j]*s;
  81. _a->pred_cov[i][j]+=_b->pred_cov[i][j]+delta_pred[i]*delta_pred[j]*s;
  82. }
  83. }
  84. _a->n+=_b->n;
  85. }
  86. void mode_data_correct(mode_data *_md){
  87. int i;
  88. int j;
  89. _md->var/=_md->n*B_SZ*B_SZ;
  90. for(i=0;i<B_SZ*B_SZ;i++){
  91. for(j=0;j<B_SZ*B_SZ;j++){
  92. _md->ref_cov[i][j]/=_md->n;
  93. _md->pred_cov[i][j]/=_md->n;
  94. }
  95. }
  96. }
  97. void mode_data_print(mode_data *_md,const char *_label,double *_scale){
  98. double cg_ref;
  99. double cg_pred;
  100. double pg;
  101. int j;
  102. int i;
  103. double satd_avg;
  104. double bits_avg;
  105. cg_ref=10*log10(_md->var);
  106. cg_pred=10*log10(_md->var);
  107. pg=0;
  108. satd_avg=0;
  109. bits_avg=0;
  110. for(j=0;j<B_SZ;j++){
  111. for(i=0;i<B_SZ;i++){
  112. int x;
  113. double b;
  114. x=B_SZ*j+i;
  115. cg_ref-=10*log10(_md->ref_cov[x][x]*_scale[j]*_scale[i])/(B_SZ*B_SZ);
  116. cg_pred-=10*log10(_md->pred_cov[x][x]*_scale[j]*_scale[i])/(B_SZ*B_SZ);
  117. /* compute prediction gain 10*log10(prod_j(ref_cov[j]/pred_cov[j])) */
  118. pg+=10*log10(_md->ref_cov[x][x]/_md->pred_cov[x][x])/(B_SZ*B_SZ);
  119. satd_avg+=sqrt(_scale[i]*_scale[j])*_md->satd_avg[x];
  120. b=sqrt(_scale[j]*_scale[i]*_md->pred_cov[x][x]/2);
  121. bits_avg+=1+OD_LOG2(b)+M_LOG2E/b*_md->satd_avg[x];
  122. }
  123. }
  124. printf("%s Blocks %5i SATD %G Bits %G Mean %G Var %G CgRef %G CgPred %G Pg %G\n",
  125. _label,_md->n,satd_avg,bits_avg,_md->mean,_md->var,cg_ref,cg_pred,pg);
  126. }
  127. void mode_data_params(mode_data *_this,double _b[B_SZ*B_SZ],double *_scale){
  128. int j;
  129. int i;
  130. for(j=0;j<B_SZ;j++){
  131. for(i=0;i<B_SZ;i++){
  132. _b[j*B_SZ+i]=sqrt(_scale[j]*_scale[i]*_this->pred_cov[j*B_SZ+i][j*B_SZ+i]/2);
  133. }
  134. }
  135. }
  136. void intra_stats_init(intra_stats *_this){
  137. int mode;
  138. mode_data_init(&_this->fr);
  139. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  140. mode_data_init(&_this->md[mode]);
  141. }
  142. }
  143. void intra_stats_correct(intra_stats *_this){
  144. int mode;
  145. mode_data_correct(&_this->fr);
  146. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  147. mode_data_correct(&_this->md[mode]);
  148. }
  149. }
  150. void intra_stats_print(intra_stats *_this,const char *_label,
  151. double *_scale){
  152. int mode;
  153. printf("%s\n",_label);
  154. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  155. char label[16];
  156. sprintf(label,"Mode %i",mode);
  157. mode_data_print(&_this->md[mode],label,_scale);
  158. }
  159. mode_data_print(&_this->fr,"Pooled",_scale);
  160. }
  161. void intra_stats_combine(intra_stats *_this,const intra_stats *_that){
  162. int mode;
  163. mode_data_combine(&_this->fr,&_that->fr);
  164. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  165. mode_data_combine(&_this->md[mode],&_that->md[mode]);
  166. }
  167. }
  168. /* compute the scale factors for the DCT and TDLT transforms */
  169. double VP8_SCALE[B_SZ];
  170. double OD_SCALE[B_SZ];
  171. #define SCALE_BITS (14)
  172. #define PRINT_SCALE (0)
  173. void vp8_scale_init(double _vp8_scale[B_SZ]){
  174. int j;
  175. int i;
  176. od_coeff buf[B_SZ];
  177. for(i=0;i<B_SZ;i++){
  178. for(j=0;j<B_SZ;j++){
  179. buf[j]=i!=j?0:(1<<SCALE_BITS);
  180. }
  181. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  182. (*OD_IDCT_1D[B_SZ_LOG-OD_LOG_BSIZE0])(buf,1,buf);
  183. #else
  184. # error "Need an iDCT implementation for this block size."
  185. #endif
  186. _vp8_scale[i]=0;
  187. for(j=0;j<B_SZ;j++){
  188. double c=((double)buf[j])/(1<<SCALE_BITS);
  189. _vp8_scale[i]+=c*c;
  190. }
  191. #if PRINT_SCALE
  192. printf("%s%G",i==0?"":" ",_vp8_scale[i]);
  193. #endif
  194. }
  195. #if PRINT_SCALE
  196. printf("\n");
  197. #endif
  198. }
  199. #define APPLY_PREFILTER (1)
  200. #define APPLY_POSTFILTER (1)
  201. void od_scale_init(double _od_scale[B_SZ]){
  202. int i;
  203. int j;
  204. od_coeff buf[2*B_SZ];
  205. for(i=0;i<B_SZ;i++){
  206. for(j=0;j<2*B_SZ;j++){
  207. buf[j]=(B_SZ>>1)+i!=j?0:(1<<SCALE_BITS);
  208. }
  209. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  210. (*OD_IDCT_1D[B_SZ_LOG-OD_LOG_BSIZE0])(&buf[B_SZ>>1],1,&buf[B_SZ>>1]);
  211. #else
  212. # error "Need an iDCT implementation for this block size."
  213. #endif
  214. #if APPLY_POSTFILTER
  215. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  216. (*NE_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(buf,buf);
  217. (*NE_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(&buf[B_SZ],&buf[B_SZ]);
  218. #else
  219. # error "Need a postfilter implementation for this block size."
  220. #endif
  221. #endif
  222. _od_scale[i]=0;
  223. for(j=0;j<2*B_SZ;j++){
  224. double c=((double)buf[j])/(1<<SCALE_BITS);
  225. _od_scale[i]+=c*c;
  226. }
  227. #if PRINT_SCALE
  228. printf("%s%G",i==0?"":" ",_od_scale[i]);
  229. #endif
  230. }
  231. #if PRINT_SCALE
  232. printf("\n");
  233. #endif
  234. }
  235. static void ne_pre_filter(od_coeff *_out,int _out_stride,od_coeff *_in,
  236. int _in_stride,int _bx,int _by){
  237. int bx;
  238. int by;
  239. int j;
  240. int i;
  241. for(by=0;by<_by;by++){
  242. int y;
  243. y=B_SZ*by;
  244. for(bx=0;bx<_bx;bx++){
  245. int x;
  246. x=B_SZ*bx;
  247. for(j=0;j<B_SZ;j++){
  248. od_coeff col[B_SZ];
  249. #if APPLY_PREFILTER
  250. for(i=0;i<B_SZ;i++){
  251. col[i]=_in[_in_stride*(y+i)+x+j];
  252. }
  253. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  254. #if 0
  255. (*OD_PRE_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(col,col);
  256. #else
  257. (*NE_PRE_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(col,col);
  258. #endif
  259. #else
  260. # error "Need a prefilter implementation for this block size."
  261. #endif
  262. for(i=0;i<B_SZ;i++){
  263. _out[_out_stride*(y+i)+x+j]=col[i];
  264. }
  265. #else
  266. for(i=0;i<B_SZ;i++){
  267. _out[_out_stride*(y+i)+x+j]=_in[_in_stride*(y+i)+x+j];
  268. }
  269. #endif
  270. }
  271. #if APPLY_PREFILTER
  272. for(j=0;j<B_SZ;j++){
  273. od_coeff *row;
  274. row=&_out[_out_stride*(y+j)+x];
  275. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  276. #if 0
  277. (*OD_PRE_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(row,row);
  278. #else
  279. (*NE_PRE_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(row,row);
  280. #endif
  281. #else
  282. # error "Need a prefilter implementation for this block size."
  283. #endif
  284. }
  285. #endif
  286. }
  287. }
  288. }
  289. static void ne_post_filter(od_coeff *_out,int _out_stride,od_coeff *_in,
  290. int _in_stride,int _bx,int _by){
  291. int bx;
  292. int by;
  293. int j;
  294. int i;
  295. for(by=0;by<_by;by++){
  296. int y;
  297. y=B_SZ*by;
  298. for(bx=0;bx<_bx;bx++){
  299. int x;
  300. x=B_SZ*bx;
  301. for(j=0;j<B_SZ;j++){
  302. od_coeff *row;
  303. for(i=0;i<B_SZ;i++){
  304. _out[_out_stride*(y+j)+x+i]=_in[_in_stride*(y+j)+x+i];
  305. }
  306. #if APPLY_POSTFILTER
  307. row=&_out[_out_stride*(y+j)+x];
  308. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  309. #if 0
  310. (*OD_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(row,row);
  311. #else
  312. (*NE_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(row,row);
  313. #endif
  314. #else
  315. # error "Need a postfilter implementation for this block size."
  316. #endif
  317. #endif
  318. }
  319. #if APPLY_POSTFILTER
  320. for(i=0;i<B_SZ;i++){
  321. od_coeff col[B_SZ];
  322. for(j=0;j<B_SZ;j++){
  323. col[j]=_out[_out_stride*(y+j)+x+i];
  324. }
  325. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  326. #if 0
  327. (*OD_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(col,col);
  328. #else
  329. (*NE_POST_FILTER[B_SZ_LOG-OD_LOG_BSIZE0])(col,col);
  330. #endif
  331. #else
  332. # error "Need a postfilter implementation for this block size."
  333. #endif
  334. for(j=0;j<B_SZ;j++){
  335. _out[_out_stride*(j+y)+x+i]=col[j];
  336. }
  337. }
  338. #endif
  339. }
  340. }
  341. }
  342. static void od_fdct_blocks(od_coeff *_out,int _out_stride,od_coeff *_in,
  343. int _in_stride,int _bx,int _by){
  344. int bx;
  345. int by;
  346. for(by=0;by<_by;by++){
  347. int y;
  348. y=B_SZ*by;
  349. for(bx=0;bx<_bx;bx++){
  350. int x;
  351. x=B_SZ*bx;
  352. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  353. (*OD_FDCT_2D[B_SZ_LOG-OD_LOG_BSIZE0])(&_out[_out_stride*y+x],_out_stride,
  354. &_in[_in_stride*y+x],_in_stride);
  355. #else
  356. # error "Need an fDCT implementation for this block size."
  357. #endif
  358. }
  359. }
  360. }
  361. static void od_idct_blocks(od_coeff *_out,int _out_stride,od_coeff *_in,
  362. int _in_stride,int _bx,int _by){
  363. int bx;
  364. int by;
  365. for(by=0;by<_by;by++){
  366. int y;
  367. y=B_SZ*by;
  368. for(bx=0;bx<_bx;bx++){
  369. int x;
  370. x=B_SZ*bx;
  371. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  372. (*OD_IDCT_2D[B_SZ_LOG-OD_LOG_BSIZE0])(&_out[_out_stride*y+x],_out_stride,
  373. &_in[_in_stride*y+x],_in_stride);
  374. #else
  375. # error "Need an iDCT implementation for this block size."
  376. #endif
  377. }
  378. }
  379. }
  380. #define SCALE_SATD (1)
  381. /* find the best vp8 mode */
  382. int vp8_select_mode(const unsigned char *_data,int _stride,double *_weight){
  383. double best_satd;
  384. double next_best_satd;
  385. int mode;
  386. int best_mode;
  387. int next_best_mode;
  388. best_mode=0;
  389. best_satd=UINT_MAX;
  390. next_best_mode=best_mode;
  391. next_best_satd=best_satd;
  392. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  393. unsigned char block[B_SZ*B_SZ];
  394. od_coeff buf[B_SZ*B_SZ];
  395. int j;
  396. int i;
  397. double satd;
  398. memset(block,0,B_SZ*B_SZ);
  399. vp8_intra_predict(block,B_SZ,_data,_stride,mode);
  400. for(j=0;j<B_SZ;j++){
  401. for(i=0;i<B_SZ;i++){
  402. buf[B_SZ*j+i]=block[B_SZ*j+i]-_data[_stride*j+i];
  403. }
  404. }
  405. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  406. (*OD_FDCT_2D[B_SZ_LOG-OD_LOG_BSIZE0])(buf,B_SZ,buf,B_SZ);
  407. #else
  408. # error "Need an fDCT implementation for this block size."
  409. #endif
  410. satd=0;
  411. for(j=0;j<B_SZ;j++){
  412. for(i=0;i<B_SZ;i++){
  413. #if SCALE_SATD
  414. satd+=sqrt(VP8_SCALE[j]*VP8_SCALE[i])*abs(buf[B_SZ*j+i]);
  415. #else
  416. satd+=abs(buf[B_SZ*j+i]);
  417. #endif
  418. }
  419. }
  420. if(satd<best_satd){
  421. next_best_satd=best_satd;
  422. next_best_mode=best_mode;
  423. best_satd=satd;
  424. best_mode=mode;
  425. }
  426. else{
  427. if(satd<next_best_satd){
  428. next_best_satd=satd;
  429. next_best_mode=mode;
  430. }
  431. }
  432. }
  433. if(_weight!=NULL){
  434. *_weight=best_mode!=0?next_best_satd-best_satd:1;
  435. }
  436. return best_mode;
  437. }
  438. int od_select_mode_bits(const od_coeff *_block,int _stride,double *_weight,
  439. double _b[OD_INTRA_NMODES][B_SZ*B_SZ]){
  440. int best_mode;
  441. double best_bits;
  442. int next_best_mode;
  443. double next_best_bits;
  444. int mode;
  445. best_mode=0;
  446. best_bits=UINT_MAX;
  447. next_best_mode=best_mode;
  448. next_best_bits=best_bits;
  449. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  450. double p[B_SZ*B_SZ];
  451. double bits;
  452. int j;
  453. int i;
  454. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  455. #if 0
  456. (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,_block,_stride,mode);
  457. #else
  458. (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,_block,_stride,mode);
  459. #endif
  460. #else
  461. # error "Need a predictor implementation for this block size."
  462. #endif
  463. bits=0;
  464. for(j=0;j<B_SZ;j++){
  465. for(i=0;i<B_SZ;i++){
  466. bits+=1+OD_LOG2(_b[mode][j*B_SZ+i])+M_LOG2E/_b[mode][j*B_SZ+i]*
  467. abs(_block[_stride*j+i]-(od_coeff)floor(p[B_SZ*j+i]+0.5));
  468. }
  469. }
  470. if(bits<best_bits){
  471. next_best_mode=best_mode;
  472. next_best_bits=best_bits;
  473. best_mode=mode;
  474. best_bits=bits;
  475. }
  476. else{
  477. if(bits<next_best_bits){
  478. next_best_mode=mode;
  479. next_best_bits=bits;
  480. }
  481. }
  482. }
  483. if(_weight!=NULL){
  484. *_weight=best_mode!=0?next_best_bits-best_bits:1;
  485. }
  486. return best_mode;
  487. }
  488. int od_select_mode_satd(const od_coeff *_block,int _stride,double *_weight){
  489. int best_mode;
  490. double best_satd;
  491. int next_best_mode;
  492. double next_best_satd;
  493. int mode;
  494. best_mode=0;
  495. best_satd=UINT_MAX;
  496. next_best_mode=best_mode;
  497. next_best_satd=best_satd;
  498. for(mode=0;mode<OD_INTRA_NMODES;mode++){
  499. double p[B_SZ*B_SZ];
  500. double satd;
  501. int j;
  502. int i;
  503. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  504. #if 0
  505. (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,_block,_stride,mode);
  506. #else
  507. (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,_block,_stride,mode);
  508. #endif
  509. #else
  510. # error "Need a predictor implementation for this block size."
  511. #endif
  512. satd=0;
  513. for(j=0;j<B_SZ;j++){
  514. for(i=0;i<B_SZ;i++){
  515. #if SCALE_SATD
  516. satd+=sqrt(OD_SCALE[j]*OD_SCALE[i])*
  517. abs(_block[_stride*j+i]-(od_coeff)floor(p[B_SZ*j+i]+0.5));
  518. #else
  519. satd+=abs(_block[_stride*j+i]-(od_coeff)floor(p[B_SZ*j+i]+0.5));
  520. #endif
  521. }
  522. }
  523. if(satd<best_satd){
  524. next_best_mode=best_mode;
  525. next_best_satd=best_satd;
  526. best_mode=mode;
  527. best_satd=satd;
  528. }
  529. else{
  530. if(satd<next_best_satd){
  531. next_best_mode=mode;
  532. next_best_satd=satd;
  533. }
  534. }
  535. }
  536. if(_weight!=NULL){
  537. *_weight=best_mode!=0?next_best_satd-best_satd:1;
  538. }
  539. return best_mode;
  540. }
  541. od_rgba16_pixel COLORS[OD_INTRA_NMODES];
  542. void image_draw_block(od_rgba16_image *_image,int _x,int _y,
  543. const unsigned char *_block,int _stride){
  544. od_rgba16_pixel color;
  545. int i;
  546. int j;
  547. color[3]=(unsigned short)0xFFFFU;
  548. for(i=0;i<B_SZ;i++){
  549. for(j=0;j<B_SZ;j++){
  550. color[0]=color[1]=color[2]=_block[_stride*i+j]<<8;
  551. od_rgba16_image_draw_point(_image,_x+j,_y+i,color);
  552. }
  553. }
  554. }
  555. int image_write_png(od_rgba16_image *_image,const char *_name){
  556. char fout_name[8192];
  557. FILE *fout;
  558. sprintf(fout_name,"%s.png",_name);
  559. fout=fopen(fout_name,"wb");
  560. if(fout==NULL){
  561. fprintf(stderr,"Could not open '%s' for reading.\n",fout_name);
  562. return EXIT_FAILURE;
  563. }
  564. od_rgba16_image_write_png(_image,fout);
  565. fclose(fout);
  566. return EXIT_SUCCESS;
  567. }
  568. void image_files_init(image_files *_this,int _nxblocks,int _nyblocks){
  569. od_rgba16_image_init(&_this->raw,B_SZ*_nxblocks,B_SZ*_nyblocks);
  570. od_rgba16_image_init(&_this->map,_nxblocks,_nyblocks);
  571. od_rgba16_image_init(&_this->pred,B_SZ*_nxblocks,B_SZ*_nyblocks);
  572. od_rgba16_image_init(&_this->res,B_SZ*_nxblocks,B_SZ*_nyblocks);
  573. }
  574. void image_files_clear(image_files *_this){
  575. od_rgba16_image_clear(&_this->raw);
  576. od_rgba16_image_clear(&_this->map);
  577. od_rgba16_image_clear(&_this->pred);
  578. od_rgba16_image_clear(&_this->res);
  579. }
  580. void image_files_write(image_files *_this,const char *_name,const char *_suf){
  581. char name[8192];
  582. sprintf(name,"%s-raw%s",_name,_suf==NULL?"":_suf);
  583. image_write_png(&_this->raw,name);
  584. sprintf(name,"%s-map%s",_name,_suf==NULL?"":_suf);
  585. image_write_png(&_this->map,name);
  586. sprintf(name,"%s-pred%s",_name,_suf==NULL?"":_suf);
  587. image_write_png(&_this->pred,name);
  588. sprintf(name,"%s-res%s",_name,_suf==NULL?"":_suf);
  589. image_write_png(&_this->res,name);
  590. }
  591. void image_data_init(image_data *_this,const char *_name,int _nxblocks,
  592. int _nyblocks){
  593. int w;
  594. int h;
  595. _this->name=_name;
  596. _this->nxblocks=_nxblocks;
  597. _this->nyblocks=_nyblocks;
  598. _this->mode=(unsigned char *)malloc(sizeof(*_this->mode)*_nxblocks*_nyblocks);
  599. _this->weight=(double *)malloc(sizeof(*_this->weight)*_nxblocks*_nyblocks);
  600. w=B_SZ*(_nxblocks+3);
  601. h=B_SZ*(_nyblocks+3);
  602. _this->pre=(od_coeff *)malloc(sizeof(*_this->pre)*w*h);
  603. _this->pre_stride=w;
  604. w=B_SZ*(_nxblocks+2);
  605. h=B_SZ*(_nyblocks+2);
  606. _this->fdct=(od_coeff *)malloc(sizeof(*_this->fdct)*w*h);
  607. _this->fdct_stride=w;
  608. w=B_SZ*_nxblocks;
  609. h=B_SZ*_nyblocks;
  610. _this->pred=(od_coeff *)malloc(sizeof(*_this->pred)*w*h);
  611. _this->pred_stride=w;
  612. w=B_SZ*(_nxblocks+2);
  613. h=B_SZ*(_nyblocks+2);
  614. _this->idct=(od_coeff *)malloc(sizeof(*_this->idct)*w*h);
  615. _this->idct_stride=w;
  616. w=B_SZ*(_nxblocks+1);
  617. h=B_SZ*(_nyblocks+1);
  618. _this->post=(od_coeff *)malloc(sizeof(*_this->post)*w*h);
  619. _this->post_stride=w;
  620. }
  621. void image_data_clear(image_data *_this){
  622. free(_this->mode);
  623. free(_this->weight);
  624. free(_this->pre);
  625. free(_this->fdct);
  626. free(_this->pred);
  627. free(_this->idct);
  628. free(_this->post);
  629. }
  630. void image_data_pre_block(image_data *_this,const unsigned char *_data,
  631. int _stride,int _bi,int _bj){
  632. int x0;
  633. int y0;
  634. int bx;
  635. int by;
  636. int x;
  637. int y;
  638. int bi;
  639. int bj;
  640. int i;
  641. int j;
  642. od_coeff buf[B_SZ*B_SZ];
  643. x0=-(B_SZ>>1);
  644. y0=-(B_SZ>>1);
  645. bx=by=1;
  646. if(_bi==0){
  647. x0-=B_SZ;
  648. bx++;
  649. }
  650. if(_bj==0){
  651. y0-=B_SZ;
  652. by++;
  653. }
  654. if(_bi==_this->nxblocks-1){
  655. bx+=2;
  656. }
  657. if(_bj==_this->nyblocks-1){
  658. by+=2;
  659. }
  660. x=x0+B_SZ*_bi+(3*B_SZ>>1);
  661. y=y0+B_SZ*_bj+(3*B_SZ>>1);
  662. for(bj=0;bj<by;bj++){
  663. for(bi=0;bi<bx;bi++){
  664. for(j=0;j<B_SZ;j++){
  665. for(i=0;i<B_SZ;i++){
  666. buf[B_SZ*j+i]=
  667. (_data[_stride*(y0+B_SZ*bj+j)+x0+B_SZ*bi+i]-128)*INPUT_SCALE;
  668. }
  669. }
  670. ne_pre_filter(&_this->pre[_this->pre_stride*(y+B_SZ*bj)+x+B_SZ*bi],
  671. _this->pre_stride,buf,B_SZ,1,1);
  672. }
  673. }
  674. }
  675. void image_data_fdct_block(image_data *_this,int _bi,int _bj){
  676. int x0;
  677. int y0;
  678. int bx;
  679. int by;
  680. int x;
  681. int y;
  682. x0=_bi*B_SZ+(3*B_SZ>>1);
  683. y0=_bj*B_SZ+(3*B_SZ>>1);
  684. bx=by=1;
  685. if(_bi==0){
  686. x0-=B_SZ;
  687. bx++;
  688. }
  689. if(_bj==0){
  690. y0-=B_SZ;
  691. by++;
  692. }
  693. if(_bi==_this->nxblocks-1){
  694. bx++;
  695. }
  696. if(_bj==_this->nyblocks-1){
  697. by++;
  698. }
  699. x=x0-(B_SZ>>1);
  700. y=y0-(B_SZ>>1);
  701. od_fdct_blocks(&_this->fdct[y*_this->fdct_stride+x],_this->fdct_stride,
  702. &_this->pre[y0*_this->pre_stride+x0],_this->pre_stride,bx,by);
  703. }
  704. void image_data_pred_block(image_data *_this,int _bi,int _bj){
  705. int mode;
  706. od_coeff *block;
  707. double p[B_SZ*B_SZ];
  708. od_coeff *pred;
  709. int j;
  710. int i;
  711. mode=_this->mode[_this->nxblocks*_bj+_bi];
  712. block=&_this->fdct[_this->fdct_stride*B_SZ*(_bj+1)+B_SZ*(_bi+1)];
  713. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  714. #if 0
  715. (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,block,_this->fdct_stride,mode);
  716. #else
  717. (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(p,block,_this->fdct_stride,mode);
  718. #endif
  719. #else
  720. # error "Need a predictor implementation for this block size."
  721. #endif
  722. pred=&_this->pred[_this->pred_stride*B_SZ*_bj+B_SZ*_bi];
  723. for(j=0;j<B_SZ;j++){
  724. for(i=0;i<B_SZ;i++){
  725. pred[_this->pred_stride*j+i]=(od_coeff)floor(p[B_SZ*j+i]+0.5);
  726. }
  727. }
  728. }
  729. void image_data_stats_block(image_data *_this,const unsigned char *_data,
  730. int _stride,int _bi,int _bj,intra_stats *_stats){
  731. int mode;
  732. mode_data *fr;
  733. mode_data *md;
  734. od_coeff *pred;
  735. od_coeff *block;
  736. int j;
  737. int i;
  738. od_coeff buf[B_SZ*B_SZ];
  739. mode=_this->mode[_bj*_this->nxblocks+_bi];
  740. fr=&_stats->fr;
  741. md=&_stats->md[mode];
  742. fr->n++;
  743. md->n++;
  744. /* update the input mean and variance */
  745. mode_data_add_input(fr,_data,_stride);
  746. mode_data_add_input(md,_data,_stride);
  747. /* update the daala reference mean and covariance */
  748. block=&_this->fdct[_this->fdct_stride*B_SZ*(_bj+1)+B_SZ*(_bi+1)];
  749. mode_data_add_block(fr,block,_this->fdct_stride,1);
  750. mode_data_add_block(md,block,_this->fdct_stride,1);
  751. /* update the daala predicted mean and covariance */
  752. pred=&_this->pred[_this->pred_stride*B_SZ*_bj+B_SZ*_bi];
  753. for(j=0;j<B_SZ;j++){
  754. for(i=0;i<B_SZ;i++){
  755. buf[B_SZ*j+i]=block[_this->fdct_stride*j+i]-pred[_this->pred_stride*j+i];
  756. }
  757. }
  758. mode_data_add_block(fr,buf,B_SZ,0);
  759. mode_data_add_block(md,buf,B_SZ,0);
  760. /* update the daala satd */
  761. for(j=0;j<B_SZ;j++){
  762. for(i=0;i<B_SZ;i++){
  763. double satd;
  764. satd=abs(buf[B_SZ*j+i]);
  765. md->satd_avg[B_SZ*j+i]+=(satd-md->satd_avg[B_SZ*j+i])/md->n;
  766. fr->satd_avg[B_SZ*j+i]+=(satd-fr->satd_avg[B_SZ*j+i])/fr->n;
  767. }
  768. }
  769. }
  770. void image_data_idct_block(image_data *_this,int _bi,int _bj){
  771. int x0;
  772. int y0;
  773. int x;
  774. int y;
  775. int bx;
  776. int by;
  777. x0=B_SZ*_bi;
  778. y0=B_SZ*_bj;
  779. x=x0+B_SZ;
  780. y=y0+B_SZ;
  781. bx=by=1;
  782. if(_bi==0){
  783. x-=B_SZ;
  784. bx++;
  785. }
  786. if(_bj==0){
  787. y-=B_SZ;
  788. by++;
  789. }
  790. if(_bi==_this->nxblocks-1){
  791. bx++;
  792. }
  793. if(_bj==_this->nyblocks-1){
  794. by++;
  795. }
  796. /* TODO remove redundant computations here */
  797. if(bx!=1||by!=1){
  798. od_idct_blocks(&_this->idct[_this->idct_stride*y+x],_this->idct_stride,
  799. &_this->fdct[_this->fdct_stride*y+x],_this->fdct_stride,bx,by);
  800. }
  801. x=x0+B_SZ;
  802. y=y0+B_SZ;
  803. od_idct_blocks(&_this->idct[_this->idct_stride*y+x],_this->idct_stride,
  804. &_this->pred[_this->pred_stride*y0+x0],_this->pred_stride,1,1);
  805. }
  806. void image_data_post_block(image_data *_this,int _bi,int _bj){
  807. int x0;
  808. int y0;
  809. int x;
  810. int y;
  811. int bx;
  812. int by;
  813. x=B_SZ*_bi;
  814. y=B_SZ*_bj;
  815. x0=x+(B_SZ>>1);
  816. y0=y+(B_SZ>>1);
  817. bx=by=1;
  818. if(_bi==_this->nxblocks-1){
  819. bx++;
  820. }
  821. if(_bj==_this->nyblocks-1){
  822. by++;
  823. }
  824. ne_post_filter(&_this->post[_this->post_stride*y+x],_this->post_stride,
  825. &_this->idct[_this->idct_stride*y0+x0],_this->idct_stride,bx,by);
  826. }
  827. void image_data_files_block(image_data *_this,const unsigned char *_data,
  828. int _stride,int _bi,int _bj,image_files *_files){
  829. int mode;
  830. od_coeff *p;
  831. int j;
  832. int i;
  833. od_coeff v;
  834. unsigned char buf[B_SZ*B_SZ];
  835. mode=_this->mode[_bj*_this->nxblocks+_bi];
  836. od_rgba16_image_draw_point(&_files->map,_bi,_bj,COLORS[mode]);
  837. p=&_this->pre[_this->pre_stride*(B_SZ*_bj+(3*B_SZ>>1))+B_SZ*_bi+(3*B_SZ>>1)];
  838. for(j=0;j<B_SZ;j++){
  839. for(i=0;i<B_SZ;i++){
  840. v=(p[_this->pre_stride*j+i]+INPUT_SCALE*128+INPUT_SCALE/2)/INPUT_SCALE;
  841. buf[B_SZ*j+i]=OD_CLAMPI(0,v,255);
  842. }
  843. }
  844. image_draw_block(&_files->raw,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);
  845. p=&_this->post[_this->post_stride*(B_SZ*_bj+(B_SZ>>1))+B_SZ*_bi+(B_SZ>>1)];
  846. for(j=0;j<B_SZ;j++){
  847. for(i=0;i<B_SZ;i++){
  848. v=(p[_this->post_stride*j+i]+INPUT_SCALE*128+INPUT_SCALE/2)/INPUT_SCALE;
  849. buf[B_SZ*j+i]=OD_CLAMPI(0,v,255);
  850. }
  851. }
  852. image_draw_block(&_files->pred,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);
  853. for(j=0;j<B_SZ;j++){
  854. for(i=0;i<B_SZ;i++){
  855. buf[B_SZ*j+i]=abs(_data[_stride*j+i]-buf[B_SZ*j+i]);
  856. }
  857. }
  858. image_draw_block(&_files->res,B_SZ*_bi,B_SZ*_bj,buf,B_SZ);
  859. }
  860. int image_data_save_map(image_data *_this){
  861. char name[8196];
  862. int eos;
  863. FILE *fout;
  864. strcpy(name,_this->name);
  865. eos=strlen(name)-4;
  866. sprintf(&name[eos],".map");
  867. fout=fopen(name,"wb");
  868. if(fout==NULL){
  869. fprintf(stderr,"Error opening output file '%s'.\n",name);
  870. return EXIT_FAILURE;
  871. }
  872. if(fwrite(_this->mode,
  873. _this->nxblocks*(size_t)_this->nyblocks*sizeof(*_this->mode),1,fout)<1){
  874. fprintf(stderr,"Error writing to output file '%s'.\n",name);
  875. return EXIT_FAILURE;
  876. }
  877. if(fwrite(_this->weight,
  878. _this->nxblocks*(size_t)_this->nyblocks*sizeof(*_this->weight),1,fout)<1){
  879. fprintf(stderr,"Error writing to output file '%s'.\n",name);
  880. return EXIT_FAILURE;
  881. }
  882. fclose(fout);
  883. return EXIT_SUCCESS;
  884. }
  885. int image_data_load_map(image_data *_this){
  886. char name[8196];
  887. int eos;
  888. FILE *fin;
  889. strcpy(name,_this->name);
  890. eos=strlen(name)-4;
  891. sprintf(&name[eos],".map");
  892. fin=fopen(name,"rb");
  893. if(fin==NULL){
  894. fprintf(stderr,"Error opening input file '%s'.\n",name);
  895. return EXIT_FAILURE;
  896. }
  897. if(fread(_this->mode,
  898. _this->nxblocks*(size_t)_this->nyblocks*sizeof(*_this->mode),1,fin)<1) {
  899. fprintf(stderr,"Error reading from input file '%s'.\n",name);
  900. return EXIT_FAILURE;
  901. }
  902. if(fread(_this->weight,
  903. _this->nxblocks*(size_t)_this->nyblocks*sizeof(*_this->weight),1,fin)<1) {
  904. fprintf(stderr,"Error reading from input file '%s'.\n",name);
  905. return EXIT_FAILURE;
  906. }
  907. fclose(fin);
  908. return EXIT_SUCCESS;
  909. }
  910. int NE_FILTER_PARAMS4[4]={91,85,-11,36};
  911. static void ne_pre_filter4(od_coeff _y[4],const od_coeff _x[4]){
  912. int t[4];
  913. t[3]=_x[0]-_x[3];
  914. t[2]=_x[1]-_x[2];
  915. t[1]=_x[1]-(t[2]>>1);
  916. t[0]=_x[0]-(t[3]>>1);
  917. t[2]=t[2]*NE_FILTER_PARAMS4[0]>>6;
  918. t[2]+=-t[2]>>15&1;
  919. t[3]=t[3]*NE_FILTER_PARAMS4[1]>>6;
  920. t[3]+=-t[3]>>15&1;
  921. t[3]+=t[2]*NE_FILTER_PARAMS4[2]+32>>6;
  922. t[2]+=t[3]*NE_FILTER_PARAMS4[3]+32>>6;
  923. t[0]+=t[3]>>1;
  924. _y[0]=(od_coeff)t[0];
  925. t[1]+=t[2]>>1;
  926. _y[1]=(od_coeff)t[1];
  927. _y[2]=(od_coeff)(t[1]-t[2]);
  928. _y[3]=(od_coeff)(t[0]-t[3]);
  929. }
  930. static void ne_post_filter4(od_coeff _x[4],const od_coeff _y[4]){
  931. int t[4];
  932. t[3]=_y[0]-_y[3];
  933. t[2]=_y[1]-_y[2];
  934. t[1]=_y[1]-(t[2]>>1);
  935. t[0]=_y[0]-(t[3]>>1);
  936. t[2]-=t[3]*NE_FILTER_PARAMS4[3]+32>>6;
  937. t[3]-=t[2]*NE_FILTER_PARAMS4[2]+32>>6;
  938. t[3]=(t[3]<<6)/NE_FILTER_PARAMS4[1];
  939. t[2]=(t[2]<<6)/NE_FILTER_PARAMS4[0];
  940. t[0]+=t[3]>>1;
  941. _x[0]=(od_coeff)t[0];
  942. t[1]+=t[2]>>1;
  943. _x[1]=(od_coeff)t[1];
  944. _x[2]=(od_coeff)(t[1]-t[2]);
  945. _x[3]=(od_coeff)(t[0]-t[3]);
  946. }
  947. const od_filter_func NE_PRE_FILTER[OD_NBSIZES]={
  948. ne_pre_filter4,
  949. od_pre_filter8,
  950. od_pre_filter16
  951. };
  952. const od_filter_func NE_POST_FILTER[OD_NBSIZES]={
  953. ne_post_filter4,
  954. od_post_filter8,
  955. od_post_filter16
  956. };
  957. void ne_intra_pred4x4_mult(double *_p,const od_coeff *_c,int _stride,int _mode){
  958. int j;
  959. int i;
  960. int by;
  961. int bx;
  962. int k;
  963. int l;
  964. for(j=0;j<4;j++){
  965. for(i=0;i<4;i++){
  966. _p[4*j+i]=NE_PRED_OFFSETS_4x4[_mode][j][i];
  967. for(by=0;by<=1;by++){
  968. for(bx=0;bx<=2-by;bx++){
  969. const od_coeff *b;
  970. b=&_c[_stride*4*(by-1)+4*(bx-1)];
  971. for(k=0;k<4;k++){
  972. for(l=0;l<4;l++){
  973. _p[4*j+i]+=
  974. b[_stride*k+l]*NE_PRED_WEIGHTS_4x4[_mode][j][i][by*4+k][bx*4+l];
  975. }
  976. }
  977. }
  978. }
  979. }
  980. }
  981. }
  982. void ne_intra_pred8x8_mult(double *_p,const od_coeff *_c,int _stride,int _mode){
  983. int j;
  984. int i;
  985. int by;
  986. int bx;
  987. int k;
  988. int l;
  989. for(j=0;j<8;j++){
  990. for(i=0;i<8;i++){
  991. _p[8*j+i]=NE_PRED_OFFSETS_8x8[_mode][j][i];
  992. for(by=0;by<=1;by++){
  993. for(bx=0;bx<=2-by;bx++){
  994. const od_coeff *b;
  995. b=&_c[_stride*8*(by-1)+8*(bx-1)];
  996. for(k=0;k<8;k++){
  997. for(l=0;l<8;l++){
  998. _p[8*j+i]+=
  999. b[_stride*k+l]*NE_PRED_WEIGHTS_8x8[_mode][j][i][by*8+k][bx*8+l];
  1000. }
  1001. }
  1002. }
  1003. }
  1004. }
  1005. }
  1006. }
  1007. void ne_intra_pred16x16_mult(double *_p,const od_coeff *_c,int _stride,int _mode){
  1008. int j;
  1009. int i;
  1010. int by;
  1011. int bx;
  1012. int k;
  1013. int l;
  1014. for(j=0;j<16;j++){
  1015. for(i=0;i<16;i++){
  1016. _p[16*j+i]=NE_PRED_OFFSETS_16x16[_mode][j][i];
  1017. for(by=0;by<=1;by++){
  1018. for(bx=0;bx<=2-by;bx++){
  1019. const od_coeff *b;
  1020. b=&_c[_stride*16*(by-1)+16*(bx-1)];
  1021. for(k=0;k<16;k++){
  1022. for(l=0;l<16;l++){
  1023. _p[16*j+i]+=
  1024. b[_stride*k+l]*NE_PRED_WEIGHTS_16x16[_mode][j][i][by*16+k][bx*16+l];
  1025. }
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. }
  1032. const od_intra_mult_func NE_INTRA_MULT[OD_NBSIZES]={
  1033. ne_intra_pred4x4_mult,
  1034. ne_intra_pred8x8_mult,
  1035. ne_intra_pred16x16_mult
  1036. };
  1037. void print_betas(FILE *_fp){
  1038. int m;
  1039. int i;
  1040. int j;
  1041. int k;
  1042. int l;
  1043. int bx;
  1044. int by;
  1045. #if B_SZ==4
  1046. fprintf(_fp,"double NE_PRED_OFFSETS_4x4[OD_INTRA_NMODES][4][4]={\n");
  1047. #elif B_SZ==8
  1048. fprintf(_fp,"double NE_PRED_OFFSETS_8x8[OD_INTRA_NMODES][8][8]={\n");
  1049. #elif B_SZ==16
  1050. fprintf(_fp,"double NE_PRED_OFFSETS_16x16[OD_INTRA_NMODES][16][16]={\n");
  1051. #else
  1052. # error "Unsupported block size."
  1053. #endif
  1054. for(m=0;m<OD_INTRA_NMODES;m++){
  1055. fprintf(_fp,"/* Mode %i */\n {\n",m);
  1056. for(j=0;j<B_SZ;j++){
  1057. fprintf(_fp," {");
  1058. for(i=0;i<B_SZ;i++){
  1059. #if B_SZ==4
  1060. fprintf(_fp,"%s %- 24.18G",i>0?",":"",NE_PRED_OFFSETS_4x4[m][j][i]);
  1061. #elif B_SZ==8
  1062. fprintf(_fp,"%s %- 24.18G",i>0?",":"",NE_PRED_OFFSETS_8x8[m][j][i]);
  1063. #elif B_SZ==16
  1064. fprintf(_fp,"%s %- 24.18G",i>0?",":"",NE_PRED_OFFSETS_16x16[m][j][i]);
  1065. #else
  1066. # error "Unsupported block size."
  1067. #endif
  1068. }
  1069. fprintf(_fp," }%s\n",j<B_SZ-1?",":"");
  1070. }
  1071. fprintf(_fp," }%s\n",m<OD_INTRA_NMODES-1?",":"");
  1072. }
  1073. fprintf(_fp,"};\n");
  1074. #if B_SZ==4
  1075. fprintf(_fp,"double NE_PRED_WEIGHTS_4x4[OD_INTRA_NMODES][4][4][2*4][3*4]={\n");
  1076. #elif B_SZ==8
  1077. fprintf(_fp,"double NE_PRED_WEIGHTS_8x8[OD_INTRA_NMODES][8][8][2*8][3*8]={\n");
  1078. #elif B_SZ==16
  1079. fprintf(_fp,"double NE_PRED_WEIGHTS_16x16[OD_INTRA_NMODES][16][16][2*16][3*16]={\n");
  1080. #else
  1081. # error "Unsupported block size."
  1082. #endif
  1083. for(m=0;m<OD_INTRA_NMODES;m++){
  1084. fprintf(_fp," {\n");
  1085. for(j=0;j<B_SZ;j++){
  1086. fprintf(_fp," {\n");
  1087. for(i=0;i<B_SZ;i++){
  1088. fprintf(_fp,"/* Mode %i (%i,%i) */\n {\n",m,j,i);
  1089. for(by=0;by<=1;by++){
  1090. for(k=0;k<B_SZ;k++){
  1091. fprintf(_fp," {");
  1092. for(bx=0;bx<=2-by;bx++){
  1093. for(l=0;l<B_SZ;l++){
  1094. #if B_SZ==4
  1095. fprintf(_fp,"%s %- 24.18G",bx>0||l>0?",":"",NE_PRED_WEIGHTS_4x4[m][j][i][B_SZ*by+k][B_SZ*bx+l]);
  1096. #elif B_SZ==8
  1097. fprintf(_fp,"%s %- 24.18G",bx>0||l>0?",":"",NE_PRED_WEIGHTS_8x8[m][j][i][B_SZ*by+k][B_SZ*bx+l]);
  1098. #elif B_SZ==16
  1099. fprintf(_fp,"%s %- 24.18G",bx>0||l>0?",":"",NE_PRED_WEIGHTS_16x16[m][j][i][B_SZ*by+k][B_SZ*bx+l]);
  1100. #else
  1101. # error "Unsupported block size."
  1102. #endif
  1103. }
  1104. }
  1105. fprintf(_fp," }%s\n",by<1||k<B_SZ-1?",":"");
  1106. }
  1107. }
  1108. fprintf(_fp," }%s\n",i<B_SZ-1?",":"");
  1109. }
  1110. fprintf(_fp," }%s\n",j<B_SZ-1?",":"");
  1111. }
  1112. fprintf(_fp," }%s\n",m<OD_INTRA_NMODES-1?",":"");
  1113. }
  1114. fprintf(_fp,"};\n");
  1115. }