]> git.sesse.net Git - fjl/blob - idct_reference.c
Add an x86 optimized version of extend().
[fjl] / idct_reference.c
1 #include <math.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #include "idct_reference.h"
6
7 void* idct_reference_alloc(const uint32_t* quant_table)
8 {
9         uint32_t* qt_copy = (uint32_t*)malloc(DCTSIZE2 * sizeof(uint32_t));
10         // FIXME: check for NULL return
11
12         memcpy(qt_copy, quant_table, DCTSIZE2 * sizeof(uint32_t));
13
14         return qt_copy;
15 }
16
17 void idct_reference_free(void* userdata)
18 {
19         free(userdata);
20 }
21
22 void idct_reference(const int16_t* input, const void* userdata, uint8_t* output)
23 {
24         const uint32_t* quant_table = (const uint32_t*)userdata;
25         double temp[DCTSIZE2];
26
27         for (unsigned y = 0; y < 8; ++y) {
28                 for (unsigned x = 0; x < 8; ++x) {
29                         double acc = 0.0;
30                         for (unsigned u = 0; u < 8; ++u) {
31                                 for (unsigned v = 0; v < 8; ++v) {
32                                         double c_u = (u == 0) ? 1/sqrt(2.0) : 1.0;
33                                         double c_v = (v == 0) ? 1/sqrt(2.0) : 1.0;
34                                         acc += c_u * c_v
35                                                 * input[u * DCTSIZE + v] * quant_table[u * DCTSIZE + v]
36                                                 * cos((2 * x + 1) * v * M_PI / 16.0)
37                                                 * cos((2 * y + 1) * u * M_PI / 16.0);
38                                 }
39                         }
40                         temp[y * DCTSIZE + x] = 0.25 * acc;
41                 }
42         }
43
44         for (unsigned y = 0; y < 8; ++y) {
45                 for (unsigned x = 0; x < 8; ++x) {
46                         double val = temp[y * DCTSIZE + x] + 128.0;
47                         if (val < 0.0) {
48                                 output[y * DCTSIZE + x] = 0;
49                         } else if (val >= 255.0) {
50                                 output[y * DCTSIZE + x] = 255;
51                         } else {
52                                 output[y * DCTSIZE + x] = (uint8_t)(val + 0.5);
53                         }
54                 }
55         }
56 }