Commit initial reference implementation of IDCT.
[fjl] / idct.c
1 #include <math.h>
2
3 #include "idct.h"
4
5 void idct_reference(const int16_t* input, const uint32_t* quant_table, uint8_t* output)
6 {
7         double temp[DCTSIZE2];
8
9         for (unsigned y = 0; y < 8; ++y) {
10                 for (unsigned x = 0; x < 8; ++x) {
11                         double acc = 0.0;
12                         for (unsigned u = 0; u < 8; ++u) {
13                                 for (unsigned v = 0; v < 8; ++v) {
14                                         double c_u = (u == 0) ? 1/sqrt(2.0) : 1.0;
15                                         double c_v = (v == 0) ? 1/sqrt(2.0) : 1.0;
16                                         acc += c_u * c_v
17                                                 * input[u * DCTSIZE + v] * quant_table[u * DCTSIZE + v]
18                                                 * cos((2 * x + 1) * v * M_PI / 16.0)
19                                                 * cos((2 * y + 1) * u * M_PI / 16.0);
20                                 }
21                         }
22                         temp[y * DCTSIZE + x] = 0.25 * acc;
23                 }
24         }
25
26         for (unsigned y = 0; y < 8; ++y) {
27                 for (unsigned x = 0; x < 8; ++x) {
28                         double val = temp[y * DCTSIZE + x];
29                         if (val < 0.0) {
30                                 output[y * DCTSIZE + x] = 0;
31                         } else if (val >= 255.0) {
32                                 output[y * DCTSIZE + x] = 255;
33                         } else {
34                                 output[y * DCTSIZE + x] = (uint8_t)(val + 0.5);
35                         }
36                 }
37         }
38 }
39