Avoid integer overflows in DWT. Fixes https://bugs.chromium.org/p/oss-fuzz/issues...
[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 #include <assert.h>
42
43 #define OPJ_SKIP_POISON
44 #include "opj_includes.h"
45
46 #ifdef __SSE__
47 #include <xmmintrin.h>
48 #endif
49 #ifdef __SSE2__
50 #include <emmintrin.h>
51 #endif
52 #ifdef __SSSE3__
53 #include <tmmintrin.h>
54 #endif
55 #ifdef __AVX2__
56 #include <immintrin.h>
57 #endif
58
59 #if defined(__GNUC__)
60 #pragma GCC poison malloc calloc realloc free
61 #endif
62
63 /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
64 /*@{*/
65
66 #define OPJ_WS(i) v->mem[(i)*2]
67 #define OPJ_WD(i) v->mem[(1+(i)*2)]
68
69 #ifdef __AVX2__
70 /** Number of int32 values in a AVX2 register */
71 #define VREG_INT_COUNT       8
72 #else
73 /** Number of int32 values in a SSE2 register */
74 #define VREG_INT_COUNT       4
75 #endif
76
77 /** Number of columns that we can process in parallel in the vertical pass */
78 #define PARALLEL_COLS_53     (2*VREG_INT_COUNT)
79
80 /** @name Local data structures */
81 /*@{*/
82
83 typedef struct dwt_local {
84     OPJ_INT32* mem;
85     OPJ_INT32 dn;   /* number of elements in high pass band */
86     OPJ_INT32 sn;   /* number of elements in low pass band */
87     OPJ_INT32 cas;  /* 0 = start on even coord, 1 = start on odd coord */
88 } opj_dwt_t;
89
90 #define NB_ELTS_V8  8
91
92 typedef union {
93     OPJ_FLOAT32 f[NB_ELTS_V8];
94 } opj_v8_t;
95
96 typedef struct v8dwt_local {
97     opj_v8_t*   wavelet ;
98     OPJ_INT32       dn ;  /* number of elements in high pass band */
99     OPJ_INT32       sn ;  /* number of elements in low pass band */
100     OPJ_INT32       cas ; /* 0 = start on even coord, 1 = start on odd coord */
101     OPJ_UINT32      win_l_x0; /* start coord in low pass band */
102     OPJ_UINT32      win_l_x1; /* end coord in low pass band */
103     OPJ_UINT32      win_h_x0; /* start coord in high pass band */
104     OPJ_UINT32      win_h_x1; /* end coord in high pass band */
105 } opj_v8dwt_t ;
106
107 /* From table F.4 from the standard */
108 static const OPJ_FLOAT32 opj_dwt_alpha =  -1.586134342f;
109 static const OPJ_FLOAT32 opj_dwt_beta  =  -0.052980118f;
110 static const OPJ_FLOAT32 opj_dwt_gamma = 0.882911075f;
111 static const OPJ_FLOAT32 opj_dwt_delta = 0.443506852f;
112
113 static const OPJ_FLOAT32 opj_K      = 1.230174105f;
114 static const OPJ_FLOAT32 opj_invK   = (OPJ_FLOAT32)(1.0 / 1.230174105);
115
116 /*@}*/
117
118 /** @name Local static functions */
119 /*@{*/
120
121 /**
122 Forward lazy transform (horizontal)
123 */
124 static void opj_dwt_deinterleave_h(const OPJ_INT32 * OPJ_RESTRICT a,
125                                    OPJ_INT32 * OPJ_RESTRICT b,
126                                    OPJ_INT32 dn,
127                                    OPJ_INT32 sn, OPJ_INT32 cas);
128
129 /**
130 Forward 9-7 wavelet transform in 1-D
131 */
132 static void opj_dwt_encode_1_real(void *a, OPJ_INT32 dn, OPJ_INT32 sn,
133                                   OPJ_INT32 cas);
134 /**
135 Explicit calculation of the Quantization Stepsizes
136 */
137 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
138                                     opj_stepsize_t *bandno_stepsize);
139 /**
140 Inverse wavelet transform in 2-D.
141 */
142 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
143                                     opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i);
144
145 static OPJ_BOOL opj_dwt_decode_partial_tile(
146     opj_tcd_tilecomp_t* tilec,
147     OPJ_UINT32 numres);
148
149 /* Forward transform, for the vertical pass, processing cols columns */
150 /* where cols <= NB_ELTS_V8 */
151 /* Where void* is a OPJ_INT32* for 5x3 and OPJ_FLOAT32* for 9x7 */
152 typedef void (*opj_encode_and_deinterleave_v_fnptr_type)(
153     void *array,
154     void *tmp,
155     OPJ_UINT32 height,
156     OPJ_BOOL even,
157     OPJ_UINT32 stride_width,
158     OPJ_UINT32 cols);
159
160 /* Where void* is a OPJ_INT32* for 5x3 and OPJ_FLOAT32* for 9x7 */
161 typedef void (*opj_encode_and_deinterleave_h_one_row_fnptr_type)(
162     void *row,
163     void *tmp,
164     OPJ_UINT32 width,
165     OPJ_BOOL even);
166
167 static OPJ_BOOL opj_dwt_encode_procedure(opj_thread_pool_t* tp,
168         opj_tcd_tilecomp_t * tilec,
169         opj_encode_and_deinterleave_v_fnptr_type p_encode_and_deinterleave_v,
170         opj_encode_and_deinterleave_h_one_row_fnptr_type
171         p_encode_and_deinterleave_h_one_row);
172
173 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
174         OPJ_UINT32 i);
175
176 /* <summary>                             */
177 /* Inverse 9-7 wavelet transform in 1-D. */
178 /* </summary>                            */
179
180 /*@}*/
181
182 /*@}*/
183
184 #define OPJ_S(i) a[(i)*2]
185 #define OPJ_D(i) a[(1+(i)*2)]
186 #define OPJ_S_(i) ((i)<0?OPJ_S(0):((i)>=sn?OPJ_S(sn-1):OPJ_S(i)))
187 #define OPJ_D_(i) ((i)<0?OPJ_D(0):((i)>=dn?OPJ_D(dn-1):OPJ_D(i)))
188 /* new */
189 #define OPJ_SS_(i) ((i)<0?OPJ_S(0):((i)>=dn?OPJ_S(dn-1):OPJ_S(i)))
190 #define OPJ_DD_(i) ((i)<0?OPJ_D(0):((i)>=sn?OPJ_D(sn-1):OPJ_D(i)))
191
192 /* <summary>                                                              */
193 /* This table contains the norms of the 5-3 wavelets for different bands. */
194 /* </summary>                                                             */
195 /* FIXME! the array should really be extended up to 33 resolution levels */
196 /* See https://github.com/uclouvain/openjpeg/issues/493 */
197 static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
198     {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
199     {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
200     {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
201     {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
202 };
203
204 /* <summary>                                                              */
205 /* This table contains the norms of the 9-7 wavelets for different bands. */
206 /* </summary>                                                             */
207 /* FIXME! the array should really be extended up to 33 resolution levels */
208 /* See https://github.com/uclouvain/openjpeg/issues/493 */
209 static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
210     {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
211     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
212     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
213     {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
214 };
215
216 /*
217 ==========================================================
218    local functions
219 ==========================================================
220 */
221
222 /* <summary>                             */
223 /* Forward lazy transform (horizontal).  */
224 /* </summary>                            */
225 static void opj_dwt_deinterleave_h(const OPJ_INT32 * OPJ_RESTRICT a,
226                                    OPJ_INT32 * OPJ_RESTRICT b,
227                                    OPJ_INT32 dn,
228                                    OPJ_INT32 sn, OPJ_INT32 cas)
229 {
230     OPJ_INT32 i;
231     OPJ_INT32 * OPJ_RESTRICT l_dest = b;
232     const OPJ_INT32 * OPJ_RESTRICT l_src = a + cas;
233
234     for (i = 0; i < sn; ++i) {
235         *l_dest++ = *l_src;
236         l_src += 2;
237     }
238
239     l_dest = b + sn;
240     l_src = a + 1 - cas;
241
242     for (i = 0; i < dn; ++i)  {
243         *l_dest++ = *l_src;
244         l_src += 2;
245     }
246 }
247
248 #ifdef STANDARD_SLOW_VERSION
249 /* <summary>                             */
250 /* Inverse lazy transform (horizontal).  */
251 /* </summary>                            */
252 static void opj_dwt_interleave_h(const opj_dwt_t* h, OPJ_INT32 *a)
253 {
254     const OPJ_INT32 *ai = a;
255     OPJ_INT32 *bi = h->mem + h->cas;
256     OPJ_INT32  i    = h->sn;
257     while (i--) {
258         *bi = *(ai++);
259         bi += 2;
260     }
261     ai  = a + h->sn;
262     bi  = h->mem + 1 - h->cas;
263     i   = h->dn ;
264     while (i--) {
265         *bi = *(ai++);
266         bi += 2;
267     }
268 }
269
270 /* <summary>                             */
271 /* Inverse lazy transform (vertical).    */
272 /* </summary>                            */
273 static void opj_dwt_interleave_v(const opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x)
274 {
275     const OPJ_INT32 *ai = a;
276     OPJ_INT32 *bi = v->mem + v->cas;
277     OPJ_INT32  i = v->sn;
278     while (i--) {
279         *bi = *ai;
280         bi += 2;
281         ai += x;
282     }
283     ai = a + (v->sn * (OPJ_SIZE_T)x);
284     bi = v->mem + 1 - v->cas;
285     i = v->dn ;
286     while (i--) {
287         *bi = *ai;
288         bi += 2;
289         ai += x;
290     }
291 }
292
293 #endif /* STANDARD_SLOW_VERSION */
294
295 #ifdef STANDARD_SLOW_VERSION
296 /* <summary>                            */
297 /* Inverse 5-3 wavelet transform in 1-D. */
298 /* </summary>                           */
299 static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
300                               OPJ_INT32 cas)
301 {
302     OPJ_INT32 i;
303
304     if (!cas) {
305         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
306             for (i = 0; i < sn; i++) {
307                 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
308             }
309             for (i = 0; i < dn; i++) {
310                 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
311             }
312         }
313     } else {
314         if (!sn  && dn == 1) {        /* NEW :  CASE ONE ELEMENT */
315             OPJ_S(0) /= 2;
316         } else {
317             for (i = 0; i < sn; i++) {
318                 OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
319             }
320             for (i = 0; i < dn; i++) {
321                 OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
322             }
323         }
324     }
325 }
326
327 static void opj_dwt_decode_1(const opj_dwt_t *v)
328 {
329     opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
330 }
331
332 #endif /* STANDARD_SLOW_VERSION */
333
334 #if !defined(STANDARD_SLOW_VERSION)
335 static void  opj_idwt53_h_cas0(OPJ_INT32* tmp,
336                                const OPJ_INT32 sn,
337                                const OPJ_INT32 len,
338                                OPJ_INT32* tiledp)
339 {
340     OPJ_INT32 i, j;
341     const OPJ_INT32* in_even = &tiledp[0];
342     const OPJ_INT32* in_odd = &tiledp[sn];
343
344 #ifdef TWO_PASS_VERSION
345     /* For documentation purpose: performs lifting in two iterations, */
346     /* but without explicit interleaving */
347
348     assert(len > 1);
349
350     /* Even */
351     tmp[0] = in_even[0] - ((in_odd[0] + 1) >> 1);
352     for (i = 2, j = 0; i <= len - 2; i += 2, j++) {
353         tmp[i] = in_even[j + 1] - ((in_odd[j] + in_odd[j + 1] + 2) >> 2);
354     }
355     if (len & 1) { /* if len is odd */
356         tmp[len - 1] = in_even[(len - 1) / 2] - ((in_odd[(len - 2) / 2] + 1) >> 1);
357     }
358
359     /* Odd */
360     for (i = 1, j = 0; i < len - 1; i += 2, j++) {
361         tmp[i] = in_odd[j] + ((tmp[i - 1] + tmp[i + 1]) >> 1);
362     }
363     if (!(len & 1)) { /* if len is even */
364         tmp[len - 1] = in_odd[(len - 1) / 2] + tmp[len - 2];
365     }
366 #else
367     OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
368
369     assert(len > 1);
370
371     /* Improved version of the TWO_PASS_VERSION: */
372     /* Performs lifting in one single iteration. Saves memory */
373     /* accesses and explicit interleaving. */
374     s1n = in_even[0];
375     d1n = in_odd[0];
376     s0n = s1n - ((d1n + 1) >> 1);
377
378     for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
379         d1c = d1n;
380         s0c = s0n;
381
382         s1n = in_even[j];
383         d1n = in_odd[j];
384
385         s0n = s1n - ((d1c + d1n + 2) >> 2);
386
387         tmp[i  ] = s0c;
388         tmp[i + 1] = opj_int_add_no_overflow(d1c, opj_int_add_no_overflow(s0c,
389                                              s0n) >> 1);
390     }
391
392     tmp[i] = s0n;
393
394     if (len & 1) {
395         tmp[len - 1] = in_even[(len - 1) / 2] - ((d1n + 1) >> 1);
396         tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
397     } else {
398         tmp[len - 1] = d1n + s0n;
399     }
400 #endif
401     memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
402 }
403
404 static void  opj_idwt53_h_cas1(OPJ_INT32* tmp,
405                                const OPJ_INT32 sn,
406                                const OPJ_INT32 len,
407                                OPJ_INT32* tiledp)
408 {
409     OPJ_INT32 i, j;
410     const OPJ_INT32* in_even = &tiledp[sn];
411     const OPJ_INT32* in_odd = &tiledp[0];
412
413 #ifdef TWO_PASS_VERSION
414     /* For documentation purpose: performs lifting in two iterations, */
415     /* but without explicit interleaving */
416
417     assert(len > 2);
418
419     /* Odd */
420     for (i = 1, j = 0; i < len - 1; i += 2, j++) {
421         tmp[i] = in_odd[j] - ((in_even[j] + in_even[j + 1] + 2) >> 2);
422     }
423     if (!(len & 1)) {
424         tmp[len - 1] = in_odd[len / 2 - 1] - ((in_even[len / 2 - 1] + 1) >> 1);
425     }
426
427     /* Even */
428     tmp[0] = in_even[0] + tmp[1];
429     for (i = 2, j = 1; i < len - 1; i += 2, j++) {
430         tmp[i] = in_even[j] + ((tmp[i + 1] + tmp[i - 1]) >> 1);
431     }
432     if (len & 1) {
433         tmp[len - 1] = in_even[len / 2] + tmp[len - 2];
434     }
435 #else
436     OPJ_INT32 s1, s2, dc, dn;
437
438     assert(len > 2);
439
440     /* Improved version of the TWO_PASS_VERSION: */
441     /* Performs lifting in one single iteration. Saves memory */
442     /* accesses and explicit interleaving. */
443
444     s1 = in_even[1];
445     dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
446     tmp[0] = in_even[0] + dc;
447
448     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
449
450         s2 = in_even[j + 1];
451
452         dn = in_odd[j] - ((s1 + s2 + 2) >> 2);
453         tmp[i  ] = dc;
454         tmp[i + 1] = opj_int_add_no_overflow(s1, opj_int_add_no_overflow(dn, dc) >> 1);
455
456         dc = dn;
457         s1 = s2;
458     }
459
460     tmp[i] = dc;
461
462     if (!(len & 1)) {
463         dn = in_odd[len / 2 - 1] - ((s1 + 1) >> 1);
464         tmp[len - 2] = s1 + ((dn + dc) >> 1);
465         tmp[len - 1] = dn;
466     } else {
467         tmp[len - 1] = s1 + dc;
468     }
469 #endif
470     memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
471 }
472
473
474 #endif /* !defined(STANDARD_SLOW_VERSION) */
475
476 /* <summary>                            */
477 /* Inverse 5-3 wavelet transform in 1-D for one row. */
478 /* </summary>                           */
479 /* Performs interleave, inverse wavelet transform and copy back to buffer */
480 static void opj_idwt53_h(const opj_dwt_t *dwt,
481                          OPJ_INT32* tiledp)
482 {
483 #ifdef STANDARD_SLOW_VERSION
484     /* For documentation purpose */
485     opj_dwt_interleave_h(dwt, tiledp);
486     opj_dwt_decode_1(dwt);
487     memcpy(tiledp, dwt->mem, (OPJ_UINT32)(dwt->sn + dwt->dn) * sizeof(OPJ_INT32));
488 #else
489     const OPJ_INT32 sn = dwt->sn;
490     const OPJ_INT32 len = sn + dwt->dn;
491     if (dwt->cas == 0) { /* Left-most sample is on even coordinate */
492         if (len > 1) {
493             opj_idwt53_h_cas0(dwt->mem, sn, len, tiledp);
494         } else {
495             /* Unmodified value */
496         }
497     } else { /* Left-most sample is on odd coordinate */
498         if (len == 1) {
499             tiledp[0] /= 2;
500         } else if (len == 2) {
501             OPJ_INT32* out = dwt->mem;
502             const OPJ_INT32* in_even = &tiledp[sn];
503             const OPJ_INT32* in_odd = &tiledp[0];
504             out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
505             out[0] = in_even[0] + out[1];
506             memcpy(tiledp, dwt->mem, (OPJ_UINT32)len * sizeof(OPJ_INT32));
507         } else if (len > 2) {
508             opj_idwt53_h_cas1(dwt->mem, sn, len, tiledp);
509         }
510     }
511 #endif
512 }
513
514 #if (defined(__SSE2__) || defined(__AVX2__)) && !defined(STANDARD_SLOW_VERSION)
515
516 /* Conveniency macros to improve the readabilty of the formulas */
517 #if __AVX2__
518 #define VREG        __m256i
519 #define LOAD_CST(x) _mm256_set1_epi32(x)
520 #define LOAD(x)     _mm256_load_si256((const VREG*)(x))
521 #define LOADU(x)    _mm256_loadu_si256((const VREG*)(x))
522 #define STORE(x,y)  _mm256_store_si256((VREG*)(x),(y))
523 #define STOREU(x,y) _mm256_storeu_si256((VREG*)(x),(y))
524 #define ADD(x,y)    _mm256_add_epi32((x),(y))
525 #define SUB(x,y)    _mm256_sub_epi32((x),(y))
526 #define SAR(x,y)    _mm256_srai_epi32((x),(y))
527 #else
528 #define VREG        __m128i
529 #define LOAD_CST(x) _mm_set1_epi32(x)
530 #define LOAD(x)     _mm_load_si128((const VREG*)(x))
531 #define LOADU(x)    _mm_loadu_si128((const VREG*)(x))
532 #define STORE(x,y)  _mm_store_si128((VREG*)(x),(y))
533 #define STOREU(x,y) _mm_storeu_si128((VREG*)(x),(y))
534 #define ADD(x,y)    _mm_add_epi32((x),(y))
535 #define SUB(x,y)    _mm_sub_epi32((x),(y))
536 #define SAR(x,y)    _mm_srai_epi32((x),(y))
537 #endif
538 #define ADD3(x,y,z) ADD(ADD(x,y),z)
539
540 static
541 void opj_idwt53_v_final_memcpy(OPJ_INT32* tiledp_col,
542                                const OPJ_INT32* tmp,
543                                OPJ_INT32 len,
544                                OPJ_SIZE_T stride)
545 {
546     OPJ_INT32 i;
547     for (i = 0; i < len; ++i) {
548         /* A memcpy(&tiledp_col[i * stride + 0],
549                     &tmp[PARALLEL_COLS_53 * i + 0],
550                     PARALLEL_COLS_53 * sizeof(OPJ_INT32))
551            would do but would be a tiny bit slower.
552            We can take here advantage of our knowledge of alignment */
553         STOREU(&tiledp_col[(OPJ_SIZE_T)i * stride + 0],
554                LOAD(&tmp[PARALLEL_COLS_53 * i + 0]));
555         STOREU(&tiledp_col[(OPJ_SIZE_T)i * stride + VREG_INT_COUNT],
556                LOAD(&tmp[PARALLEL_COLS_53 * i + VREG_INT_COUNT]));
557     }
558 }
559
560 /** Vertical inverse 5x3 wavelet transform for 8 columns in SSE2, or
561  * 16 in AVX2, when top-most pixel is on even coordinate */
562 static void opj_idwt53_v_cas0_mcols_SSE2_OR_AVX2(
563     OPJ_INT32* tmp,
564     const OPJ_INT32 sn,
565     const OPJ_INT32 len,
566     OPJ_INT32* tiledp_col,
567     const OPJ_SIZE_T stride)
568 {
569     const OPJ_INT32* in_even = &tiledp_col[0];
570     const OPJ_INT32* in_odd = &tiledp_col[(OPJ_SIZE_T)sn * stride];
571
572     OPJ_INT32 i;
573     OPJ_SIZE_T j;
574     VREG d1c_0, d1n_0, s1n_0, s0c_0, s0n_0;
575     VREG d1c_1, d1n_1, s1n_1, s0c_1, s0n_1;
576     const VREG two = LOAD_CST(2);
577
578     assert(len > 1);
579 #if __AVX2__
580     assert(PARALLEL_COLS_53 == 16);
581     assert(VREG_INT_COUNT == 8);
582 #else
583     assert(PARALLEL_COLS_53 == 8);
584     assert(VREG_INT_COUNT == 4);
585 #endif
586
587     /* Note: loads of input even/odd values must be done in a unaligned */
588     /* fashion. But stores in tmp can be done with aligned store, since */
589     /* the temporary buffer is properly aligned */
590     assert((OPJ_SIZE_T)tmp % (sizeof(OPJ_INT32) * VREG_INT_COUNT) == 0);
591
592     s1n_0 = LOADU(in_even + 0);
593     s1n_1 = LOADU(in_even + VREG_INT_COUNT);
594     d1n_0 = LOADU(in_odd);
595     d1n_1 = LOADU(in_odd + VREG_INT_COUNT);
596
597     /* s0n = s1n - ((d1n + 1) >> 1); <==> */
598     /* s0n = s1n - ((d1n + d1n + 2) >> 2); */
599     s0n_0 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
600     s0n_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
601
602     for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
603         d1c_0 = d1n_0;
604         s0c_0 = s0n_0;
605         d1c_1 = d1n_1;
606         s0c_1 = s0n_1;
607
608         s1n_0 = LOADU(in_even + j * stride);
609         s1n_1 = LOADU(in_even + j * stride + VREG_INT_COUNT);
610         d1n_0 = LOADU(in_odd + j * stride);
611         d1n_1 = LOADU(in_odd + j * stride + VREG_INT_COUNT);
612
613         /*s0n = s1n - ((d1c + d1n + 2) >> 2);*/
614         s0n_0 = SUB(s1n_0, SAR(ADD3(d1c_0, d1n_0, two), 2));
615         s0n_1 = SUB(s1n_1, SAR(ADD3(d1c_1, d1n_1, two), 2));
616
617         STORE(tmp + PARALLEL_COLS_53 * (i + 0), s0c_0);
618         STORE(tmp + PARALLEL_COLS_53 * (i + 0) + VREG_INT_COUNT, s0c_1);
619
620         /* d1c + ((s0c + s0n) >> 1) */
621         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
622               ADD(d1c_0, SAR(ADD(s0c_0, s0n_0), 1)));
623         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + VREG_INT_COUNT,
624               ADD(d1c_1, SAR(ADD(s0c_1, s0n_1), 1)));
625     }
626
627     STORE(tmp + PARALLEL_COLS_53 * (i + 0) + 0, s0n_0);
628     STORE(tmp + PARALLEL_COLS_53 * (i + 0) + VREG_INT_COUNT, s0n_1);
629
630     if (len & 1) {
631         VREG tmp_len_minus_1;
632         s1n_0 = LOADU(in_even + (OPJ_SIZE_T)((len - 1) / 2) * stride);
633         /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
634         tmp_len_minus_1 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
635         STORE(tmp + PARALLEL_COLS_53 * (len - 1), tmp_len_minus_1);
636         /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
637         STORE(tmp + PARALLEL_COLS_53 * (len - 2),
638               ADD(d1n_0, SAR(ADD(s0n_0, tmp_len_minus_1), 1)));
639
640         s1n_1 = LOADU(in_even + (OPJ_SIZE_T)((len - 1) / 2) * stride + VREG_INT_COUNT);
641         /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
642         tmp_len_minus_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
643         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
644               tmp_len_minus_1);
645         /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
646         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + VREG_INT_COUNT,
647               ADD(d1n_1, SAR(ADD(s0n_1, tmp_len_minus_1), 1)));
648
649
650     } else {
651         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0,
652               ADD(d1n_0, s0n_0));
653         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
654               ADD(d1n_1, s0n_1));
655     }
656
657     opj_idwt53_v_final_memcpy(tiledp_col, tmp, len, stride);
658 }
659
660
661 /** Vertical inverse 5x3 wavelet transform for 8 columns in SSE2, or
662  * 16 in AVX2, when top-most pixel is on odd coordinate */
663 static void opj_idwt53_v_cas1_mcols_SSE2_OR_AVX2(
664     OPJ_INT32* tmp,
665     const OPJ_INT32 sn,
666     const OPJ_INT32 len,
667     OPJ_INT32* tiledp_col,
668     const OPJ_SIZE_T stride)
669 {
670     OPJ_INT32 i;
671     OPJ_SIZE_T j;
672
673     VREG s1_0, s2_0, dc_0, dn_0;
674     VREG s1_1, s2_1, dc_1, dn_1;
675     const VREG two = LOAD_CST(2);
676
677     const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
678     const OPJ_INT32* in_odd = &tiledp_col[0];
679
680     assert(len > 2);
681 #if __AVX2__
682     assert(PARALLEL_COLS_53 == 16);
683     assert(VREG_INT_COUNT == 8);
684 #else
685     assert(PARALLEL_COLS_53 == 8);
686     assert(VREG_INT_COUNT == 4);
687 #endif
688
689     /* Note: loads of input even/odd values must be done in a unaligned */
690     /* fashion. But stores in tmp can be done with aligned store, since */
691     /* the temporary buffer is properly aligned */
692     assert((OPJ_SIZE_T)tmp % (sizeof(OPJ_INT32) * VREG_INT_COUNT) == 0);
693
694     s1_0 = LOADU(in_even + stride);
695     /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
696     dc_0 = SUB(LOADU(in_odd + 0),
697                SAR(ADD3(LOADU(in_even + 0), s1_0, two), 2));
698     STORE(tmp + PARALLEL_COLS_53 * 0, ADD(LOADU(in_even + 0), dc_0));
699
700     s1_1 = LOADU(in_even + stride + VREG_INT_COUNT);
701     /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
702     dc_1 = SUB(LOADU(in_odd + VREG_INT_COUNT),
703                SAR(ADD3(LOADU(in_even + VREG_INT_COUNT), s1_1, two), 2));
704     STORE(tmp + PARALLEL_COLS_53 * 0 + VREG_INT_COUNT,
705           ADD(LOADU(in_even + VREG_INT_COUNT), dc_1));
706
707     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
708
709         s2_0 = LOADU(in_even + (j + 1) * stride);
710         s2_1 = LOADU(in_even + (j + 1) * stride + VREG_INT_COUNT);
711
712         /* dn = in_odd[j * stride] - ((s1 + s2 + 2) >> 2); */
713         dn_0 = SUB(LOADU(in_odd + j * stride),
714                    SAR(ADD3(s1_0, s2_0, two), 2));
715         dn_1 = SUB(LOADU(in_odd + j * stride + VREG_INT_COUNT),
716                    SAR(ADD3(s1_1, s2_1, two), 2));
717
718         STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
719         STORE(tmp + PARALLEL_COLS_53 * i + VREG_INT_COUNT, dc_1);
720
721         /* tmp[i + 1] = s1 + ((dn + dc) >> 1); */
722         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
723               ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
724         STORE(tmp + PARALLEL_COLS_53 * (i + 1) + VREG_INT_COUNT,
725               ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
726
727         dc_0 = dn_0;
728         s1_0 = s2_0;
729         dc_1 = dn_1;
730         s1_1 = s2_1;
731     }
732     STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
733     STORE(tmp + PARALLEL_COLS_53 * i + VREG_INT_COUNT, dc_1);
734
735     if (!(len & 1)) {
736         /*dn = in_odd[(len / 2 - 1) * stride] - ((s1 + 1) >> 1); */
737         dn_0 = SUB(LOADU(in_odd + (OPJ_SIZE_T)(len / 2 - 1) * stride),
738                    SAR(ADD3(s1_0, s1_0, two), 2));
739         dn_1 = SUB(LOADU(in_odd + (OPJ_SIZE_T)(len / 2 - 1) * stride + VREG_INT_COUNT),
740                    SAR(ADD3(s1_1, s1_1, two), 2));
741
742         /* tmp[len - 2] = s1 + ((dn + dc) >> 1); */
743         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + 0,
744               ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
745         STORE(tmp + PARALLEL_COLS_53 * (len - 2) + VREG_INT_COUNT,
746               ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
747
748         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, dn_0);
749         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT, dn_1);
750     } else {
751         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, ADD(s1_0, dc_0));
752         STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
753               ADD(s1_1, dc_1));
754     }
755
756     opj_idwt53_v_final_memcpy(tiledp_col, tmp, len, stride);
757 }
758
759 #undef VREG
760 #undef LOAD_CST
761 #undef LOADU
762 #undef LOAD
763 #undef STORE
764 #undef STOREU
765 #undef ADD
766 #undef ADD3
767 #undef SUB
768 #undef SAR
769
770 #endif /* (defined(__SSE2__) || defined(__AVX2__)) && !defined(STANDARD_SLOW_VERSION) */
771
772 #if !defined(STANDARD_SLOW_VERSION)
773 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
774  * pixel is on even coordinate */
775 static void opj_idwt3_v_cas0(OPJ_INT32* tmp,
776                              const OPJ_INT32 sn,
777                              const OPJ_INT32 len,
778                              OPJ_INT32* tiledp_col,
779                              const OPJ_SIZE_T stride)
780 {
781     OPJ_INT32 i, j;
782     OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
783
784     assert(len > 1);
785
786     /* Performs lifting in one single iteration. Saves memory */
787     /* accesses and explicit interleaving. */
788
789     s1n = tiledp_col[0];
790     d1n = tiledp_col[(OPJ_SIZE_T)sn * stride];
791     s0n = s1n - ((d1n + 1) >> 1);
792
793     for (i = 0, j = 0; i < (len - 3); i += 2, j++) {
794         d1c = d1n;
795         s0c = s0n;
796
797         s1n = tiledp_col[(OPJ_SIZE_T)(j + 1) * stride];
798         d1n = tiledp_col[(OPJ_SIZE_T)(sn + j + 1) * stride];
799
800         s0n = opj_int_sub_no_overflow(s1n,
801                                       opj_int_add_no_overflow(opj_int_add_no_overflow(d1c, d1n), 2) >> 2);
802
803         tmp[i  ] = s0c;
804         tmp[i + 1] = d1c + ((s0c + s0n) >> 1);
805     }
806
807     tmp[i] = s0n;
808
809     if (len & 1) {
810         tmp[len - 1] =
811             tiledp_col[(OPJ_SIZE_T)((len - 1) / 2) * stride] -
812             ((d1n + 1) >> 1);
813         tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
814     } else {
815         tmp[len - 1] = d1n + s0n;
816     }
817
818     for (i = 0; i < len; ++i) {
819         tiledp_col[(OPJ_SIZE_T)i * stride] = tmp[i];
820     }
821 }
822
823
824 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
825  * pixel is on odd coordinate */
826 static void opj_idwt3_v_cas1(OPJ_INT32* tmp,
827                              const OPJ_INT32 sn,
828                              const OPJ_INT32 len,
829                              OPJ_INT32* tiledp_col,
830                              const OPJ_SIZE_T stride)
831 {
832     OPJ_INT32 i, j;
833     OPJ_INT32 s1, s2, dc, dn;
834     const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
835     const OPJ_INT32* in_odd = &tiledp_col[0];
836
837     assert(len > 2);
838
839     /* Performs lifting in one single iteration. Saves memory */
840     /* accesses and explicit interleaving. */
841
842     s1 = in_even[stride];
843     dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
844     tmp[0] = in_even[0] + dc;
845     for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
846
847         s2 = in_even[(OPJ_SIZE_T)(j + 1) * stride];
848
849         dn = in_odd[(OPJ_SIZE_T)j * stride] - ((s1 + s2 + 2) >> 2);
850         tmp[i  ] = dc;
851         tmp[i + 1] = s1 + ((dn + dc) >> 1);
852
853         dc = dn;
854         s1 = s2;
855     }
856     tmp[i] = dc;
857     if (!(len & 1)) {
858         dn = in_odd[(OPJ_SIZE_T)(len / 2 - 1) * stride] - ((s1 + 1) >> 1);
859         tmp[len - 2] = s1 + ((dn + dc) >> 1);
860         tmp[len - 1] = dn;
861     } else {
862         tmp[len - 1] = s1 + dc;
863     }
864
865     for (i = 0; i < len; ++i) {
866         tiledp_col[(OPJ_SIZE_T)i * stride] = tmp[i];
867     }
868 }
869 #endif /* !defined(STANDARD_SLOW_VERSION) */
870
871 /* <summary>                            */
872 /* Inverse vertical 5-3 wavelet transform in 1-D for several columns. */
873 /* </summary>                           */
874 /* Performs interleave, inverse wavelet transform and copy back to buffer */
875 static void opj_idwt53_v(const opj_dwt_t *dwt,
876                          OPJ_INT32* tiledp_col,
877                          OPJ_SIZE_T stride,
878                          OPJ_INT32 nb_cols)
879 {
880 #ifdef STANDARD_SLOW_VERSION
881     /* For documentation purpose */
882     OPJ_INT32 k, c;
883     for (c = 0; c < nb_cols; c ++) {
884         opj_dwt_interleave_v(dwt, tiledp_col + c, stride);
885         opj_dwt_decode_1(dwt);
886         for (k = 0; k < dwt->sn + dwt->dn; ++k) {
887             tiledp_col[c + k * stride] = dwt->mem[k];
888         }
889     }
890 #else
891     const OPJ_INT32 sn = dwt->sn;
892     const OPJ_INT32 len = sn + dwt->dn;
893     if (dwt->cas == 0) {
894         /* If len == 1, unmodified value */
895
896 #if (defined(__SSE2__) || defined(__AVX2__))
897         if (len > 1 && nb_cols == PARALLEL_COLS_53) {
898             /* Same as below general case, except that thanks to SSE2/AVX2 */
899             /* we can efficiently process 8/16 columns in parallel */
900             opj_idwt53_v_cas0_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
901             return;
902         }
903 #endif
904         if (len > 1) {
905             OPJ_INT32 c;
906             for (c = 0; c < nb_cols; c++, tiledp_col++) {
907                 opj_idwt3_v_cas0(dwt->mem, sn, len, tiledp_col, stride);
908             }
909             return;
910         }
911     } else {
912         if (len == 1) {
913             OPJ_INT32 c;
914             for (c = 0; c < nb_cols; c++, tiledp_col++) {
915                 tiledp_col[0] /= 2;
916             }
917             return;
918         }
919
920         if (len == 2) {
921             OPJ_INT32 c;
922             OPJ_INT32* out = dwt->mem;
923             for (c = 0; c < nb_cols; c++, tiledp_col++) {
924                 OPJ_INT32 i;
925                 const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
926                 const OPJ_INT32* in_odd = &tiledp_col[0];
927
928                 out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
929                 out[0] = in_even[0] + out[1];
930
931                 for (i = 0; i < len; ++i) {
932                     tiledp_col[(OPJ_SIZE_T)i * stride] = out[i];
933                 }
934             }
935
936             return;
937         }
938
939 #if (defined(__SSE2__) || defined(__AVX2__))
940         if (len > 2 && nb_cols == PARALLEL_COLS_53) {
941             /* Same as below general case, except that thanks to SSE2/AVX2 */
942             /* we can efficiently process 8/16 columns in parallel */
943             opj_idwt53_v_cas1_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
944             return;
945         }
946 #endif
947         if (len > 2) {
948             OPJ_INT32 c;
949             for (c = 0; c < nb_cols; c++, tiledp_col++) {
950                 opj_idwt3_v_cas1(dwt->mem, sn, len, tiledp_col, stride);
951             }
952             return;
953         }
954     }
955 #endif
956 }
957
958 #if 0
959 static void opj_dwt_encode_step1(OPJ_FLOAT32* fw,
960                                  OPJ_UINT32 end,
961                                  const OPJ_FLOAT32 c)
962 {
963     OPJ_UINT32 i = 0;
964     for (; i < end; ++i) {
965         fw[0] *= c;
966         fw += 2;
967     }
968 }
969 #else
970 static void opj_dwt_encode_step1_combined(OPJ_FLOAT32* fw,
971         OPJ_UINT32 iters_c1,
972         OPJ_UINT32 iters_c2,
973         const OPJ_FLOAT32 c1,
974         const OPJ_FLOAT32 c2)
975 {
976     OPJ_UINT32 i = 0;
977     const OPJ_UINT32 iters_common =  opj_uint_min(iters_c1, iters_c2);
978     assert((((OPJ_SIZE_T)fw) & 0xf) == 0);
979     assert(opj_int_abs((OPJ_INT32)iters_c1 - (OPJ_INT32)iters_c2) <= 1);
980     for (; i + 3 < iters_common; i += 4) {
981 #ifdef __SSE__
982         const __m128 vcst = _mm_set_ps(c2, c1, c2, c1);
983         *(__m128*)fw = _mm_mul_ps(*(__m128*)fw, vcst);
984         *(__m128*)(fw + 4) = _mm_mul_ps(*(__m128*)(fw + 4), vcst);
985 #else
986         fw[0] *= c1;
987         fw[1] *= c2;
988         fw[2] *= c1;
989         fw[3] *= c2;
990         fw[4] *= c1;
991         fw[5] *= c2;
992         fw[6] *= c1;
993         fw[7] *= c2;
994 #endif
995         fw += 8;
996     }
997     for (; i < iters_common; i++) {
998         fw[0] *= c1;
999         fw[1] *= c2;
1000         fw += 2;
1001     }
1002     if (i < iters_c1) {
1003         fw[0] *= c1;
1004     } else if (i < iters_c2) {
1005         fw[1] *= c2;
1006     }
1007 }
1008
1009 #endif
1010
1011 static void opj_dwt_encode_step2(OPJ_FLOAT32* fl, OPJ_FLOAT32* fw,
1012                                  OPJ_UINT32 end,
1013                                  OPJ_UINT32 m,
1014                                  OPJ_FLOAT32 c)
1015 {
1016     OPJ_UINT32 i;
1017     OPJ_UINT32 imax = opj_uint_min(end, m);
1018     if (imax > 0) {
1019         fw[-1] += (fl[0] + fw[0]) * c;
1020         fw += 2;
1021         i = 1;
1022         for (; i + 3 < imax; i += 4) {
1023             fw[-1] += (fw[-2] + fw[0]) * c;
1024             fw[1] += (fw[0] + fw[2]) * c;
1025             fw[3] += (fw[2] + fw[4]) * c;
1026             fw[5] += (fw[4] + fw[6]) * c;
1027             fw += 8;
1028         }
1029         for (; i < imax; ++i) {
1030             fw[-1] += (fw[-2] + fw[0]) * c;
1031             fw += 2;
1032         }
1033     }
1034     if (m < end) {
1035         assert(m + 1 == end);
1036         fw[-1] += (2 * fw[-2]) * c;
1037     }
1038 }
1039
1040 static void opj_dwt_encode_1_real(void *aIn, OPJ_INT32 dn, OPJ_INT32 sn,
1041                                   OPJ_INT32 cas)
1042 {
1043     OPJ_FLOAT32* w = (OPJ_FLOAT32*)aIn;
1044     OPJ_INT32 a, b;
1045     assert(dn + sn > 1);
1046     if (cas == 0) {
1047         a = 0;
1048         b = 1;
1049     } else {
1050         a = 1;
1051         b = 0;
1052     }
1053     opj_dwt_encode_step2(w + a, w + b + 1,
1054                          (OPJ_UINT32)dn,
1055                          (OPJ_UINT32)opj_int_min(dn, sn - b),
1056                          opj_dwt_alpha);
1057     opj_dwt_encode_step2(w + b, w + a + 1,
1058                          (OPJ_UINT32)sn,
1059                          (OPJ_UINT32)opj_int_min(sn, dn - a),
1060                          opj_dwt_beta);
1061     opj_dwt_encode_step2(w + a, w + b + 1,
1062                          (OPJ_UINT32)dn,
1063                          (OPJ_UINT32)opj_int_min(dn, sn - b),
1064                          opj_dwt_gamma);
1065     opj_dwt_encode_step2(w + b, w + a + 1,
1066                          (OPJ_UINT32)sn,
1067                          (OPJ_UINT32)opj_int_min(sn, dn - a),
1068                          opj_dwt_delta);
1069 #if 0
1070     opj_dwt_encode_step1(w + b, (OPJ_UINT32)dn,
1071                          opj_K);
1072     opj_dwt_encode_step1(w + a, (OPJ_UINT32)sn,
1073                          opj_invK);
1074 #else
1075     if (a == 0) {
1076         opj_dwt_encode_step1_combined(w,
1077                                       (OPJ_UINT32)sn,
1078                                       (OPJ_UINT32)dn,
1079                                       opj_invK,
1080                                       opj_K);
1081     } else {
1082         opj_dwt_encode_step1_combined(w,
1083                                       (OPJ_UINT32)dn,
1084                                       (OPJ_UINT32)sn,
1085                                       opj_K,
1086                                       opj_invK);
1087     }
1088 #endif
1089 }
1090
1091 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
1092                                     opj_stepsize_t *bandno_stepsize)
1093 {
1094     OPJ_INT32 p, n;
1095     p = opj_int_floorlog2(stepsize) - 13;
1096     n = 11 - opj_int_floorlog2(stepsize);
1097     bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
1098     bandno_stepsize->expn = numbps - p;
1099 }
1100
1101 /*
1102 ==========================================================
1103    DWT interface
1104 ==========================================================
1105 */
1106
1107 /** Process one line for the horizontal pass of the 5x3 forward transform */
1108 static
1109 void opj_dwt_encode_and_deinterleave_h_one_row(void* rowIn,
1110         void* tmpIn,
1111         OPJ_UINT32 width,
1112         OPJ_BOOL even)
1113 {
1114     OPJ_INT32* OPJ_RESTRICT row = (OPJ_INT32*)rowIn;
1115     OPJ_INT32* OPJ_RESTRICT tmp = (OPJ_INT32*)tmpIn;
1116     const OPJ_INT32 sn = (OPJ_INT32)((width + (even ? 1 : 0)) >> 1);
1117     const OPJ_INT32 dn = (OPJ_INT32)(width - (OPJ_UINT32)sn);
1118
1119     if (even) {
1120         if (width > 1) {
1121             OPJ_INT32 i;
1122             for (i = 0; i < sn - 1; i++) {
1123                 tmp[sn + i] = row[2 * i + 1] - ((row[(i) * 2] + row[(i + 1) * 2]) >> 1);
1124             }
1125             if ((width % 2) == 0) {
1126                 tmp[sn + i] = row[2 * i + 1] - row[(i) * 2];
1127             }
1128             row[0] += (tmp[sn] + tmp[sn] + 2) >> 2;
1129             for (i = 1; i < dn; i++) {
1130                 row[i] = row[2 * i] + ((tmp[sn + (i - 1)] + tmp[sn + i] + 2) >> 2);
1131             }
1132             if ((width % 2) == 1) {
1133                 row[i] = row[2 * i] + ((tmp[sn + (i - 1)] + tmp[sn + (i - 1)] + 2) >> 2);
1134             }
1135             memcpy(row + sn, tmp + sn, (OPJ_SIZE_T)dn * sizeof(OPJ_INT32));
1136         }
1137     } else {
1138         if (width == 1) {
1139             row[0] *= 2;
1140         } else {
1141             OPJ_INT32 i;
1142             tmp[sn + 0] = row[0] - row[1];
1143             for (i = 1; i < sn; i++) {
1144                 tmp[sn + i] = row[2 * i] - ((row[2 * i + 1] + row[2 * (i - 1) + 1]) >> 1);
1145             }
1146             if ((width % 2) == 1) {
1147                 tmp[sn + i] = row[2 * i] - row[2 * (i - 1) + 1];
1148             }
1149
1150             for (i = 0; i < dn - 1; i++) {
1151                 row[i] = row[2 * i + 1] + ((tmp[sn + i] + tmp[sn + i + 1] + 2) >> 2);
1152             }
1153             if ((width % 2) == 0) {
1154                 row[i] = row[2 * i + 1] + ((tmp[sn + i] + tmp[sn + i] + 2) >> 2);
1155             }
1156             memcpy(row + sn, tmp + sn, (OPJ_SIZE_T)dn * sizeof(OPJ_INT32));
1157         }
1158     }
1159 }
1160
1161 /** Process one line for the horizontal pass of the 9x7 forward transform */
1162 static
1163 void opj_dwt_encode_and_deinterleave_h_one_row_real(void* rowIn,
1164         void* tmpIn,
1165         OPJ_UINT32 width,
1166         OPJ_BOOL even)
1167 {
1168     OPJ_FLOAT32* OPJ_RESTRICT row = (OPJ_FLOAT32*)rowIn;
1169     OPJ_FLOAT32* OPJ_RESTRICT tmp = (OPJ_FLOAT32*)tmpIn;
1170     const OPJ_INT32 sn = (OPJ_INT32)((width + (even ? 1 : 0)) >> 1);
1171     const OPJ_INT32 dn = (OPJ_INT32)(width - (OPJ_UINT32)sn);
1172     if (width == 1) {
1173         return;
1174     }
1175     memcpy(tmp, row, width * sizeof(OPJ_FLOAT32));
1176     opj_dwt_encode_1_real(tmp, dn, sn, even ? 0 : 1);
1177     opj_dwt_deinterleave_h((OPJ_INT32 * OPJ_RESTRICT)tmp,
1178                            (OPJ_INT32 * OPJ_RESTRICT)row,
1179                            dn, sn, even ? 0 : 1);
1180 }
1181
1182 typedef struct {
1183     opj_dwt_t h;
1184     OPJ_UINT32 rw; /* Width of the resolution to process */
1185     OPJ_UINT32 w; /* Width of tiledp */
1186     OPJ_INT32 * OPJ_RESTRICT tiledp;
1187     OPJ_UINT32 min_j;
1188     OPJ_UINT32 max_j;
1189     opj_encode_and_deinterleave_h_one_row_fnptr_type p_function;
1190 } opj_dwt_encode_h_job_t;
1191
1192 static void opj_dwt_encode_h_func(void* user_data, opj_tls_t* tls)
1193 {
1194     OPJ_UINT32 j;
1195     opj_dwt_encode_h_job_t* job;
1196     (void)tls;
1197
1198     job = (opj_dwt_encode_h_job_t*)user_data;
1199     for (j = job->min_j; j < job->max_j; j++) {
1200         OPJ_INT32* OPJ_RESTRICT aj = job->tiledp + j * job->w;
1201         (*job->p_function)(aj, job->h.mem, job->rw,
1202                            job->h.cas == 0 ? OPJ_TRUE : OPJ_FALSE);
1203     }
1204
1205     opj_aligned_free(job->h.mem);
1206     opj_free(job);
1207 }
1208
1209 typedef struct {
1210     opj_dwt_t v;
1211     OPJ_UINT32 rh;
1212     OPJ_UINT32 w;
1213     OPJ_INT32 * OPJ_RESTRICT tiledp;
1214     OPJ_UINT32 min_j;
1215     OPJ_UINT32 max_j;
1216     opj_encode_and_deinterleave_v_fnptr_type p_encode_and_deinterleave_v;
1217 } opj_dwt_encode_v_job_t;
1218
1219 static void opj_dwt_encode_v_func(void* user_data, opj_tls_t* tls)
1220 {
1221     OPJ_UINT32 j;
1222     opj_dwt_encode_v_job_t* job;
1223     (void)tls;
1224
1225     job = (opj_dwt_encode_v_job_t*)user_data;
1226     for (j = job->min_j; j + NB_ELTS_V8 - 1 < job->max_j; j += NB_ELTS_V8) {
1227         (*job->p_encode_and_deinterleave_v)(job->tiledp + j,
1228                                             job->v.mem,
1229                                             job->rh,
1230                                             job->v.cas == 0,
1231                                             job->w,
1232                                             NB_ELTS_V8);
1233     }
1234     if (j < job->max_j) {
1235         (*job->p_encode_and_deinterleave_v)(job->tiledp + j,
1236                                             job->v.mem,
1237                                             job->rh,
1238                                             job->v.cas == 0,
1239                                             job->w,
1240                                             job->max_j - j);
1241     }
1242
1243     opj_aligned_free(job->v.mem);
1244     opj_free(job);
1245 }
1246
1247 /** Fetch up to cols <= NB_ELTS_V8 for each line, and put them in tmpOut */
1248 /* that has a NB_ELTS_V8 interleave factor. */
1249 static void opj_dwt_fetch_cols_vertical_pass(const void *arrayIn,
1250         void *tmpOut,
1251         OPJ_UINT32 height,
1252         OPJ_UINT32 stride_width,
1253         OPJ_UINT32 cols)
1254 {
1255     const OPJ_INT32* OPJ_RESTRICT array = (const OPJ_INT32 * OPJ_RESTRICT)arrayIn;
1256     OPJ_INT32* OPJ_RESTRICT tmp = (OPJ_INT32 * OPJ_RESTRICT)tmpOut;
1257     if (cols == NB_ELTS_V8) {
1258         OPJ_UINT32 k;
1259         for (k = 0; k < height; ++k) {
1260             memcpy(tmp + NB_ELTS_V8 * k,
1261                    array + k * stride_width,
1262                    NB_ELTS_V8 * sizeof(OPJ_INT32));
1263         }
1264     } else {
1265         OPJ_UINT32 k;
1266         for (k = 0; k < height; ++k) {
1267             OPJ_UINT32 c;
1268             for (c = 0; c < cols; c++) {
1269                 tmp[NB_ELTS_V8 * k + c] = array[c + k * stride_width];
1270             }
1271             for (; c < NB_ELTS_V8; c++) {
1272                 tmp[NB_ELTS_V8 * k + c] = 0;
1273             }
1274         }
1275     }
1276 }
1277
1278 /* Deinterleave result of forward transform, where cols <= NB_ELTS_V8 */
1279 /* and src contains NB_ELTS_V8 consecutive values for up to NB_ELTS_V8 */
1280 /* columns. */
1281 static INLINE void opj_dwt_deinterleave_v_cols(
1282     const OPJ_INT32 * OPJ_RESTRICT src,
1283     OPJ_INT32 * OPJ_RESTRICT dst,
1284     OPJ_INT32 dn,
1285     OPJ_INT32 sn,
1286     OPJ_UINT32 stride_width,
1287     OPJ_INT32 cas,
1288     OPJ_UINT32 cols)
1289 {
1290     OPJ_INT32 k;
1291     OPJ_INT32 i = sn;
1292     OPJ_INT32 * OPJ_RESTRICT l_dest = dst;
1293     const OPJ_INT32 * OPJ_RESTRICT l_src = src + cas * NB_ELTS_V8;
1294     OPJ_UINT32 c;
1295
1296     for (k = 0; k < 2; k++) {
1297         while (i--) {
1298             if (cols == NB_ELTS_V8) {
1299                 memcpy(l_dest, l_src, NB_ELTS_V8 * sizeof(OPJ_INT32));
1300             } else {
1301                 c = 0;
1302                 switch (cols) {
1303                 case 7:
1304                     l_dest[c] = l_src[c];
1305                     c++; /* fallthru */
1306                 case 6:
1307                     l_dest[c] = l_src[c];
1308                     c++; /* fallthru */
1309                 case 5:
1310                     l_dest[c] = l_src[c];
1311                     c++; /* fallthru */
1312                 case 4:
1313                     l_dest[c] = l_src[c];
1314                     c++; /* fallthru */
1315                 case 3:
1316                     l_dest[c] = l_src[c];
1317                     c++; /* fallthru */
1318                 case 2:
1319                     l_dest[c] = l_src[c];
1320                     c++; /* fallthru */
1321                 default:
1322                     l_dest[c] = l_src[c];
1323                     break;
1324                 }
1325             }
1326             l_dest += stride_width;
1327             l_src += 2 * NB_ELTS_V8;
1328         }
1329
1330         l_dest = dst + (OPJ_SIZE_T)sn * (OPJ_SIZE_T)stride_width;
1331         l_src = src + (1 - cas) * NB_ELTS_V8;
1332         i = dn;
1333     }
1334 }
1335
1336
1337 /* Forward 5-3 transform, for the vertical pass, processing cols columns */
1338 /* where cols <= NB_ELTS_V8 */
1339 static void opj_dwt_encode_and_deinterleave_v(
1340     void *arrayIn,
1341     void *tmpIn,
1342     OPJ_UINT32 height,
1343     OPJ_BOOL even,
1344     OPJ_UINT32 stride_width,
1345     OPJ_UINT32 cols)
1346 {
1347     OPJ_INT32* OPJ_RESTRICT array = (OPJ_INT32 * OPJ_RESTRICT)arrayIn;
1348     OPJ_INT32* OPJ_RESTRICT tmp = (OPJ_INT32 * OPJ_RESTRICT)tmpIn;
1349     const OPJ_UINT32 sn = (height + (even ? 1 : 0)) >> 1;
1350     const OPJ_UINT32 dn = height - sn;
1351
1352     opj_dwt_fetch_cols_vertical_pass(arrayIn, tmpIn, height, stride_width, cols);
1353
1354 #define OPJ_Sc(i) tmp[(i)*2* NB_ELTS_V8 + c]
1355 #define OPJ_Dc(i) tmp[((1+(i)*2))* NB_ELTS_V8 + c]
1356
1357 #ifdef __SSE2__
1358     if (height == 1) {
1359         if (!even) {
1360             OPJ_UINT32 c;
1361             for (c = 0; c < NB_ELTS_V8; c++) {
1362                 tmp[c] *= 2;
1363             }
1364         }
1365     } else if (even) {
1366         OPJ_UINT32 c;
1367         OPJ_UINT32 i;
1368         i = 0;
1369         if (i + 1 < sn) {
1370             __m128i xmm_Si_0 = *(const __m128i*)(tmp + 4 * 0);
1371             __m128i xmm_Si_1 = *(const __m128i*)(tmp + 4 * 1);
1372             for (; i + 1 < sn; i++) {
1373                 __m128i xmm_Sip1_0 = *(const __m128i*)(tmp +
1374                                                        (i + 1) * 2 * NB_ELTS_V8 + 4 * 0);
1375                 __m128i xmm_Sip1_1 = *(const __m128i*)(tmp +
1376                                                        (i + 1) * 2 * NB_ELTS_V8 + 4 * 1);
1377                 __m128i xmm_Di_0 = *(const __m128i*)(tmp +
1378                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 0);
1379                 __m128i xmm_Di_1 = *(const __m128i*)(tmp +
1380                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 1);
1381                 xmm_Di_0 = _mm_sub_epi32(xmm_Di_0,
1382                                          _mm_srai_epi32(_mm_add_epi32(xmm_Si_0, xmm_Sip1_0), 1));
1383                 xmm_Di_1 = _mm_sub_epi32(xmm_Di_1,
1384                                          _mm_srai_epi32(_mm_add_epi32(xmm_Si_1, xmm_Sip1_1), 1));
1385                 *(__m128i*)(tmp + (1 + i * 2) * NB_ELTS_V8 + 4 * 0) =  xmm_Di_0;
1386                 *(__m128i*)(tmp + (1 + i * 2) * NB_ELTS_V8 + 4 * 1) =  xmm_Di_1;
1387                 xmm_Si_0 = xmm_Sip1_0;
1388                 xmm_Si_1 = xmm_Sip1_1;
1389             }
1390         }
1391         if (((height) % 2) == 0) {
1392             for (c = 0; c < NB_ELTS_V8; c++) {
1393                 OPJ_Dc(i) -= OPJ_Sc(i);
1394             }
1395         }
1396         for (c = 0; c < NB_ELTS_V8; c++) {
1397             OPJ_Sc(0) += (OPJ_Dc(0) + OPJ_Dc(0) + 2) >> 2;
1398         }
1399         i = 1;
1400         if (i < dn) {
1401             __m128i xmm_Dim1_0 = *(const __m128i*)(tmp + (1 +
1402                                                    (i - 1) * 2) * NB_ELTS_V8 + 4 * 0);
1403             __m128i xmm_Dim1_1 = *(const __m128i*)(tmp + (1 +
1404                                                    (i - 1) * 2) * NB_ELTS_V8 + 4 * 1);
1405             const __m128i xmm_two = _mm_set1_epi32(2);
1406             for (; i < dn; i++) {
1407                 __m128i xmm_Di_0 = *(const __m128i*)(tmp +
1408                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 0);
1409                 __m128i xmm_Di_1 = *(const __m128i*)(tmp +
1410                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 1);
1411                 __m128i xmm_Si_0 = *(const __m128i*)(tmp +
1412                                                      (i * 2) * NB_ELTS_V8 + 4 * 0);
1413                 __m128i xmm_Si_1 = *(const __m128i*)(tmp +
1414                                                      (i * 2) * NB_ELTS_V8 + 4 * 1);
1415                 xmm_Si_0 = _mm_add_epi32(xmm_Si_0,
1416                                          _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(xmm_Dim1_0, xmm_Di_0), xmm_two), 2));
1417                 xmm_Si_1 = _mm_add_epi32(xmm_Si_1,
1418                                          _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(xmm_Dim1_1, xmm_Di_1), xmm_two), 2));
1419                 *(__m128i*)(tmp + (i * 2) * NB_ELTS_V8 + 4 * 0) = xmm_Si_0;
1420                 *(__m128i*)(tmp + (i * 2) * NB_ELTS_V8 + 4 * 1) = xmm_Si_1;
1421                 xmm_Dim1_0 = xmm_Di_0;
1422                 xmm_Dim1_1 = xmm_Di_1;
1423             }
1424         }
1425         if (((height) % 2) == 1) {
1426             for (c = 0; c < NB_ELTS_V8; c++) {
1427                 OPJ_Sc(i) += (OPJ_Dc(i - 1) + OPJ_Dc(i - 1) + 2) >> 2;
1428             }
1429         }
1430     } else {
1431         OPJ_UINT32 c;
1432         OPJ_UINT32 i;
1433         for (c = 0; c < NB_ELTS_V8; c++) {
1434             OPJ_Sc(0) -= OPJ_Dc(0);
1435         }
1436         i = 1;
1437         if (i < sn) {
1438             __m128i xmm_Dim1_0 = *(const __m128i*)(tmp + (1 +
1439                                                    (i - 1) * 2) * NB_ELTS_V8 + 4 * 0);
1440             __m128i xmm_Dim1_1 = *(const __m128i*)(tmp + (1 +
1441                                                    (i - 1) * 2) * NB_ELTS_V8 + 4 * 1);
1442             for (; i < sn; i++) {
1443                 __m128i xmm_Di_0 = *(const __m128i*)(tmp +
1444                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 0);
1445                 __m128i xmm_Di_1 = *(const __m128i*)(tmp +
1446                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 1);
1447                 __m128i xmm_Si_0 = *(const __m128i*)(tmp +
1448                                                      (i * 2) * NB_ELTS_V8 + 4 * 0);
1449                 __m128i xmm_Si_1 = *(const __m128i*)(tmp +
1450                                                      (i * 2) * NB_ELTS_V8 + 4 * 1);
1451                 xmm_Si_0 = _mm_sub_epi32(xmm_Si_0,
1452                                          _mm_srai_epi32(_mm_add_epi32(xmm_Di_0, xmm_Dim1_0), 1));
1453                 xmm_Si_1 = _mm_sub_epi32(xmm_Si_1,
1454                                          _mm_srai_epi32(_mm_add_epi32(xmm_Di_1, xmm_Dim1_1), 1));
1455                 *(__m128i*)(tmp + (i * 2) * NB_ELTS_V8 + 4 * 0) = xmm_Si_0;
1456                 *(__m128i*)(tmp + (i * 2) * NB_ELTS_V8 + 4 * 1) = xmm_Si_1;
1457                 xmm_Dim1_0 = xmm_Di_0;
1458                 xmm_Dim1_1 = xmm_Di_1;
1459             }
1460         }
1461         if (((height) % 2) == 1) {
1462             for (c = 0; c < NB_ELTS_V8; c++) {
1463                 OPJ_Sc(i) -= OPJ_Dc(i - 1);
1464             }
1465         }
1466         i = 0;
1467         if (i + 1 < dn) {
1468             __m128i xmm_Si_0 = *((const __m128i*)(tmp + 4 * 0));
1469             __m128i xmm_Si_1 = *((const __m128i*)(tmp + 4 * 1));
1470             const __m128i xmm_two = _mm_set1_epi32(2);
1471             for (; i + 1 < dn; i++) {
1472                 __m128i xmm_Sip1_0 = *(const __m128i*)(tmp +
1473                                                        (i + 1) * 2 * NB_ELTS_V8 + 4 * 0);
1474                 __m128i xmm_Sip1_1 = *(const __m128i*)(tmp +
1475                                                        (i + 1) * 2 * NB_ELTS_V8 + 4 * 1);
1476                 __m128i xmm_Di_0 = *(const __m128i*)(tmp +
1477                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 0);
1478                 __m128i xmm_Di_1 = *(const __m128i*)(tmp +
1479                                                      (1 + i * 2) * NB_ELTS_V8 + 4 * 1);
1480                 xmm_Di_0 = _mm_add_epi32(xmm_Di_0,
1481                                          _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(xmm_Si_0, xmm_Sip1_0), xmm_two), 2));
1482                 xmm_Di_1 = _mm_add_epi32(xmm_Di_1,
1483                                          _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(xmm_Si_1, xmm_Sip1_1), xmm_two), 2));
1484                 *(__m128i*)(tmp + (1 + i * 2) * NB_ELTS_V8 + 4 * 0) = xmm_Di_0;
1485                 *(__m128i*)(tmp + (1 + i * 2) * NB_ELTS_V8 + 4 * 1) = xmm_Di_1;
1486                 xmm_Si_0 = xmm_Sip1_0;
1487                 xmm_Si_1 = xmm_Sip1_1;
1488             }
1489         }
1490         if (((height) % 2) == 0) {
1491             for (c = 0; c < NB_ELTS_V8; c++) {
1492                 OPJ_Dc(i) += (OPJ_Sc(i) + OPJ_Sc(i) + 2) >> 2;
1493             }
1494         }
1495     }
1496 #else
1497     if (even) {
1498         OPJ_UINT32 c;
1499         if (height > 1) {
1500             OPJ_UINT32 i;
1501             for (i = 0; i + 1 < sn; i++) {
1502                 for (c = 0; c < NB_ELTS_V8; c++) {
1503                     OPJ_Dc(i) -= (OPJ_Sc(i) + OPJ_Sc(i + 1)) >> 1;
1504                 }
1505             }
1506             if (((height) % 2) == 0) {
1507                 for (c = 0; c < NB_ELTS_V8; c++) {
1508                     OPJ_Dc(i) -= OPJ_Sc(i);
1509                 }
1510             }
1511             for (c = 0; c < NB_ELTS_V8; c++) {
1512                 OPJ_Sc(0) += (OPJ_Dc(0) + OPJ_Dc(0) + 2) >> 2;
1513             }
1514             for (i = 1; i < dn; i++) {
1515                 for (c = 0; c < NB_ELTS_V8; c++) {
1516                     OPJ_Sc(i) += (OPJ_Dc(i - 1) + OPJ_Dc(i) + 2) >> 2;
1517                 }
1518             }
1519             if (((height) % 2) == 1) {
1520                 for (c = 0; c < NB_ELTS_V8; c++) {
1521                     OPJ_Sc(i) += (OPJ_Dc(i - 1) + OPJ_Dc(i - 1) + 2) >> 2;
1522                 }
1523             }
1524         }
1525     } else {
1526         OPJ_UINT32 c;
1527         if (height == 1) {
1528             for (c = 0; c < NB_ELTS_V8; c++) {
1529                 OPJ_Sc(0) *= 2;
1530             }
1531         } else {
1532             OPJ_UINT32 i;
1533             for (c = 0; c < NB_ELTS_V8; c++) {
1534                 OPJ_Sc(0) -= OPJ_Dc(0);
1535             }
1536             for (i = 1; i < sn; i++) {
1537                 for (c = 0; c < NB_ELTS_V8; c++) {
1538                     OPJ_Sc(i) -= (OPJ_Dc(i) + OPJ_Dc(i - 1)) >> 1;
1539                 }
1540             }
1541             if (((height) % 2) == 1) {
1542                 for (c = 0; c < NB_ELTS_V8; c++) {
1543                     OPJ_Sc(i) -= OPJ_Dc(i - 1);
1544                 }
1545             }
1546             for (i = 0; i + 1 < dn; i++) {
1547                 for (c = 0; c < NB_ELTS_V8; c++) {
1548                     OPJ_Dc(i) += (OPJ_Sc(i) + OPJ_Sc(i + 1) + 2) >> 2;
1549                 }
1550             }
1551             if (((height) % 2) == 0) {
1552                 for (c = 0; c < NB_ELTS_V8; c++) {
1553                     OPJ_Dc(i) += (OPJ_Sc(i) + OPJ_Sc(i) + 2) >> 2;
1554                 }
1555             }
1556         }
1557     }
1558 #endif
1559
1560     if (cols == NB_ELTS_V8) {
1561         opj_dwt_deinterleave_v_cols(tmp, array, (OPJ_INT32)dn, (OPJ_INT32)sn,
1562                                     stride_width, even ? 0 : 1, NB_ELTS_V8);
1563     } else {
1564         opj_dwt_deinterleave_v_cols(tmp, array, (OPJ_INT32)dn, (OPJ_INT32)sn,
1565                                     stride_width, even ? 0 : 1, cols);
1566     }
1567 }
1568
1569 static void opj_v8dwt_encode_step1(OPJ_FLOAT32* fw,
1570                                    OPJ_UINT32 end,
1571                                    const OPJ_FLOAT32 cst)
1572 {
1573     OPJ_UINT32 i;
1574 #ifdef __SSE__
1575     __m128* vw = (__m128*) fw;
1576     const __m128 vcst = _mm_set1_ps(cst);
1577     for (i = 0; i < end; ++i) {
1578         vw[0] = _mm_mul_ps(vw[0], vcst);
1579         vw[1] = _mm_mul_ps(vw[1], vcst);
1580         vw += 2 * (NB_ELTS_V8 * sizeof(OPJ_FLOAT32) / sizeof(__m128));
1581     }
1582 #else
1583     OPJ_UINT32 c;
1584     for (i = 0; i < end; ++i) {
1585         for (c = 0; c < NB_ELTS_V8; c++) {
1586             fw[i * 2 * NB_ELTS_V8 + c] *= cst;
1587         }
1588     }
1589 #endif
1590 }
1591
1592 static void opj_v8dwt_encode_step2(OPJ_FLOAT32* fl, OPJ_FLOAT32* fw,
1593                                    OPJ_UINT32 end,
1594                                    OPJ_UINT32 m,
1595                                    OPJ_FLOAT32 cst)
1596 {
1597     OPJ_UINT32 i;
1598     OPJ_UINT32 imax = opj_uint_min(end, m);
1599 #ifdef __SSE__
1600     __m128* vw = (__m128*) fw;
1601     __m128 vcst = _mm_set1_ps(cst);
1602     if (imax > 0) {
1603         __m128* vl = (__m128*) fl;
1604         vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(_mm_add_ps(vl[0], vw[0]), vcst));
1605         vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(_mm_add_ps(vl[1], vw[1]), vcst));
1606         vw += 2 * (NB_ELTS_V8 * sizeof(OPJ_FLOAT32) / sizeof(__m128));
1607         i = 1;
1608
1609         for (; i < imax; ++i) {
1610             vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(_mm_add_ps(vw[-4], vw[0]), vcst));
1611             vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(_mm_add_ps(vw[-3], vw[1]), vcst));
1612             vw += 2 * (NB_ELTS_V8 * sizeof(OPJ_FLOAT32) / sizeof(__m128));
1613         }
1614     }
1615     if (m < end) {
1616         assert(m + 1 == end);
1617         vcst = _mm_add_ps(vcst, vcst);
1618         vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(vw[-4], vcst));
1619         vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(vw[-3], vcst));
1620     }
1621 #else
1622     OPJ_INT32 c;
1623     if (imax > 0) {
1624         for (c = 0; c < NB_ELTS_V8; c++) {
1625             fw[-1 * NB_ELTS_V8 + c] += (fl[0 * NB_ELTS_V8 + c] + fw[0 * NB_ELTS_V8 + c]) *
1626                                        cst;
1627         }
1628         fw += 2 * NB_ELTS_V8;
1629         i = 1;
1630         for (; i < imax; ++i) {
1631             for (c = 0; c < NB_ELTS_V8; c++) {
1632                 fw[-1 * NB_ELTS_V8 + c] += (fw[-2 * NB_ELTS_V8 + c] + fw[0 * NB_ELTS_V8 + c]) *
1633                                            cst;
1634             }
1635             fw += 2 * NB_ELTS_V8;
1636         }
1637     }
1638     if (m < end) {
1639         assert(m + 1 == end);
1640         for (c = 0; c < NB_ELTS_V8; c++) {
1641             fw[-1 * NB_ELTS_V8 + c] += (2 * fw[-2 * NB_ELTS_V8 + c]) * cst;
1642         }
1643     }
1644 #endif
1645 }
1646
1647 /* Forward 9-7 transform, for the vertical pass, processing cols columns */
1648 /* where cols <= NB_ELTS_V8 */
1649 static void opj_dwt_encode_and_deinterleave_v_real(
1650     void *arrayIn,
1651     void *tmpIn,
1652     OPJ_UINT32 height,
1653     OPJ_BOOL even,
1654     OPJ_UINT32 stride_width,
1655     OPJ_UINT32 cols)
1656 {
1657     OPJ_FLOAT32* OPJ_RESTRICT array = (OPJ_FLOAT32 * OPJ_RESTRICT)arrayIn;
1658     OPJ_FLOAT32* OPJ_RESTRICT tmp = (OPJ_FLOAT32 * OPJ_RESTRICT)tmpIn;
1659     const OPJ_INT32 sn = (OPJ_INT32)((height + (even ? 1 : 0)) >> 1);
1660     const OPJ_INT32 dn = (OPJ_INT32)(height - (OPJ_UINT32)sn);
1661     OPJ_INT32 a, b;
1662
1663     if (height == 1) {
1664         return;
1665     }
1666
1667     opj_dwt_fetch_cols_vertical_pass(arrayIn, tmpIn, height, stride_width, cols);
1668
1669     if (even) {
1670         a = 0;
1671         b = 1;
1672     } else {
1673         a = 1;
1674         b = 0;
1675     }
1676     opj_v8dwt_encode_step2(tmp + a * NB_ELTS_V8,
1677                            tmp + (b + 1) * NB_ELTS_V8,
1678                            (OPJ_UINT32)dn,
1679                            (OPJ_UINT32)opj_int_min(dn, sn - b),
1680                            opj_dwt_alpha);
1681     opj_v8dwt_encode_step2(tmp + b * NB_ELTS_V8,
1682                            tmp + (a + 1) * NB_ELTS_V8,
1683                            (OPJ_UINT32)sn,
1684                            (OPJ_UINT32)opj_int_min(sn, dn - a),
1685                            opj_dwt_beta);
1686     opj_v8dwt_encode_step2(tmp + a * NB_ELTS_V8,
1687                            tmp + (b + 1) * NB_ELTS_V8,
1688                            (OPJ_UINT32)dn,
1689                            (OPJ_UINT32)opj_int_min(dn, sn - b),
1690                            opj_dwt_gamma);
1691     opj_v8dwt_encode_step2(tmp + b * NB_ELTS_V8,
1692                            tmp + (a + 1) * NB_ELTS_V8,
1693                            (OPJ_UINT32)sn,
1694                            (OPJ_UINT32)opj_int_min(sn, dn - a),
1695                            opj_dwt_delta);
1696     opj_v8dwt_encode_step1(tmp + b * NB_ELTS_V8, (OPJ_UINT32)dn,
1697                            opj_K);
1698     opj_v8dwt_encode_step1(tmp + a * NB_ELTS_V8, (OPJ_UINT32)sn,
1699                            opj_invK);
1700
1701
1702     if (cols == NB_ELTS_V8) {
1703         opj_dwt_deinterleave_v_cols((OPJ_INT32*)tmp,
1704                                     (OPJ_INT32*)array,
1705                                     (OPJ_INT32)dn, (OPJ_INT32)sn,
1706                                     stride_width, even ? 0 : 1, NB_ELTS_V8);
1707     } else {
1708         opj_dwt_deinterleave_v_cols((OPJ_INT32*)tmp,
1709                                     (OPJ_INT32*)array,
1710                                     (OPJ_INT32)dn, (OPJ_INT32)sn,
1711                                     stride_width, even ? 0 : 1, cols);
1712     }
1713 }
1714
1715
1716 /* <summary>                            */
1717 /* Forward 5-3 wavelet transform in 2-D. */
1718 /* </summary>                           */
1719 static INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_thread_pool_t* tp,
1720         opj_tcd_tilecomp_t * tilec,
1721         opj_encode_and_deinterleave_v_fnptr_type p_encode_and_deinterleave_v,
1722         opj_encode_and_deinterleave_h_one_row_fnptr_type
1723         p_encode_and_deinterleave_h_one_row)
1724 {
1725     OPJ_INT32 i;
1726     OPJ_INT32 *bj = 00;
1727     OPJ_UINT32 w;
1728     OPJ_INT32 l;
1729
1730     OPJ_SIZE_T l_data_size;
1731
1732     opj_tcd_resolution_t * l_cur_res = 0;
1733     opj_tcd_resolution_t * l_last_res = 0;
1734     const int num_threads = opj_thread_pool_get_thread_count(tp);
1735     OPJ_INT32 * OPJ_RESTRICT tiledp = tilec->data;
1736
1737     w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
1738     l = (OPJ_INT32)tilec->numresolutions - 1;
1739
1740     l_cur_res = tilec->resolutions + l;
1741     l_last_res = l_cur_res - 1;
1742
1743     l_data_size = opj_dwt_max_resolution(tilec->resolutions, tilec->numresolutions);
1744     /* overflow check */
1745     if (l_data_size > (SIZE_MAX / (NB_ELTS_V8 * sizeof(OPJ_INT32)))) {
1746         /* FIXME event manager error callback */
1747         return OPJ_FALSE;
1748     }
1749     l_data_size *= NB_ELTS_V8 * sizeof(OPJ_INT32);
1750     bj = (OPJ_INT32*)opj_aligned_32_malloc(l_data_size);
1751     /* l_data_size is equal to 0 when numresolutions == 1 but bj is not used */
1752     /* in that case, so do not error out */
1753     if (l_data_size != 0 && ! bj) {
1754         return OPJ_FALSE;
1755     }
1756     i = l;
1757
1758     while (i--) {
1759         OPJ_UINT32 j;
1760         OPJ_UINT32 rw;           /* width of the resolution level computed   */
1761         OPJ_UINT32 rh;           /* height of the resolution level computed  */
1762         OPJ_UINT32
1763         rw1;      /* width of the resolution level once lower than computed one                                       */
1764         OPJ_UINT32
1765         rh1;      /* height of the resolution level once lower than computed one                                      */
1766         OPJ_INT32 cas_col;  /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
1767         OPJ_INT32 cas_row;  /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
1768         OPJ_INT32 dn, sn;
1769
1770         rw  = (OPJ_UINT32)(l_cur_res->x1 - l_cur_res->x0);
1771         rh  = (OPJ_UINT32)(l_cur_res->y1 - l_cur_res->y0);
1772         rw1 = (OPJ_UINT32)(l_last_res->x1 - l_last_res->x0);
1773         rh1 = (OPJ_UINT32)(l_last_res->y1 - l_last_res->y0);
1774
1775         cas_row = l_cur_res->x0 & 1;
1776         cas_col = l_cur_res->y0 & 1;
1777
1778         sn = (OPJ_INT32)rh1;
1779         dn = (OPJ_INT32)(rh - rh1);
1780
1781         /* Perform vertical pass */
1782         if (num_threads <= 1 || rw < 2 * NB_ELTS_V8) {
1783             for (j = 0; j + NB_ELTS_V8 - 1 < rw; j += NB_ELTS_V8) {
1784                 p_encode_and_deinterleave_v(tiledp + j,
1785                                             bj,
1786                                             rh,
1787                                             cas_col == 0,
1788                                             w,
1789                                             NB_ELTS_V8);
1790             }
1791             if (j < rw) {
1792                 p_encode_and_deinterleave_v(tiledp + j,
1793                                             bj,
1794                                             rh,
1795                                             cas_col == 0,
1796                                             w,
1797                                             rw - j);
1798             }
1799         }  else {
1800             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1801             OPJ_UINT32 step_j;
1802
1803             if (rw < num_jobs) {
1804                 num_jobs = rw;
1805             }
1806             step_j = ((rw / num_jobs) / NB_ELTS_V8) * NB_ELTS_V8;
1807
1808             for (j = 0; j < num_jobs; j++) {
1809                 opj_dwt_encode_v_job_t* job;
1810
1811                 job = (opj_dwt_encode_v_job_t*) opj_malloc(sizeof(opj_dwt_encode_v_job_t));
1812                 if (!job) {
1813                     opj_thread_pool_wait_completion(tp, 0);
1814                     opj_aligned_free(bj);
1815                     return OPJ_FALSE;
1816                 }
1817                 job->v.mem = (OPJ_INT32*)opj_aligned_32_malloc(l_data_size);
1818                 if (!job->v.mem) {
1819                     opj_thread_pool_wait_completion(tp, 0);
1820                     opj_free(job);
1821                     opj_aligned_free(bj);
1822                     return OPJ_FALSE;
1823                 }
1824                 job->v.dn = dn;
1825                 job->v.sn = sn;
1826                 job->v.cas = cas_col;
1827                 job->rh = rh;
1828                 job->w = w;
1829                 job->tiledp = tiledp;
1830                 job->min_j = j * step_j;
1831                 job->max_j = (j + 1 == num_jobs) ? rw : (j + 1) * step_j;
1832                 job->p_encode_and_deinterleave_v = p_encode_and_deinterleave_v;
1833                 opj_thread_pool_submit_job(tp, opj_dwt_encode_v_func, job);
1834             }
1835             opj_thread_pool_wait_completion(tp, 0);
1836         }
1837
1838         sn = (OPJ_INT32)rw1;
1839         dn = (OPJ_INT32)(rw - rw1);
1840
1841         /* Perform horizontal pass */
1842         if (num_threads <= 1 || rh <= 1) {
1843             for (j = 0; j < rh; j++) {
1844                 OPJ_INT32* OPJ_RESTRICT aj = tiledp + j * w;
1845                 (*p_encode_and_deinterleave_h_one_row)(aj, bj, rw,
1846                                                        cas_row == 0 ? OPJ_TRUE : OPJ_FALSE);
1847             }
1848         }  else {
1849             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1850             OPJ_UINT32 step_j;
1851
1852             if (rh < num_jobs) {
1853                 num_jobs = rh;
1854             }
1855             step_j = (rh / num_jobs);
1856
1857             for (j = 0; j < num_jobs; j++) {
1858                 opj_dwt_encode_h_job_t* job;
1859
1860                 job = (opj_dwt_encode_h_job_t*) opj_malloc(sizeof(opj_dwt_encode_h_job_t));
1861                 if (!job) {
1862                     opj_thread_pool_wait_completion(tp, 0);
1863                     opj_aligned_free(bj);
1864                     return OPJ_FALSE;
1865                 }
1866                 job->h.mem = (OPJ_INT32*)opj_aligned_32_malloc(l_data_size);
1867                 if (!job->h.mem) {
1868                     opj_thread_pool_wait_completion(tp, 0);
1869                     opj_free(job);
1870                     opj_aligned_free(bj);
1871                     return OPJ_FALSE;
1872                 }
1873                 job->h.dn = dn;
1874                 job->h.sn = sn;
1875                 job->h.cas = cas_row;
1876                 job->rw = rw;
1877                 job->w = w;
1878                 job->tiledp = tiledp;
1879                 job->min_j = j * step_j;
1880                 job->max_j = (j + 1U) * step_j; /* this can overflow */
1881                 if (j == (num_jobs - 1U)) {  /* this will take care of the overflow */
1882                     job->max_j = rh;
1883                 }
1884                 job->p_function = p_encode_and_deinterleave_h_one_row;
1885                 opj_thread_pool_submit_job(tp, opj_dwt_encode_h_func, job);
1886             }
1887             opj_thread_pool_wait_completion(tp, 0);
1888         }
1889
1890         l_cur_res = l_last_res;
1891
1892         --l_last_res;
1893     }
1894
1895     opj_aligned_free(bj);
1896     return OPJ_TRUE;
1897 }
1898
1899 /* Forward 5-3 wavelet transform in 2-D. */
1900 /* </summary>                           */
1901 OPJ_BOOL opj_dwt_encode(opj_tcd_t *p_tcd,
1902                         opj_tcd_tilecomp_t * tilec)
1903 {
1904     return opj_dwt_encode_procedure(p_tcd->thread_pool, tilec,
1905                                     opj_dwt_encode_and_deinterleave_v,
1906                                     opj_dwt_encode_and_deinterleave_h_one_row);
1907 }
1908
1909 /* <summary>                            */
1910 /* Inverse 5-3 wavelet transform in 2-D. */
1911 /* </summary>                           */
1912 OPJ_BOOL opj_dwt_decode(opj_tcd_t *p_tcd, opj_tcd_tilecomp_t* tilec,
1913                         OPJ_UINT32 numres)
1914 {
1915     if (p_tcd->whole_tile_decoding) {
1916         return opj_dwt_decode_tile(p_tcd->thread_pool, tilec, numres);
1917     } else {
1918         return opj_dwt_decode_partial_tile(tilec, numres);
1919     }
1920 }
1921
1922 /* <summary>                */
1923 /* Get norm of 5-3 wavelet. */
1924 /* </summary>               */
1925 OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient)
1926 {
1927     /* FIXME ! This is just a band-aid to avoid a buffer overflow */
1928     /* but the array should really be extended up to 33 resolution levels */
1929     /* See https://github.com/uclouvain/openjpeg/issues/493 */
1930     if (orient == 0 && level >= 10) {
1931         level = 9;
1932     } else if (orient > 0 && level >= 9) {
1933         level = 8;
1934     }
1935     return opj_dwt_norms[orient][level];
1936 }
1937
1938 /* <summary>                             */
1939 /* Forward 9-7 wavelet transform in 2-D. */
1940 /* </summary>                            */
1941 OPJ_BOOL opj_dwt_encode_real(opj_tcd_t *p_tcd,
1942                              opj_tcd_tilecomp_t * tilec)
1943 {
1944     return opj_dwt_encode_procedure(p_tcd->thread_pool, tilec,
1945                                     opj_dwt_encode_and_deinterleave_v_real,
1946                                     opj_dwt_encode_and_deinterleave_h_one_row_real);
1947 }
1948
1949 /* <summary>                */
1950 /* Get norm of 9-7 wavelet. */
1951 /* </summary>               */
1952 OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient)
1953 {
1954     /* FIXME ! This is just a band-aid to avoid a buffer overflow */
1955     /* but the array should really be extended up to 33 resolution levels */
1956     /* See https://github.com/uclouvain/openjpeg/issues/493 */
1957     if (orient == 0 && level >= 10) {
1958         level = 9;
1959     } else if (orient > 0 && level >= 9) {
1960         level = 8;
1961     }
1962     return opj_dwt_norms_real[orient][level];
1963 }
1964
1965 void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec)
1966 {
1967     OPJ_UINT32 numbands, bandno;
1968     numbands = 3 * tccp->numresolutions - 2;
1969     for (bandno = 0; bandno < numbands; bandno++) {
1970         OPJ_FLOAT64 stepsize;
1971         OPJ_UINT32 resno, level, orient, gain;
1972
1973         resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
1974         orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
1975         level = tccp->numresolutions - 1 - resno;
1976         gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) ||
1977                                           (orient == 2)) ? 1 : 2));
1978         if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
1979             stepsize = 1.0;
1980         } else {
1981             OPJ_FLOAT64 norm = opj_dwt_getnorm_real(level, orient);
1982             stepsize = (1 << (gain)) / norm;
1983         }
1984         opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0),
1985                                 (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]);
1986     }
1987 }
1988
1989 /* <summary>                             */
1990 /* Determine maximum computed resolution level for inverse wavelet transform */
1991 /* </summary>                            */
1992 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
1993         OPJ_UINT32 i)
1994 {
1995     OPJ_UINT32 mr   = 0;
1996     OPJ_UINT32 w;
1997     while (--i) {
1998         ++r;
1999         if (mr < (w = (OPJ_UINT32)(r->x1 - r->x0))) {
2000             mr = w ;
2001         }
2002         if (mr < (w = (OPJ_UINT32)(r->y1 - r->y0))) {
2003             mr = w ;
2004         }
2005     }
2006     return mr ;
2007 }
2008
2009 typedef struct {
2010     opj_dwt_t h;
2011     OPJ_UINT32 rw;
2012     OPJ_UINT32 w;
2013     OPJ_INT32 * OPJ_RESTRICT tiledp;
2014     OPJ_UINT32 min_j;
2015     OPJ_UINT32 max_j;
2016 } opj_dwt_decode_h_job_t;
2017
2018 static void opj_dwt_decode_h_func(void* user_data, opj_tls_t* tls)
2019 {
2020     OPJ_UINT32 j;
2021     opj_dwt_decode_h_job_t* job;
2022     (void)tls;
2023
2024     job = (opj_dwt_decode_h_job_t*)user_data;
2025     for (j = job->min_j; j < job->max_j; j++) {
2026         opj_idwt53_h(&job->h, &job->tiledp[j * job->w]);
2027     }
2028
2029     opj_aligned_free(job->h.mem);
2030     opj_free(job);
2031 }
2032
2033 typedef struct {
2034     opj_dwt_t v;
2035     OPJ_UINT32 rh;
2036     OPJ_UINT32 w;
2037     OPJ_INT32 * OPJ_RESTRICT tiledp;
2038     OPJ_UINT32 min_j;
2039     OPJ_UINT32 max_j;
2040 } opj_dwt_decode_v_job_t;
2041
2042 static void opj_dwt_decode_v_func(void* user_data, opj_tls_t* tls)
2043 {
2044     OPJ_UINT32 j;
2045     opj_dwt_decode_v_job_t* job;
2046     (void)tls;
2047
2048     job = (opj_dwt_decode_v_job_t*)user_data;
2049     for (j = job->min_j; j + PARALLEL_COLS_53 <= job->max_j;
2050             j += PARALLEL_COLS_53) {
2051         opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_SIZE_T)job->w,
2052                      PARALLEL_COLS_53);
2053     }
2054     if (j < job->max_j)
2055         opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_SIZE_T)job->w,
2056                      (OPJ_INT32)(job->max_j - j));
2057
2058     opj_aligned_free(job->v.mem);
2059     opj_free(job);
2060 }
2061
2062
2063 /* <summary>                            */
2064 /* Inverse wavelet transform in 2-D.    */
2065 /* </summary>                           */
2066 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
2067                                     opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres)
2068 {
2069     opj_dwt_t h;
2070     opj_dwt_t v;
2071
2072     opj_tcd_resolution_t* tr = tilec->resolutions;
2073
2074     OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
2075                                  tr->x0);  /* width of the resolution level computed */
2076     OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
2077                                  tr->y0);  /* height of the resolution level computed */
2078
2079     OPJ_UINT32 w = (OPJ_UINT32)(tilec->resolutions[tilec->minimum_num_resolutions -
2080                                                                1].x1 -
2081                                 tilec->resolutions[tilec->minimum_num_resolutions - 1].x0);
2082     OPJ_SIZE_T h_mem_size;
2083     int num_threads;
2084
2085     if (numres == 1U) {
2086         return OPJ_TRUE;
2087     }
2088     num_threads = opj_thread_pool_get_thread_count(tp);
2089     h_mem_size = opj_dwt_max_resolution(tr, numres);
2090     /* overflow check */
2091     if (h_mem_size > (SIZE_MAX / PARALLEL_COLS_53 / sizeof(OPJ_INT32))) {
2092         /* FIXME event manager error callback */
2093         return OPJ_FALSE;
2094     }
2095     /* We need PARALLEL_COLS_53 times the height of the array, */
2096     /* since for the vertical pass */
2097     /* we process PARALLEL_COLS_53 columns at a time */
2098     h_mem_size *= PARALLEL_COLS_53 * sizeof(OPJ_INT32);
2099     h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
2100     if (! h.mem) {
2101         /* FIXME event manager error callback */
2102         return OPJ_FALSE;
2103     }
2104
2105     v.mem = h.mem;
2106
2107     while (--numres) {
2108         OPJ_INT32 * OPJ_RESTRICT tiledp = tilec->data;
2109         OPJ_UINT32 j;
2110
2111         ++tr;
2112         h.sn = (OPJ_INT32)rw;
2113         v.sn = (OPJ_INT32)rh;
2114
2115         rw = (OPJ_UINT32)(tr->x1 - tr->x0);
2116         rh = (OPJ_UINT32)(tr->y1 - tr->y0);
2117
2118         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
2119         h.cas = tr->x0 % 2;
2120
2121         if (num_threads <= 1 || rh <= 1) {
2122             for (j = 0; j < rh; ++j) {
2123                 opj_idwt53_h(&h, &tiledp[(OPJ_SIZE_T)j * w]);
2124             }
2125         } else {
2126             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
2127             OPJ_UINT32 step_j;
2128
2129             if (rh < num_jobs) {
2130                 num_jobs = rh;
2131             }
2132             step_j = (rh / num_jobs);
2133
2134             for (j = 0; j < num_jobs; j++) {
2135                 opj_dwt_decode_h_job_t* job;
2136
2137                 job = (opj_dwt_decode_h_job_t*) opj_malloc(sizeof(opj_dwt_decode_h_job_t));
2138                 if (!job) {
2139                     /* It would be nice to fallback to single thread case, but */
2140                     /* unfortunately some jobs may be launched and have modified */
2141                     /* tiledp, so it is not practical to recover from that error */
2142                     /* FIXME event manager error callback */
2143                     opj_thread_pool_wait_completion(tp, 0);
2144                     opj_aligned_free(h.mem);
2145                     return OPJ_FALSE;
2146                 }
2147                 job->h = h;
2148                 job->rw = rw;
2149                 job->w = w;
2150                 job->tiledp = tiledp;
2151                 job->min_j = j * step_j;
2152                 job->max_j = (j + 1U) * step_j; /* this can overflow */
2153                 if (j == (num_jobs - 1U)) {  /* this will take care of the overflow */
2154                     job->max_j = rh;
2155                 }
2156                 job->h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
2157                 if (!job->h.mem) {
2158                     /* FIXME event manager error callback */
2159                     opj_thread_pool_wait_completion(tp, 0);
2160                     opj_free(job);
2161                     opj_aligned_free(h.mem);
2162                     return OPJ_FALSE;
2163                 }
2164                 opj_thread_pool_submit_job(tp, opj_dwt_decode_h_func, job);
2165             }
2166             opj_thread_pool_wait_completion(tp, 0);
2167         }
2168
2169         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
2170         v.cas = tr->y0 % 2;
2171
2172         if (num_threads <= 1 || rw <= 1) {
2173             for (j = 0; j + PARALLEL_COLS_53 <= rw;
2174                     j += PARALLEL_COLS_53) {
2175                 opj_idwt53_v(&v, &tiledp[j], (OPJ_SIZE_T)w, PARALLEL_COLS_53);
2176             }
2177             if (j < rw) {
2178                 opj_idwt53_v(&v, &tiledp[j], (OPJ_SIZE_T)w, (OPJ_INT32)(rw - j));
2179             }
2180         } else {
2181             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
2182             OPJ_UINT32 step_j;
2183
2184             if (rw < num_jobs) {
2185                 num_jobs = rw;
2186             }
2187             step_j = (rw / num_jobs);
2188
2189             for (j = 0; j < num_jobs; j++) {
2190                 opj_dwt_decode_v_job_t* job;
2191
2192                 job = (opj_dwt_decode_v_job_t*) opj_malloc(sizeof(opj_dwt_decode_v_job_t));
2193                 if (!job) {
2194                     /* It would be nice to fallback to single thread case, but */
2195                     /* unfortunately some jobs may be launched and have modified */
2196                     /* tiledp, so it is not practical to recover from that error */
2197                     /* FIXME event manager error callback */
2198                     opj_thread_pool_wait_completion(tp, 0);
2199                     opj_aligned_free(v.mem);
2200                     return OPJ_FALSE;
2201                 }
2202                 job->v = v;
2203                 job->rh = rh;
2204                 job->w = w;
2205                 job->tiledp = tiledp;
2206                 job->min_j = j * step_j;
2207                 job->max_j = (j + 1U) * step_j; /* this can overflow */
2208                 if (j == (num_jobs - 1U)) {  /* this will take care of the overflow */
2209                     job->max_j = rw;
2210                 }
2211                 job->v.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
2212                 if (!job->v.mem) {
2213                     /* FIXME event manager error callback */
2214                     opj_thread_pool_wait_completion(tp, 0);
2215                     opj_free(job);
2216                     opj_aligned_free(v.mem);
2217                     return OPJ_FALSE;
2218                 }
2219                 opj_thread_pool_submit_job(tp, opj_dwt_decode_v_func, job);
2220             }
2221             opj_thread_pool_wait_completion(tp, 0);
2222         }
2223     }
2224     opj_aligned_free(h.mem);
2225     return OPJ_TRUE;
2226 }
2227
2228 static void opj_dwt_interleave_partial_h(OPJ_INT32 *dest,
2229         OPJ_INT32 cas,
2230         opj_sparse_array_int32_t* sa,
2231         OPJ_UINT32 sa_line,
2232         OPJ_UINT32 sn,
2233         OPJ_UINT32 win_l_x0,
2234         OPJ_UINT32 win_l_x1,
2235         OPJ_UINT32 win_h_x0,
2236         OPJ_UINT32 win_h_x1)
2237 {
2238     OPJ_BOOL ret;
2239     ret = opj_sparse_array_int32_read(sa,
2240                                       win_l_x0, sa_line,
2241                                       win_l_x1, sa_line + 1,
2242                                       dest + cas + 2 * win_l_x0,
2243                                       2, 0, OPJ_TRUE);
2244     assert(ret);
2245     ret = opj_sparse_array_int32_read(sa,
2246                                       sn + win_h_x0, sa_line,
2247                                       sn + win_h_x1, sa_line + 1,
2248                                       dest + 1 - cas + 2 * win_h_x0,
2249                                       2, 0, OPJ_TRUE);
2250     assert(ret);
2251     OPJ_UNUSED(ret);
2252 }
2253
2254
2255 static void opj_dwt_interleave_partial_v(OPJ_INT32 *dest,
2256         OPJ_INT32 cas,
2257         opj_sparse_array_int32_t* sa,
2258         OPJ_UINT32 sa_col,
2259         OPJ_UINT32 nb_cols,
2260         OPJ_UINT32 sn,
2261         OPJ_UINT32 win_l_y0,
2262         OPJ_UINT32 win_l_y1,
2263         OPJ_UINT32 win_h_y0,
2264         OPJ_UINT32 win_h_y1)
2265 {
2266     OPJ_BOOL ret;
2267     ret  = opj_sparse_array_int32_read(sa,
2268                                        sa_col, win_l_y0,
2269                                        sa_col + nb_cols, win_l_y1,
2270                                        dest + cas * 4 + 2 * 4 * win_l_y0,
2271                                        1, 2 * 4, OPJ_TRUE);
2272     assert(ret);
2273     ret = opj_sparse_array_int32_read(sa,
2274                                       sa_col, sn + win_h_y0,
2275                                       sa_col + nb_cols, sn + win_h_y1,
2276                                       dest + (1 - cas) * 4 + 2 * 4 * win_h_y0,
2277                                       1, 2 * 4, OPJ_TRUE);
2278     assert(ret);
2279     OPJ_UNUSED(ret);
2280 }
2281
2282 static void opj_dwt_decode_partial_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
2283                                      OPJ_INT32 cas,
2284                                      OPJ_INT32 win_l_x0,
2285                                      OPJ_INT32 win_l_x1,
2286                                      OPJ_INT32 win_h_x0,
2287                                      OPJ_INT32 win_h_x1)
2288 {
2289     OPJ_INT32 i;
2290
2291     if (!cas) {
2292         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
2293
2294             /* Naive version is :
2295             for (i = win_l_x0; i < i_max; i++) {
2296                 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
2297             }
2298             for (i = win_h_x0; i < win_h_x1; i++) {
2299                 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
2300             }
2301             but the compiler doesn't manage to unroll it to avoid bound
2302             checking in OPJ_S_ and OPJ_D_ macros
2303             */
2304
2305             i = win_l_x0;
2306             if (i < win_l_x1) {
2307                 OPJ_INT32 i_max;
2308
2309                 /* Left-most case */
2310                 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
2311                 i ++;
2312
2313                 i_max = win_l_x1;
2314                 if (i_max > dn) {
2315                     i_max = dn;
2316                 }
2317                 for (; i < i_max; i++) {
2318                     /* No bound checking */
2319                     OPJ_S(i) -= (OPJ_D(i - 1) + OPJ_D(i) + 2) >> 2;
2320                 }
2321                 for (; i < win_l_x1; i++) {
2322                     /* Right-most case */
2323                     OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
2324                 }
2325             }
2326
2327             i = win_h_x0;
2328             if (i < win_h_x1) {
2329                 OPJ_INT32 i_max = win_h_x1;
2330                 if (i_max >= sn) {
2331                     i_max = sn - 1;
2332                 }
2333                 for (; i < i_max; i++) {
2334                     /* No bound checking */
2335                     OPJ_D(i) += (OPJ_S(i) + OPJ_S(i + 1)) >> 1;
2336                 }
2337                 for (; i < win_h_x1; i++) {
2338                     /* Right-most case */
2339                     OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
2340                 }
2341             }
2342         }
2343     } else {
2344         if (!sn  && dn == 1) {        /* NEW :  CASE ONE ELEMENT */
2345             OPJ_S(0) /= 2;
2346         } else {
2347             for (i = win_l_x0; i < win_l_x1; i++) {
2348                 OPJ_D(i) = opj_int_sub_no_overflow(OPJ_D(i),
2349                                                    opj_int_add_no_overflow(opj_int_add_no_overflow(OPJ_SS_(i), OPJ_SS_(i + 1)),
2350                                                            2) >> 2);
2351             }
2352             for (i = win_h_x0; i < win_h_x1; i++) {
2353                 OPJ_S(i) = opj_int_add_no_overflow(OPJ_S(i),
2354                                                    opj_int_add_no_overflow(OPJ_DD_(i), OPJ_DD_(i - 1)) >> 1);
2355             }
2356         }
2357     }
2358 }
2359
2360 #define OPJ_S_off(i,off) a[(OPJ_UINT32)(i)*2*4+off]
2361 #define OPJ_D_off(i,off) a[(1+(OPJ_UINT32)(i)*2)*4+off]
2362 #define OPJ_S__off(i,off) ((i)<0?OPJ_S_off(0,off):((i)>=sn?OPJ_S_off(sn-1,off):OPJ_S_off(i,off)))
2363 #define OPJ_D__off(i,off) ((i)<0?OPJ_D_off(0,off):((i)>=dn?OPJ_D_off(dn-1,off):OPJ_D_off(i,off)))
2364 #define OPJ_SS__off(i,off) ((i)<0?OPJ_S_off(0,off):((i)>=dn?OPJ_S_off(dn-1,off):OPJ_S_off(i,off)))
2365 #define OPJ_DD__off(i,off) ((i)<0?OPJ_D_off(0,off):((i)>=sn?OPJ_D_off(sn-1,off):OPJ_D_off(i,off)))
2366
2367 static void opj_dwt_decode_partial_1_parallel(OPJ_INT32 *a,
2368         OPJ_UINT32 nb_cols,
2369         OPJ_INT32 dn, OPJ_INT32 sn,
2370         OPJ_INT32 cas,
2371         OPJ_INT32 win_l_x0,
2372         OPJ_INT32 win_l_x1,
2373         OPJ_INT32 win_h_x0,
2374         OPJ_INT32 win_h_x1)
2375 {
2376     OPJ_INT32 i;
2377     OPJ_UINT32 off;
2378
2379     (void)nb_cols;
2380
2381     if (!cas) {
2382         if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
2383
2384             /* Naive version is :
2385             for (i = win_l_x0; i < i_max; i++) {
2386                 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
2387             }
2388             for (i = win_h_x0; i < win_h_x1; i++) {
2389                 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
2390             }
2391             but the compiler doesn't manage to unroll it to avoid bound
2392             checking in OPJ_S_ and OPJ_D_ macros
2393             */
2394
2395             i = win_l_x0;
2396             if (i < win_l_x1) {
2397                 OPJ_INT32 i_max;
2398
2399                 /* Left-most case */
2400                 for (off = 0; off < 4; off++) {
2401                     OPJ_S_off(i, off) -= (OPJ_D__off(i - 1, off) + OPJ_D__off(i, off) + 2) >> 2;
2402                 }
2403                 i ++;
2404
2405                 i_max = win_l_x1;
2406                 if (i_max > dn) {
2407                     i_max = dn;
2408                 }
2409
2410 #ifdef __SSE2__
2411                 if (i + 1 < i_max) {
2412                     const __m128i two = _mm_set1_epi32(2);
2413                     __m128i Dm1 = _mm_load_si128((__m128i * const)(a + 4 + (i - 1) * 8));
2414                     for (; i + 1 < i_max; i += 2) {
2415                         /* No bound checking */
2416                         __m128i S = _mm_load_si128((__m128i * const)(a + i * 8));
2417                         __m128i D = _mm_load_si128((__m128i * const)(a + 4 + i * 8));
2418                         __m128i S1 = _mm_load_si128((__m128i * const)(a + (i + 1) * 8));
2419                         __m128i D1 = _mm_load_si128((__m128i * const)(a + 4 + (i + 1) * 8));
2420                         S = _mm_sub_epi32(S,
2421                                           _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(Dm1, D), two), 2));
2422                         S1 = _mm_sub_epi32(S1,
2423                                            _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(D, D1), two), 2));
2424                         _mm_store_si128((__m128i*)(a + i * 8), S);
2425                         _mm_store_si128((__m128i*)(a + (i + 1) * 8), S1);
2426                         Dm1 = D1;
2427                     }
2428                 }
2429 #endif
2430
2431                 for (; i < i_max; i++) {
2432                     /* No bound checking */
2433                     for (off = 0; off < 4; off++) {
2434                         OPJ_S_off(i, off) -= (OPJ_D_off(i - 1, off) + OPJ_D_off(i, off) + 2) >> 2;
2435                     }
2436                 }
2437                 for (; i < win_l_x1; i++) {
2438                     /* Right-most case */
2439                     for (off = 0; off < 4; off++) {
2440                         OPJ_S_off(i, off) -= (OPJ_D__off(i - 1, off) + OPJ_D__off(i, off) + 2) >> 2;
2441                     }
2442                 }
2443             }
2444
2445             i = win_h_x0;
2446             if (i < win_h_x1) {
2447                 OPJ_INT32 i_max = win_h_x1;
2448                 if (i_max >= sn) {
2449                     i_max = sn - 1;
2450                 }
2451
2452 #ifdef __SSE2__
2453                 if (i + 1 < i_max) {
2454                     __m128i S =  _mm_load_si128((__m128i * const)(a + i * 8));
2455                     for (; i + 1 < i_max; i += 2) {
2456                         /* No bound checking */
2457                         __m128i D = _mm_load_si128((__m128i * const)(a + 4 + i * 8));
2458                         __m128i S1 = _mm_load_si128((__m128i * const)(a + (i + 1) * 8));
2459                         __m128i D1 = _mm_load_si128((__m128i * const)(a + 4 + (i + 1) * 8));
2460                         __m128i S2 = _mm_load_si128((__m128i * const)(a + (i + 2) * 8));
2461                         D = _mm_add_epi32(D, _mm_srai_epi32(_mm_add_epi32(S, S1), 1));
2462                         D1 = _mm_add_epi32(D1, _mm_srai_epi32(_mm_add_epi32(S1, S2), 1));
2463                         _mm_store_si128((__m128i*)(a + 4 + i * 8), D);
2464                         _mm_store_si128((__m128i*)(a + 4 + (i + 1) * 8), D1);
2465                         S = S2;
2466                     }
2467                 }
2468 #endif
2469
2470                 for (; i < i_max; i++) {
2471                     /* No bound checking */
2472                     for (off = 0; off < 4; off++) {
2473                         OPJ_D_off(i, off) += (OPJ_S_off(i, off) + OPJ_S_off(i + 1, off)) >> 1;
2474                     }
2475                 }
2476                 for (; i < win_h_x1; i++) {
2477                     /* Right-most case */
2478                     for (off = 0; off < 4; off++) {
2479                         OPJ_D_off(i, off) += (OPJ_S__off(i, off) + OPJ_S__off(i + 1, off)) >> 1;
2480                     }
2481                 }
2482             }
2483         }
2484     } else {
2485         if (!sn  && dn == 1) {        /* NEW :  CASE ONE ELEMENT */
2486             for (off = 0; off < 4; off++) {
2487                 OPJ_S_off(0, off) /= 2;
2488             }
2489         } else {
2490             for (i = win_l_x0; i < win_l_x1; i++) {
2491                 for (off = 0; off < 4; off++) {
2492                     OPJ_D_off(i, off) = opj_int_sub_no_overflow(
2493                                             OPJ_D_off(i, off),
2494                                             opj_int_add_no_overflow(
2495                                                 opj_int_add_no_overflow(OPJ_SS__off(i, off), OPJ_SS__off(i + 1, off)), 2) >> 2);
2496                 }
2497             }
2498             for (i = win_h_x0; i < win_h_x1; i++) {
2499                 for (off = 0; off < 4; off++) {
2500                     OPJ_S_off(i, off) = opj_int_add_no_overflow(
2501                                             OPJ_S_off(i, off),
2502                                             opj_int_add_no_overflow(OPJ_DD__off(i, off), OPJ_DD__off(i - 1, off)) >> 1);
2503                 }
2504             }
2505         }
2506     }
2507 }
2508
2509 static void opj_dwt_get_band_coordinates(opj_tcd_tilecomp_t* tilec,
2510         OPJ_UINT32 resno,
2511         OPJ_UINT32 bandno,
2512         OPJ_UINT32 tcx0,
2513         OPJ_UINT32 tcy0,
2514         OPJ_UINT32 tcx1,
2515         OPJ_UINT32 tcy1,
2516         OPJ_UINT32* tbx0,
2517         OPJ_UINT32* tby0,
2518         OPJ_UINT32* tbx1,
2519         OPJ_UINT32* tby1)
2520 {
2521     /* Compute number of decomposition for this band. See table F-1 */
2522     OPJ_UINT32 nb = (resno == 0) ?
2523                     tilec->numresolutions - 1 :
2524                     tilec->numresolutions - resno;
2525     /* Map above tile-based coordinates to sub-band-based coordinates per */
2526     /* equation B-15 of the standard */
2527     OPJ_UINT32 x0b = bandno & 1;
2528     OPJ_UINT32 y0b = bandno >> 1;
2529     if (tbx0) {
2530         *tbx0 = (nb == 0) ? tcx0 :
2531                 (tcx0 <= (1U << (nb - 1)) * x0b) ? 0 :
2532                 opj_uint_ceildivpow2(tcx0 - (1U << (nb - 1)) * x0b, nb);
2533     }
2534     if (tby0) {
2535         *tby0 = (nb == 0) ? tcy0 :
2536                 (tcy0 <= (1U << (nb - 1)) * y0b) ? 0 :
2537                 opj_uint_ceildivpow2(tcy0 - (1U << (nb - 1)) * y0b, nb);
2538     }
2539     if (tbx1) {
2540         *tbx1 = (nb == 0) ? tcx1 :
2541                 (tcx1 <= (1U << (nb - 1)) * x0b) ? 0 :
2542                 opj_uint_ceildivpow2(tcx1 - (1U << (nb - 1)) * x0b, nb);
2543     }
2544     if (tby1) {
2545         *tby1 = (nb == 0) ? tcy1 :
2546                 (tcy1 <= (1U << (nb - 1)) * y0b) ? 0 :
2547                 opj_uint_ceildivpow2(tcy1 - (1U << (nb - 1)) * y0b, nb);
2548     }
2549 }
2550
2551 static void opj_dwt_segment_grow(OPJ_UINT32 filter_width,
2552                                  OPJ_UINT32 max_size,
2553                                  OPJ_UINT32* start,
2554                                  OPJ_UINT32* end)
2555 {
2556     *start = opj_uint_subs(*start, filter_width);
2557     *end = opj_uint_adds(*end, filter_width);
2558     *end = opj_uint_min(*end, max_size);
2559 }
2560
2561
2562 static opj_sparse_array_int32_t* opj_dwt_init_sparse_array(
2563     opj_tcd_tilecomp_t* tilec,
2564     OPJ_UINT32 numres)
2565 {
2566     opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
2567     OPJ_UINT32 w = (OPJ_UINT32)(tr_max->x1 - tr_max->x0);
2568     OPJ_UINT32 h = (OPJ_UINT32)(tr_max->y1 - tr_max->y0);
2569     OPJ_UINT32 resno, bandno, precno, cblkno;
2570     opj_sparse_array_int32_t* sa = opj_sparse_array_int32_create(
2571                                        w, h, opj_uint_min(w, 64), opj_uint_min(h, 64));
2572     if (sa == NULL) {
2573         return NULL;
2574     }
2575
2576     for (resno = 0; resno < numres; ++resno) {
2577         opj_tcd_resolution_t* res = &tilec->resolutions[resno];
2578
2579         for (bandno = 0; bandno < res->numbands; ++bandno) {
2580             opj_tcd_band_t* band = &res->bands[bandno];
2581
2582             for (precno = 0; precno < res->pw * res->ph; ++precno) {
2583                 opj_tcd_precinct_t* precinct = &band->precincts[precno];
2584                 for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
2585                     opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
2586                     if (cblk->decoded_data != NULL) {
2587                         OPJ_UINT32 x = (OPJ_UINT32)(cblk->x0 - band->x0);
2588                         OPJ_UINT32 y = (OPJ_UINT32)(cblk->y0 - band->y0);
2589                         OPJ_UINT32 cblk_w = (OPJ_UINT32)(cblk->x1 - cblk->x0);
2590                         OPJ_UINT32 cblk_h = (OPJ_UINT32)(cblk->y1 - cblk->y0);
2591
2592                         if (band->bandno & 1) {
2593                             opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
2594                             x += (OPJ_UINT32)(pres->x1 - pres->x0);
2595                         }
2596                         if (band->bandno & 2) {
2597                             opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
2598                             y += (OPJ_UINT32)(pres->y1 - pres->y0);
2599                         }
2600
2601                         if (!opj_sparse_array_int32_write(sa, x, y,
2602                                                           x + cblk_w, y + cblk_h,
2603                                                           cblk->decoded_data,
2604                                                           1, cblk_w, OPJ_TRUE)) {
2605                             opj_sparse_array_int32_free(sa);
2606                             return NULL;
2607                         }
2608                     }
2609                 }
2610             }
2611         }
2612     }
2613
2614     return sa;
2615 }
2616
2617
2618 static OPJ_BOOL opj_dwt_decode_partial_tile(
2619     opj_tcd_tilecomp_t* tilec,
2620     OPJ_UINT32 numres)
2621 {
2622     opj_sparse_array_int32_t* sa;
2623     opj_dwt_t h;
2624     opj_dwt_t v;
2625     OPJ_UINT32 resno;
2626     /* This value matches the maximum left/right extension given in tables */
2627     /* F.2 and F.3 of the standard. */
2628     const OPJ_UINT32 filter_width = 2U;
2629
2630     opj_tcd_resolution_t* tr = tilec->resolutions;
2631     opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
2632
2633     OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
2634                                  tr->x0);  /* width of the resolution level computed */
2635     OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
2636                                  tr->y0);  /* height of the resolution level computed */
2637
2638     OPJ_SIZE_T h_mem_size;
2639
2640     /* Compute the intersection of the area of interest, expressed in tile coordinates */
2641     /* with the tile coordinates */
2642     OPJ_UINT32 win_tcx0 = tilec->win_x0;
2643     OPJ_UINT32 win_tcy0 = tilec->win_y0;
2644     OPJ_UINT32 win_tcx1 = tilec->win_x1;
2645     OPJ_UINT32 win_tcy1 = tilec->win_y1;
2646
2647     if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
2648         return OPJ_TRUE;
2649     }
2650
2651     sa = opj_dwt_init_sparse_array(tilec, numres);
2652     if (sa == NULL) {
2653         return OPJ_FALSE;
2654     }
2655
2656     if (numres == 1U) {
2657         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
2658                        tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
2659                        tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
2660                        tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
2661                        tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
2662                        tilec->data_win,
2663                        1, tr_max->win_x1 - tr_max->win_x0,
2664                        OPJ_TRUE);
2665         assert(ret);
2666         OPJ_UNUSED(ret);
2667         opj_sparse_array_int32_free(sa);
2668         return OPJ_TRUE;
2669     }
2670     h_mem_size = opj_dwt_max_resolution(tr, numres);
2671     /* overflow check */
2672     /* in vertical pass, we process 4 columns at a time */
2673     if (h_mem_size > (SIZE_MAX / (4 * sizeof(OPJ_INT32)))) {
2674         /* FIXME event manager error callback */
2675         opj_sparse_array_int32_free(sa);
2676         return OPJ_FALSE;
2677     }
2678
2679     h_mem_size *= 4 * sizeof(OPJ_INT32);
2680     h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
2681     if (! h.mem) {
2682         /* FIXME event manager error callback */
2683         opj_sparse_array_int32_free(sa);
2684         return OPJ_FALSE;
2685     }
2686
2687     v.mem = h.mem;
2688
2689     for (resno = 1; resno < numres; resno ++) {
2690         OPJ_UINT32 i, j;
2691         /* Window of interest subband-based coordinates */
2692         OPJ_UINT32 win_ll_x0, win_ll_y0, win_ll_x1, win_ll_y1;
2693         OPJ_UINT32 win_hl_x0, win_hl_x1;
2694         OPJ_UINT32 win_lh_y0, win_lh_y1;
2695         /* Window of interest tile-resolution-based coordinates */
2696         OPJ_UINT32 win_tr_x0, win_tr_x1, win_tr_y0, win_tr_y1;
2697         /* Tile-resolution subband-based coordinates */
2698         OPJ_UINT32 tr_ll_x0, tr_ll_y0, tr_hl_x0, tr_lh_y0;
2699
2700         ++tr;
2701
2702         h.sn = (OPJ_INT32)rw;
2703         v.sn = (OPJ_INT32)rh;
2704
2705         rw = (OPJ_UINT32)(tr->x1 - tr->x0);
2706         rh = (OPJ_UINT32)(tr->y1 - tr->y0);
2707
2708         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
2709         h.cas = tr->x0 % 2;
2710
2711         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
2712         v.cas = tr->y0 % 2;
2713
2714         /* Get the subband coordinates for the window of interest */
2715         /* LL band */
2716         opj_dwt_get_band_coordinates(tilec, resno, 0,
2717                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2718                                      &win_ll_x0, &win_ll_y0,
2719                                      &win_ll_x1, &win_ll_y1);
2720
2721         /* HL band */
2722         opj_dwt_get_band_coordinates(tilec, resno, 1,
2723                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2724                                      &win_hl_x0, NULL, &win_hl_x1, NULL);
2725
2726         /* LH band */
2727         opj_dwt_get_band_coordinates(tilec, resno, 2,
2728                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2729                                      NULL, &win_lh_y0, NULL, &win_lh_y1);
2730
2731         /* Beware: band index for non-LL0 resolution are 0=HL, 1=LH and 2=HH */
2732         tr_ll_x0 = (OPJ_UINT32)tr->bands[1].x0;
2733         tr_ll_y0 = (OPJ_UINT32)tr->bands[0].y0;
2734         tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
2735         tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
2736
2737         /* Subtract the origin of the bands for this tile, to the subwindow */
2738         /* of interest band coordinates, so as to get them relative to the */
2739         /* tile */
2740         win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);
2741         win_ll_y0 = opj_uint_subs(win_ll_y0, tr_ll_y0);
2742         win_ll_x1 = opj_uint_subs(win_ll_x1, tr_ll_x0);
2743         win_ll_y1 = opj_uint_subs(win_ll_y1, tr_ll_y0);
2744         win_hl_x0 = opj_uint_subs(win_hl_x0, tr_hl_x0);
2745         win_hl_x1 = opj_uint_subs(win_hl_x1, tr_hl_x0);
2746         win_lh_y0 = opj_uint_subs(win_lh_y0, tr_lh_y0);
2747         win_lh_y1 = opj_uint_subs(win_lh_y1, tr_lh_y0);
2748
2749         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.sn, &win_ll_x0, &win_ll_x1);
2750         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.dn, &win_hl_x0, &win_hl_x1);
2751
2752         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.sn, &win_ll_y0, &win_ll_y1);
2753         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.dn, &win_lh_y0, &win_lh_y1);
2754
2755         /* Compute the tile-resolution-based coordinates for the window of interest */
2756         if (h.cas == 0) {
2757             win_tr_x0 = opj_uint_min(2 * win_ll_x0, 2 * win_hl_x0 + 1);
2758             win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_ll_x1, 2 * win_hl_x1 + 1), rw);
2759         } else {
2760             win_tr_x0 = opj_uint_min(2 * win_hl_x0, 2 * win_ll_x0 + 1);
2761             win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_hl_x1, 2 * win_ll_x1 + 1), rw);
2762         }
2763
2764         if (v.cas == 0) {
2765             win_tr_y0 = opj_uint_min(2 * win_ll_y0, 2 * win_lh_y0 + 1);
2766             win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_ll_y1, 2 * win_lh_y1 + 1), rh);
2767         } else {
2768             win_tr_y0 = opj_uint_min(2 * win_lh_y0, 2 * win_ll_y0 + 1);
2769             win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_lh_y1, 2 * win_ll_y1 + 1), rh);
2770         }
2771
2772         for (j = 0; j < rh; ++j) {
2773             if ((j >= win_ll_y0 && j < win_ll_y1) ||
2774                     (j >= win_lh_y0 + (OPJ_UINT32)v.sn && j < win_lh_y1 + (OPJ_UINT32)v.sn)) {
2775
2776                 /* Avoids dwt.c:1584:44 (in opj_dwt_decode_partial_1): runtime error: */
2777                 /* signed integer overflow: -1094795586 + -1094795586 cannot be represented in type 'int' */
2778                 /* on opj_decompress -i  ../../openjpeg/MAPA.jp2 -o out.tif -d 0,0,256,256 */
2779                 /* This is less extreme than memsetting the whole buffer to 0 */
2780                 /* although we could potentially do better with better handling of edge conditions */
2781                 if (win_tr_x1 >= 1 && win_tr_x1 < rw) {
2782                     h.mem[win_tr_x1 - 1] = 0;
2783                 }
2784                 if (win_tr_x1 < rw) {
2785                     h.mem[win_tr_x1] = 0;
2786                 }
2787
2788                 opj_dwt_interleave_partial_h(h.mem,
2789                                              h.cas,
2790                                              sa,
2791                                              j,
2792                                              (OPJ_UINT32)h.sn,
2793                                              win_ll_x0,
2794                                              win_ll_x1,
2795                                              win_hl_x0,
2796                                              win_hl_x1);
2797                 opj_dwt_decode_partial_1(h.mem, h.dn, h.sn, h.cas,
2798                                          (OPJ_INT32)win_ll_x0,
2799                                          (OPJ_INT32)win_ll_x1,
2800                                          (OPJ_INT32)win_hl_x0,
2801                                          (OPJ_INT32)win_hl_x1);
2802                 if (!opj_sparse_array_int32_write(sa,
2803                                                   win_tr_x0, j,
2804                                                   win_tr_x1, j + 1,
2805                                                   h.mem + win_tr_x0,
2806                                                   1, 0, OPJ_TRUE)) {
2807                     /* FIXME event manager error callback */
2808                     opj_sparse_array_int32_free(sa);
2809                     opj_aligned_free(h.mem);
2810                     return OPJ_FALSE;
2811                 }
2812             }
2813         }
2814
2815         for (i = win_tr_x0; i < win_tr_x1;) {
2816             OPJ_UINT32 nb_cols = opj_uint_min(4U, win_tr_x1 - i);
2817             opj_dwt_interleave_partial_v(v.mem,
2818                                          v.cas,
2819                                          sa,
2820                                          i,
2821                                          nb_cols,
2822                                          (OPJ_UINT32)v.sn,
2823                                          win_ll_y0,
2824                                          win_ll_y1,
2825                                          win_lh_y0,
2826                                          win_lh_y1);
2827             opj_dwt_decode_partial_1_parallel(v.mem, nb_cols, v.dn, v.sn, v.cas,
2828                                               (OPJ_INT32)win_ll_y0,
2829                                               (OPJ_INT32)win_ll_y1,
2830                                               (OPJ_INT32)win_lh_y0,
2831                                               (OPJ_INT32)win_lh_y1);
2832             if (!opj_sparse_array_int32_write(sa,
2833                                               i, win_tr_y0,
2834                                               i + nb_cols, win_tr_y1,
2835                                               v.mem + 4 * win_tr_y0,
2836                                               1, 4, OPJ_TRUE)) {
2837                 /* FIXME event manager error callback */
2838                 opj_sparse_array_int32_free(sa);
2839                 opj_aligned_free(h.mem);
2840                 return OPJ_FALSE;
2841             }
2842
2843             i += nb_cols;
2844         }
2845     }
2846     opj_aligned_free(h.mem);
2847
2848     {
2849         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
2850                        tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
2851                        tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
2852                        tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
2853                        tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
2854                        tilec->data_win,
2855                        1, tr_max->win_x1 - tr_max->win_x0,
2856                        OPJ_TRUE);
2857         assert(ret);
2858         OPJ_UNUSED(ret);
2859     }
2860     opj_sparse_array_int32_free(sa);
2861     return OPJ_TRUE;
2862 }
2863
2864 static void opj_v8dwt_interleave_h(opj_v8dwt_t* OPJ_RESTRICT dwt,
2865                                    OPJ_FLOAT32* OPJ_RESTRICT a,
2866                                    OPJ_UINT32 width,
2867                                    OPJ_UINT32 remaining_height)
2868 {
2869     OPJ_FLOAT32* OPJ_RESTRICT bi = (OPJ_FLOAT32*)(dwt->wavelet + dwt->cas);
2870     OPJ_UINT32 i, k;
2871     OPJ_UINT32 x0 = dwt->win_l_x0;
2872     OPJ_UINT32 x1 = dwt->win_l_x1;
2873
2874     for (k = 0; k < 2; ++k) {
2875         if (remaining_height >= NB_ELTS_V8 && ((OPJ_SIZE_T) a & 0x0f) == 0 &&
2876                 ((OPJ_SIZE_T) bi & 0x0f) == 0) {
2877             /* Fast code path */
2878             for (i = x0; i < x1; ++i) {
2879                 OPJ_UINT32 j = i;
2880                 OPJ_FLOAT32* OPJ_RESTRICT dst = bi + i * 2 * NB_ELTS_V8;
2881                 dst[0] = a[j];
2882                 j += width;
2883                 dst[1] = a[j];
2884                 j += width;
2885                 dst[2] = a[j];
2886                 j += width;
2887                 dst[3] = a[j];
2888                 j += width;
2889                 dst[4] = a[j];
2890                 j += width;
2891                 dst[5] = a[j];
2892                 j += width;
2893                 dst[6] = a[j];
2894                 j += width;
2895                 dst[7] = a[j];
2896             }
2897         } else {
2898             /* Slow code path */
2899             for (i = x0; i < x1; ++i) {
2900                 OPJ_UINT32 j = i;
2901                 OPJ_FLOAT32* OPJ_RESTRICT dst = bi + i * 2 * NB_ELTS_V8;
2902                 dst[0] = a[j];
2903                 j += width;
2904                 if (remaining_height == 1) {
2905                     continue;
2906                 }
2907                 dst[1] = a[j];
2908                 j += width;
2909                 if (remaining_height == 2) {
2910                     continue;
2911                 }
2912                 dst[2] = a[j];
2913                 j += width;
2914                 if (remaining_height == 3) {
2915                     continue;
2916                 }
2917                 dst[3] = a[j];
2918                 j += width;
2919                 if (remaining_height == 4) {
2920                     continue;
2921                 }
2922                 dst[4] = a[j];
2923                 j += width;
2924                 if (remaining_height == 5) {
2925                     continue;
2926                 }
2927                 dst[5] = a[j];
2928                 j += width;
2929                 if (remaining_height == 6) {
2930                     continue;
2931                 }
2932                 dst[6] = a[j];
2933                 j += width;
2934                 if (remaining_height == 7) {
2935                     continue;
2936                 }
2937                 dst[7] = a[j];
2938             }
2939         }
2940
2941         bi = (OPJ_FLOAT32*)(dwt->wavelet + 1 - dwt->cas);
2942         a += dwt->sn;
2943         x0 = dwt->win_h_x0;
2944         x1 = dwt->win_h_x1;
2945     }
2946 }
2947
2948 static void opj_v8dwt_interleave_partial_h(opj_v8dwt_t* dwt,
2949         opj_sparse_array_int32_t* sa,
2950         OPJ_UINT32 sa_line,
2951         OPJ_UINT32 remaining_height)
2952 {
2953     OPJ_UINT32 i;
2954     for (i = 0; i < remaining_height; i++) {
2955         OPJ_BOOL ret;
2956         ret = opj_sparse_array_int32_read(sa,
2957                                           dwt->win_l_x0, sa_line + i,
2958                                           dwt->win_l_x1, sa_line + i + 1,
2959                                           /* Nasty cast from float* to int32* */
2960                                           (OPJ_INT32*)(dwt->wavelet + dwt->cas + 2 * dwt->win_l_x0) + i,
2961                                           2 * NB_ELTS_V8, 0, OPJ_TRUE);
2962         assert(ret);
2963         ret = opj_sparse_array_int32_read(sa,
2964                                           (OPJ_UINT32)dwt->sn + dwt->win_h_x0, sa_line + i,
2965                                           (OPJ_UINT32)dwt->sn + dwt->win_h_x1, sa_line + i + 1,
2966                                           /* Nasty cast from float* to int32* */
2967                                           (OPJ_INT32*)(dwt->wavelet + 1 - dwt->cas + 2 * dwt->win_h_x0) + i,
2968                                           2 * NB_ELTS_V8, 0, OPJ_TRUE);
2969         assert(ret);
2970         OPJ_UNUSED(ret);
2971     }
2972 }
2973
2974 static INLINE void opj_v8dwt_interleave_v(opj_v8dwt_t* OPJ_RESTRICT dwt,
2975         OPJ_FLOAT32* OPJ_RESTRICT a,
2976         OPJ_UINT32 width,
2977         OPJ_UINT32 nb_elts_read)
2978 {
2979     opj_v8_t* OPJ_RESTRICT bi = dwt->wavelet + dwt->cas;
2980     OPJ_UINT32 i;
2981
2982     for (i = dwt->win_l_x0; i < dwt->win_l_x1; ++i) {
2983         memcpy(&bi[i * 2], &a[i * (OPJ_SIZE_T)width],
2984                (OPJ_SIZE_T)nb_elts_read * sizeof(OPJ_FLOAT32));
2985     }
2986
2987     a += (OPJ_UINT32)dwt->sn * (OPJ_SIZE_T)width;
2988     bi = dwt->wavelet + 1 - dwt->cas;
2989
2990     for (i = dwt->win_h_x0; i < dwt->win_h_x1; ++i) {
2991         memcpy(&bi[i * 2], &a[i * (OPJ_SIZE_T)width],
2992                (OPJ_SIZE_T)nb_elts_read * sizeof(OPJ_FLOAT32));
2993     }
2994 }
2995
2996 static void opj_v8dwt_interleave_partial_v(opj_v8dwt_t* OPJ_RESTRICT dwt,
2997         opj_sparse_array_int32_t* sa,
2998         OPJ_UINT32 sa_col,
2999         OPJ_UINT32 nb_elts_read)
3000 {
3001     OPJ_BOOL ret;
3002     ret = opj_sparse_array_int32_read(sa,
3003                                       sa_col, dwt->win_l_x0,
3004                                       sa_col + nb_elts_read, dwt->win_l_x1,
3005                                       (OPJ_INT32*)(dwt->wavelet + dwt->cas + 2 * dwt->win_l_x0),
3006                                       1, 2 * NB_ELTS_V8, OPJ_TRUE);
3007     assert(ret);
3008     ret = opj_sparse_array_int32_read(sa,
3009                                       sa_col, (OPJ_UINT32)dwt->sn + dwt->win_h_x0,
3010                                       sa_col + nb_elts_read, (OPJ_UINT32)dwt->sn + dwt->win_h_x1,
3011                                       (OPJ_INT32*)(dwt->wavelet + 1 - dwt->cas + 2 * dwt->win_h_x0),
3012                                       1, 2 * NB_ELTS_V8, OPJ_TRUE);
3013     assert(ret);
3014     OPJ_UNUSED(ret);
3015 }
3016
3017 #ifdef __SSE__
3018
3019 static void opj_v8dwt_decode_step1_sse(opj_v8_t* w,
3020                                        OPJ_UINT32 start,
3021                                        OPJ_UINT32 end,
3022                                        const __m128 c)
3023 {
3024     __m128* OPJ_RESTRICT vw = (__m128*) w;
3025     OPJ_UINT32 i = start;
3026     /* To be adapted if NB_ELTS_V8 changes */
3027     vw += 4 * start;
3028     /* Note: attempt at loop unrolling x2 doesn't help */
3029     for (; i < end; ++i, vw += 4) {
3030         vw[0] = _mm_mul_ps(vw[0], c);
3031         vw[1] = _mm_mul_ps(vw[1], c);
3032     }
3033 }
3034
3035 static void opj_v8dwt_decode_step2_sse(opj_v8_t* l, opj_v8_t* w,
3036                                        OPJ_UINT32 start,
3037                                        OPJ_UINT32 end,
3038                                        OPJ_UINT32 m,
3039                                        __m128 c)
3040 {
3041     __m128* OPJ_RESTRICT vl = (__m128*) l;
3042     __m128* OPJ_RESTRICT vw = (__m128*) w;
3043     /* To be adapted if NB_ELTS_V8 changes */
3044     OPJ_UINT32 i;
3045     OPJ_UINT32 imax = opj_uint_min(end, m);
3046     if (start == 0) {
3047         if (imax >= 1) {
3048             vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(_mm_add_ps(vl[0], vw[0]), c));
3049             vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(_mm_add_ps(vl[1], vw[1]), c));
3050             vw += 4;
3051             start = 1;
3052         }
3053     } else {
3054         vw += start * 4;
3055     }
3056
3057     i = start;
3058     /* Note: attempt at loop unrolling x2 doesn't help */
3059     for (; i < imax; ++i) {
3060         vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(_mm_add_ps(vw[-4], vw[0]), c));
3061         vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(_mm_add_ps(vw[-3], vw[1]), c));
3062         vw += 4;
3063     }
3064     if (m < end) {
3065         assert(m + 1 == end);
3066         c = _mm_add_ps(c, c);
3067         vw[-2] = _mm_add_ps(vw[-2], _mm_mul_ps(c, vw[-4]));
3068         vw[-1] = _mm_add_ps(vw[-1], _mm_mul_ps(c, vw[-3]));
3069     }
3070 }
3071
3072 #else
3073
3074 static void opj_v8dwt_decode_step1(opj_v8_t* w,
3075                                    OPJ_UINT32 start,
3076                                    OPJ_UINT32 end,
3077                                    const OPJ_FLOAT32 c)
3078 {
3079     OPJ_FLOAT32* OPJ_RESTRICT fw = (OPJ_FLOAT32*) w;
3080     OPJ_UINT32 i;
3081     /* To be adapted if NB_ELTS_V8 changes */
3082     for (i = start; i < end; ++i) {
3083         fw[i * 2 * 8    ] = fw[i * 2 * 8    ] * c;
3084         fw[i * 2 * 8 + 1] = fw[i * 2 * 8 + 1] * c;
3085         fw[i * 2 * 8 + 2] = fw[i * 2 * 8 + 2] * c;
3086         fw[i * 2 * 8 + 3] = fw[i * 2 * 8 + 3] * c;
3087         fw[i * 2 * 8 + 4] = fw[i * 2 * 8 + 4] * c;
3088         fw[i * 2 * 8 + 5] = fw[i * 2 * 8 + 5] * c;
3089         fw[i * 2 * 8 + 6] = fw[i * 2 * 8 + 6] * c;
3090         fw[i * 2 * 8 + 7] = fw[i * 2 * 8 + 7] * c;
3091     }
3092 }
3093
3094 static void opj_v8dwt_decode_step2(opj_v8_t* l, opj_v8_t* w,
3095                                    OPJ_UINT32 start,
3096                                    OPJ_UINT32 end,
3097                                    OPJ_UINT32 m,
3098                                    OPJ_FLOAT32 c)
3099 {
3100     OPJ_FLOAT32* fl = (OPJ_FLOAT32*) l;
3101     OPJ_FLOAT32* fw = (OPJ_FLOAT32*) w;
3102     OPJ_UINT32 i;
3103     OPJ_UINT32 imax = opj_uint_min(end, m);
3104     if (start > 0) {
3105         fw += 2 * NB_ELTS_V8 * start;
3106         fl = fw - 2 * NB_ELTS_V8;
3107     }
3108     /* To be adapted if NB_ELTS_V8 changes */
3109     for (i = start; i < imax; ++i) {
3110         fw[-8] = fw[-8] + ((fl[0] + fw[0]) * c);
3111         fw[-7] = fw[-7] + ((fl[1] + fw[1]) * c);
3112         fw[-6] = fw[-6] + ((fl[2] + fw[2]) * c);
3113         fw[-5] = fw[-5] + ((fl[3] + fw[3]) * c);
3114         fw[-4] = fw[-4] + ((fl[4] + fw[4]) * c);
3115         fw[-3] = fw[-3] + ((fl[5] + fw[5]) * c);
3116         fw[-2] = fw[-2] + ((fl[6] + fw[6]) * c);
3117         fw[-1] = fw[-1] + ((fl[7] + fw[7]) * c);
3118         fl = fw;
3119         fw += 2 * NB_ELTS_V8;
3120     }
3121     if (m < end) {
3122         assert(m + 1 == end);
3123         c += c;
3124         fw[-8] = fw[-8] + fl[0] * c;
3125         fw[-7] = fw[-7] + fl[1] * c;
3126         fw[-6] = fw[-6] + fl[2] * c;
3127         fw[-5] = fw[-5] + fl[3] * c;
3128         fw[-4] = fw[-4] + fl[4] * c;
3129         fw[-3] = fw[-3] + fl[5] * c;
3130         fw[-2] = fw[-2] + fl[6] * c;
3131         fw[-1] = fw[-1] + fl[7] * c;
3132     }
3133 }
3134
3135 #endif
3136
3137 /* <summary>                             */
3138 /* Inverse 9-7 wavelet transform in 1-D. */
3139 /* </summary>                            */
3140 static void opj_v8dwt_decode(opj_v8dwt_t* OPJ_RESTRICT dwt)
3141 {
3142     OPJ_INT32 a, b;
3143     /* BUG_WEIRD_TWO_INVK (look for this identifier in tcd.c) */
3144     /* Historic value for 2 / opj_invK */
3145     /* Normally, we should use invK, but if we do so, we have failures in the */
3146     /* conformance test, due to MSE and peak errors significantly higher than */
3147     /* accepted value */
3148     /* Due to using two_invK instead of invK, we have to compensate in tcd.c */
3149     /* the computation of the stepsize for the non LL subbands */
3150     const float two_invK = 1.625732422f;
3151     if (dwt->cas == 0) {
3152         if (!((dwt->dn > 0) || (dwt->sn > 1))) {
3153             return;
3154         }
3155         a = 0;
3156         b = 1;
3157     } else {
3158         if (!((dwt->sn > 0) || (dwt->dn > 1))) {
3159             return;
3160         }
3161         a = 1;
3162         b = 0;
3163     }
3164 #ifdef __SSE__
3165     opj_v8dwt_decode_step1_sse(dwt->wavelet + a, dwt->win_l_x0, dwt->win_l_x1,
3166                                _mm_set1_ps(opj_K));
3167     opj_v8dwt_decode_step1_sse(dwt->wavelet + b, dwt->win_h_x0, dwt->win_h_x1,
3168                                _mm_set1_ps(two_invK));
3169     opj_v8dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1,
3170                                dwt->win_l_x0, dwt->win_l_x1,
3171                                (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
3172                                _mm_set1_ps(-opj_dwt_delta));
3173     opj_v8dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1,
3174                                dwt->win_h_x0, dwt->win_h_x1,
3175                                (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
3176                                _mm_set1_ps(-opj_dwt_gamma));
3177     opj_v8dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1,
3178                                dwt->win_l_x0, dwt->win_l_x1,
3179                                (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
3180                                _mm_set1_ps(-opj_dwt_beta));
3181     opj_v8dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1,
3182                                dwt->win_h_x0, dwt->win_h_x1,
3183                                (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
3184                                _mm_set1_ps(-opj_dwt_alpha));
3185 #else
3186     opj_v8dwt_decode_step1(dwt->wavelet + a, dwt->win_l_x0, dwt->win_l_x1,
3187                            opj_K);
3188     opj_v8dwt_decode_step1(dwt->wavelet + b, dwt->win_h_x0, dwt->win_h_x1,
3189                            two_invK);
3190     opj_v8dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1,
3191                            dwt->win_l_x0, dwt->win_l_x1,
3192                            (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
3193                            -opj_dwt_delta);
3194     opj_v8dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1,
3195                            dwt->win_h_x0, dwt->win_h_x1,
3196                            (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
3197                            -opj_dwt_gamma);
3198     opj_v8dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1,
3199                            dwt->win_l_x0, dwt->win_l_x1,
3200                            (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
3201                            -opj_dwt_beta);
3202     opj_v8dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1,
3203                            dwt->win_h_x0, dwt->win_h_x1,
3204                            (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
3205                            -opj_dwt_alpha);
3206 #endif
3207 }
3208
3209 typedef struct {
3210     opj_v8dwt_t h;
3211     OPJ_UINT32 rw;
3212     OPJ_UINT32 w;
3213     OPJ_FLOAT32 * OPJ_RESTRICT aj;
3214     OPJ_UINT32 nb_rows;
3215 } opj_dwt97_decode_h_job_t;
3216
3217 static void opj_dwt97_decode_h_func(void* user_data, opj_tls_t* tls)
3218 {
3219     OPJ_UINT32 j;
3220     opj_dwt97_decode_h_job_t* job;
3221     OPJ_FLOAT32 * OPJ_RESTRICT aj;
3222     OPJ_UINT32 w;
3223     (void)tls;
3224
3225     job = (opj_dwt97_decode_h_job_t*)user_data;
3226     w = job->w;
3227
3228     assert((job->nb_rows % NB_ELTS_V8) == 0);
3229
3230     aj = job->aj;
3231     for (j = 0; j + NB_ELTS_V8 <= job->nb_rows; j += NB_ELTS_V8) {
3232         OPJ_UINT32 k;
3233         opj_v8dwt_interleave_h(&job->h, aj, job->w, NB_ELTS_V8);
3234         opj_v8dwt_decode(&job->h);
3235
3236         /* To be adapted if NB_ELTS_V8 changes */
3237         for (k = 0; k < job->rw; k++) {
3238             aj[k      ] = job->h.wavelet[k].f[0];
3239             aj[k + (OPJ_SIZE_T)w  ] = job->h.wavelet[k].f[1];
3240             aj[k + (OPJ_SIZE_T)w * 2] = job->h.wavelet[k].f[2];
3241             aj[k + (OPJ_SIZE_T)w * 3] = job->h.wavelet[k].f[3];
3242         }
3243         for (k = 0; k < job->rw; k++) {
3244             aj[k + (OPJ_SIZE_T)w * 4] = job->h.wavelet[k].f[4];
3245             aj[k + (OPJ_SIZE_T)w * 5] = job->h.wavelet[k].f[5];
3246             aj[k + (OPJ_SIZE_T)w * 6] = job->h.wavelet[k].f[6];
3247             aj[k + (OPJ_SIZE_T)w * 7] = job->h.wavelet[k].f[7];
3248         }
3249
3250         aj += w * NB_ELTS_V8;
3251     }
3252
3253     opj_aligned_free(job->h.wavelet);
3254     opj_free(job);
3255 }
3256
3257
3258 typedef struct {
3259     opj_v8dwt_t v;
3260     OPJ_UINT32 rh;
3261     OPJ_UINT32 w;
3262     OPJ_FLOAT32 * OPJ_RESTRICT aj;
3263     OPJ_UINT32 nb_columns;
3264 } opj_dwt97_decode_v_job_t;
3265
3266 static void opj_dwt97_decode_v_func(void* user_data, opj_tls_t* tls)
3267 {
3268     OPJ_UINT32 j;
3269     opj_dwt97_decode_v_job_t* job;
3270     OPJ_FLOAT32 * OPJ_RESTRICT aj;
3271     (void)tls;
3272
3273     job = (opj_dwt97_decode_v_job_t*)user_data;
3274
3275     assert((job->nb_columns % NB_ELTS_V8) == 0);
3276
3277     aj = job->aj;
3278     for (j = 0; j + NB_ELTS_V8 <= job->nb_columns; j += NB_ELTS_V8) {
3279         OPJ_UINT32 k;
3280
3281         opj_v8dwt_interleave_v(&job->v, aj, job->w, NB_ELTS_V8);
3282         opj_v8dwt_decode(&job->v);
3283
3284         for (k = 0; k < job->rh; ++k) {
3285             memcpy(&aj[k * (OPJ_SIZE_T)job->w], &job->v.wavelet[k],
3286                    NB_ELTS_V8 * sizeof(OPJ_FLOAT32));
3287         }
3288         aj += NB_ELTS_V8;
3289     }
3290
3291     opj_aligned_free(job->v.wavelet);
3292     opj_free(job);
3293 }
3294
3295
3296 /* <summary>                             */
3297 /* Inverse 9-7 wavelet transform in 2-D. */
3298 /* </summary>                            */
3299 static
3300 OPJ_BOOL opj_dwt_decode_tile_97(opj_thread_pool_t* tp,
3301                                 opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
3302                                 OPJ_UINT32 numres)
3303 {
3304     opj_v8dwt_t h;
3305     opj_v8dwt_t v;
3306
3307     opj_tcd_resolution_t* res = tilec->resolutions;
3308
3309     OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 -
3310                                  res->x0);    /* width of the resolution level computed */
3311     OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 -
3312                                  res->y0);    /* height of the resolution level computed */
3313
3314     OPJ_UINT32 w = (OPJ_UINT32)(tilec->resolutions[tilec->minimum_num_resolutions -
3315                                                                1].x1 -
3316                                 tilec->resolutions[tilec->minimum_num_resolutions - 1].x0);
3317
3318     OPJ_SIZE_T l_data_size;
3319     const int num_threads = opj_thread_pool_get_thread_count(tp);
3320
3321     if (numres == 1) {
3322         return OPJ_TRUE;
3323     }
3324
3325     l_data_size = opj_dwt_max_resolution(res, numres);
3326     /* overflow check */
3327     if (l_data_size > (SIZE_MAX / sizeof(opj_v8_t))) {
3328         /* FIXME event manager error callback */
3329         return OPJ_FALSE;
3330     }
3331     h.wavelet = (opj_v8_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v8_t));
3332     if (!h.wavelet) {
3333         /* FIXME event manager error callback */
3334         return OPJ_FALSE;
3335     }
3336     v.wavelet = h.wavelet;
3337
3338     while (--numres) {
3339         OPJ_FLOAT32 * OPJ_RESTRICT aj = (OPJ_FLOAT32*) tilec->data;
3340         OPJ_UINT32 j;
3341
3342         h.sn = (OPJ_INT32)rw;
3343         v.sn = (OPJ_INT32)rh;
3344
3345         ++res;
3346
3347         rw = (OPJ_UINT32)(res->x1 -
3348                           res->x0);   /* width of the resolution level computed */
3349         rh = (OPJ_UINT32)(res->y1 -
3350                           res->y0);   /* height of the resolution level computed */
3351
3352         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
3353         h.cas = res->x0 % 2;
3354
3355         h.win_l_x0 = 0;
3356         h.win_l_x1 = (OPJ_UINT32)h.sn;
3357         h.win_h_x0 = 0;
3358         h.win_h_x1 = (OPJ_UINT32)h.dn;
3359
3360         if (num_threads <= 1 || rh < 2 * NB_ELTS_V8) {
3361             for (j = 0; j + (NB_ELTS_V8 - 1) < rh; j += NB_ELTS_V8) {
3362                 OPJ_UINT32 k;
3363                 opj_v8dwt_interleave_h(&h, aj, w, NB_ELTS_V8);
3364                 opj_v8dwt_decode(&h);
3365
3366                 /* To be adapted if NB_ELTS_V8 changes */
3367                 for (k = 0; k < rw; k++) {
3368                     aj[k      ] = h.wavelet[k].f[0];
3369                     aj[k + (OPJ_SIZE_T)w  ] = h.wavelet[k].f[1];
3370                     aj[k + (OPJ_SIZE_T)w * 2] = h.wavelet[k].f[2];
3371                     aj[k + (OPJ_SIZE_T)w * 3] = h.wavelet[k].f[3];
3372                 }
3373                 for (k = 0; k < rw; k++) {
3374                     aj[k + (OPJ_SIZE_T)w * 4] = h.wavelet[k].f[4];
3375                     aj[k + (OPJ_SIZE_T)w * 5] = h.wavelet[k].f[5];
3376                     aj[k + (OPJ_SIZE_T)w * 6] = h.wavelet[k].f[6];
3377                     aj[k + (OPJ_SIZE_T)w * 7] = h.wavelet[k].f[7];
3378                 }
3379
3380                 aj += w * NB_ELTS_V8;
3381             }
3382         } else {
3383             OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
3384             OPJ_UINT32 step_j;
3385
3386             if ((rh / NB_ELTS_V8) < num_jobs) {
3387                 num_jobs = rh / NB_ELTS_V8;
3388             }
3389             step_j = ((rh / num_jobs) / NB_ELTS_V8) * NB_ELTS_V8;
3390             for (j = 0; j < num_jobs; j++) {
3391                 opj_dwt97_decode_h_job_t* job;
3392
3393                 job = (opj_dwt97_decode_h_job_t*) opj_malloc(sizeof(opj_dwt97_decode_h_job_t));
3394                 if (!job) {
3395                     opj_thread_pool_wait_completion(tp, 0);
3396                     opj_aligned_free(h.wavelet);
3397                     return OPJ_FALSE;
3398                 }
3399                 job->h.wavelet = (opj_v8_t*)opj_aligned_malloc(l_data_size * sizeof(opj_v8_t));
3400                 if (!job->h.wavelet) {
3401                     opj_thread_pool_wait_completion(tp, 0);
3402                     opj_free(job);
3403                     opj_aligned_free(h.wavelet);
3404                     return OPJ_FALSE;
3405                 }
3406                 job->h.dn = h.dn;
3407                 job->h.sn = h.sn;
3408                 job->h.cas = h.cas;
3409                 job->h.win_l_x0 = h.win_l_x0;
3410                 job->h.win_l_x1 = h.win_l_x1;
3411                 job->h.win_h_x0 = h.win_h_x0;
3412                 job->h.win_h_x1 = h.win_h_x1;
3413                 job->rw = rw;
3414                 job->w = w;
3415                 job->aj = aj;
3416                 job->nb_rows = (j + 1 == num_jobs) ? (rh & (OPJ_UINT32)~
3417                                                       (NB_ELTS_V8 - 1)) - j * step_j : step_j;
3418                 aj += w * job->nb_rows;
3419                 opj_thread_pool_submit_job(tp, opj_dwt97_decode_h_func, job);
3420             }
3421             opj_thread_pool_wait_completion(tp, 0);
3422             j = rh & (OPJ_UINT32)~(NB_ELTS_V8 - 1);
3423         }
3424
3425         if (j < rh) {
3426             OPJ_UINT32 k;
3427             opj_v8dwt_interleave_h(&h, aj, w, rh - j);
3428             opj_v8dwt_decode(&h);
3429             for (k = 0; k < rw; k++) {
3430                 OPJ_UINT32 l;
3431                 for (l = 0; l < rh - j; l++) {
3432                     aj[k + (OPJ_SIZE_T)w  * l ] = h.wavelet[k].f[l];
3433                 }
3434             }
3435         }
3436
3437         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
3438         v.cas = res->y0 % 2;
3439         v.win_l_x0 = 0;
3440         v.win_l_x1 = (OPJ_UINT32)v.sn;
3441         v.win_h_x0 = 0;
3442         v.win_h_x1 = (OPJ_UINT32)v.dn;
3443
3444         aj = (OPJ_FLOAT32*) tilec->data;
3445         if (num_threads <= 1 || rw < 2 * NB_ELTS_V8) {
3446             for (j = rw; j > (NB_ELTS_V8 - 1); j -= NB_ELTS_V8) {
3447                 OPJ_UINT32 k;
3448
3449                 opj_v8dwt_interleave_v(&v, aj, w, NB_ELTS_V8);
3450                 opj_v8dwt_decode(&v);
3451
3452                 for (k = 0; k < rh; ++k) {
3453                     memcpy(&aj[k * (OPJ_SIZE_T)w], &v.wavelet[k], NB_ELTS_V8 * sizeof(OPJ_FLOAT32));
3454                 }
3455                 aj += NB_ELTS_V8;
3456             }
3457         } else {
3458             /* "bench_dwt -I" shows that scaling is poor, likely due to RAM
3459                 transfer being the limiting factor. So limit the number of
3460                 threads.
3461              */
3462             OPJ_UINT32 num_jobs = opj_uint_max((OPJ_UINT32)num_threads / 2, 2U);
3463             OPJ_UINT32 step_j;
3464
3465             if ((rw / NB_ELTS_V8) < num_jobs) {
3466                 num_jobs = rw / NB_ELTS_V8;
3467             }
3468             step_j = ((rw / num_jobs) / NB_ELTS_V8) * NB_ELTS_V8;
3469             for (j = 0; j < num_jobs; j++) {
3470                 opj_dwt97_decode_v_job_t* job;
3471
3472                 job = (opj_dwt97_decode_v_job_t*) opj_malloc(sizeof(opj_dwt97_decode_v_job_t));
3473                 if (!job) {
3474                     opj_thread_pool_wait_completion(tp, 0);
3475                     opj_aligned_free(h.wavelet);
3476                     return OPJ_FALSE;
3477                 }
3478                 job->v.wavelet = (opj_v8_t*)opj_aligned_malloc(l_data_size * sizeof(opj_v8_t));
3479                 if (!job->v.wavelet) {
3480                     opj_thread_pool_wait_completion(tp, 0);
3481                     opj_free(job);
3482                     opj_aligned_free(h.wavelet);
3483                     return OPJ_FALSE;
3484                 }
3485                 job->v.dn = v.dn;
3486                 job->v.sn = v.sn;
3487                 job->v.cas = v.cas;
3488                 job->v.win_l_x0 = v.win_l_x0;
3489                 job->v.win_l_x1 = v.win_l_x1;
3490                 job->v.win_h_x0 = v.win_h_x0;
3491                 job->v.win_h_x1 = v.win_h_x1;
3492                 job->rh = rh;
3493                 job->w = w;
3494                 job->aj = aj;
3495                 job->nb_columns = (j + 1 == num_jobs) ? (rw & (OPJ_UINT32)~
3496                                   (NB_ELTS_V8 - 1)) - j * step_j : step_j;
3497                 aj += job->nb_columns;
3498                 opj_thread_pool_submit_job(tp, opj_dwt97_decode_v_func, job);
3499             }
3500             opj_thread_pool_wait_completion(tp, 0);
3501         }
3502
3503         if (rw & (NB_ELTS_V8 - 1)) {
3504             OPJ_UINT32 k;
3505
3506             j = rw & (NB_ELTS_V8 - 1);
3507
3508             opj_v8dwt_interleave_v(&v, aj, w, j);
3509             opj_v8dwt_decode(&v);
3510
3511             for (k = 0; k < rh; ++k) {
3512                 memcpy(&aj[k * (OPJ_SIZE_T)w], &v.wavelet[k],
3513                        (OPJ_SIZE_T)j * sizeof(OPJ_FLOAT32));
3514             }
3515         }
3516     }
3517
3518     opj_aligned_free(h.wavelet);
3519     return OPJ_TRUE;
3520 }
3521
3522 static
3523 OPJ_BOOL opj_dwt_decode_partial_97(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
3524                                    OPJ_UINT32 numres)
3525 {
3526     opj_sparse_array_int32_t* sa;
3527     opj_v8dwt_t h;
3528     opj_v8dwt_t v;
3529     OPJ_UINT32 resno;
3530     /* This value matches the maximum left/right extension given in tables */
3531     /* F.2 and F.3 of the standard. Note: in opj_tcd_is_subband_area_of_interest() */
3532     /* we currently use 3. */
3533     const OPJ_UINT32 filter_width = 4U;
3534
3535     opj_tcd_resolution_t* tr = tilec->resolutions;
3536     opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
3537
3538     OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
3539                                  tr->x0);    /* width of the resolution level computed */
3540     OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
3541                                  tr->y0);    /* height of the resolution level computed */
3542
3543     OPJ_SIZE_T l_data_size;
3544
3545     /* Compute the intersection of the area of interest, expressed in tile coordinates */
3546     /* with the tile coordinates */
3547     OPJ_UINT32 win_tcx0 = tilec->win_x0;
3548     OPJ_UINT32 win_tcy0 = tilec->win_y0;
3549     OPJ_UINT32 win_tcx1 = tilec->win_x1;
3550     OPJ_UINT32 win_tcy1 = tilec->win_y1;
3551
3552     if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
3553         return OPJ_TRUE;
3554     }
3555
3556     sa = opj_dwt_init_sparse_array(tilec, numres);
3557     if (sa == NULL) {
3558         return OPJ_FALSE;
3559     }
3560
3561     if (numres == 1U) {
3562         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
3563                        tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
3564                        tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
3565                        tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
3566                        tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
3567                        tilec->data_win,
3568                        1, tr_max->win_x1 - tr_max->win_x0,
3569                        OPJ_TRUE);
3570         assert(ret);
3571         OPJ_UNUSED(ret);
3572         opj_sparse_array_int32_free(sa);
3573         return OPJ_TRUE;
3574     }
3575
3576     l_data_size = opj_dwt_max_resolution(tr, numres);
3577     /* overflow check */
3578     if (l_data_size > (SIZE_MAX / sizeof(opj_v8_t))) {
3579         /* FIXME event manager error callback */
3580         opj_sparse_array_int32_free(sa);
3581         return OPJ_FALSE;
3582     }
3583     h.wavelet = (opj_v8_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v8_t));
3584     if (!h.wavelet) {
3585         /* FIXME event manager error callback */
3586         opj_sparse_array_int32_free(sa);
3587         return OPJ_FALSE;
3588     }
3589     v.wavelet = h.wavelet;
3590
3591     for (resno = 1; resno < numres; resno ++) {
3592         OPJ_UINT32 j;
3593         /* Window of interest subband-based coordinates */
3594         OPJ_UINT32 win_ll_x0, win_ll_y0, win_ll_x1, win_ll_y1;
3595         OPJ_UINT32 win_hl_x0, win_hl_x1;
3596         OPJ_UINT32 win_lh_y0, win_lh_y1;
3597         /* Window of interest tile-resolution-based coordinates */
3598         OPJ_UINT32 win_tr_x0, win_tr_x1, win_tr_y0, win_tr_y1;
3599         /* Tile-resolution subband-based coordinates */
3600         OPJ_UINT32 tr_ll_x0, tr_ll_y0, tr_hl_x0, tr_lh_y0;
3601
3602         ++tr;
3603
3604         h.sn = (OPJ_INT32)rw;
3605         v.sn = (OPJ_INT32)rh;
3606
3607         rw = (OPJ_UINT32)(tr->x1 - tr->x0);
3608         rh = (OPJ_UINT32)(tr->y1 - tr->y0);
3609
3610         h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
3611         h.cas = tr->x0 % 2;
3612
3613         v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
3614         v.cas = tr->y0 % 2;
3615
3616         /* Get the subband coordinates for the window of interest */
3617         /* LL band */
3618         opj_dwt_get_band_coordinates(tilec, resno, 0,
3619                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
3620                                      &win_ll_x0, &win_ll_y0,
3621                                      &win_ll_x1, &win_ll_y1);
3622
3623         /* HL band */
3624         opj_dwt_get_band_coordinates(tilec, resno, 1,
3625                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
3626                                      &win_hl_x0, NULL, &win_hl_x1, NULL);
3627
3628         /* LH band */
3629         opj_dwt_get_band_coordinates(tilec, resno, 2,
3630                                      win_tcx0, win_tcy0, win_tcx1, win_tcy1,
3631                                      NULL, &win_lh_y0, NULL, &win_lh_y1);
3632
3633         /* Beware: band index for non-LL0 resolution are 0=HL, 1=LH and 2=HH */
3634         tr_ll_x0 = (OPJ_UINT32)tr->bands[1].x0;
3635         tr_ll_y0 = (OPJ_UINT32)tr->bands[0].y0;
3636         tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
3637         tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
3638
3639         /* Subtract the origin of the bands for this tile, to the subwindow */
3640         /* of interest band coordinates, so as to get them relative to the */
3641         /* tile */
3642         win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);
3643         win_ll_y0 = opj_uint_subs(win_ll_y0, tr_ll_y0);
3644         win_ll_x1 = opj_uint_subs(win_ll_x1, tr_ll_x0);
3645         win_ll_y1 = opj_uint_subs(win_ll_y1, tr_ll_y0);
3646         win_hl_x0 = opj_uint_subs(win_hl_x0, tr_hl_x0);
3647         win_hl_x1 = opj_uint_subs(win_hl_x1, tr_hl_x0);
3648         win_lh_y0 = opj_uint_subs(win_lh_y0, tr_lh_y0);
3649         win_lh_y1 = opj_uint_subs(win_lh_y1, tr_lh_y0);
3650
3651         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.sn, &win_ll_x0, &win_ll_x1);
3652         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.dn, &win_hl_x0, &win_hl_x1);
3653
3654         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.sn, &win_ll_y0, &win_ll_y1);
3655         opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.dn, &win_lh_y0, &win_lh_y1);
3656
3657         /* Compute the tile-resolution-based coordinates for the window of interest */
3658         if (h.cas == 0) {
3659             win_tr_x0 = opj_uint_min(2 * win_ll_x0, 2 * win_hl_x0 + 1);
3660             win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_ll_x1, 2 * win_hl_x1 + 1), rw);
3661         } else {
3662             win_tr_x0 = opj_uint_min(2 * win_hl_x0, 2 * win_ll_x0 + 1);
3663             win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_hl_x1, 2 * win_ll_x1 + 1), rw);
3664         }
3665
3666         if (v.cas == 0) {
3667             win_tr_y0 = opj_uint_min(2 * win_ll_y0, 2 * win_lh_y0 + 1);
3668             win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_ll_y1, 2 * win_lh_y1 + 1), rh);
3669         } else {
3670             win_tr_y0 = opj_uint_min(2 * win_lh_y0, 2 * win_ll_y0 + 1);
3671             win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_lh_y1, 2 * win_ll_y1 + 1), rh);
3672         }
3673
3674         h.win_l_x0 = win_ll_x0;
3675         h.win_l_x1 = win_ll_x1;
3676         h.win_h_x0 = win_hl_x0;
3677         h.win_h_x1 = win_hl_x1;
3678         for (j = 0; j + (NB_ELTS_V8 - 1) < rh; j += NB_ELTS_V8) {
3679             if ((j + (NB_ELTS_V8 - 1) >= win_ll_y0 && j < win_ll_y1) ||
3680                     (j + (NB_ELTS_V8 - 1) >= win_lh_y0 + (OPJ_UINT32)v.sn &&
3681                      j < win_lh_y1 + (OPJ_UINT32)v.sn)) {
3682                 opj_v8dwt_interleave_partial_h(&h, sa, j, opj_uint_min(NB_ELTS_V8, rh - j));
3683                 opj_v8dwt_decode(&h);
3684                 if (!opj_sparse_array_int32_write(sa,
3685                                                   win_tr_x0, j,
3686                                                   win_tr_x1, j + NB_ELTS_V8,
3687                                                   (OPJ_INT32*)&h.wavelet[win_tr_x0].f[0],
3688                                                   NB_ELTS_V8, 1, OPJ_TRUE)) {
3689                     /* FIXME event manager error callback */
3690                     opj_sparse_array_int32_free(sa);
3691                     opj_aligned_free(h.wavelet);
3692                     return OPJ_FALSE;
3693                 }
3694             }
3695         }
3696
3697         if (j < rh &&
3698                 ((j + (NB_ELTS_V8 - 1) >= win_ll_y0 && j < win_ll_y1) ||
3699                  (j + (NB_ELTS_V8 - 1) >= win_lh_y0 + (OPJ_UINT32)v.sn &&
3700                   j < win_lh_y1 + (OPJ_UINT32)v.sn))) {
3701             opj_v8dwt_interleave_partial_h(&h, sa, j, rh - j);
3702             opj_v8dwt_decode(&h);
3703             if (!opj_sparse_array_int32_write(sa,
3704                                               win_tr_x0, j,
3705                                               win_tr_x1, rh,
3706                                               (OPJ_INT32*)&h.wavelet[win_tr_x0].f[0],
3707                                               NB_ELTS_V8, 1, OPJ_TRUE)) {
3708                 /* FIXME event manager error callback */
3709                 opj_sparse_array_int32_free(sa);
3710                 opj_aligned_free(h.wavelet);
3711                 return OPJ_FALSE;
3712             }
3713         }
3714
3715         v.win_l_x0 = win_ll_y0;
3716         v.win_l_x1 = win_ll_y1;
3717         v.win_h_x0 = win_lh_y0;
3718         v.win_h_x1 = win_lh_y1;
3719         for (j = win_tr_x0; j < win_tr_x1; j += NB_ELTS_V8) {
3720             OPJ_UINT32 nb_elts = opj_uint_min(NB_ELTS_V8, win_tr_x1 - j);
3721
3722             opj_v8dwt_interleave_partial_v(&v, sa, j, nb_elts);
3723             opj_v8dwt_decode(&v);
3724
3725             if (!opj_sparse_array_int32_write(sa,
3726                                               j, win_tr_y0,
3727                                               j + nb_elts, win_tr_y1,
3728                                               (OPJ_INT32*)&h.wavelet[win_tr_y0].f[0],
3729                                               1, NB_ELTS_V8, OPJ_TRUE)) {
3730                 /* FIXME event manager error callback */
3731                 opj_sparse_array_int32_free(sa);
3732                 opj_aligned_free(h.wavelet);
3733                 return OPJ_FALSE;
3734             }
3735         }
3736     }
3737
3738     {
3739         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
3740                        tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
3741                        tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
3742                        tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
3743                        tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
3744                        tilec->data_win,
3745                        1, tr_max->win_x1 - tr_max->win_x0,
3746                        OPJ_TRUE);
3747         assert(ret);
3748         OPJ_UNUSED(ret);
3749     }
3750     opj_sparse_array_int32_free(sa);
3751
3752     opj_aligned_free(h.wavelet);
3753     return OPJ_TRUE;
3754 }
3755
3756
3757 OPJ_BOOL opj_dwt_decode_real(opj_tcd_t *p_tcd,
3758                              opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
3759                              OPJ_UINT32 numres)
3760 {
3761     if (p_tcd->whole_tile_decoding) {
3762         return opj_dwt_decode_tile_97(p_tcd->thread_pool, tilec, numres);
3763     } else {
3764         return opj_dwt_decode_partial_97(tilec, numres);
3765     }
3766 }