clear
%Read given image data and convert it to double
f = imread('\siva\course\cs445\assign5\text.tif');
[m,n] = size(f);

f = im2double(f);

%run0 and run1 are arrays that store the runlengths of 0 
%and 1. Initialize them to be empty arrays and append the 
%runlength sequence computed row-by-row

run0 = [];
run1 = [];

%Find runlength of each row
for k=1:n
   %the runlength function takes a row (of 0 and 1) and returns 
   %the sequence of runlengths of 0 and 1 in arrays b0 and b1
   
   [b0,b1] = runlength(f(k,:));
   
   %Update the runlength sequence of the whole image by appending the 
   %runlength sequence of current row
   
   run0 = [run0 b0];
   run1 = [run1 b1];
end

%Use the hist command to get the distribution of runlengths of 
%runs of 0 and 1. 
p0 = hist(run0,[1:n]);
p1 = hist(run1,[0:n]);

%Normalize them (by dividing them by the total # runs) 
%to get the probabilities
p0 = p0/length(run0);
p1 = p1/length(run1);

%Plot the probabilities
figure(1)
stem(p0)
figure(2)
stem(p1)

%Find entropy of runlength probabilities. 
%The function entropy does this job. 
h0 = entropy(p0);
h1 = entropy(p1);

%Find average length of a run
l0 = sum(p0.*[1:n]);
l1 = sum(p1.*[0:n]);

%Compute runlength entropy
hrl = (h0+h1)/(l0+l1);

%To compute the actual file size, need the length of the codewords 
%for runlengths of 0 and 1. This is obtained from Table 6.11 and 6.12 
% in the text
white = [8 6 4*ones(1,6) 5*ones(1,4) 6*ones(1,6) 7*ones(1,11) 8*ones(1,35)];
white = [white 5+white 5+white 6+white 7+white 8+white 8+white 8+white 8+white];

black = [10 3 2*ones(1,2) 3 4*ones(1,2) 5*ones(1,2) 6*ones(1,2) 7*ones(1,2) 8*ones(1,2) 9 10*ones(1,3) 11*ones(1,7) 12*ones(1,38)];
black = [black 10+black 11+black 11+black 11+black 11+black 11+black 11+black 12+black];


%Finally, compute the total number of bits

%bits required for encoding runlengths of 0
%Note that p0 was normalized earlier. 
%We un-normalize it because we need the actual number 
%of runs for a given runlength
total_bits = sum((length(run0)*p0).*black(2:n+1));    

%bits required for encoding runlengths of 1
%Again, first un-normalize p1
total_bits = total_bits + sum((length(run1)*p1).*white(1:n+1));

%Bits for the end-of-line (EOL) symbol, one EOL (12 bits) for each row
total_bits = total_bits + m*12; 

%Bits for end of an image (6 EOL symbols)
total_bits = total_bits + 6*12

%Number of bits reqd. per pixel using this scheme
total_bits/(n*m)

%Theoretical value given by runlength entropy
hrl