function Y=rle(X,flag,mode);
%RLE	Compress a vector using Run Length Encoding.
%	Compdata=RLE(Rawdata,Flag,Mode) compresses the vector Rawdata,
%	marking the start of an RLE sequence with the value Flag, followed
%	by a count value and a data value. The Flag and repeat count can 
%	be stored either as two explicit bytes at the start of an RLE
%	sequence, as a single byte where Flag is a high order bit(s), and 
%	the remaining bits in the flag byte are used to store the repeat
%	count, depending on the value for the Mode parameter. 
%	Valid values for the Mode parameter are:
%
%	  Mode	Description
%
%		1	RLE flag is a high order set of bit(s).
%			The remaining bits in the byte represent the repeat count.
%
%		2	RLE flag is an explicit byte.
%			The following byte represents the repeat count.
%
%	For example, RLE(data,128+64,1) compresses a vector, and marks the
%	start of any RLE sequences by setting the top two bits. The
%	remaining 6-bits represent the repeat count.
%
%	Note, when using Mode 1 (single byte mode), any data values that set
%	a high order bit will be stored as a RLE sequence, which can result
%	in negative compression. Mode one is not effective for data that has
%	values that may set the RLE flag bit (as in 8-bit data). Mode 2, 
%	which stores the RLE flag and repeat count as seperate bytes, is a more
%	effective method for 8-bit data.
%
%	Also note that the data to be compressed is assumed to be 8-bit data.

%	Mounil Patel 7/20/93
%	Copyright (c) 1993 by The MathWorks, Inc.
%	$Revision: 1.4 $  $Date: 1993/10/21 12:59:32 $


if (nargin~=3)
	error('RLE requires three parameters.');
end

if ((mode~=1)&(mode~=2))
	error('Sorry, RLE flag mode can be set to either 1 or 2 only.');
end

% first make the raw data a column vector
Y=X';
Y=Y(:);

% find the start, end, and body of all repeating runs
Start=[diff(Y)==0;0];
End=[0;diff(Start)==-1];
All=Start|End;
Start=diff([0;[diff(Y)==0;0]])==1;

% eleminate runs of less than 3 bytes
index=find(Start);
index(~((find(End)-index)==1))=[];
Start(index)=zeros(size(index));
End(index+1)=zeros(size(index));
All(index)=zeros(size(index));
All(index+1)=zeros(size(index));

% replace runs with rle coded data
index=find(Start);
counts=find(End)-index+1;
values=Y(index);
if (mode==2)
	Y(index)=flag.*ones(size(index));
	Y(index+1)=counts;
	Y(index+2)=values;
elseif (mode==1)
	Y(index)=flag.*ones(size(index))+counts;
	Y(index+1)=values;
end

All(index)=zeros(size(index));
All(index+1)=zeros(size(index));
if (mode==2)
	All(index+2)=zeros(size(index));
end;

Y(All)=[];

