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