[trunk] fix warnings when printing large integers
[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 && ((size_t) bi & 0x0f) == 0 && (x & 0x0f) == 0 ) {
770                         /* Fast code path */
771                         for(i = 0; i < count; ++i){
772                                 int j = i;
773                                 bi[i*8    ] = a[j];
774                                 j += x;
775                                 bi[i*8 + 1] = a[j];
776                                 j += x;
777                                 bi[i*8 + 2] = a[j];
778                                 j += x;
779                                 bi[i*8 + 3] = a[j];
780                         }
781                 }
782                 else {
783                         /* Slow code path */
784                         for(i = 0; i < count; ++i){
785                                 int j = i;
786                                 bi[i*8    ] = a[j];
787                                 j += x;
788                                 if(j >= size) continue;
789                                 bi[i*8 + 1] = a[j];
790                                 j += x;
791                                 if(j >= size) continue;
792                                 bi[i*8 + 2] = a[j];
793                                 j += x;
794                                 if(j >= size) continue;
795                                 bi[i*8 + 3] = a[j]; /* This one*/
796                         }
797                 }
798
799                 bi = (float*) (w->wavelet + 1 - w->cas);
800                 a += w->sn;
801                 size -= w->sn;
802                 count = w->dn;
803         }
804 }
805
806 static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x, int nb_elts_read){
807         v4* restrict bi = v->wavelet + v->cas;
808         int i;
809
810         for(i = 0; i < v->sn; ++i){
811                 memcpy(&bi[i*2], &a[i*x], nb_elts_read * sizeof(float));
812         }
813
814         a += v->sn * x;
815         bi = v->wavelet + 1 - v->cas;
816
817         for(i = 0; i < v->dn; ++i){
818                 memcpy(&bi[i*2], &a[i*x], nb_elts_read * sizeof(float));
819         }
820 }
821
822 #ifdef __SSE__
823
824 static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){
825         __m128* restrict vw = (__m128*) w;
826         int i;
827         /* 4x unrolled loop */
828         for(i = 0; i < count >> 2; ++i){
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                 *vw = _mm_mul_ps(*vw, c);
836                 vw += 2;
837         }
838         count &= 3;
839         for(i = 0; i < count; ++i){
840                 *vw = _mm_mul_ps(*vw, c);
841                 vw += 2;
842         }
843 }
844
845 static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){
846         __m128* restrict vl = (__m128*) l;
847         __m128* restrict vw = (__m128*) w;
848         int i;
849         __m128 tmp1, tmp2, tmp3;
850         tmp1 = vl[0];
851         for(i = 0; i < m; ++i){
852                 tmp2 = vw[-1];
853                 tmp3 = vw[ 0];
854                 vw[-1] = _mm_add_ps(tmp2, _mm_mul_ps(_mm_add_ps(tmp1, tmp3), c));
855                 tmp1 = tmp3;
856                 vw += 2;
857         }
858         vl = vw - 2;
859         if(m >= k){
860                 return;
861         }
862         c = _mm_add_ps(c, c);
863         c = _mm_mul_ps(c, vl[0]);
864         for(; m < k; ++m){
865                 __m128 tmp = vw[-1];
866                 vw[-1] = _mm_add_ps(tmp, c);
867                 vw += 2;
868         }
869 }
870
871 #else
872
873 static void v4dwt_decode_step1(v4* w, int count, const float c){
874         float* restrict fw = (float*) w;
875         int i;
876         for(i = 0; i < count; ++i){
877                 float tmp1 = fw[i*8    ];
878                 float tmp2 = fw[i*8 + 1];
879                 float tmp3 = fw[i*8 + 2];
880                 float tmp4 = fw[i*8 + 3];
881                 fw[i*8    ] = tmp1 * c;
882                 fw[i*8 + 1] = tmp2 * c;
883                 fw[i*8 + 2] = tmp3 * c;
884                 fw[i*8 + 3] = tmp4 * c;
885         }
886 }
887
888 static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){
889         float* restrict fl = (float*) l;
890         float* restrict fw = (float*) w;
891         int i;
892         for(i = 0; i < m; ++i){
893                 float tmp1_1 = fl[0];
894                 float tmp1_2 = fl[1];
895                 float tmp1_3 = fl[2];
896                 float tmp1_4 = fl[3];
897                 float tmp2_1 = fw[-4];
898                 float tmp2_2 = fw[-3];
899                 float tmp2_3 = fw[-2];
900                 float tmp2_4 = fw[-1];
901                 float tmp3_1 = fw[0];
902                 float tmp3_2 = fw[1];
903                 float tmp3_3 = fw[2];
904                 float tmp3_4 = fw[3];
905                 fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c);
906                 fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c);
907                 fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c);
908                 fw[-1] = tmp2_4 + ((tmp1_4 + tmp3_4) * c);
909                 fl = fw;
910                 fw += 8;
911         }
912         if(m < k){
913                 float c1;
914                 float c2;
915                 float c3;
916                 float c4;
917                 c += c;
918                 c1 = fl[0] * c;
919                 c2 = fl[1] * c;
920                 c3 = fl[2] * c;
921                 c4 = fl[3] * c;
922                 for(; m < k; ++m){
923                         float tmp1 = fw[-4];
924                         float tmp2 = fw[-3];
925                         float tmp3 = fw[-2];
926                         float tmp4 = fw[-1];
927                         fw[-4] = tmp1 + c1;
928                         fw[-3] = tmp2 + c2;
929                         fw[-2] = tmp3 + c3;
930                         fw[-1] = tmp4 + c4;
931                         fw += 8;
932                 }
933         }
934 }
935
936 #endif
937
938 /* <summary>                             */
939 /* Inverse 9-7 wavelet transform in 1-D. */
940 /* </summary>                            */
941 static void v4dwt_decode(v4dwt_t* restrict dwt){
942         int a, b;
943         if(dwt->cas == 0) {
944                 if(!((dwt->dn > 0) || (dwt->sn > 1))){
945                         return;
946                 }
947                 a = 0;
948                 b = 1;
949         }else{
950                 if(!((dwt->sn > 0) || (dwt->dn > 1))) {
951                         return;
952                 }
953                 a = 1;
954                 b = 0;
955         }
956 #ifdef __SSE__
957         v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K));
958         v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318));
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_delta));
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_gamma));
961         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));
962         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));
963 #else
964         v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K);
965         v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318);
966         v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta);
967         v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma);
968         v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta);
969         v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha);
970 #endif
971 }
972
973
974 // KEEP TRUNK VERSION + return type of v2 because rev557
975 /* <summary>                             */
976 /* Inverse 9-7 wavelet transform in 2-D. */
977 /* </summary>                            */
978 // V1 void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
979 opj_bool dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){
980         v4dwt_t h;
981         v4dwt_t v;
982
983         opj_tcd_resolution_t* res = tilec->resolutions;
984
985         int rw = res->x1 - res->x0;     /* width of the resolution level computed */
986         int rh = res->y1 - res->y0;     /* height of the resolution level computed */
987
988         int w = tilec->x1 - tilec->x0;
989
990         h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution(res, numres)+5) * sizeof(v4));
991         v.wavelet = h.wavelet;
992
993         while( --numres) {
994                 float * restrict aj = (float*) tilec->data;
995                 int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
996                 int j;
997
998                 h.sn = rw;
999                 v.sn = rh;
1000
1001                 ++res;
1002
1003                 rw = res->x1 - res->x0; /* width of the resolution level computed */
1004                 rh = res->y1 - res->y0; /* height of the resolution level computed */
1005
1006                 h.dn = rw - h.sn;
1007                 h.cas = res->x0 % 2;
1008
1009                 for(j = rh; j > 3; j -= 4){
1010                         int k;
1011                         v4dwt_interleave_h(&h, aj, w, bufsize);
1012                         v4dwt_decode(&h);
1013                                 for(k = rw; --k >= 0;){
1014                                         aj[k    ] = h.wavelet[k].f[0];
1015                                         aj[k+w  ] = h.wavelet[k].f[1];
1016                                         aj[k+w*2] = h.wavelet[k].f[2];
1017                                         aj[k+w*3] = h.wavelet[k].f[3];
1018                                 }
1019                         aj += w*4;
1020                         bufsize -= w*4;
1021                 }
1022                 if (rh & 0x03) {
1023                                 int k;
1024                         j = rh & 0x03;
1025                         v4dwt_interleave_h(&h, aj, w, bufsize);
1026                         v4dwt_decode(&h);
1027                                 for(k = rw; --k >= 0;){
1028                                         switch(j) {
1029                                                 case 3: aj[k+w*2] = h.wavelet[k].f[2];
1030                                                 case 2: aj[k+w  ] = h.wavelet[k].f[1];
1031                                                 case 1: aj[k    ] = h.wavelet[k].f[0];
1032                                         }
1033                                 }
1034                         }
1035
1036                 v.dn = rh - v.sn;
1037                 v.cas = res->y0 % 2;
1038
1039                 aj = (float*) tilec->data;
1040                 for(j = rw; j > 3; j -= 4){
1041                         int k;
1042                         v4dwt_interleave_v(&v, aj, w, 4);
1043                         v4dwt_decode(&v);
1044                                 for(k = 0; k < rh; ++k){
1045                                         memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float));
1046                                 }
1047                         aj += 4;
1048                 }
1049                 if (rw & 0x03){
1050                                 int k;
1051                         j = rw & 0x03;
1052                         v4dwt_interleave_v(&v, aj, w, j);
1053                         v4dwt_decode(&v);
1054                                 for(k = 0; k < rh; ++k){
1055                                         memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float));
1056                                 }
1057                         }
1058         }
1059
1060         opj_aligned_free(h.wavelet);
1061         return OPJ_TRUE;
1062 }
1063
1064
1065 /* <summary>                             */
1066 /* Inverse 9-7 wavelet transform in 2-D. */
1067 /* </summary>                            */
1068 opj_bool dwt_decode_real_v2(opj_tcd_tilecomp_v2_t* restrict tilec, OPJ_UINT32 numres){
1069         v4dwt_t h;
1070         v4dwt_t v;
1071
1072         opj_tcd_resolution_v2_t* res = tilec->resolutions;
1073
1074         OPJ_UINT32 rw = res->x1 - res->x0;      /* width of the resolution level computed */
1075         OPJ_UINT32 rh = res->y1 - res->y0;      /* height of the resolution level computed */
1076
1077         OPJ_UINT32 w = tilec->x1 - tilec->x0;
1078
1079         h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution_v2(res, numres)+5) * sizeof(v4));
1080         v.wavelet = h.wavelet;
1081
1082         while( --numres) {
1083                 OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data;
1084                 OPJ_UINT32 bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0);
1085                 OPJ_INT32 j;
1086
1087                 h.sn = rw;
1088                 v.sn = rh;
1089
1090                 ++res;
1091
1092                 rw = res->x1 - res->x0; /* width of the resolution level computed */
1093                 rh = res->y1 - res->y0; /* height of the resolution level computed */
1094
1095                 h.dn = rw - h.sn;
1096                 h.cas = res->x0 % 2;
1097
1098                 for(j = rh; j > 3; j -= 4) {
1099                         OPJ_INT32 k;
1100                         v4dwt_interleave_h(&h, aj, w, bufsize);
1101                         v4dwt_decode(&h);
1102
1103                         for(k = rw; --k >= 0;){
1104                                 aj[k    ] = h.wavelet[k].f[0];
1105                                 aj[k+w  ] = h.wavelet[k].f[1];
1106                                 aj[k+w*2] = h.wavelet[k].f[2];
1107                                 aj[k+w*3] = h.wavelet[k].f[3];
1108                         }
1109
1110                         aj += w*4;
1111                         bufsize -= w*4;
1112                 }
1113
1114                 if (rh & 0x03) {
1115                         int k;
1116                         j = rh & 0x03;
1117                         v4dwt_interleave_h(&h, aj, w, bufsize);
1118                         v4dwt_decode(&h);
1119                         for(k = rw; --k >= 0;){
1120                                 switch(j) {
1121                                         case 3: aj[k+w*2] = h.wavelet[k].f[2];
1122                                         case 2: aj[k+w  ] = h.wavelet[k].f[1];
1123                                         case 1: aj[k    ] = h.wavelet[k].f[0];
1124                                 }
1125                         }
1126                 }
1127
1128                 v.dn = rh - v.sn;
1129                 v.cas = res->y0 % 2;
1130
1131                 aj = (OPJ_FLOAT32*) tilec->data;
1132                 for(j = rw; j > 3; j -= 4){
1133                         OPJ_INT32 k;
1134
1135                         v4dwt_interleave_v(&v, aj, w, 4);
1136                         v4dwt_decode(&v);
1137
1138                         for(k = 0; k < rh; ++k){
1139                                 memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32));
1140                         }
1141                         aj += 4;
1142                 }
1143
1144                 if (rw & 0x03){
1145                         OPJ_INT32 k;
1146
1147                         j = rw & 0x03;
1148
1149                         v4dwt_interleave_v(&v, aj, w, j);
1150                         v4dwt_decode(&v);
1151
1152                         for(k = 0; k < rh; ++k){
1153                                 memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(OPJ_FLOAT32));
1154                         }
1155                 }
1156         }
1157
1158         opj_aligned_free(h.wavelet);
1159         return OPJ_TRUE;
1160 }