⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arith06.m

📁 算术编码
💻 M
📖 第 1 页 / 共 2 页
字号:
      PutABit(0);      % indicate that M0==0
   else
      PutABit(1);      % indicate that M0~=0
      PutVLIC(M0);     % some bits for M0
      x=x-M0;          % translate x
   end
   M=max(x);
   PutVLIC(M);         % 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 EncodeVector and DecodeVector
      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
   EndPos=Byte*8-BitPos;     % used for counting bits
   bits=EndPos-StartPos;
end
return    % end of EncodeVector

function x = DecodeVector
global y Byte BitPos
global high low range ub hc lc sc K code

if GetABit
   x1=DecodeVector;
   x2=DecodeVector;
   L=length(x1)+length(x2);
   xm=median([x1;x2]);
   x=zeros(L,1);
   x(1)=x2(1);
   i1=0;i2=1;
   for i=2:L
      if (x(i-1) <= xm) 
         i1=i1+1; x(i)=x1(i1);
      else
         i2=i2+1; x(i)=x2(i2);
      end
   end
else
   L=GetVLIC;
   if (L>1)      % the normal (?) situation
      x=zeros(L,1);
      if GetABit
         M0=GetVLIC;   
      else
         M0=0;
      end
      M=GetVLIC;   
      % 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;
         count=floor(( (code-low+1)*sc-1 )/range);
         m=2; while (T(m)>count); 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;
            count=floor(( (code-low+1)*sc-1 )/range);
            m=2; while (Tu(m)>count); 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 EncodeVector and DecodeVector
         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
      if M0~=0
         x=x+M0;
      end
   elseif L==0
      if GetABit
         % length 0 was not confirmed
         La=GetVLIC;  % actual length
         x=GetVLIC*ones(La,1);
      else
         x=[];    % this was really a length 0 sequence
      end
   elseif L==1
      x=GetVLIC;
   else
      error('DecodeVector: illegal length of sequence.');
   end
end
return    % end of DecodeVector


% ------- Other subroutines ------------------------------------------------

% Functions to write and read a Variable Length Integer Code word
% This is a way of coding non-negative integers that uses fewer 
% bits for small integers than for large ones. The scheme is:
%   '00'   +  4 bit  - integers from 0 to 15
%   '01'   +  8 bit  - integers from 16 to 271
%   '10'   + 12 bit  - integers from 272 to 4367
%   '110'  + 16 bit  - integers from 4368 to 69903
%   '1110' + 20 bit  - integers from 69940 to 1118479
%   '1111' + 24 bit  - integers from 1118480 to 17895695
%   not supported  - integers >= 17895696 (=2^4+2^8+2^12+2^16+2^20+2^24)
function PutVLIC(N)
global y Byte BitPos
global high low range ub hc lc sc K code
if (N<0)
   error('Arith06-PutVLIC: Number is negative.'); 
elseif (N<16)
   PutABit(0);PutABit(0);
   for (i=4:-1:1); PutABit(bitget(N,i)); end;
elseif (N<272)
   PutABit(0);PutABit(1);
   N=N-16;
   for (i=8:-1:1); PutABit(bitget(N,i)); end;
elseif (N<4368)
   PutABit(1);PutABit(0);
   N=N-272;
   for (i=12:-1:1); PutABit(bitget(N,i)); end;
elseif (N<69940)
   PutABit(1);PutABit(1);PutABit(0);
   N=N-4368;
   for (i=16:-1:1); PutABit(bitget(N,i)); end;
elseif (N<1118480)
   PutABit(1);PutABit(1);PutABit(1);PutABit(0);
   N=N-69940;
   for (i=20:-1:1); PutABit(bitget(N,i)); end;
elseif (N<17895696)
   PutABit(1);PutABit(1);PutABit(1);PutABit(1);
   N=N-1118480;
   for (i=24:-1:1); PutABit(bitget(N,i)); end;
else
   error('Arith06-PutVLIC: Number is too large.'); 
end
return

function N=GetVLIC
global y Byte BitPos
global high low range ub hc lc sc K code
N=0;
if GetABit
   if GetABit
      if GetABit
         if GetABit
            for (i=1:24); N=N*2+GetABit; end;
            N=N+1118480;
         else
            for (i=1:20); N=N*2+GetABit; end;
            N=N+69940;
         end
      else
         for (i=1:16); N=N*2+GetABit; end;
         N=N+4368;
      end
   else
      for (i=1:12); N=N*2+GetABit; end;
      N=N+272;
   end
else
   if GetABit
      for (i=1:8); N=N*2+GetABit; end;
      N=N+16;
   else
      for (i=1:4); N=N*2+GetABit; end;
   end
end
return

% Aritmetic coding of a bit, probability is 0.5 for both 1 and 0
function PutABit(Bit)
global y Byte BitPos
global high low range ub hc lc sc K code
sc=2;
if Bit 
   hc=1;lc=0; 
else 
   hc=2;lc=1; 
end
EncodeSymbol;  % code the bit
return
   
function Bit=GetABit
global y Byte BitPos
global high low range ub hc lc sc K code
range=high-low+1;
sc=2;
count=floor(( (code-low+1)*sc-1 )/range);
if (1>count)
   Bit=1;hc=1;lc=0;
else
   Bit=0;hc=2;lc=1;
end
RemoveSymbol;
return;

% The EncodeSymbol function encode a symbol, (correspond to encode_symbol page 149)
function EncodeSymbol
global y Byte BitPos 
global high low range ub hc lc sc K code
range=high-low+1;
high=low+floor(((range*hc)/sc)-1);
low=low+floor((range*lc)/sc);
while 1          % for loop on page 149
   if bitget(high,K)==bitget(low,K)
      PutBit(bitget(high,K));
      while ub > 0
         PutBit(~bitget(high,K));
         ub=ub-1;
      end
   elseif (bitget(low,K-1) & (~bitget(high,K-1)))
      ub=ub+1;
      low=bitset(low,K-1,0);
      high=bitset(high,K-1,1);
   else
      break
   end
   low=bitset(low*2,K+1,0);
   high=bitset(high*2+1,K+1,0);
end
return

% The RemoveSymbol function removes (and fill in new) bits from
% file, y, to code
function RemoveSymbol 
global y Byte BitPos 
global high low range ub hc lc sc K code
range=high-low+1;
high=low+floor(((range*hc)/sc)-1);
low=low+floor((range*lc)/sc);
while 1
   if bitget(high,K)==bitget(low,K)
      % do nothing (shift bits out)
   elseif (bitget(low,K-1) & (~bitget(high,K-1)))
      code=bitset(code,K-1,~bitget(code,K-1));     % switch bit K-1
      low=bitset(low,K-1,0);
      high=bitset(high,K-1,1);
   else
      break
   end
   low=bitset(low*2,K+1,0);
   high=bitset(high*2+1,K+1,0);
   code=bitset(code*2+GetBit,K+1,0);
end
if (low > high); error('low > high'); end;
return

% Functions to write and read a Bit
function PutBit(Bit)
global y Byte BitPos
BitPos=BitPos-1;
if (~BitPos); Byte=Byte+1; BitPos=8; end; 
y(Byte) = bitset(y(Byte),BitPos,Bit);
return
   
function Bit=GetBit
global y Byte BitPos
BitPos=BitPos-1;
if (~BitPos); Byte=Byte+1; BitPos=8; end; 
Bit=bitget(y(Byte),BitPos);
return;
   
% this function is a variant of the standard hist function
function Hi=IntHist(W,i1,i2);
W=W(:);
L=length(W);
Hi=zeros(i2-i1+1,1);
if (i2-i1)>50
   for l=1:L
      i=W(l)-i1+1;
      Hi(i)=Hi(i)+1;
   end
else
   for i=i1:i2
      I=find(W==i);
      Hi(i-i1+1)=length(I);
   end
end
return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -