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 }