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