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

📄 spihtencode3d.c

📁 该文件是小波信源编码SPIHT算法的C语言代码
💻 C
字号:
/* * * QccPack: Quantization, compression, and coding utilities * Copyright (C) 1997-2001  James E. Fowler *  *//* * ---------------------------------------------------------------------------- *  * Public License for the 3D-SPIHT Algorithm * Version 1.1, March 8, 2004 *  * ---------------------------------------------------------------------------- *  * The 3D Set Partitioning In Hierarchical Trees (3D-SPIHT) algorithm is * protected by US patents 5,764,807 and 6,674,911, and other patents pending. * An implementation of the 3D-SPIHT algorithm is included herein with the * gracious permission of Dr. William A. Pearlman, President of PrimaComp, * Inc., exclusive holder of patent rights. PrimaComp, Inc., has granted the * following license governing the terms and conditions for use, copying, * distribution, and modification of the 3D-SPIHT algorithm implementation * contained herein (hereafter referred to as "the 3D-SPIHT source code"). *  * 0. Use of the 3D-SPIHT source code, including any executable-program or *    linkable-library form resulting from its compilation, is restricted to *    solely academic or non-commercial research activities. *  * 1. Any other use, including, but not limited to, use in the development *    of a commercial product, use in a commercial application, or commercial *    distribution, is prohibited by this license. Such acts require a separate *    license directly from Dr. Pearlman. *  * 2. For academic and non-commercial purposes, this license does not restrict *    use; copying, distribution, and modification are permitted under the *    terms of the GNU General Public License as published by the Free Software *    Foundation, with the further restriction that the terms of the present *    license shall also apply to all subsequent copies, distributions, *    or modifications of the 3D-SPIHT source code. *  * NO WARRANTY *  * 3. PrimaComp, Inc., dislaims all warranties, expressed or implied, including *    without limitation any warranty whatsoever as to the fitness for a *    particular use or the merchantability of the 3D-SPIHT source code. *  * 4. In no event shall PrimaComp, Inc., be liable for any loss of profits, *    loss of business, loss of use or loss of data, nor for indirect, special, *    incidental or consequential damages of any kind related to use of the *    3D-SPIHT source code. *  *  * END OF TERMS AND CONDITIONS *  *  * Persons desiring to license the 3D-SPIHT algorithm for commercial purposes * or for uses otherwise prohibited by this license may wish to contact * Dr. Pearlman regarding the possibility of negotiating such licenses: *  *   Dr. William A. Pearlman, President *   PrimaComp, Inc. *   851 Maxwell Drive *   Niskayuna, NY 12309 *   U.S.A. *    *   e-mail: wpearlman@spiht.com *   tel.: +1 (518) 522-7781 *   fax: +1 (518) 393-7412 *   * ---------------------------------------------------------------------------- */#include "spihtencode3d.h"#define USG_STRING "[-w %s:wavelet] [-b %s:boundary] [-nl %: %d:num_levels] [-sl %: %d:spatial_num_levels] [-tl %: %d:temporal_num_levels] [-dt %:] [-pt %:] [-at %:] [-noac %:] [-m %: %s:mask] [-vo %:] %f:rate %s:icbfile %s:bitstream"QccWAVWavelet Wavelet;QccString WaveletFilename = QCCWAVWAVELET_DEFAULT_WAVELET;QccString Boundary = "symmetric";int TransformType = QCCWAVSUBBANDPYRAMID3D_DYADIC;int ZerotreeType = QCCSPIHT3D_ZEROTREE_ASPACKET;int DyadicTreeSpecified = 0;int PacketTreeSpecified = 0;int AsymmetricTreeSpecified = 0;int NumLevelsSpecified = 0;int NumLevels = 5;int SpatialNumLevelsSpecified = 0;int SpatialNumLevels = 0;int TemporalNumLevelsSpecified = 0;int TemporalNumLevels = 0;QccIMGImageCube InputImage;int ImageNumFrames, ImageNumRows, ImageNumCols;QccIMGImageCube Mask;int MaskSpecified = 0;int MaskNumFrames, MaskNumRows, MaskNumCols;QccBitBuffer OutputBuffer;int NoArithmeticCoding = 0;int ValueOnly = 0;float TargetRate;float ActualRate;int NumPixels;int TargetBitCnt;int main(int argc, char *argv[]){  int frame, row, col;  QccInit(argc, argv);    QccSPIHT3DHeader();  QccWAVWaveletInitialize(&Wavelet);  QccIMGImageCubeInitialize(&InputImage);  QccIMGImageCubeInitialize(&Mask);  QccBitBufferInitialize(&OutputBuffer);  if (QccParseParameters(argc, argv,                         USG_STRING,                         WaveletFilename,                         Boundary,                         &NumLevelsSpecified,                         &NumLevels,                         &SpatialNumLevelsSpecified,                         &SpatialNumLevels,                         &TemporalNumLevelsSpecified,                         &TemporalNumLevels,                         &DyadicTreeSpecified,                         &PacketTreeSpecified,                         &AsymmetricTreeSpecified,                         &NoArithmeticCoding,                         &MaskSpecified,                         Mask.filename,                         &ValueOnly,                         &TargetRate,                         InputImage.filename,                         OutputBuffer.filename))    QccErrorExit();    if (DyadicTreeSpecified + PacketTreeSpecified + AsymmetricTreeSpecified > 1)    {      QccErrorAddMessage("%s: Only one zerotree type can be specified",                         argv[0]);      QccErrorExit();    }  if ((NumLevels < 0) || (SpatialNumLevels < 0) || (TemporalNumLevels < 0))    {      QccErrorAddMessage("%s: Number of levels of decomposition must be nonnegative",                         argv[0]);      QccErrorExit();    }  if (NumLevelsSpecified &&      (SpatialNumLevelsSpecified || TemporalNumLevelsSpecified))    {      QccErrorAddMessage("%s: If num_levels is given (dyadic transform), neither spatial_num_levels or temporal_num_levels (packet transform) can be specified",                         argv[0]);      QccErrorExit();    }  if (NumLevelsSpecified ||      ((!SpatialNumLevelsSpecified) && (!TemporalNumLevelsSpecified)))    {      if (PacketTreeSpecified || AsymmetricTreeSpecified)        {          QccErrorAddMessage("%s: Packet tree or asymmetric packet tree cannot be specified for a dyadic decomposition",                             argv[0]);          QccErrorExit();        }      TransformType = QCCWAVSUBBANDPYRAMID3D_DYADIC;      ZerotreeType = QCCSPIHT3D_ZEROTREE_DYADIC;      SpatialNumLevels = NumLevels;      TemporalNumLevels = NumLevels;    }  else    {      TransformType = QCCWAVSUBBANDPYRAMID3D_PACKET;      if (SpatialNumLevelsSpecified && (!TemporalNumLevelsSpecified))        TemporalNumLevels = SpatialNumLevels;      else        if ((!SpatialNumLevelsSpecified) && TemporalNumLevelsSpecified)          SpatialNumLevels = TemporalNumLevels;      if (DyadicTreeSpecified)        ZerotreeType = QCCSPIHT3D_ZEROTREE_DYADIC;      if (PacketTreeSpecified)        ZerotreeType = QCCSPIHT3D_ZEROTREE_PACKET;      if (AsymmetricTreeSpecified)        ZerotreeType = QCCSPIHT3D_ZEROTREE_ASPACKET;    }    if (((ZerotreeType == QCCSPIHT3D_ZEROTREE_DYADIC) ||       (ZerotreeType == QCCSPIHT3D_ZEROTREE_PACKET)) &&      (TemporalNumLevels != SpatialNumLevels))    {      QccErrorAddMessage("%s: Packet and dyadic zerotrees must be applied to a transform with the same number of temporal and spatial levels",                         argv[0]);      QccErrorExit();    }  if (QccWAVWaveletCreate(&Wavelet, WaveletFilename, Boundary))    {      QccErrorAddMessage("%s: Error calling QccWAVWaveletCreate()",                         argv[0]);      QccErrorExit();    }    if (QccIMGImageCubeRead(&InputImage))    {      QccErrorAddMessage("%s: Error calling QccIMGImageCubeRead()",                         argv[0]);      QccErrorExit();    }  ImageNumFrames = InputImage.num_frames;  ImageNumRows = InputImage.num_rows;  ImageNumCols = InputImage.num_cols;  if (ImageNumFrames !=       ((int)(ImageNumFrames >> (TemporalNumLevels + 1)) <<       (TemporalNumLevels + 1)))    {      QccErrorAddMessage("%s: Image-cube size (%d x %d x %d) is not a multiple of %d (as needed for a temporal decomposition of %d levels)",                         argv[0],                         ImageNumCols, ImageNumRows, ImageNumFrames,                         (1 << (TemporalNumLevels + 1)), TemporalNumLevels);      QccErrorExit();    }  if (ImageNumCols !=       ((int)(ImageNumCols >> (SpatialNumLevels + 1)) <<       (SpatialNumLevels + 1)))    {      QccErrorAddMessage("%s: Image-cube size (%d x %d x %d) is not a multiple of %d (as needed for a spatial decomposition of %d levels)",                         argv[0],                         ImageNumCols, ImageNumRows, ImageNumFrames,                         (1 << (SpatialNumLevels + 1)), SpatialNumLevels);      QccErrorExit();    }  if (ImageNumRows !=       ((int)(ImageNumRows >> (SpatialNumLevels + 1)) <<       (SpatialNumLevels + 1)))    {      QccErrorAddMessage("%s: Image-cube size (%d x %d x %d) is not a multiple of %d (as needed for a spatial decomposition of %d levels)",                         argv[0],                         ImageNumCols, ImageNumRows, ImageNumFrames,                         (1 << (SpatialNumLevels + 1)), SpatialNumLevels);      QccErrorExit();    }    if (MaskSpecified)    {      if (QccIMGImageCubeRead(&Mask))        {          QccErrorAddMessage("%s: Error calling QccIMGImageCubeRead()",                             argv[0]);          QccErrorExit();        }      MaskNumFrames = Mask.num_frames;      MaskNumRows = Mask.num_rows;      MaskNumCols = Mask.num_cols;      if ((MaskNumFrames != ImageNumFrames) ||          (MaskNumRows != ImageNumRows) ||          (MaskNumCols != ImageNumCols))        {          QccErrorAddMessage("%s: Mask must be same size as image cube",                             argv[0]);          QccErrorExit();        }      NumPixels = 0;      for (frame = 0; frame < MaskNumFrames; frame++)        for (row = 0; row < MaskNumRows; row++)          for (col = 0; col < MaskNumCols; col++)            if (!QccAlphaTransparent(Mask.volume[frame][row][col]))              NumPixels++;    }  else    NumPixels = ImageNumFrames * ImageNumRows * ImageNumCols;  OutputBuffer.type = QCCBITBUFFER_OUTPUT;  if (QccBitBufferStart(&OutputBuffer))    {      QccErrorAddMessage("%s: Error calling QccBitBufferStart()",                         argv[0]);      QccErrorExit();    }     TargetBitCnt = (int)(ceil((NumPixels * TargetRate)/8.0))*8;  if (QccSPIHT3DEncode(&(InputImage),                       (MaskSpecified ? &(Mask) : NULL),                       &OutputBuffer,                       TransformType,                       ZerotreeType,                       TemporalNumLevels,                       SpatialNumLevels,                       &Wavelet,                       TargetBitCnt,                       !NoArithmeticCoding))    {      QccErrorAddMessage("%s: Error calling QccSPIHT3DEncode()",                         argv[0]);      QccErrorExit();    }        ActualRate =     (double)OutputBuffer.bit_cnt / NumPixels;  if (QccBitBufferEnd(&OutputBuffer))    {      QccErrorAddMessage("%s: Error calling QccBitBufferEnd()",                         argv[0]);      QccErrorExit();    }    if (ValueOnly)    printf("%f\n", ActualRate);  else    {      printf("3D-SPIHT coding of %s:\n",             InputImage.filename);      printf("  Target rate: %f bpv\n", TargetRate);      printf("  Actual rate: %f bpv\n", ActualRate);    }  QccIMGImageCubeFree(&InputImage);  QccIMGImageCubeFree(&Mask);  QccWAVWaveletFree(&Wavelet);  QccExit;}

⌨️ 快捷键说明

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