trans_tools.c 29 KB

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