[trunk] WIP: correct mistake in text output inside set_decoded_area function (credit...
[openjpeg.git] / libopenjpeg / dwt.c
1 /*
2  * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2007, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7  * Copyright (c) 2005, Herve Drolon, FreeImage Team
8  * Copyright (c) 2007, Jonathan Ballard <dzonatas@dzonux.net>
9  * Copyright (c) 2007, Callum Lerwick <seg@haxxed.com>
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #ifdef __SSE__
35 #include <xmmintrin.h>
36 #endif
37
38 #include "opj_includes.h"
39
40 /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */
41 /*@{*/
42
43 #define WS(i) v->mem[(i)*2]
44 #define WD(i) v->mem[(1+(i)*2)]
45
46 /** @name Local data structures */
47 /*@{*/
48
49 typedef struct dwt_local {
50         int* mem;
51         int dn;
52         int sn;
53         int cas;
54 } dwt_t;
55
56 typedef union {
57         float   f[4];
58 } v4;
59
60 typedef struct v4dwt_local {
61         v4*     wavelet ;
62         int             dn ;
63         int             sn ;
64         int             cas ;
65 } v4dwt_t ;
66
67 static const float dwt_alpha =  1.586134342f; //  12994
68 static const float dwt_beta  =  0.052980118f; //    434
69 static const float dwt_gamma = -0.882911075f; //  -7233
70 static const float dwt_delta = -0.443506852f; //  -3633
71
72 static const float K      = 1.230174105f; //  10078
73 /* FIXME: What is this constant? */
74 static const float c13318 = 1.625732422f;
75
76 /*@}*/
77
78 /**
79 Virtual function type for wavelet transform in 1-D 
80 */
81 typedef void (*DWT1DFN)(dwt_t* v);
82
83 /** @name Local static functions */
84 /*@{*/
85
86 /**
87 Forward lazy transform (horizontal)
88 */
89 static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas);
90 /**
91 Forward lazy transform (vertical)
92 */
93 static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas);
94 /**
95 Inverse lazy transform (horizontal)
96 */
97 static void dwt_interleave_h(dwt_t* h, int *a);
98 /**
99 Inverse lazy transform (vertical)
100 */
101 static void dwt_interleave_v(dwt_t* v, int *a, int x);
102 /**
103 Forward 5-3 wavelet transform in 1-D
104 */
105 static void dwt_encode_1(int *a, int dn, int sn, int cas);
106 /**
107 Inverse 5-3 wavelet transform in 1-D
108 */
109 static void dwt_decode_1(dwt_t *v);
110 /**
111 Forward 9-7 wavelet transform in 1-D
112 */
113 static void dwt_encode_1_real(int *a, int dn, int sn, int cas);
114 /**
115 Explicit calculation of the Quantization Stepsizes 
116 */
117 static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize);
118 /**
119 Inverse wavelet transform in 2-D.
120 */
121 #ifdef OPJ_V1
122 static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn);
123 #endif
124 static opj_bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
125
126 /**
127 Inverse wavelet transform in 2-D.
128 */
129 static opj_bool dwt_decode_tile_v2(opj_tcd_tilecomp_v2_t* tilec, OPJ_UINT32 i, DWT1DFN fn);
130
131 /*@}*/
132
133 /*@}*/
134
135 #define S(i) a[(i)*2]
136 #define D(i) a[(1+(i)*2)]
137 #define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i)))
138 #define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i)))
139 /* new */
140 #define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i)))
141 #define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i)))
142
143 /* <summary>                                                              */
144 /* This table contains the norms of the 5-3 wavelets for different bands. */
145 /* </summary>                                                             */
146 static const double dwt_norms[4][10] = {
147         {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
148         {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
149         {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
150         {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}
151 };
152
153 /* <summary>                                                              */
154 /* This table contains the norms of the 9-7 wavelets for different bands. */
155 /* </summary>                                                             */
156 static const double dwt_norms_real[4][10] = {
157         {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
158         {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
159         {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
160         {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
161 };
162
163 /* 
164 ==========================================================
165    local functions
166 ==========================================================
167 */
168
169 /* <summary>                                     */
170 /* Forward lazy transform (horizontal).  */
171 /* </summary>                            */ 
172 static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) {
173         int i;
174     for (i=0; i<sn; i++) b[i]=a[2*i+cas];
175     for (i=0; i<dn; i++) b[sn+i]=a[(2*i+1-cas)];
176 }
177
178 /* <summary>                             */  
179 /* Forward lazy transform (vertical).    */
180 /* </summary>                            */ 
181 static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) {
182     int i;
183     for (i=0; i<sn; i++) b[i*x]=a[2*i+cas];
184     for (i=0; i<dn; i++) b[(sn+i)*x]=a[(2*i+1-cas)];
185 }
186
187 /* <summary>                             */
188 /* Inverse lazy transform (horizontal).  */
189 /* </summary>                            */
190 static void dwt_interleave_h(dwt_t* h, int *a) {
191     int *ai = a;
192     int *bi = h->mem + h->cas;
193     int  i      = h->sn;
194     while( i-- ) {
195       *bi = *(ai++);
196           bi += 2;
197     }
198     ai  = a + h->sn;
199     bi  = h->mem + 1 - h->cas;
200     i   = h->dn ;
201     while( i-- ) {
202       *bi = *(ai++);
203           bi += 2;
204     }
205 }
206
207 /* <summary>                             */  
208 /* Inverse lazy transform (vertical).    */
209 /* </summary>                            */ 
210 static void dwt_interleave_v(dwt_t* v, int *a, int x) {
211     int *ai = a;
212     int *bi = v->mem + v->cas;
213     int  i = v->sn;
214     while( i-- ) {
215       *bi = *ai;
216           bi += 2;
217           ai += x;
218     }
219     ai = a + (v->sn * x);
220     bi = v->mem + 1 - v->cas;
221     i = v->dn ;
222     while( i-- ) {
223       *bi = *ai;
224           bi += 2;  
225           ai += x;
226     }
227 }
228
229
230 /* <summary>                            */
231 /* Forward 5-3 wavelet transform in 1-D. */
232 /* </summary>                           */
233 static void dwt_encode_1(int *a, int dn, int sn, int cas) {
234         int i;
235         
236         if (!cas) {
237                 if ((dn > 0) || (sn > 1)) {     /* NEW :  CASE ONE ELEMENT */
238                         for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1;
239                         for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2;
240                 }
241         } else {
242                 if (!sn && dn == 1)                 /* NEW :  CASE ONE ELEMENT */
243                         S(0) *= 2;
244                 else {
245                         for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1;
246                         for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2;
247                 }
248         }
249 }
250
251 /* <summary>                            */
252 /* Inverse 5-3 wavelet transform in 1-D. */
253 /* </summary>                           */ 
254 static void dwt_decode_1_(int *a, int dn, int sn, int cas) {
255         int i;
256         
257         if (!cas) {
258                 if ((dn > 0) || (sn > 1)) { /* NEW :  CASE ONE ELEMENT */
259                         for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2;
260                         for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1;
261                 }
262         } else {
263                 if (!sn  && dn == 1)          /* NEW :  CASE ONE ELEMENT */
264                         S(0) /= 2;
265                 else {
266                         for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2;
267                         for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1;
268                 }
269         }
270 }
271
272 /* <summary>                            */
273 /* Inverse 5-3 wavelet transform in 1-D. */
274 /* </summary>                           */ 
275 static void dwt_decode_1(dwt_t *v) {
276         dwt_decode_1_(v->mem, v->dn, v->sn, v->cas);
277 }
278
279 /* <summary>                             */
280 /* Forward 9-7 wavelet transform in 1-D. */
281 /* </summary>                            */
282 static void dwt_encode_1_real(int *a, int dn, int sn, int cas) {
283         int i;
284         if (!cas) {
285                 if ((dn > 0) || (sn > 1)) {     /* NEW :  CASE ONE ELEMENT */
286                         for (i = 0; i < dn; i++)
287                                 D(i) -= fix_mul(S_(i) + S_(i + 1), 12993);
288                         for (i = 0; i < sn; i++)
289                                 S(i) -= fix_mul(D_(i - 1) + D_(i), 434);
290                         for (i = 0; i < dn; i++)
291                                 D(i) += fix_mul(S_(i) + S_(i + 1), 7233);
292                         for (i = 0; i < sn; i++)
293                                 S(i) += fix_mul(D_(i - 1) + D_(i), 3633);
294                         for (i = 0; i < dn; i++)
295                                 D(i) = fix_mul(D(i), 5038);     /*5038 */
296                         for (i = 0; i < sn; i++)
297                                 S(i) = fix_mul(S(i), 6659);     /*6660 */
298                 }
299         } else {
300                 if ((sn > 0) || (dn > 1)) {     /* NEW :  CASE ONE ELEMENT */
301                         for (i = 0; i < dn; i++)
302                                 S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993);
303                         for (i = 0; i < sn; i++)
304                                 D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434);
305                         for (i = 0; i < dn; i++)
306                                 S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233);
307                         for (i = 0; i < sn; i++)
308                                 D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633);
309                         for (i = 0; i < dn; i++)
310                                 S(i) = fix_mul(S(i), 5038);     /*5038 */
311                         for (i = 0; i < sn; i++)
312                                 D(i) = fix_mul(D(i), 6659);     /*6660 */
313                 }
314         }
315 }
316
317 static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) {
318         int p, n;
319         p = int_floorlog2(stepsize) - 13;
320         n = 11 - int_floorlog2(stepsize);
321         bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
322         bandno_stepsize->expn = numbps - p;
323 }
324
325 /* 
326 ==========================================================
327    DWT interface
328 ==========================================================
329 */
330
331 /* <summary>                            */
332 /* Forward 5-3 wavelet transform in 2-D. */
333 /* </summary>                           */
334 void dwt_encode(opj_tcd_tilecomp_t * tilec) {
335         int i, j, k;
336         int *a = NULL;
337         int *aj = NULL;
338         int *bj = NULL;
339         int w, l;
340         
341         w = tilec->x1-tilec->x0;
342         l = tilec->numresolutions-1;
343         a = tilec->data;
344         
345         for (i = 0; i < l; i++) {
346                 int rw;                 /* width of the resolution level computed                                                           */
347                 int rh;                 /* height of the resolution level computed                                                          */
348                 int rw1;                /* width of the resolution level once lower than computed one                                       */
349                 int rh1;                /* height of the resolution level once lower than computed one                                      */
350                 int cas_col;    /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
351                 int cas_row;    /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
352                 int dn, sn;
353                 
354                 rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
355                 rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
356                 rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
357                 rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
358                 
359                 cas_row = tilec->resolutions[l - i].x0 % 2;
360                 cas_col = tilec->resolutions[l - i].y0 % 2;
361         
362                 sn = rh1;
363                 dn = rh - rh1;
364                 bj = (int*)opj_malloc(rh * sizeof(int));
365                 for (j = 0; j < rw; j++) {
366                         aj = a + j;
367                         for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
368                         dwt_encode_1(bj, dn, sn, cas_col);
369                         dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
370                 }
371                 opj_free(bj);
372                 
373                 sn = rw1;
374                 dn = rw - rw1;
375                 bj = (int*)opj_malloc(rw * sizeof(int));
376                 for (j = 0; j < rh; j++) {
377                         aj = a + j * w;
378                         for (k = 0; k < rw; k++)  bj[k] = aj[k];
379                         dwt_encode_1(bj, dn, sn, cas_row);
380                         dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
381                 }
382                 opj_free(bj);
383         }
384 }
385
386 #ifdef OPJ_V1
387 /* <summary>                            */
388 /* Inverse 5-3 wavelet transform in 2-D. */
389 /* </summary>                           */
390 void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) {
391         dwt_decode_tile(tilec, numres, &dwt_decode_1);
392 }
393 #endif
394
395 /* <summary>                            */
396 /* Inverse 5-3 wavelet transform in 2-D. */
397 /* </summary>                           */
398 opj_bool dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) {
399         return dwt_decode_tile(tilec, numres, &dwt_decode_1);
400 }
401
402 /* <summary>                            */
403 /* Inverse 5-3 wavelet transform in 2-D. */
404 /* </summary>                           */
405 opj_bool dwt_decode_v2(opj_tcd_tilecomp_v2_t* tilec, OPJ_UINT32 numres) {
406         return dwt_decode_tile_v2(tilec, numres, &dwt_decode_1);
407 }
408
409
410 /* <summary>                          */
411 /* Get gain of 5-3 wavelet transform. */
412 /* </summary>                         */
413 int dwt_getgain(int orient) {
414         if (orient == 0)
415                 return 0;
416         if (orient == 1 || orient == 2)
417                 return 1;
418         return 2;
419 }
420
421 /* <summary>                          */
422 /* Get gain of 5-3 wavelet transform. */
423 /* </summary>                         */
424 OPJ_UINT32 dwt_getgain_v2(OPJ_UINT32 orient) {
425         if (orient == 0)
426                 return 0;
427         if (orient == 1 || orient == 2)
428                 return 1;
429         return 2;
430 }
431
432 /* <summary>                */
433 /* Get norm of 5-3 wavelet. */
434 /* </summary>               */
435 double dwt_getnorm(int level, int orient) {
436         return dwt_norms[orient][level];
437 }
438
439 /* <summary>                             */
440 /* Forward 9-7 wavelet transform in 2-D. */
441 /* </summary>                            */
442
443 void dwt_encode_real(opj_tcd_tilecomp_t * tilec) {
444         int i, j, k;
445         int *a = NULL;
446         int *aj = NULL;
447         int *bj = NULL;
448         int w, l;
449         
450         w = tilec->x1-tilec->x0;
451         l = tilec->numresolutions-1;
452         a = tilec->data;
453         
454         for (i = 0; i < l; i++) {
455                 int rw;                 /* width of the resolution level computed                                                     */
456                 int rh;                 /* height of the resolution level computed                                                    */
457                 int rw1;                /* width of the resolution level once lower than computed one                                 */
458                 int rh1;                /* height of the resolution level once lower than computed one                                */
459                 int cas_col;    /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */
460                 int cas_row;    /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering   */
461                 int dn, sn;
462                 
463                 rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0;
464                 rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0;
465                 rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0;
466                 rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0;
467                 
468                 cas_row = tilec->resolutions[l - i].x0 % 2;
469                 cas_col = tilec->resolutions[l - i].y0 % 2;
470                 
471                 sn = rh1;
472                 dn = rh - rh1;
473                 bj = (int*)opj_malloc(rh * sizeof(int));
474                 for (j = 0; j < rw; j++) {
475                         aj = a + j;
476                         for (k = 0; k < rh; k++)  bj[k] = aj[k*w];
477                         dwt_encode_1_real(bj, dn, sn, cas_col);
478                         dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col);
479                 }
480                 opj_free(bj);
481                 
482                 sn = rw1;
483                 dn = rw - rw1;
484                 bj = (int*)opj_malloc(rw * sizeof(int));
485                 for (j = 0; j < rh; j++) {
486                         aj = a + j * w;
487                         for (k = 0; k < rw; k++)  bj[k] = aj[k];
488                         dwt_encode_1_real(bj, dn, sn, cas_row);
489                         dwt_deinterleave_h(bj, aj, dn, sn, cas_row);
490                 }
491                 opj_free(bj);
492         }
493 }
494
495
496 /* <summary>                          */
497 /* Get gain of 9-7 wavelet transform. */
498 /* </summary>                         */
499 int dwt_getgain_real(int orient) {
500         (void)orient;
501         return 0;
502 }
503
504 /* <summary>                          */
505 /* Get gain of 9-7 wavelet transform. */
506 /* </summary>                         */
507 OPJ_UINT32 dwt_getgain_real_v2(OPJ_UINT32 orient) {
508         (void)orient;
509         return 0;
510 }
511
512 /* <summary>                */
513 /* Get norm of 9-7 wavelet. */
514 /* </summary>               */
515 double dwt_getnorm_real(int level, int orient) {
516         return dwt_norms_real[orient][level];
517 }
518
519 void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) {
520         int numbands, bandno;
521         numbands = 3 * tccp->numresolutions - 2;
522         for (bandno = 0; bandno < numbands; bandno++) {
523                 double stepsize;
524                 int resno, level, orient, gain;
525
526                 resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1);
527                 orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1);
528                 level = tccp->numresolutions - 1 - resno;
529                 gain = (tccp->qmfbid == 0) ? 0 : ((orient == 0) ? 0 : (((orient == 1) || (orient == 2)) ? 1 : 2));
530                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
531                         stepsize = 1.0;
532                 } else {
533                         double norm = dwt_norms_real[orient][level];
534                         stepsize = (1 << (gain)) / norm;
535                 }
536                 dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]);
537         }
538 }
539
540 #ifdef OPJ_V1
541 /* <summary>                             */
542 /* Determine maximum computed resolution level for inverse wavelet transform */
543 /* </summary>                            */
544 static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) {
545         int mr  = 1;
546         int w;
547         while( --i ) {
548                 r++;
549                 if( mr < ( w = r->x1 - r->x0 ) )
550                         mr = w ;
551                 if( mr < ( w = r->y1 - r->y0 ) )
552                         mr = w ;
553         }
554         return mr ;
555 }
556 #endif
557 /* <summary>                             */
558 /* Determine maximum computed resolution level for inverse wavelet transform */
559 /* </summary>                            */
560 static OPJ_UINT32 dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) {
561         OPJ_UINT32 mr   = 0;
562         OPJ_UINT32 w;
563         while( --i ) {
564                 ++r;
565                 if( mr < ( w = r->x1 - r->x0 ) )
566                         mr = w ;
567                 if( mr < ( w = r->y1 - r->y0 ) )
568                         mr = w ;
569         }
570         return mr ;
571 }
572
573 /* <summary>                             */
574 /* Determine maximum computed resolution level for inverse wavelet transform */
575 /* </summary>                            */
576 static OPJ_UINT32 dwt_max_resolution_v2(opj_tcd_resolution_v2_t* restrict r, OPJ_UINT32 i) {
577         OPJ_UINT32 mr   = 0;
578         OPJ_UINT32 w;
579         while( --i ) {
580                 ++r;
581                 if( mr < ( w = r->x1 - r->x0 ) )
582                         mr = w ;
583                 if( mr < ( w = r->y1 - r->y0 ) )
584                         mr = w ;
585         }
586         return mr ;
587 }
588
589 #ifdef OPJ_V1
590 /* <summary>                            */
591 /* Inverse wavelet transform in 2-D.     */
592 /* </summary>                           */
593 static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1D) {
594         dwt_t h;
595         dwt_t v;
596
597         opj_tcd_resolution_t* tr = tilec->resolutions;
598
599         int rw = tr->x1 - tr->x0;       /* width of the resolution level computed */
600         int rh = tr->y1 - tr->y0;       /* height of the resolution level computed */
601
602         int w = tilec->x1 - tilec->x0;
603
604         h.mem = (int*)opj_aligned_malloc(dwt_max_resolution(tr, numres) * sizeof(int));
605         v.mem = h.mem;
606
607         while( --numres) {
608                 int * restrict tiledp = tilec->data;
609                 int j;
610
611                 ++tr;
612                 h.sn = rw;
613                 v.sn = rh;
614
615                 rw = tr->x1 - tr->x0;
616                 rh = tr->y1 - tr->y0;
617
618                 h.dn = rw - h.sn;
619                 h.cas = tr->x0 % 2;
620
621                 for(j = 0; j < rh; ++j) {
622                         dwt_interleave_h(&h, &tiledp[j*w]);
623                         (dwt_1D)(&h);
624                         memcpy(&tiledp[j*w], h.mem, rw * sizeof(int));
625                 }
626
627                 v.dn = rh - v.sn;
628                 v.cas = tr->y0 % 2;
629
630                 for(j = 0; j < rw; ++j){
631                         int k;
632                         dwt_interleave_v(&v, &tiledp[j], w);
633                         (dwt_1D)(&v);
634                         for(k = 0; k < rh; ++k) {
635                                 tiledp[k * w + j] = v.mem[k];
636                         }
637                 }
638         }
639         opj_aligned_free(h.mem);
640 }
641 #endif
642
643 /* <summary>                            */
644 /* Inverse wavelet transform in 2-D.     */
645 /* </summary>                           */
646 static opj_bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
647         dwt_t h;
648         dwt_t v;
649
650         opj_tcd_resolution_t* tr = tilec->resolutions;
651
652         OPJ_UINT32 rw = tr->x1 - tr->x0;        /* width of the resolution level computed */
653         OPJ_UINT32 rh = tr->y1 - tr->y0;        /* height of the resolution level computed */
654
655         OPJ_UINT32 w = tilec->x1 - tilec->x0;
656
657         h.mem = (OPJ_INT32*)
658         opj_aligned_malloc(dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
659         if
660                 (! h.mem)
661         {
662                 return OPJ_FALSE;
663         }
664
665         v.mem = h.mem;
666
667         while( --numres) {
668                 OPJ_INT32 * restrict tiledp = tilec->data;
669                 OPJ_UINT32 j;
670
671                 ++tr;
672                 h.sn = rw;
673                 v.sn = rh;
674
675                 rw = tr->x1 - tr->x0;
676                 rh = tr->y1 - tr->y0;
677
678                 h.dn = rw - h.sn;
679                 h.cas = tr->x0 % 2;
680
681                 for(j = 0; j < rh; ++j) {
682                         dwt_interleave_h(&h, &tiledp[j*w]);
683                         (dwt_1D)(&h);
684                         memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
685                 }
686
687                 v.dn = rh - v.sn;
688                 v.cas = tr->y0 % 2;
689
690                 for(j = 0; j < rw; ++j){
691                         OPJ_UINT32 k;
692                         dwt_interleave_v(&v, &tiledp[j], w);
693                         (dwt_1D)(&v);
694                         for(k = 0; k < rh; ++k) {
695                                 tiledp[k * w + j] = v.mem[k];
696                         }
697                 }
698         }
699         opj_aligned_free(h.mem);
700         return OPJ_TRUE;
701 }
702
703 /* <summary>                            */
704 /* Inverse wavelet transform in 2-D.     */
705 /* </summary>                           */
706 static opj_bool dwt_decode_tile_v2(opj_tcd_tilecomp_v2_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) {
707         dwt_t h;
708         dwt_t v;
709
710         opj_tcd_resolution_v2_t* tr = tilec->resolutions;
711
712         OPJ_UINT32 rw = tr->x1 - tr->x0;        /* width of the resolution level computed */
713         OPJ_UINT32 rh = tr->y1 - tr->y0;        /* height of the resolution level computed */
714
715         OPJ_UINT32 w = tilec->x1 - tilec->x0;
716
717         h.mem = (OPJ_INT32*)
718         opj_aligned_malloc(dwt_max_resolution_v2(tr, numres) * sizeof(OPJ_INT32));
719         if
720                 (! h.mem)
721         {
722                 return OPJ_FALSE;
723         }
724
725         v.mem = h.mem;
726
727         while( --numres) {
728                 OPJ_INT32 * restrict tiledp = tilec->data;
729                 OPJ_UINT32 j;
730
731                 ++tr;
732                 h.sn = rw;
733                 v.sn = rh;
734
735                 rw = tr->x1 - tr->x0;
736                 rh = tr->y1 - tr->y0;
737
738                 h.dn = rw - h.sn;
739                 h.cas = tr->x0 % 2;
740
741                 for(j = 0; j < rh; ++j) {
742                         dwt_interleave_h(&h, &tiledp[j*w]);
743                         (dwt_1D)(&h);
744                         memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32));
745                 }
746
747                 v.dn = rh - v.sn;
748                 v.cas = tr->y0 % 2;
749
750                 for(j = 0; j < rw; ++j){
751                         OPJ_UINT32 k;
752                         dwt_interleave_v(&v, &tiledp[j], w);
753                         (dwt_1D)(&v);
754                         for(k = 0; k < rh; ++k) {
755                                 tiledp[k * w + j] = v.mem[k];
756                         }
757                 }
758         }
759         opj_aligned_free(h.mem);
760         return OPJ_TRUE;
761 }
762
763 static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){
764         float* restrict bi = (float*) (w->wavelet + w->cas);
765         int count = w->sn;
766         int i, k;
767
768         for(k = 0; k < 2; ++k){
769                 if (count + 3 * x < size && ((size_t) a & 0x0f) == 0 &&
770                                 ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0) {
771                         /* Fast code path */
772                         for(i = 0; i < count; ++i){
773                                 int j = i;
774                                 bi[i*8    ] = a[j];
775                                 j += x;
776                                 bi[i*8 + 1] = a[j];
777                                 j += x;
778                                 bi[i*8 + 2] = a[j];
779                                 j += x;
780                                 bi[i*8 + 3] = a[j];
781                         }
782                 }
783                 else {
784                         /* Slow code path */
785                         for(i = 0; i < count; ++i){
786                                 int j = i;
787                                 bi[i*8    ] = a[j];
788                                 j += x;
789                                 if(j > size) continue;
790                                 bi[i*8 + 1] = a[j];
791                                 j += x;
792                                 if(j > size) continue;
793                                 bi[i*8 + 2] = a[j];
794                                 j += x;
795                                 if(j > size) continue;
796                                 bi[i*8 + 3] = a[j];
797                         }
798                 }
799
800                 bi = (float*) (w->wavelet + 1 - w->cas);
801                 a += w->sn;
802                 size -= w->sn;
803                 count = w->dn;
804         }
805 }
806
807 static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){
808         v4* restrict bi = v->wavelet + v->cas;
809         int i;
810         for(i = 0; i < v->sn; ++i){
811                 memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
812         }
813         a += v->sn * x;
814         bi = v->wavelet + 1 - v->cas;
815         for(i = 0; i < v->dn; ++i){
816                 memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float));
817         }
818 }
819
820 #ifdef __SSE__
821
822 static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
823         __m128* restrict vw = (__m128*) w;
824         int i;
825         /* 4x unrolled loop */
826         for(i = 0; i < count >> 2; ++i){
827                 *vw = _mm_mul_ps(*vw, c);
828                 vw += 2;
829                 *vw = _mm_mul_ps(*vw, c);
830                 vw += 2;
831                 *vw = _mm_mul_ps(*vw, c);
832                 vw += 2;
833                 *vw = _mm_mul_ps(*vw, c);
834                 vw += 2;
835         }
836         count &= 3;
837         for(i = 0; i < count; ++i){
838                 *vw = _mm_mul_ps(*vw, c);
839                 vw += 2;
840         }
841 }
842
843 static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
844         __m128* restrict vl = (__m128*) l;
845         __m128* restrict vw = (__m128*) w;
846         int i;
847         __m128 tmp1, tmp2, tmp3;
848         tmp1 = vl[0];
849         for(i = 0; i < m; ++i){
850                 tmp2 = vw[-1];
851                 tmp3 = vw[ 0];
852                 vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
853                 tmp1 = tmp3;
854                 vw += 2;
855         }
856         vl = vw - 2;
857         if(m >= k){
858                 return;
859         }
860         c = _mm_add_ps(c, c);
861         c = _mm_mul_ps(c, vl[0]);
862         for(; m < k; ++m){
863                 __m128 tmp = vw[-1];
864                 vw[-1] = _mm_add_ps(tmp, c);
865                 vw += 2;
866         }
867 }
868
869 #else
870
871 static void v4dwt_decode_step1(v4* w, int count, const float c){
872         float* restrict fw = (float*) w;
873         int i;
874         for(i = 0; i < count; ++i){
875                 float tmp1 = fw[i*8    ];
876                 float tmp2 = fw[i*8 + 1];
877                 float tmp3 = fw[i*8 + 2];
878                 float tmp4 = fw[i*8 + 3];
879                 fw[i*8    ] = tmp1 * c;
880                 fw[i*8 + 1] = tmp2 * c;
881                 fw[i*8 + 2] = tmp3 * c;
882                 fw[i*8 + 3] = tmp4 * c;
883         }
884 }
885
886 static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
887         float* restrict fl = (float*) l;
888         float* restrict fw = (float*) w;
889         int i;
890         for(i = 0; i < m; ++i){
891                 float tmp1_1 = fl[0];
892                 float tmp1_2 = fl[1];
893                 float tmp1_3 = fl[2];
894                 float tmp1_4 = fl[3];
895                 float tmp2_1 = fw[-4];
896                 float tmp2_2 = fw[-3];
897                 float tmp2_3 = fw[-2];
898                 float tmp2_4 = fw[-1];
899                 float tmp3_1 = fw[0];
900                 float tmp3_2 = fw[1];
901                 float tmp3_3 = fw[2];
902                 float tmp3_4 = fw[3];
903                 fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
904                 fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
905                 fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
906                 fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
907                 fl = fw;
908                 fw += 8;
909         }
910         if(m < k){
911                 float c1;
912                 float c2;
913                 float c3;
914                 float c4;
915                 c += c;
916                 c1 = fl[0] * c;
917                 c2 = fl[1] * c;
918                 c3 = fl[2] * c;
919                 c4 = fl[3] * c;
920                 for(; m < k; ++m){
921                         float tmp1 = fw[-4];
922                         float tmp2 = fw[-3];
923                         float tmp3 = fw[-2];
924                         float tmp4 = fw[-1];
925                         fw[-4] = tmp1 + c1;
926                         fw[-3] = tmp2 + c2;
927                         fw[-2] = tmp3 + c3;
928                         fw[-1] = tmp4 + c4;
929                         fw += 8;
930                 }
931         }
932 }
933
934 #endif
935
936 /* <summary>                             */
937 /* Inverse 9-7 wavelet transform in 1-D. */
938 /* </summary>                            */
939 static void v4dwt_decode(v4dwt_t* restrict dwt){
940         int a, b;
941         if(dwt->cas == 0) {
942                 if(!((dwt->dn > 0) || (dwt->sn > 1))){
943                         return;
944                 }
945                 a = 0;
946                 b = 1;
947         }else{
948                 if(!((dwt->sn > 0) || (dwt->dn > 1))) {
949                         return;
950                 }
951                 a = 1;
952                 b = 0;
953         }
954 #ifdef __SSE__
955         v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K));
956         v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318));
957         v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta));
958         v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma));
959         v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta));
960         v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha));
961 #else
962         v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K);
963         v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318);
964         v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
965         v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
966         v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
967         v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
968 #endif
969 }
970
971
972 // KEEP TRUNK VERSION + return type of v2 because rev557
973 /* <summary>                             */
974 /* Inverse 9-7 wavelet transform in 2-D. */
975 /* </summary>                            */
976 // V1 void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
977 opj_bool dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
978         v4dwt_t h;
979         v4dwt_t v;
980
981         opj_tcd_resolution_t* res = tilec->resolutions;
982
983         int rw = res->x1 - res->x0;     /* width of the resolution level computed */
984         int rh = res->y1 - res->y0;     /* height of the resolution level computed */
985
986         int w = tilec->x1 - tilec->x0;
987
988         h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution(res, numres)+5) * sizeof(v4));
989         v.wavelet = h.wavelet;
990
991         while( --numres) {
992                 float * restrict aj = (float*) tilec->data;
993                 int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
994                 int j;
995
996                 h.sn = rw;
997                 v.sn = rh;
998
999                 ++res;
1000
1001                 rw = res->x1 - res->x0; /* width of the resolution level computed */
1002                 rh = res->y1 - res->y0; /* height of the resolution level computed */
1003
1004                 h.dn = rw - h.sn;
1005                 h.cas = res->x0 % 2;
1006
1007                 for(j = rh; j > 3; j -= 4){
1008                         int k;
1009                         v4dwt_interleave_h(&h, aj, w, bufsize);
1010                         v4dwt_decode(&h);
1011                                 for(k = rw; --k >= 0;){
1012                                         aj[k    ] = h.wavelet[k].f[0];
1013                                         aj[k+w  ] = h.wavelet[k].f[1];
1014                                         aj[k+w*2] = h.wavelet[k].f[2];
1015                                         aj[k+w*3] = h.wavelet[k].f[3];
1016                                 }
1017                         aj += w*4;
1018                         bufsize -= w*4;
1019                 }
1020                 if (rh & 0x03) {
1021                                 int k;
1022                         j = rh & 0x03;
1023                         v4dwt_interleave_h(&h, aj, w, bufsize);
1024                         v4dwt_decode(&h);
1025                                 for(k = rw; --k >= 0;){
1026                                         switch(j) {
1027                                                 case 3: aj[k+w*2] = h.wavelet[k].f[2];
1028                                                 case 2: aj[k+w  ] = h.wavelet[k].f[1];
1029                                                 case 1: aj[k    ] = h.wavelet[k].f[0];
1030                                         }
1031                                 }
1032                         }
1033
1034                 v.dn = rh - v.sn;
1035                 v.cas = res->y0 % 2;
1036
1037                 aj = (float*) tilec->data;
1038                 for(j = rw; j > 3; j -= 4){
1039                         int k;
1040                         v4dwt_interleave_v(&v, aj, w);
1041                         v4dwt_decode(&v);
1042                                 for(k = 0; k < rh; ++k){
1043                                         memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float));
1044                                 }
1045                         aj += 4;
1046                 }
1047                 if (rw & 0x03){
1048                                 int k;
1049                         j = rw & 0x03;
1050                         v4dwt_interleave_v(&v, aj, w);
1051                         v4dwt_decode(&v);
1052                                 for(k = 0; k < rh; ++k){
1053                                         memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float));
1054                                 }
1055                         }
1056         }
1057
1058         opj_aligned_free(h.wavelet);
1059         return OPJ_TRUE;
1060 }
1061
1062
1063 /* <summary>                             */
1064 /* Inverse 9-7 wavelet transform in 2-D. */
1065 /* </summary>                            */
1066 opj_bool dwt_decode_real_v2(opj_tcd_tilecomp_v2_t* restrict tilec, OPJ_UINT32 numres){
1067         v4dwt_t h;
1068         v4dwt_t v;
1069
1070         opj_tcd_resolution_v2_t* res = tilec->resolutions;
1071
1072         OPJ_UINT32 rw = res->x1 - res->x0;      /* width of the resolution level computed */
1073         OPJ_UINT32 rh = res->y1 - res->y0;      /* height of the resolution level computed */
1074
1075         OPJ_UINT32 w = tilec->x1 - tilec->x0;
1076
1077         h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution_v2(res, numres)+5) * sizeof(v4));
1078         v.wavelet = h.wavelet;
1079
1080         while( --numres) {
1081                 OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data;
1082                 OPJ_UINT32 bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
1083                 OPJ_INT32 j;
1084
1085                 h.sn = rw;
1086                 v.sn = rh;
1087
1088                 ++res;
1089
1090                 rw = res->x1 - res->x0; /* width of the resolution level computed */
1091                 rh = res->y1 - res->y0; /* height of the resolution level computed */
1092
1093                 h.dn = rw - h.sn;
1094                 h.cas = res->x0 % 2;
1095
1096                 for(j = rh; j > 3; j -= 4) {
1097                         OPJ_INT32 k;
1098                         v4dwt_interleave_h(&h, aj, w, bufsize);
1099                         v4dwt_decode(&h);
1100
1101                         for(k = rw; --k >= 0;){
1102                                 aj[k    ] = h.wavelet[k].f[0];
1103                                 aj[k+w  ] = h.wavelet[k].f[1];
1104                                 aj[k+w*2] = h.wavelet[k].f[2];
1105                                 aj[k+w*3] = h.wavelet[k].f[3];
1106                         }
1107
1108                         aj += w*4;
1109                         bufsize -= w*4;
1110                 }
1111
1112                 if (rh & 0x03) {
1113                         int k;
1114                         j = rh & 0x03;
1115                         v4dwt_interleave_h(&h, aj, w, bufsize);
1116                         v4dwt_decode(&h);
1117                         for(k = rw; --k >= 0;){
1118                                 switch(j) {
1119                                         case 3: aj[k+w*2] = h.wavelet[k].f[2];
1120                                         case 2: aj[k+w  ] = h.wavelet[k].f[1];
1121                                         case 1: aj[k    ] = h.wavelet[k].f[0];
1122                                 }
1123                         }
1124                 }
1125
1126                 v.dn = rh - v.sn;
1127                 v.cas = res->y0 % 2;
1128
1129                 aj = (OPJ_FLOAT32*) tilec->data;
1130                 for(j = rw; j > 3; j -= 4){
1131                         OPJ_INT32 k;
1132
1133                         v4dwt_interleave_v(&v, aj, w);
1134                         v4dwt_decode(&v);
1135
1136                         for(k = 0; k < rh; ++k){
1137                                 memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
1138                         }
1139                         aj += 4;
1140                 }
1141
1142                 if (rw & 0x03){
1143                         OPJ_INT32 k;
1144
1145                         j = rw & 0x03;
1146
1147                         v4dwt_interleave_v(&v, aj, w);
1148                         v4dwt_decode(&v);
1149
1150                         for(k = 0; k < rh; ++k){
1151                                 memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(OPJ_FLOAT32));
1152                         }
1153                 }
1154         }
1155
1156         opj_aligned_free(h.wavelet);
1157         return OPJ_TRUE;
1158 }