📄 wpccoding.c
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved. *//* WPCCODING: $Revision: 1.4 $ ; $Date: 1997/07/30 15:33:25 $ *//*********************** self documentation **********************//***************************************************************************WPCCODING - Routines for in memory coding of the quantized coeffiecientscodeEncoder encode the quantized coeffiecients into a bit stream codeDecoder decode a bit stream into the quantized coeffiecients****************************************************************************Function Prototypes:int codeEncoder(void *inconf, void *qstate, void *obuff, void *interblock)int codeDecoder(void *inconf, void *qstate, void *ibuff, void *interblock)****************************************************************************codeEncoder:Input:inconf configuration infoqstate quantization statusOutput:outbuff buffer to hold encoded bit streaminterblock reserved for inter block communicationReturn:# of bytes after codingcodeDecoder:Input:inconf configuration infoibuff buffer to hold encoded symbolsinterblock reserved for inter block communicationOutput:qstate quantization statusReturn:consistency flag, 1 if wpcCompressed data, 0 otherwise*************************************************************************Author: Tong Chen, 07/29/94*************************************************************************//**************** end self doc ********************************/#include "wpc.h"#include "wpclib.h"#include "wpcbuffer.h"#define CODEMAXLOAD 0x7fff#define CODEOVERFLOW 127#define CODEUNDERFLOW -127#define CODESHORTSIZE 2#define CODEBYTEMASK 0xff#define CODEBYTEBIT 8int codeEncoder(void *inconf, void *qstate, void *obuff, void *interblock)/*******************************************************************************encoding the quantized coefficients ********************************************************************************Input:inconf configuration infoqstate quantization statusOutput:outbuff buffer to hold encoded bit streaminterblock reserved for inter block communication (unused)Return: # of bytes after coding********************************************************************************Note: This routine might seem messy. The essence is to store all the information needed for reconstruction, while using minimal storage. Some of the side information is also huffman coded, making the mixed type buffering operation necessary. In short, each block of quantized wavelet coefficients are first encoded, using "home brewed" prefix coding. This prefix coding takes advantage of the p.d.f. of the wavelet coefficients and proves to be straight forward and efficient. Following this, are the runlength coding and huffman coding. Several of the wavelet blocks are first merged to increase the runlength and to reduce the overhead of static huffman coding. This merging should be based on the entropy, but here I use deviation instead, which turns out to be well correlated to the entropy. Of course, it can also be fixed like the zig-zag in the JPEG standard. ********************************************************************************Author: Tong Chen, 07/29/94*******************************************************************************/{ wpcCONFIG *config = (wpcCONFIG *) inconf; wpcQUANT *quant = (wpcQUANT *) qstate; wpcBUFF *outbuff = (wpcBUFF *) obuff; wpcBUFF *pbuff = (wpcBUFF *) interblock; /* dummy */ wpcBUFF **quantbuff, **rlebuff, **huffbuff; int i, j, bind, nsize=0, shortsize, outputsize; unsigned int s; int iblock, nblock, lblock, codenblock, codelblock; int **qx; unsigned char zeroflag, *flowflag, *blockind; float ave, step; int quantmbound, huffmbound; /* obtain the configuration info */ nblock = config->nblock; lblock = config->lblock; codenblock = config->codenblock; codelblock = config->codelblock; /* obtain the quantization status */ zeroflag = quant->zeroflag; flowflag = quant->flowflag; blockind = quant->blockind; ave = quant->ave; step = quant->step; qx = quant->qx; outputsize = 0; /* if dc signal */ if(zeroflag==QUANTZEROFLAGY){ /* output a zero flag */ if(buffPutc(outbuff, QUANTZEROFLAGY) == WPC_EOB) return WPC_EOB; outputsize ++; /* output the average as well */ if(buffWrite(outbuff, sizeof(float), 1, &ave) == WPC_EOB) return WPC_EOB; outputsize += sizeof(float); return (outputsize); } /* else, output the zeroflag, average and stepsize, which are not huffman coded to preserve the low entroy nature of wavelet coefficients */ if(buffPutc(outbuff, QUANTZEROFLAGN) == WPC_EOB) return WPC_EOB; outputsize ++; /* output the average */ if(buffWrite(outbuff, sizeof(float), 1, &ave) == WPC_EOB) return WPC_EOB; outputsize += sizeof(float); /* output the step size */ if(buffWrite(outbuff, sizeof(float), 1, &step) == WPC_EOB) return WPC_EOB; outputsize += sizeof(float); /* decide the bounds for the buffers */ quantmbound = ((int) sizeof(int))*lblock; /* guaranteed to be enough */ huffmbound = ((int) sizeof(int))*codelblock*lblock;/* guaranteed to be enough */ /* allocate and init buffers for RLE and Huffman */ quantbuff = (wpcBUFF **) buffAlloc2(nblock, quantmbound); rlebuff = (wpcBUFF **) buffAlloc2(codenblock, huffmbound); huffbuff = (wpcBUFF **) buffAlloc2(codenblock, huffmbound); /* encode each one of the blocks of wavelet coefficients */ for(iblock = 0; iblock < nblock; iblock ++){ pbuff = quantbuff[iblock]; /* if no flow, then fast version */ if(flowflag[iblock] == QUANTFLOWFLAGN){ /* output the flow flag, no bound checking needed */ buffPutc(pbuff, QUANTFLOWFLAGN); /* convert into bytes */ for(i=0;i<lblock;i++) buffPutc(pbuff, (unsigned char) qx[iblock][i]); } /* else */ else{ /* output the flow flag, no bound checking needed */ buffPutc(pbuff, QUANTFLOWFLAGY); /* encoding */ for(i=0;i<lblock;i++){ if(qx[iblock][i] > 0){ /* if overflow */ if(qx[iblock][i] > QUANTMAX){ s = (unsigned) qx[iblock][i]; /* is there any signal on earth that can make this happen? */ if(s > CODEMAXLOAD) s = CODEMAXLOAD; /* shift the level to avoid silence code */ s = (s << 1) + 1; /* output a prefix code */ buffPutc(pbuff, CODEOVERFLOW); /* output a short */ shortsize = CODESHORTSIZE; while(shortsize-- > 0){ buffPutc(pbuff, s & CODEBYTEMASK); s >>= CODEBYTEBIT; } } else{ buffPutc(pbuff, (unsigned char) qx[iblock][i]); } } /* negative */ else{ /* if underflow */ if(qx[iblock][i] < -QUANTMAX){ s = (unsigned) (- qx[iblock][i]); /* is there any signal on earth that can make this happen? */ if(s > CODEMAXLOAD) s = CODEMAXLOAD; /* shift the level to avoid silence code */ s = (s << 1) + 1; /* output a prefix code */ buffPutc(pbuff, CODEUNDERFLOW); /* output a short */ shortsize = CODESHORTSIZE; while(shortsize-- > 0){ buffPutc(pbuff, s & CODEBYTEMASK); s >>= CODEBYTEBIT; } } else{ buffPutc(pbuff, (unsigned char) qx[iblock][i]); } } } } /* adjust the buffer size */ buffRealloc1((void *)pbuff, pbuff->pos); } /* output the block indices and buffer lengths as the header, to the Huffman buffer */ for(iblock = 0; iblock < nblock; iblock ++){ /* no bound checking needed */ buffPutc(huffbuff[0], blockind[iblock]); } for(iblock = 0; iblock < nblock; iblock ++){ buffWrite(huffbuff[0], sizeof(int), 1, &(quantbuff[iblock]->mbound)); } /* put several blocks together to reduce overhead */ for(iblock=0; iblock < codenblock; iblock++){ pbuff = rlebuff[iblock]; for(i=0; i< codelblock; i++){ /* the block with largest deviation(entropy) is encoded first, so that the header does not damage the low entropy blocks */ j = (codenblock-1-iblock)*codelblock + i; bind = blockind[j]; /* no bound checking needed */ buffMerge(pbuff, quantbuff[bind]); } /* adjust the buffer sizes */ buffRealloc1((void *)pbuff, pbuff->pos); /* rewind the buffers */ buffRewind(pbuff); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -