]> git.sesse.net Git - fjl/blobdiff - idct.c
Commit initial reference implementation of IDCT.
[fjl] / idct.c
diff --git a/idct.c b/idct.c
new file mode 100644 (file)
index 0000000..54a9dc9
--- /dev/null
+++ b/idct.c
@@ -0,0 +1,39 @@
+#include <math.h>
+
+#include "idct.h"
+
+void idct_reference(const int16_t* input, const uint32_t* quant_table, uint8_t* output)
+{
+       double temp[DCTSIZE2];
+
+       for (unsigned y = 0; y < 8; ++y) {
+               for (unsigned x = 0; x < 8; ++x) {
+                       double acc = 0.0;
+                       for (unsigned u = 0; u < 8; ++u) {
+                               for (unsigned v = 0; v < 8; ++v) {
+                                       double c_u = (u == 0) ? 1/sqrt(2.0) : 1.0;
+                                       double c_v = (v == 0) ? 1/sqrt(2.0) : 1.0;
+                                       acc += c_u * c_v
+                                               * input[u * DCTSIZE + v] * quant_table[u * DCTSIZE + v]
+                                               * cos((2 * x + 1) * v * M_PI / 16.0)
+                                               * cos((2 * y + 1) * u * M_PI / 16.0);
+                               }
+                       }
+                       temp[y * DCTSIZE + x] = 0.25 * acc;
+               }
+       }
+
+       for (unsigned y = 0; y < 8; ++y) {
+               for (unsigned x = 0; x < 8; ++x) {
+                       double val = temp[y * DCTSIZE + x];
+                       if (val < 0.0) {
+                               output[y * DCTSIZE + x] = 0;
+                       } else if (val >= 255.0) {
+                               output[y * DCTSIZE + x] = 255;
+                       } else {
+                               output[y * DCTSIZE + x] = (uint8_t)(val + 0.5);
+                       }
+               }
+       }
+}
+