vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

jpc_tsfb.c (17635B)


      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  * Tree-Structured Filter Bank (TSFB) Library
     66  *
     67  * $Id: jpc_tsfb.c 1918 2005-07-24 14:12:08Z baford $
     68  */
     69 
     70 /******************************************************************************\
     71 * Includes.
     72 \******************************************************************************/
     73 
     74 #include <assert.h>
     75 
     76 #include "jasper/jas_malloc.h"
     77 #include "jasper/jas_seq.h"
     78 
     79 #include "jpc_tsfb.h"
     80 #include "jpc_cod.h"
     81 #include "jpc_cs.h"
     82 #include "jpc_util.h"
     83 
     84 /******************************************************************************\
     85 *
     86 \******************************************************************************/
     87 
     88 #define	bandnotovind(tsfbnode, x)	((x) / (tsfbnode)->numhchans)
     89 #define	bandnotohind(tsfbnode, x)	((x) % (tsfbnode)->numhchans)
     90 
     91 static jpc_tsfb_t *jpc_tsfb_create(void);
     92 static jpc_tsfbnode_t *jpc_tsfbnode_create(void);
     93 static void jpc_tsfbnode_destroy(jpc_tsfbnode_t *node);
     94 static void jpc_tsfbnode_synthesize(jpc_tsfbnode_t *node, int flags, jas_seq2d_t *x);
     95 static void jpc_tsfbnode_analyze(jpc_tsfbnode_t *node, int flags, jas_seq2d_t *x);
     96 static void qmfb2d_getbands(jpc_qmfb1d_t *hqmfb, jpc_qmfb1d_t *vqmfb,
     97   uint_fast32_t xstart, uint_fast32_t ystart, uint_fast32_t xend,
     98   uint_fast32_t yend, int maxbands, int *numbandsptr, jpc_tsfbnodeband_t *bands);
     99 static void jpc_tsfbnode_getbandstree(jpc_tsfbnode_t *node, uint_fast32_t posxstart,
    100   uint_fast32_t posystart, uint_fast32_t xstart, uint_fast32_t ystart,
    101   uint_fast32_t xend, uint_fast32_t yend, jpc_tsfb_band_t **bands);
    102 static int jpc_tsfbnode_findchild(jpc_tsfbnode_t *parnode, jpc_tsfbnode_t *cldnode);
    103 static int jpc_tsfbnode_getequivfilters(jpc_tsfbnode_t *tsfbnode, int cldind,
    104   int width, int height, jas_seq_t **vfilter, jas_seq_t **hfilter);
    105 
    106 /******************************************************************************\
    107 *
    108 \******************************************************************************/
    109 
    110 jpc_tsfb_t *jpc_tsfb_wavelet(jpc_qmfb1d_t *hqmfb, jpc_qmfb1d_t *vqmfb, int numdlvls)
    111 {
    112 	jpc_tsfb_t *tsfb;
    113 	int dlvlno;
    114 	jpc_tsfbnode_t *curnode;
    115 	jpc_tsfbnode_t *prevnode;
    116 	int childno;
    117 	if (!(tsfb = jpc_tsfb_create())) {
    118 		return 0;
    119 	}
    120 	prevnode = 0;
    121 	for (dlvlno = 0; dlvlno < numdlvls; ++dlvlno) {
    122 		if (!(curnode = jpc_tsfbnode_create())) {
    123 			jpc_tsfb_destroy(tsfb);
    124 			return 0;
    125 		}
    126 		if (prevnode) {
    127 			prevnode->children[0] = curnode;
    128 			++prevnode->numchildren;
    129 			curnode->parent = prevnode;
    130 		} else {
    131 			tsfb->root = curnode;
    132 			curnode->parent = 0;
    133 		}
    134 		if (hqmfb) {
    135 			curnode->numhchans = jpc_qmfb1d_getnumchans(hqmfb);
    136 			if (!(curnode->hqmfb = jpc_qmfb1d_copy(hqmfb))) {
    137 				jpc_tsfb_destroy(tsfb);
    138 				return 0;
    139 			}
    140 		} else {
    141 			curnode->hqmfb = 0;
    142 			curnode->numhchans = 1;
    143 		}
    144 		if (vqmfb) {
    145 			curnode->numvchans = jpc_qmfb1d_getnumchans(vqmfb);
    146 			if (!(curnode->vqmfb = jpc_qmfb1d_copy(vqmfb))) {
    147 				jpc_tsfb_destroy(tsfb);
    148 				return 0;
    149 			}
    150 		} else {
    151 			curnode->vqmfb = 0;
    152 			curnode->numvchans = 1;
    153 		}
    154 		curnode->maxchildren = curnode->numhchans * curnode->numvchans;
    155 		for (childno = 0; childno < curnode->maxchildren;
    156 		  ++childno) {
    157 			curnode->children[childno] = 0;
    158 		}
    159 		prevnode = curnode;
    160 	}
    161 	return tsfb;
    162 }
    163 
    164 static jpc_tsfb_t *jpc_tsfb_create()
    165 {
    166 	jpc_tsfb_t *tsfb;
    167 	if (!(tsfb = jas_malloc(sizeof(jpc_tsfb_t)))) {
    168 		return 0;
    169 	}
    170 	tsfb->root = 0;
    171 	return tsfb;
    172 }
    173 
    174 void jpc_tsfb_destroy(jpc_tsfb_t *tsfb)
    175 {
    176 	if (tsfb->root) {
    177 		jpc_tsfbnode_destroy(tsfb->root);
    178 	}
    179 	jas_free(tsfb);
    180 }
    181 
    182 /******************************************************************************\
    183 *
    184 \******************************************************************************/
    185 
    186 void jpc_tsfb_analyze(jpc_tsfb_t *tsfb, int flags, jas_seq2d_t *x)
    187 {
    188 	if (tsfb->root) {
    189 		jpc_tsfbnode_analyze(tsfb->root, flags, x);
    190 	}
    191 }
    192 
    193 static void jpc_tsfbnode_analyze(jpc_tsfbnode_t *node, int flags, jas_seq2d_t *x)
    194 {
    195 	jpc_tsfbnodeband_t nodebands[JPC_TSFB_MAXBANDSPERNODE];
    196 	int numbands;
    197 	jas_seq2d_t *y;
    198 	int bandno;
    199 	jpc_tsfbnodeband_t *band;
    200 
    201 	if (node->vqmfb) {
    202 		jpc_qmfb1d_analyze(node->vqmfb, flags | JPC_QMFB1D_VERT, x);
    203 	}
    204 	if (node->hqmfb) {
    205 		jpc_qmfb1d_analyze(node->hqmfb, flags, x);
    206 	}
    207 	if (node->numchildren > 0) {
    208 		qmfb2d_getbands(node->hqmfb, node->vqmfb, jas_seq2d_xstart(x),
    209 		  jas_seq2d_ystart(x), jas_seq2d_xend(x), jas_seq2d_yend(x),
    210 		  JPC_TSFB_MAXBANDSPERNODE, &numbands, nodebands);
    211 		y = jas_seq2d_create(0, 0, 0, 0);
    212 		assert(y);
    213 		for (bandno = 0, band = nodebands; bandno < numbands; ++bandno, ++band) {
    214 			if (node->children[bandno]) {
    215 				if (band->xstart != band->xend && band->ystart != band->yend) {
    216 					jas_seq2d_bindsub(y, x, band->locxstart, band->locystart,
    217 					  band->locxend, band->locyend);
    218 					jas_seq2d_setshift(y, band->xstart, band->ystart);
    219 					jpc_tsfbnode_analyze(node->children[bandno], flags, y);
    220 				}
    221 			}
    222 		}
    223 		jas_matrix_destroy(y);
    224 	}
    225 }
    226 
    227 void jpc_tsfb_synthesize(jpc_tsfb_t *tsfb, int flags, jas_seq2d_t *x)
    228 {
    229 	if (tsfb->root) {
    230 		jpc_tsfbnode_synthesize(tsfb->root, flags, x);
    231 	}
    232 }
    233 
    234 static void jpc_tsfbnode_synthesize(jpc_tsfbnode_t *node, int flags, jas_seq2d_t *x)
    235 {
    236 	jpc_tsfbnodeband_t nodebands[JPC_TSFB_MAXBANDSPERNODE];
    237 	int numbands;
    238 	jas_seq2d_t *y;
    239 	int bandno;
    240 	jpc_tsfbnodeband_t *band;
    241 
    242 	if (node->numchildren > 0) {
    243 		qmfb2d_getbands(node->hqmfb, node->vqmfb, jas_seq2d_xstart(x),
    244 		  jas_seq2d_ystart(x), jas_seq2d_xend(x), jas_seq2d_yend(x),
    245 		  JPC_TSFB_MAXBANDSPERNODE, &numbands, nodebands);
    246 		y = jas_seq2d_create(0, 0, 0, 0);
    247 		for (bandno = 0, band = nodebands; bandno < numbands; ++bandno, ++band) {
    248 			if (node->children[bandno]) {
    249 				if (band->xstart != band->xend && band->ystart != band->yend) {
    250 					jas_seq2d_bindsub(y, x, band->locxstart, band->locystart,
    251 					  band->locxend, band->locyend);
    252 					jas_seq2d_setshift(y, band->xstart, band->ystart);
    253 					jpc_tsfbnode_synthesize(node->children[bandno], flags, y);
    254 				}
    255 			}
    256 		}
    257 		jas_seq2d_destroy(y);
    258 	}
    259 	if (node->hqmfb) {
    260 		jpc_qmfb1d_synthesize(node->hqmfb, flags, x);
    261 	}
    262 	if (node->vqmfb) {
    263 		jpc_qmfb1d_synthesize(node->vqmfb, flags | JPC_QMFB1D_VERT, x);
    264 	}
    265 }
    266 
    267 /******************************************************************************\
    268 *
    269 \******************************************************************************/
    270 
    271 
    272 int jpc_tsfb_getbands(jpc_tsfb_t *tsfb, uint_fast32_t xstart, uint_fast32_t ystart,
    273   uint_fast32_t xend, uint_fast32_t yend, jpc_tsfb_band_t *bands)
    274 {
    275 	jpc_tsfb_band_t *savbands;
    276 	savbands = bands;
    277 	if (!tsfb->root) {
    278 		bands[0].xstart = xstart;
    279 		bands[0].ystart = ystart;
    280 		bands[0].xend = xend;
    281 		bands[0].yend = yend;
    282 		bands[0].locxstart = xstart;
    283 		bands[0].locystart = ystart;
    284 		bands[0].locxend = xend;
    285 		bands[0].locyend = yend;
    286 		bands[0].orient = JPC_TSFB_LL;
    287 		bands[0].synenergywt = JPC_FIX_ONE;
    288 		++bands;
    289 	} else {
    290 		jpc_tsfbnode_getbandstree(tsfb->root, xstart, ystart,
    291 		  xstart, ystart, xend, yend, &bands);
    292 	}
    293 	return bands - savbands;
    294 }
    295 
    296 static void jpc_tsfbnode_getbandstree(jpc_tsfbnode_t *node, uint_fast32_t posxstart,
    297   uint_fast32_t posystart, uint_fast32_t xstart, uint_fast32_t ystart,
    298   uint_fast32_t xend, uint_fast32_t yend, jpc_tsfb_band_t **bands)
    299 {
    300 	jpc_tsfbnodeband_t nodebands[JPC_TSFB_MAXBANDSPERNODE];
    301 	jpc_tsfbnodeband_t *nodeband;
    302 	int nodebandno;
    303 	int numnodebands;
    304 	jpc_tsfb_band_t *band;
    305 	jas_seq_t *hfilter;
    306 	jas_seq_t *vfilter;
    307 
    308 	qmfb2d_getbands(node->hqmfb, node->vqmfb, xstart, ystart, xend, yend,
    309 	  JPC_TSFB_MAXBANDSPERNODE, &numnodebands, nodebands);
    310 	if (node->numchildren > 0) {
    311 		for (nodebandno = 0, nodeband = nodebands;
    312 		  nodebandno < numnodebands; ++nodebandno, ++nodeband) {
    313 			if (node->children[nodebandno]) {
    314 				jpc_tsfbnode_getbandstree(node->children[
    315 				  nodebandno], posxstart +
    316 				  nodeband->locxstart - xstart, posystart +
    317 				  nodeband->locystart - ystart, nodeband->xstart,
    318 				  nodeband->ystart, nodeband->xend,
    319 				  nodeband->yend, bands);
    320 
    321 			}
    322 		}
    323 	}
    324 assert(numnodebands == 4 || numnodebands == 3);
    325 	for (nodebandno = 0, nodeband = nodebands; nodebandno < numnodebands;
    326 	  ++nodebandno, ++nodeband) {
    327 		if (!node->children[nodebandno]) {
    328 			band = *bands;
    329 			band->xstart = nodeband->xstart;
    330 			band->ystart = nodeband->ystart;
    331 			band->xend = nodeband->xend;
    332 			band->yend = nodeband->yend;
    333 			band->locxstart = posxstart + nodeband->locxstart -
    334 			  xstart;
    335 			band->locystart = posystart + nodeband->locystart -
    336 			  ystart;
    337 			band->locxend = band->locxstart + band->xend -
    338 			  band->xstart;
    339 			band->locyend = band->locystart + band->yend -
    340 			  band->ystart;
    341 			if (numnodebands == 4) {
    342 				switch (nodebandno) {
    343 				case 0:
    344 					band->orient = JPC_TSFB_LL;
    345 					break;
    346 				case 1:
    347 					band->orient = JPC_TSFB_HL;
    348 					break;
    349 				case 2:
    350 					band->orient = JPC_TSFB_LH;
    351 					break;
    352 				case 3:
    353 					band->orient = JPC_TSFB_HH;
    354 					break;
    355 				default:
    356 					abort();
    357 					break;
    358 				}
    359 			} else {
    360 				switch (nodebandno) {
    361 				case 0:
    362 					band->orient = JPC_TSFB_HL;
    363 					break;
    364 				case 1:
    365 					band->orient = JPC_TSFB_LH;
    366 					break;
    367 				case 2:
    368 					band->orient = JPC_TSFB_HH;
    369 					break;
    370 				default:
    371 					abort();
    372 					break;
    373 				}
    374 			}
    375 			jpc_tsfbnode_getequivfilters(node, nodebandno, band->xend - band->xstart, band->yend - band->ystart, &hfilter, &vfilter);
    376 			band->synenergywt = jpc_fix_mul(jpc_seq_norm(hfilter),
    377 			  jpc_seq_norm(vfilter));
    378 			jas_seq_destroy(hfilter);
    379 			jas_seq_destroy(vfilter);
    380 			++(*bands);
    381 		}
    382 	}
    383 }
    384 
    385 /******************************************************************************\
    386 *
    387 \******************************************************************************/
    388 
    389 static jpc_tsfbnode_t *jpc_tsfbnode_create()
    390 {
    391 	jpc_tsfbnode_t *node;
    392 	if (!(node = jas_malloc(sizeof(jpc_tsfbnode_t)))) {
    393 		return 0;
    394 	}
    395 	node->numhchans = 0;
    396 	node->numvchans = 0;
    397 	node->numchildren = 0;
    398 	node->maxchildren = 0;
    399 	node->hqmfb = 0;
    400 	node->vqmfb = 0;
    401 	node->parent = 0;
    402 	return node;
    403 }
    404 
    405 static void jpc_tsfbnode_destroy(jpc_tsfbnode_t *node)
    406 {
    407 	jpc_tsfbnode_t **child;
    408 	int childno;
    409 	for (childno = 0, child = node->children; childno < node->maxchildren;
    410 	  ++childno, ++child) {
    411 		if (*child) {
    412 			jpc_tsfbnode_destroy(*child);
    413 		}
    414 	}
    415 	if (node->hqmfb) {
    416 		jpc_qmfb1d_destroy(node->hqmfb);
    417 	}
    418 	if (node->vqmfb) {
    419 		jpc_qmfb1d_destroy(node->vqmfb);
    420 	}
    421 	jas_free(node);
    422 }
    423 
    424 
    425 
    426 
    427 
    428 
    429 
    430 
    431 static void qmfb2d_getbands(jpc_qmfb1d_t *hqmfb, jpc_qmfb1d_t *vqmfb,
    432   uint_fast32_t xstart, uint_fast32_t ystart, uint_fast32_t xend,
    433   uint_fast32_t yend, int maxbands, int *numbandsptr, jpc_tsfbnodeband_t *bands)
    434 {
    435 	jpc_qmfb1dband_t hbands[JPC_QMFB1D_MAXCHANS];
    436 	jpc_qmfb1dband_t vbands[JPC_QMFB1D_MAXCHANS];
    437 	int numhbands;
    438 	int numvbands;
    439 	int numbands;
    440 	int bandno;
    441 	int hbandno;
    442 	int vbandno;
    443 	jpc_tsfbnodeband_t *band;
    444 
    445 	if (hqmfb) {
    446 		jpc_qmfb1d_getbands(hqmfb, 0, xstart, ystart, xend, yend,
    447 		  JPC_QMFB1D_MAXCHANS, &numhbands, hbands);
    448 	} else {
    449 		numhbands = 1;
    450 		hbands[0].start = xstart;
    451 		hbands[0].end = xend;
    452 		hbands[0].locstart = xstart;
    453 		hbands[0].locend = xend;
    454 	}
    455 	if (vqmfb) {
    456 		jpc_qmfb1d_getbands(vqmfb, JPC_QMFB1D_VERT, xstart, ystart, xend,
    457 		  yend, JPC_QMFB1D_MAXCHANS, &numvbands, vbands);
    458 	} else {
    459 		numvbands = 1;
    460 		vbands[0].start = ystart;
    461 		vbands[0].end = yend;
    462 		vbands[0].locstart = ystart;
    463 		vbands[0].locend = yend;
    464 	}
    465 	numbands = numhbands * numvbands;
    466 	assert(numbands <= maxbands);
    467 	*numbandsptr = numbands;
    468 	for (bandno = 0, band = bands; bandno < numbands; ++bandno, ++band) {
    469 		hbandno = bandno % numhbands;
    470 		vbandno = bandno / numhbands;
    471 		band->xstart = hbands[hbandno].start;
    472 		band->ystart = vbands[vbandno].start;
    473 		band->xend = hbands[hbandno].end;
    474 		band->yend = vbands[vbandno].end;
    475 		band->locxstart = hbands[hbandno].locstart;
    476 		band->locystart = vbands[vbandno].locstart;
    477 		band->locxend = hbands[hbandno].locend;
    478 		band->locyend = vbands[vbandno].locend;
    479 		assert(band->xstart <= band->xend &&
    480 		  band->ystart <= band->yend);
    481 		if (band->xstart == band->xend) {
    482 			band->yend = band->ystart;
    483 			band->locyend = band->locystart;
    484 		} else if (band->ystart == band->yend) {
    485 			band->xend = band->xstart;
    486 			band->locxend = band->locxstart;
    487 		}
    488 	}
    489 }
    490 
    491 static int jpc_tsfbnode_getequivfilters(jpc_tsfbnode_t *tsfbnode, int cldind,
    492   int width, int height, jas_seq_t **hfilter, jas_seq_t **vfilter)
    493 {
    494 	jas_seq_t *hseq;
    495 	jas_seq_t *vseq;
    496 	jpc_tsfbnode_t *node;
    497 	jas_seq2d_t *hfilters[JPC_QMFB1D_MAXCHANS];
    498 	jas_seq2d_t *vfilters[JPC_QMFB1D_MAXCHANS];
    499 	int numhchans;
    500 	int numvchans;
    501 	jas_seq_t *tmpseq;
    502 
    503 	hseq = 0;
    504 	vseq = 0;
    505 
    506 	if (!(hseq = jas_seq_create(0, 1))) {
    507 		goto error;
    508 	}
    509 	jas_seq_set(hseq, 0, jpc_inttofix(1));
    510 	if (!(vseq = jas_seq_create(0, 1))) {
    511 		goto error;
    512 	}
    513 	jas_seq_set(vseq, 0, jpc_inttofix(1));
    514 
    515 	node = tsfbnode;
    516 	while (node) {
    517 		if (node->hqmfb) {
    518 			numhchans = jpc_qmfb1d_getnumchans(node->hqmfb);
    519 			if (jpc_qmfb1d_getsynfilters(node->hqmfb, width, hfilters)) {
    520 				goto error;
    521 			}
    522 			if (!(tmpseq = jpc_seq_upsample(hseq, numhchans))) {
    523 				goto error;
    524 			}
    525 			jas_seq_destroy(hseq);
    526 			hseq = tmpseq;
    527 			if (!(tmpseq = jpc_seq_conv(hseq, hfilters[bandnotohind(node, cldind)]))) {
    528 				goto error;
    529 			}
    530 			jas_seq_destroy(hfilters[0]);
    531 			jas_seq_destroy(hfilters[1]);
    532 			jas_seq_destroy(hseq);
    533 			hseq = tmpseq;
    534 		}
    535 		if (node->vqmfb) {
    536 			numvchans = jpc_qmfb1d_getnumchans(node->vqmfb);
    537 			if (jpc_qmfb1d_getsynfilters(node->vqmfb, height, vfilters)) {
    538 				abort();
    539 			}
    540 			if (!(tmpseq = jpc_seq_upsample(vseq, numvchans))) {
    541 				goto error;
    542 			}
    543 			jas_seq_destroy(vseq);
    544 			vseq = tmpseq;
    545 			if (!(tmpseq = jpc_seq_conv(vseq, vfilters[bandnotovind(node, cldind)]))) {
    546 				goto error;
    547 			}
    548 			jas_seq_destroy(vfilters[0]);
    549 			jas_seq_destroy(vfilters[1]);
    550 			jas_seq_destroy(vseq);
    551 			vseq = tmpseq;
    552 		}
    553 		if (node->parent) {
    554 			cldind = jpc_tsfbnode_findchild(node->parent, node);
    555 		}
    556 		node = node->parent;
    557 	}
    558 
    559 	*hfilter = hseq;
    560 	*vfilter = vseq;
    561 
    562 	return 0;
    563 
    564 error:
    565 	if (hseq) {
    566 		jas_seq_destroy(hseq);
    567 	}
    568 	if (vseq) {
    569 		jas_seq_destroy(vseq);
    570 	}
    571 	return -1;
    572 
    573 }
    574 
    575 static int jpc_tsfbnode_findchild(jpc_tsfbnode_t *parnode, jpc_tsfbnode_t *cldnode)
    576 {
    577 	int i;
    578 
    579 	for (i = 0; i < parnode->maxchildren; i++) {
    580 		if (parnode->children[i] == cldnode)
    581 			return i;
    582 	}
    583 	assert(0);
    584 	return -1;
    585 }
    586 
    587 jpc_tsfb_t *jpc_cod_gettsfb(int qmfbid, int numlevels)
    588 {
    589 	jpc_tsfb_t *tsfb;
    590 
    591 	switch (qmfbid) {
    592 	case JPC_COX_RFT:
    593 		qmfbid = JPC_QMFB1D_FT;
    594 		break;
    595 	case JPC_COX_INS:
    596 		qmfbid = JPC_QMFB1D_NS;
    597 		break;
    598 	default:
    599 		assert(0);
    600 		qmfbid = 10;
    601 		break;
    602 	}
    603 
    604 {
    605 	jpc_qmfb1d_t *hqmfb;
    606 	hqmfb = jpc_qmfb1d_make(qmfbid);
    607 	assert(hqmfb);
    608 	tsfb = jpc_tsfb_wavelet(hqmfb, hqmfb, numlevels);
    609 	assert(tsfb);
    610 	jpc_qmfb1d_destroy(hqmfb);
    611 }
    612 
    613 	return tsfb;
    614 }