?? code_huffman.m
字號:
function B=Code_Huffman(A)
%根據huffman編碼表對量化后的數據編碼
%依次輸入DC系數差值(A中DC系數已做過差分)和AC系數的典型Huffman表
%只處理8×8DCT系數量化矩陣,每個A都是8*8
DC_Huff={'00','010','011','100','101','110','1110','11110','111110','1111110','11111110','111111110'};
%由于AC系數數據量較大,我們將它保存在AC_Huff.txt文件中,將它讀入元胞數組中
fid=fopen('AC_Huff.txt','r');
AC_Huff=cell(16,10);
for a=1:16
for b=1:10
temp=fscanf(fid,'%s',1);%以行為單位讀取,保存在temp中
AC_Huff(a,b)={temp};%代表每行的一組數據
end
end
fclose(fid);
%對A中的數據進行Zig-Zag掃描,保存在數組Z中
i=1;
for a=1:15
if a<=8
for b=1:a
if mod(a,2)==1
Z(i)=A(b,a+1-b);
i=i+1;
else
Z(i)=A(a+1-b,b);
i=i+1;
end
end
else
for b=1:16-a
if mod(a,2)==0
Z(i)=A(9-b,a+b-8);
i=i+1;
else
Z(i)=A(a+b-8,9-b);
i=i+1;
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%先對DC差值系數編碼:前綴碼SSSS+尾碼
%dc為其Huffman編碼
if Z(1)==0
sa.s=DC_Huff(1); %%%size分量存放前綴碼
sa.a='0'; %%%amp分量存放尾碼
dc=strcat(sa.s,sa.a);
else
n=fix(log2(abs(Z(1))))+1;
sa.s=DC_Huff(n);
sa.a=binCode(Z(1));
dc=strcat(sa.s,sa.a);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%再對AC系數進行行程編碼,保存在結構體數組rsa中
if isempty(find(Z(2:end))) %如果63個交流系數全部為0,rsa系數全部為0
rsa(1).r=0; %行程runlength
rsa(1).s=0; %碼長size
rsa(1).a=0; %二進制編碼
else
T=find(Z); %找出Z中非零元素的下標
T=[0 T(2:end)]; %為統一處理將第一個下標元素置為0
i=1; % i為rsa結構體的下標
%從第二個元素即第一個交流元素開始處理
j=2;
while j<=length(T)
t=fix((T(j)-1-T(j-1))/16); %判斷下標間隔是否超過16
if t==0 %如果小于16,較簡單
rsa(i).r=T(j)-T(j-1)-1;
rsa(i).s=fix(log2(abs(Z(T(j)))))+1;
rsa(i).a=Z(T(j));
i=i+1;
else %如果超過16,需要處理(15,0)的特殊情況
for n=1:t %可能出現t組(15,0)
rsa(i)=struct('r',15,'s',0,'a',0);
i=i+1;
end
%接著處理剩余的那部分
rsa(i).r=T(j)-1-16*t;
rsa(i).s=fix(log2(abs(Z(T(j)))))+1;
rsa(i).a=Z(T(j));
i=i+1;
end
j=j+1;
end
%判斷最后一個非零元素是否為Z中最后一個元素
if T(end)<64
rsa(i).r=0;
rsa(i).s=0;
rsa(i).a=0;
end %以EOB結束
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%---------通過查表獲取AC系數的Huffman編碼
B=dc; %B初始化為直流系數編碼
for n=1:length(rsa)
if rsa(n).r==0&rsa(n).s==0&rsa(n).a==0
ac(n)={'1010'};
elseif rsa(n).r==15&rsa(n).s==0&rsa(n).a==0
ac(n)={'11111111001'};
else
t1=AC_Huff(rsa(n).s+1,rsa(n).s);
t2=binCode(rsa(n).a);
ac(n)=strcat(t1,t2);
end
B=strcat(B,ac(n));
end
%%%-------------Subfunction----------%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function s=binCode(a)
%求任意整數的二進制碼
if a>=0
s=dec2bin(a);
else
%求a的反碼,返回“01”字符串,按位取反
s=dec2bin(abs(a));
for t=1:numel(s)
if s(t)=='0'
s(t)='1';
else s(t)='0';
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -