www.pudn.com > wavecode.rar > wpacket.c
/********************* the activity measure for deciding whether to transform a level is critical. The ideal measure is of course actually packing it (that's a hassle cuz you've got to correctly assign parents and whatnot). In particular, we need to take the 'quantizer' into account. ************************/ #include#include #include #include #include #include #include #include subband_node *new_subband_node(); subband_node *new_subband_node_foliated(); subband_leaf *new_subband_leaf(); void transLeafToQuadMaybe(subband ** sb_ptr,int levels,int trans) { subband_leaf *sbl; subband *sb; int oldact; sbl = *sb_ptr; if ( sbl->width < 4 ) return; activitySubbands(sbl); oldact = sbl->activity; transQuad(sbl->band,sbl->width,sbl->height,sbl->width+sbl->rowpad,0,trans); activitySubbands(sbl); /** * the details of the "activity" measurement are critical for this decision * mse & rmse seem quite poor * the percentage of nonzeros seems to be best ***/ #if 0 if ( sbl->activity <= oldact ) { // on images where WP helps, this helps more, but on images // where it hurts, this hurts even more #else if ( sbl->activity < oldact ) { #endif // buono sb = makeSubbandQuad(sbl->band,sbl->width,sbl->height,sbl->width+sbl->rowpad,0,sbl->prev); free(sbl); *sb_ptr = sb; if ( levels ) { transLeafToQuadMaybe(&(sb->LL),levels-1,trans); transLeafToQuadMaybe(&(sb->LH),levels-1,trans); transLeafToQuadMaybe(&(sb->HL),levels-1,trans); transLeafToQuadMaybe(&(sb->HH),levels-1,trans); } } else { // undo it transQuad(sbl->band,sbl->width,sbl->height,sbl->width+sbl->rowpad,1,trans); } } subband * transLeafToQuad(subband_leaf *sbl,int levels,bool doWP,int trans) { subband *sb; transQuad(sbl->band,sbl->width,sbl->height,sbl->width+sbl->rowpad,0,trans); sb = makeSubbandQuad(sbl->band,sbl->width,sbl->height,sbl->width+sbl->rowpad,0,sbl->prev); free(sbl); if ( levels ) { sb->LL = transLeafToQuad(sb->LL,levels-1,doWP,trans); if ( doWP && levels > 1 ) { /** makes sure that wavelet packets have proper parents **/ transLeafToQuadMaybe(&(sb->LH),levels-2,trans); transLeafToQuadMaybe(&(sb->HL),levels-2,trans); transLeafToQuadMaybe(&(sb->HH),levels-2,trans); } } return sb; } void detransSubbands(subband *sb,int trans) { if ( !sb || sb->leaf ) return; detransSubbands(sb->LL,trans); detransSubbands(sb->LH,trans); detransSubbands(sb->HL,trans); detransSubbands(sb->HH,trans); if ( sb->width ) { int w,h,fw; w = sb->width; fw = sb->width + sb->rowpad; h = sb->height; while( ! sb->leaf ) sb = sb->LL; transQuad(((subband_leaf *)sb)->band,w,h,fw,1,trans); } } subband * transPlaneSubbands(image *im,int plane,int levels,bool doWP,int trans) { subband_leaf * sbl; sbl = new_subband_leaf(); sbl->band = im->data[plane][0]; sbl->width = im->width; sbl->height= im->height; sbl->rowpad = 0; if ( levels ) return transLeafToQuad(sbl,levels-1,doWP,trans); else return sbl; } subband * transImageSubbands(image *im,int levels,bool doWP,int trans) { if ( im->planes <= 1 ) return transPlaneSubbands(im,0,levels,doWP,trans); else { subband_node * sb; sb = new_subband_node(); if ( im->planes >= 1 ) sb->LL = transPlaneSubbands(im,0,levels,doWP,trans); if ( im->planes >= 2 ) sb->LH = transPlaneSubbands(im,1,levels,doWP,trans); if ( im->planes >= 3 ) sb->HL = transPlaneSubbands(im,2,levels,doWP,trans); if ( im->planes >= 4 ) sb->HH = transPlaneSubbands(im,3,levels,doWP,trans); if ( im->planes >= 5 ) errexit("too many planes for my cheezy ass"); return sb; } } wavelet * makeSubband(image *im,int levels,double q, int stoplen,const coder *coder_template, bool doWP,int transformN) { wavelet * w; if ( (w = newWavelet(im,levels)) == NULL ) return NULL; w->stoplen = stoplen; w->coder_template = coder_template; w->transform = transformN; w->qi = findQuantizers(0,0,q, NULL,levels,0,NULL); w->subband_root = transImageSubbands(im,levels,doWP,transformN); transposeSubbandLHs(w->subband_root); if ( q != 1.0 ) quantizeImage(im,levels,w->qi); activitySubbands(w->subband_root); return w; } void unSubband(wavelet * w) { if ( w->qi && w->qi->nquants > 0 ) dequantizeImage(w->im,w->levels,w->qi); transposeSubbandLHs(w->subband_root); detransSubbands(w->subband_root,w->transform); }