function map = imadjust(cm,lowhigh,bottop,gamma)
%IMADJUST Adjust and stretch image intensity.
%	J = IMADJUST(I,[LOW;HIGH],[BOT;TOP],GAMMA) transforms the
%	values in the intensity image I.  The result in returned in
%	the intensity image J.  The intensities between LOW and HIGH
%	are stretched to fill the intensity range from BOT to TOP.  
%	LOW, HIGH, BOT, and TOP must be between 0.0 and 1.0.
%
%	      LOW               HIGH
%	0.0----|------------------|----1.0 (input intensity range)
%	      /                   \
%	     /   mapping: x^gamma  \
%	0.0-|-----------------------|--1.0 (output intensity range)
%	   BOT                     TOP
%
%	Intensity values below LOW and above HIGH are clipped.  GAMMA 
%	is used to control the stretching process.  GAMMA = 1.0 
%	specifies linear stretching.  0<GAMMA<1 lightens the image,
%	while 1.0<GAMMA<inf darkens the image.
%
%	NEWMAP = IMADJUST(MAP,[LOW;HIGH],[BOT;TOP],GAMMA) transforms the
%	colormap MAP associated with an indexed image.  If GAMMA is a 
%	1-by-3 vector and [LOW;HIGH] and [BOT;TOP] are 2-by-3 matrices,
%	then the values along the columns are used to transform the
%	R, G, and B components of the colormap individually.
%
%	Null matrices can be used to specify the default for any
%	parameter.  [LOW;HIGH] defaults to [0;1], [BOT;TOP] defaults
%	to [0;1], and GAMMA defaults to 1.

%	Clay M. Thompson 10-26-92
%	Copyright (c) 1992 by The MathWorks, Inc.
%	$Revision: 1.10 $  $Date: 1993/08/10 02:20:04 $

error(nargchk(2,4,nargin));

if size(cm,2)~=3, isGray = 1; else isGray = 0; end

% Default values
if nargin<3, bottop = [0;1]; end
if nargin<4, gamma = 1; end
if isempty(lowhigh), lowhigh = [0;1]; end
if isempty(bottop), bottop = [0;1]; end
if isempty(gamma), gamma = 1; end

if min(size(lowhigh))==1,
  low = lowhigh(1)*ones(1,3);
  high = lowhigh(2)*ones(1,3);
else
  low = lowhigh(1,:);
  high = lowhigh(2,:);
end
if min(size(bottop))==1,
  bot = bottop(1)*ones(1,3);
  top = bottop(2)*ones(1,3);
else
  bot = bottop(1,:);
  top = bottop(2,:);
end
if max(size(gamma))==1, gamma = gamma*ones(1,3); end

if isGray, % All the parameters must be scalars for intensity image.
  low = low(1); high = high(1); bot = bot(1); top = top(1); gamma = gamma(1);
end

if min(low)<0 | max(low)>1 | min(high)<0 | max(high)>1 | ...
   min(bot)<0 | max(bot)>1 | min(top)<0  | max(top)>1,
  error('LOW,HIGH,BOT and TOP must be in the range from 0.0 to 1.0.');
end
if min(gamma)<0, error('GAMMA must be greater than 0.0 .'); end

% Make sure cm is in the range [low,high]
if isGray, n = 1; else n = size(cm,1); end
cm(:) = max(low(ones(n,1),:),min(high(ones(n,1),:),cm));

% Transform colormap or intensity image
d = ones(n,1);
map = ( (cm-low(d,:))./(high(d,:)-low(d,:)) ).^(gamma(d,:));
map(:) = map.*(top(d,:)-bot(d,:)) + bot(d,:);
