/************************************************************************
 *									*
 *		    Copyright (c) 1988, David B. Wecker			*
 *			    All Rights Reserved				*
 *									*
 * This file is part of DBW_uRAY					*
 *									*
 * DBW_uRAY is distributed in the hope that it will be useful, but	*
 * WITHOUT ANY WARRANTY. No author or distributor accepts		*
 * responsibility to anyone for the consequences of using it or for	*
 * whether it serves any particular purpose or works at all, unless	*
 * he says so in writing. Refer to the DBW_uRAY General Public		*
 * License for full details.						*
 *									*
 * Everyone is granted permission to copy, modify and redistribute	*
 * DBW_uRAY, but only under the conditions described in the		*
 * DBW_uRAY General Public License. A copy of this license is		*
 * supposed to have been given to you along with DBW_uRAY so you	*
 * can know your rights and responsibilities. It should be in a file	*
 * named COPYING. Among other things, the copyright notice and this	*
 * notice must be preserved on all copies.				*
 ************************************************************************
 *									*
 * Authors:								*
 *	DBW - David B. Wecker						*
 *									*
 * Versions:								*
 *	V1.0 881023 DBW	- First released version			*
 *	V1.1 881110 DBW - Fixed scan coherence code			*
 *	V1.2 881125 DBW - Removed ALL scan coherence code (useless)	*
 *			  added "fat" extent boxes			*
 *									*
 ************************************************************************/

/***********************************************************************/
/************************ run length encoding from RKM *****************/
/***********************************************************************/

#define DUMP		0
#define RUN		1
#define MinRun		3
#define MaxRun		128
#define	MaxDat		128
#define GetByte()	(*source++)
#define PutByte(c)	{ *dest++ = (c); ++PutSize; }
#define OutDump(nn)	dest = PutDump(dest,nn)
#define OutRun(nn,cc)	dest = PutRun(dest,nn,cc)

short	PutSize;
char	buf[256];

/* put out nn bytes into the dest buffer */
unsigned char *PutDump(dest,nn)
unsigned char	*dest;
short		nn;
    {
    short i;

    PutByte(nn-1);
    for (i = 0; i < nn; i++) PutByte(buf[i]);
    return(dest);
    }

/* put out the cc byte nn times into the dest buffer */
unsigned char *PutRun(dest,nn,cc)
unsigned char	*dest;
short		nn,cc;
    {
    PutByte(-(nn-1));
    PutByte(cc);
    return(dest);
    }

/* put out a row of the current image */
short PackRow(source,dest,RowSize)
unsigned char	*source,*dest;
short		RowSize;
    {
    char	    c,
		    lastc = '\000';
    short	    mode = DUMP,
		    nbuf = 0,	    /* number of chars in buf */
		    rstart = 0;	    /* buf index current run starts */

    PutSize = 0;
    buf[0]  = lastc = c = GetByte();
    nbuf    = 1;
    RowSize--;

    for (; RowSize; --RowSize) {
	buf[nbuf++] = c = GetByte();

	switch (mode) {
	    case DUMP:
	    if (nbuf > MaxDat) {
		OutDump(nbuf-1);
		buf[0]	= c;
		nbuf	= 1;
		rstart	= 0;
		break;
		}
	    if (c == lastc) {
		if (nbuf-rstart >= MinRun) {
		    if (rstart > 0) OutDump(rstart);
		    mode = RUN;
		    }
		else if (rstart == 0) mode = RUN;
		}
	    else rstart = nbuf - 1;
	    break;

	    case RUN:
	    if ((c != lastc) || (nbuf-rstart > MaxRun)) {
		OutRun((nbuf-1)-rstart,lastc);
		buf[0]	= c;
		nbuf	= 1;
		rstart	= 0;
		mode	= DUMP;
		}
	    break;
	    }
	lastc = c;
	}
    switch (mode) {
	case DUMP: OutDump(nbuf); break;
	case RUN:  OutRun(nbuf-rstart,lastc); break;
	}

    return(PutSize);
    }


