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

📄 gtr.c

📁 QccPack implementation in C
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  * QccPack: Quantization, compression, and coding libraries * Copyright (C) 1997-2005  James E. Fowler *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. *  * This library 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 * Library General Public License for more details. *  * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. *  */#include "libQccPack.h"static void QccAVQgtrCalcProb(QccVQCodebook *codebook, const QccVector cnt){  int codeword;  double sum_cnt = 0;    for (codeword = 0; codeword < codebook->num_codewords; codeword++)    sum_cnt += cnt[codeword];  for (codeword = 0; codeword < codebook->num_codewords; codeword++)    codebook->codeword_probs[codeword] = cnt[codeword]/sum_cnt;}static int QccAVQgtrSendSideInfo(QccAVQSideInfo *sideinfo,                                  QccAVQSideInfoSymbol *updatevector_symbol,                                 int update_flag){  QccAVQSideInfoSymbol flag_symbol;    flag_symbol.type = QCCAVQSIDEINFO_FLAG;  flag_symbol.flag = update_flag;  flag_symbol.vector = NULL;  flag_symbol.vector_indices = NULL;  if (QccAVQSideInfoSymbolWrite(sideinfo, &flag_symbol))    {      QccErrorAddMessage("(QccAVQgtrSendSideInfo): Error calling QccAVQSideInfoSymbolWrite()");      return(1);    }    if (update_flag == QCCAVQSIDEINFO_FLAG_UPDATE)    {      updatevector_symbol->type = QCCAVQSIDEINFO_VECTOR;      if (QccAVQSideInfoSymbolWrite(sideinfo, updatevector_symbol))        {          QccErrorAddMessage("(QccAVQgtrSendSideInfo): Error calling QccAVQSideInfoSymbolWrite()");          return(1);        }    }    return(0);}static void QccAVQgtrCalcUpdateCosts(double *update_distortion,                                     double *update_rate,                                     const                                     QccAVQSideInfoSymbol *new_codeword_symbol,                                     QccVector current_vector,                                     QccAVQSideInfo *sideinfo){  int offset;  int component;  double current_prob;  offset = sideinfo->codebook_coder.num_levels/2;  *update_distortion =     QccVectorSquareDistance(current_vector,                            new_codeword_symbol->vector,                            sideinfo->vector_dimension);  *update_rate = 0;  switch (sideinfo->codebook_coder.type)    {    case QCCSQSCALARQUANTIZER_GENERAL:      for (component = 0; component < sideinfo->vector_dimension; component++)        {          current_prob = sideinfo->codebook_coder.probs               [new_codeword_symbol->vector_indices[component]];          if (current_prob != 0.0)            *update_rate += -QccMathLog2(current_prob);        }      break;    case QCCSQSCALARQUANTIZER_UNIFORM:    case QCCSQSCALARQUANTIZER_DEADZONE:      for (component = 0; component < sideinfo->vector_dimension; component++)        {          current_prob = sideinfo->codebook_coder.probs            [new_codeword_symbol->vector_indices[component] + offset];          if (current_prob != 0.0)            *update_rate += -QccMathLog2(current_prob);        }      break;    }}static void QccAVQgtrUpdateCodebookCoderProbs(QccAVQSideInfo *sideinfo,                                              const QccAVQSideInfoSymbol                                               *new_codeword_symbol,                                              double omega){  int cnt_total = 0;  int component;  int offset;  int codeword;  offset = sideinfo->codebook_coder.num_levels/2;  for (codeword = 0; codeword < sideinfo->codebook_coder.num_levels;        codeword++)    {      sideinfo->codebook_coder.probs[codeword] =        (int)(sideinfo->codebook_coder.probs[codeword] * omega + 0.5);      cnt_total +=        sideinfo->codebook_coder.probs[codeword];    }  switch (sideinfo->codebook_coder.type)    {    case QCCSQSCALARQUANTIZER_GENERAL:      for (component = 0; component < sideinfo->vector_dimension; component++)        sideinfo->codebook_coder.probs          [new_codeword_symbol->vector_indices[component]] += 1;      break;    case QCCSQSCALARQUANTIZER_UNIFORM:    case QCCSQSCALARQUANTIZER_DEADZONE:      for (component = 0; component < sideinfo->vector_dimension; component++)        sideinfo->codebook_coder.probs          [new_codeword_symbol->vector_indices[component] + offset] += 1;      break;    }  cnt_total += sideinfo->vector_dimension;  for (codeword = 0; codeword < sideinfo->codebook_coder.num_levels;        codeword++)    sideinfo->codebook_coder.probs[codeword] /= cnt_total;}int QccAVQgtrEncode(const QccDataset *dataset,                     QccVQCodebook *codebook,                     QccChannel *channel,                    QccAVQSideInfo *sideinfo,                    double lambda,                    double omega,                    QccVQDistortionMeasure distortion_measure){  int return_value;  int block_size;  int vector_dimension;  int current_vector;  double winning_distortion;  double update_distortion;  double update_rate;  int winner;  QccDataset tmp_dataset;  QccVector cnt = NULL;  int codeword;  double newcnt;  double delta_J;  QccAVQSideInfoSymbol *new_codeword_symbol = NULL;  if ((dataset == NULL) || (codebook == NULL) || (channel == NULL) ||      (sideinfo == NULL))    return(0);  if (dataset->vectors == NULL)    return(0);    vector_dimension = dataset->vector_dimension;  if ((vector_dimension != codebook->codeword_dimension) ||      (vector_dimension != sideinfo->vector_dimension))    {      QccErrorAddMessage("(QccAVQgtrEncode): Codebook %s, dataset %s, and sideinfo %s have different vector dimensions",                         codebook->filename, dataset->filename, sideinfo->filename);      goto QccAVQError;    }    if ((new_codeword_symbol =        QccAVQSideInfoSymbolAlloc(vector_dimension)) == NULL)    {      QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccAVQSideInfoSymbolAlloc()");      goto QccAVQError;    }  new_codeword_symbol->type = QCCAVQSIDEINFO_VECTOR;  /*    precision =     (int)(log((double)sideinfo->codebook_coder.num_levels)/log(2.0) + 0.5);  */  block_size = QccDatasetGetBlockSize(dataset);    QccDatasetInitialize(&tmp_dataset);  tmp_dataset.num_vectors = 1;  tmp_dataset.vector_dimension = dataset->vector_dimension;  tmp_dataset.access_block_size = QCCDATASET_ACCESSWHOLEFILE;  tmp_dataset.num_blocks_accessed = 0;  if (QccDatasetAlloc(&tmp_dataset))    {      QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccDatasetAlloc()");      goto QccAVQError;    }    if ((cnt =        QccVectorAlloc(sideinfo->max_codebook_size)) == NULL)    {      QccErrorAddMessage("(QccAVQgtrEncode): Error allocating memory");      goto QccAVQError;    }    for (current_vector = 0; current_vector < block_size; current_vector++)    {      QccVectorCopy(tmp_dataset.vectors[0],                    dataset->vectors[current_vector],                    vector_dimension);            if (QccVQEntropyConstrainedVQ(&tmp_dataset, codebook, lambda,                                     (QccVector)&winning_distortion, &winner,                                    distortion_measure))        {          QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccVQEntropyConstrainedVQ()");          goto QccAVQError;        }      QccVectorCopy(new_codeword_symbol->vector,                    dataset->vectors[current_vector],                    vector_dimension);      QccAVQSideInfoCodebookCoder(sideinfo, new_codeword_symbol);      /*        update_distortion =         QccVectorSquareDistance(dataset->vectors[current_vector],        new_codeword_symbol->vector,        vector_dimension);      */      QccAVQgtrCalcUpdateCosts(&update_distortion,                               &update_rate,                               new_codeword_symbol,                               dataset->vectors[current_vector],                               sideinfo);      for (codeword = 0; codeword < codebook->num_codewords; codeword++)        cnt[codeword] =           (int)(codebook->codeword_probs[codeword] * omega + 0.5);      /*        delta_J = (update_distortion - winning_distortion) +        lambda*vector_dimension*precision;      */      delta_J = (update_distortion - winning_distortion) +        lambda * update_rate;            if (delta_J < 0.0)        {          /*  Update codebook  */          if (codebook->num_codewords < sideinfo->max_codebook_size)            {              if (QccVQCodebookAddCodeword(codebook,                                           (QccVQCodeword)                                           new_codeword_symbol->vector))                {                  QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccVQCodebookAddCodeword()");                  goto QccAVQError;                }              winner = codebook->num_codewords - 1;              newcnt = 1;            }          else            {              QccVectorCopy((QccVector)codebook->codewords                            [codebook->num_codewords - 1],                             new_codeword_symbol->vector,                            vector_dimension);              newcnt = cnt[winner] + 1;            }                    if (QccVQCodebookMoveCodewordToFront(codebook,                                                codebook->num_codewords - 1))            {              QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccVQCodebookMoveCodewordToFront()");              goto QccAVQError;            }                    if (winner != (codebook->num_codewords - 1))            {              cnt[winner] = newcnt/2;              cnt[codebook->num_codewords - 1] = cnt[winner];            }          else            cnt[winner] = newcnt;                    QccAVQgtrCalcProb(codebook, cnt);          QccVectorMoveComponentToFront(codebook->codeword_probs,                                        codebook->num_codewords,                                        codebook->num_codewords - 1);                    channel->channel_symbols[current_vector] = QCCCHANNEL_NULLSYMBOL;                    if (QccAVQgtrSendSideInfo(sideinfo, new_codeword_symbol,                                     QCCAVQSIDEINFO_FLAG_UPDATE))            {              QccErrorAddMessage("(QccAVQgtrEncode): Error calling QccAVQgtrSendSideInfo()");              goto QccAVQError;            }          QccAVQgtrUpdateCodebookCoderProbs(sideinfo,                                            new_codeword_symbol,                                            omega);        }      else        {          /*  No codebook update  */          QccVQCodebookMoveCodewordToFront(codebook, winner);          cnt[winner]++;          QccAVQgtrCalcProb(codebook, cnt);          if (QccVectorMoveComponentToFront(codebook->codeword_probs,

⌨️ 快捷键说明

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