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

📄 filter_bank.c

📁 spiht的压缩解压缩c编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "spiht.h"
#include "spihtdecode.h"

int QccWAVFilterBankInitialize(QccWAVFilterBank *filter_bank)
{
  if (filter_bank == NULL)
    return(0);
  
  QccStringMakeNull(filter_bank->filename);

  QccStringCopy(filter_bank->magic_num, QCCWAVFILTERBANK_MAGICNUM);
  QccGetQccPackVersion(&filter_bank->major_version,
                       &filter_bank->minor_version,
                       NULL);
  
  filter_bank->orthogonality = -1;
  QccFilterInitialize(&filter_bank->lowpass_analysis_filter);
  QccFilterInitialize(&filter_bank->highpass_analysis_filter);
  QccFilterInitialize(&filter_bank->lowpass_synthesis_filter);
  QccFilterInitialize(&filter_bank->highpass_synthesis_filter);
  
  return(0);
}

int QccWAVFilterBankAlloc(QccWAVFilterBank *filter_bank)
{
  int return_value;
  
  if (filter_bank == NULL)
    return(0);
  
  if (QccFilterAlloc(&filter_bank->lowpass_analysis_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
      goto QccError;
    }
  if (QccFilterAlloc(&filter_bank->highpass_analysis_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
      goto QccError;
    }
  if (QccFilterAlloc(&filter_bank->lowpass_synthesis_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
      goto QccError;
    }
  if (QccFilterAlloc(&filter_bank->highpass_synthesis_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankAlloc): Error calling QccFilterAlloc()");
      goto QccError;
    }
  
  return_value = 0;
  goto QccReturn;
 QccError:
  return_value = 1;
 QccReturn:
  return(return_value);
}

void QccWAVFilterBankFree(QccWAVFilterBank *filter_bank)
{
  if (filter_bank == NULL)
    return;
  
  QccFilterFree(&filter_bank->lowpass_analysis_filter);
  QccFilterFree(&filter_bank->highpass_analysis_filter);
  QccFilterFree(&filter_bank->lowpass_synthesis_filter);
  QccFilterFree(&filter_bank->highpass_synthesis_filter);
  
}

int QccWAVFilterBankMakeOrthogonal(QccWAVFilterBank *filter_bank,
                                   const QccFilter *primary_filter)
{
  if (filter_bank == NULL)
    return(0);
  if (primary_filter == NULL)
    return(0);
  
  if (primary_filter->causality != QCCFILTER_CAUSAL)
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error primary filter must be causal");
      return(1);
    }
  
  filter_bank->lowpass_analysis_filter.length =
    filter_bank->highpass_analysis_filter.length =
    filter_bank->lowpass_synthesis_filter.length =
    filter_bank->highpass_synthesis_filter.length =
    primary_filter->length;
  
  if (QccWAVFilterBankAlloc(filter_bank))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccWAVFilterBankAlloc()");
      return(1);
    }
  
  /*   h[n]  */
  if (QccFilterCopy(&(filter_bank->lowpass_synthesis_filter),
                    primary_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterCopy()");
      return(1);
    }
  
  /*  h[-n]  */
  if (QccFilterReversal(&(filter_bank->lowpass_synthesis_filter),
                        &(filter_bank->lowpass_analysis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()");
      return(1);
    }
  
  /*  g[n] = (-(-1)^n) * h[N - 1 - n]  */
  if (QccFilterReversal(&(filter_bank->lowpass_synthesis_filter),
                        &(filter_bank->highpass_synthesis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()");
      return(1);
    }
  if (QccFilterAlternateSignFlip(&(filter_bank->highpass_synthesis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterAlternateSignFlip()");
      return(1);
    }
  filter_bank->highpass_synthesis_filter.causality =
    filter_bank->lowpass_synthesis_filter.causality;

  /*  g[-n]  */
  if (QccFilterReversal(&(filter_bank->highpass_synthesis_filter),
                        &(filter_bank->highpass_analysis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeOrthogonal): Error calling QccFilterReversal()");
      return(1);
    }
  
  return(0);
}

int QccWAVFilterBankMakeBiorthogonal(QccWAVFilterBank *filter_bank,
                                     const QccFilter *primary_filter,
                                     const QccFilter *dual_filter)
{
  if (filter_bank == NULL)
    return(0);
  if (primary_filter == NULL)
    return(0);
  if (dual_filter == NULL)
    return(0);
  
  if ((primary_filter->causality != QCCFILTER_SYMMETRIC) ||
      (dual_filter->causality != QCCFILTER_SYMMETRIC))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): primary filter and dual filter must by of symmetric causality");
      return(1);
    }
  
  filter_bank->lowpass_synthesis_filter.length =
    filter_bank->highpass_analysis_filter.length =
    primary_filter->length;
  
  filter_bank->highpass_synthesis_filter.length =
    filter_bank->lowpass_analysis_filter.length =
    dual_filter->length;
  
  if (QccWAVFilterBankAlloc(filter_bank))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccWAVFilterBankAlloc()");
      return(1);
    }
  
  /*   h[n]  */
  if (QccFilterCopy(&(filter_bank->lowpass_synthesis_filter),
                    primary_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()");
      return(1);
    }
  
  /*  ~h[-n]  */
  if (QccFilterCopy(&(filter_bank->lowpass_analysis_filter),
                    dual_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()");
      return(1);
    }
  
  /*  ~g[-n]  */
  if (QccFilterCopy(&(filter_bank->highpass_analysis_filter),
                    primary_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()");
      return(1);
    }
  if (QccFilterAlternateSignFlip(&(filter_bank->highpass_analysis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterAlternateSignFlip()");
      return(1);
    }
  
  /*  g[n]  */
  if (QccFilterCopy(&(filter_bank->highpass_synthesis_filter),
                    dual_filter))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterCopy()");
      return(1);
    }
  if (QccFilterAlternateSignFlip(&(filter_bank->highpass_synthesis_filter)))
    {
      QccErrorAddMessage("(QccWAVFilterBankMakeBiorthogonal): Error calling QccFilterAlternateSignFlip()");
      return(1);
    }
  
  return(0);
}

static int QccWAVFilterBankReadHeader(FILE *infile,
                                      QccWAVFilterBank *filter_bank)
{
  
  if ((infile == NULL) || (filter_bank == NULL))
    return(0);
  
  if (QccFileReadMagicNumber(infile,
                             filter_bank->magic_num, 
                             &filter_bank->major_version,
                             &filter_bank->minor_version))
    {
      QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading magic number in filter bank %s",
                         filter_bank->filename);
      return(1);
    }
  
  if (strcmp(filter_bank->magic_num, QCCWAVFILTERBANK_MAGICNUM))
    {
      QccErrorAddMessage("(QccWAVFilterBankReadHeader): %s is not of filter-bank (%s) type",
                         filter_bank->filename, QCCWAVFILTERBANK_MAGICNUM);
      return(1);
    }
  
  fscanf(infile, "%d", &(filter_bank->orthogonality));
  if (ferror(infile) || feof(infile))
    {
      QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading filter-bank orthogonality in filter bank %s",
                         filter_bank->filename);
      return(1);
    }
  
  if (QccFileSkipWhiteSpace(infile, 0))
    {
      QccErrorAddMessage("(QccWAVFilterBankReadHeader): Error reading filter-bank orthogonality in filter bank %s",
                         filter_bank->filename);
      return(1);
    }
  
  return(0);
}

static int QccWAVFilterBankReadData(FILE *infile,
                                    QccWAVFilterBank *filter_bank)
{
  int return_value;
  QccFilter primary_filter;
  QccFilter dual_filter;
  
  if (infile == NULL)
    return(0);
  if (filter_bank == NULL)
    return(0);
  
  QccFilterInitialize(&primary_filter);
  QccFilterInitialize(&dual_filter);
  
  switch (filter_bank->orthogonality)
    {
    case QCCWAVFILTERBANK_ORTHOGONAL:
      if (QccFilterRead(infile,
                        &primary_filter))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
          goto QccError;
        }
      if (QccWAVFilterBankMakeOrthogonal(filter_bank, &primary_filter))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeOrthogonal()");
          goto QccError;
        }
      break;
    case QCCWAVFILTERBANK_BIORTHOGONAL:
      if (QccFilterRead(infile,
                        &primary_filter))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
          goto QccError;
        }
      if (QccFilterRead(infile,
                        &dual_filter))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
          goto QccError;
        }
      if (QccWAVFilterBankMakeBiorthogonal(filter_bank,
                                           &primary_filter,
                                           &dual_filter))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccWAVFilterBankMakeBiorthogonal()");
          goto QccError;
        }
      break;
    case QCCWAVFILTERBANK_GENERAL:
      if (QccFilterRead(infile,
                        &(filter_bank->lowpass_analysis_filter)))
        {
          QccErrorAddMessage("(QccWAVFilterBankReadData): Error calling QccFilterRead()");
          goto QccError;
        }

⌨️ 快捷键说明

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