📄 perform_arith_coding.sci
字号:
function [y,nbr_bits] = perform_arith_coding(xC, dir)// perform_arith_coding - perform adaptive arithmetic coding//// [y,nbr_bits] = perform_arith_coding(x, dir);//// dir=1 for encoding, dir=-1 for decoding.//// Interface to the code of (c) Karl Skretting//// Copyright (c) 2008 Gabriel Peyre//// ------------------------------------------------------------------// Arguments:// y a column vector of non-negative integers (bytes) representing// the code, 0 <= y(i) <= 255.// Res a matrix that sum up the results, size is (NumOfX+1)x4// one line for each of the input sequences, the columns are// Res(:,1) - number of elements in the sequence// Res(:,2) - unused (=0)// Res(:,3) - bits needed to code the sequence// Res(:,4) - bit rate for the sequence, Res(:,3)/Res(:,1)// Then the last line is total (which include bits needed to store NumOfX)// x a cell array of column vectors of integers representing the// symbol sequences. (should not be to large integers)// If only one sequence is to be coded, we must make the cell array// like: xC=cell(2,1); xC{1}=x; // where x is the sequence// ------------------------------------------------------------------// Note: this routine is extremely slow since it is all Matlab code// SOME NOTES ON THE FUNCTION// This function is almost like Arith06, but some important changes have// been done. Arith06 is buildt almost like Huff06, but this close connection// is removed in Arith07. This imply that to understand the way Arith06// works you should read the dokumentation for Huff06 and especially the// article on Recursive Huffman Coding. To understand how Arith07 works it is// only confusing to read about the recursive Huffman coder, Huff06.//// Arith07 code each of the input sequences in xC in sequence, the// method used for each sequence depends on what kind (xType) the// sequence is. We have// xType Explanation// 0 Empty sequence (L=0)// 1 Only one symbol (L=1) and x>1// 9 Only one symbol (L=1) and x=0/1// 11 Only one symbol (L=1) and x<0// 2 all symbols are equal, L>1, x(1)=x(2)=...=x(L)>1// 8 all symbols are equal, L>1, x(1)=x(2)=...=x(L)=0/1// 10 all symbols are equal, L>1, x(1)=x(2)=...=x(L)<0// 3 non-negative integers, 0<=x(l)<=1000// 4 not to large integers, -1000<=x(l)<=1000// 5 large non-negative integers possible, 0<=x(l)// 6 also possible with large negative numbers// 7 A binary sequence, x(l)=0/1.// Many functions are defined in this m-file:// PutBit, GetBit read and write bit from/to bitstream// PutABit, GetABit Arithmetic encoding of a bit, P{0}=P{1}=0.5// PutVLIC, GetVLIC Variable Length Integer Code// PutS(x,S,C), GetS(S,C) A symbol x, which is in S, is aritmetic coded// according to the counts given by C.// Ex: A binary variable with the givene probabilities// P{0}=0.8 and P{1}=0.2, PutS(x,[0,1],[4,1]).// PutN(x,N), GetN(N) Arithmetic coding of a number x in range 0<=x<=N where// we assume equal probability, P{0}=P{1}=...=P{N}=1/(N+1)xC = uint32(xC);if dir==1// xC = {xC};end//----------------------------------------------------------------------// Copyright (c) 1999-2001. Karl Skretting. All rights reserved.// Hogskolen in Stavanger (Stavanger University), Signal Processing Group// Mail: karl.skretting@tn.his.no Homepage: http://www.ux.his.no/~karlsk///// HISTORY:// Ver. 1.0 19.05.2001 KS: Function made (based on Arith06 and Huff06)//----------------------------------------------------------------------// these global variables are used to read from or write to the compressed sequenceglobal y Byte BitPos// and these are used by the subfunctions for arithmetic codingglobal high low range ub hc lc sc K codeMfile='Arith07';K=24; // number of bits to use in integers (4 <= K <= 24)Display=0; // display progress and/or results// check input and output arguments, and assign values to argumentsif (argn(2) < 1); error('function must have input arguments, see help.');endif (argn(1) < 1); error('function must have output arguments, see help.');endif dir==0 // (~iscell(xC)) Encode=0;Decode=1; y=xC(:); // first argument is y y=[y;0;0;0;0]; // add some zeros to always have bits availableelse Encode=1;Decode=0; NumOfX = 1; // length(xC);endByte=0;BitPos=1; // ready to read/write into first positionlow=0;high=2^K-1;ub=0; // initialize the codercode=0;// we just select some probabilities which we belive will work quite wellTypeS=[ 3, 4, 5, 7, 6, 1, 9, 11, 2, 8, 10, 0];TypeC=[100, 50, 50, 50, 20, 10, 10, 10, 4, 4, 2, 1];if Encode Res=zeros(NumOfX,4); // initalize the global variables y=zeros(10,1); // put some zeros into y initially // start encoding, first write VLIC to give number of sequences PutVLIC(NumOfX); // now encode each sequence continuously Ltot=0; for num=1:NumOfX x=xC(:); // {num};// x=full(x(:)); // make sure x is a non-sparse column vector L=length(x); Ltot=Ltot+L; y=[y(1:Byte);zeros(50+2*L,1)]; // make more space available in y StartPos=Byte*8-BitPos+ub; // used for counting bits // find what kind of sequenqe we have, save this in xType if (L==0) xType=0; elseif L==1 if (x==0) | (x==1) // and it is 0/1 xType=9; elseif (x>1) // and it is not 0/1 (and positive) xType=1; else // and it is not 0/1 (and negative) xType=11; end else // now find some more info about x maxx=max(x); minx=min(x); rangex=maxx-minx+1; if (rangex==1) // only one symbol if (maxx==0) | (maxx==1) // and it is 0/1 xType=8; elseif (maxx>1) // and it is not 0/1 (and positive) xType=2; else // and it is not 0/1 (and negative) xType=10; end elseif (minx == 0) & (maxx == 1) // a binary sequence xType=7; elseif (minx >= 0) & (maxx <= 1000) xType=3; elseif (minx >= 0) xType=5; elseif (minx >= -1000) & (maxx <= 1000) xType=4; else xType=6; end end // if (L==0) // if sum(xType==[4,6]) // negative values are present I=find(x); // non-zero entries in x Sg=(sign(x(I))+1)/2; // the signs will be needed later, 0/1 x=abs(x); end if sum(xType==[5,6]) // we take the logarithms of the values I=find(x); // non-zero entries in x xa=x; // additional bits x(I)=floor(log2(x(I))); xa(I)=xa(I)-2.^x(I); x(I)=x(I)+1; end // now do the coding of this sequence PutS(xType,TypeS,TypeC); if (xType==1) // one symbol and x=x(1)>1 PutVLIC(x-2); elseif (xType==2) // L>1 but only one symbol, x(1)=x(2)=...=x(L)>1 PutVLIC(L-2); PutVLIC(x(1)-2); elseif sum(xType==[3,4,5,6]) // now 'normalized' sequences: 0 <= x(i) <= 1000 PutVLIC(L-2); M=max(x); PutN(M,1000); // some bits for M // initialize model T=[ones(M+2,1);0]; Tu=flipud((-1:(M+1))'); // (-1) since ESC never is used in Tu context // and code the symbols in the sequence x for l=1:L sc=T(1); m=x(l); hc=T(m+1);lc=T(m+2); if hc==lc // unused symbol, code ESC symbol first hc=T(M+2);lc=T(M+3); EncodeSymbol; // code escape with T table sc=Tu(1);hc=Tu(m+1);lc=Tu(m+2); // symbol with Tu table Tu(1:(m+1))=Tu(1:(m+1))-1; // update Tu table end EncodeSymbol; // code actual symbol with T table (or Tu table) // update T table, MUST be identical in Encode and Decode // this avoid very large values in T even if sequence is very long T(1:(m+1))=T(1:(m+1))+1; if (rem(l,5000)==0) dT=T(1:(M+2))-T(2:(M+3)); dT=floor(dT*7/8+1/8); for m=(M+2):(-1):1; T(m)=T(m+1)+dT(m); end; end end // for l=1:L // this end the "elseif sum(xType==[3,4,5,6])"-clause elseif (xType==7) // L>1 and 0 <= x(i) <= 1 PutVLIC(L-2); EncodeBin(x,L); // code this sequence a special way elseif (xType==8) // L>1 and 0 <= x(1)=x(2)=...=x(L) <= 1 PutVLIC(L-2); PutABit(x(1)); elseif (xType==9) // L=1 and 0 <= x(1) <= 1 PutABit(x(1)); elseif (xType==10) // L>1 and x(1)=x(2)=...=x(L) <= -1 PutVLIC(L-2); PutVLIC(-1-x(1)); elseif (xType==11) // L=1 and x(1) <= -1 PutVLIC(-1-x); end // if (xType==1) // additional information should be coded as well if 0 // first the way it is not done any more if sum(xType==[4,6]) // sign must be stored for i=1:length(Sg); PutABit(Sg(i)); end; end if sum(xType==[5,6]) // additional bits must be stored for i=1:L for ii=(x(i)-1):(-1):1 PutABit(bitget(xa(i),ii)); end end end else // this is how we do it if sum(xType==[4,6]) // sign must be stored EncodeBin(Sg,length(I)); // since length(I)=length(Sg) end if sum(xType==[5,6]) // additional bits must be stored b=zeros(sum(x)-length(I),1); // number of additional bits bi=0; for i=1:L for ii=(x(i)-1):(-1):1 bi=bi+1; b(bi)=bitget(xa(i),ii); end end if (bi~=(sum(x)-length(I))) error([Mfile,': logical error, bi~=(sum(x)-length(I)).']); end EncodeBin(b,bi); // since bi=(sum(x)-length(I)) end end // EndPos=Byte*8-BitPos+ub; // used for counting bits bits=EndPos-StartPos; Res(num,1)=L; Res(num,2)=0; Res(num,3)=bits; if L>0; Res(num,4)=bits/L; else Res(num,4)=bits; end; end // for num=1:NumOfX // flush the arithmetic coder PutBit(bitget(low,K-1)); ub=ub+1; while ub>0 PutBit(~bitget(low,K-1)); ub=ub-1; end // flush is finished y=y(1:Byte); // varargout(1) = {y}; if (nargout >= 2) // now calculate results for the total Res(NumOfX+1,1)=Ltot; Res(NumOfX+1,2)=0; Res(NumOfX+1,3)=Byte*8; if (Ltot>0); Res(NumOfX+1,4)=Byte*8/Ltot; else Res(NumOfX+1,4)=Byte*8; end; // varargout(2) = {Res}; endend // if Encodeif Decode for k=1:K code=code*2; code=code+GetBit; // read bits into code end NumOfX=GetVLIC; // first read number of sequences xC=cell(NumOfX,1); for num=1:NumOfX // find what kind of sequenqe we have, xType, stored first in sequence xType=GetS(TypeS,TypeC); // now decode the different kind of sequences, each the way it was stored if (xType==0) // empty sequence, no more symbols coded x=[]; elseif (xType==1) // one symbol and x=x(1)>1 x=GetVLIC+2; elseif (xType==2) // L>1 but only one symbol, x(1)=x(2)=...=x(L)>1 L=GetVLIC+2; x=ones(L,1)*(GetVLIC+2); elseif sum(xType==[3,4,5,6]) // now 'normalized' sequences: 0 <= x(i) <= 1000 L=GetVLIC+2; x=zeros(L,1); M=GetN(1000); // M is max(x) // initialize model T=[ones(M+2,1);0]; Tu=flipud((-1:(M+1))'); // (-1) since ESC never is used in Tu context // and decode the symbols in the sequence x for l=1:L sc=T(1); range=high-low+1; counts=floor(( (code-low+1)*sc-1 )/range); m=2; while (T(m)>counts); m=m+1; end; hc=T(m-1);lc=T(m);m=m-2; RemoveSymbol; if (m>M) // decoded ESC symbol, find symbol from Tu table sc=Tu(1);range=high-low+1; counts=floor(( (code-low+1)*sc-1 )/range); m=2; while (Tu(m)>counts); m=m+1; end; hc=Tu(m-1);lc=Tu(m);m=m-2; RemoveSymbol; Tu(1:(m+1))=Tu(1:(m+1))-1; // update Tu table end x(l)=m; // update T table, MUST be identical in Encode and Decode // this avoid very large values in T even if sequence is very long T(1:(m+1))=T(1:(m+1))+1; if (rem(l,5000)==0) dT=T(1:(M+2))-T(2:(M+3)); dT=floor(dT*7/8+1/8); for m=(M+2):(-1):1; T(m)=T(m+1)+dT(m); end; end end // for l=1:L // this end the "elseif sum(xType==[3,4,5,6])"-clause elseif (xType==7) // L>1 and 0 <= x(i) <= 1 L=GetVLIC+2; x=DecodeBin(L); // decode this sequence a special way elseif (xType==8) // L>1 and 0 <= x(1)=x(2)=...=x(L) <= 1 L=GetVLIC+2; x=ones(L,1)*GetABit; elseif (xType==9) // L=1 and 0 <= x(1) <= 1 x=GetABit; elseif (xType==10) // L>1 and x(1)=x(2)=...=x(L) <= -1 L=GetVLIC+2; x=ones(L,1)*(-1-GetVLIC); elseif (xType==11) // L=1 and x(1) <= -1 x=(-1-GetVLIC); end // if (xType==0) // additional information should be decoded as well L=length(x); I=find(x); if 0 if sum(xType==[4,6]) // sign must be retrieved Sg=zeros(size(I)); for i=1:length(I); Sg(i)=GetABit; end; // and the signs (0/1) Sg=Sg*2-1; // (-1/1) end if sum(xType==[5,6]) // additional bits must be retrieved xa=zeros(L,1); for i=1:L for ii=2:x(i) xa(i)=2*xa(i)+GetABit; end end x(I)=2.^(x(I)-1); x=x+xa; end else if sum(xType==[4,6]) // sign must be retrieved Sg=DecodeBin(length(I)); // since length(I)=length(Sg) Sg=Sg*2-1; // (-1/1) end if sum(xType==[5,6]) // additional bits must be retrieved bi=sum(x)-length(I); // number of additional bits b=DecodeBin(bi); bi=0; xa=zeros(L,1); for i=1:L for ii=2:x(i) bi=bi+1; xa(i)=2*xa(i)+b(bi); end end x(I)=2.^(x(I)-1); x=x+xa; end end if sum(xType==[4,6]) // sign must be used x(I)=x(I).*Sg; end // now x is the retrieved sequence xC = x; // {num}=x; end // for num=1:NumOfX // varargout(1) = {xC};endif dir==1 nbr_bits = Res(1,3);else // undef for decoding nbr_bits = -1; y = xC; // {1};endendfunction//----------------------------------------------------------------------//----------------------------------------------------------------------// --- The functions for binary sequences: EncodeBin and DecodeBin -------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -