📄 wpc1coding.c
字号:
/**********************************************************************entropy decoder using some codebook ***********************************************************************Input:qstate quantization statusnblock # of blocksinbuff input memory bufferOutput:qstate quantization statusReturn: consistency flag, 1 if wpc1Compressed data, 0 otherwise**********************************************************************/{ wpc1QUANT **quant = (wpc1QUANT **) qstate; wpcBUFF *buff = (wpcBUFF *) inbuff; wpcBITBUFF *bitbuff; codeBOOK codebook; static codeDICT *codedict; int iblock,flag, retval=0; int numsmp, nbit; int *qx; /* init the bitwise buffer */ bitInitbuff(bitbuff, buff); /* read # of bits to the buffer */ for(iblock=0; iblock<nblock; iblock++){ bitInputbits(bitbuff, BITMAXNBIT, nbit, flag); quant[iblock]->nbit = nbit; } /* build the code dictionary */ codedict = builddict(); /* entropy decoding each block */ for(iblock=0; iblock<nblock; iblock++){ nbit = quant[iblock]->nbit; numsmp = quant[iblock]->numsmp; qx = quant[iblock]->qx; /* obtain the code book for this nbit */ codebook = codedict->book[nbit]; /* decode according to the code book */ retval = bookDecoder(bitbuff, &codebook, qx, numsmp); if(!retval) break; } /* close the buffer */ bitFreebuff(bitbuff); retval += 0*flag; /* dummy */ return (retval);}void bookCoder(void *buff, void *book, void *q, int numsmp)/************************************************************************entropy coding using a codebook*************************************************************************Input:book pointer to the codebookq array of symbols need encodednumsmp # of samples in the arrayOutput:buff output memory buffer (bitwise) ************************************************************************/{ wpcBITBUFF *bitbuff = (wpcBITBUFF *) buff; codeBOOK *codebook = (codeBOOK *) book; entCODE code; int *qx = (int *) q; int symbol, absq; int runlen = 0; int i, ibit, booksize, flag; /* booksize */ booksize = codebook->booksize; /* for each symbol */ for(i=0; i<numsmp; i++){ symbol = qx[i]; /* if zero */ if(symbol == 0){ runlen ++; continue; } /* output the runlength */ if(runlen !=0 ){ while(runlen > 0){ code = codebook->code[0]; bitOutputbits(bitbuff, code.value, code.bits, flag); if(runlen <= codebook->maxrun){ bitOutputbits(bitbuff, runlen-1, codebook->bitmaxrun, flag); runlen = 0; } else{ bitOutputbits(bitbuff, codebook->maxrun - 1, codebook->bitmaxrun, flag); runlen -= codebook->maxrun; } } } absq = abs(symbol); /* # of bits */ for(ibit=0; ibit<MAXNBIT; ibit++) if(absq < amptbl[ibit]) break; /* prefix coding */ code = codebook->code[ibit]; bitOutputbits(bitbuff, code.value, code.bits, flag); /* code */ if(symbol > 0){ bitOutputbits(bitbuff, symbol, ibit, flag); } else{ symbol += amptbl[ibit] - 1; bitOutputbits(bitbuff, symbol, ibit, flag); } } /* if ended with a run */ if(runlen !=0 ){ while(runlen > 0){ code = codebook->code[0]; bitOutputbits(bitbuff, code.value, code.bits, flag); if(runlen <= codebook->maxrun){ bitOutputbits(bitbuff, runlen-1, codebook->bitmaxrun, flag); runlen = 0; } else{ bitOutputbits(bitbuff, codebook->maxrun - 1, codebook->bitmaxrun, flag); runlen -= codebook->maxrun; } } } /* output the end of block symbol */ code = codebook->code[booksize - 1]; bitOutputbits(bitbuff, code.value, code.bits, flag); runlen = flag; /* dummy */}int bookDecoder(void *bbuff, void *book, void *q, int numsmp)/************************************************************************entropy decoding using a codebook*************************************************************************Input:bbuff input memory buffer (bitwise) book pointer to the codebooknumsmp # of samples in the arrayOutput:q array of symbols decodedReturn: consistency flag, 1 if wpc1Compressed, 0 otherwise************************************************************************/{ wpcBITBUFF *bitbuff = (wpcBITBUFF *) bbuff; codeBOOK *codebook = (codeBOOK *) book; entCODE code0; int *qx = (int *) q; int symbol, absq; int runlen, maxrun, bitmaxrun; int i, ibit, pbit, morebit, eobbits, pref, booksize, flag; unsigned int value, eobflag, fullpref; /* booksize, 0 code and eob */ booksize = codebook->booksize; code0 = codebook->code[0]; maxrun = codebook->maxrun; bitmaxrun = codebook->bitmaxrun +0*maxrun; eobflag = codebook->code[booksize-1].value; eobbits = codebook->code[booksize-1].bits; fullpref = (eobbits == code0.bits); i = 0; do { /* read some bits */ bitInputbits(bitbuff, code0.bits, pref, flag); if(flag == WPC_EOB) return (0); /* if it's a zero run */ if(pref == code0.value){ /* input the runlength */ bitInputbits(bitbuff, bitmaxrun, runlen, flag); if(flag == WPC_EOB) return (0); /* convert into integers */ while(runlen >= 0){ qx[i++] = 0; runlen --; } } /* else if other prefix */ else if(codebook->code[pref].bits == code0.bits){ /* if the end of block symbol */ if(fullpref && (codebook->code[pref].value == eobflag)) break; /* conver to # of bits */ ibit = codebook->pref2bit[pref]; /* input the code */ bitInputbits(bitbuff, ibit, absq, flag); if(flag == WPC_EOB) return (0); /* if the end of block symbol */ if((!fullpref) && ((pref << ibit) + absq == eobflag)) break; /* convert to integer */ if(absq & amptbl[ibit-1]) symbol = absq; else symbol = absq - amptbl[ibit] + 1; qx[i++] = symbol; } /* else if not full prefix */ else{ pbit = codebook->code[pref].bits; morebit = pbit - code0.bits; /* input the remaining prefix */ bitInputbits(bitbuff, morebit, value, flag); if(flag == WPC_EOB) return (0); /* get the full prefix */ pref = (pref << morebit) + value; /* if the end of block symbol */ if((pbit == eobbits) && (pref == eobflag)) break; /* convert to # of bits */ ibit = codebook->pref2bit[pref]; /* input the code */ bitInputbits(bitbuff, ibit, absq, flag); if(flag == WPC_EOB) return (0); /* if the end of block symbol */ if((pbit+ibit == eobbits)&&((pref<<ibit)+absq == eobflag)) break; /* convert to integer */ if(absq & amptbl[ibit-1]) symbol = absq; else symbol = absq - amptbl[ibit] + 1; qx[i++] = symbol; } } while( i >= 0 /*TRUE*/); /* consistency check */ if(i != numsmp) return (0); else return (1);} static codeDICT *builddict(void)/************************************************************************build the dictionary for entropy coding*************************************************************************Return: pointer to the dictionary*************************************************************************Note: The codebooks here are just a variable form of variable-length integer code book. Each symbol is represented by two parts, a prefix of bit count indicating how many bits are used to encode the symbol, and the symbol itself. E.g., for codebook[1], the book looks like this: bit count amplitude 0 0 1 -1, 1 2 -3, -2, 2, 3 3 end_of_block So, the number 3 is coded as 1011, instead of 0011 (the first 0 is the sign bit), the number 1 on the other hand is coded as 011, instead of 0001. The end_of_block symbol is used to indicate the end of a block, since the coding here is bitwise, and the result might not align up with byte boundaries. To further reduce the overhead, the bit counts are also variable-length coded, though they happen to be the same in codebook[1]. The table pref2bit is used to convert the variable-length coded prefix into actually bit count. ************************************************************************/{ codeDICT *codedict; codeBOOK *codebook; int *pref2bit; int dictsize, booksize; int i; /* allocate the code dictionary */ codedict = (codeDICT *) malloc(sizeof(codeDICT)); codedict->dictsize = dictsize = MAXNBIT - 1; /* allocate the code books */ codedict->book = (codeBOOK *) malloc(dictsize*sizeof(codeBOOK)); codebook = codedict->book; /* for each book */ for(i=0; i<dictsize; i++){ codebook[i].booksize = booksize = i+3; codebook[i].code = (entCODE *) malloc(booksize*sizeof(entCODE)); } /* initialize each of the code books */ /* prefix codes and # of bits */ codebook[0].maxrun = 16; codebook[0].bitmaxrun = 4; codebook[0].code[0].value = 0; codebook[0].code[0].bits = 1; codebook[0].code[1].value = 2; codebook[0].code[1].bits = 2; codebook[0].code[2].value = 3; codebook[0].code[2].bits = 2; /* table convert prefix to # of bits */ codebook[0].pref2bit = (int *) malloc(4*sizeof(int)); pref2bit = codebook[0].pref2bit; pref2bit[0] = 0; pref2bit[1] = 0; pref2bit[2] = 1; pref2bit[3] = 0; codebook[1].maxrun = 16; codebook[1].bitmaxrun = 4; codebook[1].code[0].value = 0; codebook[1].code[0].bits = 2; codebook[1].code[1].value = 1; codebook[1].code[1].bits = 2; codebook[1].code[2].value = 2; codebook[1].code[2].bits = 2; codebook[1].code[3].value = 3; codebook[1].code[3].bits = 2; codebook[1].pref2bit = (int *) malloc(4*sizeof(int)); pref2bit = codebook[1].pref2bit; for(i=0; i<3; i++) pref2bit[i] = i; pref2bit[3] = 0; codebook[2].maxrun = 16; codebook[2].bitmaxrun = 4; codebook[2].code[0].value = 0; codebook[2].code[0].bits = 2; codebook[2].code[1].value = 1; codebook[2].code[1].bits = 2; codebook[2].code[2].value = 2; codebook[2].code[2].bits = 2; codebook[2].code[3].value = 6; codebook[2].code[3].bits = 3; codebook[2].code[4].value = 7; codebook[2].code[4].bits = 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -