Move the sources to trunk
[opencv] / otherlibs / _graphics / src / libjasper / jpc_qmfb.c
1 /*
2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3  *   British Columbia.
4  * Copyright (c) 2001-2003 Michael David Adams.
5  * All rights reserved.
6  */
7
8 /* __START_OF_JASPER_LICENSE__
9  * 
10  * JasPer License Version 2.0
11  * 
12  * Copyright (c) 1999-2000 Image Power, Inc.
13  * Copyright (c) 1999-2000 The University of British Columbia
14  * Copyright (c) 2001-2003 Michael David Adams
15  * 
16  * All rights reserved.
17  * 
18  * Permission is hereby granted, free of charge, to any person (the
19  * "User") obtaining a copy of this software and associated documentation
20  * files (the "Software"), to deal in the Software without restriction,
21  * including without limitation the rights to use, copy, modify, merge,
22  * publish, distribute, and/or sell copies of the Software, and to permit
23  * persons to whom the Software is furnished to do so, subject to the
24  * following conditions:
25  * 
26  * 1.  The above copyright notices and this permission notice (which
27  * includes the disclaimer below) shall be included in all copies or
28  * substantial portions of the Software.
29  * 
30  * 2.  The name of a copyright holder shall not be used to endorse or
31  * promote products derived from the Software without specific prior
32  * written permission.
33  * 
34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60  * 
61  * __END_OF_JASPER_LICENSE__
62  */
63
64 /*
65  * Quadrature Mirror-Image Filter Bank (QMFB) Library
66  *
67  * $Id: jpc_qmfb.c,v 1.1 2007/01/15 16:09:28 vp153 Exp $
68  */
69
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73
74 #include <assert.h>
75
76 #include "jasper/jas_fix.h"
77 #include "jasper/jas_malloc.h"
78 #include "jasper/jas_math.h"
79
80 #include "jpc_qmfb.h"
81 #include "jpc_tsfb.h"
82 #include "jpc_math.h"
83
84 /******************************************************************************\
85 *
86 \******************************************************************************/
87
88 static jpc_qmfb1d_t *jpc_qmfb1d_create(void);
89
90 static int jpc_ft_getnumchans(jpc_qmfb1d_t *qmfb);
91 static int jpc_ft_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
92 static int jpc_ft_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
93 static void jpc_ft_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
94 static void jpc_ft_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
95
96 static int jpc_ns_getnumchans(jpc_qmfb1d_t *qmfb);
97 static int jpc_ns_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
98 static int jpc_ns_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters);
99 static void jpc_ns_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
100 static void jpc_ns_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x);
101
102 /******************************************************************************\
103 *
104 \******************************************************************************/
105
106 jpc_qmfb1dops_t jpc_ft_ops = {
107         jpc_ft_getnumchans,
108         jpc_ft_getanalfilters,
109         jpc_ft_getsynfilters,
110         jpc_ft_analyze,
111         jpc_ft_synthesize
112 };
113
114 jpc_qmfb1dops_t jpc_ns_ops = {
115         jpc_ns_getnumchans,
116         jpc_ns_getanalfilters,
117         jpc_ns_getsynfilters,
118         jpc_ns_analyze,
119         jpc_ns_synthesize
120 };
121
122 /******************************************************************************\
123 *
124 \******************************************************************************/
125
126 static void jpc_qmfb1d_setup(jpc_fix_t *startptr, int startind, int endind,
127   int intrastep, jpc_fix_t **lstartptr, int *lstartind, int *lendind,
128   jpc_fix_t **hstartptr, int *hstartind, int *hendind)
129 {
130         *lstartind = JPC_CEILDIVPOW2(startind, 1);
131         *lendind = JPC_CEILDIVPOW2(endind, 1);
132         *hstartind = JPC_FLOORDIVPOW2(startind, 1);
133         *hendind = JPC_FLOORDIVPOW2(endind, 1);
134         *lstartptr = startptr;
135         *hstartptr = &startptr[(*lendind - *lstartind) * intrastep];
136 }
137
138 static void jpc_qmfb1d_split(jpc_fix_t *startptr, int startind, int endind,
139   register int step, jpc_fix_t *lstartptr, int lstartind, int lendind,
140   jpc_fix_t *hstartptr, int hstartind, int hendind)
141 {
142         int bufsize = JPC_CEILDIVPOW2(endind - startind, 2);
143 #if !defined(HAVE_VLA)
144 #define QMFB_SPLITBUFSIZE 4096
145         jpc_fix_t splitbuf[QMFB_SPLITBUFSIZE];
146 #else
147         jpc_fix_t splitbuf[bufsize];
148 #endif
149         jpc_fix_t *buf = splitbuf;
150         int llen;
151         int hlen;
152         int twostep;
153         jpc_fix_t *tmpptr;
154         register jpc_fix_t *ptr;
155         register jpc_fix_t *hptr;
156         register jpc_fix_t *lptr;
157         register int n;
158         int state;
159
160         twostep = step << 1;
161         llen = lendind - lstartind;
162         hlen = hendind - hstartind;
163
164 #if !defined(HAVE_VLA)
165         /* Get a buffer. */
166         if (bufsize > QMFB_SPLITBUFSIZE) {
167                 if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
168                         /* We have no choice but to commit suicide in this case. */
169                         abort();
170                 }
171         }
172 #endif
173
174         if (hstartind < lstartind) {
175                 /* The first sample in the input signal is to appear
176                   in the highpass subband signal. */
177                 /* Copy the appropriate samples into the lowpass subband
178                   signal, saving any samples destined for the highpass subband
179                   signal as they are overwritten. */
180                 tmpptr = buf;
181                 ptr = &startptr[step];
182                 lptr = lstartptr;
183                 n = llen;
184                 state = 1;
185                 while (n-- > 0) {
186                         if (state) {
187                                 *tmpptr = *lptr;
188                                 ++tmpptr;
189                         }
190                         *lptr = *ptr;
191                         ptr += twostep;
192                         lptr += step;
193                         state ^= 1;
194                 }
195                 /* Copy the appropriate samples into the highpass subband
196                   signal. */
197                 /* Handle the nonoverwritten samples. */
198                 hptr = &hstartptr[(hlen - 1) * step];
199                 ptr = &startptr[(((llen + hlen - 1) >> 1) << 1) * step];
200                 n = hlen - (tmpptr - buf);
201                 while (n-- > 0) {
202                         *hptr = *ptr;
203                         hptr -= step;
204                         ptr -= twostep;
205                 }
206                 /* Handle the overwritten samples. */
207                 n = tmpptr - buf;
208                 while (n-- > 0) {
209                         --tmpptr;
210                         *hptr = *tmpptr;
211                         hptr -= step;
212                 }
213         } else {
214                 /* The first sample in the input signal is to appear
215                   in the lowpass subband signal. */
216                 /* Copy the appropriate samples into the lowpass subband
217                   signal, saving any samples for the highpass subband
218                   signal as they are overwritten. */
219                 state = 0;
220                 ptr = startptr;
221                 lptr = lstartptr;
222                 tmpptr = buf;
223                 n = llen;
224                 while (n-- > 0) {
225                         if (state) {
226                                 *tmpptr = *lptr;
227                                 ++tmpptr;
228                         }
229                         *lptr = *ptr;
230                         ptr += twostep;
231                         lptr += step;
232                         state ^= 1;
233                 }
234                 /* Copy the appropriate samples into the highpass subband
235                   signal. */
236                 /* Handle the nonoverwritten samples. */
237                 ptr = &startptr[((((llen + hlen) >> 1) << 1) - 1) * step];
238                 hptr = &hstartptr[(hlen - 1) * step];
239                 n = hlen - (tmpptr - buf);
240                 while (n-- > 0) {
241                         *hptr = *ptr;
242                         ptr -= twostep;
243                         hptr -= step;
244                 }
245                 /* Handle the overwritten samples. */
246                 n = tmpptr - buf;
247                 while (n-- > 0) {
248                         --tmpptr;
249                         *hptr = *tmpptr;
250                         hptr -= step;
251                 }
252         }
253
254 #if !defined(HAVE_VLA)
255         /* If the split buffer was allocated on the heap, free this memory. */
256         if (buf != splitbuf) {
257                 jas_free(buf);
258         }
259 #endif
260 }
261
262 static void jpc_qmfb1d_join(jpc_fix_t *startptr, int startind, int endind,
263   register int step, jpc_fix_t *lstartptr, int lstartind, int lendind,
264   jpc_fix_t *hstartptr, int hstartind, int hendind)
265 {
266         int bufsize = JPC_CEILDIVPOW2(endind - startind, 2);
267 #if !defined(HAVE_VLA)
268 #define QMFB_JOINBUFSIZE        4096
269         jpc_fix_t joinbuf[QMFB_JOINBUFSIZE];
270 #else
271         jpc_fix_t joinbuf[bufsize];
272 #endif
273         jpc_fix_t *buf = joinbuf;
274         int llen;
275         int hlen;
276         int twostep;
277         jpc_fix_t *tmpptr;
278         register jpc_fix_t *ptr;
279         register jpc_fix_t *hptr;
280         register jpc_fix_t *lptr;
281         register int n;
282         int state;
283
284 #if !defined(HAVE_VLA)
285         /* Allocate memory for the join buffer from the heap. */
286         if (bufsize > QMFB_JOINBUFSIZE) {
287                 if (!(buf = jas_malloc(bufsize * sizeof(jpc_fix_t)))) {
288                         /* We have no choice but to commit suicide. */
289                         abort();
290                 }
291         }
292 #endif
293
294         twostep = step << 1;
295         llen = lendind - lstartind;
296         hlen = hendind - hstartind;
297
298         if (hstartind < lstartind) {
299                 /* The first sample in the highpass subband signal is to
300                   appear first in the output signal. */
301                 /* Copy the appropriate samples into the first phase of the
302                   output signal. */
303                 tmpptr = buf;
304                 hptr = hstartptr;
305                 ptr = startptr;
306                 n = (llen + 1) >> 1;
307                 while (n-- > 0) {
308                         *tmpptr = *ptr;
309                         *ptr = *hptr;
310                         ++tmpptr;
311                         ptr += twostep;
312                         hptr += step;
313                 }
314                 n = hlen - ((llen + 1) >> 1);
315                 while (n-- > 0) {
316                         *ptr = *hptr;
317                         ptr += twostep;
318                         hptr += step;
319                 }
320                 /* Copy the appropriate samples into the second phase of
321                   the output signal. */
322                 ptr -= (lendind > hendind) ? (step) : (step + twostep);
323                 state = !((llen - 1) & 1);
324                 lptr = &lstartptr[(llen - 1) * step];
325                 n = llen;
326                 while (n-- > 0) {
327                         if (state) {
328                                 --tmpptr;
329                                 *ptr = *tmpptr;
330                         } else {
331                                 *ptr = *lptr;
332                         }
333                         lptr -= step;
334                         ptr -= twostep;
335                         state ^= 1;
336                 }
337         } else {
338                 /* The first sample in the lowpass subband signal is to
339                   appear first in the output signal. */
340                 /* Copy the appropriate samples into the first phase of the
341                   output signal (corresponding to even indexed samples). */
342                 lptr = &lstartptr[(llen - 1) * step];
343                 ptr = &startptr[((llen - 1) << 1) * step];
344                 n = llen >> 1;
345                 tmpptr = buf;
346                 while (n-- > 0) {
347                         *tmpptr = *ptr;
348                         *ptr = *lptr;
349                         ++tmpptr;
350                         ptr -= twostep;
351                         lptr -= step;
352                 }
353                 n = llen - (llen >> 1);
354                 while (n-- > 0) {
355                         *ptr = *lptr;
356                         ptr -= twostep;
357                         lptr -= step;
358                 }
359                 /* Copy the appropriate samples into the second phase of
360                   the output signal (corresponding to odd indexed
361                   samples). */
362                 ptr = &startptr[step];
363                 hptr = hstartptr;
364                 state = !(llen & 1);
365                 n = hlen;
366                 while (n-- > 0) {
367                         if (state) {
368                                 --tmpptr;
369                                 *ptr = *tmpptr;
370                         } else {
371                                 *ptr = *hptr;
372                         }
373                         hptr += step;
374                         ptr += twostep;
375                         state ^= 1;
376                 }
377         }
378
379 #if !defined(HAVE_VLA)
380         /* If the join buffer was allocated on the heap, free this memory. */
381         if (buf != joinbuf) {
382                 jas_free(buf);
383         }
384 #endif
385 }
386
387 /******************************************************************************\
388 * Code for 5/3 transform.
389 \******************************************************************************/
390
391 static int jpc_ft_getnumchans(jpc_qmfb1d_t *qmfb)
392 {
393         /* Avoid compiler warnings about unused parameters. */
394         qmfb = 0;
395
396         return 2;
397 }
398
399 static int jpc_ft_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
400 {
401         /* Avoid compiler warnings about unused parameters. */
402         qmfb = 0;
403         len = 0;
404         filters = 0;
405         abort();
406         return -1;
407 }
408
409 static int jpc_ft_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
410 {
411         jas_seq_t *lf;
412         jas_seq_t *hf;
413
414         /* Avoid compiler warnings about unused parameters. */
415         qmfb = 0;
416
417         lf = 0;
418         hf = 0;
419
420         if (len > 1 || (!len)) {
421                 if (!(lf = jas_seq_create(-1, 2))) {
422                         goto error;
423                 }
424                 jas_seq_set(lf, -1, jpc_dbltofix(0.5));
425                 jas_seq_set(lf, 0, jpc_dbltofix(1.0));
426                 jas_seq_set(lf, 1, jpc_dbltofix(0.5));
427                 if (!(hf = jas_seq_create(-1, 4))) {
428                         goto error;
429                 }
430                 jas_seq_set(hf, -1, jpc_dbltofix(-0.125));
431                 jas_seq_set(hf, 0, jpc_dbltofix(-0.25));
432                 jas_seq_set(hf, 1, jpc_dbltofix(0.75));
433                 jas_seq_set(hf, 2, jpc_dbltofix(-0.25));
434                 jas_seq_set(hf, 3, jpc_dbltofix(-0.125));
435         } else if (len == 1) {
436                 if (!(lf = jas_seq_create(0, 1))) {
437                         goto error;
438                 }
439                 jas_seq_set(lf, 0, jpc_dbltofix(1.0));
440                 if (!(hf = jas_seq_create(0, 1))) {
441                         goto error;
442                 }
443                 jas_seq_set(hf, 0, jpc_dbltofix(2.0));
444         } else {
445                 abort();
446         }
447
448         filters[0] = lf;
449         filters[1] = hf;
450
451         return 0;
452
453 error:
454         if (lf) {
455                 jas_seq_destroy(lf);
456         }
457         if (hf) {
458                 jas_seq_destroy(hf);
459         }
460         return -1;
461 }
462
463 #define NFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
464 { \
465         register jpc_fix_t *lptr = (lstartptr); \
466         register jpc_fix_t *hptr = (hstartptr); \
467         register int n = (hendind) - (hstartind); \
468         if ((hstartind) < (lstartind)) { \
469                 pluseq(*hptr, *lptr); \
470                 hptr += (step); \
471                 --n; \
472         } \
473         if ((hendind) >= (lendind)) { \
474                 --n; \
475         } \
476         while (n-- > 0) { \
477                 pluseq(*hptr, jpc_fix_asr(jpc_fix_add(*lptr, lptr[(step)]), 1)); \
478                 hptr += (step); \
479                 lptr += (step); \
480         } \
481         if ((hendind) >= (lendind)) { \
482                 pluseq(*hptr, *lptr); \
483         } \
484 }
485
486 #define NFT_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
487 { \
488         register jpc_fix_t *lptr = (lstartptr); \
489         register jpc_fix_t *hptr = (hstartptr); \
490         register int n = (lendind) - (lstartind); \
491         if ((hstartind) >= (lstartind)) { \
492                 pluseq(*lptr, *hptr); \
493                 lptr += (step); \
494                 --n; \
495         } \
496         if ((lendind) > (hendind)) { \
497                 --n; \
498         } \
499         while (n-- > 0) { \
500                 pluseq(*lptr, jpc_fix_asr(jpc_fix_add(*hptr, hptr[(step)]), 2)); \
501                 lptr += (step); \
502                 hptr += (step); \
503         } \
504         if ((lendind) > (hendind)) { \
505                 pluseq(*lptr, *hptr); \
506         } \
507 }
508
509 #define RFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pmeqop) \
510 { \
511         register jpc_fix_t *lptr = (lstartptr); \
512         register jpc_fix_t *hptr = (hstartptr); \
513         register int n = (hendind) - (hstartind); \
514         if ((hstartind) < (lstartind)) { \
515                 *hptr pmeqop *lptr; \
516                 hptr += (step); \
517                 --n; \
518         } \
519         if ((hendind) >= (lendind)) { \
520                 --n; \
521         } \
522         while (n-- > 0) { \
523                 *hptr pmeqop (*lptr + lptr[(step)]) >> 1; \
524                 hptr += (step); \
525                 lptr += (step); \
526         } \
527         if ((hendind) >= (lendind)) { \
528                 *hptr pmeqop *lptr; \
529         } \
530 }
531
532 #define RFT_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pmeqop) \
533 { \
534         register jpc_fix_t *lptr = (lstartptr); \
535         register jpc_fix_t *hptr = (hstartptr); \
536         register int n = (lendind) - (lstartind); \
537         if ((hstartind) >= (lstartind)) { \
538                 *lptr pmeqop ((*hptr << 1) + 2) >> 2; \
539                 lptr += (step); \
540                 --n; \
541         } \
542         if ((lendind) > (hendind)) { \
543                 --n; \
544         } \
545         while (n-- > 0) { \
546                 *lptr pmeqop ((*hptr + hptr[(step)]) + 2) >> 2; \
547                 lptr += (step); \
548                 hptr += (step); \
549         } \
550         if ((lendind) > (hendind)) { \
551                 *lptr pmeqop ((*hptr << 1) + 2) >> 2; \
552         } \
553 }
554
555 static void jpc_ft_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
556 {
557         jpc_fix_t *startptr;
558         int startind;
559         int endind;
560         jpc_fix_t *  lstartptr;
561         int   lstartind;
562         int   lendind;
563         jpc_fix_t *  hstartptr;
564         int   hstartind;
565         int   hendind;
566         int interstep;
567         int intrastep;
568         int numseq;
569
570         /* Avoid compiler warnings about unused parameters. */
571         qmfb = 0;
572
573         if (flags & JPC_QMFB1D_VERT) {
574                 interstep = 1;
575                 intrastep = jas_seq2d_rowstep(x);
576                 numseq = jas_seq2d_width(x);
577                 startind = jas_seq2d_ystart(x);
578                 endind = jas_seq2d_yend(x);
579         } else {
580                 interstep = jas_seq2d_rowstep(x);
581                 intrastep = 1;
582                 numseq = jas_seq2d_height(x);
583                 startind = jas_seq2d_xstart(x);
584                 endind = jas_seq2d_xend(x);
585         }
586
587         assert(startind < endind);
588
589         startptr = jas_seq2d_getref(x, jas_seq2d_xstart(x), jas_seq2d_ystart(x));
590         if (flags & JPC_QMFB1D_RITIMODE) {
591                 while (numseq-- > 0) {
592                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
593                           &lstartptr, &lstartind, &lendind, &hstartptr,
594                           &hstartind, &hendind);
595                         if (endind - startind > 1) {
596                                 jpc_qmfb1d_split(startptr, startind, endind,
597                                   intrastep, lstartptr, lstartind, lendind,
598                                   hstartptr, hstartind, hendind);
599                                 RFT_LIFT0(lstartptr, lstartind, lendind,
600                                   hstartptr, hstartind, hendind, intrastep, -=);
601                                 RFT_LIFT1(lstartptr, lstartind, lendind,
602                                   hstartptr, hstartind, hendind, intrastep, +=);
603                         } else {
604                                 if (lstartind == lendind) {
605                                         *startptr <<= 1;
606                                 }
607                         }
608                         startptr += interstep;
609                 }
610         } else {
611                 while (numseq-- > 0) {
612                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
613                           &lstartptr, &lstartind, &lendind, &hstartptr,
614                           &hstartind, &hendind);
615                         if (endind - startind > 1) {
616                                 jpc_qmfb1d_split(startptr, startind, endind,
617                                   intrastep, lstartptr, lstartind, lendind,
618                                   hstartptr, hstartind, hendind);
619                                 NFT_LIFT0(lstartptr, lstartind, lendind,
620                                   hstartptr, hstartind, hendind, intrastep,
621                                   jpc_fix_minuseq);
622                                 NFT_LIFT1(lstartptr, lstartind, lendind,
623                                   hstartptr, hstartind, hendind, intrastep,
624                                   jpc_fix_pluseq);
625                         } else {
626                                 if (lstartind == lendind) {
627                                         *startptr = jpc_fix_asl(*startptr, 1);
628                                 }
629                         }
630                         startptr += interstep;
631                 }
632         }
633 }
634
635 static void jpc_ft_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
636 {
637         jpc_fix_t *startptr;
638         int startind;
639         int endind;
640         jpc_fix_t *lstartptr;
641         int lstartind;
642         int lendind;
643         jpc_fix_t *hstartptr;
644         int hstartind;
645         int hendind;
646         int interstep;
647         int intrastep;
648         int numseq;
649
650         /* Avoid compiler warnings about unused parameters. */
651         qmfb = 0;
652
653         if (flags & JPC_QMFB1D_VERT) {
654                 interstep = 1;
655                 intrastep = jas_seq2d_rowstep(x);
656                 numseq = jas_seq2d_width(x);
657                 startind = jas_seq2d_ystart(x);
658                 endind = jas_seq2d_yend(x);
659         } else {
660                 interstep = jas_seq2d_rowstep(x);
661                 intrastep = 1;
662                 numseq = jas_seq2d_height(x);
663                 startind = jas_seq2d_xstart(x);
664                 endind = jas_seq2d_xend(x);
665         }
666
667         assert(startind < endind);
668
669         startptr = jas_seq2d_getref(x, jas_seq2d_xstart(x), jas_seq2d_ystart(x));
670         if (flags & JPC_QMFB1D_RITIMODE) {
671                 while (numseq-- > 0) {
672                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
673                           &lstartptr, &lstartind, &lendind, &hstartptr,
674                           &hstartind, &hendind);
675                         if (endind - startind > 1) {
676                                 RFT_LIFT1(lstartptr, lstartind, lendind,
677                                   hstartptr, hstartind, hendind, intrastep, -=);
678                                 RFT_LIFT0(lstartptr, lstartind, lendind,
679                                   hstartptr, hstartind, hendind, intrastep, +=);
680                                 jpc_qmfb1d_join(startptr, startind, endind,
681                                   intrastep, lstartptr, lstartind, lendind,
682                                   hstartptr, hstartind, hendind);
683                         } else {
684                                 if (lstartind == lendind) {
685                                         *startptr >>= 1;
686                                 }
687                         }
688                         startptr += interstep;
689                 }
690         } else {
691                 while (numseq-- > 0) {
692                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
693                           &lstartptr, &lstartind, &lendind, &hstartptr,
694                           &hstartind, &hendind);
695                         if (endind - startind > 1) {
696                                 NFT_LIFT1(lstartptr, lstartind, lendind,
697                                   hstartptr, hstartind, hendind, intrastep,
698                                   jpc_fix_minuseq);
699                                 NFT_LIFT0(lstartptr, lstartind, lendind,
700                                   hstartptr, hstartind, hendind, intrastep,
701                                   jpc_fix_pluseq);
702                                 jpc_qmfb1d_join(startptr, startind, endind,
703                                   intrastep, lstartptr, lstartind, lendind,
704                                   hstartptr, hstartind, hendind);
705                         } else {
706                                 if (lstartind == lendind) {
707                                         *startptr = jpc_fix_asr(*startptr, 1);
708                                 }
709                         }
710                         startptr += interstep;
711                 }
712         }
713 }
714
715 /******************************************************************************\
716 * Code for 9/7 transform.
717 \******************************************************************************/
718
719 static int jpc_ns_getnumchans(jpc_qmfb1d_t *qmfb)
720 {
721         /* Avoid compiler warnings about unused parameters. */
722         qmfb = 0;
723
724         return 2;
725 }
726
727 static int jpc_ns_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
728 {
729         /* Avoid compiler warnings about unused parameters. */
730         qmfb = 0;
731         len = 0;
732         filters = 0;
733
734         abort();
735         return -1;
736 }
737
738 static int jpc_ns_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
739 {
740         jas_seq_t *lf;
741         jas_seq_t *hf;
742
743         /* Avoid compiler warnings about unused parameters. */
744         qmfb = 0;
745
746         lf = 0;
747         hf = 0;
748
749         if (len > 1 || (!len)) {
750                 if (!(lf = jas_seq_create(-3, 4))) {
751                         goto error;
752                 }
753                 jas_seq_set(lf, -3, jpc_dbltofix(-0.09127176311424948));
754                 jas_seq_set(lf, -2, jpc_dbltofix(-0.05754352622849957));
755                 jas_seq_set(lf, -1, jpc_dbltofix(0.5912717631142470));
756                 jas_seq_set(lf, 0, jpc_dbltofix(1.115087052456994));
757                 jas_seq_set(lf, 1, jpc_dbltofix(0.5912717631142470));
758                 jas_seq_set(lf, 2, jpc_dbltofix(-0.05754352622849957));
759                 jas_seq_set(lf, 3, jpc_dbltofix(-0.09127176311424948));
760                 if (!(hf = jas_seq_create(-3, 6))) {
761                         goto error;
762                 }
763                 jas_seq_set(hf, -3, jpc_dbltofix(-0.02674875741080976 * 2.0));
764                 jas_seq_set(hf, -2, jpc_dbltofix(-0.01686411844287495 * 2.0));
765                 jas_seq_set(hf, -1, jpc_dbltofix(0.07822326652898785 * 2.0));
766                 jas_seq_set(hf, 0, jpc_dbltofix(0.2668641184428723 * 2.0));
767                 jas_seq_set(hf, 1, jpc_dbltofix(-0.6029490182363579 * 2.0));
768                 jas_seq_set(hf, 2, jpc_dbltofix(0.2668641184428723 * 2.0));
769                 jas_seq_set(hf, 3, jpc_dbltofix(0.07822326652898785 * 2.0));
770                 jas_seq_set(hf, 4, jpc_dbltofix(-0.01686411844287495 * 2.0));
771                 jas_seq_set(hf, 5, jpc_dbltofix(-0.02674875741080976 * 2.0));
772         } else if (len == 1) {
773                 if (!(lf = jas_seq_create(0, 1))) {
774                         goto error;
775                 }
776                 jas_seq_set(lf, 0, jpc_dbltofix(1.0));
777                 if (!(hf = jas_seq_create(0, 1))) {
778                         goto error;
779                 }
780                 jas_seq_set(hf, 0, jpc_dbltofix(2.0));
781         } else {
782                 abort();
783         }
784
785         filters[0] = lf;
786         filters[1] = hf;
787
788         return 0;
789
790 error:
791         if (lf) {
792                 jas_seq_destroy(lf);
793         }
794         if (hf) {
795                 jas_seq_destroy(hf);
796         }
797         return -1;
798 }
799
800 #define NNS_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, alpha) \
801 { \
802         register jpc_fix_t *lptr = (lstartptr); \
803         register jpc_fix_t *hptr = (hstartptr); \
804         register int n = (hendind) - (hstartind); \
805         jpc_fix_t twoalpha = jpc_fix_mulbyint(alpha, 2); \
806         if ((hstartind) < (lstartind)) { \
807                 jpc_fix_pluseq(*hptr, jpc_fix_mul(*lptr, (twoalpha))); \
808                 hptr += (step); \
809                 --n; \
810         } \
811         if ((hendind) >= (lendind)) { \
812                 --n; \
813         } \
814         while (n-- > 0) { \
815                 jpc_fix_pluseq(*hptr, jpc_fix_mul(jpc_fix_add(*lptr, lptr[(step)]), (alpha))); \
816                 hptr += (step); \
817                 lptr += (step); \
818         } \
819         if ((hendind) >= (lendind)) { \
820                 jpc_fix_pluseq(*hptr, jpc_fix_mul(*lptr, (twoalpha))); \
821         } \
822 }
823
824 #define NNS_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, alpha) \
825 { \
826         register jpc_fix_t *lptr = (lstartptr); \
827         register jpc_fix_t *hptr = (hstartptr); \
828         register int n = (lendind) - (lstartind); \
829         int twoalpha = jpc_fix_mulbyint(alpha, 2); \
830         if ((hstartind) >= (lstartind)) { \
831                 jpc_fix_pluseq(*lptr, jpc_fix_mul(*hptr, (twoalpha))); \
832                 lptr += (step); \
833                 --n; \
834         } \
835         if ((lendind) > (hendind)) { \
836                 --n; \
837         } \
838         while (n-- > 0) { \
839                 jpc_fix_pluseq(*lptr, jpc_fix_mul(jpc_fix_add(*hptr, hptr[(step)]), (alpha))); \
840                 lptr += (step); \
841                 hptr += (step); \
842         } \
843         if ((lendind) > (hendind)) { \
844                 jpc_fix_pluseq(*lptr, jpc_fix_mul(*hptr, (twoalpha))); \
845         } \
846 }
847
848 #define NNS_SCALE(startptr, startind, endind, step, alpha) \
849 { \
850         register jpc_fix_t *ptr = (startptr); \
851         register int n = (endind) - (startind); \
852         while (n-- > 0) { \
853                 jpc_fix_muleq(*ptr, alpha); \
854                 ptr += (step); \
855         } \
856 }
857
858 static void jpc_ns_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
859 {
860         jpc_fix_t *startptr;
861         int startind;
862         int endind;
863         jpc_fix_t *lstartptr;
864         int lstartind;
865         int lendind;
866         jpc_fix_t *hstartptr;
867         int hstartind;
868         int hendind;
869         int interstep;
870         int intrastep;
871         int numseq;
872
873         /* Avoid compiler warnings about unused parameters. */
874         qmfb = 0;
875
876         if (flags & JPC_QMFB1D_VERT) {
877                 interstep = 1;
878                 intrastep = jas_seq2d_rowstep(x);
879                 numseq = jas_seq2d_width(x);
880                 startind = jas_seq2d_ystart(x);
881                 endind = jas_seq2d_yend(x);
882         } else {
883                 interstep = jas_seq2d_rowstep(x);
884                 intrastep = 1;
885                 numseq = jas_seq2d_height(x);
886                 startind = jas_seq2d_xstart(x);
887                 endind = jas_seq2d_xend(x);
888         }
889
890         assert(startind < endind);
891
892         startptr = jas_seq2d_getref(x, jas_seq2d_xstart(x), jas_seq2d_ystart(x));
893         if (!(flags & JPC_QMFB1D_RITIMODE)) {
894                 while (numseq-- > 0) {
895                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
896                           &lstartptr, &lstartind, &lendind, &hstartptr,
897                           &hstartind, &hendind);
898                         if (endind - startind > 1) {
899                                 jpc_qmfb1d_split(startptr, startind, endind,
900                                   intrastep, lstartptr, lstartind, lendind,
901                                   hstartptr, hstartind, hendind);
902                                 NNS_LIFT0(lstartptr, lstartind, lendind,
903                                   hstartptr, hstartind, hendind, intrastep,
904                                   jpc_dbltofix(-1.586134342));
905                                 NNS_LIFT1(lstartptr, lstartind, lendind,
906                                   hstartptr, hstartind, hendind, intrastep,
907                                   jpc_dbltofix(-0.052980118));
908                                 NNS_LIFT0(lstartptr, lstartind, lendind,
909                                   hstartptr, hstartind, hendind, intrastep,
910                                   jpc_dbltofix(0.882911075));
911                                 NNS_LIFT1(lstartptr, lstartind, lendind,
912                                   hstartptr, hstartind, hendind, intrastep,
913                                   jpc_dbltofix(0.443506852));
914                                 NNS_SCALE(lstartptr, lstartind, lendind,
915                                   intrastep, jpc_dbltofix(1.0/1.23017410558578));
916                                 NNS_SCALE(hstartptr, hstartind, hendind,
917                                   intrastep, jpc_dbltofix(1.0/1.62578613134411));
918                         } else {
919 #if 0
920                                 if (lstartind == lendind) {
921                                         *startptr = jpc_fix_asl(*startptr, 1);
922                                 }
923 #endif
924                         }
925                         startptr += interstep;
926                 }
927         } else {
928                 /* The reversible integer-to-integer mode is not supported
929                   for this transform. */
930                 abort();
931         }
932 }
933
934 static void jpc_ns_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
935 {
936         jpc_fix_t *startptr;
937         int startind;
938         int endind;
939         jpc_fix_t *lstartptr;
940         int lstartind;
941         int lendind;
942         jpc_fix_t *hstartptr;
943         int hstartind;
944         int hendind;
945         int interstep;
946         int intrastep;
947         int numseq;
948
949         /* Avoid compiler warnings about unused parameters. */
950         qmfb = 0;
951
952         if (flags & JPC_QMFB1D_VERT) {
953                 interstep = 1;
954                 intrastep = jas_seq2d_rowstep(x);
955                 numseq = jas_seq2d_width(x);
956                 startind = jas_seq2d_ystart(x);
957                 endind = jas_seq2d_yend(x);
958         } else {
959                 interstep = jas_seq2d_rowstep(x);
960                 intrastep = 1;
961                 numseq = jas_seq2d_height(x);
962                 startind = jas_seq2d_xstart(x);
963                 endind = jas_seq2d_xend(x);
964         }
965
966         assert(startind < endind);
967
968         startptr = jas_seq2d_getref(x, jas_seq2d_xstart(x), jas_seq2d_ystart(x));
969         if (!(flags & JPC_QMFB1D_RITIMODE)) {
970                 while (numseq-- > 0) {
971                         jpc_qmfb1d_setup(startptr, startind, endind, intrastep,
972                           &lstartptr, &lstartind, &lendind, &hstartptr,
973                           &hstartind, &hendind);
974                         if (endind - startind > 1) {
975                                 NNS_SCALE(lstartptr, lstartind, lendind,
976                                   intrastep, jpc_dbltofix(1.23017410558578));
977                                 NNS_SCALE(hstartptr, hstartind, hendind,
978                                   intrastep, jpc_dbltofix(1.62578613134411));
979                                 NNS_LIFT1(lstartptr, lstartind, lendind,
980                                   hstartptr, hstartind, hendind, intrastep,
981                                   jpc_dbltofix(-0.443506852));
982                                 NNS_LIFT0(lstartptr, lstartind, lendind,
983                                   hstartptr, hstartind, hendind, intrastep,
984                                   jpc_dbltofix(-0.882911075));
985                                 NNS_LIFT1(lstartptr, lstartind, lendind,
986                                   hstartptr, hstartind, hendind, intrastep,
987                                   jpc_dbltofix(0.052980118));
988                                 NNS_LIFT0(lstartptr, lstartind, lendind,
989                                   hstartptr, hstartind, hendind, intrastep,
990                                   jpc_dbltofix(1.586134342));
991                                 jpc_qmfb1d_join(startptr, startind, endind,
992                                   intrastep, lstartptr, lstartind, lendind,
993                                   hstartptr, hstartind, hendind);
994                         } else {
995 #if 0
996                                 if (lstartind == lendind) {
997                                         *startptr = jpc_fix_asr(*startptr, 1);
998                                 }
999 #endif
1000                         }
1001                         startptr += interstep;
1002                 }
1003         } else {
1004                 /* The reversible integer-to-integer mode is not supported
1005                   for this transform. */
1006                 abort();
1007         }
1008 }
1009
1010 /******************************************************************************\
1011 *
1012 \******************************************************************************/
1013
1014 jpc_qmfb1d_t *jpc_qmfb1d_make(int qmfbid)
1015 {
1016         jpc_qmfb1d_t *qmfb;
1017         if (!(qmfb = jpc_qmfb1d_create())) {
1018                 return 0;
1019         }
1020         switch (qmfbid) {
1021         case JPC_QMFB1D_FT:
1022                 qmfb->ops = &jpc_ft_ops;
1023                 break;
1024         case JPC_QMFB1D_NS:
1025                 qmfb->ops = &jpc_ns_ops;
1026                 break;
1027         default:
1028                 jpc_qmfb1d_destroy(qmfb);
1029                 return 0;
1030                 break;
1031         }
1032         return qmfb;
1033 }
1034
1035 static jpc_qmfb1d_t *jpc_qmfb1d_create()
1036 {
1037         jpc_qmfb1d_t *qmfb;
1038         if (!(qmfb = jas_malloc(sizeof(jpc_qmfb1d_t)))) {
1039                 return 0;
1040         }
1041         qmfb->ops = 0;
1042         return qmfb;
1043 }
1044
1045 jpc_qmfb1d_t *jpc_qmfb1d_copy(jpc_qmfb1d_t *qmfb)
1046 {
1047         jpc_qmfb1d_t *newqmfb;
1048
1049         if (!(newqmfb = jpc_qmfb1d_create())) {
1050                 return 0;
1051         }
1052         newqmfb->ops = qmfb->ops;
1053         return newqmfb;
1054 }
1055
1056 void jpc_qmfb1d_destroy(jpc_qmfb1d_t *qmfb)
1057 {
1058         jas_free(qmfb);
1059 }
1060
1061 /******************************************************************************\
1062 *
1063 \******************************************************************************/
1064
1065 void jpc_qmfb1d_getbands(jpc_qmfb1d_t *qmfb, int flags, uint_fast32_t xstart,
1066   uint_fast32_t ystart, uint_fast32_t xend, uint_fast32_t yend, int maxbands,
1067   int *numbandsptr, jpc_qmfb1dband_t *bands)
1068 {
1069         int start;
1070         int end;
1071
1072         assert(maxbands >= 2);
1073
1074         if (flags & JPC_QMFB1D_VERT) {
1075                 start = ystart;
1076                 end = yend;
1077         } else {
1078                 start = xstart;
1079                 end = xend;
1080         }
1081         assert(jpc_qmfb1d_getnumchans(qmfb) == 2);
1082         assert(start <= end);
1083         bands[0].start = JPC_CEILDIVPOW2(start, 1);
1084         bands[0].end = JPC_CEILDIVPOW2(end, 1);
1085         bands[0].locstart = start;
1086         bands[0].locend = start + bands[0].end - bands[0].start;
1087         bands[1].start = JPC_FLOORDIVPOW2(start, 1);
1088         bands[1].end = JPC_FLOORDIVPOW2(end, 1);
1089         bands[1].locstart = bands[0].locend;
1090         bands[1].locend = bands[1].locstart + bands[1].end - bands[1].start;
1091         assert(bands[1].locend == end);
1092         *numbandsptr = 2;
1093 }
1094
1095 /******************************************************************************\
1096 *
1097 \******************************************************************************/
1098
1099 int jpc_qmfb1d_getnumchans(jpc_qmfb1d_t *qmfb)
1100 {
1101         return (*qmfb->ops->getnumchans)(qmfb);
1102 }
1103
1104 int jpc_qmfb1d_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
1105 {
1106         return (*qmfb->ops->getanalfilters)(qmfb, len, filters);
1107 }
1108
1109 int jpc_qmfb1d_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
1110 {
1111         return (*qmfb->ops->getsynfilters)(qmfb, len, filters);
1112 }
1113
1114 void jpc_qmfb1d_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
1115 {
1116         (*qmfb->ops->analyze)(qmfb, flags, x);
1117 }
1118
1119 void jpc_qmfb1d_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
1120 {
1121         (*qmfb->ops->synthesize)(qmfb, flags, x);
1122 }