#include <stdio.h>

/*
 * This program is the inverse of encode
 *
 * It collects runs of 12 characters, combines pairs of those
 * to form 6 13 bit numbers, extracts the top bit of each of
 * those to make a 13th 6 bit character, and splits each of
 * the remaining 6 12 bit numbers to form 12 6 bit ones.
 *
 * The strings of 6 bit numbers are collected into groups of
 * 4 and converted into 3 8 bit characters.
 *
 * Now all that would be trivial, if we didn't need to worry
 * about ending all this correctly.  About 1/2 of the following
 * program wouldn't be here if the ending didn't matter....
 */

/*
 * the following pair of characters can never occur as a pair
 * in legal input (since (90 * 91 + 90) > 2^13) - they are
 * noticed at the beginning of a 12 char block, and serve to
 * indicate that this block is the terminator.  The character
 * immediately following is the (expanded) terminator length.
 */
#define	ENDMARK1	((90*91 + 90) / 91)
#define	ENDMARK2	((90*91 + 90) % 91)

int errcnt = 0;

main()
{
	register c;
	register char *p;
	register i;
	register first = 1;
	register cnt = 0;
	char b12[12];
	char c12[12];

	p = b12;
	i = 12;

	while ((c = getchar()) != EOF) {
		if (c < ' ' || c >= (' ' + 91)) {
			if (errcnt++ == 0)
				fprintf(stderr, "c7decode: Bad data\n");
			continue;
		}
		if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
			cnt = c - ' ';
			i = 12;
			p -= 2;
			continue;
		}
		*p++ = c - ' ';
		if (--i == 0) {
			if (p == &b12[12]) {
				if (!first)
					pack12(c12, 12, 0);
				else
					first = 0;
				p = c12;
			} else {
				pack12(b12, 12, 0);
				p = b12;
			}
			i = 12;
		}
	}

	if (p >= &b12[0] && p < &b12[12]) {
		if (!first)
			pack12(c12, 12, i == 12 ? cnt : 0);
	} else
		pack12(b12, 12, i == 12 ? cnt : 0);

	if (i != 12) {
		if (p >= &b12[0] && p < &b12[12])
			pack12(b12, 12-i, cnt);
		else
			pack12(c12, 12-i, cnt);
	}

	exit((errcnt > 0) ? 1 : 0);
}

static char b4[4];
static int cnt = 0;

pack12(p, n, last)
	register char *p;
	register n;
	int last;
{
	register i;
	register char *q;
	char b13[13];

	{
		register c;
		register c13;

		q = b13;
		c13 = 0;

		for (i = 0; i < n; i += 2) {
			c = *p++ * 91;
			c += *p++;
			c13 <<= 1;
			if (c & (1 << 12))
				c13 |= 1;
			*q++ = (c >> 6) & 0x3f;
			*q++ = c & 0x3f;
		}
		*q++ = c13;
		if (last)
			q = &b13[last];
	}

	p = b13;
	n = q - p;
	i = cnt;
	q = &b4[cnt];

	while (--n > 0) {
		*q++ = *p++;
		if (++i == 4) {
			char b3[3];
			register char *b = b4;

			/* inline expansion of pack6bit, to save calls ... */

			q = b3;
			*q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
			*q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
			*q = (b[2] << 6) | (b[3] & 0x3f);

			q = b3;
			while (--i > 0)
				putchar(*q++);

			q = b4;
		}
	}

	*q++ = *p++;	/* the last octet */
	++i;

	if (last || i == 4) {
		pack6bit(b4, i, last);
		i = 0;
	}

	cnt = i;
}

pack6bit(p, n, last)
	register char *p;
	register int n;
	int last;
{
	register char *q;
	register i = 3;
	char b3[3];

	if (last) {
		i = p[n-1];
		if (i >= 3) {
			fprintf(stderr, "c7decode: Badly encoded file\n");
			errcnt++;
			i = 3;		/* do the best we can */
		}
	}

	q = b3;
	*q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
	*q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
	*q = (p[2] << 6) | (p[3] & 0x3f);

	q = b3;

	while (--i >= 0)
		putchar(*q++);
}
