function CODE=huffman(p)
%HUFFMAN Builds a variable-length Huffman code for a symbol source.
% CODE=HUFFMAN(P) returns a Huffman code as binary string in
% cell array CODE for input symbol probability vector P. Each word
% in CODE corresponds to a symbol whose probability is at the
% corresponding index of P.
%
% Based on huffman5 by Sean Danaher, University of northumbria,
% Newcastle UK. Available at the MATLAB Central File Exchage:
% Category General DSP in Signal Processing and Communications.
% Check the input arguments for reasonableness
error(nargchk(1,1,nargin));
if(ndims(p)~=2 | (min(size(p))>1) | ~isreal(p) | ~isnumeric(p))
error('P must be a real numeric vector.');
end
% Global variable surviving all recursions of function 'makecode'
global CODE
CODE=cell(length(p),1); %Init the global cell array
if length(p)>1 %When more than one symbol...
p=p/sum(p); %Normalize the input probabilities
s=reduce(p); %Do Huffman source symbol reductions
makecode(s,[]); %Recursively generate the code
else
CODE={'1'}; %Else, trivial one symbol case!
end
%--------------------------------------------------------------------%
function s=reduce(p)
% Create a Huffman source reduction tree in a MATLAB cell structure
% by performing source symbol reductions until there are only two
% reduce symbols remaining
s=cell(length(p),1);
% Generate a strarting tree with symbol nodes 1, 2, 3, ...to
% reference the symbol probabilities.
for i=1:length(p)
s{i}=i;
end
while size(s,1)>2
[p,i]=sort(p); %Sort the symbol probabilities
p(2)=p(2)+p(1); %Merge the 2 lowest probabilities
p(1)=[]; %and prune the lowest one
s=s(i); %Reorder tree for new probabilities
s{2}={s{1},s{2}}; %and merge & prune its nodes
s(1)=[]; %to match the probabilities
end
%----------------------------------------------------------------------%
function makecode(sc,codeword)
% Scan the nodes of a Huffman source reduction tree recursively to
% generate the indicated variable lenth code words.
% Global variable surviving all recursive calls
global CODE
if isa(sc,'cell')
makecode(sc{1},[codeword 0]);
makecode(sc{2},[codeword 1]);
else
CODE{sc}=char('0'+codeword);
end
function y=mat2huff(x)
%MAT2HUFF Huffman encodes a matrix.
% Y=MAT2HUFF(X) Huffman encodes matrix X using symbol
% probabilities in unit-width histogram bins between X's minimum
% and maximum values. The encoded data is returned as a structure
% Y:
% Y.code The Huffman-encoded values of X, stored in
% a uint16 vector. The other fields of Y contain
% additional decoding information, including:
% Y.min The minimum value of X plus 32768
% Y.size The size of X
% Y.hist The histogram of X
% If X is logical, uint8, uint16, uint32, int8, int16,or double,
% with integer values, it can be input directly to MAT2HUFF. The
% minimum value of X must be representable as an int16
%
% If X is double with non-integer values --- for example, an image
% with values between 0 and 1---first scale X to an appropriate
% integer range before the call. For example, use Y=
% MAT2HUFF(255*X) for 256 gray level encoding.
%
% NOTE: The number of Huffman code words is round(max(X(:)))-
% round(min(X(:)))+1. You may need to scale input X to generate
% codes of reasonable length. The maximum row or column dimension
% of X is 65535.
%
% See also HUFFMAN2MAT
if ndims(x)~=2 | ~isreal(x) | (~isnumeric(x) & ~islogical(x))
errror('X must be a 2-D real numeric or logical matrix');
end
% Store the size of input x.
y.size=uint32(size(x));
% Find the range of x values and store its minimum value biased
% by+32768 as a UINT16.
x=round(double(x));
xmin=min(x(:));
xmax=max(x(:));
pmin=double(int16(xmin));
pmin=uint16(pmin+32768);
y.min=pmin;
% Compute the input histogram between xmin and xmax with uint
% width bins, scale to UINT16, and store.
x=x(:)';
h=histc(x,xmin:xmax);
if max(h)>65535
h=65535*h/max(h);
end
h=uint16(h);
y.hist=h;
% Code the input matrix and store the result.
map=huffman(double(h)); %Make Huffman code map
hx=map(x(:)-xmin+1); %Map image
hx=char(hx)';
hx=hx(:)';
hx(hx==' ')=[]; %Remove blanks
% ysize=ceil(length(hx)/16); %Compute encoded size
% hx16=repmat('0',1,ysize*16); %pre-allocate modulo-16 vector
% hx16(1:length(hx))=hx; %Make hx modulo-16 in length
% hx16=reshape(hx16,16,ysize); %Reshape to 16-character words
% hx16=hx16'-'0'; %Convert binary string to decimal
% twos=pow2(15:-1:0);
% y.code=uint16(sum(hx16.*twos(ones(ysize,1),:),2))';
y.code=hx;
%test
%本程序用于测试
f2=uint8([2 3 4 2;3 2 4 4;2 2 1 2;1 1 2 2])
whos('f2')
c=huffman(hist(double(f2(:)),4))
h1f2=c(f2(:))'
whos('h1f2')
h2f2=char(h1f2)'
whos('h2f2')
h2f2=h2f2(:)
h2f2(h2f2==' ')=[]
whos('h2f2')
h3f2=mat2huff(f2)
whos('h3f2')
hcode=h3f2.code
whos('hcode')
dec2bin(hcode)
f=imread('Tracy.tif');
c=mat2huff(f);
cr1=imratio(f,c)
save SqueezeTracy c;
cr2=imratio('Tracy.tif','SqueezeTracy.mat')