Improve performance of inverse DWT 5x3 (#953)
[openjpeg.git] / src / lib / openjp2 / dwt.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses
3  * BSD License, included below. This software may be subject to other third
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2001-2003, David Janssens
10  * Copyright (c) 2002-2003, Yannick Verschueren
11  * Copyright (c) 2003-2007, Francois-Olivier Devaux
12  * Copyright (c) 2003-2014, Antonin Descampe
13  * Copyright (c) 2005, Herve Drolon, FreeImage Team
14  * Copyright (c) 2007, Jonathan Ballard <dzonatas@dzonux.net>
15  * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
16  * Copyright (c) 2017, IntoPIX SA <support@intopix.com>
17  * All rights reserved.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  * 1. Redistributions of source code must retain the above copyright
23  *    notice, this list of conditions and the following disclaimer.
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in the
26  *    documentation and/or other materials provided with the distribution.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
29  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 #ifdef __SSE__
42 #include <xmmintrin.h>
43 #endif
44 #ifdef __SSE2__
45 #include <emmintrin.h>
46 #endif
47
48 #include <assert.h>
49
50 #include "opj_includes.h"
51
52 /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
53 /*@{*/
54
55 #define OPJ_WS(i) v->mem[(i)*2]
56 #define OPJ_WD(i) v->mem[(1+(i)*2)]
57
58 #define PARALLEL_COLS_53     8
59
60 /** @name Local data structures */
61 /*@{*/
62
63 typedef struct dwt_local {
64     OPJ_INT32* mem;
65     OPJ_INT32 dn;
66     OPJ_INT32 sn;
67     OPJ_INT32 cas;
68 } opj_dwt_t;
69
70 typedef union {
71     OPJ_FLOAT32 f[4];
72 } opj_v4_t;
73
74 typedef struct v4dwt_local {
75     opj_v4_t*   wavelet ;
76     OPJ_INT32       dn ;
77     OPJ_INT32       sn ;
78     OPJ_INT32       cas ;
79 } opj_v4dwt_t ;
80
81 static const OPJ_FLOAT32 opj_dwt_alpha =  1.586134342f; /*  12994 */
82 static const OPJ_FLOAT32 opj_dwt_beta  =  0.052980118f; /*    434 */
83 static const OPJ_FLOAT32 opj_dwt_gamma = -0.882911075f; /*  -7233 */
84 static const OPJ_FLOAT32 opj_dwt_delta = -0.443506852f; /*  -3633 */
85
86 static const OPJ_FLOAT32 opj_K      = 1.230174105f; /*  10078 */
87 static const OPJ_FLOAT32 opj_c13318 = 1.625732422f;
88
89 /*@}*/
90
91 /**
92 Virtual function type for wavelet transform in 1-D
93 */
94 typedef void (*DWT1DFN)(const opj_dwt_t* v);
95
96 /** @name Local static functions */
97 /*@{*/
98
99 /**
100 Forward lazy transform (horizontal)
101 */
102 static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
103                                    OPJ_INT32 sn, OPJ_INT32 cas);
104 /**
105 Forward lazy transform (vertical)
106 */
107 static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
108                                    OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas);
109 /**
110 Forward 5-3 wavelet transform in 1-D
111 */
112 static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
113                              OPJ_INT32 cas);
114 /**
115 Forward 9-7 wavelet transform in 1-D
116 */
117 static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
118                                   OPJ_INT32 cas);
119 /**
120 Explicit calculation of the Quantization Stepsizes
121 */
122 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
123                                     opj_stepsize_t *bandno_stepsize);
124 /**
125 Inverse wavelet transform in 2-D.
126 */
127 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
128                                     opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i);
129
130 static OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,
131         void (*p_function)(OPJ_INT32 *, OPJ_INT32, OPJ_INT32, OPJ_INT32));
132
133 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
134         OPJ_UINT32 i);
135
136 /* <summary>                             */
137 /* Inverse 9-7 wavelet transform in 1-D. */
138 /* </summary>                            */
139 static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt);
140
141 static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT w,
142                                    OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 size);
143
144 static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT v,
145                                    OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 nb_elts_read);
146
147 #ifdef __SSE__
148 static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count,
149                                        const __m128 c);
150
151 static void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k,
152                                        OPJ_INT32 m, __m128 c);
153
154 #else
155 static void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count,
156                                    const OPJ_FLOAT32 c);
157
158 static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k,
159                                    OPJ_INT32 m, OPJ_FLOAT32 c);
160
161 #endif
162
163 /*@}*/
164
165 /*@}*/
166
167 #define OPJ_S(i) a[(i)*2]
168 #define OPJ_D(i) a[(1+(i)*2)]
169 #define OPJ_S_(i) ((i)<0?OPJ_S(0):((i)>=sn?OPJ_S(sn-1):OPJ_S(i)))
170 #define OPJ_D_(i) ((i)<0?OPJ_D(0):((i)>=dn?OPJ_D(dn-1):OPJ_D(i)))
171 /* new */
172 #define OPJ_SS_(i) ((i)<0?OPJ_S(0):((i)>=dn?OPJ_S(dn-1):OPJ_S(i)))
173 #define OPJ_DD_(i) ((i)<0?OPJ_D(0):((i)>=sn?OPJ_D(sn-1):OPJ_D(i)))
174
175 /* <summary>                                                              */
176 /* This table contains the norms of the 5-3 wavelets for different bands. */
177 /* </summary>                                                             */
178 static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
179     {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
180     {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
181     {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
182     {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
183 };
184
185 /* <summary>                                                              */
186 /* This table contains the norms of the 9-7 wavelets for different bands. */
187 /* </summary>                                                             */
188 static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
189     {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
190     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
191     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
192     {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
193 };
194
195 /*
196 ==========================================================
197    local functions
198 ==========================================================
199 */
200
201 /* <summary>                             */
202 /* Forward lazy transform (horizontal).  */
203 /* </summary>                            */
204 static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
205                                    OPJ_INT32 sn, OPJ_INT32 cas)
206 {
207     OPJ_INT32 i;
208     OPJ_INT32 * l_dest = b;
209     OPJ_INT32 * l_src = a + cas;
210
211     for (i = 0; i < sn; ++i) {
212         *l_dest++ = *l_src;
213         l_src += 2;
214     }
215
216     l_dest = b + sn;
217     l_src = a + 1 - cas;
218
219     for (i = 0; i < dn; ++i)  {
220         *l_dest++ = *l_src;
221         l_src += 2;
222     }
223 }
224
225 /* <summary>                             */
226 /* Forward lazy transform (vertical).    */
227 /* </summary>                            */
228 static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
229                                    OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas)
230 {
231     OPJ_INT32 i = sn;
232     OPJ_INT32 * l_dest = b;
233     OPJ_INT32 * l_src = a + cas;
234
235     while (i--) {
236         *l_dest = *l_src;
237         l_dest += x;
238         l_src += 2;
239     } /* b[i*x]=a[2*i+cas]; */
240
241     l_dest = b + sn * x;
242     l_src = a + 1 - cas;
243
244     i = dn;
245     while (i--) {
246         *l_dest = *l_src;
247         l_dest += x;
248         l_src += 2;
249     } /*b[(sn+i)*x]=a[(2*i+1-cas)];*/
250 }
251
252 #ifdef STANDARD_SLOW_VERSION
253 /* <summary>                             */
254 /* Inverse lazy transform (horizontal).  */
255 /* </summary>                            */
256 static void opj_dwt_interleave_h(const opj_dwt_t* h, OPJ_INT32 *a)
257 {
258     OPJ_INT32 *ai = a;
259     OPJ_INT32 *bi = h->mem + h->cas;
260     OPJ_INT32  i    = h->sn;
261     while (i--) {
262         *bi = *(ai++);
263         bi += 2;
264     }
265     ai  = a + h->sn;
266     bi  = h->mem + 1 - h->cas;
267     i   = h->dn ;
268     while (i--) {
269         *bi = *(ai++);
270         bi += 2;
271     }
272 }
273
274 /* <summary>                             */
275 /* Inverse lazy transform (vertical).    */
276 /* </summary>                            */
277 static void opj_dwt_interleave_v(const opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x)
278 {
279     OPJ_INT32 *ai = a;
280     OPJ_INT32 *bi = v->mem + v->cas;
281     OPJ_INT32  i = v->sn;
282     while (i--) {
283         *bi = *ai;
284         bi += 2;
285         ai += x;
286     }
287     ai = a + (v->sn * x);
288     bi = v->mem + 1 - v->cas;
289     i = v->dn ;
290     while (i--) {
291         *bi = *ai;
292         bi += 2;
293         ai += x;
294     }
295 }
296
297 #endif /* STANDARD_SLOW_VERSION */
298
299 /* <summary>                            */
300 /* Forward 5-3 wavelet transform in 1-D. */
301 /* </summary>                           */
302 static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
303                              OPJ_INT32 cas)
304 {
305     OPJ_INT32 i;
306
307     if (!cas) {
308         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
309             for (i = 0; i < dn; i++) {
310                 OPJ_D(i) -= (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
311             }
312             for (i = 0; i < sn; i++) {
313                 OPJ_S(i) += (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
314             }
315         }
316     } else {
317         if (!sn && dn == 1) {       /* NEW :  CASE ONE ELEMENT */
318             OPJ_S(0) *= 2;
319         } else {
320             for (i = 0; i < dn; i++) {
321                 OPJ_S(i) -= (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
322             }
323             for (i = 0; i < sn; i++) {
324                 OPJ_D(i) += (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
325             }
326         }
327     }
328 }
329
330 #ifdef STANDARD_SLOW_VERSION
331 /* <summary>                            */
332 /* Inverse 5-3 wavelet transform in 1-D. */
333 /* </summary>                           */
334 static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
335                               OPJ_INT32 cas)
336 {
337     OPJ_INT32 i;
338
339     if (!cas) {
340         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
341             for (i = 0; i < sn; i++) {
342                 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
343             }
344             for (i = 0; i < dn; i++) {
345                 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
346             }
347         }
348     } else {
349         if (!sn  && dn == 1) {        /* NEW :  CASE ONE ELEMENT */
350             OPJ_S(0) /= 2;
351         } else {
352             for (i = 0; i < sn; i++) {
353                 OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
354             }
355             for (i = 0; i < dn; i++) {
356                 OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
357             }
358         }
359     }
360 }
361
362 static void opj_dwt_decode_1(const opj_dwt_t *v)
363 {
364     opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
365 }
366
367 #endif /* STANDARD_SLOW_VERSION */
368
369 #if !defined(STANDARD_SLOW_VERSION)
370 static void  opj_idwt53_h_cas0(OPJ_INT32* tmp,
371                                const OPJ_INT32 sn,
372                                const OPJ_INT32 len,
373                                OPJ_INT32* tiledp)
374 {
375     OPJ_INT32 i, j;
376     const OPJ_INT32* in_even = &tiledp[0];
377     const OPJ_INT32* in_odd = &tiledp[sn];
378
379 #ifdef TWO_PASS_VERSION
380     /* For documentation purpose: performs lifting in two iterations, */
381     /* but withtmp explicit interleaving */
382
383     assert(len > 1);
384
385     /* Even */
386     tmp[0] = in_even[0] - ((in_odd[0] + 1) >> 1);
387     for (i = 2, j = 0; i <= len - 2; i += 2, j++) {
388         tmp[i] = in_even[j + 1] - ((in_odd[j] + in_odd[j + 1] + 2) >> 2);
389     }
390     if (len & 1) { /* if len is odd */
391         tmp[len - 1] = in_even[(len - 1) / 2] - ((in_odd[(len - 2) / 2] + 1) >> 1);
392     }
393
394     /* Odd */
395     for (i = 1, j = 0; i < len - 1; i += 2, j++) {
396         tmp[i] = in_odd[j] + ((tmp[i - 1] + tmp[i + 1]) >> 1);
397     }
398     if (!(len & 1)) { /* if len is even */
399         tmp[len - 1] = in_odd[(len - 1) / 2] + tmp[len - 2];
400     }
401 #else
402     OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
403
404     assert(len > 1);
405
406     /* Improved version of the TWO_PASS_VERSION: */
407     /* Performs lifting in one single iteration. Saves memory */
408     /* accesses and explicit interleaving. */
409     s1n = in_even[0];
410     d1n = in_odd[0];
411     s0n = s1n - ((d1n + 1) >> 1);
412
413     for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
414         d1c = d1n;
415         s0c = s0n;
416
417         s1n = in_even[j];
418         d1n = in_odd[j];
419
420         s0n = s1n - ((d1c + d1n + 2) >> 2);
421
422         tmp[i  ] = s0c;
423         tmp[i + 1] = d1c + ((s0c + s0n) >> 1);
424     }
425
426     tmp[i] = s0n;
427
428     if (len & 1) {
429         tmp[len - 1] = in_even[(len - 1) / 2] - ((d1n + 1) >> 1);
430         tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
431     } else {
432         tmp[len - 1] = d1n + s0n;
433     }
434 #endif
435     memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
436 }
437
438 static void  opj_idwt53_h_cas1(OPJ_INT32* tmp,
439                                const OPJ_INT32 sn,
440                                const OPJ_INT32 len,
441                                OPJ_INT32* tiledp)
442 {
443     OPJ_INT32 i, j;
444     const OPJ_INT32* in_even = &tiledp[sn];
445     const OPJ_INT32* in_odd = &tiledp[0];
446
447 #ifdef TWO_PASS_VERSION
448     /* For documentation purpose: performs lifting in two iterations, */
449     /* but withtmp explicit interleaving */
450
451     assert(len > 2);
452
453     /* Odd */
454     for (i = 1, j = 0; i < len - 1; i += 2, j++) {
455         tmp[i] = in_odd[j] - ((in_even[j] + in_even[j + 1] + 2) >> 2);
456     }
457     if (!(len & 1)) {
458         tmp[len - 1] = in_odd[len / 2 - 1] - ((in_even[len / 2 - 1] + 1) >> 1);
459     }
460
461     /* Even */
462     tmp[0] = in_even[0] + tmp[1];
463     for (i = 2, j = 1; i < len - 1; i += 2, j++) {
464         tmp[i] = in_even[j] + ((tmp[i + 1] + tmp[i - 1]) >> 1);
465     }
466     if (len & 1) {
467         tmp[len - 1] = in_even[len / 2] + tmp[len - 2];
468     }
469 #else
470     OPJ_INT32 s1, s2, dc, dn;
471
472     assert(len > 2);
473
474     /* Improved version of the TWO_PASS_VERSION: */
475     /* Performs lifting in one single iteration. Saves memory */
476     /* accesses and explicit interleaving. */
477
478     s1 = in_even[1];
479     dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
480     tmp[0] = in_even[0] + dc;
481
482     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
483
484         s2 = in_even[j + 1];
485
486         dn = in_odd[j] - ((s1 + s2 + 2) >> 2);
487         tmp[i  ] = dc;
488         tmp[i + 1] = s1 + ((dn + dc) >> 1);
489
490         dc = dn;
491         s1 = s2;
492     }
493
494     tmp[i] = dc;
495
496     if (!(len & 1)) {
497         dn = in_odd[len / 2 - 1] - ((s1 + 1) >> 1);
498         tmp[len - 2] = s1 + ((dn + dc) >> 1);
499         tmp[len - 1] = dn;
500     } else {
501         tmp[len - 1] = s1 + dc;
502     }
503 #endif
504     memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
505 }
506
507
508 #endif /* !defined(STANDARD_SLOW_VERSION) */
509
510 /* <summary>                            */
511 /* Inverse 5-3 wavelet transform in 1-D for one row. */
512 /* </summary>                           */
513 /* Performs interleave, inverse wavelet transform and copy back to buffer */
514 static void opj_idwt53_h(const opj_dwt_t *dwt,
515                          OPJ_INT32* tiledp)
516 {
517 #ifdef STANDARD_SLOW_VERSION
518     /* For documentation purpose */
519     opj_dwt_interleave_h(dwt, tiledp);
520     opj_dwt_decode_1(dwt);
521     memcpy(tiledp, dwt->mem, (OPJ_UINT32)(dwt->sn + dwt->dn) * sizeof(OPJ_INT32));
522 #else
523     const OPJ_INT32 sn = dwt->sn;
524     const OPJ_INT32 len = sn + dwt->dn;
525     if (dwt->cas == 0) { /* Left-most sample is on even coordinate */
526         if (len > 1) {
527             opj_idwt53_h_cas0(dwt->mem, sn, len, tiledp);
528         } else {
529             /* Unmodified value */
530         }
531     } else { /* Left-most sample is on odd coordinate */
532         if (len == 1) {
533             tiledp[0] /= 2;
534         } else if (len == 2) {
535             OPJ_INT32* out = dwt->mem;
536             const OPJ_INT32* in_even = &tiledp[sn];
537             const OPJ_INT32* in_odd = &tiledp[0];
538             out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
539             out[0] = in_even[0] + out[1];
540             memcpy(tiledp, dwt->mem, (OPJ_UINT32)len * sizeof(OPJ_INT32));
541         } else if (len > 2) {
542             opj_idwt53_h_cas1(dwt->mem, sn, len, tiledp);
543         }
544     }
545 #endif
546 }
547
548 #if defined(__SSE2__) && !defined(STANDARD_SLOW_VERSION)
549
550 /* Conveniency macros to improve the readabilty of the formulas */
551 #define LOADU(x)   _mm_loadu_si128((const __m128i*)(x))
552 #define STORE(x,y) _mm_store_si128((__m128i*)(x),(y))
553 #define ADD(x,y)   _mm_add_epi32((x),(y))
554 #define ADD3(x,y,z) ADD(ADD(x,y),z)
555 #define SUB(x,y)   _mm_sub_epi32((x),(y))
556 #define SAR(x,y)   _mm_srai_epi32((x),(y))
557
558 /** Vertical inverse 5x3 wavelet transform for 8 columns, when top-most
559  * pixel is on even coordinate */
560 static void opj_idwt53_v_cas0_8cols_SSE2(
561     OPJ_INT32* tmp,
562     const OPJ_INT32 sn,
563     const OPJ_INT32 len,
564     OPJ_INT32* tiledp_col,
565     const OPJ_INT32 stride)
566 {
567     const OPJ_INT32* in_even = &tiledp_col[0];
568     const OPJ_INT32* in_odd = &tiledp_col[sn * stride];
569
570     OPJ_INT32 i, j;
571     __m128i d1c_0, d1n_0, s1n_0, s0c_0, s0n_0;
572     __m128i d1c_1, d1n_1, s1n_1, s0c_1, s0n_1;
573     const __m128i two = _mm_set1_epi32(2);
574
575     assert(len > 1);
576     assert(PARALLEL_COLS_53 == 8);
577
578     s1n_0 = LOADU(in_even + 0);
579     s1n_1 = LOADU(in_even + 4);
580     d1n_0 = LOADU(in_odd);
581     d1n_1 = LOADU(in_odd + 4);
582
583     /* s0n = s1n - ((d1n + 1) >> 1); <==> */
584     /* s0n = s1n - ((d1n + d1n + 2) >> 2); */
585     s0n_0 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
586     s0n_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
587
588     for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
589         d1c_0 = d1n_0;
590         s0c_0 = s0n_0;
591         d1c_1 = d1n_1;
592         s0c_1 = s0n_1;
593
594         s1n_0 = LOADU(in_even + j * stride);
595         s1n_1 = LOADU(in_even + j * stride + 4);
596         d1n_0 = LOADU(in_odd + j * stride);
597         d1n_1 = LOADU(in_odd + j * stride + 4);
598
599         /*s0n = s1n - ((d1c + d1n + 2) >> 2);*/
600         s0n_0 = SUB(s1n_0, SAR(ADD3(d1c_0, d1n_0, two), 2));
601         s0n_1 = SUB(s1n_1, SAR(ADD3(d1c_1, d1n_1, two), 2));
602
603         STORE(tmp + PARALLEL_COLS_53 * (i + 0), s0c_0);
604         STORE(tmp + PARALLEL_COLS_53 * (i + 0) + 4, s0c_1);
605
606         /* d1c + ((s0c + s0n) >> 1) */
607         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
608               ADD(d1c_0, SAR(ADD(s0c_0, s0n_0), 1)));
609         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 4,
610               ADD(d1c_1, SAR(ADD(s0c_1, s0n_1), 1)));
611     }
612
613     STORE(tmp + PARALLEL_COLS_53 * (i + 0) + 0, s0n_0);
614     STORE(tmp + PARALLEL_COLS_53 * (i + 0) + 4, s0n_1);
615
616     if (len & 1) {
617         __m128i tmp_len_minus_1;
618         s1n_0 = LOADU(in_even + ((len - 1) / 2) * stride);
619         /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
620         tmp_len_minus_1 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
621         STORE(tmp + 8 * (len - 1), tmp_len_minus_1);
622         /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
623         STORE(tmp + 8 * (len - 2),
624               ADD(d1n_0, SAR(ADD(s0n_0, tmp_len_minus_1), 1)));
625
626         s1n_1 = LOADU(in_even + ((len - 1) / 2) * stride + 4);
627         /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
628         tmp_len_minus_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
629         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 4, tmp_len_minus_1);
630         /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
631         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + 4,
632               ADD(d1n_1, SAR(ADD(s0n_1, tmp_len_minus_1), 1)));
633
634
635     } else {
636         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, ADD(d1n_0, s0n_0));
637         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 4, ADD(d1n_1, s0n_1));
638     }
639
640     for (i = 0; i < len; ++i) {
641         memcpy(&tiledp_col[i * stride],
642                &tmp[PARALLEL_COLS_53 * i],
643                PARALLEL_COLS_53 * sizeof(OPJ_INT32));
644     }
645 }
646
647
648 /** Vertical inverse 5x3 wavelet transform for 8 columns, when top-most
649  * pixel is on odd coordinate */
650 static void opj_idwt53_v_cas1_8cols_SSE2(
651     OPJ_INT32* tmp,
652     const OPJ_INT32 sn,
653     const OPJ_INT32 len,
654     OPJ_INT32* tiledp_col,
655     const OPJ_INT32 stride)
656 {
657     OPJ_INT32 i, j;
658
659     __m128i s1_0, s2_0, dc_0, dn_0;
660     __m128i s1_1, s2_1, dc_1, dn_1;
661     const __m128i two = _mm_set1_epi32(2);
662
663     const OPJ_INT32* in_even = &tiledp_col[sn * stride];
664     const OPJ_INT32* in_odd = &tiledp_col[0];
665
666     assert(len > 2);
667     assert(PARALLEL_COLS_53 == 8);
668
669     s1_0 = LOADU(in_even + stride);
670     /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
671     dc_0 = _mm_sub_epi32(
672                LOADU(in_odd + 0),
673                SAR(ADD3(LOADU(in_even + 0), s1_0, two), 2));
674     STORE(tmp + PARALLEL_COLS_53 * 0, ADD(LOADU(in_even + 0), dc_0));
675
676     s1_1 = LOADU(in_even + stride + 4);
677     /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
678     dc_1 = _mm_sub_epi32(
679                LOADU(in_odd + 4),
680                SAR(ADD3(LOADU(in_even + 4), s1_1, two), 2));
681     STORE(tmp + PARALLEL_COLS_53 * 0 + 4, ADD(LOADU(in_even + 4), dc_1));
682
683     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
684
685         s2_0 = LOADU(in_even + (j + 1) * stride);
686         s2_1 = LOADU(in_even + (j + 1) * stride + 4);
687
688         /* dn = in_odd[j * stride] - ((s1 + s2 + 2) >> 2); */
689         dn_0 = SUB(LOADU(in_odd + j * stride),
690                    SAR(ADD3(s1_0, s2_0, two), 2));
691         dn_1 = SUB(LOADU(in_odd + j * stride + 4),
692                    SAR(ADD3(s1_1, s2_1, two), 2));
693
694         STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
695         STORE(tmp + PARALLEL_COLS_53 * i + 4, dc_1);
696
697         /* tmp[i + 1] = s1 + ((dn + dc) >> 1); */
698         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
699               ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
700         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 4,
701               ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
702
703         dc_0 = dn_0;
704         s1_0 = s2_0;
705         dc_1 = dn_1;
706         s1_1 = s2_1;
707     }
708     STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
709     STORE(tmp + PARALLEL_COLS_53 * i + 4, dc_1);
710
711     if (!(len & 1)) {
712         /*dn = in_odd[(len / 2 - 1) * stride] - ((s1 + 1) >> 1); */
713         dn_0 = SUB(LOADU(in_odd + (len / 2 - 1) * stride),
714                    SAR(ADD3(s1_0, s1_0, two), 2));
715         dn_1 = SUB(LOADU(in_odd + (len / 2 - 1) * stride + 4),
716                    SAR(ADD3(s1_1, s1_1, two), 2));
717
718         /* tmp[len - 2] = s1 + ((dn + dc) >> 1); */
719         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + 0,
720               ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
721         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + 4,
722               ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
723
724         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, dn_0);
725         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 4, dn_1);
726     } else {
727         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, ADD(s1_0, dc_0));
728         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 4, ADD(s1_1, dc_1));
729     }
730
731     for (i = 0; i < len; ++i) {
732         memcpy(&tiledp_col[i * stride],
733                &tmp[PARALLEL_COLS_53 * i],
734                PARALLEL_COLS_53 * sizeof(OPJ_INT32));
735     }
736 }
737
738 #undef LOADU
739 #undef STORE
740 #undef ADD
741 #undef ADD3
742 #undef SUB
743 #undef SAR
744
745 #endif /* defined(__SSE2__) && !defined(STANDARD_SLOW_VERSION) */
746
747 #if !defined(STANDARD_SLOW_VERSION)
748 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
749  * pixel is on even coordinate */
750 static void opj_idwt3_v_cas0(OPJ_INT32* tmp,
751                              const OPJ_INT32 sn,
752                              const OPJ_INT32 len,
753                              OPJ_INT32* tiledp_col,
754                              const OPJ_INT32 stride)
755 {
756     OPJ_INT32 i, j;
757     OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
758
759     assert(len > 1);
760
761     /* Performs lifting in one single iteration. Saves memory */
762     /* accesses and explicit interleaving. */
763
764     s1n = tiledp_col[0];
765     d1n = tiledp_col[sn * stride];
766     s0n = s1n - ((d1n + 1) >> 1);
767
768     for (i = 0, j = 0; i < (len - 3); i += 2, j++) {
769         d1c = d1n;
770         s0c = s0n;
771
772         s1n = tiledp_col[(j + 1) * stride];
773         d1n = tiledp_col[(sn + j + 1) * stride];
774
775         s0n = s1n - ((d1c + d1n + 2) >> 2);
776
777         tmp[i  ] = s0c;
778         tmp[i + 1] = d1c + ((s0c + s0n) >> 1);
779     }
780
781     tmp[i] = s0n;
782
783     if (len & 1) {
784         tmp[len - 1] =
785             tiledp_col[((len - 1) / 2) * stride] -
786             ((d1n + 1) >> 1);
787         tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
788     } else {
789         tmp[len - 1] = d1n + s0n;
790     }
791
792     for (i = 0; i < len; ++i) {
793         tiledp_col[i * stride] = tmp[i];
794     }
795 }
796
797
798 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
799  * pixel is on odd coordinate */
800 static void opj_idwt3_v_cas1(OPJ_INT32* tmp,
801                              const OPJ_INT32 sn,
802                              const OPJ_INT32 len,
803                              OPJ_INT32* tiledp_col,
804                              const OPJ_INT32 stride)
805 {
806     OPJ_INT32 i, j;
807     OPJ_INT32 s1, s2, dc, dn;
808     const OPJ_INT32* in_even = &tiledp_col[sn * stride];
809     const OPJ_INT32* in_odd = &tiledp_col[0];
810
811     assert(len > 2);
812
813     /* Performs lifting in one single iteration. Saves memory */
814     /* accesses and explicit interleaving. */
815
816     s1 = in_even[stride];
817     dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
818     tmp[0] = in_even[0] + dc;
819     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
820
821         s2 = in_even[(j + 1) * stride];
822
823         dn = in_odd[j * stride] - ((s1 + s2 + 2) >> 2);
824         tmp[i  ] = dc;
825         tmp[i + 1] = s1 + ((dn + dc) >> 1);
826
827         dc = dn;
828         s1 = s2;
829     }
830     tmp[i] = dc;
831     if (!(len & 1)) {
832         dn = in_odd[(len / 2 - 1) * stride] - ((s1 + 1) >> 1);
833         tmp[len - 2] = s1 + ((dn + dc) >> 1);
834         tmp[len - 1] = dn;
835     } else {
836         tmp[len - 1] = s1 + dc;
837     }
838
839     for (i = 0; i < len; ++i) {
840         tiledp_col[i * stride] = tmp[i];
841     }
842 }
843 #endif /* !defined(STANDARD_SLOW_VERSION) */
844
845 /* <summary>                            */
846 /* Inverse vertical 5-3 wavelet transform in 1-D for several columns. */
847 /* </summary>                           */
848 /* Performs interleave, inverse wavelet transform and copy back to buffer */
849 static void opj_idwt53_v(const opj_dwt_t *dwt,
850                          OPJ_INT32* tiledp_col,
851                          OPJ_INT32 stride,
852                          OPJ_INT32 nb_cols)
853 {
854 #ifdef STANDARD_SLOW_VERSION
855     /* For documentation purpose */
856     OPJ_INT32 k, c;
857     for (c = 0; c < nb_cols; c ++) {
858         opj_dwt_interleave_v(dwt, tiledp_col + c, stride);
859         opj_dwt_decode_1(dwt);
860         for (k = 0; k < dwt->sn + dwt->dn; ++k) {
861             tiledp_col[c + k * stride] = dwt->mem[k];
862         }
863     }
864 #else
865     const OPJ_INT32 sn = dwt->sn;
866     const OPJ_INT32 len = sn + dwt->dn;
867     if (dwt->cas == 0) {
868         /* If len == 1, unmodified value */
869
870 #if __SSE2__
871         if (len > 1 && nb_cols == PARALLEL_COLS_53) {
872             /* Same as below general case, except that thanks to SSE2 */
873             /* we can efficently process 8 columns in parallel */
874             opj_idwt53_v_cas0_8cols_SSE2(dwt->mem, sn, len, tiledp_col, stride);
875             return;
876         }
877 #endif
878         if (len > 1) {
879             OPJ_INT32 c;
880             for (c = 0; c < nb_cols; c++, tiledp_col++) {
881                 opj_idwt3_v_cas0(dwt->mem, sn, len, tiledp_col, stride);
882             }
883             return;
884         }
885     } else {
886         if (len == 1) {
887             OPJ_INT32 c;
888             for (c = 0; c < nb_cols; c++, tiledp_col++) {
889                 tiledp_col[0] /= 2;
890             }
891             return;
892         }
893
894         if (len == 2) {
895             OPJ_INT32 c;
896             OPJ_INT32* out = dwt->mem;
897             for (c = 0; c < nb_cols; c++, tiledp_col++) {
898                 OPJ_INT32 i;
899                 const OPJ_INT32* in_even = &tiledp_col[sn * stride];
900                 const OPJ_INT32* in_odd = &tiledp_col[0];
901
902                 out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
903                 out[0] = in_even[0] + out[1];
904
905                 for (i = 0; i < len; ++i) {
906                     tiledp_col[i * stride] = out[i];
907                 }
908             }
909
910             return;
911         }
912
913 #ifdef __SSE2__
914         if (len > 2 && nb_cols == PARALLEL_COLS_53) {
915             /* Same as below general case, except that thanks to SSE2 */
916             /* we can efficently process 8 columns in parallel */
917             opj_idwt53_v_cas1_8cols_SSE2(dwt->mem, sn, len, tiledp_col, stride);
918             return;
919         }
920 #endif
921         if (len > 2) {
922             OPJ_INT32 c;
923             for (c = 0; c < nb_cols; c++, tiledp_col++) {
924                 opj_idwt3_v_cas1(dwt->mem, sn, len, tiledp_col, stride);
925             }
926             return;
927         }
928     }
929 #endif
930 }
931
932
933 /* <summary>                             */
934 /* Forward 9-7 wavelet transform in 1-D. */
935 /* </summary>                            */
936 static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
937                                   OPJ_INT32 cas)
938 {
939     OPJ_INT32 i;
940     if (!cas) {
941         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
942             for (i = 0; i < dn; i++) {
943                 OPJ_D(i) -= opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 12993);
944             }
945             for (i = 0; i < sn; i++) {
946                 OPJ_S(i) -= opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 434);
947             }
948             for (i = 0; i < dn; i++) {
949                 OPJ_D(i) += opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 7233);
950             }
951             for (i = 0; i < sn; i++) {
952                 OPJ_S(i) += opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 3633);
953             }
954             for (i = 0; i < dn; i++) {
955                 OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 5038);    /*5038 */
956             }
957             for (i = 0; i < sn; i++) {
958                 OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 6659);    /*6660 */
959             }
960         }
961     } else {
962         if ((sn > 0) || (dn > 1)) { /* NEW :  CASE ONE ELEMENT */
963             for (i = 0; i < dn; i++) {
964                 OPJ_S(i) -= opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 12993);
965             }
966             for (i = 0; i < sn; i++) {
967                 OPJ_D(i) -= opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 434);
968             }
969             for (i = 0; i < dn; i++) {
970                 OPJ_S(i) += opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 7233);
971             }
972             for (i = 0; i < sn; i++) {
973                 OPJ_D(i) += opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 3633);
974             }
975             for (i = 0; i < dn; i++) {
976                 OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 5038);    /*5038 */
977             }
978             for (i = 0; i < sn; i++) {
979                 OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 6659);    /*6660 */
980             }
981         }
982     }
983 }
984
985 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
986                                     opj_stepsize_t *bandno_stepsize)
987 {
988     OPJ_INT32 p, n;
989     p = opj_int_floorlog2(stepsize) - 13;
990     n = 11 - opj_int_floorlog2(stepsize);
991     bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
992     bandno_stepsize->expn = numbps - p;
993 }
994
995 /*
996 ==========================================================
997    DWT interface
998 ==========================================================
999 */
1000
1001
1002 /* <summary>                            */
1003 /* Forward 5-3 wavelet transform in 2-D. */
1004 /* </summary>                           */
1005 static INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,
1006         void (*p_function)(OPJ_INT32 *, OPJ_INT32, OPJ_INT32, OPJ_INT32))
1007 {
1008     OPJ_INT32 i, j, k;
1009     OPJ_INT32 *a = 00;
1010     OPJ_INT32 *aj = 00;
1011     OPJ_INT32 *bj = 00;
1012     OPJ_INT32 w, l;
1013
1014     OPJ_INT32 rw;           /* width of the resolution level computed   */
1015     OPJ_INT32 rh;           /* height of the resolution level computed  */
1016     size_t l_data_size;
1017
1018     opj_tcd_resolution_t * l_cur_res = 0;
1019     opj_tcd_resolution_t * l_last_res = 0;
1020
1021     w = tilec->x1 - tilec->x0;
1022     l = (OPJ_INT32)tilec->numresolutions - 1;
1023     a = tilec->data;
1024
1025     l_cur_res = tilec->resolutions + l;
1026     l_last_res = l_cur_res - 1;
1027
1028     l_data_size = opj_dwt_max_resolution(tilec->resolutions, tilec->numresolutions);
1029     /* overflow check */
1030     if (l_data_size > (SIZE_MAX / sizeof(OPJ_INT32))) {
1031         /* FIXME event manager error callback */
1032         return OPJ_FALSE;
1033     }
1034     l_data_size *= sizeof(OPJ_INT32);
1035     bj = (OPJ_INT32*)opj_malloc(l_data_size);
1036     /* l_data_size is equal to 0 when numresolutions == 1 but bj is not used */
1037     /* in that case, so do not error out */
1038     if (l_data_size != 0 && ! bj) {
1039         return OPJ_FALSE;
1040     }
1041     i = l;
1042
1043     while (i--) {
1044         OPJ_INT32 rw1;      /* width of the resolution level once lower than computed one                                       */
1045         OPJ_INT32 rh1;      /* height of the resolution level once lower than computed one                                      */
1046         OPJ_INT32 cas_col;  /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
1047         OPJ_INT32 cas_row;  /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
1048         OPJ_INT32 dn, sn;
1049
1050         rw  = l_cur_res->x1 - l_cur_res->x0;
1051         rh  = l_cur_res->y1 - l_cur_res->y0;
1052         rw1 = l_last_res->x1 - l_last_res->x0;
1053         rh1 = l_last_res->y1 - l_last_res->y0;
1054
1055         cas_row = l_cur_res->x0 & 1;
1056         cas_col = l_cur_res->y0 & 1;
1057
1058         sn = rh1;
1059         dn = rh - rh1;
1060         for (j = 0; j < rw; ++j) {
1061             aj = a + j;
1062             for (k = 0; k < rh; ++k) {
1063                 bj[k] = aj[k * w];
1064             }
1065
1066             (*p_function)(bj, dn, sn, cas_col);
1067
1068             opj_dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
1069         }
1070
1071         sn = rw1;
1072         dn = rw - rw1;
1073
1074         for (j = 0; j < rh; j++) {
1075             aj = a + j * w;
1076             for (k = 0; k < rw; k++) {
1077                 bj[k] = aj[k];
1078             }
1079             (*p_function)(bj, dn, sn, cas_row);
1080             opj_dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
1081         }
1082
1083         l_cur_res = l_last_res;
1084
1085         --l_last_res;
1086     }
1087
1088     opj_free(bj);
1089     return OPJ_TRUE;
1090 }
1091
1092 /* Forward 5-3 wavelet transform in 2-D. */
1093 /* </summary>                           */
1094 OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec)
1095 {
1096     return opj_dwt_encode_procedure(tilec, opj_dwt_encode_1);
1097 }
1098
1099 /* <summary>                            */
1100 /* Inverse 5-3 wavelet transform in 2-D. */
1101 /* </summary>                           */
1102 OPJ_BOOL opj_dwt_decode(opj_thread_pool_t* tp, opj_tcd_tilecomp_t* tilec,
1103                         OPJ_UINT32 numres)
1104 {
1105     return opj_dwt_decode_tile(tp, tilec, numres);
1106 }
1107
1108
1109 /* <summary>                          */
1110 /* Get gain of 5-3 wavelet transform. */
1111 /* </summary>                         */
1112 OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient)
1113 {
1114     if (orient == 0) {
1115         return 0;
1116     }
1117     if (orient == 1 || orient == 2) {
1118         return 1;
1119     }
1120     return 2;
1121 }
1122
1123 /* <summary>                */
1124 /* Get norm of 5-3 wavelet. */
1125 /* </summary>               */
1126 OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient)
1127 {
1128     return opj_dwt_norms[orient][level];
1129 }
1130
1131 /* <summary>                             */
1132 /* Forward 9-7 wavelet transform in 2-D. */
1133 /* </summary>                            */
1134 OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec)
1135 {
1136     return opj_dwt_encode_procedure(tilec, opj_dwt_encode_1_real);
1137 }
1138
1139 /* <summary>                          */
1140 /* Get gain of 9-7 wavelet transform. */
1141 /* </summary>                         */
1142 OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient)
1143 {
1144     (void)orient;
1145     return 0;
1146 }
1147
1148 /* <summary>                */
1149 /* Get norm of 9-7 wavelet. */
1150 /* </summary>               */
1151 OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient)
1152 {
1153     return opj_dwt_norms_real[orient][level];
1154 }
1155
1156 void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec)
1157 {
1158     OPJ_UINT32 numbands, bandno;
1159     numbands = 3 * tccp->numresolutions - 2;
1160     for (bandno = 0; bandno < numbands; bandno++) {
1161         OPJ_FLOAT64 stepsize;
1162         OPJ_UINT32 resno, level, orient, gain;
1163
1164         resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
1165         orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
1166         level = tccp->numresolutions - 1 - resno;
1167         gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) ||
1168                                           (orient == 2)) ? 1 : 2));
1169         if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
1170             stepsize = 1.0;
1171         } else {
1172             OPJ_FLOAT64 norm = opj_dwt_norms_real[orient][level];
1173             stepsize = (1 << (gain)) / norm;
1174         }
1175         opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0),
1176                                 (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]);
1177     }
1178 }
1179
1180 /* <summary>                             */
1181 /* Determine maximum computed resolution level for inverse wavelet transform */
1182 /* </summary>                            */
1183 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
1184         OPJ_UINT32 i)
1185 {
1186     OPJ_UINT32 mr   = 0;
1187     OPJ_UINT32 w;
1188     while (--i) {
1189         ++r;
1190         if (mr < (w = (OPJ_UINT32)(r->x1 - r->x0))) {
1191             mr = w ;
1192         }
1193         if (mr < (w = (OPJ_UINT32)(r->y1 - r->y0))) {
1194             mr = w ;
1195         }
1196     }
1197     return mr ;
1198 }
1199
1200 typedef struct {
1201     opj_dwt_t h;
1202     OPJ_UINT32 rw;
1203     OPJ_UINT32 w;
1204     OPJ_INT32 * OPJ_RESTRICT tiledp;
1205     OPJ_UINT32 min_j;
1206     OPJ_UINT32 max_j;
1207 } opj_dwd_decode_h_job_t;
1208
1209 static void opj_dwt_decode_h_func(void* user_data, opj_tls_t* tls)
1210 {
1211     OPJ_UINT32 j;
1212     opj_dwd_decode_h_job_t* job;
1213     (void)tls;
1214
1215     job = (opj_dwd_decode_h_job_t*)user_data;
1216     for (j = job->min_j; j < job->max_j; j++) {
1217         opj_idwt53_h(&job->h, &job->tiledp[j * job->w]);
1218     }
1219
1220     opj_aligned_free(job->h.mem);
1221     opj_free(job);
1222 }
1223
1224 typedef struct {
1225     opj_dwt_t v;
1226     OPJ_UINT32 rh;
1227     OPJ_UINT32 w;
1228     OPJ_INT32 * OPJ_RESTRICT tiledp;
1229     OPJ_UINT32 min_j;
1230     OPJ_UINT32 max_j;
1231 } opj_dwd_decode_v_job_t;
1232
1233 static void opj_dwt_decode_v_func(void* user_data, opj_tls_t* tls)
1234 {
1235     OPJ_UINT32 j;
1236     opj_dwd_decode_v_job_t* job;
1237     (void)tls;
1238
1239     job = (opj_dwd_decode_v_job_t*)user_data;
1240     for (j = job->min_j; j + PARALLEL_COLS_53 <= job->max_j;
1241             j += PARALLEL_COLS_53) {
1242         opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_INT32)job->w,
1243                      PARALLEL_COLS_53);
1244     }
1245     if (j < job->max_j)
1246         opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_INT32)job->w,
1247                      (OPJ_INT32)(job->max_j - j));
1248
1249     opj_aligned_free(job->v.mem);
1250     opj_free(job);
1251 }
1252
1253
1254 /* <summary>                            */
1255 /* Inverse wavelet transform in 2-D.    */
1256 /* </summary>                           */
1257 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
1258                                     opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres)
1259 {
1260     opj_dwt_t h;
1261     opj_dwt_t v;
1262
1263     opj_tcd_resolution_t* tr = tilec->resolutions;
1264
1265     OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
1266                                  tr->x0);  /* width of the resolution level computed */
1267     OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
1268                                  tr->y0);  /* height of the resolution level computed */
1269
1270     OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
1271     size_t h_mem_size;
1272     int num_threads;
1273
1274     if (numres == 1U) {
1275         return OPJ_TRUE;
1276     }
1277     num_threads = opj_thread_pool_get_thread_count(tp);
1278     h_mem_size = opj_dwt_max_resolution(tr, numres);
1279     /* overflow check */
1280     if (h_mem_size > (SIZE_MAX / PARALLEL_COLS_53 / sizeof(OPJ_INT32))) {
1281         /* FIXME event manager error callback */
1282         return OPJ_FALSE;
1283     }
1284     /* We need PARALLEL_COLS_53 times the height of the array, */
1285     /* since for the vertical pass */
1286     /* we process PARALLEL_COLS_53 columns at a time */
1287     h_mem_size *= PARALLEL_COLS_53 * sizeof(OPJ_INT32);
1288     h.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
1289     if (! h.mem) {
1290         /* FIXME event manager error callback */
1291         return OPJ_FALSE;
1292     }
1293
1294     v.mem = h.mem;
1295
1296     while (--numres) {
1297         OPJ_INT32 * OPJ_RESTRICT tiledp = tilec->data;
1298         OPJ_UINT32 j;
1299
1300         ++tr;
1301         h.sn = (OPJ_INT32)rw;
1302         v.sn = (OPJ_INT32)rh;
1303
1304         rw = (OPJ_UINT32)(tr->x1 - tr->x0);
1305         rh = (OPJ_UINT32)(tr->y1 - tr->y0);
1306
1307         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
1308         h.cas = tr->x0 % 2;
1309
1310         if (num_threads <= 1 || rh <= 1) {
1311             for (j = 0; j < rh; ++j) {
1312                 opj_idwt53_h(&h, &tiledp[j * w]);
1313             }
1314         } else {
1315             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1316             OPJ_UINT32 step_j;
1317
1318             if (rh < num_jobs) {
1319                 num_jobs = rh;
1320             }
1321             step_j = (rh / num_jobs);
1322
1323             for (j = 0; j < num_jobs; j++) {
1324                 opj_dwd_decode_h_job_t* job;
1325
1326                 job = (opj_dwd_decode_h_job_t*) opj_malloc(sizeof(opj_dwd_decode_h_job_t));
1327                 if (!job) {
1328                     /* It would be nice to fallback to single thread case, but */
1329                     /* unfortunately some jobs may be launched and have modified */
1330                     /* tiledp, so it is not practical to recover from that error */
1331                     /* FIXME event manager error callback */
1332                     opj_thread_pool_wait_completion(tp, 0);
1333                     opj_aligned_free(h.mem);
1334                     return OPJ_FALSE;
1335                 }
1336                 job->h = h;
1337                 job->rw = rw;
1338                 job->w = w;
1339                 job->tiledp = tiledp;
1340                 job->min_j = j * step_j;
1341                 job->max_j = (j + 1U) * step_j; /* this can overflow */
1342                 if (j == (num_jobs - 1U)) {  /* this will take care of the overflow */
1343                     job->max_j = rh;
1344                 }
1345                 job->h.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
1346                 if (!job->h.mem) {
1347                     /* FIXME event manager error callback */
1348                     opj_thread_pool_wait_completion(tp, 0);
1349                     opj_free(job);
1350                     opj_aligned_free(h.mem);
1351                     return OPJ_FALSE;
1352                 }
1353                 opj_thread_pool_submit_job(tp, opj_dwt_decode_h_func, job);
1354             }
1355             opj_thread_pool_wait_completion(tp, 0);
1356         }
1357
1358         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
1359         v.cas = tr->y0 % 2;
1360
1361         if (num_threads <= 1 || rw <= 1) {
1362             for (j = 0; j + PARALLEL_COLS_53 <= rw;
1363                     j += PARALLEL_COLS_53) {
1364                 opj_idwt53_v(&v, &tiledp[j], (OPJ_INT32)w, PARALLEL_COLS_53);
1365             }
1366             if (j < rw) {
1367                 opj_idwt53_v(&v, &tiledp[j], (OPJ_INT32)w, (OPJ_INT32)(rw - j));
1368             }
1369         } else {
1370             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1371             OPJ_UINT32 step_j;
1372
1373             if (rw < num_jobs) {
1374                 num_jobs = rw;
1375             }
1376             step_j = (rw / num_jobs);
1377
1378             for (j = 0; j < num_jobs; j++) {
1379                 opj_dwd_decode_v_job_t* job;
1380
1381                 job = (opj_dwd_decode_v_job_t*) opj_malloc(sizeof(opj_dwd_decode_v_job_t));
1382                 if (!job) {
1383                     /* It would be nice to fallback to single thread case, but */
1384                     /* unfortunately some jobs may be launched and have modified */
1385                     /* tiledp, so it is not practical to recover from that error */
1386                     /* FIXME event manager error callback */
1387                     opj_thread_pool_wait_completion(tp, 0);
1388                     opj_aligned_free(v.mem);
1389                     return OPJ_FALSE;
1390                 }
1391                 job->v = v;
1392                 job->rh = rh;
1393                 job->w = w;
1394                 job->tiledp = tiledp;
1395                 job->min_j = j * step_j;
1396                 job->max_j = (j + 1U) * step_j; /* this can overflow */
1397                 if (j == (num_jobs - 1U)) {  /* this will take care of the overflow */
1398                     job->max_j = rw;
1399                 }
1400                 job->v.mem = (OPJ_INT32*)opj_aligned_malloc(h_mem_size);
1401                 if (!job->v.mem) {
1402                     /* FIXME event manager error callback */
1403                     opj_thread_pool_wait_completion(tp, 0);
1404                     opj_free(job);
1405                     opj_aligned_free(v.mem);
1406                     return OPJ_FALSE;
1407                 }
1408                 opj_thread_pool_submit_job(tp, opj_dwt_decode_v_func, job);
1409             }
1410             opj_thread_pool_wait_completion(tp, 0);
1411         }
1412     }
1413     opj_aligned_free(h.mem);
1414     return OPJ_TRUE;
1415 }
1416
1417 static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT w,
1418                                    OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 size)
1419 {
1420     OPJ_FLOAT32* OPJ_RESTRICT bi = (OPJ_FLOAT32*)(w->wavelet + w->cas);
1421     OPJ_INT32 count = w->sn;
1422     OPJ_INT32 i, k;
1423
1424     for (k = 0; k < 2; ++k) {
1425         if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 &&
1426                 ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
1427             /* Fast code path */
1428             for (i = 0; i < count; ++i) {
1429                 OPJ_INT32 j = i;
1430                 bi[i * 8    ] = a[j];
1431                 j += x;
1432                 bi[i * 8 + 1] = a[j];
1433                 j += x;
1434                 bi[i * 8 + 2] = a[j];
1435                 j += x;
1436                 bi[i * 8 + 3] = a[j];
1437             }
1438         } else {
1439             /* Slow code path */
1440             for (i = 0; i < count; ++i) {
1441                 OPJ_INT32 j = i;
1442                 bi[i * 8    ] = a[j];
1443                 j += x;
1444                 if (j >= size) {
1445                     continue;
1446                 }
1447                 bi[i * 8 + 1] = a[j];
1448                 j += x;
1449                 if (j >= size) {
1450                     continue;
1451                 }
1452                 bi[i * 8 + 2] = a[j];
1453                 j += x;
1454                 if (j >= size) {
1455                     continue;
1456                 }
1457                 bi[i * 8 + 3] = a[j]; /* This one*/
1458             }
1459         }
1460
1461         bi = (OPJ_FLOAT32*)(w->wavelet + 1 - w->cas);
1462         a += w->sn;
1463         size -= w->sn;
1464         count = w->dn;
1465     }
1466 }
1467
1468 static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT v,
1469                                    OPJ_FLOAT32* OPJ_RESTRICT a, OPJ_INT32 x, OPJ_INT32 nb_elts_read)
1470 {
1471     opj_v4_t* OPJ_RESTRICT bi = v->wavelet + v->cas;
1472     OPJ_INT32 i;
1473
1474     for (i = 0; i < v->sn; ++i) {
1475         memcpy(&bi[i * 2], &a[i * x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
1476     }
1477
1478     a += v->sn * x;
1479     bi = v->wavelet + 1 - v->cas;
1480
1481     for (i = 0; i < v->dn; ++i) {
1482         memcpy(&bi[i * 2], &a[i * x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32));
1483     }
1484 }
1485
1486 #ifdef __SSE__
1487
1488 static void opj_v4dwt_decode_step1_sse(opj_v4_t* w, OPJ_INT32 count,
1489                                        const __m128 c)
1490 {
1491     __m128* OPJ_RESTRICT vw = (__m128*) w;
1492     OPJ_INT32 i;
1493     /* 4x unrolled loop */
1494     for (i = 0; i < count >> 2; ++i) {
1495         *vw = _mm_mul_ps(*vw, c);
1496         vw += 2;
1497         *vw = _mm_mul_ps(*vw, c);
1498         vw += 2;
1499         *vw = _mm_mul_ps(*vw, c);
1500         vw += 2;
1501         *vw = _mm_mul_ps(*vw, c);
1502         vw += 2;
1503     }
1504     count &= 3;
1505     for (i = 0; i < count; ++i) {
1506         *vw = _mm_mul_ps(*vw, c);
1507         vw += 2;
1508     }
1509 }
1510
1511 void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k,
1512                                 OPJ_INT32 m, __m128 c)
1513 {
1514     __m128* OPJ_RESTRICT vl = (__m128*) l;
1515     __m128* OPJ_RESTRICT vw = (__m128*) w;
1516     OPJ_INT32 i;
1517     __m128 tmp1, tmp2, tmp3;
1518     tmp1 = vl[0];
1519     for (i = 0; i < m; ++i) {
1520         tmp2 = vw[-1];
1521         tmp3 = vw[ 0];
1522         vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
1523         tmp1 = tmp3;
1524         vw += 2;
1525     }
1526     vl = vw - 2;
1527     if (m >= k) {
1528         return;
1529     }
1530     c = _mm_add_ps(c, c);
1531     c = _mm_mul_ps(c, vl[0]);
1532     for (; m < k; ++m) {
1533         __m128 tmp = vw[-1];
1534         vw[-1] = _mm_add_ps(tmp, c);
1535         vw += 2;
1536     }
1537 }
1538
1539 #else
1540
1541 static void opj_v4dwt_decode_step1(opj_v4_t* w, OPJ_INT32 count,
1542                                    const OPJ_FLOAT32 c)
1543 {
1544     OPJ_FLOAT32* OPJ_RESTRICT fw = (OPJ_FLOAT32*) w;
1545     OPJ_INT32 i;
1546     for (i = 0; i < count; ++i) {
1547         OPJ_FLOAT32 tmp1 = fw[i * 8    ];
1548         OPJ_FLOAT32 tmp2 = fw[i * 8 + 1];
1549         OPJ_FLOAT32 tmp3 = fw[i * 8 + 2];
1550         OPJ_FLOAT32 tmp4 = fw[i * 8 + 3];
1551         fw[i * 8    ] = tmp1 * c;
1552         fw[i * 8 + 1] = tmp2 * c;
1553         fw[i * 8 + 2] = tmp3 * c;
1554         fw[i * 8 + 3] = tmp4 * c;
1555     }
1556 }
1557
1558 static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w, OPJ_INT32 k,
1559                                    OPJ_INT32 m, OPJ_FLOAT32 c)
1560 {
1561     OPJ_FLOAT32* fl = (OPJ_FLOAT32*) l;
1562     OPJ_FLOAT32* fw = (OPJ_FLOAT32*) w;
1563     OPJ_INT32 i;
1564     for (i = 0; i < m; ++i) {
1565         OPJ_FLOAT32 tmp1_1 = fl[0];
1566         OPJ_FLOAT32 tmp1_2 = fl[1];
1567         OPJ_FLOAT32 tmp1_3 = fl[2];
1568         OPJ_FLOAT32 tmp1_4 = fl[3];
1569         OPJ_FLOAT32 tmp2_1 = fw[-4];
1570         OPJ_FLOAT32 tmp2_2 = fw[-3];
1571         OPJ_FLOAT32 tmp2_3 = fw[-2];
1572         OPJ_FLOAT32 tmp2_4 = fw[-1];
1573         OPJ_FLOAT32 tmp3_1 = fw[0];
1574         OPJ_FLOAT32 tmp3_2 = fw[1];
1575         OPJ_FLOAT32 tmp3_3 = fw[2];
1576         OPJ_FLOAT32 tmp3_4 = fw[3];
1577         fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
1578         fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
1579         fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
1580         fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
1581         fl = fw;
1582         fw += 8;
1583     }
1584     if (m < k) {
1585         OPJ_FLOAT32 c1;
1586         OPJ_FLOAT32 c2;
1587         OPJ_FLOAT32 c3;
1588         OPJ_FLOAT32 c4;
1589         c += c;
1590         c1 = fl[0] * c;
1591         c2 = fl[1] * c;
1592         c3 = fl[2] * c;
1593         c4 = fl[3] * c;
1594         for (; m < k; ++m) {
1595             OPJ_FLOAT32 tmp1 = fw[-4];
1596             OPJ_FLOAT32 tmp2 = fw[-3];
1597             OPJ_FLOAT32 tmp3 = fw[-2];
1598             OPJ_FLOAT32 tmp4 = fw[-1];
1599             fw[-4] = tmp1 + c1;
1600             fw[-3] = tmp2 + c2;
1601             fw[-2] = tmp3 + c3;
1602             fw[-1] = tmp4 + c4;
1603             fw += 8;
1604         }
1605     }
1606 }
1607
1608 #endif
1609
1610 /* <summary>                             */
1611 /* Inverse 9-7 wavelet transform in 1-D. */
1612 /* </summary>                            */
1613 static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt)
1614 {
1615     OPJ_INT32 a, b;
1616     if (dwt->cas == 0) {
1617         if (!((dwt->dn > 0) || (dwt->sn > 1))) {
1618             return;
1619         }
1620         a = 0;
1621         b = 1;
1622     } else {
1623         if (!((dwt->sn > 0) || (dwt->dn > 1))) {
1624             return;
1625         }
1626         a = 1;
1627         b = 0;
1628     }
1629 #ifdef __SSE__
1630     opj_v4dwt_decode_step1_sse(dwt->wavelet + a, dwt->sn, _mm_set1_ps(opj_K));
1631     opj_v4dwt_decode_step1_sse(dwt->wavelet + b, dwt->dn, _mm_set1_ps(opj_c13318));
1632     opj_v4dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1, dwt->sn,
1633                                opj_int_min(dwt->sn, dwt->dn - a), _mm_set1_ps(opj_dwt_delta));
1634     opj_v4dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1, dwt->dn,
1635                                opj_int_min(dwt->dn, dwt->sn - b), _mm_set1_ps(opj_dwt_gamma));
1636     opj_v4dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1, dwt->sn,
1637                                opj_int_min(dwt->sn, dwt->dn - a), _mm_set1_ps(opj_dwt_beta));
1638     opj_v4dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1, dwt->dn,
1639                                opj_int_min(dwt->dn, dwt->sn - b), _mm_set1_ps(opj_dwt_alpha));
1640 #else
1641     opj_v4dwt_decode_step1(dwt->wavelet + a, dwt->sn, opj_K);
1642     opj_v4dwt_decode_step1(dwt->wavelet + b, dwt->dn, opj_c13318);
1643     opj_v4dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1, dwt->sn,
1644                            opj_int_min(dwt->sn, dwt->dn - a), opj_dwt_delta);
1645     opj_v4dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1, dwt->dn,
1646                            opj_int_min(dwt->dn, dwt->sn - b), opj_dwt_gamma);
1647     opj_v4dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1, dwt->sn,
1648                            opj_int_min(dwt->sn, dwt->dn - a), opj_dwt_beta);
1649     opj_v4dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1, dwt->dn,
1650                            opj_int_min(dwt->dn, dwt->sn - b), opj_dwt_alpha);
1651 #endif
1652 }
1653
1654
1655 /* <summary>                             */
1656 /* Inverse 9-7 wavelet transform in 2-D. */
1657 /* </summary>                            */
1658 OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
1659                              OPJ_UINT32 numres)
1660 {
1661     opj_v4dwt_t h;
1662     opj_v4dwt_t v;
1663
1664     opj_tcd_resolution_t* res = tilec->resolutions;
1665
1666     OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 -
1667                                  res->x0);    /* width of the resolution level computed */
1668     OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 -
1669                                  res->y0);    /* height of the resolution level computed */
1670
1671     OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
1672
1673     size_t l_data_size;
1674
1675     l_data_size = opj_dwt_max_resolution(res, numres);
1676     /* overflow check */
1677     if (l_data_size > (SIZE_MAX - 5U)) {
1678         /* FIXME event manager error callback */
1679         return OPJ_FALSE;
1680     }
1681     l_data_size += 5U;
1682     /* overflow check */
1683     if (l_data_size > (SIZE_MAX / sizeof(opj_v4_t))) {
1684         /* FIXME event manager error callback */
1685         return OPJ_FALSE;
1686     }
1687     h.wavelet = (opj_v4_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v4_t));
1688     if (!h.wavelet) {
1689         /* FIXME event manager error callback */
1690         return OPJ_FALSE;
1691     }
1692     v.wavelet = h.wavelet;
1693
1694     while (--numres) {
1695         OPJ_FLOAT32 * OPJ_RESTRICT aj = (OPJ_FLOAT32*) tilec->data;
1696         OPJ_UINT32 bufsize = (OPJ_UINT32)((tilec->x1 - tilec->x0) *
1697                                           (tilec->y1 - tilec->y0));
1698         OPJ_INT32 j;
1699
1700         h.sn = (OPJ_INT32)rw;
1701         v.sn = (OPJ_INT32)rh;
1702
1703         ++res;
1704
1705         rw = (OPJ_UINT32)(res->x1 -
1706                           res->x0);   /* width of the resolution level computed */
1707         rh = (OPJ_UINT32)(res->y1 -
1708                           res->y0);   /* height of the resolution level computed */
1709
1710         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
1711         h.cas = res->x0 % 2;
1712
1713         for (j = (OPJ_INT32)rh; j > 3; j -= 4) {
1714             OPJ_INT32 k;
1715             opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
1716             opj_v4dwt_decode(&h);
1717
1718             for (k = (OPJ_INT32)rw; --k >= 0;) {
1719                 aj[k               ] = h.wavelet[k].f[0];
1720                 aj[k + (OPJ_INT32)w  ] = h.wavelet[k].f[1];
1721                 aj[k + (OPJ_INT32)w * 2] = h.wavelet[k].f[2];
1722                 aj[k + (OPJ_INT32)w * 3] = h.wavelet[k].f[3];
1723             }
1724
1725             aj += w * 4;
1726             bufsize -= w * 4;
1727         }
1728
1729         if (rh & 0x03) {
1730             OPJ_INT32 k;
1731             j = rh & 0x03;
1732             opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize);
1733             opj_v4dwt_decode(&h);
1734             for (k = (OPJ_INT32)rw; --k >= 0;) {
1735                 switch (j) {
1736                 case 3:
1737                     aj[k + (OPJ_INT32)w * 2] = h.wavelet[k].f[2];
1738                 /* FALLTHRU */
1739                 case 2:
1740                     aj[k + (OPJ_INT32)w  ] = h.wavelet[k].f[1];
1741                 /* FALLTHRU */
1742                 case 1:
1743                     aj[k               ] = h.wavelet[k].f[0];
1744                 }
1745             }
1746         }
1747
1748         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
1749         v.cas = res->y0 % 2;
1750
1751         aj = (OPJ_FLOAT32*) tilec->data;
1752         for (j = (OPJ_INT32)rw; j > 3; j -= 4) {
1753             OPJ_UINT32 k;
1754
1755             opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, 4);
1756             opj_v4dwt_decode(&v);
1757
1758             for (k = 0; k < rh; ++k) {
1759                 memcpy(&aj[k * w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
1760             }
1761             aj += 4;
1762         }
1763
1764         if (rw & 0x03) {
1765             OPJ_UINT32 k;
1766
1767             j = rw & 0x03;
1768
1769             opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, j);
1770             opj_v4dwt_decode(&v);
1771
1772             for (k = 0; k < rh; ++k) {
1773                 memcpy(&aj[k * w], &v.wavelet[k], (size_t)j * sizeof(OPJ_FLOAT32));
1774             }
1775         }
1776     }
1777
1778     opj_aligned_free(h.wavelet);
1779     return OPJ_TRUE;
1780 }