📄 perform_arith_coding.m.svn-base
字号:
function [y,nbr_bits] = perform_arith_coding(xC, dir)% perform_arithmetic_coding_slow - perform adaptive arithmetic coding%% [y,nbr_bits] = perform_arithmetic_coding_slow(x, dir);%% dir=1 for encoding, dir=-1 for decoding.%% Based on 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)if iscell(xC) & length(xC)>1 nbr_bits = 0; for k=1:length(xC) [y{k},nb] = perform_arithmetic_coding(xC{k}, dir); nbr_bits = nbr_bits + nb; end return;endif 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 (nargin < 1); error([Mfile,': function must have input arguments, see help.']);endif (nargout < 1); error([Mfile,': function must have output arguments, see help.']);endif (~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 = 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 Display >= 2 disp([Mfile,': sequence ',int2str(num),' has xType=',int2str(xType)]); end % 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; if Display disp([Mfile,': Sequence ',int2str(num),' of ',int2str(L),' symbols ',... 'encoded using ',int2str(bits),' 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{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};endreturn % end of main function, Arith07%----------------------------------------------------------------------%----------------------------------------------------------------------% --- The functions for binary sequences: EncodeBin and DecodeBin -------% These function may call themselves recursivelyfunction EncodeBin(x,L)global y Byte BitPosglobal high low range ub hc lc sc K codeDisplay=0;x=x(:);if (length(x)~=L); error('EncodeBin: length(x) not equal L.'); end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -