/* * @(#) arithpck.h - Arithmetic encode/decode operations library header. * (c) 1998 Ivan Maidanski http://ivmai.chat.ru * Freeware function library source. All rights reserved. ** * Language: ANSI C * Tested with: Microsoft Visual C++ (R) v4.2, Borland C/C++ v3.1 * Last modified: 1998-08-04 20:05:00 GMT+04:00 */ /* Library source file: arithpck.c */ /* ARITHPCK_VALUE_TYPE, ARITHPCK_SYM_TYPE, ARITHPCK_FREQ_TYPE, ARITHPCK_FREQ_MAX, ARITHSTART(), arithinitinput(), arithencode(), arithdecode(), arithpacksym(), arithunpacksym(), ARITHPACKVALUE(), ARITHUNPACKVALUE(), arithoutput(), ARITHOUTFINISH(), arithflushfinish(), FREQMODELALLOC(), FREQMODELFREE(), freqmodelstart(), freqmodelupdate(), freqmodelsearch(), freqmodelgetcum(), freqmodelindex() */ #ifndef _ARITHPCK_H_INCLUDED #define _ARITHPCK_H_INCLUDED /* Notes: declare your own ARITHPCK_VALUE_TYPE macro to override predefined encoded/decoded value type, declare your own ARITHPCK_SYM_TYPE macro to override predefined symbol/index type, declare your own ARITHPCK_FREQ_TYPE macro to override predefined frequence type, declare your own ARITHPCK_FREQ_MAX macro to override predefined maximum frequence constant. */ /* declaration section */ /* ARITHPCK_VALUE_TYPE used for encoded/decoded value representation */ #ifndef ARITHPCK_VALUE_TYPE #define ARITHPCK_VALUE_TYPE unsigned long /* must have no sign */ #endif /* ARITHPCK_SYM_TYPE used for symbol/index representation in frequence models */ #ifndef ARITHPCK_SYM_TYPE #define ARITHPCK_SYM_TYPE unsigned int #endif /* ARITHPCK_FREQ_TYPE used for frequence value representation */ #ifndef ARITHPCK_FREQ_TYPE #define ARITHPCK_FREQ_TYPE unsigned short #endif /* ARITHPCK_FREQ_MAX used for frequence overflow check */ #ifndef ARITHPCK_FREQ_MAX /* assuming ARITHPCK_FREQ_TYPE has no sign */ #define ARITHPCK_FREQ_MAX ((ARITHPCK_FREQ_TYPE)~(ARITHPCK_FREQ_TYPE)0) #endif /* ARITHSTART() - initiate arithmetic encoding/decoding (low/high internal values) */ /* #define void ARITHSTART(ARITHPCK_VALUE_TYPE &llow, ARITHPCK_VALUE_TYPE &lhigh); */ /* arithinitinput() - initiate (at arithmetic decoder start) input *pinput (which must be set to 0 or 1 before) for decoding, filling it with incode codes, return flag that operation is not completed (i.e. this function must be called again with the next incode code) */ int arithinitinput(ARITHPCK_VALUE_TYPE *pinput, unsigned char incode); /* arithencode() - encode value (which has cumlower cumulative frequence and the successor value has cumupper+1 cumulative frequence and maxcum+1 is the total cumulative frequence) into low/high internal values */ /* note: also used internally by arithpacksym(), arithunpacksym(), ARITHPACKVALUE() and ARITHUNPACKVALUE() */ void arithencode(ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_VALUE_TYPE cumlower, ARITHPCK_VALUE_TYPE cumupper, ARITHPCK_VALUE_TYPE maxcum); /* arithdecode() - decode value i.e. get value approximate cumulative frequence (which is greater than or equal to the value exact cumulative frequence and less than the successor value exact cumulative frequence) from input using (without update) low/high internal values (and if maxcum+1 is the total cumulative frequence), return value approximate cumulative frequence */ /* note: also used internally by arithunpacksym() and ARITHUNPACKVALUE() */ ARITHPCK_VALUE_TYPE arithdecode(ARITHPCK_VALUE_TYPE low, ARITHPCK_VALUE_TYPE high, ARITHPCK_VALUE_TYPE input, ARITHPCK_VALUE_TYPE maxcum); /* arithpacksym() - encode symbol sym using (and updating) frequence model (which has symtbl/freqtbl tables, symbol frequence grow scale and *pmaxcum+1 is the sum of symbols frequences) into low/high internal values */ void arithpacksym(ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_SYM_TYPE sym, ARITHPCK_SYM_TYPE symtbl[], ARITHPCK_FREQ_TYPE freqtbl[], ARITHPCK_FREQ_TYPE scale, ARITHPCK_VALUE_TYPE *pmaxcum); /* arithunpacksym() - decode symbol from input using (and updating) frequence model (which has symtbl/freqtbl tables, symbol frequence grow scale and *pmaxcum+1 is the sum of symbols frequences) and low/high internal values, return decoded symbol */ ARITHPCK_SYM_TYPE arithunpacksym(ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_VALUE_TYPE input, ARITHPCK_SYM_TYPE symtbl[], ARITHPCK_FREQ_TYPE freqtbl[], ARITHPCK_FREQ_TYPE scale, ARITHPCK_VALUE_TYPE *pmaxcum); /* ARITHPACKVALUE() - encode value (which is within the range of 0..maxval) into low/high internal values */ /* #define void ARITHPACKVALUE(ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_VALUE_TYPE value, ARITHPCK_VALUE_TYPE maxval); */ /* ARITHUNPACKVALUE() - decode lvalue (which is within the range of 0..maxval) from input using (and updating) low/high internal values */ /* #define void ARITHUNPACKVALUE(ARITHPCK_VALUE_TYPE &lvalue, ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_VALUE_TYPE input, ARITHPCK_VALUE_TYPE maxval); */ /* arithoutput() - output bits of encoded value into *poutcode (on arithmetic coder start *poutcode must be set to 0 or 1) from (with update) low/high internal values and advance input code from *pincode to *pinput (only if pinput!=NULL) using the sum of all the symbols updated frequences newmaxcum+1, return flag that *poutcode is full and *pincode is empty (only if pinput!=NULL) and that the operation is not completed (i.e. this function must be called again with *poutcode set to 0 or 1 and *pincode set to the new input code (only if pinput!=NULL)) */ /* note: also used internally by ARITHOUTFINISH() */ int arithoutput(unsigned char *poutcode, ARITHPCK_VALUE_TYPE *pinput, unsigned char *pincode, ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh, ARITHPCK_VALUE_TYPE newmaxcum); /* ARITHOUTFINISH() - output tail bits (finish (or restart) arithmetic encoding) into *poutcode from (with update) low/high internal values and advance input code from *pincode to *pinput (only if pinput!=NULL), return flag that *poutcode is full and *pincode is empty (only if pinput!=NULL) and that the operation is not completed (i.e. this function must be called again with *poutcode set to 0 or 1 and *pincode set to the new input code (only if pinput!=NULL)) */ /* #define int ARITHOUTFINISH(unsigned char *poutcode, ARITHPCK_VALUE_TYPE *pinput, unsigned char *pincode, ARITHPCK_VALUE_TYPE *plow, ARITHPCK_VALUE_TYPE *phigh); */ /* arithflushfinish() - prepare for flushing output remaining bits in *poutcode and advance input code from *pincode to *pinput (only if pinput!=NULL), return flag that remaining bits present (and prepared) in *poutcode (and input advanced (only if pinput!=NULL)) */ int arithflushfinish(unsigned char *poutcode, ARITHPCK_VALUE_TYPE *pinput, unsigned char *pincode); /* FREQMODELALLOC() - allocate frequence model buffers (i.e. index-to-symbol translation table lsymtbl and ordered index-to-frequence translation table lfreqtbl where maxsym+1 is the number of symbols), return -1 on error and 0 otherwise */ /* note: to use FREQMODELALLOC() include for NULL macro & malloc() prototype */ /* #define int FREQMODELALLOC(ARITHPCK_SYM_TYPE (&lsymtbl)[], ARITHPCK_FREQ_TYPE (&lfreqtbl)[], ARITHPCK_SYM_TYPE maxsym); */ /* FREQMODELFREE() - free frequence model buffers (i.e. index-to-symbol translation table lsymtbl and ordered index-to-frequence translation table lfreqtbl) and set buffer pointers to NULL */ /* note: to use FREQMODELFREE() include for NULL macro & free() prototype */ /* #define void FREQMODELFREE(ARITHPCK_SYM_TYPE (&lsymtbl)[], ARITHPCK_FREQ_TYPE (&lfreqtbl)[]); */ /* freqmodelstart() - initiate frequence model (i.e. symtbl/freqtbl tables and the sum of all the symbol initial frequences *pmaxcum+1) where maxsym+1 is the number of symbols */ void freqmodelstart(ARITHPCK_SYM_TYPE symtbl[], ARITHPCK_FREQ_TYPE freqtbl[], ARITHPCK_VALUE_TYPE *pmaxcum, ARITHPCK_SYM_TYPE maxsym); /* freqmodelupdate() - update frequence model (i.e. symtbl/freqtbl tables and the sum of all the symbol frequences *pmaxcum+1) for the symbol with specified index using specified scale */ /* note: also used internally by arithpacksym() and arithunpacksym() */ void freqmodelupdate(ARITHPCK_SYM_TYPE symtbl[], ARITHPCK_FREQ_TYPE freqtbl[], ARITHPCK_VALUE_TYPE *pmaxcum, ARITHPCK_FREQ_TYPE scale, ARITHPCK_SYM_TYPE index); /* freqmodelsearch() - get index of symbol in the frequence model symtbl table, return index */ /* note: also used internally by arithpacksym() */ ARITHPCK_SYM_TYPE freqmodelsearch(ARITHPCK_SYM_TYPE sym, ARITHPCK_SYM_TYPE symtbl[]); /* freqmodelgetcum() - get symbol (with specified index) cumulative frequence *pcumlower and the successor cumulative frequence *pcumupper+1 using the frequence model freqtbl table */ /* note: also used internally by arithpacksym() */ void freqmodelgetcum(ARITHPCK_VALUE_TYPE *pcumlower, ARITHPCK_VALUE_TYPE *pcumupper, ARITHPCK_FREQ_TYPE freqtbl[], ARITHPCK_SYM_TYPE index); /* freqmodelindex() - get index of the decoded symbol with the approximate cumulative frequence *pcumlower and get the symbol exact cumulative frequence *pcumlower and the successor cumulative frequence *pcumupper+1 (using the frequence model freqtbl table), return index */ /* note: also used internally by arithunpacksym() */ ARITHPCK_SYM_TYPE freqmodelindex(ARITHPCK_VALUE_TYPE *pcumlower, ARITHPCK_VALUE_TYPE *pcumupper, ARITHPCK_FREQ_TYPE freqtbl[]); /* macro definition section */ #define ARITHSTART(llow,lhigh) \ ((lhigh=(ARITHPCK_VALUE_TYPE)~(ARITHPCK_VALUE_TYPE)0), \ (llow=(ARITHPCK_VALUE_TYPE)0)) #define ARITHPACKVALUE(plow,phigh,value,maxval) \ (arithencode(plow,phigh,value,value,maxval)) #define ARITHUNPACKVALUE(lvalue,plow,phigh,input,maxval) \ ((lvalue=arithdecode(*(plow),*(phigh),input,maxval)), \ arithencode(plow,phigh,lvalue,lvalue,maxval)) #define ARITHOUTFINISH(poutcode,pinput,pincode,plow,phigh) \ (arithoutput(poutcode,pinput,pincode,plow,phigh, \ (ARITHPCK_VALUE_TYPE)~(ARITHPCK_VALUE_TYPE)0)) #define FREQMODELALLOC(lsymtbl,lfreqtbl,maxsym) \ ((lsymtbl=(ARITHPCK_SYM_TYPE *)malloc((maxsym) \ *sizeof(ARITHPCK_SYM_TYPE)+sizeof(ARITHPCK_SYM_TYPE)))!=NULL? \ (lfreqtbl=(ARITHPCK_FREQ_TYPE *)malloc((maxsym) \ *sizeof(ARITHPCK_FREQ_TYPE)+sizeof(ARITHPCK_FREQ_TYPE)))!=NULL? \ 0 : (free((void *)(lsymtbl)),(lsymtbl=NULL),-1) : ((lfreqtbl=NULL),-1)) #define FREQMODELFREE(lsymtbl,lfreqtbl) \ (((lfreqtbl)!=NULL? (free((void *)(lfreqtbl)),lfreqtbl=NULL) : NULL), \ ((lsymtbl)!=NULL? (free((void *)(lsymtbl)),lsymtbl=NULL) : NULL)) #endif