%  Heidi Thornquist
%  Christy Hard

%  This program will compute the Haar transform for the selected
%  image.  The images will be shown upon request of the user.  There
%  are two types of blocking employed by this method:  full matrix
%  and blocked matrix.  There are three types of quantizing schemes
%  implemented:  uniform, adaptive, and statistical (Lloyd-Max).

%clear;

%------------------Choose Image-------------------------%

imnum = menu('Choose an Image','Baby','Building','Girl');
switch imnum
case 1
   imfile = 'Images/baby.tif';
case 2
   imfile = 'Images/building.tif';
case 3
   imfile = 'Images/kgirl.tif';
otherwise
   disp('Unknown image')
end  

[A,map] = tiffread(imfile);
n = length(A);
n2 = log2(n);
Im = A;

prntimin = menu('Display Input Images','Yes','No');
if prntimin == 1
   % Output the original image
      figure(1);
      makeImage(Im);
      title('Original Image');
end

%----------------Compute Haar Transform on Image Matrix------------------%
%-------------------Obtain Bit Mask for Quantization---------------------%

% Obtain information from user about bit mask
lev = input('Number of quantization levels: ');
for i = 1:lev+1
   lout = sprintf('How many bits for level %d: ',i);
   lnum = input(lout);
   if lnum > 0      
      q(i) = lnum - 1;
   else
      q(i) = 0;
   end     
end

% Obtain type of transform blocking
blktype = menu('Haar Transform Blocking','Full Matrix','Blocked Matrix');
switch blktype
case 1
   % Haar transform for full matrix
   fignum = 2;
   for i = lev:-1:1
      num = 2^(i+n2-lev);
      Im(1:num,1:num) = haar_col(haar_row(Im(1:num,1:num)));       
      if prntimin == 1
         % Output the images created by the Haar transform
         figure(fignum);
         makeImage(Im);
         fignum = fignum + 1;       
      end
   end
   qtype = menu('Quantization Type','Uniform','Adapted','Statistical');
   switch qtype
   case 1
      [M,nbits] = makeBitMask('u',n,q);
   case 2
      [M,nbits] = makeBitMask('a',n,q);
   case 3;
      [M,nbits] = makeBitMask('a',n,q);
   otherwise
      disp('Unknown quantization type')
   end  
case 2 
   % Haar transform for blocked matrix
   fignum = 2;
   lev = 3;
   for k = lev:-1:1
      for i = 1:8:n
         for j = 1:8:n
            num = 2^k;
            Im(i:i+num-1,j:j+num-1) = haar_col(haar_row(Im(i:i+num-1,j:j+num-1)));
         end
      end
      if prntimin == 1
         % Output the images created by the blocked Haar transform
         figure(fignum);
         makeImage(Im);
         fignum = fignum + 1;
      end
   end
   [M,nbits] = makeBitMask('b',n,q(1:lev+1));
otherwise
   disp('Unknown blocking type')
end

%-------------------Quantize Image Using Bit Mask Matrix--------------------%

% Normalize transformed image, quantize image, then save it to binary file. 
% Then image is retrieved from the binary file and inverse quantized.

% Normalize matrix
%[Im,temp2,dtemp] = nrmlMat(Im)
[Im,div] = nrmlMat2(Im,lev);

% Quantize matrix
if qtype==3

      % Use statistical quantizing method
      [Im,grk,gtk] = statcom2(Im,q);
      BinOut(Im,M,imnum);
      Im = istatcom(Im,q,grk);
else
      % Use adaptive or uniform quantizing method
      Im = Quntze(Im,M);
      BinOut(Im,M,imnum);
      Im = IQuntze(Im,M);                
end

Im = inrmlMat2(Im,lev,div);
%Im = inrmlMat(Im,temp2,dtemp);

%------------------------Haar Inverse Transform----------------------------%


switch blktype
case 1
   % Haar transform for full matrix
   for i = 1:lev
      num = 2^(n2-lev+i);
      Im(1:num,1:num) = ihaar_row(ihaar_col(Im(1:num,1:num)));     
   end
case 2
   % Haar transform for blocked matrix
   for k = 1:lev
      for i = 1:8:n
         for j = 1:8:n
            num = 2^k;
            Im(i:i+num-1,j:j+num-1) = ihaar_row(ihaar_col(Im(i:i+num-1,j:j+num-1)));
         end
      end
   end
otherwise
   disp('Unknown blocking type')
end

% Print out transformed and quantized image if requested by user
prntimout = menu('Display Output Image','Yes','No');

if prntimout == 1 
   % Output the image created by the Haar transform using quantization
   figure(fignum);
   makeImage(Im);
end

MSE = (1/n)^2*sum((A(:)-Im(:)).^2)
PSNR = 10*log10(255^2/MSE)