trans_tools.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. /*Daala video codec
  2. Copyright (c) 2013 Daala project contributors. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. - Redistributions of source code must retain the above copyright notice, this
  6. list of conditions and the following disclaimer.
  7. - Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
  11. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  12. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  13. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  14. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  15. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  16. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  17. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  18. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  19. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <stdlib.h>
  24. #include "od_defs.h"
  25. #include "od_filter.h"
  26. #include "stats_tools.h"
  27. #include "trans_tools.h"
  28. #define PRINT_COLLAPSE (0)
  29. #define PRINT_CG_MATH (0)
  30. void image_ctx_init(image_ctx *_this,const char *_name,int _nxblocks,
  31. int _nyblocks){
  32. _this->name=_name;
  33. _this->nxblocks=_nxblocks;
  34. _this->nyblocks=_nyblocks;
  35. }
  36. void trans_data_init(trans_data *_this,int _sz){
  37. int i;
  38. int j;
  39. _this->sz=_sz;
  40. _this->n=0;
  41. _this->mean=(double *)malloc(sizeof(*_this->mean)*_this->sz);
  42. _this->cov=(double *)malloc(sizeof(*_this->cov)*_this->sz*_this->sz);
  43. _this->work=(double *)malloc(sizeof(*_this->work)*_this->sz);
  44. for(j=0;j<_this->sz;j++){
  45. _this->mean[j]=0;
  46. for(i=0;i<_this->sz;i++){
  47. _this->cov[_this->sz*j+i]=0;
  48. }
  49. }
  50. }
  51. void trans_data_clear(trans_data *_this){
  52. free(_this->mean);
  53. free(_this->cov);
  54. free(_this->work);
  55. }
  56. void trans_data_add(trans_data *_this,const unsigned char *_data){
  57. double s;
  58. int i;
  59. int j;
  60. _this->n++;
  61. s=1.0/_this->n;
  62. for(i=0;i<_this->sz;i++){
  63. _this->work[i]=_data[i]-_this->mean[i];
  64. #if FAST_MATH
  65. _this->mean[i]+=_this->work[i]*s;
  66. #else
  67. _this->mean[i]+=_this->work[i]/_this->n;
  68. #endif
  69. }
  70. s=(_this->n-1.0)/_this->n;
  71. for(j=0;j<_this->sz;j++){
  72. for(i=0;i<_this->sz;i++){
  73. #if FAST_MATH
  74. _this->cov[_this->sz*j+i]+=_this->work[j]*_this->work[i]*s;
  75. #else
  76. _this->cov[_this->sz*j+i]+=
  77. _this->work[j]*_this->work[i]*(_this->n-1)/_this->n;
  78. #endif
  79. }
  80. }
  81. }
  82. void trans_data_combine(trans_data *_a,const trans_data *_b){
  83. double s;
  84. int i;
  85. int j;
  86. if(_b->n==0){
  87. return;
  88. }
  89. s=((double)_b->n)/(_a->n+_b->n);
  90. for(i=0;i<_a->sz;i++){
  91. _a->work[i]=_b->mean[i]-_a->mean[i];
  92. #if FAST_MATH
  93. _a->mean[i]+=_a->work[i]*s;
  94. #else
  95. _a->mean[i]+=_a->work[i]*_b->n/(_a->n+_b->n);
  96. #endif
  97. }
  98. s*=_a->n;
  99. for(i=0;i<_a->sz;i++){
  100. for(j=0;j<_a->sz;j++){
  101. #if FAST_MATH
  102. _a->cov[_a->sz*i+j]+=_b->cov[_a->sz*i+j]+_a->work[i]*_a->work[j]*s;
  103. #else
  104. _a->cov[_a->sz*i+j]+=
  105. _b->cov[_a->sz*i+j]+_a->work[i]*_a->work[j]*_a->n*_b->n/(_a->n+_b->n);
  106. #endif
  107. }
  108. }
  109. _a->n+=_b->n;
  110. }
  111. void trans_data_correct(trans_data *_this){
  112. double s;
  113. int j;
  114. int i;
  115. s=1.0/_this->n;
  116. for(j=0;j<_this->sz;j++){
  117. for(i=0;i<_this->sz;i++){
  118. #if FAST_MATH
  119. _this->cov[_this->sz*j+i]*=s;
  120. #else
  121. _this->cov[_this->sz*j+i]/=_this->n;
  122. #endif
  123. }
  124. }
  125. }
  126. void trans_data_normalize(trans_data *_this){
  127. int i;
  128. int j;
  129. for(i=0;i<_this->sz;i++){
  130. _this->work[i]=sqrt(_this->cov[_this->sz*i+i]);
  131. }
  132. for(j=0;j<_this->sz;j++){
  133. for(i=0;i<_this->sz;i++){
  134. _this->cov[_this->sz*j+i]/=_this->work[j]*_this->work[i];
  135. }
  136. }
  137. }
  138. void trans_data_collapse(trans_data *_this,int _n,double *_r){
  139. covariance_collapse(_this->cov,_this->sz,_n,_r,_this->work);
  140. }
  141. void trans_data_expand(trans_data *_this,int _n,const double *_r){
  142. covariance_expand(_this->cov,_this->sz,_n,_r);
  143. }
  144. void trans_data_print(trans_data *_this,FILE *_fp){
  145. int i;
  146. int j;
  147. for(i=0;i<_this->sz;i++){
  148. fprintf(_fp,"%s %- 24.18G",i>0?",":"",_this->mean[i]);
  149. }
  150. fprintf(_fp,"\n");
  151. for(j=0;j<_this->sz;j++){
  152. for(i=0;i<_this->sz;i++){
  153. fprintf(_fp,"%s %- 24.18G",i>0?",":"",_this->cov[_this->sz*j+i]);
  154. }
  155. fprintf(_fp,"\n");
  156. }
  157. }
  158. void covariance_collapse(const double *_cov,int _sz,int _n,double *_r,
  159. double *_work){
  160. int m;
  161. int i;
  162. int j;
  163. int u;
  164. int v;
  165. m=_sz/_n;
  166. for(i=0;i<_sz;i++){
  167. _r[i]=0;
  168. _work[i]=0;
  169. }
  170. for(v=0;v<_n;v++){
  171. for(u=v;u<_n;u++){
  172. for(j=0;j<m;j++){
  173. for(i=j;i<m;i++){
  174. _r[(u-v)*m+(i-j)]+=_cov[(v*m+j)*_sz+(u*m+i)];
  175. _r[(u-v)*m+(i-j)]+=_cov[(v*m+i)*_sz+(u*m+j)];
  176. _r[(u-v)*m+(i-j)]+=_cov[(u*m+j)*_sz+(v*m+i)];
  177. _r[(u-v)*m+(i-j)]+=_cov[(u*m+i)*_sz+(v*m+j)];
  178. _work[(u-v)*m+(i-j)]+=4;
  179. }
  180. }
  181. }
  182. }
  183. for(i=0;i<_sz;i++){
  184. _r[i]/=_work[i];
  185. }
  186. #if PRINT_COLLAPSE
  187. for(i=0;i<_sz;i++){
  188. fprintf(stderr,"%s %- 24.18G",i>0?",":"",_r[i]);
  189. }
  190. fprintf(stderr,"\n");
  191. #endif
  192. }
  193. void covariance_expand(double *_cov,int _sz,int _n,const double *_r){
  194. int i;
  195. int j;
  196. int u;
  197. int v;
  198. int m;
  199. m=_sz/_n;
  200. for(v=0;v<_n;v++){
  201. for(u=0;u<_n;u++){
  202. for(j=0;j<m;j++){
  203. for(i=0;i<m;i++){
  204. _cov[(v*m+j)*_sz+u*m+i]=_r[abs(v-u)*m+abs(i-j)];
  205. }
  206. }
  207. }
  208. }
  209. }
  210. /*The true forward 4-point type-II DCT basis, to 32-digit (100 bit) precision.
  211. The inverse is merely the transpose.*/
  212. static const double DCT4_BASIS[4][4]={
  213. {
  214. 0.5, 0.5,
  215. 0.5, 0.5
  216. },
  217. {
  218. 0.65328148243818826392832158671359, 0.27059805007309849219986160268319,
  219. -0.27059805007309849219986160268319, -0.65328148243818826392832158671359
  220. },
  221. {
  222. 0.5, -0.5,
  223. -0.5, 0.5
  224. },
  225. {
  226. 0.27059805007309849219986160268319, -0.65328148243818826392832158671359,
  227. 0.65328148243818826392832158671359, -0.27059805007309849219986160268319
  228. },
  229. };
  230. /*The true forward 8-point type-II DCT basis, to 32-digit (100 bit) precision.
  231. The inverse is merely the transpose.*/
  232. static const double DCT8_BASIS[8][8]={
  233. {
  234. 0.35355339059327376220042218105242, 0.35355339059327376220042218105242,
  235. 0.35355339059327376220042218105242, 0.35355339059327376220042218105242,
  236. 0.35355339059327376220042218105242, 0.35355339059327376220042218105242,
  237. 0.35355339059327376220042218105242, 0.35355339059327376220042218105242
  238. },
  239. {
  240. 0.49039264020161522456309111806712, 0.41573480615127261853939418880895,
  241. 0.27778511650980111237141540697427, 0.097545161008064133924142434238511,
  242. -0.097545161008064133924142434238511,-0.27778511650980111237141540697427,
  243. -0.41573480615127261853939418880895, -0.49039264020161522456309111806712
  244. },
  245. {
  246. 0.46193976625574337806409159469839, 0.19134171618254488586422999201520,
  247. -0.19134171618254488586422999201520, -0.46193976625574337806409159469839,
  248. -0.46193976625574337806409159469839, -0.19134171618254488586422999201520,
  249. 0.19134171618254488586422999201520, 0.46193976625574337806409159469839
  250. },
  251. {
  252. 0.41573480615127261853939418880895, -0.097545161008064133924142434238511,
  253. -0.49039264020161522456309111806712, -0.27778511650980111237141540697427,
  254. 0.27778511650980111237141540697427, 0.49039264020161522456309111806712,
  255. 0.097545161008064133924142434238511,-0.41573480615127261853939418880895
  256. },
  257. {
  258. 0.35355339059327376220042218105242, -0.35355339059327376220042218105242,
  259. -0.35355339059327376220042218105242, 0.35355339059327376220042218105242,
  260. 0.35355339059327376220042218105242, -0.35355339059327376220042218105242,
  261. -0.35355339059327376220042218105242, 0.35355339059327376220042218105242
  262. },
  263. {
  264. 0.27778511650980111237141540697427, -0.49039264020161522456309111806712,
  265. 0.097545161008064133924142434238511, 0.41573480615127261853939418880895,
  266. -0.41573480615127261853939418880895, -0.097545161008064133924142434238511,
  267. 0.49039264020161522456309111806712, -0.27778511650980111237141540697427
  268. },
  269. {
  270. 0.19134171618254488586422999201520, -0.46193976625574337806409159469839,
  271. 0.46193976625574337806409159469839, -0.19134171618254488586422999201520,
  272. -0.19134171618254488586422999201520, 0.46193976625574337806409159469839,
  273. -0.46193976625574337806409159469839, 0.19134171618254488586422999201520
  274. },
  275. {
  276. 0.097545161008064133924142434238511,-0.27778511650980111237141540697427,
  277. 0.41573480615127261853939418880895, -0.49039264020161522456309111806712,
  278. 0.49039264020161522456309111806712, -0.41573480615127261853939418880895,
  279. 0.27778511650980111237141540697427, -0.097545161008064133924142434238511
  280. }
  281. };
  282. /*The true forward 8-point type-II DCT basis, to 32-digit (100 bit) precision.
  283. The inverse is merely the transpose.*/
  284. static const double DCT16_BASIS[16][16]={
  285. {
  286. 0.25, 0.25,
  287. 0.25, 0.25,
  288. 0.25, 0.25,
  289. 0.25, 0.25,
  290. 0.25, 0.25,
  291. 0.25, 0.25,
  292. 0.25, 0.25,
  293. 0.25, 0.25
  294. },{
  295. 0.35185093438159561475651955574599, 0.33832950029358816956728612239141,
  296. 0.31180625324666780814299756569942, 0.27330046675043937205975812924953,
  297. 0.22429189658565907106266034730521, 0.16666391461943662432490137779072,
  298. 0.10263113188058934528909230943878, 0.034654292299772865648933749133244,
  299. -0.034654292299772865648933749133244,-0.10263113188058934528909230943878,
  300. -0.16666391461943662432490137779072, -0.22429189658565907106266034730521,
  301. -0.27330046675043937205975812924953, -0.31180625324666780814299756569942,
  302. -0.33832950029358816956728612239141, -0.35185093438159561475651955574599
  303. },{
  304. 0.34675996133053686545540479789161, 0.29396890060483967924361677615282,
  305. 0.19642373959677554531947434191430, 0.068974844820735753083989390917343,
  306. -0.068974844820735753083989390917343,-0.19642373959677554531947434191430,
  307. -0.29396890060483967924361677615282, -0.34675996133053686545540479789161,
  308. -0.34675996133053686545540479789161, -0.29396890060483967924361677615282,
  309. -0.19642373959677554531947434191430, -0.068974844820735753083989390917343,
  310. 0.068974844820735753083989390917343, 0.19642373959677554531947434191430,
  311. 0.29396890060483967924361677615282, 0.34675996133053686545540479789161
  312. },{
  313. 0.33832950029358816956728612239141, 0.22429189658565907106266034730521,
  314. 0.034654292299772865648933749133244,-0.16666391461943662432490137779072,
  315. -0.31180625324666780814299756569942, -0.35185093438159561475651955574599,
  316. -0.27330046675043937205975812924953, -0.10263113188058934528909230943878,
  317. 0.10263113188058934528909230943878, 0.27330046675043937205975812924953,
  318. 0.35185093438159561475651955574599, 0.31180625324666780814299756569942,
  319. 0.16666391461943662432490137779072, -0.034654292299772865648933749133244,
  320. -0.22429189658565907106266034730521, -0.33832950029358816956728612239141
  321. },{
  322. 0.32664074121909413196416079335680, 0.13529902503654924609993080134160,
  323. -0.13529902503654924609993080134160, -0.32664074121909413196416079335680,
  324. -0.32664074121909413196416079335680, -0.13529902503654924609993080134160,
  325. 0.13529902503654924609993080134160, 0.32664074121909413196416079335680,
  326. 0.32664074121909413196416079335680, 0.13529902503654924609993080134160,
  327. -0.13529902503654924609993080134160, -0.32664074121909413196416079335680,
  328. -0.32664074121909413196416079335680, -0.13529902503654924609993080134160,
  329. 0.13529902503654924609993080134160, 0.32664074121909413196416079335680
  330. },{
  331. 0.31180625324666780814299756569942, 0.034654292299772865648933749133244,
  332. -0.27330046675043937205975812924953, -0.33832950029358816956728612239141,
  333. -0.10263113188058934528909230943878, 0.22429189658565907106266034730521,
  334. 0.35185093438159561475651955574599, 0.16666391461943662432490137779072,
  335. -0.16666391461943662432490137779072, -0.35185093438159561475651955574599,
  336. -0.22429189658565907106266034730521, 0.10263113188058934528909230943878,
  337. 0.33832950029358816956728612239141, 0.27330046675043937205975812924953,
  338. -0.034654292299772865648933749133244,-0.31180625324666780814299756569942
  339. },{
  340. 0.29396890060483967924361677615282, -0.068974844820735753083989390917343,
  341. -0.34675996133053686545540479789161, -0.19642373959677554531947434191430,
  342. 0.19642373959677554531947434191430, 0.34675996133053686545540479789161,
  343. 0.068974844820735753083989390917343,-0.29396890060483967924361677615282,
  344. -0.29396890060483967924361677615282, 0.068974844820735753083989390917343,
  345. 0.34675996133053686545540479789161, 0.19642373959677554531947434191430,
  346. -0.19642373959677554531947434191430, -0.34675996133053686545540479789161,
  347. -0.068974844820735753083989390917343, 0.29396890060483967924361677615282
  348. },{
  349. 0.27330046675043937205975812924953, -0.16666391461943662432490137779072,
  350. -0.33832950029358816956728612239141, 0.034654292299772865648933749133244,
  351. 0.35185093438159561475651955574599, 0.10263113188058934528909230943878,
  352. -0.31180625324666780814299756569942, -0.22429189658565907106266034730521,
  353. 0.22429189658565907106266034730521, 0.31180625324666780814299756569942,
  354. -0.10263113188058934528909230943878, -0.35185093438159561475651955574599,
  355. -0.034654292299772865648933749133244, 0.33832950029358816956728612239141,
  356. 0.16666391461943662432490137779072, -0.27330046675043937205975812924953
  357. },{
  358. 0.25, -0.25,
  359. -0.25, 0.25,
  360. 0.25, -0.25,
  361. -0.25, 0.25,
  362. 0.25, -0.25,
  363. -0.25, 0.25,
  364. 0.25, -0.25,
  365. -0.25, 0.25
  366. },{
  367. 0.22429189658565907106266034730521, -0.31180625324666780814299756569942,
  368. -0.10263113188058934528909230943878, 0.35185093438159561475651955574599,
  369. -0.034654292299772865648933749133244,-0.33832950029358816956728612239141,
  370. 0.16666391461943662432490137779072, 0.27330046675043937205975812924953,
  371. -0.27330046675043937205975812924953, -0.16666391461943662432490137779072,
  372. 0.33832950029358816956728612239141, 0.034654292299772865648933749133244,
  373. -0.35185093438159561475651955574599, 0.10263113188058934528909230943878,
  374. 0.31180625324666780814299756569942, -0.22429189658565907106266034730521
  375. },{
  376. 0.19642373959677554531947434191430, -0.34675996133053686545540479789161,
  377. 0.068974844820735753083989390917343, 0.29396890060483967924361677615282,
  378. -0.29396890060483967924361677615282, -0.068974844820735753083989390917343,
  379. 0.34675996133053686545540479789161, -0.19642373959677554531947434191430,
  380. -0.19642373959677554531947434191430, 0.34675996133053686545540479789161,
  381. -0.068974844820735753083989390917343,-0.29396890060483967924361677615282,
  382. 0.29396890060483967924361677615282, 0.068974844820735753083989390917343,
  383. -0.34675996133053686545540479789161, 0.19642373959677554531947434191430
  384. },{
  385. 0.16666391461943662432490137779072, -0.35185093438159561475651955574599,
  386. 0.22429189658565907106266034730521, 0.10263113188058934528909230943878,
  387. -0.33832950029358816956728612239141, 0.27330046675043937205975812924953,
  388. 0.034654292299772865648933749133244,-0.31180625324666780814299756569942,
  389. 0.31180625324666780814299756569942, -0.034654292299772865648933749133244,
  390. -0.27330046675043937205975812924953, 0.33832950029358816956728612239141,
  391. -0.10263113188058934528909230943878, -0.22429189658565907106266034730521,
  392. 0.35185093438159561475651955574599, -0.16666391461943662432490137779072
  393. },{
  394. 0.13529902503654924609993080134160, -0.32664074121909413196416079335680,
  395. 0.32664074121909413196416079335680, -0.13529902503654924609993080134160,
  396. -0.13529902503654924609993080134160, 0.32664074121909413196416079335680,
  397. -0.32664074121909413196416079335680, 0.13529902503654924609993080134160,
  398. 0.13529902503654924609993080134160, -0.32664074121909413196416079335680,
  399. 0.32664074121909413196416079335680, -0.13529902503654924609993080134160,
  400. -0.13529902503654924609993080134160, 0.32664074121909413196416079335680,
  401. -0.32664074121909413196416079335680, 0.13529902503654924609993080134160
  402. },{
  403. 0.10263113188058934528909230943878, -0.27330046675043937205975812924953,
  404. 0.35185093438159561475651955574599, -0.31180625324666780814299756569942,
  405. 0.16666391461943662432490137779072, 0.034654292299772865648933749133244,
  406. -0.22429189658565907106266034730521, 0.33832950029358816956728612239141,
  407. -0.33832950029358816956728612239141, 0.22429189658565907106266034730521,
  408. -0.034654292299772865648933749133244,-0.16666391461943662432490137779072,
  409. 0.31180625324666780814299756569942, -0.35185093438159561475651955574599,
  410. 0.27330046675043937205975812924953, -0.10263113188058934528909230943878
  411. },{
  412. 0.068974844820735753083989390917343,-0.19642373959677554531947434191430,
  413. 0.29396890060483967924361677615282, -0.34675996133053686545540479789161,
  414. 0.34675996133053686545540479789161, -0.29396890060483967924361677615282,
  415. 0.19642373959677554531947434191430, -0.068974844820735753083989390917343,
  416. -0.068974844820735753083989390917343, 0.19642373959677554531947434191430,
  417. -0.29396890060483967924361677615282, 0.34675996133053686545540479789161,
  418. -0.34675996133053686545540479789161, 0.29396890060483967924361677615282,
  419. -0.19642373959677554531947434191430, 0.068974844820735753083989390917343
  420. },{
  421. 0.034654292299772865648933749133244,-0.10263113188058934528909230943878,
  422. 0.16666391461943662432490137779072, -0.22429189658565907106266034730521,
  423. 0.27330046675043937205975812924953, -0.31180625324666780814299756569942,
  424. 0.33832950029358816956728612239141, -0.35185093438159561475651955574599,
  425. 0.35185093438159561475651955574599, -0.33832950029358816956728612239141,
  426. 0.31180625324666780814299756569942, -0.27330046675043937205975812924953,
  427. 0.22429189658565907106266034730521, -0.16666391461943662432490137779072,
  428. 0.10263113188058934528909230943878, -0.034654292299772865648933749133244
  429. }
  430. };
  431. void ne_fdct4_double(double _x[],const double _y[],int _in_stride){
  432. double t[4];
  433. int i;
  434. int j;
  435. for(j=0;j<4;j++){
  436. t[j]=0;
  437. for(i=0;i<4;i++){
  438. t[j]+=DCT4_BASIS[j][i]*_y[i*_in_stride];
  439. }
  440. }
  441. for(j=0;j<4;j++){
  442. _x[j]=t[j];
  443. }
  444. }
  445. void ne_idct4_double(double _x[],int _out_stride,const double _y[]){
  446. double t[4];
  447. int i;
  448. int j;
  449. for(j=0;j<4;j++){
  450. t[j]=0;
  451. for(i=0;i<4;i++){
  452. t[j]+=DCT4_BASIS[i][j]*_y[i];
  453. }
  454. }
  455. for(j=0;j<4;j++){
  456. _x[j*_out_stride]=t[j];
  457. }
  458. }
  459. void ne_fdct8_double(double _x[],const double _y[],int _in_stride){
  460. double t[8];
  461. int i;
  462. int j;
  463. for(j=0;j<8;j++){
  464. t[j]=0;
  465. for(i=0;i<8;i++){
  466. t[j]+=DCT8_BASIS[j][i]*_y[i*_in_stride];
  467. }
  468. }
  469. for(j=0;j<8;j++){
  470. _x[j]=t[j];
  471. }
  472. }
  473. void ne_idct8_double(double _x[],int _out_stride,const double _y[]){
  474. double t[8];
  475. int i;
  476. int j;
  477. for(j=0;j<8;j++){
  478. t[j]=0;
  479. for(i=0;i<8;i++){
  480. t[j]+=DCT8_BASIS[i][j]*_y[i];
  481. }
  482. }
  483. for(j=0;j<8;j++){
  484. _x[j*_out_stride]=t[j];
  485. }
  486. }
  487. void ne_fdct16_double(double _x[],const double _y[],int _in_stride){
  488. double t[16];
  489. int i;
  490. int j;
  491. for(j=0;j<16;j++){
  492. t[j]=0;
  493. for(i=0;i<16;i++){
  494. t[j]+=DCT16_BASIS[j][i]*_y[i*_in_stride];
  495. }
  496. }
  497. for(j=0;j<16;j++){
  498. _x[j]=t[j];
  499. }
  500. }
  501. void ne_idct16_double(double _x[],int _out_stride,const double _y[]){
  502. double t[16];
  503. int i;
  504. int j;
  505. for(j=0;j<16;j++){
  506. t[j]=0;
  507. for(i=0;i<16;i++){
  508. t[j]+=DCT16_BASIS[i][j]*_y[i];
  509. }
  510. }
  511. for(j=0;j<16;j++){
  512. _x[j*_out_stride]=t[j];
  513. }
  514. }
  515. typedef void (*ne_fdct_func_1d)(double *_out,const double *_in,int _in_stride);
  516. typedef void (*ne_idct_func_1d)(double *_out,int _out_stride,const double *_in);
  517. const ne_fdct_func_1d OD_FDCT_1D_DOUBLE[OD_NBSIZES]={
  518. ne_fdct4_double,
  519. ne_fdct8_double,
  520. ne_fdct16_double
  521. };
  522. const ne_idct_func_1d OD_IDCT_1D_DOUBLE[OD_NBSIZES]={
  523. ne_idct4_double,
  524. ne_idct8_double,
  525. ne_idct16_double
  526. };
  527. /* 2-dimensional AR(1) model using parameter _r */
  528. void auto_regressive_collapsed(double *_out,int _sz,int _n,double _r){
  529. int m;
  530. int j;
  531. int i;
  532. m=_sz/_n;
  533. for(j=0;j<_n;j++){
  534. _out[j*m]=j==0?1:_out[(j-1)*m]*_r;
  535. for(i=1;i<m;i++){
  536. _out[j*m+i]=_out[j*m+i-1]*_r;
  537. }
  538. }
  539. }
  540. void analysis(double *_out,int _out_stride,const double *_in,int _in_stride,
  541. int _n,const int *_f){
  542. int i;
  543. int j;
  544. double t[2*B_SZ];
  545. for(i=0;i<_n;i++){
  546. for(j=0;j<2*B_SZ;j++){
  547. t[j]=_in[j*_in_stride+i];
  548. }
  549. #if !NE_DISABLE_FILTER
  550. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  551. (*NE_PRE_FILTER_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[0],&t[0],_f);
  552. (*NE_PRE_FILTER_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[B_SZ],&t[B_SZ],_f);
  553. #else
  554. # error "Need a prefilter implementation for this block size."
  555. #endif
  556. #endif
  557. #if !NE_DISABLE_TRANSFORM
  558. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  559. (*OD_FDCT_1D_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[B_SZ/2],&t[B_SZ/2],1);
  560. #else
  561. # error "Need an fDCT implementation for this block size."
  562. #endif
  563. #endif
  564. for(j=0;j<B_SZ;j++){
  565. _out[j*_out_stride+i]=t[B_SZ/2+j];
  566. }
  567. }
  568. }
  569. void synthesis(double *_out,int _out_stride,const double *_in,int _in_stride,
  570. int _n,const int *_f){
  571. int i;
  572. int j;
  573. double t[2*B_SZ];
  574. for(i=0;i<_n;i++){
  575. for(j=0;j<2*B_SZ;j++){
  576. t[j]=0;
  577. }
  578. for(j=0;j<B_SZ;j++){
  579. t[B_SZ/2+j]=_in[j*_in_stride+i];
  580. }
  581. #if !NE_DISABLE_TRANSFORM
  582. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  583. (*OD_IDCT_1D_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[B_SZ/2],1,&t[B_SZ/2]);
  584. #else
  585. # error "Need an iDCT implementation for this block size."
  586. #endif
  587. #endif
  588. #if !NE_DISABLE_FILTER
  589. #if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
  590. (*NE_POST_FILTER_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[0],&t[0],_f);
  591. (*NE_POST_FILTER_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(&t[B_SZ],&t[B_SZ],_f);
  592. #else
  593. # error "Need a postfilter implementation for this block size."
  594. #endif
  595. #endif
  596. for(j=0;j<2*B_SZ;j++){
  597. _out[j*_out_stride+i]=t[j];
  598. }
  599. }
  600. }
  601. #if PRINT_CG_MATH
  602. static void print_matrix(FILE *_fp,const char *_label,const double *_mat,
  603. int _stride,int _n,int _m){
  604. int i;
  605. int j;
  606. fprintf(_fp,"%s=\n",_label);
  607. for(j=0;j<_n;j++){
  608. for(i=0;i<_m;i++){
  609. fprintf(_fp,"%s %- 12.6G",i>0?",":"",_mat[j*_m+i]);
  610. }
  611. fprintf(_fp,"\n");
  612. }
  613. }
  614. #endif
  615. double coding_gain_1d(const double _r[2*B_SZ*2*B_SZ],const int *_f){
  616. int j;
  617. int i;
  618. double r[B_SZ];
  619. double rgt[2*B_SZ*B_SZ];
  620. double grgt[B_SZ*B_SZ];
  621. double cg;
  622. /* R*G^T */
  623. for(j=0;j<2*B_SZ;j++){
  624. analysis(&rgt[j*B_SZ],1,&_r[2*B_SZ*j],1,1,_f);
  625. }
  626. #if PRINT_CG_MATH
  627. print_matrix(stdout,"rgt",rgt,B_SZ,2*B_SZ,B_SZ);
  628. #endif
  629. /* G*R*G^T */
  630. analysis(grgt,B_SZ,rgt,B_SZ,B_SZ,_f);
  631. #if PRINT_CG_MATH
  632. print_matrix(stdout,"grgt",grgt,B_SZ,B_SZ,B_SZ);
  633. #endif
  634. /* H */
  635. for(j=0;j<B_SZ;j++){
  636. for(i=0;i<B_SZ;i++){
  637. r[i]=i==j?1:0;
  638. }
  639. synthesis(&rgt[j],B_SZ,r,1,1,_f);
  640. }
  641. #if PRINT_CG_MATH
  642. print_matrix(stdout,"hi",rgt,B_SZ,2*B_SZ,B_SZ);
  643. fprintf(stdout,"G,H=\n");
  644. #endif
  645. /* (G*R*G^T)_ii * (H^T*H)_ii */
  646. cg=0;
  647. for(j=0;j<B_SZ;j++){
  648. double h;
  649. h=0;
  650. for(i=0;i<2*B_SZ;i++){
  651. h+=rgt[i*B_SZ+j]*rgt[i*B_SZ+j];
  652. }
  653. #if PRINT_CG_MATH
  654. fprintf(stdout," %- 12.6G, %- 12.6G\n",grgt[j*B_SZ+j],h);
  655. #endif
  656. cg-=10*log10(grgt[j*B_SZ+j]*h);
  657. }
  658. return cg/B_SZ;
  659. }
  660. double coding_gain_1d_collapsed(const double _r[2*B_SZ],const int *_f){
  661. int j;
  662. int i;
  663. double r[2*B_SZ];
  664. double rgt[2*B_SZ*B_SZ];
  665. double grgt[B_SZ*B_SZ];
  666. double cg;
  667. /* R*G^T */
  668. for(j=0;j<2*B_SZ;j++){
  669. for(i=0;i<2*B_SZ;i++){
  670. r[i]=_r[abs(i-j)];
  671. }
  672. analysis(&rgt[j*B_SZ],1,r,1,1,_f);
  673. }
  674. #if PRINT_CG_MATH
  675. print_matrix(stdout,"rgt",rgt,B_SZ,2*B_SZ,B_SZ);
  676. #endif
  677. /* G*R*G^T */
  678. analysis(grgt,B_SZ,rgt,B_SZ,B_SZ,_f);
  679. #if PRINT_CG_MATH
  680. print_matrix(stdout,"grgt",grgt,B_SZ,B_SZ,B_SZ);
  681. #endif
  682. /* H */
  683. for(j=0;j<B_SZ;j++){
  684. for(i=0;i<B_SZ;i++){
  685. r[i]=i==j?1:0;
  686. }
  687. synthesis(&rgt[j],B_SZ,r,1,1,_f);
  688. }
  689. #if PRINT_CG_MATH
  690. print_matrix(stdout,"hi",rgt,B_SZ,2*B_SZ,B_SZ);
  691. fprintf(stdout,"G,H=\n");
  692. #endif
  693. /* (G*R*G^T)_ii * (H^T*H)_ii */
  694. cg=0;
  695. for(j=0;j<B_SZ;j++){
  696. double h;
  697. h=0;
  698. for(i=0;i<2*B_SZ;i++){
  699. h+=rgt[i*B_SZ+j]*rgt[i*B_SZ+j];
  700. }
  701. #if PRINT_CG_MATH
  702. fprintf(stdout," %- 12.6G, %- 12.6G\n",grgt[j*B_SZ+j],h);
  703. #endif
  704. cg-=10*log10(grgt[j*B_SZ+j]*h);
  705. }
  706. return cg/B_SZ;
  707. }
  708. double coding_gain_2d(const double _r[2*B_SZ*2*B_SZ*2*B_SZ*2*B_SZ],const int *_f){
  709. int v;
  710. int u;
  711. int j;
  712. int i;
  713. double r[2*B_SZ];
  714. double s[2*B_SZ*B_SZ];
  715. double rggt[2*B_SZ*2*B_SZ*B_SZ*B_SZ];
  716. double ggrggt[B_SZ*B_SZ*B_SZ*B_SZ];
  717. double cg;
  718. /* R*(G2*P*G1)^T */
  719. for(v=0;v<2*B_SZ;v++){
  720. for(j=0;j<2*B_SZ;j++){
  721. for(u=0;u<2*B_SZ;u++){
  722. analysis(&s[u*B_SZ],1,&_r[2*B_SZ*2*B_SZ*2*B_SZ*u+2*B_SZ*v+j],2*B_SZ*2*B_SZ,1,_f);
  723. }
  724. analysis(&rggt[(v*2*B_SZ+j)*B_SZ*B_SZ],B_SZ,s,B_SZ,B_SZ,_f);
  725. }
  726. }
  727. #if PRINT_CG_MATH
  728. print_matrix(stdout,"rggt",rggt,B_SZ*B_SZ,4*B_SZ*B_SZ,B_SZ*B_SZ);
  729. #endif
  730. /* G1*P*G2*R*(G2*P*G1)^T */
  731. for(v=0;v<B_SZ;v++){
  732. for(j=0;j<B_SZ;j++){
  733. for(u=0;u<2*B_SZ;u++){
  734. analysis(&s[u*B_SZ],1,&rggt[2*B_SZ*B_SZ*B_SZ*u+v*B_SZ+j],B_SZ*B_SZ,1,_f);
  735. }
  736. analysis(&ggrggt[(v*B_SZ+j)*B_SZ*B_SZ],B_SZ,s,B_SZ,B_SZ,_f);
  737. }
  738. }
  739. #if PRINT_CG_MATH
  740. print_matrix(stdout,"ggrggt",ggrggt,B_SZ*B_SZ,B_SZ*B_SZ,B_SZ*B_SZ);
  741. #endif
  742. /* H */
  743. for(j=0;j<B_SZ;j++){
  744. for(i=0;i<B_SZ;i++){
  745. r[i]=i==j?1:0;
  746. }
  747. synthesis(&s[j],B_SZ,r,1,1,_f);
  748. }
  749. #if PRINT_CG_MATH
  750. print_matrix(stdout,"hi",s,B_SZ,2*B_SZ,B_SZ);
  751. #endif
  752. /* H1*P*H2 */
  753. for(i=0;i<2*B_SZ;i++){
  754. r[i]=0;
  755. }
  756. for(u=0;u<2*B_SZ;u++){
  757. for(j=0;j<B_SZ;j++){
  758. r[B_SZ]=s[B_SZ*u+j];
  759. for(i=0;i<B_SZ;i++){
  760. synthesis(&rggt[B_SZ*B_SZ*u*2*B_SZ+j+i*B_SZ],B_SZ*B_SZ,&r[B_SZ-i],1,1,_f);
  761. }
  762. }
  763. }
  764. #if PRINT_CG_MATH
  765. print_matrix(stdout,"hhi",rggt,B_SZ*B_SZ,4*B_SZ*B_SZ,B_SZ*B_SZ);
  766. fprintf(stdout,"G,H=\n");
  767. #endif
  768. /* ((H1*P*H2)^T*H1*P*H2)_ii */
  769. for(j=0;j<B_SZ*B_SZ;j++){
  770. s[j]=0;
  771. for(i=0;i<4*B_SZ*B_SZ;i++){
  772. s[j]+=rggt[i*B_SZ*B_SZ+j]*rggt[i*B_SZ*B_SZ+j];
  773. }
  774. }
  775. /* (G1*P*G2*R*(G1*P*G2)^T)_ii * ((H1*P*H2)^T*H1*P*H2)_ii */
  776. cg=0;
  777. for(j=0;j<B_SZ*B_SZ;j++){
  778. fprintf(stdout," %- 12.6G, %- 12.6G\n",ggrggt[B_SZ*B_SZ*j+j],s[j]);
  779. cg-=10*log10(ggrggt[B_SZ*B_SZ*j+j]*s[j]);
  780. }
  781. return cg/(B_SZ*B_SZ);
  782. }
  783. double coding_gain_2d_collapsed(const double _r[2*B_SZ*2*B_SZ],const int *_f){
  784. int v;
  785. int u;
  786. int j;
  787. int i;
  788. double r[2*B_SZ];
  789. double s[2*B_SZ*B_SZ];
  790. double rggt[2*B_SZ*2*B_SZ*B_SZ*B_SZ];
  791. double ggrggt[B_SZ*B_SZ*B_SZ*B_SZ];
  792. double cg;
  793. #if NN_SEARCH
  794. double basis[B_SZ];
  795. for(v=0;v<B_SZ;v++)basis[v]=v<(B_SZ>>1)?0:255;
  796. (NE_POST_FILTER_DOUBLE[B_SZ_LOG-OD_LOG_BSIZE0])(basis,basis,_f);
  797. for(v=0;v<B_SZ;v++)if(basis[v]<0)return -100;
  798. #endif
  799. /* R*(G2*P*G1)^T */
  800. for(v=0;v<2*B_SZ;v++){
  801. for(j=0;j<2*B_SZ;j++){
  802. for(u=0;u<2*B_SZ;u++){
  803. for(i=0;i<2*B_SZ;i++){
  804. r[i]=_r[abs(u-v)*2*B_SZ+abs(i-j)];
  805. }
  806. analysis(&s[u*B_SZ],1,r,1,1,_f);
  807. }
  808. analysis(&rggt[(v*2*B_SZ+j)*B_SZ*B_SZ],B_SZ,s,B_SZ,B_SZ,_f);
  809. }
  810. }
  811. #if PRINT_CG_MATH
  812. print_matrix(stdout,"rggt",rggt,B_SZ*B_SZ,4*B_SZ*B_SZ,B_SZ*B_SZ);
  813. #endif
  814. /* G1*P*G2*R*(G2*P*G1)^T */
  815. for(v=0;v<B_SZ;v++){
  816. for(j=0;j<B_SZ;j++){
  817. for(u=0;u<2*B_SZ;u++){
  818. analysis(&s[u*B_SZ],1,&rggt[2*B_SZ*B_SZ*B_SZ*u+v*B_SZ+j],B_SZ*B_SZ,1,_f);
  819. }
  820. analysis(&ggrggt[(v*B_SZ+j)*B_SZ*B_SZ],B_SZ,s,B_SZ,B_SZ,_f);
  821. }
  822. }
  823. #if PRINT_CG_MATH
  824. print_matrix(stdout,"ggrggt",ggrggt,B_SZ*B_SZ,B_SZ*B_SZ,B_SZ*B_SZ);
  825. #endif
  826. /* H */
  827. for(j=0;j<B_SZ;j++){
  828. for(i=0;i<B_SZ;i++){
  829. r[i]=i==j?1:0;
  830. }
  831. synthesis(&s[j],B_SZ,r,1,1,_f);
  832. }
  833. #if PRINT_CG_MATH
  834. print_matrix(stdout,"hi",s,B_SZ,2*B_SZ,B_SZ);
  835. #endif
  836. /* H1*P*H2 */
  837. for(i=0;i<2*B_SZ;i++){
  838. r[i]=0;
  839. }
  840. for(u=0;u<2*B_SZ;u++){
  841. for(j=0;j<B_SZ;j++){
  842. r[B_SZ]=s[B_SZ*u+j];
  843. for(i=0;i<B_SZ;i++){
  844. synthesis(&rggt[B_SZ*B_SZ*u*2*B_SZ+j+i*B_SZ],B_SZ*B_SZ,&r[B_SZ-i],1,1,_f);
  845. }
  846. }
  847. }
  848. #if PRINT_CG_MATH
  849. print_matrix(stdout,"hhi",rggt,B_SZ*B_SZ,4*B_SZ*B_SZ,B_SZ*B_SZ);
  850. fprintf(stdout,"G,H=\n");
  851. #endif
  852. /* ((H1*P*H2)^T*H1*P*H2)_ii */
  853. for(j=0;j<B_SZ*B_SZ;j++){
  854. s[j]=0;
  855. for(i=0;i<4*B_SZ*B_SZ;i++){
  856. s[j]+=rggt[i*B_SZ*B_SZ+j]*rggt[i*B_SZ*B_SZ+j];
  857. }
  858. }
  859. /* (G1*P*G2*R*(G1*P*G2)^T)_ii * ((H1*P*H2)^T*H1*P*H2)_ii */
  860. cg=0;
  861. for(j=0;j<B_SZ*B_SZ;j++){
  862. #if PRINT_CG_MATH
  863. fprintf(stdout," %- 12.6G, %- 12.6G\n",ggrggt[B_SZ*B_SZ*j+j],s[j]);
  864. #endif
  865. cg-=10*log10(ggrggt[B_SZ*B_SZ*j+j]*s[j]);
  866. }
  867. return cg/(B_SZ*B_SZ);
  868. }