1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
let pi = 4.0 *. atan 1.0
let cosines : float array =
Array.init 64 (fun n ->
let i = n / 8 and k = n mod 8 in
cos (float ((2 * i) + 1) *. float k *. pi /. 16.))
let c (k : int) : float = if k = 0 then 1. /. sqrt 2. else 1.
let fdct (f : float array) : float array =
Array.init 64 (fun n ->
let u = n mod 8 and v = n / 8 in
let sum = ref 0. in
for y = 0 to 7 do
for x = 0 to 7 do
sum := !sum +. (f.((y * 8) + x) *. cosines.((x * 8) + u) *. cosines.((y * 8) + v))
done
done;
0.25 *. c u *. c v *. !sum)
let idct (big_f : float array) : float array =
Array.init 64 (fun n ->
let x = n mod 8 and y = n / 8 in
let sum = ref 0. in
for v = 0 to 7 do
for u = 0 to 7 do
sum := !sum +. (c u *. c v *. big_f.((v * 8) + u) *. cosines.((x * 8) + u) *. cosines.((y * 8) + v))
done
done;
0.25 *. !sum)
let aan_scale : float array =
Array.init 8 (fun k -> if k = 0 then 1. else cos (float k *. pi /. 16.) *. sqrt 2.)
let idct_1d (a : float array) ~(off : int) ~(step : int) : unit =
let get k = a.(off + (k * step)) and set k v = a.(off + (k * step)) <- v in
let tmp0 = get 0 and tmp1 = get 2 and tmp2 = get 4 and tmp3 = get 6 in
let tmp10 = tmp0 +. tmp2 and tmp11 = tmp0 -. tmp2 in
let tmp13 = tmp1 +. tmp3 in
let tmp12 = ((tmp1 -. tmp3) *. 1.414213562) -. tmp13 in
let tmp0 = tmp10 +. tmp13 and tmp3 = tmp10 -. tmp13 in
let tmp1 = tmp11 +. tmp12 and tmp2 = tmp11 -. tmp12 in
let tmp4 = get 1 and tmp5 = get 3 and tmp6 = get 5 and tmp7 = get 7 in
let z13 = tmp6 +. tmp5 and z10 = tmp6 -. tmp5 in
let z11 = tmp4 +. tmp7 and z12 = tmp4 -. tmp7 in
let tmp7 = z11 +. z13 in
let tmp11 = (z11 -. z13) *. 1.414213562 in
let z5 = (z10 +. z12) *. 1.847759065 in
let tmp10 = (1.082392200 *. z12) -. z5 in
let tmp12 = (-2.613125930 *. z10) +. z5 in
let tmp6 = tmp12 -. tmp7 in
let tmp5 = tmp11 -. tmp6 in
let tmp4 = tmp10 +. tmp5 in
set 0 (tmp0 +. tmp7);
set 7 (tmp0 -. tmp7);
set 1 (tmp1 +. tmp6);
set 6 (tmp1 -. tmp6);
set 2 (tmp2 +. tmp5);
set 5 (tmp2 -. tmp5);
set 4 (tmp3 +. tmp4);
set 3 (tmp3 -. tmp4)
let idct_aan (big_f : float array) : float array =
let a = Array.init 64 (fun n -> big_f.(n) *. aan_scale.(n mod 8) *. aan_scale.(n / 8) /. 8.) in
for u = 0 to 7 do
idct_1d a ~off:u ~step:8
done;
for y = 0 to 7 do
idct_1d a ~off:(y * 8) ~step:1
done;
a