jpc_tsfb.c - vx32 - Local 9vx git repository for patches.
(HTM) git clone git://r-36.net/vx32
(DIR) Log
(DIR) Files
(DIR) 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 }