%
% TwoHypoDisparity.m
%
% The two-hypothesis scheme is where two integer disparity 
% values are specified along with the respective indices of the 
% reference images that should be used for prediction.  The target 
% image is predicted by disparity compensating the specified 
% reference image and averaging the result.
%

function [R, D, pdfout, predBlock] = ...
	TwoHypoDisparity(Itarget, Irefs, lambda, ...
					 indices, pdfin, ...
					 rowBlock, colBlock, ...
					 blocksize)

R = 0;
D = 0;
J = inf;
r = (rowBlock-1)*blocksize + 1;
c = (colBlock-1)*blocksize + 1;
targetBlock = GetBlock(Itarget, r, c, blocksize);

i = 0;
for disparity1 = indices

  i = i+1;
  p_i = pdfin(i)/sum(pdfin);

  j = 0;
  for disparity2 = indices
	
	j = j+1;
	p_j = pdfin(j)/sum(pdfin);

	% rate = cost of encoding the two disparity values (entropy)
	%        + 2 bits/reference index
	Rcurr = -log2(p_i)-log2(p_j) + 4;
	
	% left
	refBlock1{1} = GetBlock(Irefs{1}, r, c+disparity1, blocksize);
	% right
	refBlock1{2} = GetBlock(Irefs{2}, r, c-disparity1, blocksize);
	% top
	refBlock1{3} = GetBlock(Irefs{3}, r+disparity1, c, blocksize);
	% bottom
	refBlock1{4} = GetBlock(Irefs{4}, r-disparity1, c, blocksize);
  
	% left
	refBlock2{1} = GetBlock(Irefs{1}, r, c+disparity2, blocksize);
	% right
	refBlock2{2} = GetBlock(Irefs{2}, r, c-disparity2, blocksize);
	% top
	refBlock2{3} = GetBlock(Irefs{3}, r+disparity2, c, blocksize);
	% bottom
	refBlock2{4} = GetBlock(Irefs{4}, r-disparity2, c, blocksize);
  
	for k=1:4
	  for m=1:4
	
		avgBlock = (refBlock1{k}+refBlock2{m})/2;
		Dcurr = GetDistortion(avgBlock, targetBlock);
		Jcurr = Dcurr + lambda*Rcurr;
		
		if (Jcurr < J)
		  J = Jcurr;
		  R = Rcurr;
		  D = Dcurr;
		  predBlock = avgBlock;
		  pdfout = zeros(size(pdfin));
		  pdfout(i) = 1;
		  pdfout(j) = 1;
		end
		
	  end
	end
	  
  end
end
