function im=ditherc( r, g, b, map, qm, qe )
%DITHERC Floyd-Steinberg image dithering (MEX function).
%	DITHERC implements the dithering algorithm for the function
%	DITHER.  It has the same syntax as DITHER.
%
%	Don't use this function directly, use DITHER instead.

%	Joseph M. Winograd 7-93
%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.2 $  $Date: 1993/10/21 12:59:32 $

%	This m-file maps the R,G,B directly to an indexed image (choosing
%	the best match) without dithering.  This function will only be called
%	if the MEX function is not available (in which case dithering
%	will not be possible).

%	References: 
%	R. W. Floyd and L. Steinberg, "An Adaptive Algorithm for
%	    Spatial Gray Scale," International Symposium Digest of Technical
%	    Papers, Society for Information Displays, 36.  1975.
%	Spencer W. Thomas, "Efficient Inverse Color Map Computation",
%	   Graphics Gems II, (ed. James Arvo), Academic Press: Boston.
%	   1991. (includes source code)

%
% Create coarse inverse colormap
%
n = qm;
nmap = [n+1 n+1 n+1]; N = size(map,1);

% Indexes for coarse color cube
[j,i,k] = meshgrid(1:nmap(2),1:nmap(1),1:nmap(3));

% Now fill inverse colormap with indexes of closest color in each bin
invmap = zeros(size3d(nmap));
M = prod(size(i));

% Manhattan Distance to colors in colormap from center of each bin
[v,l] = min(abs(ones(N,1)*(i(:)'-0.5)/n-map(:,1)*ones(1,M)) + ...
            abs(ones(N,1)*(j(:)'-0.5)/n-map(:,2)*ones(1,M)) + ...
            abs(ones(N,1)*(k(:)'-0.5)/n-map(:,3)*ones(1,M)));
invmap(elem3d(nmap,i,j,k)) = l;

% Return inverse colormap color for each pixel in (r,g,b).
im = zeros(size(r));
im(:) = invmap(elem3d(nmap,round(r*n)+1,round(g*n)+1,round(b*n)+1));
