%STRETCH   Grey-value stretching
%
% SYNOPSIS:
%  image_out = stretch(image_in, low, high, minimum, maximum)
%  low = lower percentile of image_in
%  high = highest percentile of image_in
%
% DEFAULTS:
%  low = 0    
%  high = 100
%  minimum = 0
%  maximum = 255
%
% NOTE: changed order of input max and min as Nov 2002

% (C) Copyright 1999-2000               Pattern Recognition Group
%     All rights reserved               Faculty of Applied Physics
%                                       Delft University of Technology
%                                       Lorentzweg 1
%                                       2628 CJ Delft
%                                       The Netherlands
%
% Cris Luengo, June 2000.
% Nov 2002, changed order of input parameter + update help

function image_out = stretch(varargin)

d = struct('menu','Point',...
  'display','Grey-value stretching',...
  'inparams',struct('name',       {'image_in',   'low','high','maximum','minimum'},...
       'description',{'Input image','Lower percentile','Upper percentile','Minimum','Maximum'},...
       'type',       {'image',      'array',           'array',           'array',     'array'},...
       'dim_check',  {0,            0,                 0,                 0,           0},...
       'range_check',{[],           [0 100],           [0 100],           [],          []},...
       'required',   {1,0,0,0, 0},...
       'default',    {'a',0,100,0,255}...
        ),...
  'outparams',struct('name',{'image_out'},...
                     'description',{'Output image'},...
                     'type',{'image'}...
                     )...
  );
if nargin == 1
   s = varargin{1};
   if ischar(s) & strcmp(s,'DIP_GetParamList')
      image_out = d;
      return
   end
end
try
   [image_in,low,high,minimum,maximum] = getparams(d,varargin{:});
catch
   if ~isempty(paramerror)
      error(paramerror)
   else
      error(firsterr)
   end
end

if low > high
   tmp = low; low = high; high = tmp;
end
if maximum == minimum
   image_out = image_in;
   image_out(:) = minimum;
   return
end
if low == high
   image_out = image_in;
   image_out(:) = (minimum+maximum)/2;
   return
end
ps = ones(1,ndims(image_in));
if low == 0
   low = min(image_in);
else
   low = double(dip_percentile(image_in,[],low,ps));
   image_in(image_in<low) = low;
end
if high == 100
   high = max(image_in);
else
   high = double(dip_percentile(image_in,[],high,ps));
   image_in(image_in>high) = high;
end
if low == high
   image_out = image_in;
   image_out(:) = (minimum+maximum)/2;
else
   if low~=0
      image_in = image_in-low;
   end
   image_out = image_in/((high-low)/(maximum-minimum));
   if minimum~=0
      image_out = image_out + minimum;
   end
end
