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 }