%EXTEND   Extends/pads an image with values
%
% SYNOPSIS:
%  out = extend(in, newsize, type, value, clip)
%
% PARAMETERS:
%  in:  input image
%  newsize:  new image size
%  type:  'symmetric',
%         'leftup',rightup','leftlow','rightlow'
%  value: extension value
%  clip:  clip images if newsize < oldsize ('no','yes')
%
% DEFAULTS:
%  type: 'symmetric'
%  value: 0
%  clip: 'no' (if newsize smaller than input, do nothing)
%
% EXAMPLE:
%  extend(readim,[512 512])
%  extend(readim('chromo3d'),30,'symmetric',1)
%
% SEE ALSO:
%  cut

% (C) Copyright 2004-2007      Department of Molecular Biology
%     All rights reserved      Max-Planck-Institute for Biophysical Chemistry
%                              Am Fassberg 11, 37077 G"ottingen
%                              Germany
%
% Bernd Rieger, Sep 2004.
% 9 April 2007, Rewrote to use SUBSASGN instead of EVAL. (CL)

function out = extend(varargin)
d = struct('menu','Manipulation',...
   'display','Extend (padding)',...
   'inparams',struct('name',       {'in','bor','typ','value','clp'},...
         'description',{'Input image','New image size',...
            'Placement flavour','Value','Clipping'},...
         'type',       {'image','array','option','array','boolean'},...
         'dim_check',  {0,1,0,0,0},...
'range_check',{[],'N+',{'symmetric','leftup','leftlow','rightup','rightlow'},'R',[]},...
         'required',   {1,1,0,0,0},...
         'default',    {'a','256','symmetric',0,0}...
        ),...
   'outparams',struct('name',{'out'},...
                      'description',{'Output image'},...
                      'type',{'image'}...
                      )...
  );
if nargin == 1
   s = varargin{1};
   if ischar(s) & strcmp(s,'DIP_GetParamList')
      out = d;
      return
   end
end
try
   [in,bor,typ,value,clp] = getparams(d,varargin{:});
catch
   if ~isempty(paramerror)
      error(paramerror)
   else
      error(firsterr)
   end
end
if ~isscalar(in)
   error('Only implemented for scalar (grey-value) images.');
end
in = squeeze(in);
sz = imsize(in);
tmp = sz>bor;
bortmp = bor;
if all(tmp)
   if clp
      out = cut(in,bor);
   else
      out = in;%nothing to do
   end
   return;
end
bor(tmp) = sz(tmp); % all extension to smaller size are put to size;
out = newim(bor,datatype(in));
if value
   out(:) = value;
end

N = ndims(in);
co = zeros(N,2);
switch typ
   case 'symmetric'
      start = floor((bor(:) - sz')./2); %start coord
      stop  = start+sz'-1;              %end coord
   case 'leftup'
      start = 0;
      stop  = sz'-1;
   case 'leftlow'
      if N>2
         error('leftlow option only up to 2D');
      end
      start = [0;bor(2)-sz(2)];
      stop  = [sz(1)-1;bor(2)-1];
   case 'rightup'
       if N>2
         error('rightup option only up to 2D');
      end
      start = [bor(1)-sz(1);0];
      stop  = [bor(1)-1;sz(2)-1];
   case 'rightlow'
      start = bor(:) - sz';
      stop  = bor(:) - 1;
   otherwise
      error('Should not happen');
end
s = substruct('()',{});
for ii = 1:N
   s.subs{ii} = start(ii):stop(ii);
end
out = subsasgn(out,s,in);

%if any dimesion is smaller than the old size and clp is yes
if any(tmp) & clp
   sz2 = bor;
   sz2(tmp) = bortmp(tmp);
   out = cut(out,sz2);
end
