2
* reference discrete cosine transform (double precision)
3
* Copyright (C) 2009 Dylan Yudaken
5
* This file is part of FFmpeg.
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
* reference discrete cosine transform (double precision)
26
* @author Dylan Yudaken (dyudaken at gmail)
28
* @note This file could be optimized a lot, but is for
29
* reference and so readability is better.
32
#include "libavutil/mathematics.h"
35
static double coefficients[8 * 8];
38
* Initialize the double precision discrete cosine transform
39
* functions fdct & idct.
41
av_cold void ff_ref_dct_init(void)
45
for (j = 0; j < 8; ++j) {
46
coefficients[j] = sqrt(0.125);
47
for (i = 8; i < 64; i += 8) {
48
coefficients[i + j] = 0.5 * cos(i * (j + 0.5) * M_PI / 64.0);
54
* Transform 8x8 block of data with a double precision forward DCT <br>
55
* This is a reference implementation.
57
* @param block pointer to 8x8 block of data to transform
59
void ff_ref_fdct(short *block)
61
/* implement the equation: block = coefficients * block * coefficients' */
66
/* out = coefficients * block */
67
for (i = 0; i < 64; i += 8) {
68
for (j = 0; j < 8; ++j) {
70
for (k = 0; k < 8; ++k) {
71
tmp += coefficients[i + k] * block[k * 8 + j];
77
/* block = out * (coefficients') */
78
for (j = 0; j < 8; ++j) {
79
for (i = 0; i < 64; i += 8) {
81
for (k = 0; k < 8; ++k) {
82
tmp += out[i + k] * coefficients[j * 8 + k];
84
block[i + j] = floor(tmp + 0.499999999999);
90
* Transform 8x8 block of data with a double precision inverse DCT <br>
91
* This is a reference implementation.
93
* @param block pointer to 8x8 block of data to transform
95
void ff_ref_idct(short *block)
97
/* implement the equation: block = (coefficients') * block * coefficients */
102
/* out = block * coefficients */
103
for (i = 0; i < 64; i += 8) {
104
for (j = 0; j < 8; ++j) {
106
for (k = 0; k < 8; ++k) {
107
tmp += block[i + k] * coefficients[k * 8 + j];
113
/* block = (coefficients') * out */
114
for (i = 0; i < 8; ++i) {
115
for (j = 0; j < 8; ++j) {
117
for (k = 0; k < 64; k += 8) {
118
tmp += coefficients[k + i] * out[k + j];
120
block[i * 8 + j] = floor(tmp + 0.5);