mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-29 23:39:35 +00:00 
			
		
		
		
	
		
			
	
	
		
			182 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			182 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | 
 | ||
|  |    /******************************************************************
 | ||
|  | 
 | ||
|  |        iLBC Speech Coder ANSI-C Source Code | ||
|  | 
 | ||
|  |        packing.c | ||
|  | 
 | ||
|  |        Copyright (C) The Internet Society (2004). | ||
|  |        All Rights Reserved. | ||
|  | 
 | ||
|  |    ******************************************************************/ | ||
|  | 
 | ||
|  |    #include <math.h>
 | ||
|  |    #include <stdlib.h>
 | ||
|  | 
 | ||
|  |    #include "iLBC_define.h"
 | ||
|  |    #include "constants.h"
 | ||
|  |    #include "helpfun.h"
 | ||
|  |    #include "string.h"
 | ||
|  | 
 | ||
|  |    /*----------------------------------------------------------------*
 | ||
|  |     *  splitting an integer into first most significant bits and | ||
|  |     *  remaining least significant bits | ||
|  |     *---------------------------------------------------------------*/ | ||
|  | 
 | ||
|  |    void packsplit( | ||
|  |        int *index,                 /* (i) the value to split */ | ||
|  |        int *firstpart,             /* (o) the value specified by most
 | ||
|  |                                           significant bits */ | ||
|  |        int *rest,                  /* (o) the value specified by least
 | ||
|  |                                           significant bits */ | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |        int bitno_firstpart,    /* (i) number of bits in most
 | ||
|  |                                           significant part */ | ||
|  |        int bitno_total             /* (i) number of bits in full range
 | ||
|  |                                           of value */ | ||
|  |    ){ | ||
|  |        int bitno_rest = bitno_total-bitno_firstpart; | ||
|  | 
 | ||
|  |        *firstpart = *index>>(bitno_rest); | ||
|  |        *rest = *index-(*firstpart<<(bitno_rest)); | ||
|  |    } | ||
|  | 
 | ||
|  |    /*----------------------------------------------------------------*
 | ||
|  |     *  combining a value corresponding to msb's with a value | ||
|  |     *  corresponding to lsb's | ||
|  |     *---------------------------------------------------------------*/ | ||
|  | 
 | ||
|  |    void packcombine( | ||
|  |        int *index,                 /* (i/o) the msb value in the
 | ||
|  |                                           combined value out */ | ||
|  |        int rest,                   /* (i) the lsb value */ | ||
|  |        int bitno_rest              /* (i) the number of bits in the
 | ||
|  |                                           lsb part */ | ||
|  |    ){ | ||
|  |        *index = *index<<bitno_rest; | ||
|  |        *index += rest; | ||
|  |    } | ||
|  | 
 | ||
|  |    /*----------------------------------------------------------------*
 | ||
|  |     *  packing of bits into bitstream, i.e., vector of bytes | ||
|  |     *---------------------------------------------------------------*/ | ||
|  | 
 | ||
|  |    void dopack( | ||
|  |        unsigned char **bitstream,  /* (i/o) on entrance pointer to
 | ||
|  |                                           place in bitstream to pack | ||
|  |                                           new data, on exit pointer | ||
|  |                                           to place in bitstream to | ||
|  |                                           pack future data */ | ||
|  |        int index,                  /* (i) the value to pack */ | ||
|  |        int bitno,                  /* (i) the number of bits that the
 | ||
|  |                                           value will fit within */ | ||
|  |        int *pos                /* (i/o) write position in the
 | ||
|  |                                           current byte */ | ||
|  |    ){ | ||
|  |        int posLeft; | ||
|  | 
 | ||
|  |        /* Clear the bits before starting in a new byte */ | ||
|  | 
 | ||
|  |        if ((*pos)==0) { | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |            **bitstream=0; | ||
|  |        } | ||
|  | 
 | ||
|  |        while (bitno>0) { | ||
|  | 
 | ||
|  |            /* Jump to the next byte if end of this byte is reached*/ | ||
|  | 
 | ||
|  |            if (*pos==8) { | ||
|  |                *pos=0; | ||
|  |                (*bitstream)++; | ||
|  |                **bitstream=0; | ||
|  |            } | ||
|  | 
 | ||
|  |            posLeft=8-(*pos); | ||
|  | 
 | ||
|  |            /* Insert index into the bitstream */ | ||
|  | 
 | ||
|  |            if (bitno <= posLeft) { | ||
|  |                **bitstream |= (unsigned char)(index<<(posLeft-bitno)); | ||
|  |                *pos+=bitno; | ||
|  |                bitno=0; | ||
|  |            } else { | ||
|  |                **bitstream |= (unsigned char)(index>>(bitno-posLeft)); | ||
|  | 
 | ||
|  |                *pos=8; | ||
|  |                index-=((index>>(bitno-posLeft))<<(bitno-posLeft)); | ||
|  | 
 | ||
|  |                bitno-=posLeft; | ||
|  |            } | ||
|  |        } | ||
|  |    } | ||
|  | 
 | ||
|  |    /*----------------------------------------------------------------*
 | ||
|  |     *  unpacking of bits from bitstream, i.e., vector of bytes | ||
|  |     *---------------------------------------------------------------*/ | ||
|  | 
 | ||
|  |    void unpack( | ||
|  |        unsigned char **bitstream,  /* (i/o) on entrance pointer to
 | ||
|  |                                           place in bitstream to | ||
|  |                                           unpack new data from, on | ||
|  |                                           exit pointer to place in | ||
|  |                                           bitstream to unpack future | ||
|  |                                           data from */ | ||
|  |        int *index,                 /* (o) resulting value */ | ||
|  |        int bitno,                  /* (i) number of bits used to
 | ||
|  |                                           represent the value */ | ||
|  |        int *pos                /* (i/o) read position in the
 | ||
|  |                                           current byte */ | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    ){ | ||
|  |        int BitsLeft; | ||
|  | 
 | ||
|  |        *index=0; | ||
|  | 
 | ||
|  |        while (bitno>0) { | ||
|  | 
 | ||
|  |            /* move forward in bitstream when the end of the
 | ||
|  |               byte is reached */ | ||
|  | 
 | ||
|  |            if (*pos==8) { | ||
|  |                *pos=0; | ||
|  |                (*bitstream)++; | ||
|  |            } | ||
|  | 
 | ||
|  |            BitsLeft=8-(*pos); | ||
|  | 
 | ||
|  |            /* Extract bits to index */ | ||
|  | 
 | ||
|  |            if (BitsLeft>=bitno) { | ||
|  |                *index+=((((**bitstream)<<(*pos)) & 0xFF)>>(8-bitno)); | ||
|  | 
 | ||
|  |                *pos+=bitno; | ||
|  |                bitno=0; | ||
|  |            } else { | ||
|  | 
 | ||
|  |                if ((8-bitno)>0) { | ||
|  |                    *index+=((((**bitstream)<<(*pos)) & 0xFF)>> | ||
|  |                        (8-bitno)); | ||
|  |                    *pos=8; | ||
|  |                } else { | ||
|  |                    *index+=(((int)(((**bitstream)<<(*pos)) & 0xFF))<< | ||
|  |                        (bitno-8)); | ||
|  |                    *pos=8; | ||
|  |                } | ||
|  |                bitno-=BitsLeft; | ||
|  |            } | ||
|  |        } | ||
|  |    } |