2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
4 * Copyright (c) 2001-2003 Michael David Adams.
8 /* __START_OF_JASPER_LICENSE__
10 * JasPer License Version 2.0
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
16 * All rights reserved.
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:
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.
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
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.
61 * __END_OF_JASPER_LICENSE__
65 * Quadrature Mirror-Image Filter Bank (QMFB) Library
67 * $Id: jpc_qmfb.c,v 1.1 2005/05/22 18:33:05 malaterre Exp $
70 /******************************************************************************\
72 \******************************************************************************/
76 #include "jasper/jas_fix.h"
77 #include "jasper/jas_malloc.h"
78 #include "jasper/jas_math.h"
84 /******************************************************************************\
86 \******************************************************************************/
88 static jpc_qmfb1d_t *jpc_qmfb1d_create(void);
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);
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);
102 /******************************************************************************\
104 \******************************************************************************/
106 jpc_qmfb1dops_t jpc_ft_ops = {
108 jpc_ft_getanalfilters,
109 jpc_ft_getsynfilters,
114 jpc_qmfb1dops_t jpc_ns_ops = {
116 jpc_ns_getanalfilters,
117 jpc_ns_getsynfilters,
122 /******************************************************************************\
124 \******************************************************************************/
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)
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];
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)
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];
147 jpc_fix_t splitbuf[bufsize];
149 jpc_fix_t *buf = splitbuf;
154 register jpc_fix_t *ptr;
155 register jpc_fix_t *hptr;
156 register jpc_fix_t *lptr;
161 llen = lendind - lstartind;
162 hlen = hendind - hstartind;
164 #if !defined(HAVE_VLA)
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. */
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. */
181 ptr = &startptr[step];
195 /* Copy the appropriate samples into the highpass subband
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);
206 /* Handle the overwritten samples. */
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. */
234 /* Copy the appropriate samples into the highpass subband
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);
245 /* Handle the overwritten samples. */
254 #if !defined(HAVE_VLA)
255 /* If the split buffer was allocated on the heap, free this memory. */
256 if (buf != splitbuf) {
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)
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];
271 jpc_fix_t joinbuf[bufsize];
273 jpc_fix_t *buf = joinbuf;
278 register jpc_fix_t *ptr;
279 register jpc_fix_t *hptr;
280 register jpc_fix_t *lptr;
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. */
295 llen = lendind - lstartind;
296 hlen = hendind - hstartind;
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
314 n = hlen - ((llen + 1) >> 1);
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];
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];
353 n = llen - (llen >> 1);
359 /* Copy the appropriate samples into the second phase of
360 the output signal (corresponding to odd indexed
362 ptr = &startptr[step];
379 #if !defined(HAVE_VLA)
380 /* If the join buffer was allocated on the heap, free this memory. */
381 if (buf != joinbuf) {
387 /******************************************************************************\
388 * Code for 5/3 transform.
389 \******************************************************************************/
391 static int jpc_ft_getnumchans(jpc_qmfb1d_t *qmfb)
393 /* Avoid compiler warnings about unused parameters. */
399 static int jpc_ft_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
401 /* Avoid compiler warnings about unused parameters. */
409 static int jpc_ft_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
414 /* Avoid compiler warnings about unused parameters. */
420 if (len > 1 || (!len)) {
421 if (!(lf = jas_seq_create(-1, 2))) {
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))) {
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))) {
439 jas_seq_set(lf, 0, jpc_dbltofix(1.0));
440 if (!(hf = jas_seq_create(0, 1))) {
443 jas_seq_set(hf, 0, jpc_dbltofix(2.0));
463 #define NFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
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); \
473 if ((hendind) >= (lendind)) { \
477 pluseq(*hptr, jpc_fix_asr(jpc_fix_add(*lptr, lptr[(step)]), 1)); \
481 if ((hendind) >= (lendind)) { \
482 pluseq(*hptr, *lptr); \
486 #define NFT_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pluseq) \
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); \
496 if ((lendind) > (hendind)) { \
500 pluseq(*lptr, jpc_fix_asr(jpc_fix_add(*hptr, hptr[(step)]), 2)); \
504 if ((lendind) > (hendind)) { \
505 pluseq(*lptr, *hptr); \
509 #define RFT_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pmeqop) \
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; \
519 if ((hendind) >= (lendind)) { \
523 *hptr pmeqop (*lptr + lptr[(step)]) >> 1; \
527 if ((hendind) >= (lendind)) { \
528 *hptr pmeqop *lptr; \
532 #define RFT_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, pmeqop) \
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; \
542 if ((lendind) > (hendind)) { \
546 *lptr pmeqop ((*hptr + hptr[(step)]) + 2) >> 2; \
550 if ((lendind) > (hendind)) { \
551 *lptr pmeqop ((*hptr << 1) + 2) >> 2; \
555 static void jpc_ft_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
560 jpc_fix_t * lstartptr;
563 jpc_fix_t * hstartptr;
570 /* Avoid compiler warnings about unused parameters. */
573 if (flags & JPC_QMFB1D_VERT) {
575 intrastep = jas_seq2d_rowstep(x);
576 numseq = jas_seq2d_width(x);
577 startind = jas_seq2d_ystart(x);
578 endind = jas_seq2d_yend(x);
580 interstep = jas_seq2d_rowstep(x);
582 numseq = jas_seq2d_height(x);
583 startind = jas_seq2d_xstart(x);
584 endind = jas_seq2d_xend(x);
587 assert(startind < endind);
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, +=);
604 if (lstartind == lendind) {
608 startptr += interstep;
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,
622 NFT_LIFT1(lstartptr, lstartind, lendind,
623 hstartptr, hstartind, hendind, intrastep,
626 if (lstartind == lendind) {
627 *startptr = jpc_fix_asl(*startptr, 1);
630 startptr += interstep;
635 static void jpc_ft_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
640 jpc_fix_t *lstartptr;
643 jpc_fix_t *hstartptr;
650 /* Avoid compiler warnings about unused parameters. */
653 if (flags & JPC_QMFB1D_VERT) {
655 intrastep = jas_seq2d_rowstep(x);
656 numseq = jas_seq2d_width(x);
657 startind = jas_seq2d_ystart(x);
658 endind = jas_seq2d_yend(x);
660 interstep = jas_seq2d_rowstep(x);
662 numseq = jas_seq2d_height(x);
663 startind = jas_seq2d_xstart(x);
664 endind = jas_seq2d_xend(x);
667 assert(startind < endind);
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);
684 if (lstartind == lendind) {
688 startptr += interstep;
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,
699 NFT_LIFT0(lstartptr, lstartind, lendind,
700 hstartptr, hstartind, hendind, intrastep,
702 jpc_qmfb1d_join(startptr, startind, endind,
703 intrastep, lstartptr, lstartind, lendind,
704 hstartptr, hstartind, hendind);
706 if (lstartind == lendind) {
707 *startptr = jpc_fix_asr(*startptr, 1);
710 startptr += interstep;
715 /******************************************************************************\
716 * Code for 9/7 transform.
717 \******************************************************************************/
719 static int jpc_ns_getnumchans(jpc_qmfb1d_t *qmfb)
721 /* Avoid compiler warnings about unused parameters. */
727 static int jpc_ns_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
729 /* Avoid compiler warnings about unused parameters. */
738 static int jpc_ns_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
743 /* Avoid compiler warnings about unused parameters. */
749 if (len > 1 || (!len)) {
750 if (!(lf = jas_seq_create(-3, 4))) {
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))) {
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))) {
776 jas_seq_set(lf, 0, jpc_dbltofix(1.0));
777 if (!(hf = jas_seq_create(0, 1))) {
780 jas_seq_set(hf, 0, jpc_dbltofix(2.0));
800 #define NNS_LIFT0(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, alpha) \
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))); \
811 if ((hendind) >= (lendind)) { \
815 jpc_fix_pluseq(*hptr, jpc_fix_mul(jpc_fix_add(*lptr, lptr[(step)]), (alpha))); \
819 if ((hendind) >= (lendind)) { \
820 jpc_fix_pluseq(*hptr, jpc_fix_mul(*lptr, (twoalpha))); \
824 #define NNS_LIFT1(lstartptr, lstartind, lendind, hstartptr, hstartind, hendind, step, alpha) \
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))); \
835 if ((lendind) > (hendind)) { \
839 jpc_fix_pluseq(*lptr, jpc_fix_mul(jpc_fix_add(*hptr, hptr[(step)]), (alpha))); \
843 if ((lendind) > (hendind)) { \
844 jpc_fix_pluseq(*lptr, jpc_fix_mul(*hptr, (twoalpha))); \
848 #define NNS_SCALE(startptr, startind, endind, step, alpha) \
850 register jpc_fix_t *ptr = (startptr); \
851 register int n = (endind) - (startind); \
853 jpc_fix_muleq(*ptr, alpha); \
858 static void jpc_ns_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
863 jpc_fix_t *lstartptr;
866 jpc_fix_t *hstartptr;
873 /* Avoid compiler warnings about unused parameters. */
876 if (flags & JPC_QMFB1D_VERT) {
878 intrastep = jas_seq2d_rowstep(x);
879 numseq = jas_seq2d_width(x);
880 startind = jas_seq2d_ystart(x);
881 endind = jas_seq2d_yend(x);
883 interstep = jas_seq2d_rowstep(x);
885 numseq = jas_seq2d_height(x);
886 startind = jas_seq2d_xstart(x);
887 endind = jas_seq2d_xend(x);
890 assert(startind < endind);
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));
920 if (lstartind == lendind) {
921 *startptr = jpc_fix_asl(*startptr, 1);
925 startptr += interstep;
928 /* The reversible integer-to-integer mode is not supported
929 for this transform. */
934 static void jpc_ns_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
939 jpc_fix_t *lstartptr;
942 jpc_fix_t *hstartptr;
949 /* Avoid compiler warnings about unused parameters. */
952 if (flags & JPC_QMFB1D_VERT) {
954 intrastep = jas_seq2d_rowstep(x);
955 numseq = jas_seq2d_width(x);
956 startind = jas_seq2d_ystart(x);
957 endind = jas_seq2d_yend(x);
959 interstep = jas_seq2d_rowstep(x);
961 numseq = jas_seq2d_height(x);
962 startind = jas_seq2d_xstart(x);
963 endind = jas_seq2d_xend(x);
966 assert(startind < endind);
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);
996 if (lstartind == lendind) {
997 *startptr = jpc_fix_asr(*startptr, 1);
1001 startptr += interstep;
1004 /* The reversible integer-to-integer mode is not supported
1005 for this transform. */
1010 /******************************************************************************\
1012 \******************************************************************************/
1014 jpc_qmfb1d_t *jpc_qmfb1d_make(int qmfbid)
1017 if (!(qmfb = jpc_qmfb1d_create())) {
1022 qmfb->ops = &jpc_ft_ops;
1025 qmfb->ops = &jpc_ns_ops;
1028 jpc_qmfb1d_destroy(qmfb);
1035 static jpc_qmfb1d_t *jpc_qmfb1d_create()
1038 if (!(qmfb = jas_malloc(sizeof(jpc_qmfb1d_t)))) {
1045 jpc_qmfb1d_t *jpc_qmfb1d_copy(jpc_qmfb1d_t *qmfb)
1047 jpc_qmfb1d_t *newqmfb;
1049 if (!(newqmfb = jpc_qmfb1d_create())) {
1052 newqmfb->ops = qmfb->ops;
1056 void jpc_qmfb1d_destroy(jpc_qmfb1d_t *qmfb)
1061 /******************************************************************************\
1063 \******************************************************************************/
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)
1072 assert(maxbands >= 2);
1074 if (flags & JPC_QMFB1D_VERT) {
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);
1095 /******************************************************************************\
1097 \******************************************************************************/
1099 int jpc_qmfb1d_getnumchans(jpc_qmfb1d_t *qmfb)
1101 return (*qmfb->ops->getnumchans)(qmfb);
1104 int jpc_qmfb1d_getanalfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
1106 return (*qmfb->ops->getanalfilters)(qmfb, len, filters);
1109 int jpc_qmfb1d_getsynfilters(jpc_qmfb1d_t *qmfb, int len, jas_seq2d_t **filters)
1111 return (*qmfb->ops->getsynfilters)(qmfb, len, filters);
1114 void jpc_qmfb1d_analyze(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
1116 (*qmfb->ops->analyze)(qmfb, flags, x);
1119 void jpc_qmfb1d_synthesize(jpc_qmfb1d_t *qmfb, int flags, jas_seq2d_t *x)
1121 (*qmfb->ops->synthesize)(qmfb, flags, x);