Metropoli BBS
VIEWER: rltext.c MODE: TEXT (ASCII)
/*
 * This is a **very** simple text compression program which performs
 * a "Run Length" encoding of duplicated characters in the input file.
 * It is designed to operate as a "unix" style filter, accepting input
 * from "stdin" and writing to "stdout".
 *
 * Syntax:	RLTEXT (Encode | Decode) <input_file >output_file
 *
 * Whenever two or more identical characters are encountered, the
 * following two character sequence is substituted:
 *		Byte1:	Character with high bit set
 *		Byte2:	Count of additional characters (up to 255)
 *
 * Note that this scheme works only on ASCII text files, and becomes *very*
 * confused if the original file contains characters with the high bit set.
 *
 * Compile command: cc rltext -fop
 */
#include <stdio.h>
#include <file.h>

main(argc, argv)
	int argc;
	char *argv[];
{
	int c, d;
	unsigned char n;

	/* Use MICRO-C's more powerful '&&' to force a zero if !enough args */
	switch((argc > 1) && toupper(*argv[1])) {
		case 'E' :				/* Encode file */
			*(char*)stdout |= F_BINARY;		/* Convert stdout to BINARY */
			c = getc(stdin);
			while((d = getc(stdin)) != EOF) {
				if(d == c) {
					n = 0;
					while(((d = getc(stdin)) == c) && (n < 255))
						++n;
					putc(c | 0x80, stdout);
					putc(n, stdout); }
				else 
					putc(c, stdout);
				c = d; }
			putc(c, stdout);
			break;
		case 'D' :				/* Decode file */
			*(char*)stdin |= F_BINARY;		/* Convert stdin to BINARY */
			while((c = getc(stdin)) != EOF)
				if(c & 0x80) {
					n = getc(stdin);
					for(d = (unsigned)n + 2; d; --d)
						putc(c & 0x7f, stdout); }
				else
					putc(c, stdout);
			break;
		default:
			abort("Use: RLTEXT E|D <input_file >output_file"); }
}
[ RETURN TO DIRECTORY ]