int pDecode(memBUFF *buff, int *qx, int n) /****************************************************************************** buff encoded input qx array[] of output integers n length of output Returned: consistency flag ******************************************************************************/ { int i; signed char sc; unsigned int s; unsigned char c1=0, c2=0; i = 0; while(buffGetc(buff, sc) != MEM_EOB){ /* if overflow */ if(sc == PC_OVERFLOW){ /* get the following two bytes */ buffGetc(buff, c1); buffGetc(buff, c2); s = c1*BYTEMAX + c2; /* convert to integer */ qx[i++] = s >> 1; } /* else if underflow */ else if(sc == PC_UNDERFLOW){
int huffInputcounts(wpcBITBUFF *bit_buff, huffNODE *nodes) /************************************************************************* input the hit count table from the input buffer ************************************************************************** bit_buff buffer holding the encoded bit stream nodes array[] of nodes hold the leaves (the symbols) of the Huffman tree *************************************************************************/ { int first, last, i, c; for(i=0; i<HUFFNSYMBOL;i++) nodes[i].count = 0; if( buffGetc(bit_buff->buff, first) == WPC_EOB) return WPC_EOB; if( buffGetc(bit_buff->buff, last) == WPC_EOB) return WPC_EOB; for( ; ; ){ for(i=first; i <= last ; i++) if(buffGetc(bit_buff->buff, c) == WPC_EOB) return WPC_EOB; else nodes[i].count = (unsigned int ) c; if(buffGetc(bit_buff->buff, first) == WPC_EOB) return WPC_EOB; if (first == 0) break; if(buffGetc(bit_buff->buff, last) == WPC_EOB) return WPC_EOB; } nodes[HUFFENDOFBLK].count = 1; return 0; }
int huffEncoder(wpcBUFF *inbuff, wpcBITBUFF *bit_buff, huffCODE *codes) /************************************************************************* encode all the symbols in the byte stream buffer ************************************************************************** inbuff input buffer for the input byte stream bit_buffer output buffer for the output bit stream codes Huffman codes ************************************************************************** Note: After the Huffman codes are built, encoding is just a table look up. *************************************************************************/ { int c; int nbytes = (bit_buff->buff)->pos; int retval; while(buffGetc(inbuff, c) != WPC_EOB){ bitOutputbits(bit_buff, codes[c].code, codes[c].code_bits, retval); if(retval == WPC_EOB) return retval; } bitOutputbits(bit_buff, codes[HUFFENDOFBLK].code, codes[HUFFENDOFBLK].code_bits, retval); if(retval == WPC_EOB) return retval; /* return this value just to check if the encoding is normal */ nbytes = (bit_buff->buff)->pos - nbytes; return (nbytes); }
void codeDesilence ( void *inb, void *outb) /*********************************************************************** Silence deencoding ************************************************************************ inb input buffer outb output buffer ***********************************************************************/ { memBUFF *inbuff = (memBUFF *) inb; memBUFF *outbuff = (memBUFF *) outb; int c, run_count=0; while(buffGetc(inbuff, c) != MEM_EOB){ if(c==SILENCECODE){ buffGetc(inbuff, run_count); while(run_count-- >0) buffPutc(outbuff, 0x0); } else buffPutc(outbuff, c); } }
void huffCountbytes (wpcBUFF *buff, unsigned int *counts) /************************************************************************* count the hit count of each input symbols ************************************************************************** buff buffer holding the byte stream to be encoded counts array[] holding the hit counts *************************************************************************/ { unsigned char c; int pos; pos = buff->pos; while(buffGetc(buff, c) != WPC_EOB) counts[c] ++; /* rewind the buffer */ buff->pos = pos; }
void codeSilence (void *inb, void *outb) /*********************************************************************** Silence encoding, takes care of "silence" pieces ************************************************************************ inb input buffer outb output buffer ***********************************************************************/ { memBUFF *inbuff = (memBUFF *) inb; memBUFF *outbuff = (memBUFF *) outb; int look_ahead[LOOKAHSZ]; int index, i, run_length, flag; /* preload the look ahead buffer */ for(i=0; i<LOOKAHSZ; i++) if(buffGetc(inbuff, look_ahead[i]) == MEM_EOB) break; /* if not enough samples, no RLE */ if(i < LOOKAHSZ){ buffMerge(outbuff, inbuff); return; } index = 0; for(;;){ if(look_ahead[index] == MEM_EOB) break; if(silence_run(look_ahead, index)){ run_length = 0; do{ flag = buffGetc(inbuff, look_ahead[index]); if(flag == MEM_EOB) look_ahead[index] = MEM_EOB; index ++; index &= LOOKAHMASK; if(++run_length == MAXLENGTH){ buffPutc(outbuff, SILENCECODE); buffPutc(outbuff, MAXLENGTH); run_length = 0; } } while(!end_of_silence(look_ahead, index)); if(run_length > 0){ buffPutc(outbuff, SILENCECODE); buffPutc(outbuff, run_length); } } if(look_ahead[index] == MEM_EOB) break; /* the silence code in the input get changed */ if(look_ahead[index] == SILENCECODE) look_ahead[index]++; buffPutc(outbuff, look_ahead[index]); /* get a new code */ flag = buffGetc(inbuff, look_ahead[index]); if(flag == MEM_EOB) look_ahead[index] = MEM_EOB; index ++; index &= LOOKAHMASK; } }
void codeSilence (void *inb, void *outb) /*********************************************************************** Silence encoding, takes care of "silence" pieces ************************************************************************ inb input buffer outb output buffer ************************************************************************ Note: To avoid the inefficiency in encoding isolated 0's, I start a run only when there are CODESTARTTHRSHOLD consective 0's. Therefore, a look ahead buffer is needed. The run is stopped as soon as there is a non-0 symbol. ***********************************************************************/ { wpcBUFF *inbuff = (wpcBUFF *) inb; wpcBUFF *outbuff = (wpcBUFF *) outb; int look_ahead[CODELOOKAHSZ]; int index, i, run_length, flag; /* preload the look ahead buffer */ for(i=0; i<CODELOOKAHSZ; i++) if(buffGetc(inbuff, look_ahead[i]) == WPC_EOB) break; /* if not enough samples, no RLE */ if(i < CODELOOKAHSZ){ buffMerge(outbuff, inbuff); return; } index = 0; for(;;){ if(look_ahead[index] == WPC_EOB) break; if(silence_run(look_ahead, index)){ run_length = 0; do{ flag = buffGetc(inbuff, look_ahead[index]); if(flag == WPC_EOB) look_ahead[index] = WPC_EOB; index ++; index &= CODELOOKAHMASK; if(++run_length == CODEMAXLENGTH){ buffPutc(outbuff, CODESILENCECODE); buffPutc(outbuff, CODEMAXLENGTH); run_length = 0; } } while(!end_of_silence(look_ahead, index)); if(run_length > 0){ buffPutc(outbuff, CODESILENCECODE); buffPutc(outbuff, run_length); } } if(look_ahead[index] == WPC_EOB) break; /* the silence code in the input get changed */ if(look_ahead[index] == CODESILENCECODE) look_ahead[index]++; buffPutc(outbuff, look_ahead[index]); /* get a new code */ flag = buffGetc(inbuff, look_ahead[index]); if(flag == WPC_EOB) look_ahead[index] = WPC_EOB; index ++; index &= CODELOOKAHMASK; } }