2
0

fwd_txfm.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. /*
  2. * Copyright (c) 2015 The WebM project authors. All Rights Reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #include <assert.h>
  11. #include "./vpx_dsp_rtcd.h"
  12. #include "vpx_dsp/fwd_txfm.h"
  13. void vpx_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride) {
  14. // The 2D transform is done with two passes which are actually pretty
  15. // similar. In the first one, we transform the columns and transpose
  16. // the results. In the second one, we transform the rows. To achieve that,
  17. // as the first pass results are transposed, we transpose the columns (that
  18. // is the transposed rows) and transpose the results (so that it goes back
  19. // in normal/row positions).
  20. int pass;
  21. // We need an intermediate buffer between passes.
  22. tran_low_t intermediate[4 * 4];
  23. const tran_low_t *in_low = NULL;
  24. tran_low_t *out = intermediate;
  25. // Do the two transform/transpose passes
  26. for (pass = 0; pass < 2; ++pass) {
  27. tran_high_t in_high[4]; // canbe16
  28. tran_high_t step[4]; // canbe16
  29. tran_high_t temp1, temp2; // needs32
  30. int i;
  31. for (i = 0; i < 4; ++i) {
  32. // Load inputs.
  33. if (pass == 0) {
  34. in_high[0] = input[0 * stride] * 16;
  35. in_high[1] = input[1 * stride] * 16;
  36. in_high[2] = input[2 * stride] * 16;
  37. in_high[3] = input[3 * stride] * 16;
  38. if (i == 0 && in_high[0]) {
  39. ++in_high[0];
  40. }
  41. } else {
  42. assert(in_low != NULL);
  43. in_high[0] = in_low[0 * 4];
  44. in_high[1] = in_low[1 * 4];
  45. in_high[2] = in_low[2 * 4];
  46. in_high[3] = in_low[3 * 4];
  47. ++in_low;
  48. }
  49. // Transform.
  50. step[0] = in_high[0] + in_high[3];
  51. step[1] = in_high[1] + in_high[2];
  52. step[2] = in_high[1] - in_high[2];
  53. step[3] = in_high[0] - in_high[3];
  54. temp1 = (step[0] + step[1]) * cospi_16_64;
  55. temp2 = (step[0] - step[1]) * cospi_16_64;
  56. out[0] = (tran_low_t)fdct_round_shift(temp1);
  57. out[2] = (tran_low_t)fdct_round_shift(temp2);
  58. temp1 = step[2] * cospi_24_64 + step[3] * cospi_8_64;
  59. temp2 = -step[2] * cospi_8_64 + step[3] * cospi_24_64;
  60. out[1] = (tran_low_t)fdct_round_shift(temp1);
  61. out[3] = (tran_low_t)fdct_round_shift(temp2);
  62. // Do next column (which is a transposed row in second/horizontal pass)
  63. ++input;
  64. out += 4;
  65. }
  66. // Setup in/out for next pass.
  67. in_low = intermediate;
  68. out = output;
  69. }
  70. {
  71. int i, j;
  72. for (i = 0; i < 4; ++i) {
  73. for (j = 0; j < 4; ++j) output[j + i * 4] = (output[j + i * 4] + 1) >> 2;
  74. }
  75. }
  76. }
  77. void vpx_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride) {
  78. int r, c;
  79. tran_low_t sum = 0;
  80. for (r = 0; r < 4; ++r)
  81. for (c = 0; c < 4; ++c) sum += input[r * stride + c];
  82. output[0] = sum * 2;
  83. }
  84. void vpx_fdct8x8_c(const int16_t *input, tran_low_t *output, int stride) {
  85. int i, j;
  86. tran_low_t intermediate[64];
  87. int pass;
  88. tran_low_t *out = intermediate;
  89. const tran_low_t *in = NULL;
  90. // Transform columns
  91. for (pass = 0; pass < 2; ++pass) {
  92. tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
  93. tran_high_t t0, t1, t2, t3; // needs32
  94. tran_high_t x0, x1, x2, x3; // canbe16
  95. for (i = 0; i < 8; i++) {
  96. // stage 1
  97. if (pass == 0) {
  98. s0 = (input[0 * stride] + input[7 * stride]) * 4;
  99. s1 = (input[1 * stride] + input[6 * stride]) * 4;
  100. s2 = (input[2 * stride] + input[5 * stride]) * 4;
  101. s3 = (input[3 * stride] + input[4 * stride]) * 4;
  102. s4 = (input[3 * stride] - input[4 * stride]) * 4;
  103. s5 = (input[2 * stride] - input[5 * stride]) * 4;
  104. s6 = (input[1 * stride] - input[6 * stride]) * 4;
  105. s7 = (input[0 * stride] - input[7 * stride]) * 4;
  106. ++input;
  107. } else {
  108. s0 = in[0 * 8] + in[7 * 8];
  109. s1 = in[1 * 8] + in[6 * 8];
  110. s2 = in[2 * 8] + in[5 * 8];
  111. s3 = in[3 * 8] + in[4 * 8];
  112. s4 = in[3 * 8] - in[4 * 8];
  113. s5 = in[2 * 8] - in[5 * 8];
  114. s6 = in[1 * 8] - in[6 * 8];
  115. s7 = in[0 * 8] - in[7 * 8];
  116. ++in;
  117. }
  118. // fdct4(step, step);
  119. x0 = s0 + s3;
  120. x1 = s1 + s2;
  121. x2 = s1 - s2;
  122. x3 = s0 - s3;
  123. t0 = (x0 + x1) * cospi_16_64;
  124. t1 = (x0 - x1) * cospi_16_64;
  125. t2 = x2 * cospi_24_64 + x3 * cospi_8_64;
  126. t3 = -x2 * cospi_8_64 + x3 * cospi_24_64;
  127. out[0] = (tran_low_t)fdct_round_shift(t0);
  128. out[2] = (tran_low_t)fdct_round_shift(t2);
  129. out[4] = (tran_low_t)fdct_round_shift(t1);
  130. out[6] = (tran_low_t)fdct_round_shift(t3);
  131. // Stage 2
  132. t0 = (s6 - s5) * cospi_16_64;
  133. t1 = (s6 + s5) * cospi_16_64;
  134. t2 = fdct_round_shift(t0);
  135. t3 = fdct_round_shift(t1);
  136. // Stage 3
  137. x0 = s4 + t2;
  138. x1 = s4 - t2;
  139. x2 = s7 - t3;
  140. x3 = s7 + t3;
  141. // Stage 4
  142. t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
  143. t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
  144. t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
  145. t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
  146. out[1] = (tran_low_t)fdct_round_shift(t0);
  147. out[3] = (tran_low_t)fdct_round_shift(t2);
  148. out[5] = (tran_low_t)fdct_round_shift(t1);
  149. out[7] = (tran_low_t)fdct_round_shift(t3);
  150. out += 8;
  151. }
  152. in = intermediate;
  153. out = output;
  154. }
  155. // Rows
  156. for (i = 0; i < 8; ++i) {
  157. for (j = 0; j < 8; ++j) output[j + i * 8] /= 2;
  158. }
  159. }
  160. void vpx_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride) {
  161. int r, c;
  162. tran_low_t sum = 0;
  163. for (r = 0; r < 8; ++r)
  164. for (c = 0; c < 8; ++c) sum += input[r * stride + c];
  165. output[0] = sum;
  166. }
  167. void vpx_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride) {
  168. // The 2D transform is done with two passes which are actually pretty
  169. // similar. In the first one, we transform the columns and transpose
  170. // the results. In the second one, we transform the rows. To achieve that,
  171. // as the first pass results are transposed, we transpose the columns (that
  172. // is the transposed rows) and transpose the results (so that it goes back
  173. // in normal/row positions).
  174. int pass;
  175. // We need an intermediate buffer between passes.
  176. tran_low_t intermediate[256];
  177. const tran_low_t *in_low = NULL;
  178. tran_low_t *out = intermediate;
  179. // Do the two transform/transpose passes
  180. for (pass = 0; pass < 2; ++pass) {
  181. tran_high_t step1[8]; // canbe16
  182. tran_high_t step2[8]; // canbe16
  183. tran_high_t step3[8]; // canbe16
  184. tran_high_t in_high[8]; // canbe16
  185. tran_high_t temp1, temp2; // needs32
  186. int i;
  187. for (i = 0; i < 16; i++) {
  188. if (0 == pass) {
  189. // Calculate input for the first 8 results.
  190. in_high[0] = (input[0 * stride] + input[15 * stride]) * 4;
  191. in_high[1] = (input[1 * stride] + input[14 * stride]) * 4;
  192. in_high[2] = (input[2 * stride] + input[13 * stride]) * 4;
  193. in_high[3] = (input[3 * stride] + input[12 * stride]) * 4;
  194. in_high[4] = (input[4 * stride] + input[11 * stride]) * 4;
  195. in_high[5] = (input[5 * stride] + input[10 * stride]) * 4;
  196. in_high[6] = (input[6 * stride] + input[9 * stride]) * 4;
  197. in_high[7] = (input[7 * stride] + input[8 * stride]) * 4;
  198. // Calculate input for the next 8 results.
  199. step1[0] = (input[7 * stride] - input[8 * stride]) * 4;
  200. step1[1] = (input[6 * stride] - input[9 * stride]) * 4;
  201. step1[2] = (input[5 * stride] - input[10 * stride]) * 4;
  202. step1[3] = (input[4 * stride] - input[11 * stride]) * 4;
  203. step1[4] = (input[3 * stride] - input[12 * stride]) * 4;
  204. step1[5] = (input[2 * stride] - input[13 * stride]) * 4;
  205. step1[6] = (input[1 * stride] - input[14 * stride]) * 4;
  206. step1[7] = (input[0 * stride] - input[15 * stride]) * 4;
  207. } else {
  208. // Calculate input for the first 8 results.
  209. assert(in_low != NULL);
  210. in_high[0] = ((in_low[0 * 16] + 1) >> 2) + ((in_low[15 * 16] + 1) >> 2);
  211. in_high[1] = ((in_low[1 * 16] + 1) >> 2) + ((in_low[14 * 16] + 1) >> 2);
  212. in_high[2] = ((in_low[2 * 16] + 1) >> 2) + ((in_low[13 * 16] + 1) >> 2);
  213. in_high[3] = ((in_low[3 * 16] + 1) >> 2) + ((in_low[12 * 16] + 1) >> 2);
  214. in_high[4] = ((in_low[4 * 16] + 1) >> 2) + ((in_low[11 * 16] + 1) >> 2);
  215. in_high[5] = ((in_low[5 * 16] + 1) >> 2) + ((in_low[10 * 16] + 1) >> 2);
  216. in_high[6] = ((in_low[6 * 16] + 1) >> 2) + ((in_low[9 * 16] + 1) >> 2);
  217. in_high[7] = ((in_low[7 * 16] + 1) >> 2) + ((in_low[8 * 16] + 1) >> 2);
  218. // Calculate input for the next 8 results.
  219. step1[0] = ((in_low[7 * 16] + 1) >> 2) - ((in_low[8 * 16] + 1) >> 2);
  220. step1[1] = ((in_low[6 * 16] + 1) >> 2) - ((in_low[9 * 16] + 1) >> 2);
  221. step1[2] = ((in_low[5 * 16] + 1) >> 2) - ((in_low[10 * 16] + 1) >> 2);
  222. step1[3] = ((in_low[4 * 16] + 1) >> 2) - ((in_low[11 * 16] + 1) >> 2);
  223. step1[4] = ((in_low[3 * 16] + 1) >> 2) - ((in_low[12 * 16] + 1) >> 2);
  224. step1[5] = ((in_low[2 * 16] + 1) >> 2) - ((in_low[13 * 16] + 1) >> 2);
  225. step1[6] = ((in_low[1 * 16] + 1) >> 2) - ((in_low[14 * 16] + 1) >> 2);
  226. step1[7] = ((in_low[0 * 16] + 1) >> 2) - ((in_low[15 * 16] + 1) >> 2);
  227. in_low++;
  228. }
  229. // Work on the first eight values; fdct8(input, even_results);
  230. {
  231. tran_high_t s0, s1, s2, s3, s4, s5, s6, s7; // canbe16
  232. tran_high_t t0, t1, t2, t3; // needs32
  233. tran_high_t x0, x1, x2, x3; // canbe16
  234. // stage 1
  235. s0 = in_high[0] + in_high[7];
  236. s1 = in_high[1] + in_high[6];
  237. s2 = in_high[2] + in_high[5];
  238. s3 = in_high[3] + in_high[4];
  239. s4 = in_high[3] - in_high[4];
  240. s5 = in_high[2] - in_high[5];
  241. s6 = in_high[1] - in_high[6];
  242. s7 = in_high[0] - in_high[7];
  243. // fdct4(step, step);
  244. x0 = s0 + s3;
  245. x1 = s1 + s2;
  246. x2 = s1 - s2;
  247. x3 = s0 - s3;
  248. t0 = (x0 + x1) * cospi_16_64;
  249. t1 = (x0 - x1) * cospi_16_64;
  250. t2 = x3 * cospi_8_64 + x2 * cospi_24_64;
  251. t3 = x3 * cospi_24_64 - x2 * cospi_8_64;
  252. out[0] = (tran_low_t)fdct_round_shift(t0);
  253. out[4] = (tran_low_t)fdct_round_shift(t2);
  254. out[8] = (tran_low_t)fdct_round_shift(t1);
  255. out[12] = (tran_low_t)fdct_round_shift(t3);
  256. // Stage 2
  257. t0 = (s6 - s5) * cospi_16_64;
  258. t1 = (s6 + s5) * cospi_16_64;
  259. t2 = fdct_round_shift(t0);
  260. t3 = fdct_round_shift(t1);
  261. // Stage 3
  262. x0 = s4 + t2;
  263. x1 = s4 - t2;
  264. x2 = s7 - t3;
  265. x3 = s7 + t3;
  266. // Stage 4
  267. t0 = x0 * cospi_28_64 + x3 * cospi_4_64;
  268. t1 = x1 * cospi_12_64 + x2 * cospi_20_64;
  269. t2 = x2 * cospi_12_64 + x1 * -cospi_20_64;
  270. t3 = x3 * cospi_28_64 + x0 * -cospi_4_64;
  271. out[2] = (tran_low_t)fdct_round_shift(t0);
  272. out[6] = (tran_low_t)fdct_round_shift(t2);
  273. out[10] = (tran_low_t)fdct_round_shift(t1);
  274. out[14] = (tran_low_t)fdct_round_shift(t3);
  275. }
  276. // Work on the next eight values; step1 -> odd_results
  277. {
  278. // step 2
  279. temp1 = (step1[5] - step1[2]) * cospi_16_64;
  280. temp2 = (step1[4] - step1[3]) * cospi_16_64;
  281. step2[2] = fdct_round_shift(temp1);
  282. step2[3] = fdct_round_shift(temp2);
  283. temp1 = (step1[4] + step1[3]) * cospi_16_64;
  284. temp2 = (step1[5] + step1[2]) * cospi_16_64;
  285. step2[4] = fdct_round_shift(temp1);
  286. step2[5] = fdct_round_shift(temp2);
  287. // step 3
  288. step3[0] = step1[0] + step2[3];
  289. step3[1] = step1[1] + step2[2];
  290. step3[2] = step1[1] - step2[2];
  291. step3[3] = step1[0] - step2[3];
  292. step3[4] = step1[7] - step2[4];
  293. step3[5] = step1[6] - step2[5];
  294. step3[6] = step1[6] + step2[5];
  295. step3[7] = step1[7] + step2[4];
  296. // step 4
  297. temp1 = step3[1] * -cospi_8_64 + step3[6] * cospi_24_64;
  298. temp2 = step3[2] * cospi_24_64 + step3[5] * cospi_8_64;
  299. step2[1] = fdct_round_shift(temp1);
  300. step2[2] = fdct_round_shift(temp2);
  301. temp1 = step3[2] * cospi_8_64 - step3[5] * cospi_24_64;
  302. temp2 = step3[1] * cospi_24_64 + step3[6] * cospi_8_64;
  303. step2[5] = fdct_round_shift(temp1);
  304. step2[6] = fdct_round_shift(temp2);
  305. // step 5
  306. step1[0] = step3[0] + step2[1];
  307. step1[1] = step3[0] - step2[1];
  308. step1[2] = step3[3] + step2[2];
  309. step1[3] = step3[3] - step2[2];
  310. step1[4] = step3[4] - step2[5];
  311. step1[5] = step3[4] + step2[5];
  312. step1[6] = step3[7] - step2[6];
  313. step1[7] = step3[7] + step2[6];
  314. // step 6
  315. temp1 = step1[0] * cospi_30_64 + step1[7] * cospi_2_64;
  316. temp2 = step1[1] * cospi_14_64 + step1[6] * cospi_18_64;
  317. out[1] = (tran_low_t)fdct_round_shift(temp1);
  318. out[9] = (tran_low_t)fdct_round_shift(temp2);
  319. temp1 = step1[2] * cospi_22_64 + step1[5] * cospi_10_64;
  320. temp2 = step1[3] * cospi_6_64 + step1[4] * cospi_26_64;
  321. out[5] = (tran_low_t)fdct_round_shift(temp1);
  322. out[13] = (tran_low_t)fdct_round_shift(temp2);
  323. temp1 = step1[3] * -cospi_26_64 + step1[4] * cospi_6_64;
  324. temp2 = step1[2] * -cospi_10_64 + step1[5] * cospi_22_64;
  325. out[3] = (tran_low_t)fdct_round_shift(temp1);
  326. out[11] = (tran_low_t)fdct_round_shift(temp2);
  327. temp1 = step1[1] * -cospi_18_64 + step1[6] * cospi_14_64;
  328. temp2 = step1[0] * -cospi_2_64 + step1[7] * cospi_30_64;
  329. out[7] = (tran_low_t)fdct_round_shift(temp1);
  330. out[15] = (tran_low_t)fdct_round_shift(temp2);
  331. }
  332. // Do next column (which is a transposed row in second/horizontal pass)
  333. input++;
  334. out += 16;
  335. }
  336. // Setup in/out for next pass.
  337. in_low = intermediate;
  338. out = output;
  339. }
  340. }
  341. void vpx_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride) {
  342. int r, c;
  343. int sum = 0;
  344. for (r = 0; r < 16; ++r)
  345. for (c = 0; c < 16; ++c) sum += input[r * stride + c];
  346. output[0] = (tran_low_t)(sum >> 1);
  347. }
  348. static INLINE tran_high_t dct_32_round(tran_high_t input) {
  349. tran_high_t rv = ROUND_POWER_OF_TWO(input, DCT_CONST_BITS);
  350. // TODO(debargha, peter.derivaz): Find new bounds for this assert,
  351. // and make the bounds consts.
  352. // assert(-131072 <= rv && rv <= 131071);
  353. return rv;
  354. }
  355. static INLINE tran_high_t half_round_shift(tran_high_t input) {
  356. tran_high_t rv = (input + 1 + (input < 0)) >> 2;
  357. return rv;
  358. }
  359. void vpx_fdct32(const tran_high_t *input, tran_high_t *output, int round) {
  360. tran_high_t step[32];
  361. // Stage 1
  362. step[0] = input[0] + input[(32 - 1)];
  363. step[1] = input[1] + input[(32 - 2)];
  364. step[2] = input[2] + input[(32 - 3)];
  365. step[3] = input[3] + input[(32 - 4)];
  366. step[4] = input[4] + input[(32 - 5)];
  367. step[5] = input[5] + input[(32 - 6)];
  368. step[6] = input[6] + input[(32 - 7)];
  369. step[7] = input[7] + input[(32 - 8)];
  370. step[8] = input[8] + input[(32 - 9)];
  371. step[9] = input[9] + input[(32 - 10)];
  372. step[10] = input[10] + input[(32 - 11)];
  373. step[11] = input[11] + input[(32 - 12)];
  374. step[12] = input[12] + input[(32 - 13)];
  375. step[13] = input[13] + input[(32 - 14)];
  376. step[14] = input[14] + input[(32 - 15)];
  377. step[15] = input[15] + input[(32 - 16)];
  378. step[16] = -input[16] + input[(32 - 17)];
  379. step[17] = -input[17] + input[(32 - 18)];
  380. step[18] = -input[18] + input[(32 - 19)];
  381. step[19] = -input[19] + input[(32 - 20)];
  382. step[20] = -input[20] + input[(32 - 21)];
  383. step[21] = -input[21] + input[(32 - 22)];
  384. step[22] = -input[22] + input[(32 - 23)];
  385. step[23] = -input[23] + input[(32 - 24)];
  386. step[24] = -input[24] + input[(32 - 25)];
  387. step[25] = -input[25] + input[(32 - 26)];
  388. step[26] = -input[26] + input[(32 - 27)];
  389. step[27] = -input[27] + input[(32 - 28)];
  390. step[28] = -input[28] + input[(32 - 29)];
  391. step[29] = -input[29] + input[(32 - 30)];
  392. step[30] = -input[30] + input[(32 - 31)];
  393. step[31] = -input[31] + input[(32 - 32)];
  394. // Stage 2
  395. output[0] = step[0] + step[16 - 1];
  396. output[1] = step[1] + step[16 - 2];
  397. output[2] = step[2] + step[16 - 3];
  398. output[3] = step[3] + step[16 - 4];
  399. output[4] = step[4] + step[16 - 5];
  400. output[5] = step[5] + step[16 - 6];
  401. output[6] = step[6] + step[16 - 7];
  402. output[7] = step[7] + step[16 - 8];
  403. output[8] = -step[8] + step[16 - 9];
  404. output[9] = -step[9] + step[16 - 10];
  405. output[10] = -step[10] + step[16 - 11];
  406. output[11] = -step[11] + step[16 - 12];
  407. output[12] = -step[12] + step[16 - 13];
  408. output[13] = -step[13] + step[16 - 14];
  409. output[14] = -step[14] + step[16 - 15];
  410. output[15] = -step[15] + step[16 - 16];
  411. output[16] = step[16];
  412. output[17] = step[17];
  413. output[18] = step[18];
  414. output[19] = step[19];
  415. output[20] = dct_32_round((-step[20] + step[27]) * cospi_16_64);
  416. output[21] = dct_32_round((-step[21] + step[26]) * cospi_16_64);
  417. output[22] = dct_32_round((-step[22] + step[25]) * cospi_16_64);
  418. output[23] = dct_32_round((-step[23] + step[24]) * cospi_16_64);
  419. output[24] = dct_32_round((step[24] + step[23]) * cospi_16_64);
  420. output[25] = dct_32_round((step[25] + step[22]) * cospi_16_64);
  421. output[26] = dct_32_round((step[26] + step[21]) * cospi_16_64);
  422. output[27] = dct_32_round((step[27] + step[20]) * cospi_16_64);
  423. output[28] = step[28];
  424. output[29] = step[29];
  425. output[30] = step[30];
  426. output[31] = step[31];
  427. // dump the magnitude by 4, hence the intermediate values are within
  428. // the range of 16 bits.
  429. if (round) {
  430. output[0] = half_round_shift(output[0]);
  431. output[1] = half_round_shift(output[1]);
  432. output[2] = half_round_shift(output[2]);
  433. output[3] = half_round_shift(output[3]);
  434. output[4] = half_round_shift(output[4]);
  435. output[5] = half_round_shift(output[5]);
  436. output[6] = half_round_shift(output[6]);
  437. output[7] = half_round_shift(output[7]);
  438. output[8] = half_round_shift(output[8]);
  439. output[9] = half_round_shift(output[9]);
  440. output[10] = half_round_shift(output[10]);
  441. output[11] = half_round_shift(output[11]);
  442. output[12] = half_round_shift(output[12]);
  443. output[13] = half_round_shift(output[13]);
  444. output[14] = half_round_shift(output[14]);
  445. output[15] = half_round_shift(output[15]);
  446. output[16] = half_round_shift(output[16]);
  447. output[17] = half_round_shift(output[17]);
  448. output[18] = half_round_shift(output[18]);
  449. output[19] = half_round_shift(output[19]);
  450. output[20] = half_round_shift(output[20]);
  451. output[21] = half_round_shift(output[21]);
  452. output[22] = half_round_shift(output[22]);
  453. output[23] = half_round_shift(output[23]);
  454. output[24] = half_round_shift(output[24]);
  455. output[25] = half_round_shift(output[25]);
  456. output[26] = half_round_shift(output[26]);
  457. output[27] = half_round_shift(output[27]);
  458. output[28] = half_round_shift(output[28]);
  459. output[29] = half_round_shift(output[29]);
  460. output[30] = half_round_shift(output[30]);
  461. output[31] = half_round_shift(output[31]);
  462. }
  463. // Stage 3
  464. step[0] = output[0] + output[(8 - 1)];
  465. step[1] = output[1] + output[(8 - 2)];
  466. step[2] = output[2] + output[(8 - 3)];
  467. step[3] = output[3] + output[(8 - 4)];
  468. step[4] = -output[4] + output[(8 - 5)];
  469. step[5] = -output[5] + output[(8 - 6)];
  470. step[6] = -output[6] + output[(8 - 7)];
  471. step[7] = -output[7] + output[(8 - 8)];
  472. step[8] = output[8];
  473. step[9] = output[9];
  474. step[10] = dct_32_round((-output[10] + output[13]) * cospi_16_64);
  475. step[11] = dct_32_round((-output[11] + output[12]) * cospi_16_64);
  476. step[12] = dct_32_round((output[12] + output[11]) * cospi_16_64);
  477. step[13] = dct_32_round((output[13] + output[10]) * cospi_16_64);
  478. step[14] = output[14];
  479. step[15] = output[15];
  480. step[16] = output[16] + output[23];
  481. step[17] = output[17] + output[22];
  482. step[18] = output[18] + output[21];
  483. step[19] = output[19] + output[20];
  484. step[20] = -output[20] + output[19];
  485. step[21] = -output[21] + output[18];
  486. step[22] = -output[22] + output[17];
  487. step[23] = -output[23] + output[16];
  488. step[24] = -output[24] + output[31];
  489. step[25] = -output[25] + output[30];
  490. step[26] = -output[26] + output[29];
  491. step[27] = -output[27] + output[28];
  492. step[28] = output[28] + output[27];
  493. step[29] = output[29] + output[26];
  494. step[30] = output[30] + output[25];
  495. step[31] = output[31] + output[24];
  496. // Stage 4
  497. output[0] = step[0] + step[3];
  498. output[1] = step[1] + step[2];
  499. output[2] = -step[2] + step[1];
  500. output[3] = -step[3] + step[0];
  501. output[4] = step[4];
  502. output[5] = dct_32_round((-step[5] + step[6]) * cospi_16_64);
  503. output[6] = dct_32_round((step[6] + step[5]) * cospi_16_64);
  504. output[7] = step[7];
  505. output[8] = step[8] + step[11];
  506. output[9] = step[9] + step[10];
  507. output[10] = -step[10] + step[9];
  508. output[11] = -step[11] + step[8];
  509. output[12] = -step[12] + step[15];
  510. output[13] = -step[13] + step[14];
  511. output[14] = step[14] + step[13];
  512. output[15] = step[15] + step[12];
  513. output[16] = step[16];
  514. output[17] = step[17];
  515. output[18] = dct_32_round(step[18] * -cospi_8_64 + step[29] * cospi_24_64);
  516. output[19] = dct_32_round(step[19] * -cospi_8_64 + step[28] * cospi_24_64);
  517. output[20] = dct_32_round(step[20] * -cospi_24_64 + step[27] * -cospi_8_64);
  518. output[21] = dct_32_round(step[21] * -cospi_24_64 + step[26] * -cospi_8_64);
  519. output[22] = step[22];
  520. output[23] = step[23];
  521. output[24] = step[24];
  522. output[25] = step[25];
  523. output[26] = dct_32_round(step[26] * cospi_24_64 + step[21] * -cospi_8_64);
  524. output[27] = dct_32_round(step[27] * cospi_24_64 + step[20] * -cospi_8_64);
  525. output[28] = dct_32_round(step[28] * cospi_8_64 + step[19] * cospi_24_64);
  526. output[29] = dct_32_round(step[29] * cospi_8_64 + step[18] * cospi_24_64);
  527. output[30] = step[30];
  528. output[31] = step[31];
  529. // Stage 5
  530. step[0] = dct_32_round((output[0] + output[1]) * cospi_16_64);
  531. step[1] = dct_32_round((-output[1] + output[0]) * cospi_16_64);
  532. step[2] = dct_32_round(output[2] * cospi_24_64 + output[3] * cospi_8_64);
  533. step[3] = dct_32_round(output[3] * cospi_24_64 - output[2] * cospi_8_64);
  534. step[4] = output[4] + output[5];
  535. step[5] = -output[5] + output[4];
  536. step[6] = -output[6] + output[7];
  537. step[7] = output[7] + output[6];
  538. step[8] = output[8];
  539. step[9] = dct_32_round(output[9] * -cospi_8_64 + output[14] * cospi_24_64);
  540. step[10] = dct_32_round(output[10] * -cospi_24_64 + output[13] * -cospi_8_64);
  541. step[11] = output[11];
  542. step[12] = output[12];
  543. step[13] = dct_32_round(output[13] * cospi_24_64 + output[10] * -cospi_8_64);
  544. step[14] = dct_32_round(output[14] * cospi_8_64 + output[9] * cospi_24_64);
  545. step[15] = output[15];
  546. step[16] = output[16] + output[19];
  547. step[17] = output[17] + output[18];
  548. step[18] = -output[18] + output[17];
  549. step[19] = -output[19] + output[16];
  550. step[20] = -output[20] + output[23];
  551. step[21] = -output[21] + output[22];
  552. step[22] = output[22] + output[21];
  553. step[23] = output[23] + output[20];
  554. step[24] = output[24] + output[27];
  555. step[25] = output[25] + output[26];
  556. step[26] = -output[26] + output[25];
  557. step[27] = -output[27] + output[24];
  558. step[28] = -output[28] + output[31];
  559. step[29] = -output[29] + output[30];
  560. step[30] = output[30] + output[29];
  561. step[31] = output[31] + output[28];
  562. // Stage 6
  563. output[0] = step[0];
  564. output[1] = step[1];
  565. output[2] = step[2];
  566. output[3] = step[3];
  567. output[4] = dct_32_round(step[4] * cospi_28_64 + step[7] * cospi_4_64);
  568. output[5] = dct_32_round(step[5] * cospi_12_64 + step[6] * cospi_20_64);
  569. output[6] = dct_32_round(step[6] * cospi_12_64 + step[5] * -cospi_20_64);
  570. output[7] = dct_32_round(step[7] * cospi_28_64 + step[4] * -cospi_4_64);
  571. output[8] = step[8] + step[9];
  572. output[9] = -step[9] + step[8];
  573. output[10] = -step[10] + step[11];
  574. output[11] = step[11] + step[10];
  575. output[12] = step[12] + step[13];
  576. output[13] = -step[13] + step[12];
  577. output[14] = -step[14] + step[15];
  578. output[15] = step[15] + step[14];
  579. output[16] = step[16];
  580. output[17] = dct_32_round(step[17] * -cospi_4_64 + step[30] * cospi_28_64);
  581. output[18] = dct_32_round(step[18] * -cospi_28_64 + step[29] * -cospi_4_64);
  582. output[19] = step[19];
  583. output[20] = step[20];
  584. output[21] = dct_32_round(step[21] * -cospi_20_64 + step[26] * cospi_12_64);
  585. output[22] = dct_32_round(step[22] * -cospi_12_64 + step[25] * -cospi_20_64);
  586. output[23] = step[23];
  587. output[24] = step[24];
  588. output[25] = dct_32_round(step[25] * cospi_12_64 + step[22] * -cospi_20_64);
  589. output[26] = dct_32_round(step[26] * cospi_20_64 + step[21] * cospi_12_64);
  590. output[27] = step[27];
  591. output[28] = step[28];
  592. output[29] = dct_32_round(step[29] * cospi_28_64 + step[18] * -cospi_4_64);
  593. output[30] = dct_32_round(step[30] * cospi_4_64 + step[17] * cospi_28_64);
  594. output[31] = step[31];
  595. // Stage 7
  596. step[0] = output[0];
  597. step[1] = output[1];
  598. step[2] = output[2];
  599. step[3] = output[3];
  600. step[4] = output[4];
  601. step[5] = output[5];
  602. step[6] = output[6];
  603. step[7] = output[7];
  604. step[8] = dct_32_round(output[8] * cospi_30_64 + output[15] * cospi_2_64);
  605. step[9] = dct_32_round(output[9] * cospi_14_64 + output[14] * cospi_18_64);
  606. step[10] = dct_32_round(output[10] * cospi_22_64 + output[13] * cospi_10_64);
  607. step[11] = dct_32_round(output[11] * cospi_6_64 + output[12] * cospi_26_64);
  608. step[12] = dct_32_round(output[12] * cospi_6_64 + output[11] * -cospi_26_64);
  609. step[13] = dct_32_round(output[13] * cospi_22_64 + output[10] * -cospi_10_64);
  610. step[14] = dct_32_round(output[14] * cospi_14_64 + output[9] * -cospi_18_64);
  611. step[15] = dct_32_round(output[15] * cospi_30_64 + output[8] * -cospi_2_64);
  612. step[16] = output[16] + output[17];
  613. step[17] = -output[17] + output[16];
  614. step[18] = -output[18] + output[19];
  615. step[19] = output[19] + output[18];
  616. step[20] = output[20] + output[21];
  617. step[21] = -output[21] + output[20];
  618. step[22] = -output[22] + output[23];
  619. step[23] = output[23] + output[22];
  620. step[24] = output[24] + output[25];
  621. step[25] = -output[25] + output[24];
  622. step[26] = -output[26] + output[27];
  623. step[27] = output[27] + output[26];
  624. step[28] = output[28] + output[29];
  625. step[29] = -output[29] + output[28];
  626. step[30] = -output[30] + output[31];
  627. step[31] = output[31] + output[30];
  628. // Final stage --- outputs indices are bit-reversed.
  629. output[0] = step[0];
  630. output[16] = step[1];
  631. output[8] = step[2];
  632. output[24] = step[3];
  633. output[4] = step[4];
  634. output[20] = step[5];
  635. output[12] = step[6];
  636. output[28] = step[7];
  637. output[2] = step[8];
  638. output[18] = step[9];
  639. output[10] = step[10];
  640. output[26] = step[11];
  641. output[6] = step[12];
  642. output[22] = step[13];
  643. output[14] = step[14];
  644. output[30] = step[15];
  645. output[1] = dct_32_round(step[16] * cospi_31_64 + step[31] * cospi_1_64);
  646. output[17] = dct_32_round(step[17] * cospi_15_64 + step[30] * cospi_17_64);
  647. output[9] = dct_32_round(step[18] * cospi_23_64 + step[29] * cospi_9_64);
  648. output[25] = dct_32_round(step[19] * cospi_7_64 + step[28] * cospi_25_64);
  649. output[5] = dct_32_round(step[20] * cospi_27_64 + step[27] * cospi_5_64);
  650. output[21] = dct_32_round(step[21] * cospi_11_64 + step[26] * cospi_21_64);
  651. output[13] = dct_32_round(step[22] * cospi_19_64 + step[25] * cospi_13_64);
  652. output[29] = dct_32_round(step[23] * cospi_3_64 + step[24] * cospi_29_64);
  653. output[3] = dct_32_round(step[24] * cospi_3_64 + step[23] * -cospi_29_64);
  654. output[19] = dct_32_round(step[25] * cospi_19_64 + step[22] * -cospi_13_64);
  655. output[11] = dct_32_round(step[26] * cospi_11_64 + step[21] * -cospi_21_64);
  656. output[27] = dct_32_round(step[27] * cospi_27_64 + step[20] * -cospi_5_64);
  657. output[7] = dct_32_round(step[28] * cospi_7_64 + step[19] * -cospi_25_64);
  658. output[23] = dct_32_round(step[29] * cospi_23_64 + step[18] * -cospi_9_64);
  659. output[15] = dct_32_round(step[30] * cospi_15_64 + step[17] * -cospi_17_64);
  660. output[31] = dct_32_round(step[31] * cospi_31_64 + step[16] * -cospi_1_64);
  661. }
  662. void vpx_fdct32x32_c(const int16_t *input, tran_low_t *output, int stride) {
  663. int i, j;
  664. tran_high_t out[32 * 32];
  665. // Columns
  666. for (i = 0; i < 32; ++i) {
  667. tran_high_t temp_in[32], temp_out[32];
  668. for (j = 0; j < 32; ++j) temp_in[j] = input[j * stride + i] * 4;
  669. vpx_fdct32(temp_in, temp_out, 0);
  670. for (j = 0; j < 32; ++j)
  671. out[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2;
  672. }
  673. // Rows
  674. for (i = 0; i < 32; ++i) {
  675. tran_high_t temp_in[32], temp_out[32];
  676. for (j = 0; j < 32; ++j) temp_in[j] = out[j + i * 32];
  677. vpx_fdct32(temp_in, temp_out, 0);
  678. for (j = 0; j < 32; ++j)
  679. output[j + i * 32] =
  680. (tran_low_t)((temp_out[j] + 1 + (temp_out[j] < 0)) >> 2);
  681. }
  682. }
  683. // Note that although we use dct_32_round in dct32 computation flow,
  684. // this 2d fdct32x32 for rate-distortion optimization loop is operating
  685. // within 16 bits precision.
  686. void vpx_fdct32x32_rd_c(const int16_t *input, tran_low_t *output, int stride) {
  687. int i, j;
  688. tran_high_t out[32 * 32];
  689. // Columns
  690. for (i = 0; i < 32; ++i) {
  691. tran_high_t temp_in[32], temp_out[32];
  692. for (j = 0; j < 32; ++j) temp_in[j] = input[j * stride + i] * 4;
  693. vpx_fdct32(temp_in, temp_out, 0);
  694. for (j = 0; j < 32; ++j)
  695. // TODO(cd): see quality impact of only doing
  696. // output[j * 32 + i] = (temp_out[j] + 1) >> 2;
  697. // PS: also change code in vpx_dsp/x86/vpx_dct_sse2.c
  698. out[j * 32 + i] = (temp_out[j] + 1 + (temp_out[j] > 0)) >> 2;
  699. }
  700. // Rows
  701. for (i = 0; i < 32; ++i) {
  702. tran_high_t temp_in[32], temp_out[32];
  703. for (j = 0; j < 32; ++j) temp_in[j] = out[j + i * 32];
  704. vpx_fdct32(temp_in, temp_out, 1);
  705. for (j = 0; j < 32; ++j) output[j + i * 32] = (tran_low_t)temp_out[j];
  706. }
  707. }
  708. void vpx_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride) {
  709. int r, c;
  710. int sum = 0;
  711. for (r = 0; r < 32; ++r)
  712. for (c = 0; c < 32; ++c) sum += input[r * stride + c];
  713. output[0] = (tran_low_t)(sum >> 3);
  714. }
  715. #if CONFIG_VP9_HIGHBITDEPTH
  716. void vpx_highbd_fdct4x4_c(const int16_t *input, tran_low_t *output,
  717. int stride) {
  718. vpx_fdct4x4_c(input, output, stride);
  719. }
  720. void vpx_highbd_fdct8x8_c(const int16_t *input, tran_low_t *output,
  721. int stride) {
  722. vpx_fdct8x8_c(input, output, stride);
  723. }
  724. void vpx_highbd_fdct8x8_1_c(const int16_t *input, tran_low_t *output,
  725. int stride) {
  726. vpx_fdct8x8_1_c(input, output, stride);
  727. }
  728. void vpx_highbd_fdct16x16_c(const int16_t *input, tran_low_t *output,
  729. int stride) {
  730. vpx_fdct16x16_c(input, output, stride);
  731. }
  732. void vpx_highbd_fdct16x16_1_c(const int16_t *input, tran_low_t *output,
  733. int stride) {
  734. vpx_fdct16x16_1_c(input, output, stride);
  735. }
  736. void vpx_highbd_fdct32x32_c(const int16_t *input, tran_low_t *output,
  737. int stride) {
  738. vpx_fdct32x32_c(input, output, stride);
  739. }
  740. void vpx_highbd_fdct32x32_rd_c(const int16_t *input, tran_low_t *output,
  741. int stride) {
  742. vpx_fdct32x32_rd_c(input, output, stride);
  743. }
  744. void vpx_highbd_fdct32x32_1_c(const int16_t *input, tran_low_t *output,
  745. int stride) {
  746. vpx_fdct32x32_1_c(input, output, stride);
  747. }
  748. #endif // CONFIG_VP9_HIGHBITDEPTH