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.
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.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
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.
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.
43 #define OPJ_SKIP_POISON
44 #include "opj_includes.h"
47 #include <xmmintrin.h>
50 #include <emmintrin.h>
53 #include <tmmintrin.h>
56 #include <immintrin.h>
60 #pragma GCC poison malloc calloc realloc free
63 /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
66 #define OPJ_WS(i) v->mem[(i)*2]
67 #define OPJ_WD(i) v->mem[(1+(i)*2)]
70 /** Number of int32 values in a AVX2 register */
71 #define VREG_INT_COUNT 8
73 /** Number of int32 values in a SSE2 register */
74 #define VREG_INT_COUNT 4
77 /** Number of columns that we can process in parallel in the vertical pass */
78 #define PARALLEL_COLS_53 (2*VREG_INT_COUNT)
80 /** @name Local data structures */
83 typedef struct dwt_local {
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 */
94 typedef struct v4dwt_local {
96 OPJ_INT32 dn ; /* number of elements in high pass band */
97 OPJ_INT32 sn ; /* number of elements in low pass band */
98 OPJ_INT32 cas ; /* 0 = start on even coord, 1 = start on odd coord */
99 OPJ_UINT32 win_l_x0; /* start coord in low pass band */
100 OPJ_UINT32 win_l_x1; /* end coord in low pass band */
101 OPJ_UINT32 win_h_x0; /* start coord in high pass band */
102 OPJ_UINT32 win_h_x1; /* end coord in high pass band */
105 static const OPJ_FLOAT32 opj_dwt_alpha = 1.586134342f; /* 12994 */
106 static const OPJ_FLOAT32 opj_dwt_beta = 0.052980118f; /* 434 */
107 static const OPJ_FLOAT32 opj_dwt_gamma = -0.882911075f; /* -7233 */
108 static const OPJ_FLOAT32 opj_dwt_delta = -0.443506852f; /* -3633 */
110 static const OPJ_FLOAT32 opj_K = 1.230174105f; /* 10078 */
111 static const OPJ_FLOAT32 opj_c13318 = 1.625732422f;
116 Virtual function type for wavelet transform in 1-D
118 typedef void (*DWT1DFN)(const opj_dwt_t* v);
120 /** @name Local static functions */
124 Forward lazy transform (horizontal)
126 static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
127 OPJ_INT32 sn, OPJ_INT32 cas);
129 Forward lazy transform (vertical)
131 static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
132 OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas);
134 Forward 5-3 wavelet transform in 1-D
136 static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
139 Forward 9-7 wavelet transform in 1-D
141 static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
144 Explicit calculation of the Quantization Stepsizes
146 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
147 opj_stepsize_t *bandno_stepsize);
149 Inverse wavelet transform in 2-D.
151 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
152 opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i);
154 static OPJ_BOOL opj_dwt_decode_partial_tile(
155 opj_tcd_tilecomp_t* tilec,
158 static OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,
159 void (*p_function)(OPJ_INT32 *, OPJ_INT32, OPJ_INT32, OPJ_INT32));
161 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
165 /* Inverse 9-7 wavelet transform in 1-D. */
167 static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt);
169 static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT dwt,
170 OPJ_FLOAT32* OPJ_RESTRICT a,
172 OPJ_UINT32 remaining_height);
174 static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT dwt,
175 OPJ_FLOAT32* OPJ_RESTRICT a,
177 OPJ_UINT32 nb_elts_read);
180 static void opj_v4dwt_decode_step1_sse(opj_v4_t* w,
185 static void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w,
188 OPJ_UINT32 m, __m128 c);
191 static void opj_v4dwt_decode_step1(opj_v4_t* w,
194 const OPJ_FLOAT32 c);
196 static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w,
208 #define OPJ_S(i) a[(i)*2]
209 #define OPJ_D(i) a[(1+(i)*2)]
210 #define OPJ_S_(i) ((i)<0?OPJ_S(0):((i)>=sn?OPJ_S(sn-1):OPJ_S(i)))
211 #define OPJ_D_(i) ((i)<0?OPJ_D(0):((i)>=dn?OPJ_D(dn-1):OPJ_D(i)))
213 #define OPJ_SS_(i) ((i)<0?OPJ_S(0):((i)>=dn?OPJ_S(dn-1):OPJ_S(i)))
214 #define OPJ_DD_(i) ((i)<0?OPJ_D(0):((i)>=sn?OPJ_D(sn-1):OPJ_D(i)))
217 /* This table contains the norms of the 5-3 wavelets for different bands. */
219 /* FIXME! the array should really be extended up to 33 resolution levels */
220 /* See https://github.com/uclouvain/openjpeg/issues/493 */
221 static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
222 {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
223 {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
224 {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
225 {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
229 /* This table contains the norms of the 9-7 wavelets for different bands. */
231 /* FIXME! the array should really be extended up to 33 resolution levels */
232 /* See https://github.com/uclouvain/openjpeg/issues/493 */
233 static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
234 {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
235 {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
236 {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
237 {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
241 ==========================================================
243 ==========================================================
247 /* Forward lazy transform (horizontal). */
249 static void opj_dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
250 OPJ_INT32 sn, OPJ_INT32 cas)
253 OPJ_INT32 * l_dest = b;
254 OPJ_INT32 * l_src = a + cas;
256 for (i = 0; i < sn; ++i) {
264 for (i = 0; i < dn; ++i) {
271 /* Forward lazy transform (vertical). */
273 static void opj_dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn,
274 OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas)
277 OPJ_INT32 * l_dest = b;
278 OPJ_INT32 * l_src = a + cas;
284 } /* b[i*x]=a[2*i+cas]; */
286 l_dest = b + (OPJ_SIZE_T)sn * (OPJ_SIZE_T)x;
294 } /*b[(sn+i)*x]=a[(2*i+1-cas)];*/
297 #ifdef STANDARD_SLOW_VERSION
299 /* Inverse lazy transform (horizontal). */
301 static void opj_dwt_interleave_h(const opj_dwt_t* h, OPJ_INT32 *a)
304 OPJ_INT32 *bi = h->mem + h->cas;
311 bi = h->mem + 1 - h->cas;
320 /* Inverse lazy transform (vertical). */
322 static void opj_dwt_interleave_v(const opj_dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x)
325 OPJ_INT32 *bi = v->mem + v->cas;
332 ai = a + (v->sn * (OPJ_SIZE_T)x);
333 bi = v->mem + 1 - v->cas;
342 #endif /* STANDARD_SLOW_VERSION */
345 /* Forward 5-3 wavelet transform in 1-D. */
347 static void opj_dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
353 if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
354 for (i = 0; i < dn; i++) {
355 OPJ_D(i) -= (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
357 for (i = 0; i < sn; i++) {
358 OPJ_S(i) += (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
362 if (!sn && dn == 1) { /* NEW : CASE ONE ELEMENT */
365 for (i = 0; i < dn; i++) {
366 OPJ_S(i) -= (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
368 for (i = 0; i < sn; i++) {
369 OPJ_D(i) += (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
375 #ifdef STANDARD_SLOW_VERSION
377 /* Inverse 5-3 wavelet transform in 1-D. */
379 static void opj_dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
385 if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
386 for (i = 0; i < sn; i++) {
387 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
389 for (i = 0; i < dn; i++) {
390 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
394 if (!sn && dn == 1) { /* NEW : CASE ONE ELEMENT */
397 for (i = 0; i < sn; i++) {
398 OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
400 for (i = 0; i < dn; i++) {
401 OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
407 static void opj_dwt_decode_1(const opj_dwt_t *v)
409 opj_dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
412 #endif /* STANDARD_SLOW_VERSION */
414 #if !defined(STANDARD_SLOW_VERSION)
415 static void opj_idwt53_h_cas0(OPJ_INT32* tmp,
421 const OPJ_INT32* in_even = &tiledp[0];
422 const OPJ_INT32* in_odd = &tiledp[sn];
424 #ifdef TWO_PASS_VERSION
425 /* For documentation purpose: performs lifting in two iterations, */
426 /* but without explicit interleaving */
431 tmp[0] = in_even[0] - ((in_odd[0] + 1) >> 1);
432 for (i = 2, j = 0; i <= len - 2; i += 2, j++) {
433 tmp[i] = in_even[j + 1] - ((in_odd[j] + in_odd[j + 1] + 2) >> 2);
435 if (len & 1) { /* if len is odd */
436 tmp[len - 1] = in_even[(len - 1) / 2] - ((in_odd[(len - 2) / 2] + 1) >> 1);
440 for (i = 1, j = 0; i < len - 1; i += 2, j++) {
441 tmp[i] = in_odd[j] + ((tmp[i - 1] + tmp[i + 1]) >> 1);
443 if (!(len & 1)) { /* if len is even */
444 tmp[len - 1] = in_odd[(len - 1) / 2] + tmp[len - 2];
447 OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
451 /* Improved version of the TWO_PASS_VERSION: */
452 /* Performs lifting in one single iteration. Saves memory */
453 /* accesses and explicit interleaving. */
456 s0n = s1n - ((d1n + 1) >> 1);
458 for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
465 s0n = s1n - ((d1c + d1n + 2) >> 2);
468 tmp[i + 1] = d1c + ((s0c + s0n) >> 1);
474 tmp[len - 1] = in_even[(len - 1) / 2] - ((d1n + 1) >> 1);
475 tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
477 tmp[len - 1] = d1n + s0n;
480 memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
483 static void opj_idwt53_h_cas1(OPJ_INT32* tmp,
489 const OPJ_INT32* in_even = &tiledp[sn];
490 const OPJ_INT32* in_odd = &tiledp[0];
492 #ifdef TWO_PASS_VERSION
493 /* For documentation purpose: performs lifting in two iterations, */
494 /* but without explicit interleaving */
499 for (i = 1, j = 0; i < len - 1; i += 2, j++) {
500 tmp[i] = in_odd[j] - ((in_even[j] + in_even[j + 1] + 2) >> 2);
503 tmp[len - 1] = in_odd[len / 2 - 1] - ((in_even[len / 2 - 1] + 1) >> 1);
507 tmp[0] = in_even[0] + tmp[1];
508 for (i = 2, j = 1; i < len - 1; i += 2, j++) {
509 tmp[i] = in_even[j] + ((tmp[i + 1] + tmp[i - 1]) >> 1);
512 tmp[len - 1] = in_even[len / 2] + tmp[len - 2];
515 OPJ_INT32 s1, s2, dc, dn;
519 /* Improved version of the TWO_PASS_VERSION: */
520 /* Performs lifting in one single iteration. Saves memory */
521 /* accesses and explicit interleaving. */
524 dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
525 tmp[0] = in_even[0] + dc;
527 for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
531 dn = in_odd[j] - ((s1 + s2 + 2) >> 2);
533 tmp[i + 1] = s1 + ((dn + dc) >> 1);
542 dn = in_odd[len / 2 - 1] - ((s1 + 1) >> 1);
543 tmp[len - 2] = s1 + ((dn + dc) >> 1);
546 tmp[len - 1] = s1 + dc;
549 memcpy(tiledp, tmp, (OPJ_UINT32)len * sizeof(OPJ_INT32));
553 #endif /* !defined(STANDARD_SLOW_VERSION) */
556 /* Inverse 5-3 wavelet transform in 1-D for one row. */
558 /* Performs interleave, inverse wavelet transform and copy back to buffer */
559 static void opj_idwt53_h(const opj_dwt_t *dwt,
562 #ifdef STANDARD_SLOW_VERSION
563 /* For documentation purpose */
564 opj_dwt_interleave_h(dwt, tiledp);
565 opj_dwt_decode_1(dwt);
566 memcpy(tiledp, dwt->mem, (OPJ_UINT32)(dwt->sn + dwt->dn) * sizeof(OPJ_INT32));
568 const OPJ_INT32 sn = dwt->sn;
569 const OPJ_INT32 len = sn + dwt->dn;
570 if (dwt->cas == 0) { /* Left-most sample is on even coordinate */
572 opj_idwt53_h_cas0(dwt->mem, sn, len, tiledp);
574 /* Unmodified value */
576 } else { /* Left-most sample is on odd coordinate */
579 } else if (len == 2) {
580 OPJ_INT32* out = dwt->mem;
581 const OPJ_INT32* in_even = &tiledp[sn];
582 const OPJ_INT32* in_odd = &tiledp[0];
583 out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
584 out[0] = in_even[0] + out[1];
585 memcpy(tiledp, dwt->mem, (OPJ_UINT32)len * sizeof(OPJ_INT32));
586 } else if (len > 2) {
587 opj_idwt53_h_cas1(dwt->mem, sn, len, tiledp);
593 #if (defined(__SSE2__) || defined(__AVX2__)) && !defined(STANDARD_SLOW_VERSION)
595 /* Conveniency macros to improve the readabilty of the formulas */
598 #define LOAD_CST(x) _mm256_set1_epi32(x)
599 #define LOAD(x) _mm256_load_si256((const VREG*)(x))
600 #define LOADU(x) _mm256_loadu_si256((const VREG*)(x))
601 #define STORE(x,y) _mm256_store_si256((VREG*)(x),(y))
602 #define STOREU(x,y) _mm256_storeu_si256((VREG*)(x),(y))
603 #define ADD(x,y) _mm256_add_epi32((x),(y))
604 #define SUB(x,y) _mm256_sub_epi32((x),(y))
605 #define SAR(x,y) _mm256_srai_epi32((x),(y))
608 #define LOAD_CST(x) _mm_set1_epi32(x)
609 #define LOAD(x) _mm_load_si128((const VREG*)(x))
610 #define LOADU(x) _mm_loadu_si128((const VREG*)(x))
611 #define STORE(x,y) _mm_store_si128((VREG*)(x),(y))
612 #define STOREU(x,y) _mm_storeu_si128((VREG*)(x),(y))
613 #define ADD(x,y) _mm_add_epi32((x),(y))
614 #define SUB(x,y) _mm_sub_epi32((x),(y))
615 #define SAR(x,y) _mm_srai_epi32((x),(y))
617 #define ADD3(x,y,z) ADD(ADD(x,y),z)
620 void opj_idwt53_v_final_memcpy(OPJ_INT32* tiledp_col,
621 const OPJ_INT32* tmp,
626 for (i = 0; i < len; ++i) {
627 /* A memcpy(&tiledp_col[i * stride + 0],
628 &tmp[PARALLEL_COLS_53 * i + 0],
629 PARALLEL_COLS_53 * sizeof(OPJ_INT32))
630 would do but would be a tiny bit slower.
631 We can take here advantage of our knowledge of alignment */
632 STOREU(&tiledp_col[(OPJ_SIZE_T)i * stride + 0],
633 LOAD(&tmp[PARALLEL_COLS_53 * i + 0]));
634 STOREU(&tiledp_col[(OPJ_SIZE_T)i * stride + VREG_INT_COUNT],
635 LOAD(&tmp[PARALLEL_COLS_53 * i + VREG_INT_COUNT]));
639 /** Vertical inverse 5x3 wavelet transform for 8 columns in SSE2, or
640 * 16 in AVX2, when top-most pixel is on even coordinate */
641 static void opj_idwt53_v_cas0_mcols_SSE2_OR_AVX2(
645 OPJ_INT32* tiledp_col,
646 const OPJ_SIZE_T stride)
648 const OPJ_INT32* in_even = &tiledp_col[0];
649 const OPJ_INT32* in_odd = &tiledp_col[(OPJ_SIZE_T)sn * stride];
653 VREG d1c_0, d1n_0, s1n_0, s0c_0, s0n_0;
654 VREG d1c_1, d1n_1, s1n_1, s0c_1, s0n_1;
655 const VREG two = LOAD_CST(2);
659 assert(PARALLEL_COLS_53 == 16);
660 assert(VREG_INT_COUNT == 8);
662 assert(PARALLEL_COLS_53 == 8);
663 assert(VREG_INT_COUNT == 4);
666 /* Note: loads of input even/odd values must be done in a unaligned */
667 /* fashion. But stores in tmp can be done with aligned store, since */
668 /* the temporary buffer is properly aligned */
669 assert((OPJ_SIZE_T)tmp % (sizeof(OPJ_INT32) * VREG_INT_COUNT) == 0);
671 s1n_0 = LOADU(in_even + 0);
672 s1n_1 = LOADU(in_even + VREG_INT_COUNT);
673 d1n_0 = LOADU(in_odd);
674 d1n_1 = LOADU(in_odd + VREG_INT_COUNT);
676 /* s0n = s1n - ((d1n + 1) >> 1); <==> */
677 /* s0n = s1n - ((d1n + d1n + 2) >> 2); */
678 s0n_0 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
679 s0n_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
681 for (i = 0, j = 1; i < (len - 3); i += 2, j++) {
687 s1n_0 = LOADU(in_even + j * stride);
688 s1n_1 = LOADU(in_even + j * stride + VREG_INT_COUNT);
689 d1n_0 = LOADU(in_odd + j * stride);
690 d1n_1 = LOADU(in_odd + j * stride + VREG_INT_COUNT);
692 /*s0n = s1n - ((d1c + d1n + 2) >> 2);*/
693 s0n_0 = SUB(s1n_0, SAR(ADD3(d1c_0, d1n_0, two), 2));
694 s0n_1 = SUB(s1n_1, SAR(ADD3(d1c_1, d1n_1, two), 2));
696 STORE(tmp + PARALLEL_COLS_53 * (i + 0), s0c_0);
697 STORE(tmp + PARALLEL_COLS_53 * (i + 0) + VREG_INT_COUNT, s0c_1);
699 /* d1c + ((s0c + s0n) >> 1) */
700 STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
701 ADD(d1c_0, SAR(ADD(s0c_0, s0n_0), 1)));
702 STORE(tmp + PARALLEL_COLS_53 * (i + 1) + VREG_INT_COUNT,
703 ADD(d1c_1, SAR(ADD(s0c_1, s0n_1), 1)));
706 STORE(tmp + PARALLEL_COLS_53 * (i + 0) + 0, s0n_0);
707 STORE(tmp + PARALLEL_COLS_53 * (i + 0) + VREG_INT_COUNT, s0n_1);
710 VREG tmp_len_minus_1;
711 s1n_0 = LOADU(in_even + (OPJ_SIZE_T)((len - 1) / 2) * stride);
712 /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
713 tmp_len_minus_1 = SUB(s1n_0, SAR(ADD3(d1n_0, d1n_0, two), 2));
714 STORE(tmp + PARALLEL_COLS_53 * (len - 1), tmp_len_minus_1);
715 /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
716 STORE(tmp + PARALLEL_COLS_53 * (len - 2),
717 ADD(d1n_0, SAR(ADD(s0n_0, tmp_len_minus_1), 1)));
719 s1n_1 = LOADU(in_even + (OPJ_SIZE_T)((len - 1) / 2) * stride + VREG_INT_COUNT);
720 /* tmp_len_minus_1 = s1n - ((d1n + 1) >> 1); */
721 tmp_len_minus_1 = SUB(s1n_1, SAR(ADD3(d1n_1, d1n_1, two), 2));
722 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
724 /* d1n + ((s0n + tmp_len_minus_1) >> 1) */
725 STORE(tmp + PARALLEL_COLS_53 * (len - 2) + VREG_INT_COUNT,
726 ADD(d1n_1, SAR(ADD(s0n_1, tmp_len_minus_1), 1)));
730 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0,
732 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
736 opj_idwt53_v_final_memcpy(tiledp_col, tmp, len, stride);
740 /** Vertical inverse 5x3 wavelet transform for 8 columns in SSE2, or
741 * 16 in AVX2, when top-most pixel is on odd coordinate */
742 static void opj_idwt53_v_cas1_mcols_SSE2_OR_AVX2(
746 OPJ_INT32* tiledp_col,
747 const OPJ_SIZE_T stride)
752 VREG s1_0, s2_0, dc_0, dn_0;
753 VREG s1_1, s2_1, dc_1, dn_1;
754 const VREG two = LOAD_CST(2);
756 const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
757 const OPJ_INT32* in_odd = &tiledp_col[0];
761 assert(PARALLEL_COLS_53 == 16);
762 assert(VREG_INT_COUNT == 8);
764 assert(PARALLEL_COLS_53 == 8);
765 assert(VREG_INT_COUNT == 4);
768 /* Note: loads of input even/odd values must be done in a unaligned */
769 /* fashion. But stores in tmp can be done with aligned store, since */
770 /* the temporary buffer is properly aligned */
771 assert((OPJ_SIZE_T)tmp % (sizeof(OPJ_INT32) * VREG_INT_COUNT) == 0);
773 s1_0 = LOADU(in_even + stride);
774 /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
775 dc_0 = SUB(LOADU(in_odd + 0),
776 SAR(ADD3(LOADU(in_even + 0), s1_0, two), 2));
777 STORE(tmp + PARALLEL_COLS_53 * 0, ADD(LOADU(in_even + 0), dc_0));
779 s1_1 = LOADU(in_even + stride + VREG_INT_COUNT);
780 /* in_odd[0] - ((in_even[0] + s1 + 2) >> 2); */
781 dc_1 = SUB(LOADU(in_odd + VREG_INT_COUNT),
782 SAR(ADD3(LOADU(in_even + VREG_INT_COUNT), s1_1, two), 2));
783 STORE(tmp + PARALLEL_COLS_53 * 0 + VREG_INT_COUNT,
784 ADD(LOADU(in_even + VREG_INT_COUNT), dc_1));
786 for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
788 s2_0 = LOADU(in_even + (j + 1) * stride);
789 s2_1 = LOADU(in_even + (j + 1) * stride + VREG_INT_COUNT);
791 /* dn = in_odd[j * stride] - ((s1 + s2 + 2) >> 2); */
792 dn_0 = SUB(LOADU(in_odd + j * stride),
793 SAR(ADD3(s1_0, s2_0, two), 2));
794 dn_1 = SUB(LOADU(in_odd + j * stride + VREG_INT_COUNT),
795 SAR(ADD3(s1_1, s2_1, two), 2));
797 STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
798 STORE(tmp + PARALLEL_COLS_53 * i + VREG_INT_COUNT, dc_1);
800 /* tmp[i + 1] = s1 + ((dn + dc) >> 1); */
801 STORE(tmp + PARALLEL_COLS_53 * (i + 1) + 0,
802 ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
803 STORE(tmp + PARALLEL_COLS_53 * (i + 1) + VREG_INT_COUNT,
804 ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
811 STORE(tmp + PARALLEL_COLS_53 * i, dc_0);
812 STORE(tmp + PARALLEL_COLS_53 * i + VREG_INT_COUNT, dc_1);
815 /*dn = in_odd[(len / 2 - 1) * stride] - ((s1 + 1) >> 1); */
816 dn_0 = SUB(LOADU(in_odd + (OPJ_SIZE_T)(len / 2 - 1) * stride),
817 SAR(ADD3(s1_0, s1_0, two), 2));
818 dn_1 = SUB(LOADU(in_odd + (OPJ_SIZE_T)(len / 2 - 1) * stride + VREG_INT_COUNT),
819 SAR(ADD3(s1_1, s1_1, two), 2));
821 /* tmp[len - 2] = s1 + ((dn + dc) >> 1); */
822 STORE(tmp + PARALLEL_COLS_53 * (len - 2) + 0,
823 ADD(s1_0, SAR(ADD(dn_0, dc_0), 1)));
824 STORE(tmp + PARALLEL_COLS_53 * (len - 2) + VREG_INT_COUNT,
825 ADD(s1_1, SAR(ADD(dn_1, dc_1), 1)));
827 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, dn_0);
828 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT, dn_1);
830 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + 0, ADD(s1_0, dc_0));
831 STORE(tmp + PARALLEL_COLS_53 * (len - 1) + VREG_INT_COUNT,
835 opj_idwt53_v_final_memcpy(tiledp_col, tmp, len, stride);
849 #endif /* (defined(__SSE2__) || defined(__AVX2__)) && !defined(STANDARD_SLOW_VERSION) */
851 #if !defined(STANDARD_SLOW_VERSION)
852 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
853 * pixel is on even coordinate */
854 static void opj_idwt3_v_cas0(OPJ_INT32* tmp,
857 OPJ_INT32* tiledp_col,
858 const OPJ_SIZE_T stride)
861 OPJ_INT32 d1c, d1n, s1n, s0c, s0n;
865 /* Performs lifting in one single iteration. Saves memory */
866 /* accesses and explicit interleaving. */
869 d1n = tiledp_col[(OPJ_SIZE_T)sn * stride];
870 s0n = s1n - ((d1n + 1) >> 1);
872 for (i = 0, j = 0; i < (len - 3); i += 2, j++) {
876 s1n = tiledp_col[(OPJ_SIZE_T)(j + 1) * stride];
877 d1n = tiledp_col[(OPJ_SIZE_T)(sn + j + 1) * stride];
879 s0n = s1n - ((d1c + d1n + 2) >> 2);
882 tmp[i + 1] = d1c + ((s0c + s0n) >> 1);
889 tiledp_col[(OPJ_SIZE_T)((len - 1) / 2) * stride] -
891 tmp[len - 2] = d1n + ((s0n + tmp[len - 1]) >> 1);
893 tmp[len - 1] = d1n + s0n;
896 for (i = 0; i < len; ++i) {
897 tiledp_col[(OPJ_SIZE_T)i * stride] = tmp[i];
902 /** Vertical inverse 5x3 wavelet transform for one column, when top-most
903 * pixel is on odd coordinate */
904 static void opj_idwt3_v_cas1(OPJ_INT32* tmp,
907 OPJ_INT32* tiledp_col,
908 const OPJ_SIZE_T stride)
911 OPJ_INT32 s1, s2, dc, dn;
912 const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
913 const OPJ_INT32* in_odd = &tiledp_col[0];
917 /* Performs lifting in one single iteration. Saves memory */
918 /* accesses and explicit interleaving. */
920 s1 = in_even[stride];
921 dc = in_odd[0] - ((in_even[0] + s1 + 2) >> 2);
922 tmp[0] = in_even[0] + dc;
923 for (i = 1, j = 1; i < (len - 2 - !(len & 1)); i += 2, j++) {
925 s2 = in_even[(OPJ_SIZE_T)(j + 1) * stride];
927 dn = in_odd[(OPJ_SIZE_T)j * stride] - ((s1 + s2 + 2) >> 2);
929 tmp[i + 1] = s1 + ((dn + dc) >> 1);
936 dn = in_odd[(OPJ_SIZE_T)(len / 2 - 1) * stride] - ((s1 + 1) >> 1);
937 tmp[len - 2] = s1 + ((dn + dc) >> 1);
940 tmp[len - 1] = s1 + dc;
943 for (i = 0; i < len; ++i) {
944 tiledp_col[(OPJ_SIZE_T)i * stride] = tmp[i];
947 #endif /* !defined(STANDARD_SLOW_VERSION) */
950 /* Inverse vertical 5-3 wavelet transform in 1-D for several columns. */
952 /* Performs interleave, inverse wavelet transform and copy back to buffer */
953 static void opj_idwt53_v(const opj_dwt_t *dwt,
954 OPJ_INT32* tiledp_col,
958 #ifdef STANDARD_SLOW_VERSION
959 /* For documentation purpose */
961 for (c = 0; c < nb_cols; c ++) {
962 opj_dwt_interleave_v(dwt, tiledp_col + c, stride);
963 opj_dwt_decode_1(dwt);
964 for (k = 0; k < dwt->sn + dwt->dn; ++k) {
965 tiledp_col[c + k * stride] = dwt->mem[k];
969 const OPJ_INT32 sn = dwt->sn;
970 const OPJ_INT32 len = sn + dwt->dn;
972 /* If len == 1, unmodified value */
974 #if (defined(__SSE2__) || defined(__AVX2__))
975 if (len > 1 && nb_cols == PARALLEL_COLS_53) {
976 /* Same as below general case, except that thanks to SSE2/AVX2 */
977 /* we can efficently process 8/16 columns in parallel */
978 opj_idwt53_v_cas0_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
984 for (c = 0; c < nb_cols; c++, tiledp_col++) {
985 opj_idwt3_v_cas0(dwt->mem, sn, len, tiledp_col, stride);
992 for (c = 0; c < nb_cols; c++, tiledp_col++) {
1000 OPJ_INT32* out = dwt->mem;
1001 for (c = 0; c < nb_cols; c++, tiledp_col++) {
1003 const OPJ_INT32* in_even = &tiledp_col[(OPJ_SIZE_T)sn * stride];
1004 const OPJ_INT32* in_odd = &tiledp_col[0];
1006 out[1] = in_odd[0] - ((in_even[0] + 1) >> 1);
1007 out[0] = in_even[0] + out[1];
1009 for (i = 0; i < len; ++i) {
1010 tiledp_col[(OPJ_SIZE_T)i * stride] = out[i];
1017 #if (defined(__SSE2__) || defined(__AVX2__))
1018 if (len > 2 && nb_cols == PARALLEL_COLS_53) {
1019 /* Same as below general case, except that thanks to SSE2/AVX2 */
1020 /* we can efficently process 8/16 columns in parallel */
1021 opj_idwt53_v_cas1_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
1027 for (c = 0; c < nb_cols; c++, tiledp_col++) {
1028 opj_idwt3_v_cas1(dwt->mem, sn, len, tiledp_col, stride);
1038 /* Forward 9-7 wavelet transform in 1-D. */
1040 static void opj_dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
1045 if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
1046 for (i = 0; i < dn; i++) {
1047 OPJ_D(i) -= opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 12993);
1049 for (i = 0; i < sn; i++) {
1050 OPJ_S(i) -= opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 434);
1052 for (i = 0; i < dn; i++) {
1053 OPJ_D(i) += opj_int_fix_mul(OPJ_S_(i) + OPJ_S_(i + 1), 7233);
1055 for (i = 0; i < sn; i++) {
1056 OPJ_S(i) += opj_int_fix_mul(OPJ_D_(i - 1) + OPJ_D_(i), 3633);
1058 for (i = 0; i < dn; i++) {
1059 OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 5038); /*5038 */
1061 for (i = 0; i < sn; i++) {
1062 OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 6659); /*6660 */
1066 if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */
1067 for (i = 0; i < dn; i++) {
1068 OPJ_S(i) -= opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 12993);
1070 for (i = 0; i < sn; i++) {
1071 OPJ_D(i) -= opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 434);
1073 for (i = 0; i < dn; i++) {
1074 OPJ_S(i) += opj_int_fix_mul(OPJ_DD_(i) + OPJ_DD_(i - 1), 7233);
1076 for (i = 0; i < sn; i++) {
1077 OPJ_D(i) += opj_int_fix_mul(OPJ_SS_(i) + OPJ_SS_(i + 1), 3633);
1079 for (i = 0; i < dn; i++) {
1080 OPJ_S(i) = opj_int_fix_mul(OPJ_S(i), 5038); /*5038 */
1082 for (i = 0; i < sn; i++) {
1083 OPJ_D(i) = opj_int_fix_mul(OPJ_D(i), 6659); /*6660 */
1089 static void opj_dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps,
1090 opj_stepsize_t *bandno_stepsize)
1093 p = opj_int_floorlog2(stepsize) - 13;
1094 n = 11 - opj_int_floorlog2(stepsize);
1095 bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
1096 bandno_stepsize->expn = numbps - p;
1100 ==========================================================
1102 ==========================================================
1107 /* Forward 5-3 wavelet transform in 2-D. */
1109 static INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,
1110 void (*p_function)(OPJ_INT32 *, OPJ_INT32, OPJ_INT32, OPJ_INT32))
1118 OPJ_INT32 rw; /* width of the resolution level computed */
1119 OPJ_INT32 rh; /* height of the resolution level computed */
1120 OPJ_SIZE_T l_data_size;
1122 opj_tcd_resolution_t * l_cur_res = 0;
1123 opj_tcd_resolution_t * l_last_res = 0;
1125 w = tilec->x1 - tilec->x0;
1126 l = (OPJ_INT32)tilec->numresolutions - 1;
1129 l_cur_res = tilec->resolutions + l;
1130 l_last_res = l_cur_res - 1;
1132 l_data_size = opj_dwt_max_resolution(tilec->resolutions, tilec->numresolutions);
1133 /* overflow check */
1134 if (l_data_size > (SIZE_MAX / sizeof(OPJ_INT32))) {
1135 /* FIXME event manager error callback */
1138 l_data_size *= sizeof(OPJ_INT32);
1139 bj = (OPJ_INT32*)opj_malloc(l_data_size);
1140 /* l_data_size is equal to 0 when numresolutions == 1 but bj is not used */
1141 /* in that case, so do not error out */
1142 if (l_data_size != 0 && ! bj) {
1148 OPJ_INT32 rw1; /* width of the resolution level once lower than computed one */
1149 OPJ_INT32 rh1; /* height of the resolution level once lower than computed one */
1150 OPJ_INT32 cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
1151 OPJ_INT32 cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */
1154 rw = l_cur_res->x1 - l_cur_res->x0;
1155 rh = l_cur_res->y1 - l_cur_res->y0;
1156 rw1 = l_last_res->x1 - l_last_res->x0;
1157 rh1 = l_last_res->y1 - l_last_res->y0;
1159 cas_row = l_cur_res->x0 & 1;
1160 cas_col = l_cur_res->y0 & 1;
1164 for (j = 0; j < rw; ++j) {
1166 for (k = 0; k < rh; ++k) {
1170 (*p_function)(bj, dn, sn, cas_col);
1172 opj_dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
1178 for (j = 0; j < rh; j++) {
1180 for (k = 0; k < rw; k++) {
1183 (*p_function)(bj, dn, sn, cas_row);
1184 opj_dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
1187 l_cur_res = l_last_res;
1196 /* Forward 5-3 wavelet transform in 2-D. */
1198 OPJ_BOOL opj_dwt_encode(opj_tcd_tilecomp_t * tilec)
1200 return opj_dwt_encode_procedure(tilec, opj_dwt_encode_1);
1204 /* Inverse 5-3 wavelet transform in 2-D. */
1206 OPJ_BOOL opj_dwt_decode(opj_tcd_t *p_tcd, opj_tcd_tilecomp_t* tilec,
1209 if (p_tcd->whole_tile_decoding) {
1210 return opj_dwt_decode_tile(p_tcd->thread_pool, tilec, numres);
1212 return opj_dwt_decode_partial_tile(tilec, numres);
1218 /* Get gain of 5-3 wavelet transform. */
1220 OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient)
1225 if (orient == 1 || orient == 2) {
1232 /* Get norm of 5-3 wavelet. */
1234 OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient)
1236 /* FIXME ! This is just a band-aid to avoid a buffer overflow */
1237 /* but the array should really be extended up to 33 resolution levels */
1238 /* See https://github.com/uclouvain/openjpeg/issues/493 */
1239 if (orient == 0 && level >= 10) {
1241 } else if (orient > 0 && level >= 9) {
1244 return opj_dwt_norms[orient][level];
1248 /* Forward 9-7 wavelet transform in 2-D. */
1250 OPJ_BOOL opj_dwt_encode_real(opj_tcd_tilecomp_t * tilec)
1252 return opj_dwt_encode_procedure(tilec, opj_dwt_encode_1_real);
1256 /* Get gain of 9-7 wavelet transform. */
1258 OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient)
1265 /* Get norm of 9-7 wavelet. */
1267 OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient)
1269 /* FIXME ! This is just a band-aid to avoid a buffer overflow */
1270 /* but the array should really be extended up to 33 resolution levels */
1271 /* See https://github.com/uclouvain/openjpeg/issues/493 */
1272 if (orient == 0 && level >= 10) {
1274 } else if (orient > 0 && level >= 9) {
1277 return opj_dwt_norms_real[orient][level];
1280 void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec)
1282 OPJ_UINT32 numbands, bandno;
1283 numbands = 3 * tccp->numresolutions - 2;
1284 for (bandno = 0; bandno < numbands; bandno++) {
1285 OPJ_FLOAT64 stepsize;
1286 OPJ_UINT32 resno, level, orient, gain;
1288 resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
1289 orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
1290 level = tccp->numresolutions - 1 - resno;
1291 gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) ||
1292 (orient == 2)) ? 1 : 2));
1293 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
1296 OPJ_FLOAT64 norm = opj_dwt_norms_real[orient][level];
1297 stepsize = (1 << (gain)) / norm;
1299 opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0),
1300 (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]);
1305 /* Determine maximum computed resolution level for inverse wavelet transform */
1307 static OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* OPJ_RESTRICT r,
1314 if (mr < (w = (OPJ_UINT32)(r->x1 - r->x0))) {
1317 if (mr < (w = (OPJ_UINT32)(r->y1 - r->y0))) {
1328 OPJ_INT32 * OPJ_RESTRICT tiledp;
1331 } opj_dwd_decode_h_job_t;
1333 static void opj_dwt_decode_h_func(void* user_data, opj_tls_t* tls)
1336 opj_dwd_decode_h_job_t* job;
1339 job = (opj_dwd_decode_h_job_t*)user_data;
1340 for (j = job->min_j; j < job->max_j; j++) {
1341 opj_idwt53_h(&job->h, &job->tiledp[j * job->w]);
1344 opj_aligned_free(job->h.mem);
1352 OPJ_INT32 * OPJ_RESTRICT tiledp;
1355 } opj_dwd_decode_v_job_t;
1357 static void opj_dwt_decode_v_func(void* user_data, opj_tls_t* tls)
1360 opj_dwd_decode_v_job_t* job;
1363 job = (opj_dwd_decode_v_job_t*)user_data;
1364 for (j = job->min_j; j + PARALLEL_COLS_53 <= job->max_j;
1365 j += PARALLEL_COLS_53) {
1366 opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_SIZE_T)job->w,
1370 opj_idwt53_v(&job->v, &job->tiledp[j], (OPJ_SIZE_T)job->w,
1371 (OPJ_INT32)(job->max_j - j));
1373 opj_aligned_free(job->v.mem);
1379 /* Inverse wavelet transform in 2-D. */
1381 static OPJ_BOOL opj_dwt_decode_tile(opj_thread_pool_t* tp,
1382 opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres)
1387 opj_tcd_resolution_t* tr = tilec->resolutions;
1389 OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
1390 tr->x0); /* width of the resolution level computed */
1391 OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
1392 tr->y0); /* height of the resolution level computed */
1394 OPJ_UINT32 w = (OPJ_UINT32)(tilec->resolutions[tilec->minimum_num_resolutions -
1396 tilec->resolutions[tilec->minimum_num_resolutions - 1].x0);
1397 OPJ_SIZE_T h_mem_size;
1403 num_threads = opj_thread_pool_get_thread_count(tp);
1404 h_mem_size = opj_dwt_max_resolution(tr, numres);
1405 /* overflow check */
1406 if (h_mem_size > (SIZE_MAX / PARALLEL_COLS_53 / sizeof(OPJ_INT32))) {
1407 /* FIXME event manager error callback */
1410 /* We need PARALLEL_COLS_53 times the height of the array, */
1411 /* since for the vertical pass */
1412 /* we process PARALLEL_COLS_53 columns at a time */
1413 h_mem_size *= PARALLEL_COLS_53 * sizeof(OPJ_INT32);
1414 h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
1416 /* FIXME event manager error callback */
1423 OPJ_INT32 * OPJ_RESTRICT tiledp = tilec->data;
1427 h.sn = (OPJ_INT32)rw;
1428 v.sn = (OPJ_INT32)rh;
1430 rw = (OPJ_UINT32)(tr->x1 - tr->x0);
1431 rh = (OPJ_UINT32)(tr->y1 - tr->y0);
1433 h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
1436 if (num_threads <= 1 || rh <= 1) {
1437 for (j = 0; j < rh; ++j) {
1438 opj_idwt53_h(&h, &tiledp[(OPJ_SIZE_T)j * w]);
1441 OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1444 if (rh < num_jobs) {
1447 step_j = (rh / num_jobs);
1449 for (j = 0; j < num_jobs; j++) {
1450 opj_dwd_decode_h_job_t* job;
1452 job = (opj_dwd_decode_h_job_t*) opj_malloc(sizeof(opj_dwd_decode_h_job_t));
1454 /* It would be nice to fallback to single thread case, but */
1455 /* unfortunately some jobs may be launched and have modified */
1456 /* tiledp, so it is not practical to recover from that error */
1457 /* FIXME event manager error callback */
1458 opj_thread_pool_wait_completion(tp, 0);
1459 opj_aligned_free(h.mem);
1465 job->tiledp = tiledp;
1466 job->min_j = j * step_j;
1467 job->max_j = (j + 1U) * step_j; /* this can overflow */
1468 if (j == (num_jobs - 1U)) { /* this will take care of the overflow */
1471 job->h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
1473 /* FIXME event manager error callback */
1474 opj_thread_pool_wait_completion(tp, 0);
1476 opj_aligned_free(h.mem);
1479 opj_thread_pool_submit_job(tp, opj_dwt_decode_h_func, job);
1481 opj_thread_pool_wait_completion(tp, 0);
1484 v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
1487 if (num_threads <= 1 || rw <= 1) {
1488 for (j = 0; j + PARALLEL_COLS_53 <= rw;
1489 j += PARALLEL_COLS_53) {
1490 opj_idwt53_v(&v, &tiledp[j], (OPJ_SIZE_T)w, PARALLEL_COLS_53);
1493 opj_idwt53_v(&v, &tiledp[j], (OPJ_SIZE_T)w, (OPJ_INT32)(rw - j));
1496 OPJ_UINT32 num_jobs = (OPJ_UINT32)num_threads;
1499 if (rw < num_jobs) {
1502 step_j = (rw / num_jobs);
1504 for (j = 0; j < num_jobs; j++) {
1505 opj_dwd_decode_v_job_t* job;
1507 job = (opj_dwd_decode_v_job_t*) opj_malloc(sizeof(opj_dwd_decode_v_job_t));
1509 /* It would be nice to fallback to single thread case, but */
1510 /* unfortunately some jobs may be launched and have modified */
1511 /* tiledp, so it is not practical to recover from that error */
1512 /* FIXME event manager error callback */
1513 opj_thread_pool_wait_completion(tp, 0);
1514 opj_aligned_free(v.mem);
1520 job->tiledp = tiledp;
1521 job->min_j = j * step_j;
1522 job->max_j = (j + 1U) * step_j; /* this can overflow */
1523 if (j == (num_jobs - 1U)) { /* this will take care of the overflow */
1526 job->v.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
1528 /* FIXME event manager error callback */
1529 opj_thread_pool_wait_completion(tp, 0);
1531 opj_aligned_free(v.mem);
1534 opj_thread_pool_submit_job(tp, opj_dwt_decode_v_func, job);
1536 opj_thread_pool_wait_completion(tp, 0);
1539 opj_aligned_free(h.mem);
1543 static void opj_dwt_interleave_partial_h(OPJ_INT32 *dest,
1545 opj_sparse_array_int32_t* sa,
1548 OPJ_UINT32 win_l_x0,
1549 OPJ_UINT32 win_l_x1,
1550 OPJ_UINT32 win_h_x0,
1551 OPJ_UINT32 win_h_x1)
1554 ret = opj_sparse_array_int32_read(sa,
1556 win_l_x1, sa_line + 1,
1557 dest + cas + 2 * win_l_x0,
1560 ret = opj_sparse_array_int32_read(sa,
1561 sn + win_h_x0, sa_line,
1562 sn + win_h_x1, sa_line + 1,
1563 dest + 1 - cas + 2 * win_h_x0,
1570 static void opj_dwt_interleave_partial_v(OPJ_INT32 *dest,
1572 opj_sparse_array_int32_t* sa,
1576 OPJ_UINT32 win_l_y0,
1577 OPJ_UINT32 win_l_y1,
1578 OPJ_UINT32 win_h_y0,
1579 OPJ_UINT32 win_h_y1)
1582 ret = opj_sparse_array_int32_read(sa,
1584 sa_col + nb_cols, win_l_y1,
1585 dest + cas * 4 + 2 * 4 * win_l_y0,
1586 1, 2 * 4, OPJ_TRUE);
1588 ret = opj_sparse_array_int32_read(sa,
1589 sa_col, sn + win_h_y0,
1590 sa_col + nb_cols, sn + win_h_y1,
1591 dest + (1 - cas) * 4 + 2 * 4 * win_h_y0,
1592 1, 2 * 4, OPJ_TRUE);
1597 static void opj_dwt_decode_partial_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn,
1607 if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
1609 /* Naive version is :
1610 for (i = win_l_x0; i < i_max; i++) {
1611 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
1613 for (i = win_h_x0; i < win_h_x1; i++) {
1614 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
1616 but the compiler doesn't manage to unroll it to avoid bound
1617 checking in OPJ_S_ and OPJ_D_ macros
1624 /* Left-most case */
1625 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
1632 for (; i < i_max; i++) {
1633 /* No bound checking */
1634 OPJ_S(i) -= (OPJ_D(i - 1) + OPJ_D(i) + 2) >> 2;
1636 for (; i < win_l_x1; i++) {
1637 /* Right-most case */
1638 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
1644 OPJ_INT32 i_max = win_h_x1;
1648 for (; i < i_max; i++) {
1649 /* No bound checking */
1650 OPJ_D(i) += (OPJ_S(i) + OPJ_S(i + 1)) >> 1;
1652 for (; i < win_h_x1; i++) {
1653 /* Right-most case */
1654 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
1659 if (!sn && dn == 1) { /* NEW : CASE ONE ELEMENT */
1662 for (i = win_l_x0; i < win_l_x1; i++) {
1663 OPJ_D(i) -= (OPJ_SS_(i) + OPJ_SS_(i + 1) + 2) >> 2;
1665 for (i = win_h_x0; i < win_h_x1; i++) {
1666 OPJ_S(i) += (OPJ_DD_(i) + OPJ_DD_(i - 1)) >> 1;
1672 #define OPJ_S_off(i,off) a[(OPJ_UINT32)(i)*2*4+off]
1673 #define OPJ_D_off(i,off) a[(1+(OPJ_UINT32)(i)*2)*4+off]
1674 #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)))
1675 #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)))
1676 #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)))
1677 #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)))
1679 static void opj_dwt_decode_partial_1_parallel(OPJ_INT32 *a,
1681 OPJ_INT32 dn, OPJ_INT32 sn,
1694 if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */
1696 /* Naive version is :
1697 for (i = win_l_x0; i < i_max; i++) {
1698 OPJ_S(i) -= (OPJ_D_(i - 1) + OPJ_D_(i) + 2) >> 2;
1700 for (i = win_h_x0; i < win_h_x1; i++) {
1701 OPJ_D(i) += (OPJ_S_(i) + OPJ_S_(i + 1)) >> 1;
1703 but the compiler doesn't manage to unroll it to avoid bound
1704 checking in OPJ_S_ and OPJ_D_ macros
1711 /* Left-most case */
1712 for (off = 0; off < 4; off++) {
1713 OPJ_S_off(i, off) -= (OPJ_D__off(i - 1, off) + OPJ_D__off(i, off) + 2) >> 2;
1723 if (i + 1 < i_max) {
1724 const __m128i two = _mm_set1_epi32(2);
1725 __m128i Dm1 = _mm_load_si128((__m128i * const)(a + 4 + (i - 1) * 8));
1726 for (; i + 1 < i_max; i += 2) {
1727 /* No bound checking */
1728 __m128i S = _mm_load_si128((__m128i * const)(a + i * 8));
1729 __m128i D = _mm_load_si128((__m128i * const)(a + 4 + i * 8));
1730 __m128i S1 = _mm_load_si128((__m128i * const)(a + (i + 1) * 8));
1731 __m128i D1 = _mm_load_si128((__m128i * const)(a + 4 + (i + 1) * 8));
1732 S = _mm_sub_epi32(S,
1733 _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(Dm1, D), two), 2));
1734 S1 = _mm_sub_epi32(S1,
1735 _mm_srai_epi32(_mm_add_epi32(_mm_add_epi32(D, D1), two), 2));
1736 _mm_store_si128((__m128i*)(a + i * 8), S);
1737 _mm_store_si128((__m128i*)(a + (i + 1) * 8), S1);
1743 for (; i < i_max; i++) {
1744 /* No bound checking */
1745 for (off = 0; off < 4; off++) {
1746 OPJ_S_off(i, off) -= (OPJ_D_off(i - 1, off) + OPJ_D_off(i, off) + 2) >> 2;
1749 for (; i < win_l_x1; i++) {
1750 /* Right-most case */
1751 for (off = 0; off < 4; off++) {
1752 OPJ_S_off(i, off) -= (OPJ_D__off(i - 1, off) + OPJ_D__off(i, off) + 2) >> 2;
1759 OPJ_INT32 i_max = win_h_x1;
1765 if (i + 1 < i_max) {
1766 __m128i S = _mm_load_si128((__m128i * const)(a + i * 8));
1767 for (; i + 1 < i_max; i += 2) {
1768 /* No bound checking */
1769 __m128i D = _mm_load_si128((__m128i * const)(a + 4 + i * 8));
1770 __m128i S1 = _mm_load_si128((__m128i * const)(a + (i + 1) * 8));
1771 __m128i D1 = _mm_load_si128((__m128i * const)(a + 4 + (i + 1) * 8));
1772 __m128i S2 = _mm_load_si128((__m128i * const)(a + (i + 2) * 8));
1773 D = _mm_add_epi32(D, _mm_srai_epi32(_mm_add_epi32(S, S1), 1));
1774 D1 = _mm_add_epi32(D1, _mm_srai_epi32(_mm_add_epi32(S1, S2), 1));
1775 _mm_store_si128((__m128i*)(a + 4 + i * 8), D);
1776 _mm_store_si128((__m128i*)(a + 4 + (i + 1) * 8), D1);
1782 for (; i < i_max; i++) {
1783 /* No bound checking */
1784 for (off = 0; off < 4; off++) {
1785 OPJ_D_off(i, off) += (OPJ_S_off(i, off) + OPJ_S_off(i + 1, off)) >> 1;
1788 for (; i < win_h_x1; i++) {
1789 /* Right-most case */
1790 for (off = 0; off < 4; off++) {
1791 OPJ_D_off(i, off) += (OPJ_S__off(i, off) + OPJ_S__off(i + 1, off)) >> 1;
1797 if (!sn && dn == 1) { /* NEW : CASE ONE ELEMENT */
1798 for (off = 0; off < 4; off++) {
1799 OPJ_S_off(0, off) /= 2;
1802 for (i = win_l_x0; i < win_l_x1; i++) {
1803 for (off = 0; off < 4; off++) {
1804 OPJ_D_off(i, off) -= (OPJ_SS__off(i, off) + OPJ_SS__off(i + 1, off) + 2) >> 2;
1807 for (i = win_h_x0; i < win_h_x1; i++) {
1808 for (off = 0; off < 4; off++) {
1809 OPJ_S_off(i, off) += (OPJ_DD__off(i, off) + OPJ_DD__off(i - 1, off)) >> 1;
1816 static void opj_dwt_get_band_coordinates(opj_tcd_tilecomp_t* tilec,
1828 /* Compute number of decomposition for this band. See table F-1 */
1829 OPJ_UINT32 nb = (resno == 0) ?
1830 tilec->numresolutions - 1 :
1831 tilec->numresolutions - resno;
1832 /* Map above tile-based coordinates to sub-band-based coordinates per */
1833 /* equation B-15 of the standard */
1834 OPJ_UINT32 x0b = bandno & 1;
1835 OPJ_UINT32 y0b = bandno >> 1;
1837 *tbx0 = (nb == 0) ? tcx0 :
1838 (tcx0 <= (1U << (nb - 1)) * x0b) ? 0 :
1839 opj_uint_ceildivpow2(tcx0 - (1U << (nb - 1)) * x0b, nb);
1842 *tby0 = (nb == 0) ? tcy0 :
1843 (tcy0 <= (1U << (nb - 1)) * y0b) ? 0 :
1844 opj_uint_ceildivpow2(tcy0 - (1U << (nb - 1)) * y0b, nb);
1847 *tbx1 = (nb == 0) ? tcx1 :
1848 (tcx1 <= (1U << (nb - 1)) * x0b) ? 0 :
1849 opj_uint_ceildivpow2(tcx1 - (1U << (nb - 1)) * x0b, nb);
1852 *tby1 = (nb == 0) ? tcy1 :
1853 (tcy1 <= (1U << (nb - 1)) * y0b) ? 0 :
1854 opj_uint_ceildivpow2(tcy1 - (1U << (nb - 1)) * y0b, nb);
1858 static void opj_dwt_segment_grow(OPJ_UINT32 filter_width,
1859 OPJ_UINT32 max_size,
1863 *start = opj_uint_subs(*start, filter_width);
1864 *end = opj_uint_adds(*end, filter_width);
1865 *end = opj_uint_min(*end, max_size);
1869 static opj_sparse_array_int32_t* opj_dwt_init_sparse_array(
1870 opj_tcd_tilecomp_t* tilec,
1873 opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
1874 OPJ_UINT32 w = (OPJ_UINT32)(tr_max->x1 - tr_max->x0);
1875 OPJ_UINT32 h = (OPJ_UINT32)(tr_max->y1 - tr_max->y0);
1876 OPJ_UINT32 resno, bandno, precno, cblkno;
1877 opj_sparse_array_int32_t* sa = opj_sparse_array_int32_create(
1878 w, h, opj_uint_min(w, 64), opj_uint_min(h, 64));
1883 for (resno = 0; resno < numres; ++resno) {
1884 opj_tcd_resolution_t* res = &tilec->resolutions[resno];
1886 for (bandno = 0; bandno < res->numbands; ++bandno) {
1887 opj_tcd_band_t* band = &res->bands[bandno];
1889 for (precno = 0; precno < res->pw * res->ph; ++precno) {
1890 opj_tcd_precinct_t* precinct = &band->precincts[precno];
1891 for (cblkno = 0; cblkno < precinct->cw * precinct->ch; ++cblkno) {
1892 opj_tcd_cblk_dec_t* cblk = &precinct->cblks.dec[cblkno];
1893 if (cblk->decoded_data != NULL) {
1894 OPJ_UINT32 x = (OPJ_UINT32)(cblk->x0 - band->x0);
1895 OPJ_UINT32 y = (OPJ_UINT32)(cblk->y0 - band->y0);
1896 OPJ_UINT32 cblk_w = (OPJ_UINT32)(cblk->x1 - cblk->x0);
1897 OPJ_UINT32 cblk_h = (OPJ_UINT32)(cblk->y1 - cblk->y0);
1899 if (band->bandno & 1) {
1900 opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
1901 x += (OPJ_UINT32)(pres->x1 - pres->x0);
1903 if (band->bandno & 2) {
1904 opj_tcd_resolution_t* pres = &tilec->resolutions[resno - 1];
1905 y += (OPJ_UINT32)(pres->y1 - pres->y0);
1908 if (!opj_sparse_array_int32_write(sa, x, y,
1909 x + cblk_w, y + cblk_h,
1911 1, cblk_w, OPJ_TRUE)) {
1912 opj_sparse_array_int32_free(sa);
1925 static OPJ_BOOL opj_dwt_decode_partial_tile(
1926 opj_tcd_tilecomp_t* tilec,
1929 opj_sparse_array_int32_t* sa;
1933 /* This value matches the maximum left/right extension given in tables */
1934 /* F.2 and F.3 of the standard. */
1935 const OPJ_UINT32 filter_width = 2U;
1937 opj_tcd_resolution_t* tr = tilec->resolutions;
1938 opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
1940 OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
1941 tr->x0); /* width of the resolution level computed */
1942 OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
1943 tr->y0); /* height of the resolution level computed */
1945 OPJ_SIZE_T h_mem_size;
1947 /* Compute the intersection of the area of interest, expressed in tile coordinates */
1948 /* with the tile coordinates */
1949 OPJ_UINT32 win_tcx0 = tilec->win_x0;
1950 OPJ_UINT32 win_tcy0 = tilec->win_y0;
1951 OPJ_UINT32 win_tcx1 = tilec->win_x1;
1952 OPJ_UINT32 win_tcy1 = tilec->win_y1;
1954 if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
1958 sa = opj_dwt_init_sparse_array(tilec, numres);
1964 OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
1965 tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
1966 tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
1967 tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
1968 tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
1970 1, tr_max->win_x1 - tr_max->win_x0,
1974 opj_sparse_array_int32_free(sa);
1977 h_mem_size = opj_dwt_max_resolution(tr, numres);
1978 /* overflow check */
1979 /* in vertical pass, we process 4 columns at a time */
1980 if (h_mem_size > (SIZE_MAX / (4 * sizeof(OPJ_INT32)))) {
1981 /* FIXME event manager error callback */
1982 opj_sparse_array_int32_free(sa);
1986 h_mem_size *= 4 * sizeof(OPJ_INT32);
1987 h.mem = (OPJ_INT32*)opj_aligned_32_malloc(h_mem_size);
1989 /* FIXME event manager error callback */
1990 opj_sparse_array_int32_free(sa);
1996 for (resno = 1; resno < numres; resno ++) {
1998 /* Window of interest subband-based coordinates */
1999 OPJ_UINT32 win_ll_x0, win_ll_y0, win_ll_x1, win_ll_y1;
2000 OPJ_UINT32 win_hl_x0, win_hl_x1;
2001 OPJ_UINT32 win_lh_y0, win_lh_y1;
2002 /* Window of interest tile-resolution-based coordinates */
2003 OPJ_UINT32 win_tr_x0, win_tr_x1, win_tr_y0, win_tr_y1;
2004 /* Tile-resolution subband-based coordinates */
2005 OPJ_UINT32 tr_ll_x0, tr_ll_y0, tr_hl_x0, tr_lh_y0;
2009 h.sn = (OPJ_INT32)rw;
2010 v.sn = (OPJ_INT32)rh;
2012 rw = (OPJ_UINT32)(tr->x1 - tr->x0);
2013 rh = (OPJ_UINT32)(tr->y1 - tr->y0);
2015 h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
2018 v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
2021 /* Get the subband coordinates for the window of interest */
2023 opj_dwt_get_band_coordinates(tilec, resno, 0,
2024 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2025 &win_ll_x0, &win_ll_y0,
2026 &win_ll_x1, &win_ll_y1);
2029 opj_dwt_get_band_coordinates(tilec, resno, 1,
2030 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2031 &win_hl_x0, NULL, &win_hl_x1, NULL);
2034 opj_dwt_get_band_coordinates(tilec, resno, 2,
2035 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2036 NULL, &win_lh_y0, NULL, &win_lh_y1);
2038 /* Beware: band index for non-LL0 resolution are 0=HL, 1=LH and 2=HH */
2039 tr_ll_x0 = (OPJ_UINT32)tr->bands[1].x0;
2040 tr_ll_y0 = (OPJ_UINT32)tr->bands[0].y0;
2041 tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
2042 tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
2044 /* Substract the origin of the bands for this tile, to the subwindow */
2045 /* of interest band coordinates, so as to get them relative to the */
2047 win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);
2048 win_ll_y0 = opj_uint_subs(win_ll_y0, tr_ll_y0);
2049 win_ll_x1 = opj_uint_subs(win_ll_x1, tr_ll_x0);
2050 win_ll_y1 = opj_uint_subs(win_ll_y1, tr_ll_y0);
2051 win_hl_x0 = opj_uint_subs(win_hl_x0, tr_hl_x0);
2052 win_hl_x1 = opj_uint_subs(win_hl_x1, tr_hl_x0);
2053 win_lh_y0 = opj_uint_subs(win_lh_y0, tr_lh_y0);
2054 win_lh_y1 = opj_uint_subs(win_lh_y1, tr_lh_y0);
2056 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.sn, &win_ll_x0, &win_ll_x1);
2057 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.dn, &win_hl_x0, &win_hl_x1);
2059 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.sn, &win_ll_y0, &win_ll_y1);
2060 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.dn, &win_lh_y0, &win_lh_y1);
2062 /* Compute the tile-resolution-based coordinates for the window of interest */
2064 win_tr_x0 = opj_uint_min(2 * win_ll_x0, 2 * win_hl_x0 + 1);
2065 win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_ll_x1, 2 * win_hl_x1 + 1), rw);
2067 win_tr_x0 = opj_uint_min(2 * win_hl_x0, 2 * win_ll_x0 + 1);
2068 win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_hl_x1, 2 * win_ll_x1 + 1), rw);
2072 win_tr_y0 = opj_uint_min(2 * win_ll_y0, 2 * win_lh_y0 + 1);
2073 win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_ll_y1, 2 * win_lh_y1 + 1), rh);
2075 win_tr_y0 = opj_uint_min(2 * win_lh_y0, 2 * win_ll_y0 + 1);
2076 win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_lh_y1, 2 * win_ll_y1 + 1), rh);
2079 for (j = 0; j < rh; ++j) {
2080 if ((j >= win_ll_y0 && j < win_ll_y1) ||
2081 (j >= win_lh_y0 + (OPJ_UINT32)v.sn && j < win_lh_y1 + (OPJ_UINT32)v.sn)) {
2083 /* Avoids dwt.c:1584:44 (in opj_dwt_decode_partial_1): runtime error: */
2084 /* signed integer overflow: -1094795586 + -1094795586 cannot be represented in type 'int' */
2085 /* on opj_decompress -i ../../openjpeg/MAPA.jp2 -o out.tif -d 0,0,256,256 */
2086 /* This is less extreme than memsetting the whole buffer to 0 */
2087 /* although we could potentially do better with better handling of edge conditions */
2088 if (win_tr_x1 >= 1 && win_tr_x1 < rw) {
2089 h.mem[win_tr_x1 - 1] = 0;
2091 if (win_tr_x1 < rw) {
2092 h.mem[win_tr_x1] = 0;
2095 opj_dwt_interleave_partial_h(h.mem,
2104 opj_dwt_decode_partial_1(h.mem, h.dn, h.sn, h.cas,
2105 (OPJ_INT32)win_ll_x0,
2106 (OPJ_INT32)win_ll_x1,
2107 (OPJ_INT32)win_hl_x0,
2108 (OPJ_INT32)win_hl_x1);
2109 if (!opj_sparse_array_int32_write(sa,
2114 /* FIXME event manager error callback */
2115 opj_sparse_array_int32_free(sa);
2116 opj_aligned_free(h.mem);
2122 for (i = win_tr_x0; i < win_tr_x1;) {
2123 OPJ_UINT32 nb_cols = opj_uint_min(4U, win_tr_x1 - i);
2124 opj_dwt_interleave_partial_v(v.mem,
2134 opj_dwt_decode_partial_1_parallel(v.mem, nb_cols, v.dn, v.sn, v.cas,
2135 (OPJ_INT32)win_ll_y0,
2136 (OPJ_INT32)win_ll_y1,
2137 (OPJ_INT32)win_lh_y0,
2138 (OPJ_INT32)win_lh_y1);
2139 if (!opj_sparse_array_int32_write(sa,
2141 i + nb_cols, win_tr_y1,
2142 v.mem + 4 * win_tr_y0,
2144 /* FIXME event manager error callback */
2145 opj_sparse_array_int32_free(sa);
2146 opj_aligned_free(h.mem);
2153 opj_aligned_free(h.mem);
2156 OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
2157 tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
2158 tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
2159 tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
2160 tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
2162 1, tr_max->win_x1 - tr_max->win_x0,
2167 opj_sparse_array_int32_free(sa);
2171 static void opj_v4dwt_interleave_h(opj_v4dwt_t* OPJ_RESTRICT dwt,
2172 OPJ_FLOAT32* OPJ_RESTRICT a,
2174 OPJ_UINT32 remaining_height)
2176 OPJ_FLOAT32* OPJ_RESTRICT bi = (OPJ_FLOAT32*)(dwt->wavelet + dwt->cas);
2178 OPJ_UINT32 x0 = dwt->win_l_x0;
2179 OPJ_UINT32 x1 = dwt->win_l_x1;
2181 for (k = 0; k < 2; ++k) {
2182 if (remaining_height >= 4 && ((OPJ_SIZE_T) a & 0x0f) == 0 &&
2183 ((OPJ_SIZE_T) bi & 0x0f) == 0 && (width & 0x0f) == 0) {
2184 /* Fast code path */
2185 for (i = x0; i < x1; ++i) {
2189 bi[i * 8 + 1] = a[j];
2191 bi[i * 8 + 2] = a[j];
2193 bi[i * 8 + 3] = a[j];
2196 /* Slow code path */
2197 for (i = x0; i < x1; ++i) {
2201 if (remaining_height == 1) {
2204 bi[i * 8 + 1] = a[j];
2206 if (remaining_height == 2) {
2209 bi[i * 8 + 2] = a[j];
2211 if (remaining_height == 3) {
2214 bi[i * 8 + 3] = a[j]; /* This one*/
2218 bi = (OPJ_FLOAT32*)(dwt->wavelet + 1 - dwt->cas);
2225 static void opj_v4dwt_interleave_partial_h(opj_v4dwt_t* dwt,
2226 opj_sparse_array_int32_t* sa,
2228 OPJ_UINT32 remaining_height)
2231 for (i = 0; i < remaining_height; i++) {
2233 ret = opj_sparse_array_int32_read(sa,
2234 dwt->win_l_x0, sa_line + i,
2235 dwt->win_l_x1, sa_line + i + 1,
2236 /* Nasty cast from float* to int32* */
2237 (OPJ_INT32*)(dwt->wavelet + dwt->cas + 2 * dwt->win_l_x0) + i,
2240 ret = opj_sparse_array_int32_read(sa,
2241 (OPJ_UINT32)dwt->sn + dwt->win_h_x0, sa_line + i,
2242 (OPJ_UINT32)dwt->sn + dwt->win_h_x1, sa_line + i + 1,
2243 /* Nasty cast from float* to int32* */
2244 (OPJ_INT32*)(dwt->wavelet + 1 - dwt->cas + 2 * dwt->win_h_x0) + i,
2251 static void opj_v4dwt_interleave_v(opj_v4dwt_t* OPJ_RESTRICT dwt,
2252 OPJ_FLOAT32* OPJ_RESTRICT a,
2254 OPJ_UINT32 nb_elts_read)
2256 opj_v4_t* OPJ_RESTRICT bi = dwt->wavelet + dwt->cas;
2259 for (i = dwt->win_l_x0; i < dwt->win_l_x1; ++i) {
2260 memcpy(&bi[i * 2], &a[i * (OPJ_SIZE_T)width],
2261 (OPJ_SIZE_T)nb_elts_read * sizeof(OPJ_FLOAT32));
2264 a += (OPJ_UINT32)dwt->sn * (OPJ_SIZE_T)width;
2265 bi = dwt->wavelet + 1 - dwt->cas;
2267 for (i = dwt->win_h_x0; i < dwt->win_h_x1; ++i) {
2268 memcpy(&bi[i * 2], &a[i * (OPJ_SIZE_T)width],
2269 (OPJ_SIZE_T)nb_elts_read * sizeof(OPJ_FLOAT32));
2273 static void opj_v4dwt_interleave_partial_v(opj_v4dwt_t* OPJ_RESTRICT dwt,
2274 opj_sparse_array_int32_t* sa,
2276 OPJ_UINT32 nb_elts_read)
2279 ret = opj_sparse_array_int32_read(sa,
2280 sa_col, dwt->win_l_x0,
2281 sa_col + nb_elts_read, dwt->win_l_x1,
2282 (OPJ_INT32*)(dwt->wavelet + dwt->cas + 2 * dwt->win_l_x0),
2285 ret = opj_sparse_array_int32_read(sa,
2286 sa_col, (OPJ_UINT32)dwt->sn + dwt->win_h_x0,
2287 sa_col + nb_elts_read, (OPJ_UINT32)dwt->sn + dwt->win_h_x1,
2288 (OPJ_INT32*)(dwt->wavelet + 1 - dwt->cas + 2 * dwt->win_h_x0),
2296 static void opj_v4dwt_decode_step1_sse(opj_v4_t* w,
2301 __m128* OPJ_RESTRICT vw = (__m128*) w;
2303 /* 4x unrolled loop */
2305 for (i = start; i + 3 < end; i += 4, vw += 8) {
2306 __m128 xmm0 = _mm_mul_ps(vw[0], c);
2307 __m128 xmm2 = _mm_mul_ps(vw[2], c);
2308 __m128 xmm4 = _mm_mul_ps(vw[4], c);
2309 __m128 xmm6 = _mm_mul_ps(vw[6], c);
2315 for (; i < end; ++i, vw += 2) {
2316 vw[0] = _mm_mul_ps(vw[0], c);
2320 static void opj_v4dwt_decode_step2_sse(opj_v4_t* l, opj_v4_t* w,
2326 __m128* OPJ_RESTRICT vl = (__m128*) l;
2327 __m128* OPJ_RESTRICT vw = (__m128*) w;
2329 OPJ_UINT32 imax = opj_uint_min(end, m);
2330 __m128 tmp1, tmp2, tmp3;
2340 /* 4x loop unrolling */
2341 for (; i + 3 < imax; i += 4) {
2342 __m128 tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
2351 vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
2352 vw[ 1] = _mm_add_ps(tmp4, _mm_mul_ps(_mm_add_ps(tmp3, tmp5), c));
2353 vw[ 3] = _mm_add_ps(tmp6, _mm_mul_ps(_mm_add_ps(tmp5, tmp7), c));
2354 vw[ 5] = _mm_add_ps(tmp8, _mm_mul_ps(_mm_add_ps(tmp7, tmp9), c));
2359 for (; i < imax; ++i) {
2362 vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
2367 assert(m + 1 == end);
2368 c = _mm_add_ps(c, c);
2369 c = _mm_mul_ps(c, vw[-2]);
2370 vw[-1] = _mm_add_ps(vw[-1], c);
2376 static void opj_v4dwt_decode_step1(opj_v4_t* w,
2379 const OPJ_FLOAT32 c)
2381 OPJ_FLOAT32* OPJ_RESTRICT fw = (OPJ_FLOAT32*) w;
2383 for (i = start; i < end; ++i) {
2384 OPJ_FLOAT32 tmp1 = fw[i * 8 ];
2385 OPJ_FLOAT32 tmp2 = fw[i * 8 + 1];
2386 OPJ_FLOAT32 tmp3 = fw[i * 8 + 2];
2387 OPJ_FLOAT32 tmp4 = fw[i * 8 + 3];
2388 fw[i * 8 ] = tmp1 * c;
2389 fw[i * 8 + 1] = tmp2 * c;
2390 fw[i * 8 + 2] = tmp3 * c;
2391 fw[i * 8 + 3] = tmp4 * c;
2395 static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w,
2401 OPJ_FLOAT32* fl = (OPJ_FLOAT32*) l;
2402 OPJ_FLOAT32* fw = (OPJ_FLOAT32*) w;
2404 OPJ_UINT32 imax = opj_uint_min(end, m);
2409 for (i = start; i < imax; ++i) {
2410 OPJ_FLOAT32 tmp1_1 = fl[0];
2411 OPJ_FLOAT32 tmp1_2 = fl[1];
2412 OPJ_FLOAT32 tmp1_3 = fl[2];
2413 OPJ_FLOAT32 tmp1_4 = fl[3];
2414 OPJ_FLOAT32 tmp2_1 = fw[-4];
2415 OPJ_FLOAT32 tmp2_2 = fw[-3];
2416 OPJ_FLOAT32 tmp2_3 = fw[-2];
2417 OPJ_FLOAT32 tmp2_4 = fw[-1];
2418 OPJ_FLOAT32 tmp3_1 = fw[0];
2419 OPJ_FLOAT32 tmp3_2 = fw[1];
2420 OPJ_FLOAT32 tmp3_3 = fw[2];
2421 OPJ_FLOAT32 tmp3_4 = fw[3];
2422 fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
2423 fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
2424 fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
2425 fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
2430 assert(m + 1 == end);
2432 fw[-4] = fw[-4] + fl[0] * c;
2433 fw[-3] = fw[-3] + fl[1] * c;
2434 fw[-2] = fw[-2] + fl[2] * c;
2435 fw[-1] = fw[-1] + fl[3] * c;
2442 /* Inverse 9-7 wavelet transform in 1-D. */
2444 static void opj_v4dwt_decode(opj_v4dwt_t* OPJ_RESTRICT dwt)
2447 if (dwt->cas == 0) {
2448 if (!((dwt->dn > 0) || (dwt->sn > 1))) {
2454 if (!((dwt->sn > 0) || (dwt->dn > 1))) {
2461 opj_v4dwt_decode_step1_sse(dwt->wavelet + a, dwt->win_l_x0, dwt->win_l_x1,
2462 _mm_set1_ps(opj_K));
2463 opj_v4dwt_decode_step1_sse(dwt->wavelet + b, dwt->win_h_x0, dwt->win_h_x1,
2464 _mm_set1_ps(opj_c13318));
2465 opj_v4dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1,
2466 dwt->win_l_x0, dwt->win_l_x1,
2467 (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
2468 _mm_set1_ps(opj_dwt_delta));
2469 opj_v4dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1,
2470 dwt->win_h_x0, dwt->win_h_x1,
2471 (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
2472 _mm_set1_ps(opj_dwt_gamma));
2473 opj_v4dwt_decode_step2_sse(dwt->wavelet + b, dwt->wavelet + a + 1,
2474 dwt->win_l_x0, dwt->win_l_x1,
2475 (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
2476 _mm_set1_ps(opj_dwt_beta));
2477 opj_v4dwt_decode_step2_sse(dwt->wavelet + a, dwt->wavelet + b + 1,
2478 dwt->win_h_x0, dwt->win_h_x1,
2479 (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
2480 _mm_set1_ps(opj_dwt_alpha));
2482 opj_v4dwt_decode_step1(dwt->wavelet + a, dwt->win_l_x0, dwt->win_l_x1,
2484 opj_v4dwt_decode_step1(dwt->wavelet + b, dwt->win_h_x0, dwt->win_h_x1,
2486 opj_v4dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1,
2487 dwt->win_l_x0, dwt->win_l_x1,
2488 (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
2490 opj_v4dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1,
2491 dwt->win_h_x0, dwt->win_h_x1,
2492 (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
2494 opj_v4dwt_decode_step2(dwt->wavelet + b, dwt->wavelet + a + 1,
2495 dwt->win_l_x0, dwt->win_l_x1,
2496 (OPJ_UINT32)opj_int_min(dwt->sn, dwt->dn - a),
2498 opj_v4dwt_decode_step2(dwt->wavelet + a, dwt->wavelet + b + 1,
2499 dwt->win_h_x0, dwt->win_h_x1,
2500 (OPJ_UINT32)opj_int_min(dwt->dn, dwt->sn - b),
2507 /* Inverse 9-7 wavelet transform in 2-D. */
2510 OPJ_BOOL opj_dwt_decode_tile_97(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
2516 opj_tcd_resolution_t* res = tilec->resolutions;
2518 OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 -
2519 res->x0); /* width of the resolution level computed */
2520 OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 -
2521 res->y0); /* height of the resolution level computed */
2523 OPJ_UINT32 w = (OPJ_UINT32)(tilec->resolutions[tilec->minimum_num_resolutions -
2525 tilec->resolutions[tilec->minimum_num_resolutions - 1].x0);
2527 OPJ_SIZE_T l_data_size;
2529 l_data_size = opj_dwt_max_resolution(res, numres);
2530 /* overflow check */
2531 if (l_data_size > (SIZE_MAX - 5U)) {
2532 /* FIXME event manager error callback */
2536 /* overflow check */
2537 if (l_data_size > (SIZE_MAX / sizeof(opj_v4_t))) {
2538 /* FIXME event manager error callback */
2541 h.wavelet = (opj_v4_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v4_t));
2543 /* FIXME event manager error callback */
2546 v.wavelet = h.wavelet;
2549 OPJ_FLOAT32 * OPJ_RESTRICT aj = (OPJ_FLOAT32*) tilec->data;
2552 h.sn = (OPJ_INT32)rw;
2553 v.sn = (OPJ_INT32)rh;
2557 rw = (OPJ_UINT32)(res->x1 -
2558 res->x0); /* width of the resolution level computed */
2559 rh = (OPJ_UINT32)(res->y1 -
2560 res->y0); /* height of the resolution level computed */
2562 h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
2563 h.cas = res->x0 % 2;
2566 h.win_l_x1 = (OPJ_UINT32)h.sn;
2568 h.win_h_x1 = (OPJ_UINT32)h.dn;
2569 for (j = 0; j + 3 < rh; j += 4) {
2571 opj_v4dwt_interleave_h(&h, aj, w, rh - j);
2572 opj_v4dwt_decode(&h);
2574 for (k = 0; k < rw; k++) {
2575 aj[k ] = h.wavelet[k].f[0];
2576 aj[k + (OPJ_SIZE_T)w ] = h.wavelet[k].f[1];
2577 aj[k + (OPJ_SIZE_T)w * 2] = h.wavelet[k].f[2];
2578 aj[k + (OPJ_SIZE_T)w * 3] = h.wavelet[k].f[3];
2586 opj_v4dwt_interleave_h(&h, aj, w, rh - j);
2587 opj_v4dwt_decode(&h);
2588 for (k = 0; k < rw; k++) {
2591 aj[k + (OPJ_SIZE_T)w * 2] = h.wavelet[k].f[2];
2594 aj[k + (OPJ_SIZE_T)w ] = h.wavelet[k].f[1];
2597 aj[k] = h.wavelet[k].f[0];
2602 v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
2603 v.cas = res->y0 % 2;
2605 v.win_l_x1 = (OPJ_UINT32)v.sn;
2607 v.win_h_x1 = (OPJ_UINT32)v.dn;
2609 aj = (OPJ_FLOAT32*) tilec->data;
2610 for (j = rw; j > 3; j -= 4) {
2613 opj_v4dwt_interleave_v(&v, aj, w, 4);
2614 opj_v4dwt_decode(&v);
2616 for (k = 0; k < rh; ++k) {
2617 memcpy(&aj[k * (OPJ_SIZE_T)w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
2627 opj_v4dwt_interleave_v(&v, aj, w, j);
2628 opj_v4dwt_decode(&v);
2630 for (k = 0; k < rh; ++k) {
2631 memcpy(&aj[k * (OPJ_SIZE_T)w], &v.wavelet[k],
2632 (OPJ_SIZE_T)j * sizeof(OPJ_FLOAT32));
2637 opj_aligned_free(h.wavelet);
2642 OPJ_BOOL opj_dwt_decode_partial_97(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
2645 opj_sparse_array_int32_t* sa;
2649 /* This value matches the maximum left/right extension given in tables */
2650 /* F.2 and F.3 of the standard. Note: in opj_tcd_is_subband_area_of_interest() */
2651 /* we currently use 3. */
2652 const OPJ_UINT32 filter_width = 4U;
2654 opj_tcd_resolution_t* tr = tilec->resolutions;
2655 opj_tcd_resolution_t* tr_max = &(tilec->resolutions[numres - 1]);
2657 OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 -
2658 tr->x0); /* width of the resolution level computed */
2659 OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 -
2660 tr->y0); /* height of the resolution level computed */
2662 OPJ_SIZE_T l_data_size;
2664 /* Compute the intersection of the area of interest, expressed in tile coordinates */
2665 /* with the tile coordinates */
2666 OPJ_UINT32 win_tcx0 = tilec->win_x0;
2667 OPJ_UINT32 win_tcy0 = tilec->win_y0;
2668 OPJ_UINT32 win_tcx1 = tilec->win_x1;
2669 OPJ_UINT32 win_tcy1 = tilec->win_y1;
2671 if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
2675 sa = opj_dwt_init_sparse_array(tilec, numres);
2681 OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
2682 tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
2683 tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
2684 tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
2685 tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
2687 1, tr_max->win_x1 - tr_max->win_x0,
2691 opj_sparse_array_int32_free(sa);
2695 l_data_size = opj_dwt_max_resolution(tr, numres);
2696 /* overflow check */
2697 if (l_data_size > (SIZE_MAX - 5U)) {
2698 /* FIXME event manager error callback */
2702 /* overflow check */
2703 if (l_data_size > (SIZE_MAX / sizeof(opj_v4_t))) {
2704 /* FIXME event manager error callback */
2707 h.wavelet = (opj_v4_t*) opj_aligned_malloc(l_data_size * sizeof(opj_v4_t));
2709 /* FIXME event manager error callback */
2712 v.wavelet = h.wavelet;
2714 for (resno = 1; resno < numres; resno ++) {
2716 /* Window of interest subband-based coordinates */
2717 OPJ_UINT32 win_ll_x0, win_ll_y0, win_ll_x1, win_ll_y1;
2718 OPJ_UINT32 win_hl_x0, win_hl_x1;
2719 OPJ_UINT32 win_lh_y0, win_lh_y1;
2720 /* Window of interest tile-resolution-based coordinates */
2721 OPJ_UINT32 win_tr_x0, win_tr_x1, win_tr_y0, win_tr_y1;
2722 /* Tile-resolution subband-based coordinates */
2723 OPJ_UINT32 tr_ll_x0, tr_ll_y0, tr_hl_x0, tr_lh_y0;
2727 h.sn = (OPJ_INT32)rw;
2728 v.sn = (OPJ_INT32)rh;
2730 rw = (OPJ_UINT32)(tr->x1 - tr->x0);
2731 rh = (OPJ_UINT32)(tr->y1 - tr->y0);
2733 h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn);
2736 v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn);
2739 /* Get the subband coordinates for the window of interest */
2741 opj_dwt_get_band_coordinates(tilec, resno, 0,
2742 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2743 &win_ll_x0, &win_ll_y0,
2744 &win_ll_x1, &win_ll_y1);
2747 opj_dwt_get_band_coordinates(tilec, resno, 1,
2748 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2749 &win_hl_x0, NULL, &win_hl_x1, NULL);
2752 opj_dwt_get_band_coordinates(tilec, resno, 2,
2753 win_tcx0, win_tcy0, win_tcx1, win_tcy1,
2754 NULL, &win_lh_y0, NULL, &win_lh_y1);
2756 /* Beware: band index for non-LL0 resolution are 0=HL, 1=LH and 2=HH */
2757 tr_ll_x0 = (OPJ_UINT32)tr->bands[1].x0;
2758 tr_ll_y0 = (OPJ_UINT32)tr->bands[0].y0;
2759 tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
2760 tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
2762 /* Substract the origin of the bands for this tile, to the subwindow */
2763 /* of interest band coordinates, so as to get them relative to the */
2765 win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);
2766 win_ll_y0 = opj_uint_subs(win_ll_y0, tr_ll_y0);
2767 win_ll_x1 = opj_uint_subs(win_ll_x1, tr_ll_x0);
2768 win_ll_y1 = opj_uint_subs(win_ll_y1, tr_ll_y0);
2769 win_hl_x0 = opj_uint_subs(win_hl_x0, tr_hl_x0);
2770 win_hl_x1 = opj_uint_subs(win_hl_x1, tr_hl_x0);
2771 win_lh_y0 = opj_uint_subs(win_lh_y0, tr_lh_y0);
2772 win_lh_y1 = opj_uint_subs(win_lh_y1, tr_lh_y0);
2774 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.sn, &win_ll_x0, &win_ll_x1);
2775 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)h.dn, &win_hl_x0, &win_hl_x1);
2777 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.sn, &win_ll_y0, &win_ll_y1);
2778 opj_dwt_segment_grow(filter_width, (OPJ_UINT32)v.dn, &win_lh_y0, &win_lh_y1);
2780 /* Compute the tile-resolution-based coordinates for the window of interest */
2782 win_tr_x0 = opj_uint_min(2 * win_ll_x0, 2 * win_hl_x0 + 1);
2783 win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_ll_x1, 2 * win_hl_x1 + 1), rw);
2785 win_tr_x0 = opj_uint_min(2 * win_hl_x0, 2 * win_ll_x0 + 1);
2786 win_tr_x1 = opj_uint_min(opj_uint_max(2 * win_hl_x1, 2 * win_ll_x1 + 1), rw);
2790 win_tr_y0 = opj_uint_min(2 * win_ll_y0, 2 * win_lh_y0 + 1);
2791 win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_ll_y1, 2 * win_lh_y1 + 1), rh);
2793 win_tr_y0 = opj_uint_min(2 * win_lh_y0, 2 * win_ll_y0 + 1);
2794 win_tr_y1 = opj_uint_min(opj_uint_max(2 * win_lh_y1, 2 * win_ll_y1 + 1), rh);
2797 h.win_l_x0 = win_ll_x0;
2798 h.win_l_x1 = win_ll_x1;
2799 h.win_h_x0 = win_hl_x0;
2800 h.win_h_x1 = win_hl_x1;
2801 for (j = 0; j + 3 < rh; j += 4) {
2802 if ((j + 3 >= win_ll_y0 && j < win_ll_y1) ||
2803 (j + 3 >= win_lh_y0 + (OPJ_UINT32)v.sn &&
2804 j < win_lh_y1 + (OPJ_UINT32)v.sn)) {
2805 opj_v4dwt_interleave_partial_h(&h, sa, j, opj_uint_min(4U, rh - j));
2806 opj_v4dwt_decode(&h);
2807 if (!opj_sparse_array_int32_write(sa,
2810 (OPJ_INT32*)&h.wavelet[win_tr_x0].f[0],
2812 /* FIXME event manager error callback */
2813 opj_sparse_array_int32_free(sa);
2814 opj_aligned_free(h.wavelet);
2821 ((j + 3 >= win_ll_y0 && j < win_ll_y1) ||
2822 (j + 3 >= win_lh_y0 + (OPJ_UINT32)v.sn &&
2823 j < win_lh_y1 + (OPJ_UINT32)v.sn))) {
2824 opj_v4dwt_interleave_partial_h(&h, sa, j, rh - j);
2825 opj_v4dwt_decode(&h);
2826 if (!opj_sparse_array_int32_write(sa,
2829 (OPJ_INT32*)&h.wavelet[win_tr_x0].f[0],
2831 /* FIXME event manager error callback */
2832 opj_sparse_array_int32_free(sa);
2833 opj_aligned_free(h.wavelet);
2838 v.win_l_x0 = win_ll_y0;
2839 v.win_l_x1 = win_ll_y1;
2840 v.win_h_x0 = win_lh_y0;
2841 v.win_h_x1 = win_lh_y1;
2842 for (j = win_tr_x0; j < win_tr_x1; j += 4) {
2843 OPJ_UINT32 nb_elts = opj_uint_min(4U, win_tr_x1 - j);
2845 opj_v4dwt_interleave_partial_v(&v, sa, j, nb_elts);
2846 opj_v4dwt_decode(&v);
2848 if (!opj_sparse_array_int32_write(sa,
2850 j + nb_elts, win_tr_y1,
2851 (OPJ_INT32*)&h.wavelet[win_tr_y0].f[0],
2853 /* FIXME event manager error callback */
2854 opj_sparse_array_int32_free(sa);
2855 opj_aligned_free(h.wavelet);
2862 OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
2863 tr_max->win_x0 - (OPJ_UINT32)tr_max->x0,
2864 tr_max->win_y0 - (OPJ_UINT32)tr_max->y0,
2865 tr_max->win_x1 - (OPJ_UINT32)tr_max->x0,
2866 tr_max->win_y1 - (OPJ_UINT32)tr_max->y0,
2868 1, tr_max->win_x1 - tr_max->win_x0,
2873 opj_sparse_array_int32_free(sa);
2875 opj_aligned_free(h.wavelet);
2880 OPJ_BOOL opj_dwt_decode_real(opj_tcd_t *p_tcd,
2881 opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
2884 if (p_tcd->whole_tile_decoding) {
2885 return opj_dwt_decode_tile_97(tilec, numres);
2887 return opj_dwt_decode_partial_97(tilec, numres);