function [c,map] = cmunique(r,g,b)
%CMUNIQUE Find unique colormap colors and corresponding image.
%	[Y,NEWMAP] = CMUNIQUE(X,MAP) returns the image Y and associated
%	colormap NEWMAP that produces the exactly same image as [X,MAP]
%	but with the smallest colormap.
%
%	[Y,NEWMAP] = CMUNIQUE(R,G,B) converts the RGB image to an
%	indexed image with the smallest colormap.  The R,G,B matrices
%	contain	intensities of the red, green, and blue components,
%	respectively, in the range from 0.0 (black) to 1.0 (full
%	intensity). NEWMAP will contain one entry for each unique
%	color in the RGB image.
%
%	[Y,NEWMAP] = CMUNIQUE(I) converts the gray level intensity 
%	image I to an indexed image with the smallest colormap.
%	NEWMAP will contain one entry for each unique intensity level
%	in the image I.
%
%	See also RGB2IND, GRAY2IND.

%	Clay M. Thompson 10-5-92
%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.13 $  $Date: 1993/09/09 15:52:22 $

error(nargchk(1,3,nargin));

% Convert all possible input arguments to an indexed image.
if nargin==1, % cmunique(I)
  [c,map] = rgb2ind(r,r,r);
elseif nargin==2, % cmunique(a,cm)
  c = r; map = g;
elseif nargin==3, % cmunique(r,g,b)
  [c,map] = rgb2ind(r,g,b);
end

tol = 1/1024;

% Quantize colormap entries to help matching below.
map = round(map/tol)*tol;

%  
% Remove matching entries from colormap
%
 
% Sort colormap entries
[dum,ndx1] = sort(map(:,1));
[dum,ndx2] = sort(map(ndx1,2));
[dum,ndx3] = sort(map(ndx1(ndx2),3));
		% ndx maps from sorted cm to original cm
ndx = ndx1(ndx2(ndx3));
		% pos maps from original cm to sorted cm
pos = zeros(size(ndx)); pos(ndx) = 1:length(ndx);

% Find matching entries
		% d indicates the location of matching entries
d = all(abs(diff(map(ndx,:)))'<tol)';

% Mapping from full cm to compressed cm
		% loc maps from sorted cm to compressed cm
loc = [1:length(ndx)]' - [0;cumsum(d)]; 
c(:) = loc(pos(c));

% Remove matching entries (compress cm)
ndx(find(d)) = [];
map = map(ndx,:);

%
% Remove colormap entries that are not used in c
%
[n,x] = imhist(c,map);
d = (n==0); % Find unused colormap entries
loc = [1:length(map)]' - cumsum(d);

% Update image values
c(:) = loc(c);

% Remove unused entries (compress cm)
map(find(d),:) = [];
