1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifdef NDEBUG
7 #    undef NDEBUG
8 #endif
9 
10 #include <ImfWav.h>
11 #include "ImathRandom.h"
12 #include <ImfArray.h>
13 #include <iostream>
14 #include <exception>
15 #include <stdlib.h>
16 #include <assert.h>
17 
18 
19 using namespace OPENEXR_IMF_NAMESPACE;
20 using namespace std;
21 
22 
23 namespace {
24 
25 
26 void
fill1_14bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny,IMATH_NAMESPACE::Rand48 & rand48)27 fill1_14bit (Array2D <unsigned short> &a,
28              Array2D <unsigned short> &b,
29              int nx,
30              int ny,
31 	     IMATH_NAMESPACE::Rand48 & rand48)
32 {
33     for (int y = 0; y < ny; ++y)
34 	for (int x = 0; x < nx; ++x)
35 	    a[y][x] = b[y][x] = rand48.nexti() & 0x3fff;
36 }
37 
38 
39 void
fill1_16bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny,IMATH_NAMESPACE::Rand48 & rand48)40 fill1_16bit (Array2D <unsigned short> &a,
41              Array2D <unsigned short> &b,
42              int nx,
43              int ny,
44 	     IMATH_NAMESPACE::Rand48 & rand48)
45 {
46     for (int y = 0; y < ny; ++y)
47 	for (int x = 0; x < nx; ++x)
48 	    a[y][x] = b[y][x] = rand48.nexti() & 0xffff;
49 }
50 
51 
52 void
fill2(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny,unsigned short v)53 fill2 (Array2D <unsigned short> &a,
54        Array2D <unsigned short> &b,
55        int nx,
56        int ny,
57        unsigned short v)
58 {
59     for (int y = 0; y < ny; ++y)
60 	for (int x = 0; x < nx; ++x)
61 	    a[y][x] = b[y][x] = v;
62 }
63 
64 
65 void
fill3_14bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)66 fill3_14bit (Array2D <unsigned short> &a,
67              Array2D <unsigned short> &b,
68              int nx,
69              int ny)
70 {
71     for (int y = 0; y < ny; ++y)
72 	for (int x = 0; x < nx; ++x)
73 	    a[y][x] = b[y][x] = (x & 1)? 0: 0x3fff;
74 }
75 
76 
77 void
fill3_16bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)78 fill3_16bit (Array2D <unsigned short> &a,
79           Array2D <unsigned short> &b,
80           int nx,
81           int ny)
82 {
83     for (int y = 0; y < ny; ++y)
84 	for (int x = 0; x < nx; ++x)
85 	    a[y][x] = b[y][x] = (x & 1)? 0: 0xffff;
86 }
87 
88 
89 void
fill4_14bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)90 fill4_14bit (Array2D <unsigned short> &a,
91              Array2D <unsigned short> &b,
92              int nx,
93              int ny)
94 {
95     for (int y = 0; y < ny; ++y)
96 	for (int x = 0; x < nx; ++x)
97 	    a[y][x] = b[y][x] = (y & 1)? 0: 0x3fff;
98 }
99 
100 
101 void
fill4_16bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)102 fill4_16bit (Array2D <unsigned short> &a,
103              Array2D <unsigned short> &b,
104              int nx,
105              int ny)
106 {
107     for (int y = 0; y < ny; ++y)
108 	for (int x = 0; x < nx; ++x)
109 	    a[y][x] = b[y][x] = (y & 1)? 0: 0xffff;
110 }
111 
112 
113 void
fill5_14bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)114 fill5_14bit (Array2D <unsigned short> &a,
115              Array2D <unsigned short> &b,
116              int nx,
117              int ny)
118 {
119     for (int y = 0; y < ny; ++y)
120 	for (int x = 0; x < nx; ++x)
121 	    a[y][x] = b[y][x] = ((x + y) & 1)? 0: 0x3fff;
122 }
123 
124 
125 void
fill5_16bit(Array2D<unsigned short> & a,Array2D<unsigned short> & b,int nx,int ny)126 fill5_16bit (Array2D <unsigned short> &a,
127              Array2D <unsigned short> &b,
128              int nx,
129              int ny)
130 {
131     for (int y = 0; y < ny; ++y)
132 	for (int x = 0; x < nx; ++x)
133 	    a[y][x] = b[y][x] = ((x + y) & 1)? 0: 0xffff;
134 }
135 
136 
137 unsigned short
maxValue(const Array2D<unsigned short> & a,int nx,int ny)138 maxValue (const Array2D <unsigned short> &a, int nx, int ny)
139 {
140     unsigned short mx = 0;
141 
142     for (int y = 0; y < ny; ++y)
143 	for (int x = 0; x < nx; ++x)
144 	    if (mx < a[y][x])
145 		mx = a[y][x];
146 
147     // cout << "max value = " << mx << endl;
148 
149     return mx;
150 }
151 
152 
153 void
wavEncodeDecode(Array2D<unsigned short> & a,const Array2D<unsigned short> & b,int nx,int ny)154 wavEncodeDecode (Array2D <unsigned short> &a,
155 		 const Array2D <unsigned short> &b,
156 		 int nx,
157 		 int ny)
158 {
159     unsigned short mx = maxValue (a, nx, ny);
160 
161     //cout << "encoding " << flush;
162 
163     wav2Encode (&a[0][0], nx, 1, ny, nx, mx);
164 
165     //cout << "decoding " << flush;
166 
167     wav2Decode (&a[0][0], nx, 1, ny, nx, mx);
168 
169     //cout << "comparing" << endl;
170 
171     for (int y = 0; y < ny; ++y)
172     {
173 	for (int x = 0; x < nx; ++x)
174 	{
175 	    //cout << x << ' ' << y << ' ' << a[y][x] << ' ' << b[y][x] << endl;
176 	    assert (a[y][x] == b[y][x]);
177 	}
178     }
179 }
180 
181 
182 void
test(int nx,int ny)183 test (int nx, int ny)
184 {
185     cout << nx << " x " << ny << endl;
186 
187     Array2D<unsigned short> a (ny, nx);
188     Array2D<unsigned short> b (ny, nx);
189 
190     IMATH_NAMESPACE::Rand48 rand48 (0);
191 
192     fill1_14bit (a, b, nx, ny, rand48);
193     wavEncodeDecode (a, b, nx, ny);
194 
195     fill1_16bit (a, b, nx, ny, rand48);
196     wavEncodeDecode (a, b, nx, ny);
197 
198     fill2 (a, b, nx, ny, 0);
199     wavEncodeDecode (a, b, nx, ny);
200 
201     fill2 (a, b, nx, ny, 1);
202     wavEncodeDecode (a, b, nx, ny);
203 
204     fill2 (a, b, nx, ny, 0x3ffe);
205     wavEncodeDecode (a, b, nx, ny);
206 
207     fill2 (a, b, nx, ny, 0x3fff);
208     wavEncodeDecode (a, b, nx, ny);
209 
210     fill2 (a, b, nx, ny, 0xfffe);
211     wavEncodeDecode (a, b, nx, ny);
212 
213     fill2 (a, b, nx, ny, 0xffff);
214     wavEncodeDecode (a, b, nx, ny);
215 
216     fill3_14bit (a, b, nx, ny);
217     wavEncodeDecode (a, b, nx, ny);
218 
219     fill3_16bit (a, b, nx, ny);
220     wavEncodeDecode (a, b, nx, ny);
221 
222     fill4_14bit (a, b, nx, ny);
223     wavEncodeDecode (a, b, nx, ny);
224 
225     fill4_16bit (a, b, nx, ny);
226     wavEncodeDecode (a, b, nx, ny);
227 
228     fill5_14bit (a, b, nx, ny);
229     wavEncodeDecode (a, b, nx, ny);
230 
231     fill5_16bit (a, b, nx, ny);
232     wavEncodeDecode (a, b, nx, ny);
233 }
234 
235 } // namespace
236 
237 
238 void
testWav(const std::string &)239 testWav (const std::string&)
240 {
241     try
242     {
243 	cout << "Testing Wavelet encoder" << endl;
244 
245 	test (1, 1);
246 	test (2, 2);
247 	test (32, 32);
248 	test (1024, 16);
249 	test (16, 1024);
250 	test (997, 37);
251 	test (37, 997);
252 	test (1024, 1024);
253 	test (997, 997);
254 
255 	cout << "ok\n" << endl;
256     }
257     catch (const std::exception &e)
258     {
259 	cerr << "ERROR -- caught exception: " << e.what() << endl;
260 	assert (false);
261     }
262 }
263