Merge commit 'a6a750c7ef240b72ce01e9653343a0ddf247d196'
[ffmpeg.git] / libavcodec / tests / jpeg2000dwt.c
1 /*
2  * Discrete wavelet transform
3  * Copyright (c) 2007 Kamil Nowosad
4  * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu@gmail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "libavcodec/jpeg2000dwt.c"
24
25 #include "libavutil/lfg.h"
26
27 #define MAX_W 256
28
29 static int test_dwt(int *array, int *ref, int border[2][2], int decomp_levels, int type, int max_diff) {
30     int ret, j;
31     DWTContext s1={{{0}}}, *s= &s1;
32     int64_t err2 = 0;
33
34     ret = ff_jpeg2000_dwt_init(s,  border, decomp_levels, type);
35     if (ret < 0) {
36         fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
37         return 1;
38     }
39     ret = ff_dwt_encode(s, array);
40     if (ret < 0) {
41         fprintf(stderr, "ff_dwt_encode failed\n");
42         return 1;
43     }
44     ret = ff_dwt_decode(s, array);
45     if (ret < 0) {
46         fprintf(stderr, "ff_dwt_encode failed\n");
47         return 1;
48     }
49     for (j = 0; j<MAX_W * MAX_W; j++) {
50         if (FFABS(array[j] - ref[j]) > max_diff) {
51             fprintf(stderr, "missmatch at %d (%d != %d) decomp:%d border %d %d %d %d\n",
52                     j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
53             return 2;
54         }
55         err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
56         array[j] = ref[j];
57     }
58     ff_dwt_destroy(s);
59
60     printf("%s, decomp:%2d border %3d %3d %3d %3d milli-err2:%9"PRId64"\n",
61            type == FF_DWT53 ? "5/3i" : "9/7i",
62            decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
63            1000*err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
64
65     return 0;
66 }
67
68 static int test_dwtf(float *array, float *ref, int border[2][2], int decomp_levels, float max_diff) {
69     int ret, j;
70     DWTContext s1={{{0}}}, *s= &s1;
71     double err2 = 0;
72
73     ret = ff_jpeg2000_dwt_init(s,  border, decomp_levels, FF_DWT97);
74     if (ret < 0) {
75         fprintf(stderr, "ff_jpeg2000_dwt_init failed\n");
76         return 1;
77     }
78     ret = ff_dwt_encode(s, array);
79     if (ret < 0) {
80         fprintf(stderr, "ff_dwt_encode failed\n");
81         return 1;
82     }
83     ret = ff_dwt_decode(s, array);
84     if (ret < 0) {
85         fprintf(stderr, "ff_dwt_encode failed\n");
86         return 1;
87     }
88     for (j = 0; j<MAX_W * MAX_W; j++) {
89         if (FFABS(array[j] - ref[j]) > max_diff) {
90             fprintf(stderr, "missmatch at %d (%f != %f) decomp:%d border %d %d %d %d\n",
91                     j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]);
92             return 2;
93         }
94         err2 += (array[j] - ref[j]) * (array[j] - ref[j]);
95         array[j] = ref[j];
96     }
97     ff_dwt_destroy(s);
98
99     printf("9/7f, decomp:%2d border %3d %3d %3d %3d err2:%20.3f\n",
100            decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1],
101            err2 / ((border[0][1] - border[0][0])*(border[1][1] - border[1][0])));
102
103     return 0;
104 }
105
106 static int array[MAX_W * MAX_W];
107 static int ref  [MAX_W * MAX_W];
108 static float arrayf[MAX_W * MAX_W];
109 static float reff  [MAX_W * MAX_W];
110
111 int main(void) {
112     AVLFG prng;
113     int i,j;
114     int border[2][2];
115     int ret, decomp_levels;
116
117     av_lfg_init(&prng, 1);
118
119     for (i = 0; i<MAX_W * MAX_W; i++)
120         arrayf[i] = reff[i] = array[i] = ref[i] =  av_lfg_get(&prng) % 2048;
121
122     for (i = 0; i < 100; i++) {
123         for (j=0; j<4; j++)
124             border[j>>1][j&1] = av_lfg_get(&prng) % MAX_W;
125         if (border[0][0] >= border[0][1] || border[1][0] >= border[1][1])
126             continue;
127         decomp_levels = av_lfg_get(&prng) % FF_DWT_MAX_DECLVLS;
128
129         ret = test_dwt(array, ref, border, decomp_levels, FF_DWT53, 0);
130         if (ret)
131             return ret;
132         ret = test_dwt(array, ref, border, decomp_levels, FF_DWT97_INT, FFMIN(7+5*decomp_levels, 15+3*decomp_levels));
133         if (ret)
134             return ret;
135         ret = test_dwtf(arrayf, reff, border, decomp_levels, 0.05);
136         if (ret)
137             return ret;
138     }
139
140     return 0;
141 }