www.pudn.com > xiaobo.zip.zip > quantim.c
#include#include #include #include #include #include "quantim.h" #include "quantutil.h" #include "coder.h" #include "subbands.h" char * qtype_names[] = { "deadzone","ESZZ",NULL }; quantInfo * findQuantizers(int qtype,int qflags,double quant_target, imageFloat *imF,int levels,int stoplen,coder *coder_template) { quantInfo *qi; if ( qflags == QFLAG_UNIFORM ) { if ( quant_target == 1.0 ) { if ( (qi = newQI(0)) == NULL ) return NULL; qi->nquants = 0; qi->qtype = qtype; } else { if ( (qi = newQI(1)) == NULL ) return NULL; qi->nquants = 1; qi->qtype = qtype; qi->quantizers[0] = (float) quant_target; } } else { int i,nq; nq = 3*levels + 1; if ( (qi = newQI(nq)) == NULL ) return NULL; qi->nquants = nq; qi->qtype = qtype; for(i=0;i quantizers[i] = (float) quant_target; if ( qflags & QFLAG_SEEKSTOP ) seekStoppedQuantizers(imF,levels,qi->quantizers,stoplen,coder_template); if ( qflags & QFLAG_FIDDLE ) fiddleQuantizers(imF,levels,qi->quantizers,coder_template); } return qi; } void quantizeImage(image *im,int levels,quantInfo *qi) { switch(qi->qtype) { case QTYPE_ESZZ: if ( qi->nquants == 1 ) quantizeBandsESZZIntU(im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) quantizeBandsESZZInt(im,levels,qi->quantizers); break; case QTYPE_DEADZONE: default: if ( qi->nquants == 1 ) quantizeBandsDZIntU(im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) quantizeBandsDZInt(im,levels,qi->quantizers); break; } } void dequantizeImage(image *im,int levels,quantInfo *qi) { switch(qi->qtype) { case QTYPE_ESZZ: if ( qi->nquants == 1 ) dequantizeBandsESZZIntU(im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) dequantizeBandsESZZInt(im,levels,qi->quantizers); break; case QTYPE_DEADZONE: default: if ( qi->nquants == 1 ) dequantizeBandsDZIntU(im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) dequantizeBandsDZInt(im,levels,qi->quantizers); break; } } void quantizeImageF(image *im,imageFloat *imF,int levels,quantInfo *qi) { switch(qi->qtype) { case QTYPE_ESZZ: if ( qi->nquants == 1 ) quantizeBandsESZZU(imF,im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) quantizeBandsESZZ(imF,im,levels,qi->quantizers); else quantizeBandsESZZU(imF,im,levels,1.0); break; case QTYPE_DEADZONE: default: if ( qi->nquants == 1 ) quantizeBandsDZU(imF,im,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) quantizeBandsDZ(imF,im,levels,qi->quantizers); else quantizeBandsDZU(imF,im,levels,1.0); break; } } void dequantizeImageF(image *im,imageFloat *imF,int levels,quantInfo *qi) { switch(qi->qtype) { case QTYPE_ESZZ: if ( qi->nquants == 1 ) dequantizeBandsESZZU(im,imF,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) dequantizeBandsESZZ(im,imF,levels,qi->quantizers); else dequantizeBandsESZZU(im,imF,levels,1.0); break; case QTYPE_DEADZONE: default: if ( qi->nquants == 1 ) dequantizeBandsDZU(im,imF,levels,qi->quantizers[0]); else if ( qi->nquants == (3*levels + 1) ) dequantizeBandsDZ(im,imF,levels,qi->quantizers); else dequantizeBandsDZU(im,imF,levels,1.0); break; } } void deTransQuantIm(image *im,int levels,int transformN,quantInfo *qi) { if ( ! levels ) return; transposeLHs(im,levels); if ( (transformN&TRANS_INT_TO_INT) && ( qi == NULL || qi->nquants == 0 ) ) { transformImageInt(im,levels,1,transformN); } else if ( (transformN&TRANS_INT_TO_INT) && qi->nquants == 1 && qi->quantizers[0] == (int)qi->quantizers[0] ) { dequantizeImage(im,levels,qi); transformImageInt(im,levels,1,transformN); } else { imageFloat *imF = NULL; if ( (imF = newImageFloatFrom(im)) == NULL ) errexit("newImageFloat failed"); dequantizeImageF(im,imF,levels,qi); if ( transformN == TRANS_DCT ) { deshuffleDctImage(&imF); } transformImage(im,imF,levels,1,transformN); freeImageFloat(imF); } } quantInfo * doTransQuantIm(image *im,int levels,int transformN, int qtype,int qflags,double q, int stoplen,const coder *coder_template) { quantInfo *qi; if ( levels == 0 ) return NULL; if ( (transformN&TRANS_INT_TO_INT) && qflags == QFLAG_UNIFORM && (int)q == q ) { qi = findQuantizers(qtype,qflags,q, NULL,levels,0,NULL); transformImageInt(im,levels,0,transformN); if ( q != 1 ) quantizeImage(im,levels,qi); } else { imageFloat *imF; if ( (imF = newImageFloatFrom(im)) == NULL ) errexit("newImage failed"); transformImage(im,imF,levels,0,transformN); if ( transformN == TRANS_DCT ) { shuffleDctImage(&imF); } qi = findQuantizers(qtype,qflags,q, imF,levels,stoplen,(coder *)coder_template); quantizeImageF(im,imF,levels,qi); freeImageFloat(imF); } transposeLHs(im,levels); return qi; } wavelet * makeTransQuantWavelet(image *im,int levels,int transformN, int qtype,int qflags,double q, int stoplen,const coder *coder_template) { wavelet * w; if ( (w = newWavelet(im,levels)) == NULL ) return NULL; w->stoplen = stoplen; w->coder_template = coder_template; w->transform = transformN; w->qi = doTransQuantIm(im,levels,transformN, qtype,qflags,q, stoplen,coder_template); w->subband_root = imageToSubbands(im,levels); activitySubbands(w->subband_root); return w; } void deTransQuantWavelet(wavelet * w) { deTransQuantIm(w->im,w->levels,w->transform,w->qi); }