function [M,CM] = xwdread(fname,flag)
%XWDREAD Read a XWD (X window dump) file from disk.
%	[X,MAP] = XWDREAD('filename') reads the file 'filename' and
%	returns the indexed image X and colormap MAP.
%	XWDREAD will read XWDs in the following formats:
%		Zpixmaps with depth of 1 or 8 bits
%		XYbitmaps
%		XYpixmaps with depth of 1
%
%	See also: XWDWRITE, BMPREAD, GIFREAD, HDFREAD, PCXREAD,
%	          TIFFREAD.

%	Drea Thomas, 7-20-93.
%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.6 $  $Date: 1993/10/21 12:59:32 $

[fid,message] = fopen(fname,'r','b');
if fid == -1,
	error(['File ',fname,' not found.']);
end

% First 2 bytes are header length, and a magic number that identifies a xwd
hsize = fread(fid,2,'long');

if isempty(hsize),
	error(['File ',fname,' is empty.']);
end
if hsize(2) ~= 7,
	error(['File ',fname,' not in XWD format.']);
end

% Read rest of header and get the xwd name
header = fread(fid,23,'ulong');
name = fread(fid,hsize(1)-100,'uchar');

% See if it is an XYPixmap (unsupported)
if (header(1) == 1) & (header(2) ~= 1),
	disp('Sorry, XYPixmap format not supported')
	return
end

% Colormap length
CMsize = header(18);

tmp = fread(fid,[6 CMsize],'ushort');
CM = [(tmp(2,:)+tmp(1,:)*65535)',tmp(3:5,:)'/65535];

% Byte order. If header is Big-endian and data is Little-endian
% Reopen with different architecture, reposition file pointer
if (header(6) ~= 1) & (header(7) ~= 8),
	pos=ftell(fid);
	fclose(fid);
	fid=fopen(fname,'r','l');
	fseek(fid,pos,-1);
end

% What storage format is the data in?
if header(1) == 2 | (header(1)==0) | (header(1) == 1 & header(2) == 1),
				% ZPixmap,  XYbitmap or XYpixmap depth 1
    % Size of pixels
	if any(header(2) == [1 8]);
		prec = 'uchar';
	else
		fprintf('Sorry, %d bit Zpixmaps not supported\n',header(2)) 		
		return
	end

	if (header(2) == 8), % ZPixmap with depth 8
		pad=ceil(header(3)/header(9)*header(2))*header(9)/header(2)-header(3);
		M=fread(fid,[header(3)+pad header(4)],prec)';
	else,      % ZBitmap XYPitmap or XYPixmap of depth 1
		M=fread(fid,[header(3)/8 header(4)],'uchar')';

        % Take apart bytes into 8 bits and store as a matrix of 1's and 0's
		[a,b]=size(M);
		P=zeros(a,b*8);
		for i=7:-1:0,
			tmp=find(M/2^i >= 1);
			if ~isempty(tmp),
				M(tmp)=M(tmp)-2^i;
                % header(8) determines LSB first or MSB first
				P(tmp+ceil(tmp/a)*(7*a)+(-i)*a+a*(2*i-7)*(~header(8)))= ...
                 ones(size(tmp));
			end
		end
		CM=[0 1 1 1;1 0 0 0];
		M=P;
	end

    % If the colormap index is not sequential then map the pixels so they are
	if ~all(gradient(CM(:,1)')==1),
		for i=1:CMsize,
			tmp=find(M==CM(i,1));
			M(tmp) = CM(i,1)*ones(size(tmp));
		end 
	end
end

M=M+1;
CM=CM(:,2:4);

fclose(fid);
