⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quantizer.c

📁 LastWave
💻 C
字号:
/*..........................................................................*//*                                                                          *//*      L a s t W a v e    P a c k a g e 'compress2d' 2.1                   *//*                                                                          *//*      Copyright (C) 1998-2002 Geoff Davis, Emmanuel Bacry, Jerome Fraleu. *//*                                                                          *//*      The original program was written in C++ by Geoff Davis.             *//*      Then it has been translated in C and adapted to LastWave by         *//*      J. Fraleu and E. Bacry.                                             *//*                                                                          *//*      If you are interested in the C++ code please go to                  *//*          http://www.cs.dartmouth.edu/~gdavis                             *//*                                                                          *//*      emails : geoffd@microsoft.com                                       *//*               fraleu@cmap.polytechnique.fr                               *//*               lastwave@cmap.polytechnique.fr                             *//*                                                                          *//*..........................................................................*//*                                                                          *//*      This program is a free software, you can redistribute it and/or     *//*      modify it under the terms of the GNU General Public License as      *//*      published by the Free Software Foundation; either version 2 of the  *//*      License, or (at your option) any later version                      *//*                                                                          *//*      This program is distributed in the hope that it will be useful,     *//*      but WITHOUT ANY WARRANTY; without even the implied warranty of      *//*      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       *//*      GNU General Public License for more details.                        *//*                                                                          *//*      You should have received a copy of the GNU General Public License   *//*      along with this program (in a file named COPYRIGHT);                *//*      if not, write to the Free Software Foundation, Inc.,                *//*      59 Temple Place, Suite 330, Boston, MA  02111-1307  USA             *//*                                                                          *//*..........................................................................*/#include "lastwave.h"#include "bitio.h"#include "ihisto.h"#include "arithcode.h"#include "coder.h"#include "quantize.h"#define MaxReal (FLT_MAX-1)static LWFLOAT intToReal (int n, LWFLOAT StepSize){   return ((LWFLOAT)(n) * StepSize); }static int realToInt (LWFLOAT x,  LWFLOAT StepSize) {  return (int)(x / StepSize);	  }/*---------------------------------------------------------------------------*/UNIFORMQUANT NewUniformQuant (MONOLAYERCODER entropy, int paramPrecision,LWFLOAT StepSize,int zeroCenter) {   UNIFORMQUANT u;  int  p=2;    u = (UNIFORMQUANT) Malloc(sizeof(UniformQuant));    u->entropy = entropy;  u->paramPrecision = paramPrecision;  u->stepSize = StepSize;  u->zeroCenter = zeroCenter;    u->data = NULL;  u->nData = 0;  u->max = u->min = u->sum = u->sumSq = u->mean = u->var = 0;  u->initialDist = 0;  u->symbol = NULL;  u->nSymbol = 0;  u->p = p;    return(u);}/*---------------------------------------------------------------------------*/void DeleteUniformQuant (UNIFORMQUANT u){          if (u->nSymbol != 0) Free(u->symbol);  Free(u);}/*---------------------------------------------------------------------------*/void GetStatsUniformQuant (UNIFORMQUANT u){  int i;    u->max = -MaxReal;  u->min = MaxReal;  u->sum = u->sumSq = 0;  for (i = 0; i < u->nData; i++) {    if (u->data[i] < u->min)      u->min = u->data[i];    if (u->data[i] > u->max)      u->max = u->data[i];    u->sum += u->data[i];    u->sumSq += u->data[i]*u->data[i];  }  u->mean = u->sum / (LWFLOAT) u->nData;  u->var = u->sumSq / (LWFLOAT) u->nData - u->mean*u->mean;}/*---------------------------------------------------------------------------*/void SetDataEncodeUniformQuant (UNIFORMQUANT u, LWFLOAT *newData, int newNData){   int i;    u->data = newData;  u->nData = newNData;  GetStatsUniformQuant (u);    if (u->zeroCenter) {    u->max = fabs(u->max) > fabs(u->min) ? fabs(u->max) : fabs(u->min);    u->min = -u->max;  }    u->imax = realToInt (u->max, u->stepSize);   u->qmax = intToReal (u->imax,u->stepSize);    /* Make sure qmax >= max and -qmax <= min*/   if (u->imax!=0)  while (u->qmax < u->max )    u->qmax = intToReal (++(u->imax), u->stepSize);   if (u->zeroCenter) {    u->imin = -u->imax;    u->qmin = -u->qmax;   } else {      u->imin = realToInt (u->min, u->stepSize);   u->qmin = intToReal (u->imin, u->stepSize);        /* Make sure qmin <= min */   if (u->imin!=0)      while (u->qmin > u->min )      u->qmin = intToReal (--(u->imin), u->stepSize);     }    u->imean = realToInt (u->mean, u->stepSize);  u->qmean = intToReal (u->imean, u->stepSize);    u->initialDist = 0;  if (u->zeroCenter)    for (i = 0; i < u->nData; i++)      u->initialDist += pow(fabs(u->data[i]),u->p);  else    for (i = 0; i < u->nData; i++)      u->initialDist += pow(fabs(u->data[i] - u->qmean),u->p);}/*---------------------------------------------------------------------------*/void SetDataDecodeUniformQuant (UNIFORMQUANT u, LWFLOAT *newData, int newNData, int imax, int imin, int imean){  u->data = newData;  u->nData = newNData;  if (imin < imax) {    u->qmax = intToReal (imin, u->stepSize);        if (u->zeroCenter) {      u->qmin = -u->qmax;      imin= -imax;    } else {      u->qmin = intToReal (imin, u->stepSize);    }    u->qmean = intToReal (imean, u->stepSize);  }    }/*---------------------------------------------------------------------------*/void GetRateDistUniformQuant( UNIFORMQUANT u, LWFLOAT minStepSize,LWFLOAT *rate, LWFLOAT *dist) {   LWFLOAT reconstruct;   int  nSteps;   int i;      *rate=0.0;   *dist =0.0;    if (u->stepSize < minStepSize) {      *rate = MaxReal;      *dist = MaxReal;      return;  }    if (u->symbol) Free(u->symbol);    u->nSymbol = u->nData;    u->symbol = IntAlloc(u->nSymbol);     if (u->qmin ==0 && u->qmax==0)        { *rate = 0.0;         for (i = 0; i < u->nData; i++)            { *dist  += pow(u->data[i],u->p);	     u->symbol[i]=0;         }       }     else {      if (u->qmin>=0)  {/*  !(Zerocenter)  */      nSteps = u->imax-u->imin;            if (nSteps==0) SetNSymMonoLayerCoder(u->entropy,1);      else  SetNSymMonoLayerCoder(u->entropy,nSteps);     }     else {        nSteps = u->imax-u->imin -1 ;           if (nSteps<=0) nSteps =0;       if (nSteps==0) SetNSymMonoLayerCoder(u->entropy,1);      else SetNSymMonoLayerCoder(u->entropy,nSteps);      }        *rate = *dist = 0;    for (i = 0; i < u->nData; i++) {     /*  encode */  	if (u->qmin>=0)  {/*  !(Zerocenter)  */               /* data[i] always >0*/         u->symbol[i] = (int)(u->data[i]/ u->stepSize) -u->imin;              }      else {      if (fabs(u->data[i]) < u->stepSize) u->symbol[i] = 0;      else {       if (u->data[i]>0)                   u->symbol[i] = (int)(u->data[i]/ u->stepSize) ;       else 	  u->symbol[i] = (int)(fabs(u->data[i])/ u->stepSize)  +u->imax-1;       }         }	           *rate += CostEntropyCoder((ENTROPYCODER) (u->entropy),u->symbol[i], YES,-1,-1);      	/*  decode */      if (u->qmin>=0)  {/*  !(Zerocenter)  */     /* data[i] always >0*/        reconstruct = (LWFLOAT) (u->symbol[i]+ u->imin +0.5) *u->stepSize ;    }      else {/*  (Zerocenter)  */           if (u->symbol[i] == 0)  reconstruct = 0;        else {       if (u->symbol[i] > (int) ((nSteps-1)/2))          reconstruct = - (LWFLOAT) (u->symbol[i] +1-u->imax+0.5) *u->stepSize ;       else           reconstruct = (LWFLOAT) (u->symbol[i]+0.5) *u->stepSize ;     }    }          *dist += pow(fabs(u->data[i]-reconstruct),u->p);    }  }  }/*---------------------------------------------------------------------------*/void EncodeUniformQuant (UNIFORMQUANT u, ENCODER encoder){     int i=0;  int nSteps;    if (!(u->qmin ==0 && u->qmax ==0)) {        if (u->qmin>=0)  {/*  !(Zerocenter)  */           nSteps = u->imax-u->imin;      if (nSteps == 0)         SetNSymMonoLayerCoder (u->entropy,1);      else         SetNSymMonoLayerCoder (u->entropy,nSteps);                for (i = 0; i < u->nSymbol; i++)  /* data[i] always >0*/         WriteEntropyCoder((ENTROPYCODER) (u->entropy), encoder, u->symbol[i], YES,-1,-1);           }      else {       nSteps = u->imax-u->imin -1 ;          if (nSteps<=0) nSteps =0;             if (nSteps == 0)         SetNSymMonoLayerCoder(u->entropy,1);      else         SetNSymMonoLayerCoder(u->entropy,nSteps);     for (i = 0; i < u->nSymbol; i++)          WriteEntropyCoder((ENTROPYCODER) (u->entropy), encoder, u->symbol[i], YES,-1,-1);          }  }}/*---------------------------------------------------------------------------*/void DequantizeUniformQuant (UNIFORMQUANT u, DECODER decoder){     int i;  int nSteps;        if (u->nSymbol) Free(u->symbol);        u->nSymbol = u->nData;      u->symbol = IntAlloc(u->nSymbol);     if (u->qmin == 0 && u->qmax == 0)       {           for (i = 0; i < u->nData; i++)           u->data[i]=0;       }     else {          if (u->qmin>=0)  {/*  !(Zerocenter)  */      nSteps = u->imax-u->imin;           if (nSteps == 0)         SetNSymMonoLayerCoder(u->entropy,1);      else         SetNSymMonoLayerCoder(u->entropy,nSteps);           for (i = 0; i < u->nData; i++) { /* data[i] always >0*/               u->symbol[i] =  ReadEntropyCoder((ENTROPYCODER) (u->entropy), decoder,  YES,-1,-1);        u->data[i] = (LWFLOAT) (u->symbol[i]+ u->imin +0.5) *u->stepSize ;               }    }      else {/*  (Zerocenter)  */      nSteps = u->imax-u->imin -1 ;           if (nSteps<=0) nSteps =0;          if (nSteps == 0)        SetNSymMonoLayerCoder(u->entropy,1);      else         SetNSymMonoLayerCoder(u->entropy,nSteps);           for (i = 0; i < u->nData; i++) {        u->symbol[i] =  ReadEntropyCoder((ENTROPYCODER) (u->entropy), decoder,  YES,-1,-1);            if (u->symbol[i] == 0)  u->data[i] = 0;        else {       if (u->symbol[i] > (int)((nSteps-1)/2))          u->data[i] = - (LWFLOAT) ((u->symbol[i]-u->imax+0.5) *u->stepSize) ;       else           u->data[i] = (LWFLOAT) (u->symbol[i]+0.5) *u->stepSize ;     }        }     }  }}/*---------------------------------------------------------------------------*/void WriteHeaderUniformQuant (UNIFORMQUANT u, ENCODER encoder){    WriteIntEncoder (encoder,u->imax);    if (!u->zeroCenter)      WriteIntEncoder (encoder,u->imin);  }/*---------------------------------------------------------------------------*/void ReadHeaderUniformQuant(UNIFORMQUANT u, DECODER decoder){    u->imax = ReadIntDecoder (decoder);    u->qmax = intToReal (u->imax, u->stepSize);    if (u->zeroCenter) {      u->qmin = -u->qmax;      u->imin= -u->imax;    } else {      u->imin = ReadIntDecoder (decoder);      u->qmin = intToReal (u->imin, u->stepSize);    }    u->qmean = 0;}/*---------------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -