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

📄 floatcompressornew.cpp

📁 对浮点型数据进行压缩
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
===============================================================================

  FILE:  floatcompressornew.cpp
  
  CONTENTS:

    see corresponding header file

  PROGRAMMERS:
  
    martin isenburg@cs.unc.edu
  
  COPYRIGHT:
  
    Copyright (C) 2000  Martin Isenburg (isenburg@cs.unc.edu)
    
    This software 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.

  CHANGE HISTORY:
  
    see corresponding header file
  
===============================================================================
*/

#include "floatcompressornew.h"

#include <stdlib.h>

#define BITS_HIGH 12

FloatCompressorNew::FloatCompressorNew()
{
  ae_mantissa_none = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);
  ae_mantissa_last = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);
  ae_mantissa_across = (RangeEncoder**)malloc(sizeof(RangeEncoder*)*3);

  ad_mantissa_none = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
  ad_mantissa_last = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
  ad_mantissa_across = (RangeDecoder**)malloc(sizeof(RangeDecoder*)*3);
}

FloatCompressorNew::~FloatCompressorNew()
{
  free(ae_mantissa_none);
  free(ae_mantissa_last);
  free(ae_mantissa_across);

  free(ad_mantissa_none);
  free(ad_mantissa_last);
  free(ad_mantissa_across);
}

void FloatCompressorNew::SetupCompressor(RangeEncoder* re)
{
  last_float = 0;

  if (re == 0)
  {
    // none predictions
    ae_signexponent_none = new RangeEncoder(0);
    ae_mantissa_none[0] = new RangeEncoder(0);
    ae_mantissa_none[1] = new RangeEncoder(0);
    ae_mantissa_none[2] = new RangeEncoder(0);

    // last predictions
    ae_signexponent_last = new RangeEncoder(0);
    ae_mantissa_last[0] = new RangeEncoder(0);
    ae_mantissa_last[1] = new RangeEncoder(0);
    ae_mantissa_last[2] = new RangeEncoder(0);

    // across predictions
    ae_signexponent_across = new RangeEncoder(0);
    ae_mantissa_across[0] = new RangeEncoder(0);
    ae_mantissa_across[1] = new RangeEncoder(0);
    ae_mantissa_across[2] = new RangeEncoder(0);
  }
  else
  {
    // none predictions
    ae_signexponent_none = re;
    ae_mantissa_none[0] = re;
    ae_mantissa_none[1] = re;
    ae_mantissa_none[2] = re;

    // last predictions
    ae_signexponent_last = re;
    ae_mantissa_last[0] = re;
    ae_mantissa_last[1] = re;
    ae_mantissa_last[2] = re;

    // across predictions
    ae_signexponent_across = re;
    ae_mantissa_across[0] = re;
    ae_mantissa_across[1] = re;
    ae_mantissa_across[2] = re;
  }
  alloc_range_tables();
}

void FloatCompressorNew::SetupDecompressor(RangeDecoder* rd)
{
  last_float = 0;

  if (rd == 0)
  {
    // none predictions
    ad_signexponent_none = new RangeDecoder(ae_signexponent_none->getChars(), ae_signexponent_none->getNumberChars());
    ad_mantissa_none[0] = new RangeDecoder(ae_mantissa_none[0]->getChars(), ae_mantissa_none[0]->getNumberChars());
    ad_mantissa_none[1] = new RangeDecoder(ae_mantissa_none[1]->getChars(), ae_mantissa_none[1]->getNumberChars());
    ad_mantissa_none[2] = new RangeDecoder(ae_mantissa_none[2]->getChars(), ae_mantissa_none[2]->getNumberChars());

    // last predictions
    ad_signexponent_last = new RangeDecoder(ae_signexponent_last->getChars(), ae_signexponent_last->getNumberChars());
    ad_mantissa_last[0] = new RangeDecoder(ae_mantissa_last[0]->getChars(), ae_mantissa_last[0]->getNumberChars());
    ad_mantissa_last[1] = new RangeDecoder(ae_mantissa_last[1]->getChars(), ae_mantissa_last[1]->getNumberChars());
    ad_mantissa_last[2] = new RangeDecoder(ae_mantissa_last[2]->getChars(), ae_mantissa_last[2]->getNumberChars());

    // across predictions
    ad_signexponent_across = new RangeDecoder(ae_signexponent_across->getChars(), ae_signexponent_across->getNumberChars());
    ad_mantissa_across[0] = new RangeDecoder(ae_mantissa_across[0]->getChars(), ae_mantissa_across[0]->getNumberChars());
    ad_mantissa_across[1] = new RangeDecoder(ae_mantissa_across[1]->getChars(), ae_mantissa_across[1]->getNumberChars());
    ad_mantissa_across[2] = new RangeDecoder(ae_mantissa_across[2]->getChars(), ae_mantissa_across[2]->getNumberChars());
  }
  else
  {
    // none predictions
    ad_signexponent_none = rd;
    ad_mantissa_none[0] = rd;
    ad_mantissa_none[1] = rd;
    ad_mantissa_none[2] = rd;

    // last predictions
    ad_signexponent_last = rd;
    ad_mantissa_last[0] = rd;
    ad_mantissa_last[1] = rd;
    ad_mantissa_last[2] = rd;

    // across predictions
    ad_signexponent_across = rd;
    ad_mantissa_across[0] = rd;
    ad_mantissa_across[1] = rd;
    ad_mantissa_across[2] = rd;
  }
  alloc_range_tables();
}

void FloatCompressorNew::alloc_range_tables()
{
  int i;

  rmSignExponentNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaBitsNone = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  rmSignExponentLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaBitsLast = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  rmSignExponentAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);
  rmMantissaBitsAcross = (RangeModel**)malloc(sizeof(RangeModel*)*256);

  for (i = 0; i < 256; i++)
  {
    rmSignExponentNone[i] = 0;
    rmSignExponentLast[i] = 0;
    rmSignExponentAcross[i] = 0;
    rmMantissaBitsNone[i] = 0;
    rmMantissaBitsLast[i] = 0;
    rmMantissaBitsAcross[i] = 0;
  }

  rmExponentOther = 0;

  // entries [0] to [BITS_HIGH-1] are for the lower corrector bits
  // while [BITS_HIGH] to [22]  are used for corrector's high bits

  rmMantissa = (RangeModel**)malloc(sizeof(RangeModel*)*23); 

  for (i = 0; i < 23; i++)
  {
    rmMantissa[i] = 0;
  }
}

void FloatCompressorNew::dealloc_range_tables()
{
  int i;

  for (i = 0; i < 256; i++)
  {
    if (rmSignExponentNone[i]) delete rmSignExponentNone[i];
    if (rmSignExponentLast[i]) delete rmSignExponentLast[i];
    if (rmSignExponentAcross[i]) delete rmSignExponentAcross[i];
    if (rmMantissaBitsNone[i]) delete rmMantissaBitsNone[i];
    if (rmMantissaBitsLast[i]) delete rmMantissaBitsLast[i];
    if (rmMantissaBitsAcross[i]) delete rmMantissaBitsAcross[i];
  }

  free(rmSignExponentNone);
  free(rmMantissaBitsNone);

  free(rmSignExponentLast);
  free(rmMantissaBitsLast);

  free(rmSignExponentAcross);
  free(rmMantissaBitsAcross);

  if (rmExponentOther) delete rmExponentOther;

  for (i = 0; i < 23; i++)
  {
    if (rmMantissa[i]) delete rmMantissa[i];
  }

  free(rmMantissa);
}

void FloatCompressorNew::FinishCompressor()
{
  if (ae_signexponent_none != ae_signexponent_last)
  {
    ae_signexponent_none->done();
    ae_signexponent_last->done();
    ae_signexponent_across->done();
    ae_mantissa_none[0]->done();
    ae_mantissa_last[0]->done();
    ae_mantissa_across[0]->done();
    ae_mantissa_none[1]->done();
    ae_mantissa_last[1]->done();
    ae_mantissa_across[1]->done();
    ae_mantissa_none[2]->done();
    ae_mantissa_last[2]->done();
    ae_mantissa_across[2]->done();
  }

  dealloc_range_tables();
}

void FloatCompressorNew::FinishDecompressor()
{
  if (ad_signexponent_none != ad_signexponent_last)
  {
    ad_signexponent_none->done();
    ad_signexponent_last->done();
    ad_signexponent_across->done();

    ad_mantissa_none[0]->done();
    ad_mantissa_last[0]->done();
    ad_mantissa_across[0]->done();

    ad_mantissa_none[1]->done();
    ad_mantissa_last[1]->done();
    ad_mantissa_across[1]->done();

    ad_mantissa_none[2]->done();
    ad_mantissa_last[2]->done();
    ad_mantissa_across[2]->done();
  }

  dealloc_range_tables();
}

int FloatCompressorNew::GetTotalBytes()
{
  return GetSignExponentBytes()+GetMantissaBytes();
}

int FloatCompressorNew::GetSignExponentBytes()
{
  return ae_signexponent_none->getNumberChars()+ae_signexponent_last->getNumberChars()+ae_signexponent_across->getNumberChars();
}

int FloatCompressorNew::GetMantissaBytes()
{
  return GetMantissaBytes(0)+GetMantissaBytes(1)+GetMantissaBytes(2);
}

int FloatCompressorNew::GetMantissaBytes(int i)
{
  return ae_mantissa_none[i]->getNumberChars()+ae_mantissa_last[i]->getNumberChars()+ae_mantissa_across[i]->getNumberChars();
}

#define DIFFERENT_SIGN    0
#define EXPONENT_MINUS_3  1
#define EXPONENT_MINUS_2  2
#define EXPONENT_MINUS_1  3
#define SAME_EXPONENT     4
#define EXPONENT_PLUS_1   5
#define EXPONENT_PLUS_2   6
#define EXPONENT_PLUS_3   7
#define OTHER_EXPONENT    8

void FloatCompressorNew::compress_signexponent(int signexponentPred, int signexponentReal, RangeEncoder* re_signexponent, RangeModel** rmSignExponent)
{
  if (rmSignExponent[signexponentPred&0xFF] == 0)
  {
    rmSignExponent[signexponentPred&0xFF] = new RangeModel(9, 0, 1, 8192, 16);
  }
  if (signexponentPred == signexponentReal)
  {
    re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],SAME_EXPONENT);
  }
  else
  {
    if ((signexponentPred & 0x100) == (signexponentReal & 0x100)) // same sign ?
    {
      int diff = signexponentReal - signexponentPred; // exponent difference
      if ((-3 <= diff) && (diff <= 3))
      {
        re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],SAME_EXPONENT+diff);
      }
      else
      {
        re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],OTHER_EXPONENT);
        if (rmExponentOther == 0)
        {
          rmExponentOther = new RangeModel(255, 0, 1, 8192, 16);
        }
        re_signexponent->encode(rmExponentOther,signexponentReal&0xFF);
      }
    }
    else
    {
      re_signexponent->encode(rmSignExponent[signexponentPred&0xFF],DIFFERENT_SIGN);
      if (rmExponentOther == 0)
      {
        rmExponentOther = new RangeModel(255, 0, 1, 8192, 16);
      }
      re_signexponent->encode(rmExponentOther,signexponentReal&0xFF);
    }
  }
}

int FloatCompressorNew::decompress_signexponent(int signexponentPred, RangeDecoder* rd_signexponent, RangeModel** rmSignExponent)
{
  if (rmSignExponent[signexponentPred&0xFF] == 0)
  {
    rmSignExponent[signexponentPred&0xFF] = new RangeModel(9, 0, 0, 8192, 16);
  }
  int signexponentReal = rd_signexponent->decode(rmSignExponent[signexponentPred&0xFF]);

  if (signexponentReal == SAME_EXPONENT)
  {
    return signexponentPred;
  }
  else
  {
    if ((EXPONENT_MINUS_3 <= signexponentReal) && (signexponentReal <= EXPONENT_PLUS_3))
    {
      return signexponentPred - (SAME_EXPONENT-signexponentReal);
    }
    else
    {
      if (rmExponentOther == 0)
      {
        rmExponentOther = new RangeModel(255, 0, 0, 8192, 16);
      }
      if (signexponentReal == OTHER_EXPONENT) // but same sign
      {
        return (signexponentPred & 0x100) | rd_signexponent->decode(rmExponentOther);
      }
      else  // ... but different sign
      {
        return ((~signexponentPred) & 0x100) | rd_signexponent->decode(rmExponentOther);
      }
    }
  }
}

⌨️ 快捷键说明

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