📄 spihtencode.c
字号:
/* * * QccPack: Quantization, compression, and coding utilities * Copyright (C) 1997-2001 James E. Fowler * *//* * ---------------------------------------------------------------------------- * * Public License for the SPIHT Algorithm * Version 1.2, March 8, 2004 * * ---------------------------------------------------------------------------- * * The Set Partitioning In Hierarchical Trees (SPIHT) algorithm is protected * by US Patent #5,764,807 (issued June 9, 1998), US Patent #6,674,911 (issued * January 6, 2004), and other international patents and patents pending. An * implementation of the 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 SPIHT algorithm implementation * contained herein (hereafter referred to as "the SPIHT source code"). * * 0. Use of the 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 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 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 * SPIHT source code. * * * END OF TERMS AND CONDITIONS * * * Persons desiring to license the SPIHT algorithm for commercial purposes or * for uses otherwise prohibited by this license may wish to contact * PrimaComp, Inc., regarding the possibility of negotiating such licenses: * * PrimaComp, Inc. * 851 Maxwell Drive * Schenectady, NY 12309 * U.S.A. * +1 (857) 231-6135 * email: bmazor@spiht.com * http://www.cipr.rpi.edu/research/SPIHT * * ----------------------------------------------------------------------------*/#include "spihtencode.h"#define USG_STRING "[-w %s:wavelet] [-b %s:boundary] [-pw %: %s:pcpfile] [-nl %d:num_levels] [-noac %:] [-m %: %s:mask] [-rd %: %s:rd_file] [-vo %:] %f:rate %s:imgfile %s:bitstream"QccWAVWavelet Wavelet;QccString WaveletFilename = QCCWAVWAVELET_DEFAULT_WAVELET;QccString Boundary = "symmetric";QccWAVPerceptualWeights PerceptualWeights;int UsePerceptualWeights = 0;int NumLevels = 5;int NumSubbands;QccIMGImage InputImage;int ImageNumRows, ImageNumCols;QccIMGImage Mask;int MaskSpecified = 0;int MaskNumRows, MaskNumCols;QccBitBuffer OutputBuffer;int NoArithmeticCoding = 0;int OutputRateDistortionFile = 0;QccString RateDistortionFilename;int ValueOnly = 0;float TargetRate;float ActualRate;int NumPixels;int TargetBitCnt;int main(int argc, char *argv[]){ int row, col; FILE *rate_distortion_file = NULL; QccInit(argc, argv); QccSPIHTHeader(); QccWAVWaveletInitialize(&Wavelet); QccWAVPerceptualWeightsInitialize(&PerceptualWeights); QccIMGImageInitialize(&InputImage); QccIMGImageInitialize(&Mask); QccBitBufferInitialize(&OutputBuffer); if (QccParseParameters(argc, argv, USG_STRING, WaveletFilename, Boundary, &UsePerceptualWeights, PerceptualWeights.filename, &NumLevels, &NoArithmeticCoding, &MaskSpecified, Mask.filename, &OutputRateDistortionFile, RateDistortionFilename, &ValueOnly, &TargetRate, InputImage.filename, OutputBuffer.filename)) QccErrorExit(); if (NumLevels < 0) { QccErrorAddMessage("%s: Number of levels of decomposition must be nonnegative", argv[0]); QccErrorExit(); } NumSubbands = QccWAVSubbandPyramidNumLevelsToNumSubbands(NumLevels); if (QccWAVWaveletCreate(&Wavelet, WaveletFilename, Boundary)) { QccErrorAddMessage("%s: Error calling QccWAVWaveletCreate()", argv[0]); QccErrorExit(); } if (UsePerceptualWeights) { if (QccWAVPerceptualWeightsRead(&PerceptualWeights)) { QccErrorAddMessage("%s: Error calling QccWAVPerceptualWeightsRead()", argv[0]); QccErrorExit(); } if (PerceptualWeights.num_subbands != NumSubbands) { QccErrorAddMessage("%s: Number of subbands in %s does not match specified number of levels (%d)", argv[0], PerceptualWeights.filename, NumLevels); } } if (QccIMGImageRead(&InputImage)) { QccErrorAddMessage("%s: Error calling QccIMGImageRead()", argv[0]); QccErrorExit(); } if (QccIMGImageColor(&InputImage)) { QccErrorAddMessage("%s: Color images not supported", argv[0]); QccErrorExit(); } if (QccIMGImageGetSize(&InputImage, &ImageNumRows, &ImageNumCols)) { QccErrorAddMessage("%s: Error calling QccIMGImageGetSize()", argv[0]); QccErrorExit(); } if (ImageNumCols != ((int)(ImageNumCols >> (NumLevels + 1)) << (NumLevels + 1))) { QccErrorAddMessage("%s: Image size (%d x %d) is not a multiple of %d (as needed for a decomposition of %d levels)", argv[0], ImageNumCols, ImageNumRows, (1 << (NumLevels + 1)), NumLevels); QccErrorExit(); } if (ImageNumRows != ((int)(ImageNumRows >> (NumLevels + 1)) << (NumLevels + 1))) { QccErrorAddMessage("%s: Image size (%d x %d) is not a multiple of %d (as needed for a decomposition of %d levels)", argv[0], ImageNumCols, ImageNumRows, (1 << (NumLevels + 1)), NumLevels); QccErrorExit(); } if (MaskSpecified) { if (QccIMGImageRead(&Mask)) { QccErrorAddMessage("%s: Error calling QccIMGImageRead()", argv[0]); QccErrorExit(); } if (QccIMGImageColor(&Mask)) { QccErrorAddMessage("%s: Mask must be grayscale", argv[0]); QccErrorExit(); } if (QccIMGImageGetSize(&Mask, &MaskNumRows, &MaskNumCols)) { QccErrorAddMessage("%s: Error calling QccIMGImageGetSize()", argv[0]); QccErrorExit(); } if ((MaskNumRows != ImageNumRows) || (MaskNumCols != ImageNumCols)) { QccErrorAddMessage("%s: Mask must be same size as image", argv[0]); QccErrorExit(); } NumPixels = 0; for (row = 0; row < MaskNumRows; row++) for (col = 0; col < MaskNumCols; col++) if (!QccAlphaTransparent(Mask.Y.image[row][col])) NumPixels++; } else NumPixels = 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 (OutputRateDistortionFile) if ((rate_distortion_file = QccFileOpen(RateDistortionFilename, "w")) == NULL) { QccErrorAddMessage("%s: Error calling QccFileOpen()", argv[0]); QccErrorExit(); } if (QccSPIHTEncode(&(InputImage.Y), (MaskSpecified ? &(Mask.Y) : NULL), &OutputBuffer, NumLevels, &Wavelet, ((UsePerceptualWeights) ? &PerceptualWeights : NULL), TargetBitCnt, !NoArithmeticCoding, rate_distortion_file)) { QccErrorAddMessage("%s: Error calling QccSPIHTEncode()", argv[0]); QccErrorExit(); } QccFileClose(rate_distortion_file); 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("SPIHT coding of %s:\n", InputImage.filename); printf(" Target rate: %f bpp\n", TargetRate); printf(" Actual rate: %f bpp\n", ActualRate); } QccIMGImageFree(&InputImage); QccIMGImageFree(&Mask); QccWAVWaveletFree(&Wavelet); QccWAVPerceptualWeightsFree(&PerceptualWeights); QccExit;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -