function [wimg, TRI]= triwarp(img,ipts,opts,tri)
%TRIWARP Use OpenGL to warp an image
%  WIMG = TRIWARP(IMG,IPTS,OPTS,TRI,VERB) warps the image IMG from the
%  input points IPTS to the output OPTS. The points are (x,y) pairs
%  where each row in the input points corresponds to the same point in
%  the output points.
%
%  The coordinates must be offset so they exist in the OpenGL 
%  coordinate space, i.e. (0, 0) is the first pixel, corresponding to 
%  (1, 1) in Matlab. 
%
%  TRI is a list of triples of indicies of the points forming the
%  vertices forming the given triangle. If none are given, the delaunay
%  of the input points is used.
%
%   Returns a 24-bit RGB uint8 image.
%
%   e.g. wimg = triwarp(img,ipts-1,opts-1,[],0);
%
%
% Version 1.0

% HISTORY:
%     28/11/2002 - 1.0 - Initial revision


% Check args
if(nargin < 4) 
    tri = []; 
end
if(nargin < 3) 
    error('Need an image, input points and output points'); 
end


% Delaunay triangulation of input points
if(isempty(tri))
	tri = delaunay(ipts(:,1), ipts(:,2),{'QJ','QJ','QJ'});
    tri = tri';
    tri = tri(:);
else
    TRI = tri;
end

% Get input and output triangle verticies
ivert = ipts(tri,:)';
ivert = single(ivert(:));
overt = opts(tri,:)';
overt = single(overt(:));

% Check image type, must be RGB
if(length(size(img)) == 2)
	img = repmat(img, [1, 1, 3]);
	rgbdata = 0;
else
	rgbdata = 1;
end
if(~isa(img,'uint8'))
	img = uint8(img);
	uintdata = 0;
else
	uintdata = 1;
end
% Warp the image
max_im_dim = 800;
if any(size(img)>max_im_dim)
    fprintf('**WARNING** - size of the input image is >%d pixels. Rescaling to reduce scale\n', max_im_dim); 
    scale = max_im_dim/max(size(img));
    img = imresize(img, scale);
    ivert = ivert*scale;
end

% Transpose so by rows [r g b]. Will be 'upside down' in OpenGL
r = img(:,:,1)';
g = img(:,:,2)';
b = img(:,:,3)';
k = [r(:) g(:) b(:)]';
k = reshape(k(:),size(img,2),size(img,1),3);



timg = gltriwarp(k,ivert,overt);


% Put back as Matlab RGB matrix
siz = size(timg);
timg = timg(:);
wimg(:,:,1) = reshape(timg(1:3:length(timg)),siz(1),siz(2))';
wimg(:,:,2) = reshape(timg(2:3:length(timg)),siz(1),siz(2))';
wimg(:,:,3) = reshape(timg(3:3:length(timg)),siz(1),siz(2))';

% Make ouput type same as input
if(~rgbdata)
	wimg = wimg(:,:,1);
end
if(~uintdata)
	wimg = double(wimg);
end
