]> git.sesse.net Git - fjl/blobdiff - idct_reference.c
Split the two IDCTs into different files.
[fjl] / idct_reference.c
diff --git a/idct_reference.c b/idct_reference.c
new file mode 100644 (file)
index 0000000..e710de3
--- /dev/null
@@ -0,0 +1,56 @@
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "idct_reference.h"
+
+void* idct_reference_alloc(const uint32_t* quant_table)
+{
+       uint32_t* qt_copy = (uint32_t*)malloc(DCTSIZE2 * sizeof(uint32_t));
+       // FIXME: check for NULL return
+
+       memcpy(qt_copy, quant_table, DCTSIZE2 * sizeof(uint32_t));
+
+       return qt_copy;
+}
+
+void idct_reference_free(void* userdata)
+{
+       free(userdata);
+}
+
+void idct_reference(const int16_t* input, const void* userdata, uint8_t* output)
+{
+       const uint32_t* quant_table = (const uint32_t*)userdata;
+       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);
+                       }
+               }
+       }
+}